This commit is contained in:
Andrej730
2025-02-18 15:18:23 +05:00
parent 83a351b1c7
commit 17642ca4e9
117 changed files with 683 additions and 1005 deletions
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.util.representation
from typing import Any
def assign_profile(
@@ -97,6 +98,7 @@ def assign_profile(
class Usecase:
file: ifcopenshell.file
settings: dict[str, Any]
def execute(self) -> None:
# TODO: handle composite profiles
@@ -28,11 +28,8 @@ def edit_assigned_material(
IfcMaterial, consult the IFC documentation.
:param element: The IfcMaterial entity you want to edit
:type element: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict
:return: None
:rtype: None
Example:
@@ -42,7 +39,5 @@ def edit_assigned_material(
ifcopenshell.api.material.edit_assigned_material(model,
element=concrete, attributes={"Description": "40MPA concrete with broom finish"})
"""
settings = {"element": element, "attributes": attributes}
for name, value in settings["attributes"].items():
setattr(settings["element"], name, value)
for name, value in attributes.items():
setattr(element, name, value)
@@ -31,13 +31,9 @@ def edit_constituent(
IfcMaterialConstituent, consult the IFC documentation.
:param constituent: The IfcMaterialConstituent entity you want to edit
:type constituent: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:param material: The IfcMaterial entity you want to change the constituent to
:type material: ifcopenshell.entity_instance, optional
:return: None
:rtype: None
Example:
@@ -65,8 +61,6 @@ def edit_constituent(
ifcopenshell.api.material.edit_constituent(model,
constituent=constituent, attributes={"Name": "Glazing"})
"""
settings = {"constituent": constituent, "attributes": attributes or {}, "material": material}
for name, value in settings["attributes"].items():
setattr(settings["constituent"], name, value)
settings["constituent"].Material = settings["material"]
for name, value in (attributes or {}).items():
setattr(constituent, name, value)
constituent.Material = material
@@ -31,14 +31,10 @@ def edit_layer(
IfcMaterialLayer, consult the IFC documentation.
:param layer: The IfcMaterialLayer entity you want to edit
:type layer: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:param material: The IfcMaterial entity you want the layer to be made
from.
:type material: ifcopenshell.entity_instance, optional
:return: None
:rtype: None
Example:
@@ -63,9 +59,7 @@ def edit_layer(
layer = ifcopenshell.api.material.add_layer(model, layer_set=material_set, material=gypsum)
ifcopenshell.api.material.edit_layer(model, layer=layer, attributes={"LayerThickness": 13})
"""
settings = {"layer": layer, "attributes": attributes or {}, "material": material}
for name, value in settings["attributes"].items():
setattr(settings["layer"], name, value)
if settings["material"]:
settings["layer"].Material = settings["material"]
for name, value in (attributes or {}).items():
setattr(layer, name, value)
if material:
layer.Material = material
@@ -29,11 +29,8 @@ def edit_layer_usage(file: ifcopenshell.file, usage: ifcopenshell.entity_instanc
IfcMaterialLayerSetUsage, consult the IFC documentation.
:param usage: The IfcMaterialLayerSetUsage entity you want to edit
:type usage: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict
:return: None
:rtype: None
Example:
@@ -75,7 +72,5 @@ def edit_layer_usage(file: ifcopenshell.file, usage: ifcopenshell.entity_instanc
ifcopenshell.api.material.edit_layer_usage(model,
usage=rel.RelatingMaterial, attributes={"OffsetFromReferenceLine": 200})
"""
settings = {"usage": usage, "attributes": attributes}
for name, value in settings["attributes"].items():
setattr(settings["usage"], name, value)
for name, value in attributes.items():
setattr(usage, name, value)
@@ -34,17 +34,12 @@ def edit_profile(
IfcMaterialProfile, consult the IFC documentation.
:param profile: The IfcMaterialProfile entity you want to edit
:type profile: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict, optional
:param profile_def: The IfcProfileDef entity the profile curve should be
extruded from.
:type profile_def: ifcopenshell.entity_instance, optional
:param material: The IfcMaterial entity you want to change the profile
to be made from.
:type material: ifcopenshell.entity_instance, optional
:return: None
:rtype: None
Example:
@@ -80,16 +75,9 @@ def edit_profile(
ifcopenshell.api.material.edit_profile(model,
profile=profile_item, profile_def=hea200, material=steel2)
"""
settings = {
"profile": profile,
"attributes": attributes or {},
"profile_def": profile_def,
"material": material,
}
for name, value in settings["attributes"].items():
setattr(settings["profile"], name, value)
if settings["material"]:
settings["profile"].Material = settings["material"]
if settings["profile_def"]:
settings["profile"].Profile = settings["profile_def"]
for name, value in (attributes or {}).items():
setattr(profile, name, value)
if material:
profile.Material = material
if profile_def:
profile.Profile = profile_def
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.geom
import ifcopenshell.util.representation
from ifcopenshell.geom import ShapeType
from typing import Any
@@ -34,11 +35,8 @@ def edit_profile_usage(
IfcMaterialProfileSetUsage, consult the IFC documentation.
:param usage: The IfcMaterialProfileSetUsage entity you want to edit
:type usage: ifcopenshell.entity_instance
:param attributes: a dictionary of attribute names and values.
:type attributes: dict
:return: None
:rtype: None
Example:
@@ -98,16 +96,19 @@ def edit_profile_usage(
class Usecase:
def execute(self):
self.cardinal_point = self.settings["attributes"].get("CardinalPoint")
if self.cardinal_point and self.cardinal_point != self.settings["usage"].CardinalPoint:
file: ifcopenshell.file
def execute(self, usage: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
self.attributes = attributes
self.cardinal_point = attributes.get("CardinalPoint")
if self.cardinal_point and self.cardinal_point != usage.CardinalPoint:
self.update_cardinal_point()
for name, value in self.settings["attributes"].items():
setattr(self.settings["usage"], name, value)
for name, value in attributes.items():
setattr(usage, name, value)
def update_cardinal_point(self):
material_set = self.settings["usage"].ForProfileSet
material_set = self.attributes["usage"].ForProfileSet
self.profile = material_set.CompositeProfile
if not self.profile and material_set.MaterialProfiles:
self.profile = material_set.MaterialProfiles[0].Profile
@@ -117,13 +118,13 @@ class Usecase:
self.position = self.calculate_position()
if self.file.schema == "IFC2X3":
for rel in self.file.get_inverse(self.settings["usage"]):
for rel in self.file.get_inverse(self.attributes["usage"]):
if not rel.is_a("IfcRelAssociatesMaterial"):
continue
for element in rel.RelatedObjects:
self.update_representation(element)
else:
for rel in self.settings["usage"].AssociatedTo:
for rel in self.attributes["usage"].AssociatedTo:
for element in rel.RelatedObjects:
self.update_representation(element)
@@ -166,7 +167,7 @@ class Usecase:
elif self.cardinal_point == 9:
return self.get_top_right(shape)
def get_bottom_left(self, shape):
def get_bottom_left(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
x = [v[i] for i in range(0, len(v), 3)]
y = [v[i + 1] for i in range(0, len(v), 3)]
@@ -174,13 +175,13 @@ class Usecase:
height = max(y) - min(y)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((-width / 2, height / 2, 0.0)))
def get_bottom_centre(self, shape):
def get_bottom_centre(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
y = [v[i + 1] for i in range(0, len(v), 3)]
height = max(y) - min(y)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((0.0, height / 2, 0.0)))
def get_bottom_right(self, shape):
def get_bottom_right(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
x = [v[i] for i in range(0, len(v), 3)]
y = [v[i + 1] for i in range(0, len(v), 3)]
@@ -188,22 +189,22 @@ class Usecase:
height = max(y) - min(y)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((width / 2, height / 2, 0.0)))
def get_mid_depth_left(self, shape):
def get_mid_depth_left(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
x = [v[i] for i in range(0, len(v), 3)]
width = max(x) - min(x)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((-width / 2, 0.0, 0.0)))
def get_mid_depth_centre(self, shape):
def get_mid_depth_centre(self, shape: ShapeType) -> ifcopenshell.entity_instance:
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((0.0, 0.0, 0.0)))
def get_mid_depth_right(self, shape):
def get_mid_depth_right(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
x = [v[i] for i in range(0, len(v), 3)]
width = max(x) - min(x)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((width / 2, 0.0, 0.0)))
def get_top_left(self, shape):
def get_top_left(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
x = [v[i] for i in range(0, len(v), 3)]
y = [v[i + 1] for i in range(0, len(v), 3)]
@@ -211,13 +212,13 @@ class Usecase:
height = max(y) - min(y)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((-width / 2, -height / 2, 0.0)))
def get_top_centre(self, shape):
def get_top_centre(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
y = [v[i + 1] for i in range(0, len(v), 3)]
height = max(y) - min(y)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((0.0, -height / 2, 0.0)))
def get_top_right(self, shape):
def get_top_right(self, shape: ShapeType) -> ifcopenshell.entity_instance:
v = shape.verts
x = [v[i] for i in range(0, len(v), 3)]
y = [v[i + 1] for i in range(0, len(v), 3)]
@@ -225,7 +226,7 @@ class Usecase:
height = max(y) - min(y)
return self.file.createIfcAxis2Placement3D(self.file.createIfcCartesianPoint((width / 2, -height / 2, 0.0)))
def update_representation(self, element):
def update_representation(self, element: ifcopenshell.entity_instance) -> None:
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not representation:
return
@@ -234,5 +235,5 @@ class Usecase:
if subelement.is_a("IfcSweptAreaSolid") and subelement.SweptArea == self.profile:
self.update_swept_area_solid(subelement)
def update_swept_area_solid(self, element):
def update_swept_area_solid(self, element: ifcopenshell.entity_instance) -> None:
element.Position = self.position
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.util.element
def remove_constituent(
@@ -54,8 +54,6 @@ def remove_list_item(
# Let's remove the glass
ifcopenshell.api.material.remove_list_item(model, material_list=material_set, material_index=1)
"""
settings = {"material_list": material_list, "material_index": material_index}
materials = list(settings["material_list"].Materials)
materials.pop(settings["material_index"])
settings["material_list"].Materials = materials
materials = list(material_list.Materials)
materials.pop(material_index)
material_list.Materials = materials
@@ -57,16 +57,17 @@ def reorder_set_item(
ifcopenshell.api.material.reorder_set_item(model,
material_set=material_set, old_index=0, new_index=1)
"""
settings = {"material_set": material_set, "old_index": old_index, "new_index": new_index}
if settings["material_set"].is_a("IfcMaterialConstituentSet"):
if material_set.is_a("IfcMaterialConstituentSet"):
set_name = "MaterialConstituents"
elif settings["material_set"].is_a("IfcMaterialLayerSet"):
elif material_set.is_a("IfcMaterialLayerSet"):
set_name = "MaterialLayers"
elif settings["material_set"].is_a("IfcMaterialProfileSet"):
elif material_set.is_a("IfcMaterialProfileSet"):
set_name = "MaterialProfiles"
elif settings["material_set"].is_a("IfcMaterialList"):
elif material_set.is_a("IfcMaterialList"):
set_name = "Materials"
items = list(getattr(settings["material_set"], set_name) or [])
items.insert(settings["new_index"], items.pop(settings["old_index"]))
setattr(settings["material_set"], set_name, items)
else:
raise ValueError(f"Unexpected material set type: '{material_set.is_a()}'.")
items = list(getattr(material_set, set_name) or [])
items.insert(new_index, items.pop(old_index))
setattr(material_set, set_name, items)
@@ -19,6 +19,7 @@
import ifcopenshell
import ifcopenshell.api.owner
import ifcopenshell.util.element
from typing import Any
def unassign_material(file: ifcopenshell.file, products: list[ifcopenshell.entity_instance]) -> None:
@@ -58,6 +59,9 @@ def unassign_material(file: ifcopenshell.file, products: list[ifcopenshell.entit
class Usecase:
file: ifcopenshell.file
settings: dict[str, Any]
def execute(self):
self.products = set(self.settings["products"])
if not self.products: