I’m running into a wall trying to get an operator to work correctly during Redo when it uses a custom orientation + bpy.ops.transform.transform on a newly added mesh object.
The operator functions correctly when it’s initially invoked. However, as soon as I modify a setting in the Redo panel, the custom transform is lost. Is there something that needs to be handled during Redo that I’m missing?
To test out:
- Start with default .blend
- Execute the python below
- Go into edit mode for the Cube, use Face select, and select 1 of the side faces
- Execute the below operator
- Works fine - new cylinder has proper orientation
- Modify the “Vertices” setting in the redo panel
- Fails - new cylinder has incorrect, default orientation
import bpy
class DCONFIG_OT_test_redo(bpy.types.Operator):
bl_idname = "dconfig.test_redo"
bl_label = "DC Test Redo"
bl_description = "Test Redo"
bl_options = {'REGISTER', 'UNDO'}
radius: bpy.props.FloatProperty(name="Radius", default=0.5, step=1)
depth: bpy.props.FloatProperty(name="Depth", default=0.5, step=1)
vertices: bpy.props.IntProperty(name="Vertices", default=8)
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.prop(self, "radius")
layout.prop(self, "depth")
layout.prop(self, "vertices")
def add_primitive(self, context):
bpy.ops.mesh.primitive_cylinder_add(radius=self.radius, depth=self.depth, vertices=self.vertices)
def execute(self, context):
prev_cursor_location = tuple(context.scene.cursor.location)
is_edit_mode = context.mode == 'EDIT_MESH'
if context.active_object.type == 'MESH' and is_edit_mode and tuple(context.scene.tool_settings.mesh_select_mode) == (False, False, True):
prev_active = context.active_object
prev_orientation = context.scene.transform_orientation_slots[0].type
bpy.ops.view3d.snap_cursor_to_selected() # snap cursor to selected set of faces
bpy.ops.transform.create_orientation(name="AddAxis", use=True, overwrite=True) # create custom transform for the selection
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
self.add_primitive(context)
bpy.ops.transform.transform(mode='ALIGN', value=(0, 0, 0, 0), constraint_axis=(False, False, False))
context.view_layer.objects.active = prev_active
context.view_layer.objects.active.select_set(True)
bpy.ops.object.join()
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
context.scene.transform_orientation_slots[0].type = prev_orientation
context.scene.cursor.location = prev_cursor_location
return {'FINISHED'}
def register():
bpy.utils.register_class(DCONFIG_OT_test_redo)
def unregister():
bpy.utils.unregister_class(DCONFIG_OT_test_redo)
if __name__ == '__main__':
register()