28
$\begingroup$

This question relates to positioning static objects while modeling. This is not a question about how to move objects dynamically/programmatically like in a game context.

For example, I need to translate the center of mesh object A to the center of mesh object B.

How can this be done easily?

$\endgroup$
33
$\begingroup$

Assuming that you have two distinct objects (rather than two unlinked meshes in the same object) and each object's origin is at the "true" center of the object (however you prefer to determine that), you would use the following process (in Object mode):

  1. Select object B
  2. Snap the 3D Cursor to object B's origin (Shift+S > Cursor to Selected)
  3. Select object A
  4. Snap object A to the 3D Cursor's location (Shift+S > Selection to Cursor)

You can also use Blender's snapping tools to do some of this interactively, but the 3D Cursor is the most reliable way.

$\endgroup$
  • $\begingroup$ I'm always thinking too complicated. Great solution. $\endgroup$ – C4d Feb 14 '18 at 8:16
10
$\begingroup$

Fweeb has already mentioned the traditional and time honored approach. I'd just like to add that the shortcut can be ShiftS,5 and ShiftS,2 since blender menu entries are accessible by numbers. The underscored letters in the menu work as well.

The context menu approach:

There is another method. Select all the objects you want to move. Then Shift select the object that has the right position. Hover over the Location numbuttons in the Transform panel, and click RMB. In the context menu, you will find Copy to Selected (Shortcut Y when the menu is open)

enter image description here

The vintage addon method:

There is yet another method. The Copy Attributes addon (disabled by default). Shortcut CtrlC (although that might change since the shortcut is now used differently). The addon simulates vintage Blender behavior. It's the same theme of copying attributes from active to selected. First select the objects you want to move, then the object in the right position to make it the active object and hit CtrlC and choose from the menu.

$\endgroup$
  • $\begingroup$ I answered this so long ago that I still had Shift S3 in the answer. I skipped S4. Now it's S5. $\endgroup$ – Haunt_House Feb 14 '18 at 16:53
5
$\begingroup$

Here's a convenience addon that moves all selected objects (=their origins) to the active object's origin (adds a button to the T-panel, "Move to Origin"):

import bpy

bl_info = {
    "name": "Move to Origin",
    "author": "CoDEmanX",
    "version": (1, 0),
    "blender": (2, 65, 0),
    "location": "View3D > Object Mode > Tool Shelf",
    "description": "Move selected objects to active object's origin",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Object"}

def main(context):
    ob_act = context.object
    loc = ob_act.matrix_world.to_translation()

    for ob in context.selected_editable_objects:
        if ob != ob_act:
            ob.location = loc


class OBJECT_OT_move_to_origin(bpy.types.Operator):
    """Move selected objects to active object's origin"""
    bl_idname = "object.move_to_origin"
    bl_label = "Move to Origin"

    @classmethod
    def poll(cls, context):
        return context.object is not None

    def execute(self, context):
        main(context)
        return {'FINISHED'}

draw_func = lambda self, context: \
    self.layout.operator(OBJECT_OT_move_to_origin.bl_idname)

def register():
    bpy.utils.register_class(OBJECT_OT_move_to_origin)
    bpy.types.VIEW3D_PT_tools_objectmode.append(draw_func)


def unregister():
    bpy.utils.unregister_class(OBJECT_OT_move_to_origin)
    bpy.types.VIEW3D_PT_tools_objectmode.remove(draw_func)


if __name__ == "__main__":
    register()
$\endgroup$
  • $\begingroup$ Updated add-on to blender 2.76, check my answer of this question. I am also curious how the line loc = ob.matrix_world.to_translation() works without an object ob. $\endgroup$ – Anders Lindén Jul 15 '17 at 1:59
  • $\begingroup$ Corrected the typo, it was supposed to be loc = ob_act... of course. $\endgroup$ – CoDEmanX Jul 26 '17 at 21:18
2
$\begingroup$

Updated convenience add-on for moving an object to another object, using blender 2.76

move_to_first_selected_object.py:

import bpy

bl_info = {
    "name": "Move to First",
    "author": "CoDEmanX",
    "version": (1, 0),
    "blender": (2, 76, 0),
    "location": "View3D > Object Mode > Tool Shelf",
    "description": "Move last selected object(s) to first",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Object"}

def main(context):
    ob_act = context.selected_editable_objects[-1]
    loc = ob_act.matrix_world.to_translation()

    for ob in context.selected_editable_objects:
        if ob != ob_act:
            ob.location = loc


class OBJECT_OT_move_to_origin(bpy.types.Operator):
    """Move last selected object(s) to first"""
    bl_idname = "object.move_to_first_selected_object"
    bl_label = "Move to First"

    @classmethod
    def poll(cls, context):
        return context.object is not None

    def execute(self, context):
        main(context)
        return {'FINISHED'}

draw_func = lambda self, context: \
    self.layout.operator(OBJECT_OT_move_to_origin.bl_idname)

def register():
    bpy.utils.register_class(OBJECT_OT_move_to_origin)
    bpy.types.VIEW3D_PT_tools_object.append(draw_func)


def unregister():
    bpy.utils.unregister_class(OBJECT_OT_move_to_origin)
    bpy.types.VIEW3D_PT_tools_object.remove(draw_func)


if __name__ == "__main__":
    register()

move_to_last_selected_object.py:

import bpy

bl_info = {
    "name": "Move to Last",
    "author": "CoDEmanX",
    "version": (1, 0),
    "blender": (2, 76, 0),
    "location": "View3D > Object Mode > Tool Shelf",
    "description": "Move first selected object(s) to last",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Object"}

def main(context):
    ob_act = context.object
    loc = ob_act.matrix_world.to_translation()

    for ob in context.selected_editable_objects:
        if ob != ob_act:
            ob.location = loc


class OBJECT_OT_move_to_origin(bpy.types.Operator):
    """Move first selected object(s) to last"""
    bl_idname = "object.move_to_last_selected_object"
    bl_label = "Move to Last"

    @classmethod
    def poll(cls, context):
        return context.object is not None

    def execute(self, context):
        main(context)
        return {'FINISHED'}

draw_func = lambda self, context: \
    self.layout.operator(OBJECT_OT_move_to_origin.bl_idname)

def register():
    bpy.utils.register_class(OBJECT_OT_move_to_origin)
    bpy.types.VIEW3D_PT_tools_object.append(draw_func)


def unregister():
    bpy.utils.unregister_class(OBJECT_OT_move_to_origin)
    bpy.types.VIEW3D_PT_tools_object.remove(draw_func)


if __name__ == "__main__":
    register()
$\endgroup$
  • 1
    $\begingroup$ context.selected_editable_objects[-1] can fail if there's no selected object (index error). Also, context.selected_editable_objects doesn't seem to reflect the order of selection. Instead, it seems to always list the selected objects in reverse creation order (Blender v2.78c). Finally, context.object will be None (poll fail) if you select an object twice, which unselects it. Hence, the last selected object would be some other object, but we don't know which because we don't know the selection order. $\endgroup$ – CoDEmanX Jul 26 '17 at 21:29
  • $\begingroup$ So selection order is not available? $\endgroup$ – Anders Lindén Jul 28 '17 at 0:33
  • $\begingroup$ I'm afraid so. Not sure if it's intentional (performance reasons?) $\endgroup$ – CoDEmanX Jul 28 '17 at 7:51

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.