mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 22:33:33 +00:00
#2111 New feature to select by style and see style usage
This commit is contained in:
@@ -92,8 +92,10 @@ class ObjectMaterialData:
|
|||||||
element_type = ifcopenshell.util.element.get_type(element)
|
element_type = ifcopenshell.util.element.get_type(element)
|
||||||
if element_type != element:
|
if element_type != element:
|
||||||
material = ifcopenshell.util.element.get_material(element_type)
|
material = ifcopenshell.util.element.get_material(element_type)
|
||||||
|
if not material:
|
||||||
|
return
|
||||||
if material.is_a() in ("IfcMaterialLayerSetUsage", "IfcMaterialLayerSet"):
|
if material.is_a() in ("IfcMaterialLayerSetUsage", "IfcMaterialLayerSet"):
|
||||||
name_attr = "LayerSetName"
|
name_attr = "LayerSetName"
|
||||||
else:
|
else:
|
||||||
name_attr = "Name"
|
name_attr = "Name"
|
||||||
return getattr(material, name_attr, "Unnamed")
|
return getattr(material, name_attr, "Unnamed") or "Unnamed"
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ classes = (
|
|||||||
operator.EnableEditingStyle,
|
operator.EnableEditingStyle,
|
||||||
operator.LoadStyles,
|
operator.LoadStyles,
|
||||||
operator.RemoveStyle,
|
operator.RemoveStyle,
|
||||||
|
operator.SelectByStyle,
|
||||||
operator.UnlinkStyle,
|
operator.UnlinkStyle,
|
||||||
operator.UpdateStyleColours,
|
operator.UpdateStyleColours,
|
||||||
operator.UpdateStyleTextures,
|
operator.UpdateStyleTextures,
|
||||||
|
|||||||
@@ -24,14 +24,7 @@ import ifcopenshell.util.representation
|
|||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
|
||||||
|
|
||||||
class Operator:
|
class UpdateStyleColours(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
def execute(self, context):
|
|
||||||
IfcStore.execute_ifc_operator(self, context)
|
|
||||||
blenderbim.bim.handler.refresh_ui_data()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateStyleColours(bpy.types.Operator, Operator):
|
|
||||||
bl_idname = "bim.update_style_colours"
|
bl_idname = "bim.update_style_colours"
|
||||||
bl_label = "Update Style Colours"
|
bl_label = "Update Style Colours"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -40,7 +33,7 @@ class UpdateStyleColours(bpy.types.Operator, Operator):
|
|||||||
core.update_style_colours(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
core.update_style_colours(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
||||||
|
|
||||||
|
|
||||||
class UpdateStyleTextures(bpy.types.Operator, Operator):
|
class UpdateStyleTextures(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.update_style_textures"
|
bl_idname = "bim.update_style_textures"
|
||||||
bl_label = "Update Style Textures"
|
bl_label = "Update Style Textures"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -55,7 +48,7 @@ class UpdateStyleTextures(bpy.types.Operator, Operator):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class RemoveStyle(bpy.types.Operator, Operator):
|
class RemoveStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.remove_style"
|
bl_idname = "bim.remove_style"
|
||||||
bl_label = "Remove Style"
|
bl_label = "Remove Style"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -65,7 +58,7 @@ class RemoveStyle(bpy.types.Operator, Operator):
|
|||||||
core.remove_style(tool.Ifc, tool.Material, tool.Style, style=tool.Ifc.get().by_id(self.style))
|
core.remove_style(tool.Ifc, tool.Material, tool.Style, style=tool.Ifc.get().by_id(self.style))
|
||||||
|
|
||||||
|
|
||||||
class AddStyle(bpy.types.Operator, Operator):
|
class AddStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.add_style"
|
bl_idname = "bim.add_style"
|
||||||
bl_label = "Add Style"
|
bl_label = "Add Style"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -74,7 +67,7 @@ class AddStyle(bpy.types.Operator, Operator):
|
|||||||
core.add_style(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
core.add_style(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
||||||
|
|
||||||
|
|
||||||
class UnlinkStyle(bpy.types.Operator, Operator):
|
class UnlinkStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.unlink_style"
|
bl_idname = "bim.unlink_style"
|
||||||
bl_label = "Unlink Style"
|
bl_label = "Unlink Style"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -83,7 +76,7 @@ class UnlinkStyle(bpy.types.Operator, Operator):
|
|||||||
core.unlink_style(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
core.unlink_style(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingStyle(bpy.types.Operator, Operator):
|
class EnableEditingStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.enable_editing_style"
|
bl_idname = "bim.enable_editing_style"
|
||||||
bl_label = "Enable Editing Style"
|
bl_label = "Enable Editing Style"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -92,7 +85,7 @@ class EnableEditingStyle(bpy.types.Operator, Operator):
|
|||||||
core.enable_editing_style(tool.Style, obj=context.active_object.active_material)
|
core.enable_editing_style(tool.Style, obj=context.active_object.active_material)
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingStyle(bpy.types.Operator, Operator):
|
class DisableEditingStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.disable_editing_style"
|
bl_idname = "bim.disable_editing_style"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_label = "Disable Editing Style"
|
bl_label = "Disable Editing Style"
|
||||||
@@ -101,7 +94,7 @@ class DisableEditingStyle(bpy.types.Operator, Operator):
|
|||||||
core.disable_editing_style(tool.Style, obj=context.active_object.active_material)
|
core.disable_editing_style(tool.Style, obj=context.active_object.active_material)
|
||||||
|
|
||||||
|
|
||||||
class EditStyle(bpy.types.Operator, Operator):
|
class EditStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.edit_style"
|
bl_idname = "bim.edit_style"
|
||||||
bl_label = "Edit Style"
|
bl_label = "Edit Style"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -110,7 +103,7 @@ class EditStyle(bpy.types.Operator, Operator):
|
|||||||
core.edit_style(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
core.edit_style(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingStyles(bpy.types.Operator, Operator):
|
class DisableEditingStyles(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.disable_editing_styles"
|
bl_idname = "bim.disable_editing_styles"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
bl_label = "Disable Editing Styles"
|
bl_label = "Disable Editing Styles"
|
||||||
@@ -119,7 +112,7 @@ class DisableEditingStyles(bpy.types.Operator, Operator):
|
|||||||
core.disable_editing_styles(tool.Style)
|
core.disable_editing_styles(tool.Style)
|
||||||
|
|
||||||
|
|
||||||
class LoadStyles(bpy.types.Operator, Operator):
|
class LoadStyles(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.load_styles"
|
bl_idname = "bim.load_styles"
|
||||||
bl_label = "Load Styles"
|
bl_label = "Load Styles"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -127,3 +120,13 @@ class LoadStyles(bpy.types.Operator, Operator):
|
|||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
core.load_styles(tool.Style, style_type=self.style_type)
|
core.load_styles(tool.Style, style_type=self.style_type)
|
||||||
|
|
||||||
|
|
||||||
|
class SelectByStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
|
bl_idname = "bim.select_by_style"
|
||||||
|
bl_label = "Select By Material"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
style: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
core.select_by_style(tool.Style, style=tool.Ifc.get().by_id(self.style))
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ class BIM_PT_styles(Panel):
|
|||||||
#row.operator("bim.add_presentation_style", text="", icon="ADD")
|
#row.operator("bim.add_presentation_style", text="", icon="ADD")
|
||||||
if self.props.styles and self.props.active_style_index < len(self.props.styles):
|
if self.props.styles and self.props.active_style_index < len(self.props.styles):
|
||||||
style = self.props.styles[self.props.active_style_index]
|
style = self.props.styles[self.props.active_style_index]
|
||||||
# op = row.operator("bim.select_by_style", text="", icon="RESTRICT_SELECT_OFF")
|
op = row.operator("bim.select_by_style", text="", icon="RESTRICT_SELECT_OFF")
|
||||||
# op.style = style.ifc_definition_id
|
op.style = style.ifc_definition_id
|
||||||
row.operator("bim.remove_style", text="", icon="X").style = style.ifc_definition_id
|
row.operator("bim.remove_style", text="", icon="X").style = style.ifc_definition_id
|
||||||
|
|
||||||
self.layout.template_list("BIM_UL_styles", "", self.props, "styles", self.props, "active_style_index")
|
self.layout.template_list("BIM_UL_styles", "", self.props, "styles", self.props, "active_style_index")
|
||||||
@@ -138,6 +138,6 @@ class BIM_UL_styles(UIList):
|
|||||||
if item:
|
if item:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text=item.name)
|
row.label(text=item.name)
|
||||||
#row2 = row.row()
|
row2 = row.row()
|
||||||
#row2.alignment = "RIGHT"
|
row2.alignment = "RIGHT"
|
||||||
#row2.label(text=str(item.total_elements))
|
row2.label(text=str(item.total_elements))
|
||||||
|
|||||||
@@ -110,3 +110,7 @@ def load_styles(style, style_type=None):
|
|||||||
|
|
||||||
def disable_editing_styles(style):
|
def disable_editing_styles(style):
|
||||||
style.disable_editing_styles()
|
style.disable_editing_styles()
|
||||||
|
|
||||||
|
|
||||||
|
def select_by_style(style_tool, style=None):
|
||||||
|
style_tool.select_elements(style_tool.get_elements_by_style(style))
|
||||||
|
|||||||
@@ -443,6 +443,7 @@ class Style:
|
|||||||
def export_surface_attributes(cls, obj): pass
|
def export_surface_attributes(cls, obj): pass
|
||||||
def get_active_style_type(cls): pass
|
def get_active_style_type(cls): pass
|
||||||
def get_context(cls, obj): pass
|
def get_context(cls, obj): pass
|
||||||
|
def get_elements_by_style(cls, style): pass
|
||||||
def get_name(cls, obj): pass
|
def get_name(cls, obj): pass
|
||||||
def get_style(cls, obj): pass
|
def get_style(cls, obj): pass
|
||||||
def get_surface_rendering_attributes(cls, obj): pass
|
def get_surface_rendering_attributes(cls, obj): pass
|
||||||
@@ -454,6 +455,7 @@ class Style:
|
|||||||
def import_presentation_styles(cls, style_type): pass
|
def import_presentation_styles(cls, style_type): pass
|
||||||
def import_surface_attributes(cls, style, obj): pass
|
def import_surface_attributes(cls, style, obj): pass
|
||||||
def is_editing_styles(cls): pass
|
def is_editing_styles(cls): pass
|
||||||
|
def select_elements(cls, elements): pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class Material(blenderbim.core.tool.Material):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_elements_by_material(cls, material):
|
def get_elements_by_material(cls, material):
|
||||||
return set(ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material))
|
return ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_name(cls, obj):
|
def get_name(cls, obj):
|
||||||
@@ -75,13 +75,13 @@ class Material(blenderbim.core.tool.Material):
|
|||||||
new = props.materials.add()
|
new = props.materials.add()
|
||||||
new.ifc_definition_id = material.id()
|
new.ifc_definition_id = material.id()
|
||||||
new.name = get_name(material)
|
new.name = get_name(material)
|
||||||
new.total_elements = len(set(ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material)))
|
new.total_elements = len(ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material))
|
||||||
else:
|
return
|
||||||
for material in materials:
|
for material in materials:
|
||||||
new = props.materials.add()
|
new = props.materials.add()
|
||||||
new.ifc_definition_id = material.id()
|
new.ifc_definition_id = material.id()
|
||||||
new.name = get_name(material)
|
new.name = get_name(material)
|
||||||
new.total_elements = len(set(ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material)))
|
new.total_elements = len(ifcopenshell.util.element.get_elements_by_material(tool.Ifc.get(), material))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_editing_materials(cls):
|
def is_editing_materials(cls):
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ class Style(blenderbim.core.tool.Style):
|
|||||||
def get_context(cls, obj):
|
def get_context(cls, obj):
|
||||||
return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_elements_by_style(cls, style):
|
||||||
|
return ifcopenshell.util.element.get_elements_by_style(tool.Ifc.get(), style)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_name(cls, obj):
|
def get_name(cls, obj):
|
||||||
return obj.name
|
return obj.name
|
||||||
@@ -188,6 +192,7 @@ class Style(blenderbim.core.tool.Style):
|
|||||||
new = props.styles.add()
|
new = props.styles.add()
|
||||||
new.ifc_definition_id = style.id()
|
new.ifc_definition_id = style.id()
|
||||||
new.name = style.Name or "Unnamed"
|
new.name = style.Name or "Unnamed"
|
||||||
|
new.total_elements = len(ifcopenshell.util.element.get_elements_by_style(tool.Ifc.get(), style))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def import_surface_attributes(cls, style, obj):
|
def import_surface_attributes(cls, style, obj):
|
||||||
@@ -197,3 +202,10 @@ class Style(blenderbim.core.tool.Style):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def is_editing_styles(cls):
|
def is_editing_styles(cls):
|
||||||
return bpy.context.scene.BIMStylesProperties.is_editing
|
return bpy.context.scene.BIMStylesProperties.is_editing
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def select_elements(cls, elements):
|
||||||
|
for element in elements:
|
||||||
|
obj = tool.Ifc.get_object(element)
|
||||||
|
if obj:
|
||||||
|
obj.select_set(True)
|
||||||
|
|||||||
@@ -75,3 +75,13 @@ Scenario: Disable editing styles
|
|||||||
And I press "bim.load_styles(style_type='IfcSurfaceStyle')"
|
And I press "bim.load_styles(style_type='IfcSurfaceStyle')"
|
||||||
When I press "bim.disable_editing_style"
|
When I press "bim.disable_editing_style"
|
||||||
Then nothing happens
|
Then nothing happens
|
||||||
|
|
||||||
|
Scenario: Select by style
|
||||||
|
Given an empty IFC project
|
||||||
|
And I add a cube
|
||||||
|
And I add a material
|
||||||
|
And I press "bim.add_style"
|
||||||
|
And I press "bim.load_styles(style_type='IfcSurfaceStyle')"
|
||||||
|
And the variable "style" is "{ifc}.by_type('IfcSurfaceStyle')[0].id()"
|
||||||
|
When I press "bim.select_by_style(style={style})"
|
||||||
|
Then nothing happens
|
||||||
|
|||||||
@@ -95,6 +95,20 @@ class TestGetContext(NewFile):
|
|||||||
assert subject.get_context("obj") == context
|
assert subject.get_context("obj") == context
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetElementsByStyle(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||||
|
style = ifc.createIfcSurfaceStyle()
|
||||||
|
item = ifc.createIfcExtrudedAreaSolid()
|
||||||
|
ifc.createIfcStyledItem(Item=item, Styles=[style])
|
||||||
|
element.Representation = ifc.createIfcProductDefinitionShape(
|
||||||
|
Representations=[ifc.createIfcShapeRepresentation(Items=[item])]
|
||||||
|
)
|
||||||
|
assert subject.get_elements_by_style(style) == {element}
|
||||||
|
|
||||||
|
|
||||||
class TestGetName(NewFile):
|
class TestGetName(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
assert subject.get_name(bpy.data.materials.new("Material")) == "Material"
|
assert subject.get_name(bpy.data.materials.new("Material")) == "Material"
|
||||||
@@ -426,3 +440,15 @@ class TestIsEditingStyles(NewFile):
|
|||||||
subject.is_editing_styles() is False
|
subject.is_editing_styles() is False
|
||||||
bpy.context.scene.BIMStylesProperties.is_editing = True
|
bpy.context.scene.BIMStylesProperties.is_editing = True
|
||||||
subject.is_editing_styles() is True
|
subject.is_editing_styles() is True
|
||||||
|
|
||||||
|
|
||||||
|
class TestSelectElements(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
tool.Ifc().set(ifc)
|
||||||
|
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcPump")
|
||||||
|
obj = bpy.data.objects.new("Object", None)
|
||||||
|
bpy.context.scene.collection.objects.link(obj)
|
||||||
|
tool.Ifc.link(element, obj)
|
||||||
|
subject.select_elements([element])
|
||||||
|
assert obj in bpy.context.selected_objects
|
||||||
|
|||||||
@@ -134,25 +134,65 @@ def get_material(element, should_skip_usage=False):
|
|||||||
|
|
||||||
|
|
||||||
def get_elements_by_material(ifc_file, material):
|
def get_elements_by_material(ifc_file, material):
|
||||||
results = []
|
results = set()
|
||||||
for inverse in ifc_file.get_inverse(material):
|
for inverse in ifc_file.get_inverse(material):
|
||||||
if inverse.is_a("IfcRelAssociatesMaterial"):
|
if inverse.is_a("IfcRelAssociatesMaterial"):
|
||||||
results.extend(inverse.RelatedObjects)
|
results.update(inverse.RelatedObjects)
|
||||||
elif inverse.is_a("IfcMaterialLayer"):
|
elif inverse.is_a("IfcMaterialLayer"):
|
||||||
for material_set in inverse.ToMaterialLayerSet:
|
for material_set in inverse.ToMaterialLayerSet:
|
||||||
results.extend(get_elements_by_material(ifc_file, material_set))
|
results.update(get_elements_by_material(ifc_file, material_set))
|
||||||
elif inverse.is_a("IfcMaterialProfile"):
|
elif inverse.is_a("IfcMaterialProfile"):
|
||||||
for material_set in inverse.ToMaterialProfileSet:
|
for material_set in inverse.ToMaterialProfileSet:
|
||||||
results.extend(get_elements_by_material(ifc_file, material_set))
|
results.update(get_elements_by_material(ifc_file, material_set))
|
||||||
elif inverse.is_a("IfcMaterialConstituent"):
|
elif inverse.is_a("IfcMaterialConstituent"):
|
||||||
for material_set in inverse.ToMaterialConstituentSet:
|
for material_set in inverse.ToMaterialConstituentSet:
|
||||||
results.extend(get_elements_by_material(ifc_file, material_set))
|
results.update(get_elements_by_material(ifc_file, material_set))
|
||||||
elif inverse.is_a("IfcMaterialLayerSetUsage"):
|
elif inverse.is_a("IfcMaterialLayerSetUsage"):
|
||||||
results.extend(get_elements_by_material(ifc_file, inverse))
|
results.update(get_elements_by_material(ifc_file, inverse))
|
||||||
elif inverse.is_a("IfcMaterialProfileSetUsage"):
|
elif inverse.is_a("IfcMaterialProfileSetUsage"):
|
||||||
results.extend(get_elements_by_material(ifc_file, inverse))
|
results.update(get_elements_by_material(ifc_file, inverse))
|
||||||
elif inverse.is_a("IfcMaterialList"):
|
elif inverse.is_a("IfcMaterialList"):
|
||||||
results.extend(get_elements_by_material(ifc_file, inverse))
|
results.update(get_elements_by_material(ifc_file, inverse))
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def get_elements_by_style(ifc_file, style):
|
||||||
|
results = set()
|
||||||
|
inverses = list(ifc_file.get_inverse(style))
|
||||||
|
while inverses:
|
||||||
|
inverse = inverses.pop()
|
||||||
|
if inverse.is_a("IfcPresentationStyleAssignment"):
|
||||||
|
inverses.extend(ifc_file.get_inverse(inverse))
|
||||||
|
continue
|
||||||
|
if not inverse.is_a("IfcStyledItem"):
|
||||||
|
continue
|
||||||
|
if inverse.Item:
|
||||||
|
[
|
||||||
|
results.update(get_elements_by_representation(ifc_file, i))
|
||||||
|
for i in ifc_file.get_inverse(inverse.Item)
|
||||||
|
if i.is_a("IfcShapeRepresentation")
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
styled_reps = [i for i in ifc_file.get_inverse(inverse) if i.is_a("IfcStyledRepresentation")]
|
||||||
|
for styled_rep in styled_reps:
|
||||||
|
for material_def_rep in styled_rep.OfProductRepresentation:
|
||||||
|
results.update(get_elements_by_material(ifc_file, material_def_rep.RepresentedMaterial))
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def get_elements_by_representation(ifc_file, representation):
|
||||||
|
results = set()
|
||||||
|
[results.update(pr.ShapeOfProduct) for pr in representation.OfProductRepresentation]
|
||||||
|
for rep_map in representation.RepresentationMap:
|
||||||
|
for inverse in ifc_file.get_inverse(rep_map):
|
||||||
|
if inverse.is_a("IfcTypeProduct"):
|
||||||
|
results.add(inverse)
|
||||||
|
elif inverse.is_a("IfcMappedItem"):
|
||||||
|
[
|
||||||
|
results.update(get_elements_by_representation(ifc_file, rep))
|
||||||
|
for rep in ifc_file.get_inverse(inverse)
|
||||||
|
if rep.is_a("IfcShapeRepresentation")
|
||||||
|
]
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ class TestGetElementsByMaterial(test.bootstrap.IFC4):
|
|||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
material = ifcopenshell.api.run("material.add_material", self.file)
|
material = ifcopenshell.api.run("material.add_material", self.file)
|
||||||
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material)
|
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material)
|
||||||
assert subject.get_elements_by_material(self.file, material) == [element]
|
assert subject.get_elements_by_material(self.file, material) == {element}
|
||||||
|
|
||||||
def test_getting_elements_of_a_material_layer_set(self):
|
def test_getting_elements_of_a_material_layer_set(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
@@ -290,9 +290,9 @@ class TestGetElementsByMaterial(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material_set)
|
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material_set)
|
||||||
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSetUsage")
|
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialLayerSetUsage")
|
||||||
usage = self.file.by_type("IfcMaterialLayerSetUsage")[0]
|
usage = self.file.by_type("IfcMaterialLayerSetUsage")[0]
|
||||||
assert set(subject.get_elements_by_material(self.file, material)) == {element, element_type}
|
assert subject.get_elements_by_material(self.file, material) == {element, element_type}
|
||||||
assert set(subject.get_elements_by_material(self.file, material_set)) == {element, element_type}
|
assert subject.get_elements_by_material(self.file, material_set) == {element, element_type}
|
||||||
assert set(subject.get_elements_by_material(self.file, usage)) == {element}
|
assert subject.get_elements_by_material(self.file, usage) == {element}
|
||||||
|
|
||||||
def test_getting_elements_of_a_material_profile_set(self):
|
def test_getting_elements_of_a_material_profile_set(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
@@ -304,18 +304,20 @@ class TestGetElementsByMaterial(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material_set)
|
ifcopenshell.api.run("material.assign_material", self.file, product=element_type, material=material_set)
|
||||||
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialProfileSetUsage")
|
ifcopenshell.api.run("material.assign_material", self.file, product=element, type="IfcMaterialProfileSetUsage")
|
||||||
usage = self.file.by_type("IfcMaterialProfileSetUsage")[0]
|
usage = self.file.by_type("IfcMaterialProfileSetUsage")[0]
|
||||||
assert set(subject.get_elements_by_material(self.file, material)) == {element, element_type}
|
assert subject.get_elements_by_material(self.file, material) == {element, element_type}
|
||||||
assert set(subject.get_elements_by_material(self.file, material_set)) == {element, element_type}
|
assert subject.get_elements_by_material(self.file, material_set) == {element, element_type}
|
||||||
assert set(subject.get_elements_by_material(self.file, usage)) == {element}
|
assert subject.get_elements_by_material(self.file, usage) == {element}
|
||||||
|
|
||||||
def test_getting_elements_of_a_material_constituent_set(self):
|
def test_getting_elements_of_a_material_constituent_set(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
material = ifcopenshell.api.run("material.add_material", self.file)
|
material = ifcopenshell.api.run("material.add_material", self.file)
|
||||||
material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialConstituentSet")
|
material_set = ifcopenshell.api.run(
|
||||||
|
"material.add_material_set", self.file, set_type="IfcMaterialConstituentSet"
|
||||||
|
)
|
||||||
ifcopenshell.api.run("material.add_constituent", self.file, constituent_set=material_set, material=material)
|
ifcopenshell.api.run("material.add_constituent", self.file, constituent_set=material_set, material=material)
|
||||||
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material_set)
|
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material_set)
|
||||||
assert set(subject.get_elements_by_material(self.file, material)) == {element}
|
assert subject.get_elements_by_material(self.file, material) == {element}
|
||||||
assert set(subject.get_elements_by_material(self.file, material_set)) == {element}
|
assert subject.get_elements_by_material(self.file, material_set) == {element}
|
||||||
|
|
||||||
def test_getting_elements_of_a_material_list(self):
|
def test_getting_elements_of_a_material_list(self):
|
||||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||||
@@ -323,8 +325,97 @@ class TestGetElementsByMaterial(test.bootstrap.IFC4):
|
|||||||
material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialList")
|
material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialList")
|
||||||
ifcopenshell.api.run("material.add_list_item", self.file, material_list=material_set, material=material)
|
ifcopenshell.api.run("material.add_list_item", self.file, material_list=material_set, material=material)
|
||||||
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material_set)
|
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material_set)
|
||||||
assert set(subject.get_elements_by_material(self.file, material)) == {element}
|
assert subject.get_elements_by_material(self.file, material) == {element}
|
||||||
assert set(subject.get_elements_by_material(self.file, material_set)) == {element}
|
assert subject.get_elements_by_material(self.file, material_set) == {element}
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetElementsByStyle(test.bootstrap.IFC4):
|
||||||
|
def test_getting_elements_of_a_styled_representation_item(self):
|
||||||
|
element = self.file.createIfcWall()
|
||||||
|
style = self.file.createIfcSurfaceStyle()
|
||||||
|
item = self.file.createIfcExtrudedAreaSolid()
|
||||||
|
self.file.createIfcStyledItem(Item=item, Styles=[style])
|
||||||
|
element.Representation = self.file.createIfcProductDefinitionShape(
|
||||||
|
Representations=[self.file.createIfcShapeRepresentation(Items=[item])]
|
||||||
|
)
|
||||||
|
assert subject.get_elements_by_style(self.file, style) == {element}
|
||||||
|
|
||||||
|
def test_getting_elements_of_a_styled_mapped_representation_item(self):
|
||||||
|
element = self.file.createIfcWall()
|
||||||
|
style = self.file.createIfcSurfaceStyle()
|
||||||
|
item = self.file.createIfcExtrudedAreaSolid()
|
||||||
|
self.file.createIfcStyledItem(Item=item, Styles=[style])
|
||||||
|
element.Representation = self.file.createIfcProductDefinitionShape(
|
||||||
|
Representations=[
|
||||||
|
self.file.createIfcShapeRepresentation(
|
||||||
|
Items=[
|
||||||
|
self.file.createIfcMappedItem(
|
||||||
|
MappingSource=self.file.createIfcRepresentationMap(
|
||||||
|
MappedRepresentation=self.file.createIfcShapeRepresentation(Items=[item])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
assert subject.get_elements_by_style(self.file, style) == {element}
|
||||||
|
|
||||||
|
def test_getting_type_elements_of_a_styled_mapped_representation_item(self):
|
||||||
|
element = self.file.createIfcWallType()
|
||||||
|
style = self.file.createIfcSurfaceStyle()
|
||||||
|
item = self.file.createIfcExtrudedAreaSolid()
|
||||||
|
self.file.createIfcStyledItem(Item=item, Styles=[style])
|
||||||
|
element.RepresentationMaps = [
|
||||||
|
self.file.createIfcRepresentationMap(
|
||||||
|
MappedRepresentation=self.file.createIfcShapeRepresentation(Items=[item])
|
||||||
|
)
|
||||||
|
]
|
||||||
|
assert subject.get_elements_by_style(self.file, style) == {element}
|
||||||
|
|
||||||
|
def test_getting_elements_of_a_styled_material(self):
|
||||||
|
element = self.file.createIfcWall()
|
||||||
|
material = ifcopenshell.api.run("material.add_material", self.file)
|
||||||
|
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material)
|
||||||
|
style = self.file.createIfcSurfaceStyle()
|
||||||
|
self.file.createIfcMaterialDefinitionRepresentation(
|
||||||
|
RepresentedMaterial=material,
|
||||||
|
Representations=[
|
||||||
|
self.file.createIfcStyledRepresentation(Items=[self.file.createIfcStyledItem(Styles=[style])])
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert subject.get_elements_by_style(self.file, style) == {element}
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetElementsByRepresentation(test.bootstrap.IFC4):
|
||||||
|
def test_getting_elements_of_a_styled_representation_item(self):
|
||||||
|
element = self.file.createIfcWall()
|
||||||
|
representation = self.file.createIfcShapeRepresentation()
|
||||||
|
element.Representation = self.file.createIfcProductDefinitionShape(Representations=[representation])
|
||||||
|
assert subject.get_elements_by_representation(self.file, representation) == {element}
|
||||||
|
|
||||||
|
def test_getting_elements_of_a_styled_mapped_representation_item(self):
|
||||||
|
element = self.file.createIfcWall()
|
||||||
|
representation = self.file.createIfcShapeRepresentation()
|
||||||
|
element.Representation = self.file.createIfcProductDefinitionShape(
|
||||||
|
Representations=[
|
||||||
|
self.file.createIfcShapeRepresentation(
|
||||||
|
Items=[
|
||||||
|
self.file.createIfcMappedItem(
|
||||||
|
MappingSource=self.file.createIfcRepresentationMap(
|
||||||
|
MappedRepresentation=representation
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
assert subject.get_elements_by_representation(self.file, representation) == {element}
|
||||||
|
|
||||||
|
def test_getting_type_elements_of_a_styled_mapped_representation_item(self):
|
||||||
|
element = self.file.createIfcWallType()
|
||||||
|
representation = self.file.createIfcShapeRepresentation()
|
||||||
|
element.RepresentationMaps = [self.file.createIfcRepresentationMap(MappedRepresentation=representation)]
|
||||||
|
assert subject.get_elements_by_representation(self.file, representation) == {element}
|
||||||
|
|
||||||
|
|
||||||
class TestGetlayers(test.bootstrap.IFC4):
|
class TestGetlayers(test.bootstrap.IFC4):
|
||||||
|
|||||||
Reference in New Issue
Block a user