mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Fix possible float precision issues similar to f6087613f0
This commit is contained in:
@@ -98,20 +98,25 @@ class OverrideMeshSeparate(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
rep_obj = props.representation_obj
|
rep_obj = props.representation_obj
|
||||||
assert rep_obj
|
assert rep_obj
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
|
verts = tool.Blender.get_verts_coordinates(obj.data.vertices)
|
||||||
|
verts = verts.astype("d")
|
||||||
if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None:
|
if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None:
|
||||||
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
|
verts += coordinate_offset
|
||||||
else:
|
verts /= unit_scale
|
||||||
verts = [v.co / unit_scale for v in obj.data.vertices]
|
|
||||||
faces = [p.vertices[:] for p in obj.data.polygons]
|
faces = [p.vertices[:] for p in obj.data.polygons]
|
||||||
|
|
||||||
representation = tool.Geometry.get_active_representation(rep_obj)
|
representation = tool.Geometry.get_active_representation(rep_obj)
|
||||||
assert representation
|
assert representation
|
||||||
representation = ifcopenshell.util.representation.resolve_representation(representation)
|
representation = ifcopenshell.util.representation.resolve_representation(representation)
|
||||||
|
|
||||||
if representation.RepresentationType in ("Brep", "AdvancedBrep"):
|
representation_type = representation.RepresentationType
|
||||||
|
if representation_type in ("Brep", "AdvancedBrep"):
|
||||||
item = builder.faceted_brep(verts, faces)
|
item = builder.faceted_brep(verts, faces)
|
||||||
elif representation.RepresentationType in ("Tessellation"):
|
elif representation_type in ("Tessellation"):
|
||||||
item = builder.mesh(verts, faces)
|
item = builder.mesh(verts, faces)
|
||||||
|
else:
|
||||||
|
assert False, f"Unexpected representation type: '{representation_type}'."
|
||||||
|
|
||||||
representation.Items = list(representation.Items) + [item]
|
representation.Items = list(representation.Items) + [item]
|
||||||
obj.name = obj.data.name = f"Item/{item.is_a()}/{item.id()}"
|
obj.name = obj.data.name = f"Item/{item.is_a()}/{item.id()}"
|
||||||
@@ -2928,10 +2933,13 @@ class AddMeshlikeItem(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
|
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
rep_obj = tool.Geometry.get_geometry_props().representation_obj
|
rep_obj = tool.Geometry.get_geometry_props().representation_obj
|
||||||
|
assert rep_obj
|
||||||
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
|
verts = tool.Blender.get_verts_coordinates(obj.data.vertices)
|
||||||
|
verts = verts.astype("d")
|
||||||
if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None:
|
if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None:
|
||||||
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
|
verts += coordinate_offset
|
||||||
else:
|
verts /= unit_scale
|
||||||
verts = [v.co / unit_scale for v in obj.data.vertices]
|
|
||||||
faces = [p.vertices[:] for p in obj.data.polygons]
|
faces = [p.vertices[:] for p in obj.data.polygons]
|
||||||
|
|
||||||
representation = tool.Geometry.get_active_representation(props.representation_obj)
|
representation = tool.Geometry.get_active_representation(props.representation_obj)
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import json
|
|||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import numpy as np
|
||||||
|
import numpy.typing as npt
|
||||||
from ifcopenshell import entity_instance
|
from ifcopenshell import entity_instance
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
@@ -1143,6 +1145,14 @@ class Blender(bonsai.core.tool.Blender):
|
|||||||
else:
|
else:
|
||||||
raise NotImplementedError(f"Attribute data type `{data_type}` not implemented yet")
|
raise NotImplementedError(f"Attribute data type `{data_type}` not implemented yet")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_verts_coordinates(cls, verts: bpy.types.MeshVertices) -> npt.NDArray[np.float32]:
|
||||||
|
# It's faster to get them as f and then convert to d
|
||||||
|
# with .astype("d"), if precision is needed.
|
||||||
|
coords = np.empty(len(verts) * 3, dtype="f")
|
||||||
|
coords = coords.reshape(-1, 3)
|
||||||
|
return coords
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_last_commit_hash(cls) -> Union[str, None]:
|
def get_last_commit_hash(cls) -> Union[str, None]:
|
||||||
"""Get 8 symbols of last commit hash if it's present or return None otherwise."""
|
"""Get 8 symbols of last commit hash if it's present or return None otherwise."""
|
||||||
|
|||||||
@@ -1818,10 +1818,12 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
props = tool.Geometry.get_geometry_props()
|
props = tool.Geometry.get_geometry_props()
|
||||||
rep_obj = props.representation_obj
|
rep_obj = props.representation_obj
|
||||||
assert rep_obj
|
assert rep_obj
|
||||||
if (coordinate_offset := cls.get_cartesian_point_offset(rep_obj)) is not None:
|
assert isinstance(obj.data, bpy.types.Mesh)
|
||||||
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
|
verts = tool.Blender.get_verts_coordinates(obj.data.vertices)
|
||||||
else:
|
verts = verts.astype("d")
|
||||||
verts = [v.co / unit_scale for v in obj.data.vertices]
|
if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None:
|
||||||
|
verts += coordinate_offset
|
||||||
|
verts /= unit_scale
|
||||||
|
|
||||||
faces = [p.vertices[:] for p in obj.data.polygons]
|
faces = [p.vertices[:] for p in obj.data.polygons]
|
||||||
if item.is_a("IfcAdvancedBrep"):
|
if item.is_a("IfcAdvancedBrep"):
|
||||||
|
|||||||
Reference in New Issue
Block a user