You've already forked stocker_helper
Compare commits
2 Commits
1548ebf4ff
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 660a5c700e | |||
| cc04a8ee48 |
+2
-2
@@ -6,7 +6,7 @@ from .scripts import phase2_geometry as logic
|
|||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "Stocker Helper",
|
"name": "Stocker Helper",
|
||||||
"author": "Gary Ritchie",
|
"author": "Gary Ritchie",
|
||||||
"version": (0, 3, 1),
|
"version": (0, 5, 0),
|
||||||
"blender": (4, 0, 0),
|
"blender": (4, 0, 0),
|
||||||
"location": "View3D > Sidebar > Stocker",
|
"location": "View3D > Sidebar > Stocker",
|
||||||
"description": "Creates boundary object with Stocker Geometry Nodes assets (sold separately.)",
|
"description": "Creates boundary object with Stocker Geometry Nodes assets (sold separately.)",
|
||||||
@@ -97,7 +97,7 @@ class STOCKER_OT_setup(bpy.types.Operator):
|
|||||||
selected_objs = context.selected_objects
|
selected_objs = context.selected_objects
|
||||||
|
|
||||||
# 2. Run logic from previous phases
|
# 2. Run logic from previous phases
|
||||||
bounds = logic.calculate_global_bounds(selected_objs)
|
bounds = logic.calculate_global_bounds(selected_objs, parent=selected_objs[0])
|
||||||
if not bounds:
|
if not bounds:
|
||||||
self.report({'ERROR'}, "No valid mesh objects selected.")
|
self.report({'ERROR'}, "No valid mesh objects selected.")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|||||||
+26
-18
@@ -21,10 +21,18 @@ def resolve_to_mesh_objects(obj):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def calculate_global_bounds(selected_objects):
|
def calculate_global_bounds(selected_objects, parent=None):
|
||||||
if not selected_objects:
|
if not selected_objects:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# Determine target coordinate space. When parent is given, compute bounds
|
||||||
|
# in the parent's local space so the boundary size matches the parent's
|
||||||
|
# orientation (not world-space AABB which grows with rotation).
|
||||||
|
if parent:
|
||||||
|
target_matrix = parent.matrix_world.inverted_safe()
|
||||||
|
else:
|
||||||
|
target_matrix = mathutils.Matrix.Identity(4)
|
||||||
|
|
||||||
min_x, min_y, min_z = float('inf'), float('inf'), float('inf')
|
min_x, min_y, min_z = float('inf'), float('inf'), float('inf')
|
||||||
max_x, max_y, max_z = float('-inf'), float('-inf'), float('-inf')
|
max_x, max_y, max_z = float('-inf'), float('-inf'), float('-inf')
|
||||||
|
|
||||||
@@ -37,25 +45,22 @@ def calculate_global_bounds(selected_objects):
|
|||||||
for source_obj in mesh_objects:
|
for source_obj in mesh_objects:
|
||||||
found_any_mesh = True
|
found_any_mesh = True
|
||||||
|
|
||||||
|
# Get world-space corners (use bound_box_world when available)
|
||||||
if hasattr(source_obj, 'bound_box_world') and source_obj.bound_box_world:
|
if hasattr(source_obj, 'bound_box_world') and source_obj.bound_box_world:
|
||||||
bbw = source_obj.bound_box_world
|
world_corners = source_obj.bound_box_world
|
||||||
for corner in bbw:
|
|
||||||
min_x = min(min_x, corner.x)
|
|
||||||
min_y = min(min_y, corner.y)
|
|
||||||
min_z = min(min_z, corner.z)
|
|
||||||
max_x = max(max_x, corner.x)
|
|
||||||
max_y = max(max_y, corner.y)
|
|
||||||
max_z = max(max_z, corner.z)
|
|
||||||
else:
|
else:
|
||||||
matrix = source_obj.matrix_world
|
matrix = source_obj.matrix_world
|
||||||
for corner in source_obj.bound_box:
|
world_corners = [matrix @ mathutils.Vector(corner) for corner in source_obj.bound_box]
|
||||||
world_corner = matrix @ mathutils.Vector(corner)
|
|
||||||
min_x = min(min_x, world_corner.x)
|
# Transform to target coordinate space and update AABB
|
||||||
min_y = min(min_y, world_corner.y)
|
for corner in world_corners:
|
||||||
min_z = min(min_z, world_corner.z)
|
target_corner = target_matrix @ corner
|
||||||
max_x = max(max_x, world_corner.x)
|
min_x = min(min_x, target_corner.x)
|
||||||
max_y = max(max_y, world_corner.y)
|
min_y = min(min_y, target_corner.y)
|
||||||
max_z = max(max_z, world_corner.z)
|
min_z = min(min_z, target_corner.z)
|
||||||
|
max_x = max(max_x, target_corner.x)
|
||||||
|
max_y = max(max_y, target_corner.y)
|
||||||
|
max_z = max(max_z, target_corner.z)
|
||||||
|
|
||||||
if not found_any_mesh:
|
if not found_any_mesh:
|
||||||
return None
|
return None
|
||||||
@@ -116,7 +121,10 @@ def create_aligned_boundary_cube(bounds, parent=None, mode=None):
|
|||||||
mesh.from_pydata(verts, [], faces)
|
mesh.from_pydata(verts, [], faces)
|
||||||
mesh.update()
|
mesh.update()
|
||||||
|
|
||||||
# Parent to selected object so boundary follows instances
|
# Parent to selected object so boundary follows instances.
|
||||||
|
# Bounds are already in parent-local space (computed by
|
||||||
|
# calculate_global_bounds with parent matrix), so location values are
|
||||||
|
# directly usable after parenting — no additional conversion needed.
|
||||||
if parent:
|
if parent:
|
||||||
obj.parent = parent
|
obj.parent = parent
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user