mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Fix #3578. Support querying surface styles in tools like IfcCSV.
This commit is contained in:
@@ -339,6 +339,8 @@ def get_material(element, should_skip_usage=False, should_inherit=True):
|
||||
The material may be a single material, material set (layered, profiled, or
|
||||
constituent), or a material set usage.
|
||||
|
||||
:param element: The element to get the material of.
|
||||
:type element: ifcopenshell.entity_instance.entity_instance
|
||||
:param should_skip_usage: If set to True, if the material is a material set
|
||||
usage, the material set itself will be returned. Useful if you don't
|
||||
care about occurrence usage parameters. If False, the usage will be
|
||||
@@ -378,6 +380,8 @@ def get_materials(element, should_inherit=True):
|
||||
If the element has a material set, the individual materials of that set are
|
||||
returned as a list.
|
||||
|
||||
:param element: The element to get the materials of.
|
||||
:type element: ifcopenshell.entity_instance.entity_instance
|
||||
:param should_inherit: If True, any inherited materials from associated
|
||||
types will be considered.
|
||||
:return: The associated materials of the element.
|
||||
@@ -403,6 +407,51 @@ def get_materials(element, should_inherit=True):
|
||||
return [c.Material for c in material.MaterialConstituents]
|
||||
|
||||
|
||||
def get_styles(element):
|
||||
"""Retrieves the styles used in an element's representation.
|
||||
|
||||
Styles may be retreived from the material or the body representation.
|
||||
|
||||
:param element: The element to get the styles of.
|
||||
:type element: ifcopenshell.entity_instance.entity_instance
|
||||
:return: A list of surface styles
|
||||
:rtype: list[ifcopenshell.entity_instance.entity_instance]
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
wall = file.by_type("IfcWall")[0]
|
||||
styles = ifcopenshell.util.element.get_styles(wall)
|
||||
"""
|
||||
styles = []
|
||||
|
||||
materials = ifcopenshell.util.element.get_materials(element)
|
||||
for material in materials:
|
||||
for material_definition_representation in material.HasRepresentation or []:
|
||||
for representation in material_definition_representation.Representations:
|
||||
for item in representation.Items:
|
||||
styles.extend([s for s in item.Styles if s.is_a("IfcSurfaceStyle")])
|
||||
|
||||
body = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
|
||||
if not body:
|
||||
return styles
|
||||
|
||||
for representation in [body]:
|
||||
queue = list(representation.Items)
|
||||
while queue:
|
||||
item = queue.pop()
|
||||
if item.is_a("IfcMappedItem"):
|
||||
queue.extend(item.MappingSource.MappedRepresentation.Items)
|
||||
if item.is_a("IfcBooleanResult"):
|
||||
queue.append(item.FirstOperand)
|
||||
queue.append(item.SecondOperand)
|
||||
if item.StyledByItem:
|
||||
styles.extend([s for s in item.StyledByItem[0].Styles if s.is_a("IfcSurfaceStyle")])
|
||||
return styles
|
||||
|
||||
|
||||
|
||||
def get_elements_by_material(ifc_file, material):
|
||||
"""Retrieves the elements related to a material.
|
||||
|
||||
|
||||
@@ -520,6 +520,10 @@ class Selector:
|
||||
value = ifcopenshell.util.element.get_type(value)
|
||||
elif key in ("material", "mat"):
|
||||
value = ifcopenshell.util.element.get_material(value, should_skip_usage=True)
|
||||
elif key in ("materials", "mats"):
|
||||
value = ifcopenshell.util.element.get_materials(value)
|
||||
elif key == "styles":
|
||||
value = ifcopenshell.util.element.get_styles(value)
|
||||
elif key in ("item", "i"):
|
||||
if value.is_a("IfcMaterialLayerSet"):
|
||||
value = value.MaterialLayers
|
||||
|
||||
@@ -386,6 +386,53 @@ class TestGetMaterial(test.bootstrap.IFC4):
|
||||
assert subject.get_material(element, should_inherit=False) is None
|
||||
|
||||
|
||||
class TestGetMaterials(test.bootstrap.IFC4):
|
||||
def test_getting_the_materials_of_a_product(self):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||
material = ifcopenshell.api.run("material.add_material", self.file)
|
||||
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material)
|
||||
assert subject.get_materials(element) == [material]
|
||||
|
||||
|
||||
class TestGetStyles(test.bootstrap.IFC4):
|
||||
def test_getting_the_styles_of_a_product(self):
|
||||
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||
assert subject.get_styles(element) == []
|
||||
|
||||
model = ifcopenshell.api.run("context.add_context", self.file, context_type="Model")
|
||||
body = ifcopenshell.api.run("context.add_context", self.file,
|
||||
context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent=model)
|
||||
|
||||
material = ifcopenshell.api.run("material.add_material", self.file)
|
||||
ifcopenshell.api.run("material.assign_material", self.file, product=element, material=material)
|
||||
|
||||
style = ifcopenshell.api.run("style.add_style", self.file)
|
||||
ifcopenshell.api.run("style.add_surface_style", self.file,
|
||||
style=style, ifc_class="IfcSurfaceStyleShading", attributes={
|
||||
"SurfaceColour": { "Name": None, "Red": 1.0, "Green": 0.8, "Blue": 0.8 },
|
||||
"Transparency": 0., # 0 is opaque, 1 is transparent
|
||||
})
|
||||
ifcopenshell.api.run("style.assign_material_style", self.file, material=material, style=style, context=body)
|
||||
|
||||
assert subject.get_styles(element) == [style]
|
||||
|
||||
style2 = ifcopenshell.api.run("style.add_style", self.file)
|
||||
ifcopenshell.api.run("style.add_surface_style", self.file,
|
||||
style=style2, ifc_class="IfcSurfaceStyleShading", attributes={
|
||||
"SurfaceColour": { "Name": None, "Red": 1.0, "Green": 0.8, "Blue": 0.8 },
|
||||
"Transparency": 0., # 0 is opaque, 1 is transparent
|
||||
})
|
||||
|
||||
representation = ifcopenshell.api.run("geometry.add_wall_representation", self.file,
|
||||
context=body, length=5, height=3, thickness=0.118)
|
||||
|
||||
ifcopenshell.api.run("geometry.assign_representation", self.file, product=element, representation=representation)
|
||||
ifcopenshell.api.run("style.assign_representation_styles", self.file, shape_representation=representation, styles=[style2])
|
||||
|
||||
assert subject.get_styles(element) == [style, style2]
|
||||
|
||||
|
||||
class TestGetElementsByMaterial(test.bootstrap.IFC4):
|
||||
def test_getting_elements_of_a_material(self):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
|
||||
|
||||
Reference in New Issue
Block a user