forked from jhmorel/Pivotier
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbatch_operations.py
More file actions
139 lines (109 loc) · 4.18 KB
/
batch_operations.py
File metadata and controls
139 lines (109 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
"""
Batch Operations - Provides batch processing capabilities for alignment operations.
This module extends the basic alignment operations to support batch processing
with additional controls and options for multiple object operations.
"""
import bpy
import bmesh
import mathutils
from typing import Set, List, Dict, Optional, Tuple
from . import preferences
def get_alignment_reference(context: bpy.types.Context) -> Tuple[mathutils.Vector, mathutils.Euler]:
"""Get reference location and rotation for alignment.
Args:
context: Current Blender context
Returns:
Tuple of (location, rotation) to use as reference
"""
wm = context.window_manager
settings = wm.pivotier.batch_align
if settings.relative_to == 'ACTIVE':
if not context.active_object:
return None
return context.active_object.location.copy(), context.active_object.rotation_euler.copy()
elif settings.relative_to == 'CURSOR':
cursor = context.scene.cursor
return cursor.location.copy(), cursor.rotation_euler.copy()
elif settings.relative_to == 'WORLD':
return mathutils.Vector((0, 0, 0)), mathutils.Euler((0, 0, 0))
else: # 'AVERAGE'
loc = mathutils.Vector((0, 0, 0))
rot = mathutils.Euler((0, 0, 0))
count = 0
for obj in context.selected_objects:
if obj.type == 'MESH':
loc += obj.location
rot.x += obj.rotation_euler.x
rot.y += obj.rotation_euler.y
rot.z += obj.rotation_euler.z
count += 1
if count > 0:
loc /= count
rot.x /= count
rot.y /= count
rot.z /= count
return loc, rot
def batch_align_objects(context: bpy.types.Context) -> Optional[str]:
"""Perform batch alignment of selected objects.
Args:
context: Current Blender context
Returns:
Error message if operation fails, None otherwise
"""
wm = context.window_manager
settings = wm.pivotier.batch_align
if len(context.selected_objects) < 1:
return "No objects selected"
if settings.relative_to == 'ACTIVE' and not context.active_object:
return "No active object selected"
# Get reference location and rotation
reference = get_alignment_reference(context)
if not reference:
return "Could not determine alignment reference"
ref_loc, ref_rot = reference
# Store initial states for undo
bpy.ops.ed.undo_push(message="Batch Align Objects")
# Apply alignment to selected objects
for obj in context.selected_objects:
if obj == context.active_object and settings.relative_to == 'ACTIVE':
continue
if settings.align_mode in {'LOCATION', 'BOTH'}:
if settings.align_x:
obj.location.x = ref_loc.x
if settings.align_y:
obj.location.y = ref_loc.y
if settings.align_z:
obj.location.z = ref_loc.z
if settings.align_mode in {'ROTATION', 'BOTH'}:
if settings.align_x:
obj.rotation_euler.x = ref_rot.x
if settings.align_y:
obj.rotation_euler.y = ref_rot.y
if settings.align_z:
obj.rotation_euler.z = ref_rot.z
return None
class OBJECT_OT_batch_align(bpy.types.Operator):
"""Align multiple objects with advanced options"""
bl_idname = "object.batch_align"
bl_label = "Batch Align Objects"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
return (context.mode == 'OBJECT' and
len(context.selected_objects) > 0)
def execute(self, context):
error = batch_align_objects(context)
if error:
self.report({'ERROR'}, error)
return {'CANCELLED'}
return {'FINISHED'}
# Registration
classes = (
OBJECT_OT_batch_align,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)