A script to place cursor on objects' surface (and some other functionality)

The functionality of the script has noticeably expanded since its initial version. To learn about current features, visit the manual on blender wiki: http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/3D_interaction/Enhanced_3D_Cursor

Latest version can be downloaded from here: https://raw.github.com/dairin0d/enhanced-3d-cursor/master/space_view3d_enhanced_3d_cursor.py

The original post:

Hello everyone :slight_smile:
I’ve just recently started learning how to develop addons for Blender. A couple of days ago I submitted my first addon, but there seems to be no feedback yet. I’m curious what other Blender users would say (critique/advices/ideas/suggestions), as I honestly believe quite many of them could find it useful (and, dare to say, such functionality should have been a part of Blender long time ago :eyebrowlift2:)

The addon is designed as a replacement for Blender’s default SetCursor3D behavior. Main features:

  • Drag cursor

  • Constrain cursor movement to:

    • surface of raycastable objects
    • axes of selected coordinate system
    • exact axis values in the selected coordinate system
  • Make snapshots of surface normal (either face normal or interpolated between vertices)

Note: internally, when in “raycasting” mode, the script performs raycasting against every object in the scene (excluding hidden objects and objects in invisible layers). Under certain conditions, it converts objects to meshes. Thus, I’d expect it to perform smoothly only on quite simple scenes, though I haven’t tested actual limits yet.

3 Likes

dairin0d this is a great script, with lot of features, thanks!
still I miss a way to snap the cursor to vertices, not just surfaces…
and maybe grid / incremental values

Thanks dairin0d, I agree with liero on the compliments and the feature request, too.
It would be awesome to drag around the 3D cursor having it constrained with the usual Blender snapping features: incremental, vertices, etc. etc. I guess this would mean to make the cursor behave somewhat like an empty.
Thanks again, keep it up! :slight_smile:

Ookay, added the snapping! Turns out it wasn’t as hard as I supposed :slight_smile: Here’s the updated manual: > ------------------------------------------------------------------------------ - Drag cursor - Constrain cursor movement to: - surface of raycastable objects - axes of selected coordinate system - exact axis values in the selected coordinate system - Snap cursor to: - grid (in the space of selected coordinate system) - vertices / edge centers / face centers - Make snapshots of surface normal (either face or interpolated) ======================================= > ------------------------------------------------------------------------------ Drag cursor with Action mouse button. While holding Action mouse button, press Tilde (Accent Grave) key to be able to move cursor without the need to hold Action mouse button. Changes to cursor position would be confirmed on the next Action mouse press. You can also press Alt+Tilde to launch the operator without touching the mouse. To discard changes in cursor position, press Esc key or Select mouse button. If view is locked to cursor, after initial repositioning, cursor location would be changed in little increments, thus making view “slide” smoothly with the cursor. Press K to enable/disable locking view on cursor. ======================================= > ------------------------------------------------------------------------------ Holding Alt enables “raycasting mode”, in which cursor snaps to the surface under the mouse. In this mode, resulting position and normal are displayed. Press one of V, E, F to enable snapping only to vertices, edges or faces correspondingly. Pressing the key second time would enable snapping only to other two types of elements. Press A to enable snapping to all elements. If snapping to all elements is already enabled, pressing A would disable them all. Press S to enable/disable normal interpolation. If enabled, resulting normal would be found by barycentric triangle interpolation (non-triangle faces are tesselated). Otherwise, face normal would be used. This also turns off any snapping to vertices/edges/faces. Press D to raycast against the “raw” mesh without any modifiers applied. This makes difference only for active mesh in edit mode. Press W to make snapshot of raycasted normal. It will be added to scene as new Empty of “SINGLE_ARROW” type. Note that in raycasted mode axis constraints and exact axis values influence cursor position as well. ======================================= > ------------------------------------------------------------------------------ Press Q to enable/disable coordinate system synchronizing. If disabled, the operator would always start with “GLOBAL” transform orientation selected, and changes in transform orientation would be reverted when operator ends. You can enter exact coordinates for any of XYZ axes; they override any constraints and positioning made with mouse. Any valid basic numeric expressions are accepted. To remove last character in current input axis, press Backspace. To switch input to the next axis (or previous, if combined with Shift), press Tab or Return/Enter. To clear current axis input, press Delete. Press A to switch between absolute and relative coordinates. In relative coordinates the position of cursor at the time of operator initialization would be considered origin (0, 0, 0). For absolute coordinates, the origin would depend on the selected transform orientation. To help user see where the reference point is, a line is drawn between the cursor’s current position and the “origin”. Press X, Y or Z to constrain cursor movement to a single axis of selected coordinate system. Pressing them with Shift would constrain cursor movement to other two axes. Pressing the same key twice would remove constraints. To select coordinate system, press one of the following: V – View. Absolute origin is at cursor initial position. G – Global. Absolute origin is at global center (0, 0, 0). L – Local. Absolute origin at active object’s origin. If there is no active object, this will coincide with Global. N – Normal. Currently same as Local. I – Gimbal. Currently same as Local. M – Mesh. Same as Local, but takes into account scale/shear. S – Surface. Z axis will be aligned with raycasted normal direction, X axis will lie in global XY plane. Absolute origin is the raycasted point. C – Custom transform orientation. Pressing this key in succession would cycle through available custom transform orientations. Absolute origin is at cursor initial position. Hold Ctrl to snap cursor to grid (integer values in the selected coordinate system). Please pay attention whether absolute or relative coordinates are selected, they result in different snapping positions! Hold Shift+Ctrl to snap to 1/10 of grid.

Ookay, added the snapping! Turns out it wasn’t as hard as I supposed :slight_smile:

Here’s the updated manual:

Feature overview:

  • Drag cursor

  • Constrain cursor movement to:

    • surface of raycastable objects
    • axes of selected coordinate system
    • exact axis values in the selected coordinate system
  • Snap cursor to:

    • grid (in the space of selected coordinate system)
    • vertices / edge centers / face centers
  • Make snapshots of surface normal (either face or interpolated)

===========================================

In general:

Drag cursor with Action mouse button.

While holding Action mouse button, press Tilde (Accent Grave) key to be able to move cursor without the need to hold Action mouse button. Changes to cursor position would be confirmed on the next Action mouse press.
You can also press Alt+Tilde to launch the operator without touching the mouse.

To discard changes in cursor position, press Esc key or Select mouse button.

If view is locked to cursor, after initial repositioning, cursor location would be changed in little increments, thus making view slide smoothly with the cursor.

Press K to enable/disable locking view on cursor.

In raycasting mode:

Holding Alt enables raycasting mode, in which cursor snaps to the surface under the mouse. In this mode, resulting position and normal are displayed.

Press one of V, E, F to enable snapping only to vertices, edges or faces correspondingly. Pressing the key second time would enable snapping only to other two types of elements.
Press A to enable snapping to all elements. If snapping to all elements is already enabled, pressing A would disable them all.

Press S to enable/disable normal interpolation. If enabled, resulting normal would be found by barycentric triangle interpolation (non-triangle faces are tesselated). Otherwise, face normal would be used.
This also turns off any snapping to vertices/edges/faces.

Press D to raycast against the raw mesh without any modifiers applied. This makes difference only for active mesh in edit mode.

Press W to make snapshot of raycasted normal. It will be added to scene as new Empty of SINGLE_ARROW type.

Note that in raycasted mode axis constraints and exact axis values influence cursor position as well.

Not in raycasting mode:

Press Q to enable/disable coordinate system synchronizing. If disabled, the operator would always start with Global transform orientation selected, and changes in transform orientation would be reverted when operator ends.

You can enter exact coordinates for any of XYZ axes; they override any constraints and positioning made with mouse. Any valid basic numeric expressions are accepted.
To remove last character in current input axis, press Backspace.
To switch input to the next axis (or previous, if combined with Shift), press Tab or Return/Enter.
To clear current axis input, press Delete.

Press A to switch between absolute and relative coordinates. In relative coordinates the position of cursor at the time of operator initialization would be considered origin (0, 0, 0). For absolute coordinates, the origin would depend on the selected transform orientation.
To help user see where the reference point is, a line is drawn between the cursor’s current position and the origin.

Press X, Y or Z to constrain cursor movement to a single axis of selected coordinate system. Pressing them with Shift would constrain cursor movement to other two axes. Pressing the same key twice would remove constraints.

To select coordinate system, press one of the following:
V – View. Absolute origin is at cursor initial position.
G – Global. Absolute origin is at global center (0, 0, 0).
L – Local. Absolute origin at active object’s origin. If there is no active object, this will coincide with Global.
N – Normal. Currently same as Local.
I – Gimbal. Currently same as Local.
M – Mesh. Same as Local, but takes into account scale/shear.
S – Surface. Z axis will be aligned with raycasted normal direction, X axis will lie in global XY plane. Absolute origin is the raycasted point.
C – Custom transform orientation. Pressing this key in succession would cycle through available custom transform orientations. Absolute origin is at cursor initial position.

Hold Ctrl to snap cursor to grid (integer values in the selected coordinate system). Please pay attention whether absolute or relative coordinates are selected, they result in different snapping positions!
Hold Shift+Ctrl to snap to 1/10 of grid.

where can we download the script?

thanks

Currently it’s on Upload tracker http://projects.blender.org/tracker/index.php?func=detail&aid=28451. There’s a tab [Attachments] at the bottom of the page. You’re welcome :slight_smile:

sorry don’t see any link on that page

where do you see it ?

thanks
happy 2.5

dairin0d: AWESOME, this script open a new era of 3D cursor usability!!!

Ricky, the link is on the bottom of the page: http://projects.blender.org/tracker/download.php/153/467/28451/17587/enhanced_set_3d_cursor.0.8.5.py

thanks colud not see this link!

i’ll give it a try this weekend

happy 2.6

Perhaps I should put a warning here too: currently the script doesn’t work correctly with quadview.
Also, the addon makes no difference between Local, Normal and Gimbal coordinate systems. With the current API there’s no way to get matrix of non-custom transform orientation… As for Normal system, I guess I can devise a workaround. As for Gimbal system… Does anyone know what it’s supposed to represent? Does anyone use it at all?

By the way, Brendon Murphy suggested me to take a look at seminumerical’s cursor tools, as they seem to be not maintained for several months. What do you think about this? Cursor position history and storing/recalling cursor locations seem like a natural supplement to the functionality present in my script. However, I’m not sure about CAD snappings – perhaps it’s better to have an independent set of CAD tools based on actual CAD programs?

Oh, and also thanks to Greg from BlenderNerd for his Ivy Gen tutorial :wink: To tell the truth, the moment at 4:12–4:21 is what actually motivated me to begin writing the script :stuck_out_tongue:

Nice, but I’m having some issues here, the ACCENT_GRAVE key isn’t working for me, changed that to something else, F10 for instance, and it goes ok. And then I can not get the snapped cusor to keep stuck to a vertex when releasing ALT or clicking… it should work that way?
Again, this must be something on my settings… very useful script once I get it working :wink:

Yes, currently vertex/edge/face snapping only works while Alt is pressed. To make cursor “stuck” to the snapped vertex, release Alt after releasing the mouse.
However, I agree that always holding Alt may be inconvenient. Perhaps I’ll try to modify the script so that pressing Alt would enable raycasting mode permanently until you press it again.

Hmm, F10 seems to be an interesting option… I was trying to choose a key/combination that’s unlikely to be used by Blender or other addons. Since the addon is expected to be frequently used by many people, it would be nice to know what default keymappings the majority of users would like :wink:

yep, but still not working here, neither ACCENT_GRAVE or the release Alt after mouse
in fact I can not even install as addon -works ok with previous version- I just run it from text editor
but don’t worry as it may be some silly problem here, will check tomorrow…

edit: found both problems…

the script not being enabled as addon got to do with the file name, removed numbers and just left .py extension -tried on windows-
the Alt problem was solved disabling ‘Emulate 3 Button Mouse’ in preferences… but I need that back :wink:

hi looking good,
I’ve made mention of your script for the blender addons dev meeting.
If you get a chance, drop into IRC freenode #blenderpython
it can be good to talk about things in real time too :slight_smile:
Thanks.
Brendon Murphy :wink:

Thanks for problem info, I’ll look into how to avoid it (or at least include a warning to the manual) =)
Currently I’m trying to do the fixes for inconveniences you mentioned in the previous post, and some other features. Maybe today’s evening or tomorow I’ll upload the new version.

After the day full of coding, version 1.0.0 is complete =)

Here’s the updated manual:

<<< Feature overview: >>>

  • Drag cursor

  • Constrain cursor movement to:
    – surface of raycastable objects
    – axes of selected coordinate system
    – exact axis values in the selected coordinate system

  • Snap cursor to:
    – grid (in the space of selected coordinate system)
    – vertices / edge centers / face centers

  • Make snapshots of surface normal (either face or interpolated)

<<< In general: >>>

Drag cursor with Action mouse button.

Press F10 (or the custom key you assigned to addon in user preferences) to launch the operator without touching the mouse. You can also press this key during cursor dragging to enter “mouse-free mode”. In that case, changes to cursor position would be confirmed on the next Action mouse press.

To discard changes in cursor position, press Esc key or Select mouse button.

Press Q to enable/disable helper line drawing. When enabled, the following will be displayed:

  • a line from current coordinate system origin to cursor;
  • lines from cursor to its projections on each plane of the selected coordinate system.

If view is locked to cursor, after the initial repositioning, cursor location would be changed in little increments, thus making view “slide” smoothly with the cursor.

Press O to enable/disable locking view on cursor.

<<< Coordinate system: >>>

Press Semicolon key to enable/disable coordinate system synchronizing. If disabled, the operator would always start with “GLOBAL” transform orientation selected, and changes in transform orientation would be reverted when operator ends.

Press A to switch between absolute and relative coordinates. In relative coordinates the position of cursor at the time of operator initialization would be considered origin (0, 0, 0). For absolute coordinates, the origin would depend on the selected transform orientation.

To select coordinate system, press one of the following:
I – View. Absolute origin is at cursor initial position.
G – Global. Absolute origin is at global center (0, 0, 0).
L – Local. Absolute origin at active object’s origin. If there is no active object, this will coincide with Global.
N – Normal. Currently same as Local.
J – Gimbal. Currently same as Local.
M – Mesh (“scaled local”). Same as Local, but takes into account scale.
B – Surface. Z axis will be aligned with raycasted normal direction, X axis will lie in global XY plane. Absolute origin is the raycasted point.
U – Custom transform orientation. Pressing this key in succession would cycle through available custom transform orientations. Absolute origin is at cursor initial position.

<<< Raycasting: >>>

Press R to enable/disable “raycasting” mode, in which cursor snaps to the surface under the mouse. In this mode, the resulting position and normal are displayed.
Note that in raycasted mode axis constraints and exact axis values influence cursor position as well.

Press one of V, E, F to enable snapping only to vertices, edges or faces correspondingly. Pressing the key second time would enable snapping only to other two types of elements.
Press C to enable snapping to all elements. If snapping to all elements is already enabled, pressing C would disable them all.

Press S to enable/disable normal interpolation. If enabled, resulting normal would be found by barycentric triangle interpolation (non-triangle faces are tesselated). Otherwise, face normal would be used.
This also turns off any snapping to vertices/edges/faces.

Press D to raycast against the “raw” mesh without any modifiers applied. This makes difference only for active mesh in edit mode.

Press W to make snapshot of raycasted normal. It will be added to scene as new Empty of “SINGLE_ARROW” type.

<<< Exact axis coordinates: >>>

You can enter exact coordinates for any of the XYZ axes; they override any constraints and positioning made with mouse. Any valid basic numeric expressions are accepted.

To remove last character in current input axis, press Backspace.

To switch input to the next axis (or previous, if combined with Shift), press Tab or Return/Enter.

To clear current axis input, press Delete.

<<< XYZ and Grid (incremental) constraints: >>>

Press X, Y or Z to constrain cursor movement to a single axis of selected coordinate system. Pressing them with Shift would constrain cursor movement to other two axes. Pressing the same key twice would remove constraints.

Hold Ctrl to snap cursor to grid (integer values in the selected coordinate system). Hold Shift+Ctrl to snap to 1/10 of grid.
Snapping to grid has no effect in raycasting mode.

Even nifty keymap is here :wink:


Attachments


Thanks for your effort!
Maybe I’m doing something wrong, but whenever I hit ‘R’ to snap the cursor on a vert / edge / face I get the snap performed correctly but I also see an error on the top of Blender window, which goes: “unknown py-exception, couldn’t convert…”.
Now for a feature request: would it be hard to enable a “permanent snapping” feature, like when in Blender you hit Shift-Tab and then every mouse operation is constrained to the current snapping option?
Thanks a lot for this useful script!

Open system console (Help -> Toggle System Console), there should be the whole error message.

Err… Do you mean by “permanent snapping” that Blender’s “snap during transform” option should affect snapping during cursor movement, and vice versa?

genius! everything works fine here…
could you store settings between sessions? also remember to change location in bl_info