7
$\begingroup$

Blender 2.83

In python I can create all of the features that I want in my world, but when I go to the world, each thing has the same location data. I can click on each and click set origin to geometry, and that fixes it. The info pane says:

bpy.ops.object.origin_set(
    type='ORIGIN_GEOMETRY',
    center='MEDIAN'
)

So I would think I can run, at the end of my script, something like:

for object in bpy.context.scene.objects:
    bpy.ops.object.origin_set(
        type='ORIGIN_GEOMETRY', 
        center='MEDIAN'
    )

but this doesn't seem to do anything. How do I set everything to have origin_geometry, so that they have reasonable position data?

$\endgroup$

1 Answer 1

14
$\begingroup$

Low-level Origin to Geometry

You can:

  1. Sum the vert coordinates
  2. Make that the origin
  3. Shift the matrix back accordingly
    import bpy
    from mathutils import Matrix, Vector
    
    scene = bpy.context.scene
    
    mesh_obs = [obj for obj in scene.objects if obj.type == 'MESH']
        
    for obj in mesh_obs:
        d = obj.data
        mw = obj.matrix_world
        origin = sum((vert.co for vert in d.vertices), Vector()) / len(d.vertices)
    
        T = Matrix.Translation(-origin)
        d.transform(T)
        mw.translation = mw @ origin

Alternatively, change your mesh creation class, such as not to use global coordinates.

Operators and Context

Operators use the context. origin_set will set the origin of all selected mesh objects, and can be run once on the selection, rather than per object. See Python performance with Blender operators as to how this matters to performance.

Another part of context is the code in question. It's possible that changing the origin could be dealt with somewhere else, if you are, to quote:

...create all of the features that I want

However, without any idea of what the prior code is, here's a Test script. It sets the origin of all mesh objects in the scene by passing them as an overridden context to the operator.

Blender 3.2+

    import bpy
    
    C = bpy.context
    scene = C.scene
    
    mesh_obs = [obj for obj in scene.objects if obj.type == 'MESH']
    c = {"object" : mesh_obs[0],
        "selected_objects" : mesh_obs,
        "selected_editable_objects" : mesh_obs}
        
    if mesh_obs:
        with C.temp_override(**c):
            bpy.ops.object.origin_set()

Blender 2.8+

    import bpy

    scene = bpy.context.scene

    mesh_obs = [obj for obj in scene.objects if obj.type == 'MESH']

    if mesh_obs:
        bpy.ops.object.origin_set({
            "object" : mesh_obs[0],
            "selected_objects" : mesh_obs,
            "selected_editable_objects" : mesh_obs,
        })
$\endgroup$
5
  • $\begingroup$ Hey batFIGNER. Probably it's my own fault in trying to apply your answer, or in poorly explaining what I wanted to do. When I create a bunch of cubes in different locations, and then go and click them, they all have the same location "5.7463,6.9448,1.5576" (despite appearing in different places on the screen). When I right click each of them, and change origin to geometry, they give reasonable coordinates (for example (7.2463,14.445,2.0575)) and are now distant from each other by integer differences like $(m,n,0)\in\Bbb Z^3$ (which is what I want). $\endgroup$
    – JmathLoy
    Commented Jul 11, 2020 at 9:51
  • $\begingroup$ After running your script, it moves all the blocks to the same location on screen, instead of doing the same thing as right clicking and changing to origin_geometry $\endgroup$
    – JmathLoy
    Commented Jul 11, 2020 at 9:52
  • $\begingroup$ Possibly I've caused the problem myself by defining my own cube class i.imgur.com/WqPl5Qg.png, instead of just using bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location=(5.74625, 6.94476, 1.5576)) $\endgroup$
    – JmathLoy
    Commented Jul 11, 2020 at 10:10
  • $\begingroup$ At some point I'll want to do other geometric figures though, and probably I would modify my above class with the appropriate vertices and faces in those cases, so I'm still interested in the answer for my class $\endgroup$
    – JmathLoy
    Commented Jul 11, 2020 at 10:13
  • $\begingroup$ Your edit works great, thank you! $\endgroup$
    – JmathLoy
    Commented Jul 12, 2020 at 19:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .