mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 23:12:34 +00:00
typing
This commit is contained in:
@@ -232,19 +232,19 @@ class IfcImporter:
|
|||||||
|
|
||||||
self.material_creator = MaterialCreator(ifc_import_settings, self)
|
self.material_creator = MaterialCreator(ifc_import_settings, self)
|
||||||
|
|
||||||
def profile_code(self, message):
|
def profile_code(self, message: str) -> None:
|
||||||
if not self.time:
|
if not self.time:
|
||||||
self.time = time.time()
|
self.time = time.time()
|
||||||
print("{} :: {:.2f}".format(message, time.time() - self.time))
|
print("{} :: {:.2f}".format(message, time.time() - self.time))
|
||||||
self.time = time.time()
|
self.time = time.time()
|
||||||
self.update_progress(self.progress + 1)
|
self.update_progress(self.progress + 1)
|
||||||
|
|
||||||
def update_progress(self, progress):
|
def update_progress(self, progress: float) -> None:
|
||||||
if progress <= 100:
|
if progress <= 100:
|
||||||
self.progress = progress
|
self.progress = progress
|
||||||
bpy.context.window_manager.progress_update(self.progress)
|
bpy.context.window_manager.progress_update(self.progress)
|
||||||
|
|
||||||
def execute(self):
|
def execute(self) -> None:
|
||||||
bpy.context.window_manager.progress_begin(0, 100)
|
bpy.context.window_manager.progress_begin(0, 100)
|
||||||
self.profile_code("Starting import process")
|
self.profile_code("Starting import process")
|
||||||
self.load_file()
|
self.load_file()
|
||||||
@@ -324,7 +324,7 @@ class IfcImporter:
|
|||||||
coords = getattr(point, "Coordinates", point)
|
coords = getattr(point, "Coordinates", point)
|
||||||
return abs(coords[0]) > limit or abs(coords[1]) > limit or abs(coords[2]) > limit
|
return abs(coords[0]) > limit or abs(coords[1]) > limit or abs(coords[2]) > limit
|
||||||
|
|
||||||
def process_context_filter(self):
|
def process_context_filter(self) -> None:
|
||||||
# Annotation ContextType is to accommodate broken Revit files
|
# Annotation ContextType is to accommodate broken Revit files
|
||||||
# See https://github.com/Autodesk/revit-ifc/issues/187
|
# See https://github.com/Autodesk/revit-ifc/issues/187
|
||||||
type_priority = ["Model", "Plan", "Annotation"]
|
type_priority = ["Model", "Plan", "Annotation"]
|
||||||
@@ -412,7 +412,7 @@ class IfcImporter:
|
|||||||
settings.set_context_ids([context.id()])
|
settings.set_context_ids([context.id()])
|
||||||
self.gross_context_settings.append(settings)
|
self.gross_context_settings.append(settings)
|
||||||
|
|
||||||
def process_element_filter(self):
|
def process_element_filter(self) -> None:
|
||||||
offset = self.ifc_import_settings.element_offset
|
offset = self.ifc_import_settings.element_offset
|
||||||
offset_limit = offset + self.ifc_import_settings.element_limit
|
offset_limit = offset + self.ifc_import_settings.element_limit
|
||||||
|
|
||||||
@@ -479,7 +479,7 @@ class IfcImporter:
|
|||||||
break
|
break
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def parse_native_elements(self):
|
def parse_native_elements(self) -> None:
|
||||||
if not self.ifc_import_settings.should_load_geometry:
|
if not self.ifc_import_settings.should_load_geometry:
|
||||||
return
|
return
|
||||||
for element in self.elements:
|
for element in self.elements:
|
||||||
@@ -487,13 +487,13 @@ class IfcImporter:
|
|||||||
self.native_elements.add(element)
|
self.native_elements.add(element)
|
||||||
self.elements -= self.native_elements
|
self.elements -= self.native_elements
|
||||||
|
|
||||||
def is_native(self, element):
|
def is_native(self, element: ifcopenshell.entity_instance) -> bool:
|
||||||
if (
|
if (
|
||||||
not element.Representation
|
not element.Representation
|
||||||
or not element.Representation.Representations
|
or not element.Representation.Representations
|
||||||
or getattr(element, "HasOpenings", None)
|
or getattr(element, "HasOpenings", None)
|
||||||
):
|
):
|
||||||
return
|
return False
|
||||||
|
|
||||||
representation = None
|
representation = None
|
||||||
representation_priority = None
|
representation_priority = None
|
||||||
@@ -508,7 +508,7 @@ class IfcImporter:
|
|||||||
context = rep.ContextOfItems
|
context = rep.ContextOfItems
|
||||||
|
|
||||||
if not representation:
|
if not representation:
|
||||||
return
|
return False
|
||||||
|
|
||||||
matrix = np.eye(4)
|
matrix = np.eye(4)
|
||||||
representation_id = None
|
representation_id = None
|
||||||
@@ -566,8 +566,11 @@ class IfcImporter:
|
|||||||
"type": "IfcFaceBasedSurfaceModel",
|
"type": "IfcFaceBasedSurfaceModel",
|
||||||
}
|
}
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def is_native_swept_disk_solid(self, element, representation):
|
def is_native_swept_disk_solid(
|
||||||
|
self, element: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
|
||||||
|
) -> bool:
|
||||||
items = [i["item"] for i in ifcopenshell.util.representation.resolve_items(representation)]
|
items = [i["item"] for i in ifcopenshell.util.representation.resolve_items(representation)]
|
||||||
if len(items) == 1 and items[0].is_a("IfcSweptDiskSolid"):
|
if len(items) == 1 and items[0].is_a("IfcSweptDiskSolid"):
|
||||||
if tool.Blender.Modifier.is_railing(element):
|
if tool.Blender.Modifier.is_railing(element):
|
||||||
@@ -583,20 +586,20 @@ class IfcImporter:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_native_faceted_brep(self, representation):
|
def is_native_faceted_brep(self, representation: ifcopenshell.entity_instance) -> bool:
|
||||||
# TODO handle mapped items
|
# TODO handle mapped items
|
||||||
for i in representation.Items:
|
for i in representation.Items:
|
||||||
if i.is_a() != "IfcFacetedBrep":
|
if i.is_a() != "IfcFacetedBrep":
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def is_native_face_based_surface_model(self, representation):
|
def is_native_face_based_surface_model(self, representation: ifcopenshell.entity_instance) -> bool:
|
||||||
for i in representation.Items:
|
for i in representation.Items:
|
||||||
if i.is_a() != "IfcFaceBasedSurfaceModel":
|
if i.is_a() != "IfcFaceBasedSurfaceModel":
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_products_from_shape_representation(self, element):
|
def get_products_from_shape_representation(self, element: ifcopenshell.entity_instance) -> None:
|
||||||
products = [pr.ShapeOfProduct[0] for pr in element.OfProductRepresentation]
|
products = [pr.ShapeOfProduct[0] for pr in element.OfProductRepresentation]
|
||||||
for rep_map in element.RepresentationMap:
|
for rep_map in element.RepresentationMap:
|
||||||
for usage in rep_map.MapUsage:
|
for usage in rep_map.MapUsage:
|
||||||
@@ -605,7 +608,7 @@ class IfcImporter:
|
|||||||
products.extend(self.get_products_from_shape_representation(inverse_element))
|
products.extend(self.get_products_from_shape_representation(inverse_element))
|
||||||
return products
|
return products
|
||||||
|
|
||||||
def predict_dense_mesh(self):
|
def predict_dense_mesh(self) -> None:
|
||||||
if self.ifc_import_settings.should_use_native_meshes:
|
if self.ifc_import_settings.should_use_native_meshes:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -632,7 +635,7 @@ class IfcImporter:
|
|||||||
if faces and max(faces) > threshold:
|
if faces and max(faces) > threshold:
|
||||||
self.ifc_import_settings.should_use_native_meshes = True
|
self.ifc_import_settings.should_use_native_meshes = True
|
||||||
|
|
||||||
def calculate_model_offset(self):
|
def calculate_model_offset(self) -> None:
|
||||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||||
if props.has_blender_offset:
|
if props.has_blender_offset:
|
||||||
return
|
return
|
||||||
@@ -650,14 +653,14 @@ class IfcImporter:
|
|||||||
return self.guess_false_origin_and_project_north(building)
|
return self.guess_false_origin_and_project_north(building)
|
||||||
return self.guess_false_origin()
|
return self.guess_false_origin()
|
||||||
|
|
||||||
def set_manual_blender_offset(self):
|
def set_manual_blender_offset(self) -> None:
|
||||||
props = bpy.context.scene.BIMGeoreferenceProperties
|
props = bpy.context.scene.BIMGeoreferenceProperties
|
||||||
props.blender_eastings = str(self.ifc_import_settings.false_origin[0])
|
props.blender_eastings = str(self.ifc_import_settings.false_origin[0])
|
||||||
props.blender_northings = str(self.ifc_import_settings.false_origin[1])
|
props.blender_northings = str(self.ifc_import_settings.false_origin[1])
|
||||||
props.blender_orthogonal_height = str(self.ifc_import_settings.false_origin[2])
|
props.blender_orthogonal_height = str(self.ifc_import_settings.false_origin[2])
|
||||||
props.has_blender_offset = True
|
props.has_blender_offset = True
|
||||||
|
|
||||||
def guess_false_origin_and_project_north(self, element):
|
def guess_false_origin_and_project_north(self, element: ifcopenshell.entity_instance) -> None:
|
||||||
if not element.ObjectPlacement or not element.ObjectPlacement.is_a("IfcLocalPlacement"):
|
if not element.ObjectPlacement or not element.ObjectPlacement.is_a("IfcLocalPlacement"):
|
||||||
return
|
return
|
||||||
placement = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
placement = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||||
@@ -672,7 +675,7 @@ class IfcImporter:
|
|||||||
props.blender_x_axis_ordinate = str(placement[1][0])
|
props.blender_x_axis_ordinate = str(placement[1][0])
|
||||||
props.has_blender_offset = True
|
props.has_blender_offset = True
|
||||||
|
|
||||||
def guess_false_origin(self):
|
def guess_false_origin(self) -> None:
|
||||||
# Civil BIM applications like to work in absolute coordinates, where the
|
# Civil BIM applications like to work in absolute coordinates, where the
|
||||||
# ObjectPlacement is usually 0,0,0 (but not always, so we'll need to
|
# ObjectPlacement is usually 0,0,0 (but not always, so we'll need to
|
||||||
# check for the actual transformation) but each individual coordinate of
|
# check for the actual transformation) but each individual coordinate of
|
||||||
@@ -1909,13 +1912,17 @@ class IfcImporter:
|
|||||||
polyline.points[-1].co = mathutils.Vector(v2)
|
polyline.points[-1].co = mathutils.Vector(v2)
|
||||||
return curve
|
return curve
|
||||||
|
|
||||||
def create_mesh(self, element: ifcopenshell.entity_instance, shape) -> bpy.types.Mesh:
|
def create_mesh(
|
||||||
|
self,
|
||||||
|
element: ifcopenshell.entity_instance,
|
||||||
|
shape: Union[ifcopenshell.geom.ShapeElementType, ifcopenshell.geom.ShapeType],
|
||||||
|
) -> bpy.types.Mesh:
|
||||||
try:
|
try:
|
||||||
if hasattr(shape, "geometry"):
|
if hasattr(shape, "geometry"):
|
||||||
# shape is ifcopenshell_wrapper.TriangulationElement
|
# shape is ifcopenshell_wrapper.TriangulationElement
|
||||||
geometry: ifcopenshell_wrapper.Triangulation = shape.geometry
|
geometry = shape.geometry
|
||||||
else:
|
else:
|
||||||
geometry: ifcopenshell_wrapper.Triangulation = shape
|
geometry = shape
|
||||||
|
|
||||||
mesh = bpy.data.meshes.new(tool.Loader.get_mesh_name(geometry))
|
mesh = bpy.data.meshes.new(tool.Loader.get_mesh_name(geometry))
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
import re
|
import re
|
||||||
import bpy
|
import bpy
|
||||||
import bmesh
|
import bmesh
|
||||||
|
import ifcopenshell.geom
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
@@ -55,9 +56,12 @@ class Loader(blenderbim.core.tool.Loader):
|
|||||||
return collection
|
return collection
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_mesh_name(cls, geometry) -> str:
|
def get_mesh_name(cls, geometry: ifcopenshell.geom.ShapeType) -> str:
|
||||||
representation_id = geometry.id
|
representation_id = geometry.id
|
||||||
if "-" in representation_id:
|
if "-" in representation_id:
|
||||||
|
# Example: 2432-openings-2468, where
|
||||||
|
# 2432 is mapped representation id
|
||||||
|
# and 2468 is IFCRELVOIDSELEMENT
|
||||||
representation_id = int(re.sub(r"\D", "", representation_id.split("-")[0]))
|
representation_id = int(re.sub(r"\D", "", representation_id.split("-")[0]))
|
||||||
else:
|
else:
|
||||||
representation_id = int(re.sub(r"\D", "", representation_id))
|
representation_id = int(re.sub(r"\D", "", representation_id))
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ class entity_instance:
|
|||||||
|
|
||||||
return file.from_pointer(self.wrapped_data.file_pointer())
|
return file.from_pointer(self.wrapped_data.file_pointer())
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name: str) -> Any:
|
||||||
INVALID, FORWARD, INVERSE = range(3)
|
INVALID, FORWARD, INVERSE = range(3)
|
||||||
attr_cat = self.wrapped_data.get_attribute_category(name)
|
attr_cat = self.wrapped_data.get_attribute_category(name)
|
||||||
if attr_cat == FORWARD:
|
if attr_cat == FORWARD:
|
||||||
|
|||||||
@@ -27,9 +27,13 @@ from ..entity_instance import entity_instance
|
|||||||
|
|
||||||
from . import has_occ
|
from . import has_occ
|
||||||
|
|
||||||
from typing import TypeVar, Union, Optional
|
from typing import TypeVar, Union, Optional, Generator
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
ShapeElementType = Union[
|
||||||
|
ifcopenshell_wrapper.BRepElement, ifcopenshell_wrapper.TriangulationElement, ifcopenshell_wrapper.SerializedElement
|
||||||
|
]
|
||||||
|
ShapeType = Union[ifcopenshell_wrapper.BRep, ifcopenshell_wrapper.Triangulation, ifcopenshell_wrapper.Serialization]
|
||||||
|
|
||||||
|
|
||||||
def wrap_shape_creation(settings, shape):
|
def wrap_shape_creation(settings, shape):
|
||||||
@@ -122,7 +126,7 @@ class iterator(ifcopenshell_wrapper.Iterator):
|
|||||||
def get(self):
|
def get(self):
|
||||||
return wrap_shape_creation(self.settings, ifcopenshell_wrapper.Iterator.get(self))
|
return wrap_shape_creation(self.settings, ifcopenshell_wrapper.Iterator.get(self))
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self) -> Generator[ShapeElementType, None, None]:
|
||||||
if self.initialize():
|
if self.initialize():
|
||||||
while True:
|
while True:
|
||||||
yield self.get()
|
yield self.get()
|
||||||
|
|||||||
@@ -738,7 +738,7 @@ def get_elements_by_style(
|
|||||||
|
|
||||||
def get_elements_by_representation(
|
def get_elements_by_representation(
|
||||||
ifc_file: ifcopenshell.file, representation: ifcopenshell.entity_instance
|
ifc_file: ifcopenshell.file, representation: ifcopenshell.entity_instance
|
||||||
) -> list[ifcopenshell.entity_instance]:
|
) -> set[ifcopenshell.entity_instance]:
|
||||||
"""Gets all elements using a geometric representation
|
"""Gets all elements using a geometric representation
|
||||||
|
|
||||||
:param ifc_file: The IFC file
|
:param ifc_file: The IFC file
|
||||||
@@ -746,7 +746,7 @@ def get_elements_by_representation(
|
|||||||
:param representation: The IfcShapeRepresentation representation
|
:param representation: The IfcShapeRepresentation representation
|
||||||
:type representation: ifcopenshell.entity_instance
|
:type representation: ifcopenshell.entity_instance
|
||||||
:return: The elements using the geometric representation
|
:return: The elements using the geometric representation
|
||||||
:rtype: list[ifcopenshell.entity_instance]
|
:rtype: set[ifcopenshell.entity_instance]
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import ifcopenshell.util.element
|
|||||||
import ifcopenshell.util.representation
|
import ifcopenshell.util.representation
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
from math import cos, sin, pi, tan, radians, degrees, atan, sqrt, ceil
|
from math import cos, sin, pi, tan, radians, degrees, atan, sqrt, ceil
|
||||||
from typing import Union, Optional, Literal, Any
|
from typing import Union, Optional, Literal, Any, Sequence
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
|
|
||||||
@@ -304,9 +304,9 @@ class ShapeBuilder:
|
|||||||
x_axis_radius: float,
|
x_axis_radius: float,
|
||||||
y_axis_radius: float,
|
y_axis_radius: float,
|
||||||
position=Vector((0.0, 0.0)).freeze(),
|
position=Vector((0.0, 0.0)).freeze(),
|
||||||
trim_points: list[Vector] = (),
|
trim_points: Sequence[Vector] = (),
|
||||||
ref_x_direction: Vector = Vector((1.0, 0.0)),
|
ref_x_direction: Vector = Vector((1.0, 0.0)),
|
||||||
trim_points_mask: list[int] = (),
|
trim_points_mask: Sequence[int] = (),
|
||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
"""
|
"""
|
||||||
Ellipse trimming points should be specified in counter clockwise order.
|
Ellipse trimming points should be specified in counter clockwise order.
|
||||||
@@ -345,7 +345,7 @@ class ShapeBuilder:
|
|||||||
self,
|
self,
|
||||||
outer_curve: ifcopenshell.entity_instance,
|
outer_curve: ifcopenshell.entity_instance,
|
||||||
name: Optional[str] = None,
|
name: Optional[str] = None,
|
||||||
inner_curves: list[ifcopenshell.entity_instance] = (),
|
inner_curves: Sequence[ifcopenshell.entity_instance] = (),
|
||||||
profile_type: str = "AREA",
|
profile_type: str = "AREA",
|
||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
# > inner_curves - list of IfcCurve;
|
# > inner_curves - list of IfcCurve;
|
||||||
@@ -882,8 +882,8 @@ class ShapeBuilder:
|
|||||||
def get_simple_2dcurve_data(
|
def get_simple_2dcurve_data(
|
||||||
self,
|
self,
|
||||||
coords: list[Vector],
|
coords: list[Vector],
|
||||||
fillets: list[int] = (),
|
fillets: Sequence[int] = (),
|
||||||
fillet_radius: list[float] = (),
|
fillet_radius: Sequence[float] = (),
|
||||||
closed: bool = True,
|
closed: bool = True,
|
||||||
create_ifc_curve: bool = False,
|
create_ifc_curve: bool = False,
|
||||||
) -> tuple[list[Vector], list[tuple[int, int], Union[ifcopenshell.entity_instance, None]]]:
|
) -> tuple[list[Vector], list[tuple[int, int], Union[ifcopenshell.entity_instance, None]]]:
|
||||||
|
|||||||
Reference in New Issue
Block a user