-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathset_pivot_to_cursor.py
More file actions
149 lines (111 loc) · 4.6 KB
/
set_pivot_to_cursor.py
File metadata and controls
149 lines (111 loc) · 4.6 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
140
141
142
143
144
145
146
147
148
149
"""
Set Pivot to Cursor - Sets object pivot points to the 3D cursor.
This module handles setting the origin (pivot point) of selected objects
to match the 3D cursor's position and orientation, with an option to
invert the Z axis by rotating the origin 180° on the local X axis.
"""
import bpy
import math
from typing import Optional
def set_pivot_to_cursor(context) -> Optional[str]:
"""Set pivot point to 3D cursor for all selected objects.
Moves the origin of each selected object to the 3D cursor position,
aligning the origin rotation to match the cursor orientation.
Args:
context: Current Blender context
Returns:
Error message if operation fails, None otherwise
"""
if not context.selected_objects:
return "No objects selected"
# Save current transform settings
original_orientation = context.scene.transform_orientation_slots[0].type
original_use_origin = context.tool_settings.use_transform_data_origin
try:
# Enable "Affect Only Origins" transform mode
context.tool_settings.use_transform_data_origin = True
# Set transform orientation to CURSOR so origin aligns to cursor rotation
context.scene.transform_orientation_slots[0].type = 'CURSOR'
# Move all selected origins to the cursor position
bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
# Align origin orientation to match cursor rotation
bpy.ops.transform.transform(mode='ALIGN')
finally:
# Restore transform settings regardless of success or failure
context.scene.transform_orientation_slots[0].type = original_orientation
context.tool_settings.use_transform_data_origin = original_use_origin
return None
def invert_pivot_z_axis(context) -> Optional[str]:
"""Rotate the origin 180° on X to invert the Z axis direction.
Args:
context: Current Blender context
Returns:
Error message if operation fails, None otherwise
"""
if not context.selected_objects:
return "No objects selected"
# Save current transform settings
original_orientation = context.scene.transform_orientation_slots[0].type
original_use_origin = context.tool_settings.use_transform_data_origin
try:
# Enable "Affect Only Origins" transform mode
context.tool_settings.use_transform_data_origin = True
# Use LOCAL orientation so rotation is relative to each object's own axes
context.scene.transform_orientation_slots[0].type = 'LOCAL'
# Rotate 180° on X axis — this flips the Z axis direction
bpy.ops.transform.rotate(
value=math.pi,
orient_axis='X',
constraint_axis=(True, False, False)
)
finally:
# Restore transform settings regardless of success or failure
context.scene.transform_orientation_slots[0].type = original_orientation
context.tool_settings.use_transform_data_origin = original_use_origin
return None
class OBJECT_OT_set_pivot_to_cursor(bpy.types.Operator):
"""Set pivot point to 3D cursor position and orientation"""
bl_idname = "object.set_pivot_to_cursor"
bl_label = "Set Pivot to Cursor"
bl_description = (
"Move the origin of selected objects to the 3D cursor, "
"matching its position and orientation"
)
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
return context.mode == 'OBJECT' and len(context.selected_objects) > 0
def execute(self, context):
error = set_pivot_to_cursor(context)
if error:
self.report({'ERROR'}, error)
return {'CANCELLED'}
return {'FINISHED'}
class OBJECT_OT_invert_pivot_z_axis(bpy.types.Operator):
"""Invert the Z axis of the pivot point by rotating 180° on local X"""
bl_idname = "object.invert_pivot_z_axis"
bl_label = "Invert Pivot Z Axis"
bl_description = (
"Rotate the origin 180° on the local X axis, "
"effectively flipping the Z axis direction"
)
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
return context.mode == 'OBJECT' and len(context.selected_objects) > 0
def execute(self, context):
error = invert_pivot_z_axis(context)
if error:
self.report({'ERROR'}, error)
return {'CANCELLED'}
return {'FINISHED'}
classes = (
OBJECT_OT_set_pivot_to_cursor,
OBJECT_OT_invert_pivot_z_axis,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)