The current task I'm working on is moving objects in 4 basic relative directions. By using the local axes this can be accomplished relatively easy through View3d port.

However to script this behavior I can't figure out how to directly set coordinates in local space. The command "object.location" seems to always work in global coordinates. If I want to move, rotate, etc I can do this (or equivalent):

bpy.ops.transform.translate(value=(0,1,0), orient_type='LOCAL')

But I don't want to move objects, instead I want to place them. For instance in this picture the y-axis is flipped. The above command would correctly move it down one unit.

enter image description here

However I'm currently working with numbers that represent the actual location, so if I enter:

object.location[1] = 1

I would want the same action - moving down one unit. Is there a way to do that (outside of calculating world space coordinates and moving accordingly)?

This behavior is consistent no matter where I place the object origin or apply location transformations. It changes the relative coordinates but not the direction in which the axis is applied.

  • $\begingroup$ Anyone have pointers in the right direction? Would solve quite a few problems for me if I knew how to get coordinates in orientation to the local axis (as opposed to relative to the local origin). $\endgroup$ – Sam Vimes Sep 27 '19 at 21:05

Believe this is the answer... although there may be better solutions.

In essence when the local x and y axes are flipped then the matrix looks like this:

>>> cab.matrix_world
Matrix(((-1.0, 1.5099580252808664e-07, 0.0, 0.0),
        (-1.5099580252808664e-07, -1.0, 0.0, -0.12700000405311584),
        (0.0, 0.0, 1.0, 0.0),
        (0.0, 0.0, 0.0, 1.0)))

The key values there being the scale values which represent the flipped axes. So this axis is determined the following way:

matrix = cab.matrix_world
axis = (matrix[0][0], matrix[1][1], matrix[2][2])
axis = (-1, -1, 1)

Then to get the relative local coordinates the scale factor has to be multiplied by the local coordinates:

x = cab.location[0] * axis[0]
y = cab.location[1] * axis[1]
z = cab.location[2] * axis[2]

This gives x,y,z as if the whole coordinate system revolved around the local axis (instead of having local coordinates still being given in relation to a parent). This may only work in cases of the axes being flipped, since other rotations use more of the matrix (haven't got that far yet).

The reason I need this work in terms of location as opposed to translation is due to the fact that I keep an offset slider parameter for the user, which is the distance from the wall. Applying this slider to a translation does not work correctly, while being able to use the local axis with relative distance does.

If there are better solutions to this I'll update/replace this answer. However the answers I could find dealt with using local axes with translation, rotation, etc.


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.