OSArch Community

New documentation about creating geometry in IFC

  1. M

    Every so often, we get questions about "how do I create geometry in IFC"? This is a difficult question to answer since you need to 1) know something about matrixes 2) know about geometry like meshes and extrusions 3) know how BIM is special that you can have multiple geometries per object 4) know how parametric BIM is extra special since we have the concept of layers and types and profiles and 5) put it altogether in a thing like IFC and the official IFC docs are spread out.

    I've been slowly chipping away at this (4 thousand word behemoth) documentation which goes through in painstaking detail (and lots of code examples) from beginning to end everything you need to know about geometry. I'd invite anybody without any Friday night plans to read through and let me know whether it helps clear any confusion: https://blenderbim.org/docs-python/ifcopenshell-python/geometry_creation.html

    This includes non-coders! There is a lot of code examples since it's meant for coders, but I genuinely believe non-coders can understand it too!

  2. C

    Wow, this is so incredibly useful! Thank you very much for all the hard work and effort you put into this.

  3. S

    When creating a beam with blenderBIM, there are options to extend/change the length.

    This option does not exist when creating a beam using python.

  4. M

    @smr02 there actually is a way to do it, but the UI isn't exposed (and right now we've moved it to the Debug panel).

    The difference is that the first is a material profile set, whereas the second is just a regular extruded profile. Right now, the "extend" tool only works for material profile sets.

  5. S

    thank you, @Moult

    I'm now looking into creating a Material profile sets.

    1. There are two errors in the code. I think it should be like this:
    
    # First, let's create a material set. This will later be assigned to our beam type element.
    
    material_set = ifcopenshell.api.run("material.add_material_set", model,
    
        name="B1", set_type="IfcMaterialProfileSet")
    
    
    # Create an I-beam profile curve. Notice how we use standardised steel profile names.
    
    hea100 = model.create_entity(
    
        "IfcIShapeProfileDef", ProfileName="HEA100", ProfileType="AREA",
    
        OverallWidth=100, OverallDepth=96, WebThickness=5, FlangeThickness=8, FilletRadius=12,
    
    )
    
    1. I'm running into a error that i can't solve:
    
      File "/home/smr/Desktop/blenderIDE/tutorial.py", line 177, in <module>
    
        representation = ifcopenshell.api.run("geometry.add_profile_representation", model, context=body, profile=hea100, depth=1)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/__init__.py", line 66, in run
    
        result = usecase_class(ifc_file, **settings).execute()
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_profile_representation.py", line 42, in execute
    
        self.settings["context"].ContextIdentifier,
    
    AttributeError: 'NoneType' object has no attribute 'ContextIdentifier'
    

    BlenderBIM version: 0.0.230801

  6. M
  7. S

    The line body = ifcopenshell.util.representation.get_representation(element, "Model", "Body") was overwriting my body variable with None. I've removed this line. Now it's working. Thank you!

  8. M
  9. S

    I've written a script that converts a FEM model to IFC.

    Now I'm looking for a function similar to "extend_profile" in BlenderBIM.

    Alternatively, how can I edit my representation?

    
        body = ifcopenshell.util.representation.get_context(model, "Model", "Body", "MODEL_VIEW")
    
        representation = ifcopenshell.api.run(
    
            "geometry.add_profile_representation", 
    
            model, 
    
            context=body, 
    
            profile=profile, 
    
            depth=beam_length #length
    
        )
    
        ifcopenshell.api.run("geometry.assign_representation", model, product=beam, representation=representation)
    

  10. M

    There is no "packaged" code available to extend a profile in pure Blender-agnostic code right now. Extension is a bit of a more advanced deal, for example: when you extend a profile, what if the profile was parametrically connected to something? Should it remove that parametric extension too? Should it then remove all boolean clippings (e.g. mitred clips) too or preserve them?

    So you'll need to decide how you want to handle it: you can remove the representation and create a fresh representation from scratch, or simply traverse the representation tree's extruded area solid element then change the Depth attribute of the extrusion.

  11. S

    Here's a screenshot of a minimal example of what i want to do.

    I want to extend the beam and then add voids to model the connections. So for now the only thing I want to preserve are voids because the beam likely has multiple connections.

    I think it's enough to change the depth attribute. However, I need to be able to do this on both ends of the beam.

  12. M
  13. S

    Ok, that makes sense.

    How do I create a IfcHalfSpaceSolid? I'm stuck here:

    
    body = ifcopenshell.util.representation.get_context(model, "Model", "Body", "MODEL_VIEW")
    
    vertices = [[(0.,0.,0.), (0.,2.,0.), (2.,2.,0.), (2.,0.,0.), (1.,1.,1.)]]
    
    faces = [[(0,1,2,3), (0,4,1), (1,4,2), (2,4,3), (3,4,0)]]
    
    representation = run("geometry.add_mesh_representation", model, context=body, vertices=vertices, faces=faces)
    
    matrix = np.array(
    
                (
    
                    (1, 0, 0, 0),
    
                    (0, 1, 0, 0),
    
                    (0, 0, 1, 0),
    
                    (0, 0, 0, 1),
    
                )
    
            )
    
    half_space = ifcopenshell.api.run(
    
            "geometry.add_boolean", 
    
            model, 
    
            representation = representation,
    
            # # IfcHalfSpaceSolid, Mesh
    
            type = "IfcHalfSpaceSolid",
    
            # # The XY plane is the clipping boundary and +Z is removed.
    
            matrix = matrix,  # A matrix to define a clipping Ifchalfspacesolid.
    
        )
    
    
      File "/home/smr/Desktop/simple_truss/test.py", line 52, in <module>
    
        half_space = ifcopenshell.api.run(
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/__init__.py", line 66, in run
    
        result = usecase_class(ifc_file, **settings).execute()
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_boolean.py", line 44, in execute
    
        result = self.create_half_space_solid()
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_boolean.py", line 58, in create_half_space_solid
    
        self.file.createIfcCartesianPoint(
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/file.py", line 337, in create_entity
    
        e[idx] = arg
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/entity_instance.py", line 262, in __setitem__
    
        self.method_list[idx](self.wrapped_data, idx, entity_instance.unwrap_value(value))
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/ifcopenshell_wrapper.py", line 3814, in setArgumentAsAggregateOfDouble
    
        return _ifcopenshell_wrapper.entity_instance_setArgumentAsAggregateOfDouble(self, i, v)
    
    TypeError: Attribute of type AGGREGATE OF REAL needs a python sequence of floats
    
  14. M

    Did you try providing floats in the matrix, not integers?

  15. S

    Now it's running. It didn't like the numpy matrix

    
    matrix = [
    
        [1., 0., 0., 0.],
    
        [0., 1., 0., 0.],
    
        [0., 0., 1., 0.],
    
        [0., 0., 0., 1.],
    
    ]
    

    Now I have a IfcHalfSpaceSolid. How do i "apply" it to my beam?

  16. R

    @Moult awsome text, tanks. Just a question about Mesh representations : in BlenderBIM we just have Tessellations, right? Btw when I export/re-import an IFC, all flat surfaces are transformed into a set of triangles, and I have to Delete>Limited Dissolve. Am I doing something wrong, could I save it differently in the IFC ?

  17. M

    @smr02 when you do geometry.add_boolean, it applies the boolean to the representation you specify via representation = representation. That should be the beam's representation.

    @"RaphaƫlVouilloz" meshes in BBIM will become Tessellations in IFC4 and FacetedBReps in IFC2X3. Non-meshes in BBIM will stay as non-meshes (e.g. extruded profiles, etc).

    Conversion into a set of triangles is unfortunately just how IfcOpenShell auto-tessellates everything right now. It's not ideal and something @aothms will be investigating in IfcOpenShell 0.8.

  18. A

    Keep in mind that ifopsh does provide additional information. In addition to the faces sequence of ints you also have edges. This serves two purposes. In case no surfaces / volumes exist, edges may provide line segment (e.g annotation, grid) geometries. But in case of non-empty faces, edges will provide the triangle edges which are also edges in the BRep model. So in principle you can dissolve exactly those edges. With one caveat though, that in the BRep model faces can be curved. So you shouldn't dissolve the edges in between of two triangles with different normal vecs.

  19. S

    @Moult thank you.

    
    matrix = np.eye(4)
    
    matrix = ifcopenshell.util.placement.rotation(30, "Y") @ matrix
    
    matrix[:,3][0:3] = (0, 0, 1)
    
    matrix = matrix.tolist()
    
    ifcopenshell.api.run(
    
            "geometry.add_boolean", 
    
            model, 
    
            representation = beam.Representation.Representations[0],
    
            # # IfcHalfSpaceSolid, Mesh
    
            type = "IfcHalfSpaceSolid",
    
            # # The XY plane is the clipping boundary and +Z is removed.
    
            matrix = matrix,  # A matrix to define a clipping Ifchalfspacesolid.
    
        )
    

    beam.Representation.Representations[0] is probably not the best way, in case there are multiple representations?

    How do i now extend the beam to the clipping plane?

  20. S

    When i try do extend the beam created with my above code into blenderBim, I get the following error:

    
    Traceback (most recent call last):
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/tool/ifc.py", line 186, in execute
    
        IfcStore.execute_ifc_operator(self, context)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/ifc.py", line 334, in execute_ifc_operator
    
        result = getattr(operator, "_execute")(context)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/module/model/profile.py", line 842, in _execute
    
        joiner.set_depth(obj, self.depth)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/module/model/profile.py", line 304, in set_depth
    
        self.recreate_profile(element1, profile1, axis, body)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/module/model/profile.py", line 443, in recreate_profile
    
        new_body = ifcopenshell.api.run(
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/__init__.py", line 66, in run
    
        result = usecase_class(ifc_file, **settings).execute()
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_profile_representation.py", line 44, in execute
    
        [self.create_item()],
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_profile_representation.py", line 60, in create_item
    
        return self.apply_clippings(extrusion)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_profile_representation.py", line 66, in apply_clippings
    
        if clipping["operand_type"] == "IfcHalfSpaceSolid":
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/entity_instance.py", line 245, in __getitem__
    
        if key < 0 or key >= len(self):
    
    TypeError: '<' not supported between instances of 'str' and 'int'
    
    Error: Python: Traceback (most recent call last):
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/tool/ifc.py", line 186, in execute
    
        IfcStore.execute_ifc_operator(self, context)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/ifc.py", line 334, in execute_ifc_operator
    
        result = getattr(operator, "_execute")(context)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/module/model/profile.py", line 842, in _execute
    
        joiner.set_depth(obj, self.depth)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/module/model/profile.py", line 304, in set_depth
    
        self.recreate_profile(element1, profile1, axis, body)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/bim/module/model/profile.py", line 443, in recreate_profile
    
        new_body = ifcopenshell.api.run(
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/__init__.py", line 66, in run
    
        result = usecase_class(ifc_file, **settings).execute()
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_profile_representation.py", line 44, in execute
    
        [self.create_item()],
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_profile_representation.py", line 60, in create_item
    
        return self.apply_clippings(extrusion)
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/api/geometry/add_profile_representation.py", line 66, in apply_clippings
    
        if clipping["operand_type"] == "IfcHalfSpaceSolid":
    
      File "/home/smr/.config/blender/3.6/scripts/addons/blenderbim/libs/site/packages/ifcopenshell/entity_instance.py", line 245, in __getitem__
    
        if key < 0 or key >= len(self):
    
    TypeError: '<' not supported between instances of 'str' and 'int'
    
  21. M

    @aothms oh wow! I have absolutely no idea that behaviour existed! Since when? Since always? This changes EVERYTHING! https://github.com/IfcOpenShell/IfcOpenShell/commit/1c74147d896f35ab250aa84bdb7fe3e7d7e04d4f

    @smr02 You'll either need to move your clipping plane down or increase the depth of your beam extrusion. You'll need to work out the math for this necessary depth yourself - we don't have any generic utils for calculating this.

    Can you share your IFC? Potentially it's a bug.

  22. S

    Here is my IFC file.

    I can change the depth of the extrusion with `

    representation.Items[0].Depth = 1500` in one direction.

    How do i change it in the opposite direction?

  23. M
  24. M

    @smr02 there is no "opposite direction", there is the start of the profile, then an extrusion depth. So you can change the object placement to change the start (or instead, just move your clipping plane).

  25. C

    This is great info. and very digestible for non-coders. Really appreciate the effort pulling it together. We often receive over detailed mesh representations so good to understand how these are handled by ifcopenshell, next step is to work out how to batch simplify these meshes...

  1. Page 1
  2. 2

Login or Register to reply.