Three Point Rotation¶
Modal operator that builds a temporary three-empty rig (origin + two aim targets) around the active mesh object and uses Damped Track constraints to drive its orientation. Move the dummies to define a new local frame, then confirm to bake the resulting transform onto the object.
Overview¶
Aligning an object to an arbitrary triplet of points (origin, primary axis target, secondary axis target) is awkward with built-in tools. This operator spawns three empties — O_Dummy (origin, single-arrow), Y_Dummy and Z_Dummy (sphere targets) — and pre-wires Damped Track constraints on the origin empty pointing at the two target empties. The user drags the dummies (optionally with snapping enabled) until the rig matches the desired frame, then parents the source object to the origin empty and bakes the result on confirm.
The operator stores and overrides the scene's snap settings during the session and restores them on exit, so the snap UI returns to its prior state regardless of whether the modal is confirmed or cancelled.
Usage¶
- Requires a single active mesh object in Object Mode (VIEW_3D).
- No default keymap binding (registered placeholder is
Ctrl+Alt+Shift+F19inprefs/hotkeys_default.py, intended to be remapped). Invoke via menu / F3 search / Pie. - On invoke the three empties are created at the object location and sized relative to its bounding-box average. The origin empty (
O_Dummy) becomes active. - Move the dummies with
G/R, optionally toggle snap withS, then press1to parent the object to the rig andSpaceto confirm.
Modal Controls¶
| Key | Action |
|---|---|
| LMB | Selection click; only O_Dummy / Y_Dummy / Z_Dummy may become active. Other picks are reverted. |
| MMB / WheelUp / WheelDown | Pass-through for viewport navigation. |
| F1 | Select O_Dummy and start transform.translate. |
| F2 | Select Y_Dummy (internally targets Z_Dummy object — see Notes) and start transform.translate. |
| F3 | Select Z_Dummy (internally targets Y_Dummy object — see Notes) and start transform.translate. |
| A | Select all three dummies. |
| G | Invoke transform.translate on current selection. |
| R | Invoke transform.rotate on current selection. |
| S | Toggle tool_settings.use_snap. |
| F | Swap locations of Y_Dummy and Z_Dummy. |
| 0 | Reset: unparent object, clear constraints on O_Dummy, remove proxy, restore the captured object world matrix. |
| 1 | Toggle parent object -> O_Dummy (keep transform). On enabling, also spawns a Proxy_Dummy cube empty parented to O_Dummy. On disabling, clears parents on all dummies and the object, and removes the proxy. |
| 2 | Toggle a single Damped Track constraint on O_Dummy tracking Z_Dummy (track axis Z). Switches O_Dummy display between SINGLE_ARROW and ARROWS. |
| 3 | Toggle two Damped Track constraints on O_Dummy (Y-axis -> Y_Dummy, Z-axis -> Z_Dummy). Clears constraints if either is already present. |
| = | Scale all three dummies by 1.5. |
| - | Scale all three dummies by 0.75. |
| Space | Confirm: parent-clear with keep-transform on the object, delete all dummies and proxy, restore snaps. |
| Esc | Cancel: delete dummies/proxy, restore the captured object world matrix, restore snaps. |
| H | HUD/help overlay toggle (handled by HUD layer; see HUD). |
HUD¶
The modal draws two overlays bound to the active VIEW_3D region:
- A title HUD (
HUDOverlay"three_point_rotation", title "3 Point Rotation"). - A help overlay (
HelpOverlay) listing the key bindings above (Reset transforms, Toggle lock, Toggle 2/3 point, Select all dummies, Flip Y and Z, Toggle snaps, Translate/Rotate, Select O/Y/Z dummy, Scale dummies, Finish, Cancel, Help / Toggle HUD).
Both overlays support drag-positioning and parameter/help toggle events via the standard IOPS HUD theme. Colours are read from preferences.addons["InteractionOps"].preferences.iops_theme; if the theme is missing the HUD still draws but drag/toggle interactions are skipped.
Notes¶
- The operator has no
bl_props; all behaviour is driven by modal keys. - F2/F3 wiring quirk: the
select_targetbranches for"Y_Dummy"and"Z_Dummy"actually select and activate the other dummy (Y branch setsZ_Dummyactive, Z branch setsY_Dummyactive). This is in the source as written; treat the F2/F3 labels in the help overlay accordingly. invokeoverwritesself.Z_Dummywithbpy.data.objects["Y_Dummy"](lines reassigningself.Z_Dummytwice); the operator works regardless because subsequent code addresses dummies by name viabpy.data.objects[...].- Snap settings touched during the session:
transform_pivot_point,snap_target,use_snap_self,snap_elements,use_snap_align_rotation,use_snap_translate,use_snap_rotate,use_snap_scale, anduse_snap. Originals are restored on Space or Esc. - Dummy names are hard-coded (
O_Dummy,Y_Dummy,Z_Dummy,Proxy_Dummy). Pre-existing objects with these names in the scene will collide and break the modal. - Poll fails outside VIEW_3D / Object Mode, with empty selection, or if the active object is not a MESH.
- Cancel restores the cached
matrix_worldof the source object captured at invoke; confirm bakes whatever transform the rig produced via parent-clear keep-transform.