1
$\begingroup$

I'm making a script which places the selected objects in a row, so I need to loop through all selected objects and move them in an axis by the same offset relative to the last one. All objects start off in the same place, say 0,0,0.

I have these constants:

rowLength = 5
objectNumber = 0
horiOffsetAmount = 0.1

So say I have 3 objects, the first object stays in the same place:

bpy.context.object.location[1] = objectNumber*HoriOffsetAmount (0*0.1 = 0)

Then I want to set the object number for the next object to be 1 greater

objectNumber = objectNumber + 1

But how do I actually make this work? At the moment it just offsets the active object, so I need to go through all the selected objects, making each one active in turn, then doing the offset, how do I do this?

Here is my current code:

import bpy
context = bpy.context
scene = context.scene

rowLength = 5
objectNumber = 0
horiOffsetAmount = 0.1
if objectNumber < rowLength:
    for obj in context.selected_objects:
        bpy.context.object.location[1] = horiOffsetAmount*objectNumber
        objectNumber = objectNumber + 1

So the problem is is that this is only affecting the active object, but I want it to go through so object 1 is offset by 0, object 2 is offset by horiOffsetAmount, object 3 is offset by horiOffsetAmount*2, object 4 is offset by horiOffsetAmount*3 etc....

$\endgroup$
1
  • 2
    $\begingroup$ bpy.context.object.location[1] = horiO,,, should be obj.location.y = horiO... (or location[1] is cool) All the objects in context.selected_objects are selected (obj.select is True) only one is "active" ie the context.object or context.active_object $\endgroup$
    – batFINGER
    Sep 20, 2016 at 16:52

1 Answer 1

2
$\begingroup$

Fortunately, your code can be made a lot simpler. In Python it is rarely needed to iterate over a collection and keep track of an index yourself, thanks to the built-in enumerate() function. Here is how I would do this:

Update: I've adjusted the code below to take the row length into account, and stack the objects in a grid.

import bpy

offset_y = 2.5
offset_z = 3
row_length = 5

for nr, obj in enumerate(bpy.context.selected_objects):
    row = nr % row_length
    col = nr // row_length
    obj.location = (0, row * offset_y, col * offset_z)

I have also renamed rowLength to row_length, as in Python usually local variables are all lower caps with underscores.

The trick is to first compute the row and column number given the object number, and then compute the Y and Z coordinates from the row and column.

$\endgroup$
2
  • $\begingroup$ thanks, the rowLength will be so once it reaches the end of the row it will place them in a row above, i.e. it will build a wall, so it puts 5 in a row(or whatever rowLength =) then after that it will start placing them in a row above. $\endgroup$ Sep 21, 2016 at 13:15
  • $\begingroup$ I've updated my answer to include this. $\endgroup$
    – dr. Sybren
    Sep 21, 2016 at 20:55

You must log in to answer this question.

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