Difference approaches using ifcopenshell

Hello everyone,

I just started getting familiar with ifcopenshell and during my research I was wondering about two different approaches that I found.
I want to convert Three.js geometry likes boxes to IFC using ifcopenshell and found two good examples that both use ifcopenshell but have completely different approaches.
One using ifcopenshell
And the other using ifcopenshell.api

Could you tell me what's the difference and which one would make more sense to use?

I personally like the way of using createIfcAxis2Placement3D to place objects but couldn't find most of the methods that were used in that example in the documentation.

Best,

Niklas

Comments

  • Definitely use the API where possible. The first link is from 2015 when the API didn't exist.

    The shape_builder utility is also recommended if you want to construct custom solid geometry https://blenderbim.org/docs-python/autoapi/ifcopenshell/util/shape_builder/index.html whereas https://blenderbim.org/docs-python/autoapi/ifcopenshell/api/geometry/add_sverchok_representation/index.html is recommended if you're doing pure meshes.

    You don't find functions like createIfcAxis2Placement3D in the documentation because they are auto-generated. You can run createFoo where Foo is any valid IFC class such as from this list: https://standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/link/inheritance-general-usage-all entities.htm - it wouldn't make sense to duplicate the entire buildingSMART docs. This is synonymous with https://blenderbim.org/docs-python/autoapi/ifcopenshell/file/index.html#ifcopenshell.file.file.create_entity

    HQue
  • Thanks @Moult

    The shape_builder utility looks great
    Even though I have some hard time understanding how to use it properly to create IFCWall and IFCSlab since I apparently can't use the IfcExtrudedAreaSolid to create a wall representation.

    How would I go for this or are there any examples to look at?

    builder = ifcopenshell.util.shape_builder.ShapeBuilder(ifcfile)
    points = [(1.0, 1.0), (2.0, 2.0), (5.0, 1.0)]
    profile_or_curve = builder.polyline(points)
    wall = ifcopenshell.api.run("root.create_entity", ifcfile, ifc_class="IfcWall")
    extruded_solid = builder.extrude(profile_or_curve, magnitude=2.0, position=mathutils.Vector((1.0, 2.0, 5.0)), extrusion_vector=mathutils.Vector((0.0, 0.0, 1.0)))
    
  • Here's an example: https://github.com/IfcOpenShell/IfcOpenShell/discussions/3260#discussioncomment-6108102

    In short after you build your shape with the shape builder, turn it into a representation with get_representation() then run the geometry.assign_representation API.

    HQue
  • That worked perfectly! Thank you!

    I'd have one last question regarding this one:
    How is it possible using "pure meshes"?
    I want to create a terrain in the IFC-file and therefor I have a terrain mesh represented by vertices and indices.

    How can I use the ifcopenshell.api.geometry.add_sverchok_representation() function you mentioned to create the IFC terrain similar to this one:
    https://cvillagrasa.github.io/IfcOpenHouse/generation.html#creating-the-terrain-as-a-nurbs-surface

  • This is the constructor of add_sverchok_representation:

        def __init__(self, file, **settings):
            self.file = file
            self.settings = {
                "context": None,  # IfcGeometricRepresentationContext
                # Vertices, edges, and faces are given in the form of: [item1, item2, item3, ...]
                # ... where itemN = [(0., 0., 0.), (1., 1., 1.), (x, y, z), ...]
                "vertices": None,  # A list of coordinates
                # ... where itemN = [(0, 1), (1, 2), (v1, v2), ...]
                "edges": None,  # A list of edges, represented by vertex index pairs
                # ... where itemN = [(0, 1, 2), (5, 4, 2, 3), (v1, v2, v3, ... vN), ...]
                "faces": None,  # A list of polygons, represented by vertex indices
                "coordinate_offset": None,  # Optionally apply a vector offset to all coordinates
                "unit_scale": None,  # A scale factor to apply for all vectors in case the unit is different
            }
            for key, value in settings.items():
                self.settings[key] = value
    

    So you can do something like:

    verts =  [(0., 0., 0.), (1., 1., 1.), (x, y, z), ...]
    faces = [(0, 1, 2), (5, 4, 2, 3), (v1, v2, v3, ... vN), ...]
    run("geometry.add_sverchok_representation", model, context=body, vertices=verts, faces=faces)
    
    HQue
Sign In or Register to comment.