mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 02:07:36 +00:00
Fix invalid IfcGrid cartesian points (774a770)
They were saved as 4d coordinates, not 2d.
This commit is contained in:
@@ -48,7 +48,7 @@ from bonsai.bim import import_ifc
|
|||||||
|
|
||||||
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData, WindowData, DoorData
|
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData, WindowData, DoorData
|
||||||
from bonsai.bim.module.model.opening import FilledOpeningGenerator
|
from bonsai.bim.module.model.opening import FilledOpeningGenerator
|
||||||
from ifcopenshell.util.shape_builder import ShapeBuilder
|
from ifcopenshell.util.shape_builder import ShapeBuilder, np_to_3d
|
||||||
from typing import Optional, Union, TypeVar, Any, Iterable, Literal, TYPE_CHECKING, Sequence, TypedDict
|
from typing import Optional, Union, TypeVar, Any, Iterable, Literal, TYPE_CHECKING, Sequence, TypedDict
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
@@ -2126,7 +2126,7 @@ class Model(bonsai.core.tool.Model):
|
|||||||
assert isinstance(obj.data, bpy.types.Mesh)
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
points = [m @ np.array(v.co.to_4d()) for v in obj.data.vertices[0:2]]
|
points = [m @ np.array(v.co.to_4d()) for v in obj.data.vertices[0:2]]
|
||||||
ifcopenshell.api.grid.create_axis_curve(
|
ifcopenshell.api.grid.create_axis_curve(
|
||||||
tool.Ifc.get(), p1=points[0], p2=points[1], is_si=True, grid_axis=grid_axis
|
tool.Ifc.get(), p1=np_to_3d(points[0]), p2=np_to_3d(points[1]), is_si=True, grid_axis=grid_axis
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import ifcopenshell.util.element
|
|||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import ifcopenshell.util.placement
|
import ifcopenshell.util.placement
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from ifcopenshell.util.shape_builder import VectorType, V, ifc_safe_vector_type
|
from ifcopenshell.util.shape_builder import VectorType, V, ifc_safe_vector_type, np_apply_matrix
|
||||||
|
|
||||||
|
|
||||||
def create_axis_curve(
|
def create_axis_curve(
|
||||||
@@ -38,6 +38,10 @@ def create_axis_curve(
|
|||||||
An IFC grid will have a minimum of two axes (typically perpendicular). Each
|
An IFC grid will have a minimum of two axes (typically perpendicular). Each
|
||||||
axis will then have a line which represents the extents of the axis.
|
axis will then have a line which represents the extents of the axis.
|
||||||
|
|
||||||
|
Points are provided as 3D coordinates in world space.
|
||||||
|
During axis creation, the coordinates will be localized relative to IfcGrid
|
||||||
|
and saved as 2D.
|
||||||
|
|
||||||
:param p1: The first point of the grid axis
|
:param p1: The first point of the grid axis
|
||||||
:param p2: The second point of the grid axis
|
:param p2: The second point of the grid axis
|
||||||
:param grid_axis: The IfcGridAxis element to add geometry to.
|
:param grid_axis: The IfcGridAxis element to add geometry to.
|
||||||
@@ -61,19 +65,19 @@ def create_axis_curve(
|
|||||||
model, p1=np.array((0., 0., 0.)), p2=np.array((0., 10., 0.)), grid_axis=axis_1)
|
model, p1=np.array((0., 0., 0.)), p2=np.array((0., 10., 0.)), grid_axis=axis_1)
|
||||||
"""
|
"""
|
||||||
existing_curve = grid_axis.AxisCurve
|
existing_curve = grid_axis.AxisCurve
|
||||||
p1, p2 = V(p1), V(p2)
|
points = V([p1, p2])
|
||||||
if is_si:
|
if is_si:
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
|
||||||
p1 /= unit_scale
|
points /= unit_scale
|
||||||
p2 /= unit_scale
|
|
||||||
|
|
||||||
grid = [i for i in file.get_inverse(grid_axis) if i.is_a("IfcGrid")][0]
|
grid = next(i for i in file.get_inverse(grid_axis) if i.is_a("IfcGrid"))
|
||||||
grid_matrix_i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(grid.ObjectPlacement))
|
grid_matrix_i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(grid.ObjectPlacement))
|
||||||
|
p1, p2 = ifc_safe_vector_type(np_apply_matrix(points, grid_matrix_i))
|
||||||
grid_axis.AxisCurve = file.create_entity(
|
grid_axis.AxisCurve = file.create_entity(
|
||||||
"IfcPolyline",
|
"IfcPolyline",
|
||||||
(
|
(
|
||||||
file.create_entity("IfcCartesianPoint", ifc_safe_vector_type(grid_matrix_i @ p1)),
|
file.create_entity("IfcCartesianPoint", p1[:2]),
|
||||||
file.create_entity("IfcCartesianPoint", ifc_safe_vector_type(grid_matrix_i @ p2)),
|
file.create_entity("IfcCartesianPoint", p2[:2]),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,16 @@ def np_to_4x4(matrix_3x3: np.ndarray) -> np.ndarray:
|
|||||||
return matrix_4x4
|
return matrix_4x4
|
||||||
|
|
||||||
|
|
||||||
|
def np_apply_matrix(vectors: SequenceOfVectors, matrix: npt.NDArray) -> npt.NDArray:
|
||||||
|
"""
|
||||||
|
:param vectors: Nx3 array of vectors.
|
||||||
|
:param matrix: 4x4 transformation matrix.
|
||||||
|
"""
|
||||||
|
m3x3 = matrix[:3, :3]
|
||||||
|
translation = matrix[:3, 3]
|
||||||
|
return vectors @ m3x3.T + translation
|
||||||
|
|
||||||
|
|
||||||
def np_angle(a: VectorType, b: VectorType) -> float:
|
def np_angle(a: VectorType, b: VectorType) -> float:
|
||||||
"""Get angle between vectors in radians.
|
"""Get angle between vectors in radians.
|
||||||
Designed to work similar to `Vector.angle`.
|
Designed to work similar to `Vector.angle`.
|
||||||
|
|||||||
Reference in New Issue
Block a user