IfcOpenshell: How to: an IfcBeamTypeInstance using an IfcProfile with IfcParametrizedProfileDef?
My attempt has been as following:
1. Tried to create an IfcProfile using ifcopenshell.api
.
Looked here:
https://sourcegraph.com/search?q=context:global+profile+repo:^github\.com/IfcOpenShell/IfcOpenShell$+file:src/ifcopenshell-python&patternType=standard
Read the BS documentation:
https://standards.buildingsmart.org/IFC/DEV/IFC4_3/RC2/HTML/schema/ifcmaterialresource/lexical/ifcmaterialprofile.htm
2) Tried to create a IfcBeamType instance with IfcMaterial:
import ifcopenshell.api
element_name='my_beam'
ifc_file = ifcopenshell.api.run("project.create_file")
project = ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class="IfcProject", name="BlenderBIM Demo")
ifcopenshell.api.run( "project.assign_declaration", ifc_file, definition=project, relating_context=project)
ifcopenshell.api.run("unit.assign_unit", ifc_file, length={"is_metric": True, "raw": "METERS"})
material = ifcopenshell.api.run("material.add_material", ifc_file, name='beam_material')
element = ifcopenshell.api.run("root.create_entity", ifc_file, ifc_class='IfcBeamType', name=element_name)
profile_1 = ifcopenshell.api.run("material.assign_material", ifc_file, product=element, type="IfcMaterialProfileSetUsage")
profile_set = profile_1.RelatingMaterial
profile_2 = ifc_file.create_entity("IfcMaterialProfile")
ifcopenshell.api.run("project.assign_declaration", ifc_file, definition=element, relating_context=project)
ifc_file.write("D:\\02_ifc\\ifc_bibliotheek\\" + str(element_name) + ".ifc")
Quite clueless on how to tie it all together, this script just outputs this:
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1');
FILE_NAME('/dev/null','2022-11-06T11:31:03+01:00',(),(),'IfcOpenShell v0.7.0-cdde5366','IfcOpenShell v0.7.0-cdde5366','Nobody');
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
#1=IFCPROJECT('3NWCe2Fg16oO7d$m1LJcmY',$,'BlenderBIM Demo',$,$,$,$,$,#6);
#2=IFCRELDECLARES('0WOKmCVaz6$QsPWDCFj_FP',$,$,$,#1,(#8,#1));
#3=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
#4=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#5=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#6=IFCUNITASSIGNMENT((#4,#5,#3));
#7=IFCMATERIAL('beam_material',$,$);
#8=IFCBEAMTYPE('2CPnfvwOT6O9ZQyImvzlxU',$,'my_beam',$,$,$,$,$,$,.NOTDEFINED.);
#9=IFCMATERIALPROFILESET($,$,$,$);
#10=IFCMATERIALPROFILESETUSAGE(#9,$,$);
#11=IFCRELASSOCIATESMATERIAL('0LU7BOA5v1h9_90260WfJ0',$,$,$,(#8),#10);
#12=IFCMATERIALPROFILE($,$,$,$,$,$);
ENDSEC;
END-ISO-10303-21;
Somehow I need to define the IfcParametrizedProfileDef somewhere, hardcoded the X and Y dimensions, say to the IfcBeamType instance, you are now using an IfcProfile..
Is there a very simple example script somewhere?
Comments
This might help:
https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.7.0/src/blenderbim/scripts/generate_demo_library.py
and also:
https://github.com/IfcOpenShell/IfcOpenShell/blob/v0.7.0/src/blenderbim/scripts/generate_steel_profiles_library.py
@theoryshaw
Thanks! I was looking for that, finally I understand it,
outputs:
In BlenderBIM:

How to add an IfcType instance with python?
not sure, does this help? https://github.com/IfcOpenShell/IfcOpenShell/blob/cbd9c898c37bb44500bf3be39c87241cfd8a4fe1/src/blenderbim/blenderbim/bim/module/model/profile.py#L142-L189
You're almost there, you're just missing at the end:
Also you can do this which is simpler:
Don't use
project.assign_declaration
it is not necessary, you can delete every line that uses that. That's only used for asset library declarations.@Moult
Thanks! how would I place the IfcElementType instance using XYZ coordinates?
Use geometry.edit_object_placement.
@Moult
Thank you. :-)
What does
depth=3
do inifcopenshell.api.run("geometry.add_profile_representation", ifc_file, context=contexts["body"], profile=profile, depth=3)
?And where is
contexts
defined inrepresentation = ifcopenshell.api.run("geometry.add_profile_representation", ifc_file, context=contexts["body"], profile=profile, depth=3)
I changed this line

ifcopenshell.api.run("geometry.add_profile_representation", ifc_file, context=contexts["body"], profile=profile, depth=3)
to
representation = ifcopenshell.api.run("geometry.add_profile_representation", ifc_file, context=representations["body"], profile=profile, depth=3)
I have not defined an IfcBuildingStorey to place the beam in, but for some strange reason, when loading the created IFC in BlenderBIM my beam appears vertical:
How do I add an IfcBuilding, IfcSite and IfcBuildingStorey using the ifcopenshell.api?
I know i can do it with IfcOpenShell like following:
Not really clear to me how to translate this to the ifcopenshell.api
EDIT:
found it here in @Martin156131 thread:
https://community.osarch.org/discussion/1221/ifcopenshell-python-how-using-the-objectplacement-in-ifcwall#latest
I have a working script, still need to figure out how to place the IfcElement correctly

Script to be found here:
https://github.com/C-Claus/BlenderScripts/blob/master/BlenderBIM_create_objects/create_beam.py
This thread... I should just have went straight here: https://blenderbim.org/docs-python/ifcopenshell-python/code_examples.html#create-a-simple-model-from-scratch

The beam is vertical because all extrusions in IFC have the convention of extruding in the local Z axis. This is an awesome convention and makes a huge difference in the reliability of geometric analysis. So if you want the beam to be flat, just edit its ObjectPlacement matrix.
@Moult, thanks, never worked with numpy arrays, need to figure it out first.
Where is the length of the IfcBeamType instance defined in the ifcopenshell.api? Can't find it in the example scripts or documentation.
The length is called
depth=3
in theadd_profile_representation
call.The matrix is a 4x4 matrix described here https://blenderbim.org/docs-python/ifcopenshell-python/geometry_processing.html#individual-processing
Yes, horizontal beam! @Moult Thanks for patiently answering all my ignorant questions.
Getting the hang of it now
Okay, this is a lot of fun, paramatric foundation beam system.. code is a mess now, but it works.

Next step, slab and walls.
EDIT:
https://github.com/C-Claus/BlenderScripts/blob/master/BlenderBIM_create_objects/create_beam_array.py
Also the beams should align neatly now within their constraint when changing the profile.
It all should work with only 5 config variables,:
If you can get the code working with an arbitrary polygonal profile (i.e. not only rectangular), then that would be super cool and we could reuse your code for a feature for exactly that.
I will attempt
It seems we are set on a very similar journey currently @Coen. I've been reading your different endeavours with great interest, and I'd like to thank you for documenting it so thorougly. I've still got lots to learn, and it's great fun to see others taking baby steps around me :)
The example demo is great but I think we can do more, there are in fact a lot of hidden snippets in the codebase, it would be nice to document them a bit more in depth. I'll do what I can to help :)
@Gorgious
Thanks for the kind words. There's a lot of knowledge on this forum. Many people here know how to point you in the right direction, so I don't drown in reading boring documentation. I'd like to document it together somewhere in a coherent way with fun little practical code snippets. Just curious where there's a demand. Because most of the stuff I document I do it for myself.
Is it possible to miter two beams with IfcOpenShell?
@Coen I think all that stuff is in the blenderbim Cad module, I would very much like to see it moved into the IfcOpenShell API.
First attempt with an I profile,


I think I need to use the predefined profiles from the EU demo library exactly for this purpose.
I was having fun and also decided to add columns
Just curious now how one would no would miter all these beams with python.
Where is the described what the feature should do exactly?