2

I would like to snap the 3D-cusor to an object. After that I would like to copy another object to the position of the 3D-cursor. The code is as follow:

Code sample:

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        ctx = bpy.context.copy()
        ctx['area'] = area
        ctx['region'] = area.regions[-1]
        bpy.ops.view3d.view_selected(ctx)
        bpy.ops.view3d.snap_cursor_to_selected()
        obj.select = False
        new_obj.select = True
        bpy.context.scene.objects.active = new_obj
        bpy.ops.view3d.snap_selected_to_cursor(use_offset=False)
        break

Python error is:

RuntimeError: Operator bpy.ops.view3d.snap_cursor_to_selected.poll() failed, context is incorrect

Modified code sample:

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        ctx = bpy.context.copy()
        ctx['area'] = area
        ctx['region'] = area.regions[-1]
        bpy.ops.view3d.view_selected(ctx)
        bpy.ops.view3d.snap_cursor_to_selected(ctx, use_offset=False)
        obj.select = False
        new_obj.select = True
        bpy.context.scene.objects.active = new_obj
        bpy.ops.view3d.snap_selected_to_cursor(use_offset=False)
        break

Python message:

TypeError: Converting py args to operator properties: : keyword "use_offset" unrecognized

I use Blender 2.77a. What can I do? Many thanks for our help.

Monster
  • 8,178
  • 1
  • 11
  • 27
PeterBluewin
  • 23
  • 1
  • 4

2 Answers2

7

You should override all operators that depends on context as follows :

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        ctx = bpy.context.copy()
        ctx['area'] = area
        ctx['region'] = area.regions[-1]
        bpy.ops.view3d.view_selected(ctx)
        bpy.ops.view3d.snap_cursor_to_selected(ctx)
        obj.select = False
        new_obj.select = True
        bpy.context.scene.objects.active = new_obj

        # take new copy of the context because it is outdated now
        ctx = bpy.context.copy()
        ctx['area'] = area
        ctx['region'] = area.regions[-1]            

        bpy.ops.view3d.snap_selected_to_cursor(ctx, use_offset=False)
        break
Chebhou
  • 19,533
  • 51
  • 98
0

You can move the cursor without using operators, then you don't have to get the context right.

import bpy

for area in bpy.context.screen.areas:
    if area.type == 'VIEW_3D':
        break

for space in area.spaces:
    if space.type == 'VIEW_3D':
        break

space.cursor_location = bpy.context.active_object.location

But then your snapping the cursor to an object, then snapping another object to the cursor, you can bypass the cursor and just set the new objects location.

new_obj.location = old_obj.location
sambler
  • 55,387
  • 3
  • 59
  • 192