This commit is contained in:
Andrej730
2024-04-10 12:08:09 +05:00
parent 773a79abc7
commit bea8b2cddc
14 changed files with 106 additions and 24 deletions
@@ -24,10 +24,14 @@ import shapely
import logging import logging
import numpy as np import numpy as np
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import ifcopenshell.geom
import ifcopenshell.util.shape import ifcopenshell.util.shape
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.shape_builder import ifcopenshell.util.shape_builder
import ifcopenshell.util.placement
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.unit
import blenderbim.tool as tool import blenderbim.tool as tool
import blenderbim.core.geometry import blenderbim.core.geometry
import blenderbim.bim.import_ifc as import_ifc import blenderbim.bim.import_ifc as import_ifc
@@ -25,9 +25,13 @@ import ifcopenshell.util.system
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.type
import ifcopenshell.util.unit
import blenderbim.tool as tool import blenderbim.tool as tool
import blenderbim.core.aggregate
import blenderbim.core.type import blenderbim.core.type
import blenderbim.core.geometry import blenderbim.core.geometry
import blenderbim.core.spatial
from . import wall, slab, profile, mep from . import wall, slab, profile, mep
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.model.data import AuthoringData from blenderbim.bim.module.model.data import AuthoringData
@@ -273,7 +277,7 @@ class AddConstrTypeInstance(bpy.types.Operator):
obj.location[2] = collection_obj.location[2] + bpy.context.scene.BIMModelProperties.rl2 obj.location[2] = collection_obj.location[2] + bpy.context.scene.BIMModelProperties.rl2
@staticmethod @staticmethod
def generate_layered_element(ifc_class, relating_type): def generate_layered_element(ifc_class: str, relating_type: ifcopenshell.entity_instance) -> bool:
layer_set_direction = None layer_set_direction = None
parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric") parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric")
@@ -297,6 +301,7 @@ class AddConstrTypeInstance(bpy.types.Operator):
material = ifcopenshell.util.element.get_material(tool.Ifc.get_entity(obj)) material = ifcopenshell.util.element.get_material(tool.Ifc.get_entity(obj))
material.LayerSetDirection = layer_set_direction material.LayerSetDirection = layer_set_direction
return True return True
return False
class ChangeTypePage(bpy.types.Operator, tool.Ifc.Operator): class ChangeTypePage(bpy.types.Operator, tool.Ifc.Operator):
@@ -21,14 +21,18 @@ import copy
import bmesh import bmesh
import mathutils.geometry import mathutils.geometry
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.type import ifcopenshell.util.type
import ifcopenshell.util.unit import ifcopenshell.util.unit
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import blenderbim.bim.handler import blenderbim.bim.handler
import blenderbim.tool as tool import blenderbim.tool as tool
import blenderbim.core.type import blenderbim.core.type
import blenderbim.core.geometry import blenderbim.core.geometry
import blenderbim.core.material import blenderbim.core.material
import blenderbim.core.root
from math import pi, degrees, inf from math import pi, degrees, inf
from mathutils import Vector, Matrix, Quaternion from mathutils import Vector, Matrix, Quaternion
from blenderbim.bim.module.geometry.helper import Helper from blenderbim.bim.module.geometry.helper import Helper
@@ -29,6 +29,7 @@ import ifcopenshell.util.type
import blenderbim.bim.handler import blenderbim.bim.handler
import blenderbim.core.type import blenderbim.core.type
import blenderbim.core.geometry import blenderbim.core.geometry
import blenderbim.core.root
import blenderbim.tool as tool import blenderbim.tool as tool
from math import radians from math import radians
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
@@ -113,7 +114,7 @@ def calculate_quantities(usecase_path, ifc_file, settings):
class DumbSlabGenerator: class DumbSlabGenerator:
def __init__(self, relating_type): def __init__(self, relating_type: ifcopenshell.entity_instance):
self.relating_type = relating_type self.relating_type = relating_type
def generate(self): def generate(self):
@@ -24,7 +24,9 @@ import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.unit import ifcopenshell.util.unit
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.type
import mathutils.geometry import mathutils.geometry
import blenderbim.bim.handler import blenderbim.bim.handler
import blenderbim.core.type import blenderbim.core.type
+1
View File
@@ -18,6 +18,7 @@
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import blenderbim.core.tool import blenderbim.core.tool
import blenderbim.tool as tool import blenderbim.tool as tool
from test.bim.bootstrap import NewFile from test.bim.bootstrap import NewFile
@@ -22,7 +22,12 @@ import ifcopenshell.util.element
class Usecase: class Usecase:
def __init__(self, file, related_object=None, relating_type=None): def __init__(
self,
file: ifcopenshell.file,
related_object: ifcopenshell.entity_instance,
relating_type: ifcopenshell.entity_instance,
):
"""Ensures that all occurrences has the same representation as the type """Ensures that all occurrences has the same representation as the type
If a type has a representation, all occurrences must have the same If a type has a representation, all occurrences must have the same
@@ -87,7 +92,7 @@ class Usecase:
"relating_type": relating_type, "relating_type": relating_type,
} }
def execute(self): def execute(self) -> None:
if not self.settings["relating_type"].RepresentationMaps: if not self.settings["relating_type"].RepresentationMaps:
return return
representations = [] representations = []
@@ -19,7 +19,7 @@
from __future__ import annotations from __future__ import annotations
import ifcopenshell import ifcopenshell
import ifcopenshell.util.element import ifcopenshell.util.element
from typing import Any, Callable, Optional, Union from typing import Any, Callable, Optional, Union, Literal, overload
def get_pset( def get_pset(
@@ -53,13 +53,13 @@ def get_pset(
:type should_inherit: bool,optional :type should_inherit: bool,optional
:return: A dictionary of property names and values, or a single value if a :return: A dictionary of property names and values, or a single value if a
property is specified. property is specified.
:rtype: dict[str, Any] :rtype: Union[Any, dict[str, Any]]
Example: Example:
.. code:: python .. code:: python
element = ifcopenshell.by_type("IfcWall")[0] element = ifc_file.by_type("IfcWall")[0]
psets_and_qtos = ifcopenshell.util.element.get_pset(element, "Pset_WallCommon") psets_and_qtos = ifcopenshell.util.element.get_pset(element, "Pset_WallCommon")
""" """
pset = None pset = None
@@ -132,6 +132,8 @@ def get_psets(
:type qtos_only: bool,optional :type qtos_only: bool,optional
:param should_inherit: Default as True. Set to false if you don't want to inherit property sets from the Type. :param should_inherit: Default as True. Set to false if you don't want to inherit property sets from the Type.
:type should_inherit: bool,optional :type should_inherit: bool,optional
:param verbose: More detailed prop values, defaults to False.
:type verbose: bool,optional
:return: Key, value pair of psets' names and their properties' names & values :return: Key, value pair of psets' names and their properties' names & values
:rtype: dict[str, dict[str, Any]] :rtype: dict[str, dict[str, Any]]
@@ -139,7 +141,7 @@ def get_psets(
.. code:: python .. code:: python
element = ifcopenshell.by_type("IfcWall")[0] element = ifc_file.by_type("IfcWall")[0]
psets = ifcopenshell.util.element.get_psets(element, psets_only=True) psets = ifcopenshell.util.element.get_psets(element, psets_only=True)
qsets = ifcopenshell.util.element.get_psets(element, qtos_only=True) qsets = ifcopenshell.util.element.get_psets(element, qtos_only=True)
psets_and_qtos = ifcopenshell.util.element.get_psets(element) psets_and_qtos = ifcopenshell.util.element.get_psets(element)
@@ -173,9 +175,20 @@ def get_psets(
return psets return psets
@overload
def get_property_definition( def get_property_definition(
definition: ifcopenshell.entity_instance, prop: Optional[str] = None, verbose=False definition: Optional[ifcopenshell.entity_instance], prop: None = None, verbose=False
) -> dict[str, Any]: ...
@overload
def get_property_definition(definition: Optional[ifcopenshell.entity_instance], prop: str, verbose=False) -> Any: ...
@overload
def get_property_definition(definition: None, prop: None = None, verbose: bool = False) -> None: ...
def get_property_definition(
definition: Optional[ifcopenshell.entity_instance], prop: Optional[str] = None, verbose=False
) -> Union[Any, dict[str, Any]]: ) -> Union[Any, dict[str, Any]]:
"""if prop name is not provided in `prop`, will return dict of all available properties
otherwise will return the value of the specified `prop`.
"""
if not definition: if not definition:
return return
@@ -214,6 +227,12 @@ def get_property_definition(
return props return props
@overload
def get_quantity(quantities: list[ifcopenshell.entity_instance], name: str, verbose: Literal[False] = False) -> Any: ...
@overload
def get_quantity(
quantities: list[ifcopenshell.entity_instance], name: str, verbose: Literal[True]
) -> dict[str, Any]: ...
def get_quantity( def get_quantity(
quantities: list[ifcopenshell.entity_instance], name: str, verbose=False quantities: list[ifcopenshell.entity_instance], name: str, verbose=False
) -> Union[Any, dict[str, Any]]: ) -> Union[Any, dict[str, Any]]:
@@ -232,7 +251,17 @@ def get_quantity(
return result return result
def get_quantities(quantities: list[ifcopenshell.entity_instance], verbose=False) -> dict[str, dict[str, Any]]: @overload
def get_quantities(
quantities: list[ifcopenshell.entity_instance], verbose: Literal[False] = False
) -> dict[str, Any]: ...
@overload
def get_quantities(
quantities: list[ifcopenshell.entity_instance], verbose: Literal[True]
) -> dict[str, dict[str, Any]]: ...
def get_quantities(
quantities: list[ifcopenshell.entity_instance], verbose=False
) -> dict[str, Union[Any, dict[str, Any]]]:
results = {} results = {}
for quantity in quantities or []: for quantity in quantities or []:
if quantity.is_a("IfcPhysicalSimpleQuantity"): if quantity.is_a("IfcPhysicalSimpleQuantity"):
@@ -257,6 +286,12 @@ def get_quantities(quantities: list[ifcopenshell.entity_instance], verbose=False
return results return results
@overload
def get_property(properties: list[ifcopenshell.entity_instance], name: str, verbose: Literal[False] = False) -> Any: ...
@overload
def get_property(
properties: list[ifcopenshell.entity_instance], name: str, verbose: Literal[True]
) -> dict[str, Any]: ...
def get_property( def get_property(
properties: list[ifcopenshell.entity_instance], name: str, verbose=False properties: list[ifcopenshell.entity_instance], name: str, verbose=False
) -> Union[Any, dict[str, Any]]: ) -> Union[Any, dict[str, Any]]:
@@ -285,7 +320,17 @@ def get_property(
return result return result
def get_properties(properties: list[ifcopenshell.entity_instance], verbose=False) -> dict[str, dict[str, Any]]: @overload
def get_properties(
properties: list[ifcopenshell.entity_instance], verbose: Literal[False] = False
) -> dict[str, Any]: ...
@overload
def get_properties(
properties: list[ifcopenshell.entity_instance], verbose: Literal[True]
) -> dict[str, dict[str, Any]]: ...
def get_properties(
properties: list[ifcopenshell.entity_instance], verbose=False
) -> dict[str, Union[Any, dict[str, Any]]]:
results = {} results = {}
for prop in properties or []: for prop in properties or []:
ifc_class = prop.is_a() ifc_class = prop.is_a()
@@ -433,7 +478,7 @@ def get_shape_aspects(element: ifcopenshell.entity_instance) -> list[ifcopenshel
def get_material( def get_material(
element: ifcopenshell.entity_instance, should_skip_usage=False, should_inherit=True element: ifcopenshell.entity_instance, should_skip_usage=False, should_inherit=True
) -> ifcopenshell.entity_instance: ) -> Union[ifcopenshell.entity_instance, None]:
"""Gets the material of the element """Gets the material of the element
The material may be a single material, material set (layered, profiled, or The material may be a single material, material set (layered, profiled, or
@@ -449,8 +494,8 @@ def get_material(
:param should_inherit: If True, any inherited materials from associated :param should_inherit: If True, any inherited materials from associated
types will be considered. types will be considered.
:type should_inherit: bool :type should_inherit: bool
:return: The associated material of the element. :return: The associated material of the element or `None`.
:rtype: ifcopenshell.entity_instance.entity_instance :rtype: Union[ifcopenshell.entity_instance.entity_instance, None]
Example: Example:
@@ -17,9 +17,10 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>. # along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell.util import ifcopenshell.util.system
from typing import Optional, Union, Literal
group_types = { group_types: dict[str, tuple[str, ...]] = {
"IfcZone": ("IfcZone", "IfcSpace", "IfcSpatialZone"), "IfcZone": ("IfcZone", "IfcSpace", "IfcSpatialZone"),
"IfcBuiltSystem": ( "IfcBuiltSystem": (
"IfcBuiltElement", "IfcBuiltElement",
@@ -39,22 +40,24 @@ group_types = {
"IfcGroup": ("IfcObjectDefinition",), "IfcGroup": ("IfcObjectDefinition",),
} }
FLOW_DIRECTION = Literal["SINK", "SOURCE", "SOURCEANDSINK", "NOTEDEFINED"]
def is_assignable(product, system) -> bool:
def is_assignable(product: ifcopenshell.entity_instance, system: ifcopenshell.entity_instance) -> bool:
for assignable in group_types.get(system.is_a(), ()): for assignable in group_types.get(system.is_a(), ()):
if product.is_a(assignable): if product.is_a(assignable):
return True return True
return False return False
def get_system_elements(system): def get_system_elements(system: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
results = [] results = []
for rel in system.IsGroupedBy: for rel in system.IsGroupedBy:
results.extend(rel.RelatedObjects) results.extend(rel.RelatedObjects)
return results return results
def get_element_systems(element): def get_element_systems(element: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
results = [] results = []
for rel in element.HasAssignments: for rel in element.HasAssignments:
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.is_a() in ( if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.is_a() in (
@@ -67,7 +70,9 @@ def get_element_systems(element):
return results return results
def get_ports(element, flow_direction=None): def get_ports(
element: ifcopenshell.entity_instance, flow_direction: Optional[FLOW_DIRECTION] = None
) -> list[ifcopenshell.entity_instance]:
results = [] results = []
for rel in getattr(element, "IsNestedBy", []) or []: for rel in getattr(element, "IsNestedBy", []) or []:
for port in rel.RelatedObjects: for port in rel.RelatedObjects:
@@ -85,14 +90,14 @@ def get_ports(element, flow_direction=None):
return results return results
def get_connected_port(port): def get_connected_port(port: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
for rel in port.ConnectedTo: for rel in port.ConnectedTo:
return rel.RelatedPort return rel.RelatedPort
for rel in port.ConnectedFrom: for rel in port.ConnectedFrom:
return rel.RelatingPort return rel.RelatingPort
def get_port_element(port): def get_port_element(port: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
if hasattr(port, "Nests"): if hasattr(port, "Nests"):
for rel in port.Nests: for rel in port.Nests:
return rel.RelatingObject return rel.RelatingObject
@@ -102,7 +107,9 @@ def get_port_element(port):
return rel.RelatedElement return rel.RelatedElement
def get_connected_to(element, flow_direction=None): def get_connected_to(
element: ifcopenshell.entity_instance, flow_direction: Optional[FLOW_DIRECTION] = None
) -> list[ifcopenshell.entity_instance]:
results = [] results = []
for port in ifcopenshell.util.system.get_ports(element, flow_direction=flow_direction): for port in ifcopenshell.util.system.get_ports(element, flow_direction=flow_direction):
for rel in port.ConnectedTo: for rel in port.ConnectedTo:
@@ -115,7 +122,9 @@ def get_connected_to(element, flow_direction=None):
return results return results
def get_connected_from(element, flow_direction=None): def get_connected_from(
element: ifcopenshell.entity_instance, flow_direction: Optional[FLOW_DIRECTION] = None
) -> list[ifcopenshell.entity_instance]:
results = [] results = []
for port in ifcopenshell.util.system.get_ports(element, flow_direction=flow_direction): for port in ifcopenshell.util.system.get_ports(element, flow_direction=flow_direction):
for rel in port.ConnectedFrom: for rel in port.ConnectedFrom:
@@ -18,6 +18,7 @@
import test.bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element
class TestAppendAsset(test.bootstrap.IFC4): class TestAppendAsset(test.bootstrap.IFC4):
@@ -18,6 +18,7 @@
import test.bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element
class TestAddPset(test.bootstrap.IFC4): class TestAddPset(test.bootstrap.IFC4):
@@ -18,6 +18,7 @@
import test.bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element
class TestAddQto(test.bootstrap.IFC4): class TestAddQto(test.bootstrap.IFC4):
@@ -19,6 +19,8 @@
import numpy import numpy
import test.bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util
import ifcopenshell.util.system
class TestCopyClass(test.bootstrap.IFC4): class TestCopyClass(test.bootstrap.IFC4):
@@ -19,6 +19,7 @@
import numpy import numpy
import test.bootstrap import test.bootstrap
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.placement
import ifcopenshell.util.system import ifcopenshell.util.system