Skip to content

Python API

Actions

  • Open Pie Menu
    bpy.ops.wm.ih_pivot_breeze_pie()

    Open the Pie Menu in a supported 3D View or UV Editor.

  • Activate Pivot
    bpy.ops.wm.ih_pivot_breeze_toggle()

    Start a regular pivot session, or apply and finish the active session.

  • Bounding Box Pivot
    bpy.ops.wm.ih_pivot_breeze_toggle_bounds()

    Place a mesh pivot from bounding-box anchors in 3D.

  • Pivot by 3 Points
    bpy.ops.wm.ih_pivot_breeze_toggle_three_points()

    Build a pivot frame from three geometry points in 3D.

  • Reset Pivot
    bpy.ops.wm.ih_pivot_breeze_reset_pivot()

    Reset pivot position and rotation using the active editor workflow.

  • Reset Pivot Position
    bpy.ops.wm.ih_pivot_breeze_reset_position()

    Reset only the pivot or cursor position.

  • Reset Pivot Rotation
    bpy.ops.wm.ih_pivot_breeze_reset_rotation()

    Reset only the 3D pivot orientation.

  • Move to Zero
    bpy.ops.wm.ih_pivot_breeze_move_to_zero()

    Move objects, editable geometry, or UVs to zero.

  • Pivot to Zero
    bpy.ops.wm.ih_pivot_breeze_pivot_to_zero()

    Move object origins or the active editor cursor to zero.

Runtime, sessions, and transforms

  • Get Runtime State
    bpy.ops.wm.ih_pivot_breeze_runtime_get()

    Read whether PivotBreeze runtime services are enabled.

  • Set Runtime State
    bpy.ops.wm.ih_pivot_breeze_runtime_set()

    Idempotently enable or disable runtime services.

  • Toggle Runtime State
    bpy.ops.wm.ih_pivot_breeze_addon_enabled_toggle()

    Toggle runtime services without returning JSON.

  • Get Session State
    bpy.ops.wm.ih_pivot_breeze_session_get()

    Read the current 3D or UV session state.

  • Start Session
    bpy.ops.wm.ih_pivot_breeze_session_start()

    Start a session with an explicit placement mode.

  • Finish Session
    bpy.ops.wm.ih_pivot_breeze_session_finish()

    Apply and close the active session.

  • Cancel Session
    bpy.ops.wm.ih_pivot_breeze_session_cancel()

    Cancel the active session and restore captured cursor state where supported.

  • Get Active Pivot Transform
    bpy.ops.wm.ih_pivot_breeze_transform_get()

    Read the active 3D helper transform in world space.

  • Set Active Pivot Transform
    bpy.ops.wm.ih_pivot_breeze_transform_set()

    Assign the active 3D helper location and rotation.

Preferences

  • Get Exit Preference
    bpy.ops.wm.ih_pivot_breeze_exit_setting_get()

    Read one context-specific exit preference.

  • Set Exit Preference
    bpy.ops.wm.ih_pivot_breeze_exit_setting_set()

    Idempotently set one context-specific exit preference.

  • Toggle Exit Preference
    bpy.ops.wm.ih_pivot_breeze_exit_setting_toggle()

    Toggle one context-specific exit preference.

  • Get Reset Preference
    bpy.ops.wm.ih_pivot_breeze_reset_setting_get()

    Read one context-specific reset preference.

  • Set Reset Preference
    bpy.ops.wm.ih_pivot_breeze_reset_setting_set()

    Idempotently set one context-specific reset preference.

  • Toggle Reset Preference
    bpy.ops.wm.ih_pivot_breeze_reset_setting_toggle()

    Toggle one context-specific reset preference.

Hotkeys and Pie Menu

  • Get Hotkey
    bpy.ops.wm.ih_pivot_breeze_hotkey_get()

    Read one stored hotkey definition.

  • Set Hotkey State
    bpy.ops.wm.ih_pivot_breeze_hotkey_set_enabled()

    Idempotently enable or disable one hotkey.

  • Toggle Hotkey State
    bpy.ops.wm.ih_pivot_breeze_hotkey_toggle_enabled()

    Toggle one hotkey between enabled and disabled.

  • Rebind Hotkey
    bpy.ops.wm.ih_pivot_breeze_hotkey_rebind()

    Change one hotkey key and modifier combination.

  • Get Hotkey Conflicts
    bpy.ops.wm.ih_pivot_breeze_hotkey_conflicts_get()

    Inspect Blender keymap conflicts for one hotkey.

  • Reset Hotkey
    bpy.ops.wm.ih_pivot_breeze_hotkey_reset()

    Restore one hotkey to its default definition.

  • Reset All Hotkeys
    bpy.ops.wm.ih_pivot_breeze_hotkeys_reset_all()

    Restore every PivotBreeze hotkey to its defaults.

  • Get Pie Menu Slot
    bpy.ops.wm.ih_pivot_breeze_pie_slot_get()

    Read the action assigned to one Pie Menu slot.

  • Set Pie Menu Slot
    bpy.ops.wm.ih_pivot_breeze_pie_slot_set()

    Assign an action or NONE to one Pie Menu slot.

Discovery

  • Set Placement Limit
    bpy.ops.wm.ih_pivot_breeze_placement_limit_set(vertex_limit=100000)

    Set the geometry budget or enable and disable placement.

  • Get Configuration
    bpy.ops.wm.ih_pivot_breeze_config_get()

    Read the complete API-managed configuration snapshot.

  • Get Capabilities
    bpy.ops.wm.ih_pivot_breeze_capabilities_get()

    Discover API metadata, identifiers, schemas, and supported features.

Use registered bpy.ops commands as the stable integration surface. Installed extension import names include an extension-repository namespace and can differ between installations. Do not hard-code a helper object name or a private module path in an external add-on.

Commands return Blender status sets such as {'FINISHED'} and {'CANCELLED'}. An error report can cause a Python RuntimeError instead of merely returning {'CANCELLED'}. Invalid RNA parameters can fail before execution. Check the return value and handle exceptions before consuming a result.

State and configuration operators write JSON to bpy.context.window_manager.ih_pivot_breeze_api_result. This is one shared last-result string, not a queue. Read it immediately after a successful call. Action operators do not clear or replace it, and failures can leave an older result in place. The result property is not saved with the blend file.

import bpy
import json
status = bpy.ops.wm.ih_pivot_breeze_capabilities_get()
if status != {'FINISHED'}:
raise RuntimeError('Capabilities query did not finish')
capabilities = json.loads(bpy.context.window_manager.ih_pivot_breeze_api_result)
if capabilities['api_version'] != 4:
raise RuntimeError('This integration expects PivotBreeze API version 4')
print(capabilities['editors'], capabilities['zero_actions'])

The wm action wrappers find a suitable existing window, editor, and WINDOW region. They do not create editors or arbitrarily change editor types. Ordinary activation/reset commands prefer an existing active session; otherwise they use the current UV editor or a suitable 3D View.

Zero commands default to editor='AUTO': the current 3D View or UV Editor is used. From Console or another unsupported editor, an active pivot session is preferred, otherwise a suitable 3D View is used. Pass editor='VIEW_3D' or editor='UV' to target that editor explicitly; a matching active session takes priority for explicit requests. Missing editors and incompatible sessions fail clearly without changing editor types.

The wrapper’s poll() is not a full geometry validation promise. Selection, data ownership, constraints, and other restrictions are checked during execution. Call from Blender’s main thread, not from an unrelated Python process or worker.

All commands in this table return a status set and do not write JSON.

Complete operator Parameters Resulting action
wm.ih_pivot_breeze_pie None Open the Pie Menu in the active or nearest supported 3D View/UV Editor
wm.ih_pivot_breeze_toggle None Start a pivot session or apply and close the current one
wm.ih_pivot_breeze_toggle_bounds None Toggle Bounding Box Pivot in the 3D View
wm.ih_pivot_breeze_toggle_three_points None Toggle three-point placement in 3D
wm.ih_pivot_breeze_reset_pivot None Reset pivot position and 3D orientation
wm.ih_pivot_breeze_reset_position None Reset only pivot position
wm.ih_pivot_breeze_reset_rotation None Reset only 3D pivot orientation; reject UV
wm.ih_pivot_breeze_move_to_zero editor='AUTO' Move objects, geometry, or UVs to zero
wm.ih_pivot_breeze_pivot_to_zero editor='AUTO' Move origins or cursors to zero
wm.ih_pivot_breeze_addon_enabled_toggle None Toggle runtime services, not extension installation
import bpy
# Requires selected objects in a suitable 3D View context.
bpy.ops.wm.ih_pivot_breeze_move_to_zero()
# Separate example: requires Mesh Edit Mode and an open UV Editor.
bpy.ops.wm.ih_pivot_breeze_pivot_to_zero(editor='UV')
Complete operator Parameters JSON kind
wm.ih_pivot_breeze_runtime_get None runtime
wm.ih_pivot_breeze_runtime_set enabled=True runtime
wm.ih_pivot_breeze_session_get None session
wm.ih_pivot_breeze_session_start placement_mode='NONE' session
wm.ih_pivot_breeze_session_finish keep_selection=False session
wm.ih_pivot_breeze_session_cancel None session

runtime_set is idempotent. Disabling runtime cancels an active pivot without applying it, stops tracking, removes owned tools and keymaps, and leaves the control API registered. It does not uninstall the extension or save preferences. Session start and action operators require enabled runtime.

session_start is idempotent and accepts NONE, BOUNDS, or THREE_POINTS. If a session is already active, its workflow and preset remain unchanged. session_finish and session_cancel are safe when no session is active. keep_selection=True has an effect only where the Object workflow supports it.

Starting a 3D session through either session_start or a toggle operator uses the same interactive geometry-picking behavior as the UI. Pivot Placement Vertex Limit defaults to 100,000. The original selected objects must fit first; all visible objects become eligible only if their combined count fits. Otherwise picking uses only the original selection, or is disabled if that selection exceeds the limit. Zero disables geometry picking, not manual transforms. Bounds stay selected-only. Three-point placement also supports Sculpt. Mesh, Curve, Surface, Text, and Metaball objects are supported; UV uses its separate 2D workflow. Objects in the active picking scope temporarily receive Viewport Display > Wireframe, and their individual original values are restored on every close, cancellation, failed activation, and Undo suspension path.

There is no public click-picking operator or separate wireframe command. These are session implementation details rather than independent actions. Integrations that need deterministic programmatic placement should start a session and call wm.ih_pivot_breeze_transform_set with explicit coordinates and rotation.

3D cancellation does not transfer the helper transform to object origins and restores the session-entry 3D Cursor position, rotation and rotation mode. UV cancellation restores the session-entry UV cursor. This also applies after completed helper moves and rotations. Cancellation does not undo geometry edits already committed by a preceding zero command.

An inactive session payload is exactly:

{"active": false, "kind": "session"}

An active 3D session adds workflow, mode, placement_mode, helper, editor: 'VIEW_3D', world location, and WXYZ rotation_quaternion when its helper is available. mode is the original workflow mode, not necessarily the temporary current Blender mode. UV reports editor: 'UV', two-coordinate location, helper: null, and rotation: null; it has no 3D quaternion field. Treat transform fields as conditional, not mandatory on every session payload.

import bpy
import json
bpy.ops.wm.ih_pivot_breeze_session_start(placement_mode='NONE')
bpy.ops.wm.ih_pivot_breeze_session_get()
state = json.loads(bpy.context.window_manager.ih_pivot_breeze_api_result)
if state.get('editor') == 'VIEW_3D' and state.get('helper'):
print(state['location'], state['rotation_quaternion'])
bpy.ops.wm.ih_pivot_breeze_session_cancel()

An integration should first query whether a session is already active before assuming ownership of starting and finishing one. An idempotent start does not transfer ownership from another caller.

Complete operator Parameters JSON kind
wm.ih_pivot_breeze_transform_get None pivot_transform
wm.ih_pivot_breeze_transform_set location=(0, 0, 0), rotation_quaternion=(1, 0, 0, 0) pivot_transform

These commands require an active 3D session and a live helper. They reject UV sessions. Set edits the helper, synchronizes the 3D Cursor, preserves helper scale, and does not finish the session or immediately apply its transform to source object origins.

Location uses world XYZ; quaternion order is WXYZ. Quaternions are normalized using a stable norm, including large nonzero components. NaN/non-finite stored values and zero quaternions are rejected before mutation. Blender RNA floating properties can clamp out-of-range inputs before the operator sees them; callers should also validate external numerical data before passing it to Blender.

Set is a complete transform assignment, not a partial patch: omitting location uses zero, and omitting rotation uses identity. To change only one component, read the transform and explicitly pass the component that must be preserved.

import bpy
import json
# Requires an active 3D pivot session.
bpy.ops.wm.ih_pivot_breeze_transform_get()
transform = json.loads(bpy.context.window_manager.ih_pivot_breeze_api_result)
bpy.ops.wm.ih_pivot_breeze_transform_set(
location=(1.0, 2.0, 3.0),
rotation_quaternion=transform['rotation_quaternion'],
)

Both commands report active: true, space: 'WORLD', location, and rotation_quaternion in their successful JSON payload. The setter is marked UNDO; read the Undo and failure handling section before using it inside another operator.

Configuration commands remain available while runtime services are disabled, provided the extension and its preferences are registered. Preference changes are not scene geometry Undo operations and do not call Save Preferences.

The two families accept OBJECT, EDIT, SCULPT, and UV. EDIT covers Mesh, Curve, and Surface. Their defaults use OBJECT and enabled=True.

Complete operator Parameters JSON kind
wm.ih_pivot_breeze_exit_setting_get setting='OBJECT' exit_setting
wm.ih_pivot_breeze_exit_setting_set setting='OBJECT', enabled=True exit_setting
wm.ih_pivot_breeze_exit_setting_toggle setting='OBJECT' exit_setting
wm.ih_pivot_breeze_reset_setting_get setting='OBJECT' reset_setting
wm.ih_pivot_breeze_reset_setting_set setting='OBJECT', enabled=True reset_setting
wm.ih_pivot_breeze_reset_setting_toggle setting='OBJECT' reset_setting

Payloads contain kind, the requested setting, and the resulting enabled Boolean. Set is idempotent; Toggle intentionally changes state on every call.

Aim is fixed to Shift + Left Click and is no longer configurable. The deprecated wm.ih_pivot_breeze_aim_settings_set remains registered for one minor-release transition, but always returns CANCELLED with a warning and changes nothing. Legacy preference fields remain hidden and do not affect the binding. Configuration discovery reports the effective fixed binding.

The hotkey parameter uses the identifiers in the default-shortcuts table and defaults to ACTIVATE_PIVOT. Query capabilities for Blender’s valid native event identifiers, including keyboard, mouse, NDOF, text-input and timer events.

Complete operator Additional parameters JSON kind
wm.ih_pivot_breeze_hotkey_get None hotkey
wm.ih_pivot_breeze_hotkey_set_enabled enabled=True hotkey
wm.ih_pivot_breeze_hotkey_toggle_enabled None hotkey
wm.ih_pivot_breeze_hotkey_rebind key='D', value='PRESS', ctrl=False, shift=False, alt=False, oskey=False hotkey
wm.ih_pivot_breeze_hotkey_conflicts_get None hotkey_conflicts
wm.ih_pivot_breeze_hotkey_reset None hotkey
wm.ih_pivot_breeze_hotkeys_reset_all No parameters, including no hotkey hotkeys_reset

A hotkey payload contains hotkey, enabled, key, value, ctrl, shift, alt, and oskey. Rebind rejects event types and values that Blender does not recognize. Rebind replaces the entire key/modifier combination, preserving enabled state. Reset restores both the original binding and its enabled state.

Conflict queries include hotkey, enabled, count, and a conflicts array. Each conflict contains description, keyconfig, keymap, operator, and shortcut. A disabled shortcut can still be inspected. Reset All returns a hotkeys array with one ordinary hotkey payload per action.

import bpy
# Example configuration change: rebind, then enable deliberately.
bpy.ops.wm.ih_pivot_breeze_hotkey_rebind(
hotkey='MOVE_TO_ZERO', key='BUTTON4MOUSE', ctrl=False, shift=False, alt=False,
)
bpy.ops.wm.ih_pivot_breeze_hotkey_set_enabled(
hotkey='MOVE_TO_ZERO', enabled=True,
)

Pie slots, configuration, and capabilities

Section titled “Pie slots, configuration, and capabilities”
Complete operator Parameters JSON kind
wm.ih_pivot_breeze_pie_slot_get slot=0 pie_slot
wm.ih_pivot_breeze_pie_slot_set slot=0, action='NONE' pie_slot
wm.ih_pivot_breeze_config_get None config
wm.ih_pivot_breeze_placement_limit_set vertex_limit=100000, optional enabled=True placement_limit
wm.ih_pivot_breeze_capabilities_get None capabilities

Slots range from 0 through 7. Validate external indices yourself; Blender RNA can clamp integer properties to their declared bounds. A pie payload contains slot, direction, and action. Setting a slot does not enable the Pie Menu.

config_get returns the following current-state fields:

  • runtime_enabled;
  • placement.vertex_limit and placement.enabled;
  • aim.enabled, aim.ctrl, aim.shift, and aim.alt;
  • exit_settings and reset_settings, keyed by the four setting identifiers;
  • hotkeys, keyed by hotkey identifier;
  • pie_menu.enabled and the eight pie_menu.slots payloads;
  • appearance.center_handle_color and appearance.use_custom_center_handle_style;
  • reset_behavior.use_empty_hierarchies;
  • snap_memory.enabled (also controls persistence between Blender sessions).

capabilities_get returns supported identifiers and contracts: addon_version, api_version, editors, exit_settings, reset_settings, hotkey_keys, hotkeys with defaults, pie_menu with its canonical open operator, result_property, placement_modes, zero_actions, transform, uv_pivot, aim, and placement_limit. The last contains set, default=100000, unit='VERTICES', and zero_disables_picking=True. aim exposes configurable=False, button='LEFTMOUSE', and requires_modifier=True.

For an active 3D session, session-state results additionally contain placement: scope (SELECTED, ALL_VISIBLE, or DISABLED), reason, enabled, vertex_limit, and the admitted objects names. A null reason means admission succeeded. Other reasons are USER_DISABLED (checkbox off or zero limit), LIMIT_EXCEEDED, NO_GEOMETRY, and SOURCE_MISSING. The query resolves the owning viewport, even from another editor. Three-point sessions also return three_points.points in world coordinates, primary_axis (the axis assigned by the second point), and current_axis (the axis currently being placed), using X, Y, or Z. These fields are absent from UV sessions.

Set the budget without requiring an active session:

bpy.ops.wm.ih_pivot_breeze_placement_limit_set(vertex_limit=100000)

The result contains kind='placement_limit', vertex_limit, and enabled. Set only enabled=False to disable geometry placement without changing the stored limit; omit enabled to preserve its current state. The checkbox defaults to true and is stored in ih_pivot_breeze_placement_enabled. Preferences lists this API immediately above the add-on enable/disable command. Integers must be nonnegative; Blender RNA can clamp values. The corresponding saved preference is ih_pivot_breeze_placement_vertex_limit. The retired all-visible and selected-only Boolean RNA fields remain hidden for compatibility but no longer control picking. Existing Boolean values are not converted into a numeric budget.

There is no bulk config_set, file import/export API, or public JSON dispatcher. Use the registered per-setting commands. Appearance and snap-memory options can be read through configuration discovery but are configured through Preferences; they do not have dedicated public setter operators.

During an active Bounding Box session, bpy.ops.view3d.ih_pivot_breeze_bounds_orientation_toggle() toggles Global/Local, using the same operation as R and supporting native Undo. It takes no arguments. Session queries return bounds_orientation='GLOBAL' or 'LOCAL' for bounds sessions. New sessions always begin in Global; this is not a persistent preference. Local uses each source object’s rotation, or the active object’s rotation for combined Edit Mesh selection. Pivot rotation follows the chosen frame when an anchor is accepted.

For calls already inside an appropriate editor, these registered operators are available. Prefix them with bpy.ops. when calling from Python.

3D View operator UV equivalent
view3d.ih_pivot_breeze_toggle uv.ih_pivot_breeze_toggle
view3d.ih_pivot_breeze_toggle_bounds Not available
view3d.ih_pivot_breeze_toggle_three_points Not available
view3d.ih_pivot_breeze_reset_pivot uv.ih_pivot_breeze_reset_pivot
view3d.ih_pivot_breeze_reset_position uv.ih_pivot_breeze_reset_position
view3d.ih_pivot_breeze_reset_rotation None
view3d.ih_pivot_breeze_move_to_zero uv.ih_pivot_breeze_move_to_zero
view3d.ih_pivot_breeze_pivot_to_zero uv.ih_pivot_breeze_pivot_to_zero
view3d.ih_pivot_breeze_pie uv.ih_pivot_breeze_pie

The contextual zero commands have no editor parameter; their namespace selects the editor. wm.ih_pivot_breeze_pie is the canonical context-independent Pie Menu entry point. It prefers the active session, then the current supported editor, and otherwise searches open windows for a compatible 3D View or UV Editor. The Pie Menu’s availability also depends on its enabled preference. After resolving the editor, the wrapper invokes the same view3d or uv operator used by the configured hotkey.

view3d.ih_pivot_breeze_exit and uv.ih_pivot_breeze_exit are internal exit plumbing with reason, apply_changes, and keep_selection properties. Use session_finish or session_cancel for integrations. wm.ih_pivot_breeze_hotkey_conflicts_info is the adjacent tooltip/UI helper; use hotkey_rebind and hotkey_conflicts_get for scripting.

The package also exposes convenience functions open_pie, toggle, toggle_bounds, toggle_three_points, reset_pivot, reset_position, reset_rotation, move_to_zero, and pivot_to_zero. They accept context=None; the last two also accept editor='VIEW_3D'. api.finish_session additionally accepts apply_changes=True and keep_selection=False. These are secondary Python entry points; installed namespaces vary, so the registered operators remain the documented cross-add-on contract.

API version 4 adds native event identifiers, the oskey hotkey field, and the context-independent wm.ih_pivot_breeze_pie entry point. Existing operator names and package-level convenience functions remain unchanged. Read structured results immediately after each command. Public contracts are deprecated for at least one documented minor release before removal in a breaking release.

The WindowManager RNA result property remains ih_pivot_breeze_api_result; it is an RNA property, not an unprefixed custom-property dictionary key.

view3d.ih_pivot_breeze_three_points_back() removes the most recent picked point while the active 3D session uses three-point placement. It has no parameters and returns FINISHED on a handled step or CANCELLED when there is no applicable active input. The normal UI exposes this through Backspace.

view3d.ih_pivot_breeze_three_points_cycle_axis() cycles the axis controlled by the second point through X, Y, and Z while three-point placement is active. It has no parameters, preserves accepted points, and is exposed through R.

Hotkey API identifier Binding Enabled
ACTIVATE_PIVOT 1 No
ACTIVATE_PIVOT_BOUNDS 2 No
ACTIVATE_PIVOT_THREE_POINTS 3 No
RESET_PIVOT 4 No
RESET_PIVOT_POSITION 5 No
RESET_PIVOT_ROTATION 6 No
MOVE_TO_ZERO 7 No
PIVOT_TO_ZERO 8 No
PIVOT_PIE_MENU Ctrl+D Yes

The number keys are placeholders, not recommended Blender keymap replacements. Rebinding does not enable a disabled shortcut. Conflict inspection is read-only. Priority registration adds PivotBreeze-owned entries; it must not disable or rewrite another add-on’s or Blender’s keymap items.

Each shortcut row uses Blender’s native compact keymap controls. Choose Keyboard, Mouse, NDOF, Tweak, Timer, or another available mapping type in the first field, then use the adjacent native event field. Keyboard, mouse, and NDOF fields capture the complete event, including Ctrl, Shift, Alt, and the platform OS modifier. The click that activates the field is not assigned as the shortcut.

Slot Direction Action identifier
0 Left MOVE_TO_ZERO
1 Right PIVOT_TO_ZERO
2 Bottom RESET_PIVOT
3 Top ACTIVATE_PIVOT
4 Top Left ACTIVATE_BOUNDS
5 Top Right ACTIVATE_THREE_POINTS
6 Bottom Left RESET_POSITION
7 Bottom Right RESET_ROTATION

NONE leaves a slot empty. Pie action identifiers differ from some hotkey identifiers: for example, RESET_POSITION versus RESET_PIVOT_POSITION. Preferences display directions in a visual order; the API always uses the slot numbers above. Every editor keeps the complete layout; unavailable actions are disabled.

Since API version 3, the session argument and result field are named placement_mode. Its values are NONE, BOUNDS, and THREE_POINTS; capability metadata uses placement_modes. The former snapping-preset fields have no compatibility aliases. UV supports only NONE. Removed pie actions do not reuse stored enum values; obsolete explicit assignments resolve to empty slots and can be reassigned.

Blender owns geometry snapshots. PivotBreeze additionally reconciles its Python session state, temporary helper identity, and editor cursor state through official Undo/Redo handlers and deferred UI restoration. This is add-on logic built on Blender’s API, not a promise that Blender automatically serializes Python objects or editor state. Geometry is not stored in a second custom undo stack. Cursor history stores positions and fingerprints used to match snapshots.

A zero action and resuming its previously active session are intended as one caller-owned Undo operation. Intermediate selection/geometry undos must not consume that command’s cursor restoration. Native UV session activation and cursor operations have their own explicit boundaries; do not add arbitrary extra undo pushes around them.

The UNDO operator flag, the caller’s context, nested operator execution, and the optional Python undo positional argument all affect history. Do not assume that a bare script call behaves exactly like a user clicking a button. For an external operator performing several related changes, define one deliberate Undo boundary and test that complete path in Blender.

Validation failures before mutation cancel safely. If an unexpected error occurs after applying a pivot or changing geometry, a zero command reports the error while preserving the operator’s finished status internally so an Undo boundary can be kept. Python may still raise from the error report. Do not automatically retry: inspect the scene/session and undo the failed operation when appropriate.

The background suite verifies native snapshot restoration, including active sessions, cursor-only actions, and interleaved edits. Several tests explicitly create the caller’s history boundaries because an interactive redo-panel path crashes the tested background Blender build. Those checks do not certify every button/hotkey path in the GUI. Full interactive and minimum-version testing remain release requirements.

The Transform Set regression additionally exercises automatic native Undo/Redo with the Python undo=True argument. This succeeds without an interactive redo panel and does not remove the GUI-testing requirement for other action paths.