This commit is contained in:
Andrej730
2024-04-11 11:27:54 +05:00
parent fed23533a4
commit 949ff535eb
4 changed files with 38 additions and 17 deletions
@@ -20,6 +20,7 @@ import bpy
import bmesh import bmesh
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.schema import ifcopenshell.util.schema
import ifcopenshell.util.representation
import ifcopenshell.util.type import ifcopenshell.util.type
import ifcopenshell.api import ifcopenshell.api
import blenderbim.tool as tool import blenderbim.tool as tool
@@ -20,7 +20,7 @@ import ifcopenshell.util.element
class Usecase: class Usecase:
def __init__(self, file, **settings): def __init__(self, file: ifcopenshell.file, representation: ifcopenshell.entity_instance):
"""Remove a representation. """Remove a representation.
Also purges representation items and their related elements Also purges representation items and their related elements
@@ -35,11 +35,9 @@ class Usecase:
:rtype: None :rtype: None
""" """
self.file = file self.file = file
self.settings = {"representation": None} self.settings = {"representation": representation}
for key, value in settings.items():
self.settings[key] = value
def execute(self): def execute(self) -> None:
styled_items = set() styled_items = set()
presentation_layer_assignments = set() presentation_layer_assignments = set()
textures = set() textures = set()
@@ -20,12 +20,21 @@ import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.representation import ifcopenshell.util.representation
from typing import Optional, Union
class Usecase: class Usecase:
def __init__(self, file, product=None, type="IfcMaterial", material=None): def __init__(
self,
file: ifcopenshell.file,
product: ifcopenshell.entity_instance,
type: str = "IfcMaterial",
material: Optional[ifcopenshell.entity_instance] = None,
):
"""Assigns a material to a product """Assigns a material to a product
Will unassign previously assigned material.
When a material is assigned to a product, it means that the product is When a material is assigned to a product, it means that the product is
made out of that material. In its simplest form, a single material may made out of that material. In its simplest form, a single material may
be assigned to a product, meaning that the entire product is made out of be assigned to a product, meaning that the entire product is made out of
@@ -60,10 +69,12 @@ class Usecase:
"IfcMaterialLayerSet", "IfcMaterialLayerSetUsage", "IfcMaterialLayerSet", "IfcMaterialLayerSetUsage",
"IfcMaterialProfileSet", "IfcMaterialProfileSetUsage", or "IfcMaterialProfileSet", "IfcMaterialProfileSetUsage", or
"IfcMaterialList". Note that "Set Usages" may only be assigned to "IfcMaterialList". Note that "Set Usages" may only be assigned to
occurrences, not types. occurrences, not types. Defaults to "IfcMaterial".
:type type: str :type type: str
:param material: The IfcMaterial or material set you are assigning here. :param material: The IfcMaterial or material set you are assigning here.
:type material: ifcopenshell.entity_instance.entity_instance If type is Usage then no need to provide `material`, it will be deduced
from the element type automatically.
:type material: ifcopenshell.entity_instance.entity_instance, optional
:return: The IfcRelAssociatesMaterial entity :return: The IfcRelAssociatesMaterial entity
:rtype: ifcopenshell.entity_instance.entity_instance :rtype: ifcopenshell.entity_instance.entity_instance
@@ -132,7 +143,7 @@ class Usecase:
self.file = file self.file = file
self.settings = {"product": product, "type": type, "material": material} self.settings = {"product": product, "type": type, "material": material}
def execute(self): def execute(self) -> ifcopenshell.entity_instance:
material = ifcopenshell.util.element.get_material(self.settings["product"]) material = ifcopenshell.util.element.get_material(self.settings["product"])
if material: if material:
ifcopenshell.api.run("material.unassign_material", self.file, product=self.settings["product"]) ifcopenshell.api.run("material.unassign_material", self.file, product=self.settings["product"])
@@ -140,12 +151,15 @@ class Usecase:
self.settings["material"] and not self.settings["material"].is_a("IfcMaterial") self.settings["material"] and not self.settings["material"].is_a("IfcMaterial")
): ):
return self.assign_ifc_material() return self.assign_ifc_material()
elif self.settings["type"] == "IfcMaterialConstituentSet": elif self.settings["type"] == "IfcMaterialConstituentSet":
material_set = self.file.create_entity(self.settings["type"]) material_set = self.file.create_entity(self.settings["type"])
return self.create_material_association(material_set) return self.create_material_association(material_set)
elif self.settings["type"] == "IfcMaterialLayerSet": elif self.settings["type"] == "IfcMaterialLayerSet":
material_set = self.file.create_entity(self.settings["type"]) material_set = self.file.create_entity(self.settings["type"])
return self.create_material_association(material_set) return self.create_material_association(material_set)
elif self.settings["type"] == "IfcMaterialLayerSetUsage": elif self.settings["type"] == "IfcMaterialLayerSetUsage":
element_type = ifcopenshell.util.element.get_type(self.settings["product"]) element_type = ifcopenshell.util.element.get_type(self.settings["product"])
if element_type: if element_type:
@@ -158,9 +172,11 @@ class Usecase:
material_set = self.file.create_entity("IfcMaterialLayerSet") material_set = self.file.create_entity("IfcMaterialLayerSet")
material_set_usage = self.create_layer_set_usage(material_set) material_set_usage = self.create_layer_set_usage(material_set)
return self.create_material_association(material_set_usage) return self.create_material_association(material_set_usage)
elif self.settings["type"] == "IfcMaterialProfileSet": elif self.settings["type"] == "IfcMaterialProfileSet":
material_set = self.file.create_entity(self.settings["type"]) material_set = self.file.create_entity(self.settings["type"])
return self.create_material_association(material_set) return self.create_material_association(material_set)
elif self.settings["type"] == "IfcMaterialProfileSetUsage": elif self.settings["type"] == "IfcMaterialProfileSetUsage":
element_type = ifcopenshell.util.element.get_type(self.settings["product"]) element_type = ifcopenshell.util.element.get_type(self.settings["product"])
if element_type: if element_type:
@@ -175,12 +191,13 @@ class Usecase:
self.update_representation_profile(material_set) self.update_representation_profile(material_set)
material_set_usage = self.create_profile_set_usage(material_set) material_set_usage = self.create_profile_set_usage(material_set)
return self.create_material_association(material_set_usage) return self.create_material_association(material_set_usage)
elif self.settings["type"] == "IfcMaterialList": elif self.settings["type"] == "IfcMaterialList":
material_set = self.file.create_entity(self.settings["type"]) material_set = self.file.create_entity(self.settings["type"])
material_set.Materials = [self.settings["material"]] material_set.Materials = [self.settings["material"]]
return self.create_material_association(material_set) return self.create_material_association(material_set)
def update_representation_profile(self, material_set): def update_representation_profile(self, material_set: ifcopenshell.entity_instance) -> None:
profile = material_set.CompositeProfile profile = material_set.CompositeProfile
if not profile and material_set.MaterialProfiles: if not profile and material_set.MaterialProfiles:
profile = material_set.MaterialProfiles[0].Profile profile = material_set.MaterialProfiles[0].Profile
@@ -195,7 +212,7 @@ class Usecase:
if subelement.is_a("IfcSweptAreaSolid"): if subelement.is_a("IfcSweptAreaSolid"):
subelement.SweptArea = profile subelement.SweptArea = profile
def create_layer_set_usage(self, material_set): def create_layer_set_usage(self, material_set: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
if self.settings["product"].is_a() in [ if self.settings["product"].is_a() in [
"IfcSlab", "IfcSlab",
"IfcSlabStandardCase", "IfcSlabStandardCase",
@@ -218,10 +235,10 @@ class Usecase:
} }
) )
def create_profile_set_usage(self, material_set): def create_profile_set_usage(self, material_set: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
return self.file.create_entity("IfcMaterialProfileSetUsage", **{"ForProfileSet": material_set}) return self.file.create_entity("IfcMaterialProfileSetUsage", **{"ForProfileSet": material_set})
def assign_ifc_material(self): def assign_ifc_material(self) -> ifcopenshell.entity_instance:
rel = self.get_rel_associates_material(self.settings["material"]) rel = self.get_rel_associates_material(self.settings["material"])
if not rel: if not rel:
return self.create_material_association(self.settings["material"]) return self.create_material_association(self.settings["material"])
@@ -230,7 +247,9 @@ class Usecase:
rel.RelatedObjects = related_objects rel.RelatedObjects = related_objects
return rel return rel
def create_material_association(self, relating_material): def create_material_association(
self, relating_material: ifcopenshell.entity_instance
) -> ifcopenshell.entity_instance:
return self.file.create_entity( return self.file.create_entity(
"IfcRelAssociatesMaterial", "IfcRelAssociatesMaterial",
**{ **{
@@ -240,7 +259,9 @@ class Usecase:
} }
) )
def get_rel_associates_material(self, material): def get_rel_associates_material(
self, material: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
if self.file.schema == "IFC2X3" or material.is_a("IfcMaterialList"): if self.file.schema == "IFC2X3" or material.is_a("IfcMaterialList"):
rel = [ rel = [
r r
@@ -17,10 +17,11 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>. # along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element
class Usecase: class Usecase:
def __init__(self, file, product=None): def __init__(self, file: ifcopenshell.entity_instance, product: ifcopenshell.entity_instance):
"""Removes a product """Removes a product
This is effectively a smart delete function that not only removes a This is effectively a smart delete function that not only removes a
@@ -58,7 +59,7 @@ class Usecase:
self.file = file self.file = file
self.settings = {"product": product} self.settings = {"product": product}
def execute(self): def execute(self) -> None:
representations = [] representations = []
if self.settings["product"].is_a("IfcProduct"): if self.settings["product"].is_a("IfcProduct"):
if self.settings["product"].Representation: if self.settings["product"].Representation: