mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
add_representation - use numpy arrays for calculations that include model offset
This commit is contained in:
@@ -21,8 +21,11 @@ import math
|
|||||||
import bmesh
|
import bmesh
|
||||||
import ifcopenshell.util.shape_builder
|
import ifcopenshell.util.shape_builder
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
|
import numpy as np
|
||||||
|
import numpy.typing as npt
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from typing import Union, Optional, Literal, Any, TYPE_CHECKING
|
from typing import Union, Optional, Literal, Any, TYPE_CHECKING
|
||||||
|
from ifcopenshell.util.shape_builder import ifc_safe_vector_type, VectorType
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from bonsai.bim.module.geometry.helper import Helper
|
from bonsai.bim.module.geometry.helper import Helper
|
||||||
@@ -39,7 +42,7 @@ def add_representation(
|
|||||||
context: ifcopenshell.entity_instance,
|
context: ifcopenshell.entity_instance,
|
||||||
blender_object: bpy.types.Object,
|
blender_object: bpy.types.Object,
|
||||||
geometry: Union[bpy.types.Mesh, bpy.types.Curve],
|
geometry: Union[bpy.types.Mesh, bpy.types.Curve],
|
||||||
coordinate_offset: Optional[Vector] = None,
|
coordinate_offset: Optional[npt.NDArray[np.float64]] = None,
|
||||||
total_items: int = 1,
|
total_items: int = 1,
|
||||||
unit_scale: Optional[float] = None,
|
unit_scale: Optional[float] = None,
|
||||||
should_force_faceted_brep: bool = False,
|
should_force_faceted_brep: bool = False,
|
||||||
@@ -89,7 +92,7 @@ def add_representation(
|
|||||||
"context": context,
|
"context": context,
|
||||||
"blender_object": blender_object,
|
"blender_object": blender_object,
|
||||||
"geometry": geometry,
|
"geometry": geometry,
|
||||||
"coordinate_offset": Vector(coordinate_offset) if coordinate_offset is not None else None,
|
"coordinate_offset": coordinate_offset if coordinate_offset is not None else None,
|
||||||
"total_items": total_items,
|
"total_items": total_items,
|
||||||
"unit_scale": unit_scale,
|
"unit_scale": unit_scale,
|
||||||
"should_force_faceted_brep": should_force_faceted_brep,
|
"should_force_faceted_brep": should_force_faceted_brep,
|
||||||
@@ -107,9 +110,11 @@ class Usecase:
|
|||||||
file: ifcopenshell.file
|
file: ifcopenshell.file
|
||||||
settings: dict[str, Any]
|
settings: dict[str, Any]
|
||||||
ifc_vertices: list[ifcopenshell.entity_instance]
|
ifc_vertices: list[ifcopenshell.entity_instance]
|
||||||
|
coordinate_offset: Union[npt.NDArray[np.float64], None]
|
||||||
|
|
||||||
def execute(self) -> Union[ifcopenshell.entity_instance, None]:
|
def execute(self) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
self.is_manifold = None
|
self.is_manifold = None
|
||||||
|
self.coordinate_offset = self.settings["coordinate_offset"]
|
||||||
if (
|
if (
|
||||||
isinstance(self.settings["geometry"], bpy.types.Mesh)
|
isinstance(self.settings["geometry"], bpy.types.Mesh)
|
||||||
and self.settings["geometry"] == self.settings["blender_object"].data
|
and self.settings["geometry"] == self.settings["blender_object"].data
|
||||||
@@ -868,11 +873,11 @@ class Usecase:
|
|||||||
|
|
||||||
x, y, z coords are provided in SI units.
|
x, y, z coords are provided in SI units.
|
||||||
"""
|
"""
|
||||||
if is_model_coords and self.settings["coordinate_offset"]:
|
if is_model_coords and self.coordinate_offset is not None:
|
||||||
x += self.settings["coordinate_offset"][0]
|
x += self.coordinate_offset[0]
|
||||||
y += self.settings["coordinate_offset"][1]
|
y += self.coordinate_offset[1]
|
||||||
if z is not None:
|
if z is not None:
|
||||||
z += self.settings["coordinate_offset"][2]
|
z += self.coordinate_offset[2]
|
||||||
x = self.convert_si_to_unit(x)
|
x = self.convert_si_to_unit(x)
|
||||||
y = self.convert_si_to_unit(y)
|
y = self.convert_si_to_unit(y)
|
||||||
if z is None:
|
if z is None:
|
||||||
@@ -881,21 +886,26 @@ class Usecase:
|
|||||||
return self.file.createIfcCartesianPoint((x, y, z))
|
return self.file.createIfcCartesianPoint((x, y, z))
|
||||||
|
|
||||||
def create_cartesian_point_list_from_vertices(
|
def create_cartesian_point_list_from_vertices(
|
||||||
self, vertices: list[bpy.types.MeshVertex], is_2d: bool = False, is_model_coords: bool = True
|
self, vertices: bpy.types.MeshVertices, is_2d: bool = False, is_model_coords: bool = True
|
||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
if is_model_coords and self.settings["coordinate_offset"]:
|
# Catch values as floats to benefit from fast buffer copy.
|
||||||
if is_2d:
|
coords = np.empty(len(vertices) * 3, dtype="f")
|
||||||
xy_offset = Vector((self.settings["coordinate_offset"][0:2]))
|
vertices.foreach_get("co", coords)
|
||||||
return self.file.createIfcCartesianPointList2D(
|
coords = coords.reshape(-1, 3)
|
||||||
[self.convert_si_to_unit(v.co.xy + xy_offset) for v in vertices]
|
|
||||||
)
|
|
||||||
xyz_offset = Vector((self.settings["coordinate_offset"][0:3]))
|
|
||||||
return self.file.createIfcCartesianPointList3D(
|
|
||||||
[self.convert_si_to_unit(v.co.xyz + xyz_offset) for v in vertices]
|
|
||||||
)
|
|
||||||
if is_2d:
|
if is_2d:
|
||||||
return self.file.createIfcCartesianPointList2D([self.convert_si_to_unit(v.co.xy) for v in vertices])
|
coords = coords[:, :2]
|
||||||
return self.file.createIfcCartesianPointList3D([self.convert_si_to_unit(v.co) for v in vertices])
|
coords_class = "IfcCartesianPointList2D"
|
||||||
|
else:
|
||||||
|
coords_class = "IfcCartesianPointList3D"
|
||||||
|
|
||||||
|
if is_model_coords and (offset := self.coordinate_offset) is not None:
|
||||||
|
coords = coords.astype("d")
|
||||||
|
if is_2d:
|
||||||
|
offset = offset[:2]
|
||||||
|
coords += offset
|
||||||
|
|
||||||
|
return self.file.create_entity(coords_class, ifc_safe_vector_type(self.convert_si_to_unit(coords)))
|
||||||
|
|
||||||
def convert_si_to_unit(self, co):
|
def convert_si_to_unit(self, co):
|
||||||
return co / self.settings["unit_scale"]
|
return co / self.settings["unit_scale"]
|
||||||
|
|||||||
Reference in New Issue
Block a user