Blender 5.0 - accomodate new mathutils buffer protocol type

Long story short - since 5.0 `np.array(Vector())` is now producing `np.float32` instead of `np.float64`. So we have to provide `dtype` explicitly to support both <5.0 and >= 5.0.

See https://projects.blender.org/blender/blender/issues/149283
This commit is contained in:
Andrej730
2025-11-03 19:32:21 +05:00
parent 1a9bd1891e
commit 3bdfbebc02
5 changed files with 16 additions and 12 deletions
+2 -2
View File
@@ -235,8 +235,8 @@ class DecoratorData:
cut_cache = {}
slice_cache = {}
fill_cache = {}
camera_location_checksum = None
camera_rotation_checksum = None
camera_location_checksum = ""
camera_rotation_checksum = ""
@classmethod
def clear_cache(cls):
@@ -1731,20 +1731,23 @@ class CutDecorator:
def cache_camera_matrix(self):
obj = bpy.context.scene.camera
DecoratorData.camera_location_checksum = repr(np.array(obj.matrix_world.translation).tobytes())
DecoratorData.camera_rotation_checksum = repr(np.array(obj.matrix_world.to_3x3()).tobytes())
# Explicit `dtype` for Blender <5.0 compatibility.
DecoratorData.camera_location_checksum = repr(
np.array(obj.matrix_world.translation, dtype=np.float32).tobytes()
)
DecoratorData.camera_rotation_checksum = repr(np.array(obj.matrix_world.to_3x3(), dtype=np.float32).tobytes())
def is_camera_moved(self):
if not DecoratorData.camera_location_checksum:
self.cache_camera_matrix()
return True # Let's be conservative
obj = bpy.context.scene.camera
loc_check = np.frombuffer(eval(DecoratorData.camera_location_checksum))
loc_check = np.frombuffer(eval(DecoratorData.camera_location_checksum), dtype=np.float32)
loc_real = np.array(obj.matrix_world.translation).flatten()
if not np.allclose(loc_check, loc_real, atol=1e-4): # 0.1 mm
self.cache_camera_matrix()
return True
rot_check = np.frombuffer(eval(DecoratorData.camera_rotation_checksum)).reshape(3, 3)
rot_check = np.frombuffer(eval(DecoratorData.camera_rotation_checksum), dtype=np.float32).reshape(3, 3)
rot_real = np.array(obj.matrix_world.to_3x3())
rot_dot = np.dot(rot_check, rot_real.T)
angle_rad = np.arccos(np.clip((np.trace(rot_dot) - 1) / 2, -1, 1))
+3 -2
View File
@@ -1146,8 +1146,9 @@ class Geometry(bonsai.core.tool.Geometry):
def record_object_position(cls, obj: bpy.types.Object) -> None:
# These are recorded separately because they have different numerical tolerances
props = tool.Blender.get_object_bim_props(obj)
props.location_checksum = repr(np.array(obj.matrix_world.translation).tobytes())
props.rotation_checksum = repr(np.array(obj.matrix_world.to_3x3()).tobytes())
# Explicit dtype for Blender <5.0 compatibility.
props.location_checksum = repr(np.array(obj.matrix_world.translation, dtype=np.float32).tobytes())
props.rotation_checksum = repr(np.array(obj.matrix_world.to_3x3(), dtype=np.float32).tobytes())
@classmethod
def remove_connection(cls, connection: ifcopenshell.entity_instance) -> None:
+2 -2
View File
@@ -110,11 +110,11 @@ class Ifc(bonsai.core.tool.Ifc):
oprops = tool.Blender.get_object_bim_props(obj)
if not oprops.location_checksum:
return True # Let's be conservative
loc_check = np.frombuffer(eval(oprops.location_checksum))
loc_check = np.frombuffer(eval(oprops.location_checksum), dtype=np.float32)
loc_real = np.array(obj.matrix_world.translation).flatten()
if not np.allclose(loc_check, loc_real, atol=1e-4): # 0.1 mm
return True
rot_check = np.frombuffer(eval(oprops.rotation_checksum)).reshape(3, 3)
rot_check = np.frombuffer(eval(oprops.rotation_checksum), dtype=np.float32).reshape(3, 3)
rot_real = np.array(obj.matrix_world.to_3x3())
rot_dot = np.dot(rot_check, rot_real.T)
angle_rad = np.arccos(np.clip((np.trace(rot_dot) - 1) / 2, -1, 1))
+2 -2
View File
@@ -321,8 +321,8 @@ class TestRecordObjectPosition(NewFile):
obj = bpy.data.objects.new("Object", None)
props = tool.Blender.get_object_bim_props(obj)
subject.record_object_position(obj)
assert props.location_checksum == repr(np.array(obj.matrix_world.translation).tobytes())
assert props.rotation_checksum == repr(np.array(obj.matrix_world.to_3x3()).tobytes())
assert props.location_checksum == repr(np.array(obj.matrix_world.translation, dtype=np.float32).tobytes())
assert props.rotation_checksum == repr(np.array(obj.matrix_world.to_3x3(), dtype=np.float32).tobytes())
class TestRemoveConnection(NewFile):