up
This commit is contained in:
parent
68e61445a2
commit
d19fa0044a
2 changed files with 27 additions and 11 deletions
|
|
@ -39,25 +39,34 @@ def get_referenced_objects(node, visited=None):
|
||||||
return objs
|
return objs
|
||||||
|
|
||||||
_is_updating = False
|
_is_updating = False
|
||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def depsgraph_update_handler(scene, depsgraph):
|
def depsgraph_update_handler(scene, depsgraph):
|
||||||
global _is_updating
|
global _is_updating
|
||||||
if _is_updating:
|
if _is_updating:
|
||||||
return
|
return
|
||||||
|
|
||||||
updated_objects = {update.id.name for update in depsgraph.updates if isinstance(update.id, bpy.types.Object)}
|
# Names of objects that have changed
|
||||||
if not updated_objects:
|
updated_object_names = {update.id.name for update in depsgraph.updates if isinstance(update.id, bpy.types.Object)}
|
||||||
|
|
||||||
|
# Also check for mesh updates (happens in Edit Mode)
|
||||||
|
updated_meshes = {update.id.name for update in depsgraph.updates if isinstance(update.id, bpy.types.Mesh)}
|
||||||
|
if updated_meshes:
|
||||||
|
for obj in bpy.data.objects:
|
||||||
|
if obj.type == 'MESH' and obj.data in updated_meshes:
|
||||||
|
updated_object_names.add(obj.name)
|
||||||
|
|
||||||
|
if not updated_object_names:
|
||||||
return
|
return
|
||||||
|
|
||||||
for tree in bpy.data.node_groups:
|
for tree in bpy.data.node_groups:
|
||||||
if tree.bl_idname != "SLICETREE_NodeTree":
|
if tree.bl_idname != "SLICETREE_NodeTree":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for node in tree.nodes:
|
for node in tree.nodes:
|
||||||
if node.bl_idname == "SLICENODE_Executor" and getattr(node, "auto_refresh", False):
|
if node.bl_idname == "SLICENODE_Executor" and getattr(node, "auto_refresh", False):
|
||||||
referenced = get_referenced_objects(node)
|
referenced = get_referenced_objects(node)
|
||||||
if any(obj.name in updated_objects for obj in referenced):
|
referenced_names = {obj.name for obj in referenced if obj}
|
||||||
|
if updated_object_names & referenced_names:
|
||||||
_is_updating = True
|
_is_updating = True
|
||||||
try:
|
try:
|
||||||
node.evaluate()
|
node.evaluate()
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ class SlicingObject():
|
||||||
scene_scale: float = bpy.context.scene.unit_settings.scale_length
|
scene_scale: float = bpy.context.scene.unit_settings.scale_length
|
||||||
|
|
||||||
if obj:
|
if obj:
|
||||||
|
if obj.mode == 'EDIT':
|
||||||
|
obj.update_from_editmode()
|
||||||
eval_objects = obj.evaluated_get(depsgraph)
|
eval_objects = obj.evaluated_get(depsgraph)
|
||||||
self.mesh = objects_to_tris([eval_objects], 1000 * scene_scale)
|
self.mesh = objects_to_tris([eval_objects], 1000 * scene_scale)
|
||||||
else:
|
else:
|
||||||
|
|
@ -219,6 +221,8 @@ class SlicingGroup():
|
||||||
|
|
||||||
self.wipe_tower_xy = self.center_xy[0:2]
|
self.wipe_tower_xy = self.center_xy[0:2]
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
|
if obj.mode == 'EDIT':
|
||||||
|
obj.update_from_editmode()
|
||||||
eval_obj = obj.evaluated_get(depsgraph)
|
eval_obj = obj.evaluated_get(depsgraph)
|
||||||
if eval_obj.blendertoprusaslicer.object_type == 'WipeTower':
|
if eval_obj.blendertoprusaslicer.object_type == 'WipeTower':
|
||||||
self.wipe_tower_xy = np.array(eval_obj.location[0:2]) * scale_tx
|
self.wipe_tower_xy = np.array(eval_obj.location[0:2]) * scale_tx
|
||||||
|
|
@ -367,7 +371,7 @@ def _cached_capture_mesh_edges(
|
||||||
# This helper expects that the object and mesh exist and are accessible via bpy.data
|
# This helper expects that the object and mesh exist and are accessible via bpy.data
|
||||||
obj = bpy.data.objects.get(obj_name)
|
obj = bpy.data.objects.get(obj_name)
|
||||||
if not obj: return []
|
if not obj: return []
|
||||||
|
|
||||||
# We don't use obj_eval here directly as it's not hashable,
|
# We don't use obj_eval here directly as it's not hashable,
|
||||||
# but we assume this is called when we know we need to re-capture.
|
# but we assume this is called when we know we need to re-capture.
|
||||||
# The actual capture logic stays the same but is now inside this cached function.
|
# The actual capture logic stays the same but is now inside this cached function.
|
||||||
|
|
@ -386,7 +390,7 @@ def _cached_capture_mesh_edges(
|
||||||
num_verts = len(mesh.vertices)
|
num_verts = len(mesh.vertices)
|
||||||
verts = np.empty((num_verts, 3), dtype=np.float64)
|
verts = np.empty((num_verts, 3), dtype=np.float64)
|
||||||
mesh.vertices.foreach_get("co", verts.ravel())
|
mesh.vertices.foreach_get("co", verts.ravel())
|
||||||
|
|
||||||
tx_verts = (verts @ world_mat[:3, :3].T + world_mat[:3, 3]) * scene_scale
|
tx_verts = (verts @ world_mat[:3, :3].T + world_mat[:3, 3]) * scene_scale
|
||||||
|
|
||||||
edges_set = {tuple(sorted(e.vertices)) for e in mesh.edges}
|
edges_set = {tuple(sorted(e.vertices)) for e in mesh.edges}
|
||||||
|
|
@ -406,20 +410,23 @@ def _cached_capture_mesh_edges(
|
||||||
final_paths.append(path_coords)
|
final_paths.append(path_coords)
|
||||||
|
|
||||||
return final_paths
|
return final_paths
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if hasattr(obj_eval, "to_mesh_clear"):
|
if hasattr(obj_eval, "to_mesh_clear"):
|
||||||
obj_eval.to_mesh_clear()
|
obj_eval.to_mesh_clear()
|
||||||
|
|
||||||
def capture_mesh_edges(obj: Object) -> list[NDArray[float64]]:
|
def capture_mesh_edges(obj: Object) -> list[NDArray[float64]]:
|
||||||
if not obj or not obj.data: return []
|
if not obj or not obj.data: return []
|
||||||
|
|
||||||
|
if obj.mode == 'EDIT':
|
||||||
|
obj.update_from_editmode()
|
||||||
|
|
||||||
assert bpy.context.scene and bpy.context.scene.unit_settings
|
assert bpy.context.scene and bpy.context.scene.unit_settings
|
||||||
scene_scale = 1000.0 * bpy.context.scene.unit_settings.scale_length
|
scene_scale = 1000.0 * bpy.context.scene.unit_settings.scale_length
|
||||||
|
|
||||||
# Create a hashable key from object state
|
# Create a hashable key from object state
|
||||||
matrix_tuple = tuple(val for row in obj.matrix_world for val in row) # Flattened tuple
|
matrix_tuple = tuple(val for row in obj.matrix_world for val in row) # Flattened tuple
|
||||||
|
|
||||||
return _cached_capture_mesh_edges(
|
return _cached_capture_mesh_edges(
|
||||||
obj.name,
|
obj.name,
|
||||||
obj.data.name,
|
obj.data.name,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue