mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 10:11:46 +00:00
Reuse builder.create_axis2_placement_3d
This commit is contained in:
@@ -40,6 +40,7 @@ from mathutils import Vector, Matrix
|
|||||||
from bonsai.bim.ifc import IfcStore
|
from bonsai.bim.ifc import IfcStore
|
||||||
from bonsai.bim.module.model.decorator import ProfileDecorator
|
from bonsai.bim.module.model.decorator import ProfileDecorator
|
||||||
from bonsai.bim.module.boundary.decorator import BoundaryDecorator
|
from bonsai.bim.module.boundary.decorator import BoundaryDecorator
|
||||||
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
import bonsai.core
|
import bonsai.core
|
||||||
import bonsai.core.geometry
|
import bonsai.core.geometry
|
||||||
from typing import Union, Optional
|
from typing import Union, Optional
|
||||||
@@ -1058,15 +1059,11 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
tool.Model.unit_scale = self.unit_scale
|
tool.Model.unit_scale = self.unit_scale
|
||||||
|
builder = ShapeBuilder(tool.Ifc.get())
|
||||||
|
|
||||||
surface = tool.Ifc.get().createIfcCurveBoundedPlane()
|
surface = tool.Ifc.get().createIfcCurveBoundedPlane()
|
||||||
surface.BasisSurface = tool.Ifc.get().createIfcPlane(
|
placement = builder.create_axis2_placement_3d([o / self.unit_scale for o in p1], z_axis, x_axis)
|
||||||
tool.Ifc.get().createIfcAxis2Placement3D(
|
surface.BasisSurface = tool.Ifc.get().create_entity("IfcPlane", placement)
|
||||||
tool.Ifc.get().createIfcCartesianPoint([o / self.unit_scale for o in p1]),
|
|
||||||
tool.Ifc.get().createIfcDirection([float(o) for o in z_axis]),
|
|
||||||
tool.Ifc.get().createIfcDirection([float(o) for o in x_axis]),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if tool.Ifc.get().schema != "IFC2X3":
|
if tool.Ifc.get().schema != "IFC2X3":
|
||||||
points = [tool.Model.convert_si_to_unit(list(co)) for co in polygon.exterior.coords]
|
points = [tool.Model.convert_si_to_unit(list(co)) for co in polygon.exterior.coords]
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import bonsai.tool as tool
|
|||||||
from math import pi, pow
|
from math import pi, pow
|
||||||
from mathutils import Vector, Matrix, geometry
|
from mathutils import Vector, Matrix, geometry
|
||||||
from typing import Union, Any, TypeVar, Optional
|
from typing import Union, Any, TypeVar, Optional
|
||||||
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ T = TypeVar("T")
|
|||||||
class Helper:
|
class Helper:
|
||||||
def __init__(self, file: ifcopenshell.file):
|
def __init__(self, file: ifcopenshell.file):
|
||||||
self.file = file
|
self.file = file
|
||||||
|
self.builder = ShapeBuilder(file)
|
||||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
||||||
|
|
||||||
# We can detect a rectangular extrusion by picking any face, then find an
|
# We can detect a rectangular extrusion by picking any face, then find an
|
||||||
@@ -340,8 +342,10 @@ class Helper:
|
|||||||
def create_extruded_area_solid(
|
def create_extruded_area_solid(
|
||||||
self, mesh: bpy.types.Mesh, extrusion_indices: list[int], profile_def: dict[str, Any]
|
self, mesh: bpy.types.Mesh, extrusion_indices: list[int], profile_def: dict[str, Any]
|
||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
position = self.create_ifc_axis_2_placement_3d(
|
position = self.builder.create_axis2_placement_3d(
|
||||||
profile_def["curve_ucs"]["center"], profile_def["curve_ucs"]["z_axis"], profile_def["curve_ucs"]["x_axis"]
|
self.convert_si_to_unit(profile_def["curve_ucs"]["center"]),
|
||||||
|
profile_def["curve_ucs"]["z_axis"],
|
||||||
|
profile_def["curve_ucs"]["x_axis"],
|
||||||
)
|
)
|
||||||
direction = self.get_extrusion_direction(mesh, extrusion_indices, profile_def["curve_ucs"])
|
direction = self.get_extrusion_direction(mesh, extrusion_indices, profile_def["curve_ucs"])
|
||||||
unit_direction = direction.normalized()
|
unit_direction = direction.normalized()
|
||||||
@@ -505,12 +509,3 @@ class Helper:
|
|||||||
return self.file.createIfcAxis2Placement2D(
|
return self.file.createIfcAxis2Placement2D(
|
||||||
self.create_cartesian_point(point.x, point.y), self.file.createIfcDirection((forward.x, forward.y))
|
self.create_cartesian_point(point.x, point.y), self.file.createIfcDirection((forward.x, forward.y))
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_ifc_axis_2_placement_3d(
|
|
||||||
self, point: Vector, up: Vector, forward: Vector
|
|
||||||
) -> ifcopenshell.entity_instance:
|
|
||||||
return self.file.createIfcAxis2Placement3D(
|
|
||||||
self.create_cartesian_point(point.x, point.y, point.z),
|
|
||||||
self.file.createIfcDirection((up.x, up.y, up.z)),
|
|
||||||
self.file.createIfcDirection((forward.x, forward.y, forward.z)),
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ from fractions import Fraction
|
|||||||
from typing import Optional, Union, Any, Literal, TYPE_CHECKING, NamedTuple
|
from typing import Optional, Union, Any, Literal, TYPE_CHECKING, NamedTuple
|
||||||
from collections.abc import Iterable, Sequence
|
from collections.abc import Iterable, Sequence
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from bonsai.bim.module.drawing.prop import (
|
from bonsai.bim.module.drawing.prop import (
|
||||||
@@ -778,11 +779,8 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def add_literal(cls, **attributes: str) -> ifcopenshell.entity_instance:
|
def add_literal(cls, **attributes: str) -> ifcopenshell.entity_instance:
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
origin = ifc_file.createIfcAxis2Placement3D(
|
builder = ShapeBuilder(ifc_file)
|
||||||
ifc_file.createIfcCartesianPoint((0.0, 0.0, 0.0)),
|
origin = builder.create_axis2_placement_3d()
|
||||||
ifc_file.createIfcDirection((0.0, 0.0, 1.0)),
|
|
||||||
ifc_file.createIfcDirection((1.0, 0.0, 0.0)),
|
|
||||||
)
|
|
||||||
ifc_literal = ifc_file.create_entity(
|
ifc_literal = ifc_file.create_entity(
|
||||||
"IfcTextLiteralWithExtent",
|
"IfcTextLiteralWithExtent",
|
||||||
attributes.get("Literal", "Literal"),
|
attributes.get("Literal", "Literal"),
|
||||||
|
|||||||
@@ -238,6 +238,8 @@ class Model(bonsai.core.tool.Model):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def export_surface(cls, obj: bpy.types.Object) -> Union[ifcopenshell.entity_instance, None]:
|
def export_surface(cls, obj: bpy.types.Object) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
|
ifc_file = tool.Ifc.get()
|
||||||
|
builder = ShapeBuilder(ifc_file)
|
||||||
p1, p2, p3 = [v.co.copy() for v in obj.data.vertices[0:3]]
|
p1, p2, p3 = [v.co.copy() for v in obj.data.vertices[0:3]]
|
||||||
|
|
||||||
edge1 = p2 - p1
|
edge1 = p2 - p1
|
||||||
@@ -271,13 +273,8 @@ class Model(bonsai.core.tool.Model):
|
|||||||
cls.bm.edges.ensure_lookup_table()
|
cls.bm.edges.ensure_lookup_table()
|
||||||
|
|
||||||
surface = tool.Ifc.get().createIfcCurveBoundedPlane()
|
surface = tool.Ifc.get().createIfcCurveBoundedPlane()
|
||||||
surface.BasisSurface = tool.Ifc.get().createIfcPlane(
|
placement = builder.create_axis2_placement_3d([o / cls.unit_scale for o in p1], z_axis, x_axis)
|
||||||
tool.Ifc.get().createIfcAxis2Placement3D(
|
surface.BasisSurface = ifc_file.create_entity("IfcPlane", placement)
|
||||||
tool.Ifc.get().createIfcCartesianPoint([o / cls.unit_scale for o in p1]),
|
|
||||||
tool.Ifc.get().createIfcDirection([float(o) for o in z_axis]),
|
|
||||||
tool.Ifc.get().createIfcDirection([float(o) for o in x_axis]),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
surface.OuterBoundary = tool.Ifc.get().add(profile_def.OuterCurve)
|
surface.OuterBoundary = tool.Ifc.get().add(profile_def.OuterCurve)
|
||||||
if profile_def.is_a("IfcArbitraryProfileDefWithVoids"):
|
if profile_def.is_a("IfcArbitraryProfileDefWithVoids"):
|
||||||
@@ -2124,13 +2121,8 @@ class Model(bonsai.core.tool.Model):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def add_extrusion_position(cls, extrusion: ifcopenshell.entity_instance, position: Vector) -> None:
|
def add_extrusion_position(cls, extrusion: ifcopenshell.entity_instance, position: Vector) -> None:
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
|
builder = ShapeBuilder(ifc_file)
|
||||||
new_position = ifc_file.createIfcAxis2Placement3D(
|
new_position = builder.create_axis2_placement_3d(position)
|
||||||
ifc_file.createIfcCartesianPoint(position),
|
|
||||||
ifc_file.createIfcDirection((0.0, 0.0, 1.0)),
|
|
||||||
ifc_file.createIfcDirection((1.0, 0.0, 0.0)),
|
|
||||||
)
|
|
||||||
|
|
||||||
extrusion.Position = new_position
|
extrusion.Position = new_position
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import ifcopenshell.api.owner
|
|||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import ifcopenshell.util.placement
|
import ifcopenshell.util.placement
|
||||||
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
from typing import Optional, Union, Any
|
from typing import Optional, Union, Any
|
||||||
|
|
||||||
NPArrayOfFloats = npt.NDArray[np.float64]
|
NPArrayOfFloats = npt.NDArray[np.float64]
|
||||||
@@ -74,6 +75,7 @@ class Usecase:
|
|||||||
if not hasattr(self.settings["product"], "ObjectPlacement"):
|
if not hasattr(self.settings["product"], "ObjectPlacement"):
|
||||||
return
|
return
|
||||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
||||||
|
self.builder = ShapeBuilder(self.file)
|
||||||
|
|
||||||
if not self.settings["is_si"]:
|
if not self.settings["is_si"]:
|
||||||
self.convert_matrix_to_si(self.settings["matrix"])
|
self.convert_matrix_to_si(self.settings["matrix"])
|
||||||
@@ -183,25 +185,12 @@ class Usecase:
|
|||||||
o = np.array((m[0][3], m[1][3], m[2][3]))
|
o = np.array((m[0][3], m[1][3], m[2][3]))
|
||||||
object_matrix = ifcopenshell.util.placement.a2p(o, z, x)
|
object_matrix = ifcopenshell.util.placement.a2p(o, z, x)
|
||||||
relative_placement_matrix = np.linalg.inv(relating_object_matrix) @ object_matrix
|
relative_placement_matrix = np.linalg.inv(relating_object_matrix) @ object_matrix
|
||||||
return self.create_ifc_axis_2_placement_3d(
|
return self.builder.create_axis2_placement_3d(
|
||||||
relative_placement_matrix[:, 3][0:3],
|
self.convert_si_to_unit(relative_placement_matrix[:, 3][0:3]),
|
||||||
relative_placement_matrix[:, 2][0:3],
|
relative_placement_matrix[:, 2][0:3],
|
||||||
relative_placement_matrix[:, 0][0:3],
|
relative_placement_matrix[:, 0][0:3],
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_ifc_axis_2_placement_3d(
|
|
||||||
self, point: NPArrayOfFloats, up: NPArrayOfFloats, forward: NPArrayOfFloats
|
|
||||||
) -> ifcopenshell.entity_instance:
|
|
||||||
return self.file.createIfcAxis2Placement3D(
|
|
||||||
self.create_cartesian_point(point),
|
|
||||||
self.file.createIfcDirection(up.tolist()),
|
|
||||||
self.file.createIfcDirection(forward.tolist()),
|
|
||||||
)
|
|
||||||
|
|
||||||
def create_cartesian_point(self, co: NPArrayOfFloats) -> ifcopenshell.entity_instance:
|
|
||||||
co = self.convert_si_to_unit(co)
|
|
||||||
return self.file.createIfcCartesianPoint(co.tolist())
|
|
||||||
|
|
||||||
def convert_si_to_unit(self, co: NPArrayOfFloats) -> NPArrayOfFloats:
|
def convert_si_to_unit(self, co: NPArrayOfFloats) -> NPArrayOfFloats:
|
||||||
return co / self.unit_scale
|
return co / self.unit_scale
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import ifcopenshell.util.geolocation
|
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
from math import sin, cos, radians
|
from math import sin, cos, radians
|
||||||
|
|
||||||
|
|
||||||
@@ -62,6 +62,7 @@ def edit_wcs(
|
|||||||
ifcopenshell.api.georeference.edit_wcs(model)
|
ifcopenshell.api.georeference.edit_wcs(model)
|
||||||
"""
|
"""
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
|
||||||
|
builder = ShapeBuilder(file)
|
||||||
if np.isclose(rotation, 0):
|
if np.isclose(rotation, 0):
|
||||||
xaxis_x = 1.0
|
xaxis_x = 1.0
|
||||||
xaxis_y = 0.0
|
xaxis_y = 0.0
|
||||||
@@ -74,14 +75,10 @@ def edit_wcs(
|
|||||||
old_wcs = context.WorldCoordinateSystem
|
old_wcs = context.WorldCoordinateSystem
|
||||||
if context.CoordinateSpaceDimension == 3:
|
if context.CoordinateSpaceDimension == 3:
|
||||||
if is_si:
|
if is_si:
|
||||||
point = file.createIfcCartesianPoint((x / unit_scale, y / unit_scale, z / unit_scale))
|
xyz = (x / unit_scale, y / unit_scale, z / unit_scale)
|
||||||
else:
|
else:
|
||||||
point = file.createIfcCartesianPoint((x, y, z))
|
xyz = (x, y, z)
|
||||||
placement = file.createIfcAxis2Placement3D(
|
placement = builder.create_axis2_placement_3d(xyz, (0.0, 0.0, 1.0), (xaxis_x, xaxis_y, 0.0))
|
||||||
point,
|
|
||||||
file.createIfcDirection((0.0, 0.0, 1.0)),
|
|
||||||
file.createIfcDirection((xaxis_x, xaxis_y, 0.0)),
|
|
||||||
)
|
|
||||||
elif context.CoordinateSpaceDimension == 2:
|
elif context.CoordinateSpaceDimension == 2:
|
||||||
if is_si:
|
if is_si:
|
||||||
point = file.createIfcCartesianPoint((x / unit_scale, y / unit_scale))
|
point = file.createIfcCartesianPoint((x / unit_scale, y / unit_scale))
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import numpy as np
|
|||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
from typing import Any, Union
|
from typing import Any, Union
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -78,9 +79,7 @@ class Clipping:
|
|||||||
|
|
||||||
if not ifc_file:
|
if not ifc_file:
|
||||||
ifc_file = first_operand.file
|
ifc_file = first_operand.file
|
||||||
|
builder = ShapeBuilder(ifc_file)
|
||||||
location = ifc_file.createIfcCartesianPoint([i / unit_scale for i in self.location])
|
|
||||||
direction = ifc_file.createIfcDirection(self.normal)
|
|
||||||
|
|
||||||
normal = np.array(self.normal)
|
normal = np.array(self.normal)
|
||||||
if np.allclose(normal, np.array([0.0, 0.0, 1.0]), atol=1e-2) or np.allclose(
|
if np.allclose(normal, np.array([0.0, 0.0, 1.0]), atol=1e-2) or np.allclose(
|
||||||
@@ -92,9 +91,9 @@ class Clipping:
|
|||||||
|
|
||||||
x_axis = np.cross(normal, arbitrary_vector)
|
x_axis = np.cross(normal, arbitrary_vector)
|
||||||
x_axis /= np.linalg.norm(x_axis)
|
x_axis /= np.linalg.norm(x_axis)
|
||||||
x_axis = ifc_file.createIfcDirection(x_axis.tolist())
|
|
||||||
|
|
||||||
plane = ifc_file.createIfcPlane(ifc_file.createIfcAxis2Placement3D(location, direction, x_axis))
|
placement = builder.create_axis2_placement_3d([i / unit_scale for i in self.location], self.normal, x_axis)
|
||||||
|
plane = ifc_file.create_entity("IfcPlane", placement)
|
||||||
|
|
||||||
second_operand = ifc_file.createIfcHalfSpaceSolid(plane, False)
|
second_operand = ifc_file.createIfcHalfSpaceSolid(plane, False)
|
||||||
return ifc_file.createIfcBooleanClippingResult("DIFFERENCE", first_operand, second_operand)
|
return ifc_file.createIfcBooleanClippingResult("DIFFERENCE", first_operand, second_operand)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import numpy as np
|
|||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.placement
|
import ifcopenshell.util.placement
|
||||||
import typing
|
import typing
|
||||||
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
|
|
||||||
|
|
||||||
class Patcher:
|
class Patcher:
|
||||||
@@ -97,6 +98,7 @@ class Patcher:
|
|||||||
self.ax = None
|
self.ax = None
|
||||||
self.ay = None
|
self.ay = None
|
||||||
self.az = None
|
self.az = None
|
||||||
|
self.builder = ShapeBuilder(file)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.ax = float(ax)
|
self.ax = float(ax)
|
||||||
@@ -183,15 +185,4 @@ class Patcher:
|
|||||||
z = np.array((m[0][2], m[1][2], m[2][2]))
|
z = np.array((m[0][2], m[1][2], m[2][2]))
|
||||||
o = np.array((m[0][3], m[1][3], m[2][3]))
|
o = np.array((m[0][3], m[1][3], m[2][3]))
|
||||||
object_matrix = ifcopenshell.util.placement.a2p(o, z, x)
|
object_matrix = ifcopenshell.util.placement.a2p(o, z, x)
|
||||||
return self.create_ifc_axis_2_placement_3d(
|
return self.builder.create_axis2_placement_3d_from_matrix(object_matrix)
|
||||||
object_matrix[:, 3][0:3],
|
|
||||||
object_matrix[:, 2][0:3],
|
|
||||||
object_matrix[:, 0][0:3],
|
|
||||||
)
|
|
||||||
|
|
||||||
def create_ifc_axis_2_placement_3d(self, point, up, forward):
|
|
||||||
return self.file.createIfcAxis2Placement3D(
|
|
||||||
self.file.createIfcCartesianPoint(point.tolist()),
|
|
||||||
self.file.createIfcDirection(up.tolist()),
|
|
||||||
self.file.createIfcDirection(forward.tolist()),
|
|
||||||
)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user