mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Purge usage of mathutils in grid API functions
The only thing left is add_representation which is Blender specific anyway and is slowly being refactored out.
This commit is contained in:
@@ -474,7 +474,7 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
if product.is_a("IfcGridAxis"):
|
||||
# Grid geometry does not follow the "representation" paradigm and needs to be treated specially
|
||||
ifcopenshell.api.grid.create_axis_curve(self.file, axis_curve=obj, grid_axis=product)
|
||||
tool.Model.create_axis_curve(obj, product)
|
||||
return
|
||||
elif product.is_a("IfcRelSpaceBoundary"):
|
||||
# TODO refactor
|
||||
|
||||
@@ -50,7 +50,7 @@ def add_object(self, context):
|
||||
"grid.create_grid_axis", tool.Ifc.get(), axis_tag=tag, uvw_axes="UAxes", grid=grid
|
||||
)
|
||||
tool.Ifc.link(result, obj)
|
||||
ifcopenshell.api.run("grid.create_axis_curve", tool.Ifc.get(), axis_curve=obj, grid_axis=result)
|
||||
tool.Model.create_axis_curve(obj, result)
|
||||
tool.Collector.assign(obj)
|
||||
|
||||
for i in range(0, self.total_v):
|
||||
@@ -69,7 +69,7 @@ def add_object(self, context):
|
||||
"grid.create_grid_axis", tool.Ifc.get(), axis_tag=tag, uvw_axes="VAxes", grid=grid
|
||||
)
|
||||
tool.Ifc.link(result, obj)
|
||||
ifcopenshell.api.run("grid.create_axis_curve", tool.Ifc.get(), axis_curve=obj, grid_axis=result)
|
||||
tool.Model.create_axis_curve(obj, result)
|
||||
tool.Collector.assign(obj)
|
||||
|
||||
tool.Root.reload_grid_decorator()
|
||||
|
||||
@@ -1978,3 +1978,11 @@ class Model(bonsai.core.tool.Model):
|
||||
x_angle = Vector((0, 1)).angle_signed(Vector((y, z)))
|
||||
|
||||
return x_angle
|
||||
|
||||
@classmethod
|
||||
def create_axis_curve(cls, obj: bpy.types.Object, grid_axis: ifcopenshell.entity_instance):
|
||||
m = tool.Surveyor.get_absolute_matrix(obj)
|
||||
points = [m @ np.array(v.co.to_4d()) for v in obj.data.vertices[0:2]]
|
||||
ifcopenshell.api.grid.create_axis_curve(
|
||||
tool.Ifc.get(), p1=points[0], p2=points[1], is_si=True, grid_axis=grid_axis
|
||||
)
|
||||
|
||||
@@ -26,32 +26,20 @@ geometry extrusions).
|
||||
from .. import wrap_usecases
|
||||
from .add_axis_representation import add_axis_representation
|
||||
from .add_boolean import add_boolean
|
||||
|
||||
try:
|
||||
from .add_door_representation import add_door_representation
|
||||
except ModuleNotFoundError as e:
|
||||
print(f"Note: API not available due to missing dependencies: geometry.add_door_representation - {e}")
|
||||
from .add_door_representation import add_door_representation
|
||||
from .add_footprint_representation import add_footprint_representation
|
||||
from .add_mesh_representation import add_mesh_representation
|
||||
from .add_profile_representation import add_profile_representation
|
||||
|
||||
try:
|
||||
from .add_railing_representation import add_railing_representation
|
||||
except ModuleNotFoundError as e:
|
||||
print(f"Note: API not available due to missing dependencies: geometry.add_railing_representation - {e}")
|
||||
from .add_railing_representation import add_railing_representation
|
||||
|
||||
try:
|
||||
from .add_representation import add_representation
|
||||
except ModuleNotFoundError as e:
|
||||
print(f"Note: API not available due to missing dependencies: geometry.add_representation - {e}")
|
||||
except ModuleNotFoundError:
|
||||
pass # Silently fail. This is Blender / Bonsai specific and on its way out.
|
||||
from .add_shape_aspect import add_shape_aspect
|
||||
from .add_slab_representation import add_slab_representation
|
||||
from .add_wall_representation import add_wall_representation
|
||||
|
||||
try:
|
||||
from .add_window_representation import add_window_representation
|
||||
except ModuleNotFoundError as e:
|
||||
print(f"Note: API not available due to missing dependencies: geometry.add_window_representation - {e}")
|
||||
from .add_window_representation import add_window_representation
|
||||
from .assign_representation import assign_representation
|
||||
from .connect_element import connect_element
|
||||
from .connect_path import connect_path
|
||||
|
||||
@@ -23,10 +23,7 @@ A grid in IFC may contain two or more axes running in two or more directions.
|
||||
|
||||
from .. import wrap_usecases
|
||||
|
||||
try:
|
||||
from .create_axis_curve import create_axis_curve
|
||||
except ModuleNotFoundError as e:
|
||||
print(f"Note: API not available due to missing dependencies: grid.create_axis_curve - {e}")
|
||||
from .create_axis_curve import create_axis_curve
|
||||
from .create_grid_axis import create_grid_axis
|
||||
from .remove_grid_axis import remove_grid_axis
|
||||
|
||||
|
||||
@@ -21,27 +21,26 @@ import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.placement
|
||||
from mathutils import Matrix # For now, we depend on Blender
|
||||
import bpy.types
|
||||
import numpy as np
|
||||
|
||||
|
||||
def create_axis_curve(
|
||||
file: ifcopenshell.file, axis_curve: bpy.types.Object, grid_axis: ifcopenshell.entity_instance
|
||||
file: ifcopenshell.file,
|
||||
*,
|
||||
p1: np.ndarray,
|
||||
p2: np.ndarray,
|
||||
grid_axis: ifcopenshell.entity_instance,
|
||||
is_si: bool = True,
|
||||
) -> None:
|
||||
"""Adds curve geometry to a grid axis to represent the axis extents
|
||||
|
||||
This currently depends on the Blender geometry kernel to function.
|
||||
|
||||
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.
|
||||
|
||||
:param axis_curve: The Blender object that contains a mesh data block with a
|
||||
single edge.
|
||||
:type axis_curve: bpy.types.Object
|
||||
:param p1: The first point of the grid axis
|
||||
:param p2: The second point of the grid axis
|
||||
:param grid_axis: The IfcGridAxis element to add geometry to.
|
||||
:type grid_axis: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
:param is_si: If true, the points are in meters, not project units
|
||||
|
||||
Example:
|
||||
|
||||
@@ -54,48 +53,27 @@ def create_axis_curve(
|
||||
axis_1 = ifcopenshell.api.grid.create_grid_axis(model,
|
||||
axis_tag="1", uvw_axes="VAxes", grid=grid)
|
||||
|
||||
# Assume you have these Blender objects in your active Blender session
|
||||
obj1 = bpy.data.objects.get("AxisA")
|
||||
obj2 = bpy.data.objects.get("Axis1")
|
||||
ifcopenshell.api.grid.create_axis_curve(model, axis_curve=obj1, grid_axis=axis_a)
|
||||
ifcopenshell.api.grid.create_axis_curve(model, axis_curve=obj2, grid_axis=axis_1)
|
||||
# By convention, alphabetic grids are horizontal, and numeric are vertical
|
||||
ifcopenshell.api.grid.create_axis_curve(
|
||||
model, p1=np.array((0., 0., 0.)), p2=np.array((10., 0., 0.)), grid_axis=axis_a)
|
||||
ifcopenshell.api.grid.create_axis_curve(
|
||||
model, p1=np.array((0., 0., 0.)), p2=np.array((0., 10., 0.)), grid_axis=axis_1)
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {
|
||||
"axis_curve": axis_curve, # A Blender object
|
||||
"grid_axis": grid_axis,
|
||||
}
|
||||
return usecase.execute()
|
||||
existing_curve = grid_axis.AxisCurve
|
||||
|
||||
if is_si:
|
||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(file)
|
||||
p1 /= unit_scale
|
||||
p2 /= unit_scale
|
||||
|
||||
class Usecase:
|
||||
def execute(self):
|
||||
existing_curve = self.settings["grid_axis"].AxisCurve
|
||||
|
||||
self.settings["unit_scale"] = ifcopenshell.util.unit.calculate_unit_scale(self.file)
|
||||
grid = [i for i in self.file.get_inverse(self.settings["grid_axis"]) if i.is_a("IfcGrid")][0]
|
||||
grid_matrix_i = Matrix(ifcopenshell.util.placement.get_local_placement(grid.ObjectPlacement))
|
||||
grid_matrix_i.translation *= self.settings["unit_scale"]
|
||||
grid_matrix_i = grid_matrix_i.inverted()
|
||||
points = [
|
||||
grid_matrix_i @ (self.settings["axis_curve"].matrix_world @ v.co)
|
||||
for v in self.settings["axis_curve"].data.vertices[0:2]
|
||||
]
|
||||
self.settings["grid_axis"].AxisCurve = self.file.createIfcPolyline(
|
||||
[
|
||||
self.create_cartesian_point(points[0][0], points[0][1]),
|
||||
self.create_cartesian_point(points[1][0], points[1][1]),
|
||||
]
|
||||
grid = [i for i in file.get_inverse(grid_axis) if i.is_a("IfcGrid")][0]
|
||||
grid_matrix_i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(grid.ObjectPlacement))
|
||||
grid_axis.AxisCurve = file.createIfcPolyline(
|
||||
(
|
||||
file.createIfcCartesianPoint((grid_matrix_i @ p1).tolist()),
|
||||
file.createIfcCartesianPoint((grid_matrix_i @ p2).tolist()),
|
||||
)
|
||||
)
|
||||
|
||||
if existing_curve:
|
||||
ifcopenshell.util.element.remove_deep2(self.file, existing_curve)
|
||||
|
||||
def create_cartesian_point(self, x, y):
|
||||
x = self.convert_si_to_unit(x)
|
||||
y = self.convert_si_to_unit(y)
|
||||
return self.file.createIfcCartesianPoint((x, y))
|
||||
|
||||
def convert_si_to_unit(self, co):
|
||||
return co / self.settings["unit_scale"]
|
||||
if existing_curve:
|
||||
ifcopenshell.util.element.remove_deep2(file, existing_curve)
|
||||
|
||||
@@ -25,9 +25,6 @@ dependencies = [
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
# mathutils is broken on Python < 3.10.
|
||||
# See: https://gitlab.com/ideasman42/blender-mathutils/-/merge_requests/3
|
||||
geometry = ["mathutils"]
|
||||
dev = ["pytest"]
|
||||
|
||||
[project.urls]
|
||||
|
||||
Reference in New Issue
Block a user