I have a model with a number of IfcSpaces with Physical 2ndLevel IfcRelSpaceBoundaries and would like to visualize them in BlenderBIM as External or Internal with different color and wonder if anybody knows how to do this?
/Max
I have a model with a number of IfcSpaces with Physical 2ndLevel IfcRelSpaceBoundaries and would like to visualize them in BlenderBIM as External or Internal with different color and wonder if anybody knows how to do this?
/Max
Chatgpt to the rescue... not vetted
import bpy
import ifcopenshell
# Load the IFC file
filename = "path/to/your/ifc/file.ifc"
ifc_file = ifcopenshell.open(filename)
# Get all IfcSpaces with Physical 2ndLevel IfcRelSpaceBoundaries
spaces = ifc_file.by_type("IfcSpace")
physical_spaces = []
for space in spaces:
if space.Representation:
for rep in space.Representation.Representations:
if rep.RepresentationIdentifier == "Body" and rep.RepresentationType == "SweptSolid":
if space.is_a("IfcSpace") and space.ElementType and space.ElementType.is_a("IfcSpaceType") and space.ElementType.PredefinedType == "INTERNAL":
physical_spaces.append(space)
elif space.is_a("IfcSpace") and space.ElementType and space.ElementType.is_a("IfcSpaceType") and space.ElementType.PredefinedType == "EXTERNAL":
physical_spaces.append(space)
# Create two materials for internal and external spaces
internal_material = bpy.data.materials.new("Internal")
external_material = bpy.data.materials.new("External")
# Set the diffuse colors for the materials
internal_material.diffuse_color = (0.8, 0.8, 0.8) # gray
external_material.diffuse_color = (0.0, 0.0, 1.0) # blue
# Assign materials to IfcSpaces based on their InternalOrExternalBoundary property
for space in physical_spaces:
if space.InternalOrExternalBoundary == "INTERNAL":
space_object = bpy.data.objects[space.GlobalId]
space_object.data.materials.append(internal_material)
elif space.InternalOrExternalBoundary == "EXTERNAL":
space_object = bpy.data.objects[space.GlobalId]
space_object.data.materials.append(external_material)
@theoryshaw
Tried to run the script on the Schependomlaan converted to IFC4, because it has a lot of spaces.
got this error.
AttributeError: entity instance of type 'IFC4.IfcSpace' has no attribute 'ElementType'
Looking at the code at first glance, it seems chatGPT does not understand what an IfcRelSpaceBoundary is.
Documentation
Would like to see an IFC which has IfcSpace boundaries, I don't think Schependomlaam.ifc has them?
I got the same error for an IFC2x3.
AttributeError: entity instance of type 'IFC2X3.IfcSpace' has no attribute 'ElementType'
@Max
Is it possible to share your IFC or maybe some similar example?
One example
https://gitlab.com/osarch/FreeMVD_WorkFlow/-/tree/master/Random_Tests/IfcRelSpaceBoundary
Here is one example IFC 2x3
https://github.com/maxtillberg/ICEBridge/blob/main/RAC_basic_sample_project_spaces.ifc
wow!, I just discovered you can select them with blenderBIM:
@Max I totally missed this topic… yes you can using IfcSelection
Do not hesitate to tag me next time you have a question on this topic.
I need to export the IfcSpaces as 3D CAD-objects (3DS) with unique colors for each face based upon IfcRelSpaceboundary (and if possible wall/slabtype) , prefarable using Python and wonder if anybody could point me in the right direction?
@Max have you looked at https://docs.blender.org/manual/en/dev/addons/import_export/scene_3ds.html ?
I'd recommend looping through each IfcRelSpaceBoundary, finding its Blender object, then clearing its material slots, adding a new material with a random colour, then assigning it as the only material slot.
f = blenderbim.tool.Ifc.get()
boundaries = f.by_type("IfcRelSpaceBoundary")
for boundary in boundaries:
obj = blenderbim.tool.Ifc.get_object(boundary)
if not obj:
pass # load it in, or ignore? What's your usecase?
while obj.material_slots:
bpy.ops.object.material_slot_remove()
mat = bpy.data.materials.new('Foo')
mat.diffuse_color = (1,0,0,1) # Or random colour, or cycled colours, etc
obj.data.materials.append(mat)
Thanks a lot @Moult that helped a lot. I have a model ( the default Revit demo file) found at https://github.com/maxtillberg/ICEBridge/blob/main/RAC_basic_sample_project_spaces.ifc that contains boundaries but the objects contains "None" when I try the code and I wonder if this is due to this example? Also I would need to separate External and Internal boundaries with code.
/Max
@Max the obj
variable is probably none because it isn't loaded into Blender yet. By default space boundaries are not loaded and only loaded on demand.
The loader is in a bit of a weird place (it should be moved to a tool function) so it's a bit awkward but you can do this to load in all space boundaries (alternatively you can choose which ones you're interested in):
import blenderbim.bim.module.boundary.operator
loader = blenderbim.bim.module.boundary.operator.Loader()
for rel in tool.Ifc.get().by_type("IfcRelSpaceBoundary"):
loader.load_boundary(rel, tool.Ifc.get_object(rel.RelatingSpace))
Thanks a lot @Moult , that explained a lot and now the code works perfectly. While I am at it I would like to add some more color features, preferable color IfcRelSpaceBoundaries according to InternalOrExternalBoundary, PhysicalOrVirtual, RelatingSpace and RelatedBuildingElement (IfcWindow, IfcWall, IfcSlab...) and wonder if you know how to do this.
@Max what's the issue? You can create your own colour map based on those properties via a dictionary and using a cycle to create the keys.
The main issue is that I am still trying to learn Python, Blender, BlenderBIM, IFC and IfcOpenShell.
Login or Register to reply.