Create CSG shapeRepresentation

Hi,
Attached is an attempt to create a boolean shaperepresentation, as a intersection between two boxes.
I am sorry if I am taking too much space on the forum lately, with a bunch of questions, but I would appreciate any help in order to create a new ifc product with an attached boolean shape.
I need boolean shapes since I am trying to visualize building phases for very long roads, and I am planning on using boolean operations in order to create new shapes belonging to certain phases (each shape assigned IfcTask's). The attached MVP.txt is a python script, the MVP.ifc contains two box'es I want to operate on.
As always, any help is appreciated:D

Comments

  • edited September 2022

    After some more attempts, I got the boolean operations to (somehow) work for some examples. But something I am very confused by is how the shape used in the IfcBooleanResult() operator doesnt care about its placement!?
    ifcFilePath = r"C:\Users\sbe\Documents\IFC\newest.ifc"
    ifcFile = ifcopenshell.open(ifcFilePath)
    cube1, cube2 = ifcFile.by_type("IfcWall")
    cube1Shape = cube1.Representation.Representations[1].Items[0]
    cube2Shape = cube2.Representation.Representations[1].Items[0]
    cube1Shape.Coordinates.CoordList == cube2Shape.Coordinates.CoordList #This line returns True(!)

    The attached .ifc file contains two boxes, but since both are described relative to their own center, their differrent position in space is ignored:(

  • edited September 2022



    An example of how the correct spatial positioning is ignored: the boolean operator only care about the objects relative displacement.
    The uppermost image is the input shapes, the next image is the resulting shapes..

  • edited September 2022

    I tried the following, but it didn't work either.
    I thought i could shift the IFCCARTESIANPOINTLIST3D by the IFCLOCALPLACEMENT and then boolean it.
    I also messed around with...

    • RepresentationType = 'Tessellation'
    • cube1Shape.Closed = True

    ...but nothing unlocked it. :\

    import bpy
    import ifcopenshell
    import blenderbim.bim.import_ifc
    from blenderbim.bim.ifc import IfcStore
    
    
    ifcFile = ifcopenshell.open(IfcStore.path)
    
    cube1 = ifcFile.by_type("IfcActuator")[0]
    cube2 = ifcFile.by_type("IfcActuator")[1]
    
    cube1Shape = cube1.Representation.Representations[1].Items[0]
    cube2Shape = cube2.Representation.Representations[1].Items[0]
    
    cube1Shape.Closed = True
    cube2Shape.Closed = True
    
    cube1placement_to_list = list(cube1.ObjectPlacement.RelativePlacement.Location.Coordinates)
    cube2placement_to_list = list(cube2.ObjectPlacement.RelativePlacement.Location.Coordinates)
    
    cube2vertices = list(cube2Shape.Coordinates.CoordList)
    
    
    temp_vertices_list = []
    for x in cube2vertices:
        x_temp_list = list(x)
        i=0
        temp_coord_list = []
        for y in x_temp_list:
            y = cube1placement_to_list[i] - cube2placement_to_list[i]
            temp_coord_list.append(y)
            i+=1
        temp_coord_list_to_tuple = tuple(temp_coord_list)
        temp_vertices_list.append(temp_coord_list_to_tuple)
    temp_vertices_list_to_tuple = tuple(temp_vertices_list)
    cube2Shape.Coordinates.CoordList = temp_vertices_list_to_tuple
    
    
    
    booleanResult = ifcFile.createIfcBooleanResult(Operator="INTERSECTION", FirstOperand=cube1Shape, SecondOperand=cube2Shape)
    context = ifcFile.by_type("IfcGeometricRepresentationContext")[0]
    storey = ifcFile.by_type("IfcBuildingStorey")[0]
    point = ifcFile.createIfcCartesianPoint((0.0, 0.0, 0.0))
    zdir = ifcFile.createIfcDirection((0.0, 0.0, 1.0))
    xdir = ifcFile.createIfcDirection((1.0, 0.0, 0.0))
    origin = ifcFile.createIfcAxis2Placement3D(point, zdir, xdir)
    placement = ifcFile.createIfcLocalPlacement(None, origin)
    road = ifcopenshell.api.run('root.create_entity', ifcFile, ifc_class = 'IfcWall')
    road.Name = "MY NEW ROAD SEGMENT!"
    road.ObjectPlacement = placement
    shapeRepresentation = ifcFile.create_entity('IfcShapeRepresentation', ContextOfItems = context, RepresentationIdentifier = 'Body', RepresentationType = 'CSG', Items = [booleanResult])
    ifcopenshell.api.run('geometry.assign_representation', ifcFile, product = road, representation = shapeRepresentation)
    
    
    
    ifcFile.write("D:/Dropbox/Learning/Python/edge_to_wall/bollean/MVP_modified.ifc") 
    
    
    
    
  • I think the error is in my understanding of Blender, as booleanresult works perfectly as long as the shape representation is in global coordinates.
    I need to understand how to update the shaperepresentation when the reference point is moved/specified.
    I will update this thread when I better understand what I am doing (wrong) in Blender:)

    theoryshaw
  • Sounds good. Can you share the script where you got the bollean's working? I'd like to tinker as well.

  • I actually altered the input to the shape representation directly in the .ifc file manually, not using python. I just made sure the vertices of the boxes were expressed in the global coordinate system, and then ifcbooleanresult worked as expected:)
    I will let you know when I get python and/or blender working as I intend (ie. shape in global coordinates, or at least expressed relative to the same point)

    theoryshaw

  • Update:)
    You move stuff however you want, and the shaperepresentation for each object is relative to the "object origin". When the object is moved where you want, you can either press Shift+E to get the menu shown above, or click on the "mesh" tab for that object and click on IFC representation, in order to chose "update IFC Representation". The object must be assigned an IfcClass in order for it to have an Ifc shape representation.
    Now, the shaperepresentation for that object is updated when saving the ifc file, and the boolean operations works as expected:)

    brunopostle
Sign In or Register to comment.