0
$\begingroup$

What's the right way to snap cursor to selected with Python? I'm getting a failed context error with this:

bpy.ops.view3d.snap_cursor_to_selected()

I've seen a solution using an operator but this is not what I want (at least I don't think?).

$\endgroup$
  • $\begingroup$ If you use it in an operator and execute it in the 3d view it will have the correct context. You can look into overriding the context, but making whatever you are making into an operator in a lot of cases is a good idea as well. You will probably want to execute your script while in 3d view anyway if it has something to do with the 3d cursor, won't you? It might be more convenient/easier. $\endgroup$ – Martynas Žiemys Jan 9 at 13:23
  • $\begingroup$ There is no need to be in 3d view to move the cursor. Rather than totally rewriting the operator, what context are we looking at here? In object mode snaps to the average of selected objects origins, in edit mode the average of selected verts for mesh, bones for bones etc etc. When the global location vector (x, y, z) is known it's simply a matter of scene.cursor.location = (x, y, z) for 2.8x or scene.cursor_location in prior. $\endgroup$ – batFINGER Jan 9 at 13:54
  • $\begingroup$ @MartynasŽiemys Actually no I just run the script and it does a bunch of appending, switching mats, and rendering. So really I don't see the point of making an operator here, but again I could be wrong. I've never overridden a context, I'll look into it thanks. $\endgroup$ – Arthur Blaquart Jan 9 at 14:19
  • $\begingroup$ You should always provide this sort of info in the question from the beginning. It makes it easier to answer without guessing. Anyway, batFINGER is right, just setting cursor's location to whatever you need makes a lot of sense. $\endgroup$ – Martynas Žiemys Jan 9 at 15:13
3
$\begingroup$

Set the location directly

There is no need to use the operator.

What context are we looking at here? In object mode snaps to the average of selected objects origins, in edit mode the average of selected verts for mesh, bones for bones etc etc. When the global location vector (x, y, z) is known it's simply a matter of scene.cursor.location = (x, y, z) for 2.8x or scene.cursor_location in prior

eg 2.8x object mode example, moves cursor to average global location of selected objects.

import bpy
from mathutils import Vector

context = bpy.context
scene = context.scene 

obs = context.selected_objects
n = len(obs)
assert(n)

scene.cursor.location = sum([o.matrix_world.translation for o in obs], Vector()) / n
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.