mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +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())
|
||||
rep_obj = 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:
|
||||
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
|
||||
else:
|
||||
verts = [v.co / unit_scale for v in obj.data.vertices]
|
||||
verts += coordinate_offset
|
||||
verts /= unit_scale
|
||||
faces = [p.vertices[:] for p in obj.data.polygons]
|
||||
|
||||
representation = tool.Geometry.get_active_representation(rep_obj)
|
||||
assert 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)
|
||||
elif representation.RepresentationType in ("Tessellation"):
|
||||
elif representation_type in ("Tessellation"):
|
||||
item = builder.mesh(verts, faces)
|
||||
else:
|
||||
assert False, f"Unexpected representation type: '{representation_type}'."
|
||||
|
||||
representation.Items = list(representation.Items) + [item]
|
||||
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())
|
||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
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:
|
||||
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
|
||||
else:
|
||||
verts = [v.co / unit_scale for v in obj.data.vertices]
|
||||
verts += coordinate_offset
|
||||
verts /= unit_scale
|
||||
faces = [p.vertices[:] for p in obj.data.polygons]
|
||||
|
||||
representation = tool.Geometry.get_active_representation(props.representation_obj)
|
||||
|
||||
@@ -23,6 +23,8 @@ import json
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import numpy as np
|
||||
import numpy.typing as npt
|
||||
from ifcopenshell import entity_instance
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
@@ -1143,6 +1145,14 @@ class Blender(bonsai.core.tool.Blender):
|
||||
else:
|
||||
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
|
||||
def get_last_commit_hash(cls) -> Union[str, None]:
|
||||
"""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()
|
||||
rep_obj = props.representation_obj
|
||||
assert rep_obj
|
||||
if (coordinate_offset := cls.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]
|
||||
else:
|
||||
verts = [v.co / unit_scale for v in obj.data.vertices]
|
||||
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:
|
||||
verts += coordinate_offset
|
||||
verts /= unit_scale
|
||||
|
||||
faces = [p.vertices[:] for p in obj.data.polygons]
|
||||
if item.is_a("IfcAdvancedBrep"):
|
||||
|
||||
Reference in New Issue
Block a user