6
$\begingroup$

I want to create a set of "distorted" images using python. The images should show possible misplacements of objects. The part of my script for translation and rotation seems to work well, but the scaling part doesn't work as expected. I want to randomly choose scaling parameters (random.gauss(1, 0.33)) to scale in the different axes - so I put the following in a while loop:

# 3 random variables for scaling in x, y and z directions
num1 = math.fabs(random.gauss(1,0.33))
num2 = math.fabs(random.gauss(1,0.33))
num3 = math.fabs(random.gauss(1,0.33))
# scaling with random variables
bpy.ops.transform.resize(value=(num1, 1, 1), constraint_axis=(True, False, False))
bpy.ops.transform.resize(value=(1, num2, 1), constraint_axis=(False, True, False))
bpy.ops.transform.resize(value=(1, 1, num3), constraint_axis=(False, False, True))

Then I save the image and want to get back to the "undistorted" image. So I tried:

# scale back to original image
bpy.ops.transform.resize(value=(1/num1, 1, 1), constraint_axis=(True, False, False))
bpy.ops.transform.resize(value=(1, 1/num2, 1), constraint_axis=(False, True, False))
bpy.ops.transform.resize(value=(1, 1, 1/num3), constraint_axis=(False, False, True))  

But this doesn't bring me back to the start. So I tried this in the console window of blenders UI. I have the simple startscreen featuring a camera, a cube and a lamp. For now resize and re-resize works. But if I turn the Cube by 45° round the z-axis it doesn't work any more. Scaling by (2,1,1) gives me a scale of (1.581,1.581,1) which suggests the scaling works in global coordinates. But why doesn't scaling with (0.5,1,1) give me the original cube. It gives me a scale of (1.25,1.25,1) instead.

So the question is, how do I get this to give me the original object back?

$\endgroup$
  • $\begingroup$ @Nightly, the title of a Q is important, if you want other people to be able to find the answers the Q title has to be relevant. You can re-edit your Title and perhaps clarify what relation the image has to the object.. is it uvmapped objects? $\endgroup$ – zeffii Apr 26 '15 at 20:59
  • $\begingroup$ I tried to do this, hope it worked. My English seems not to be as good, as it should be to communicate my problem here. $\endgroup$ – Nightfly Apr 26 '15 at 21:07
  • $\begingroup$ screenshots, and placeholder images (if you aren't comfortable including the actual images of this things you are trying to resize ).. let pixels speak! $\endgroup$ – zeffii Apr 26 '15 at 22:05
5
$\begingroup$

One way to do this is to get used to scaling using the obj.matrix_world and obj.matrix_local. Where obj is a reference to your Object. That way you can reset to the original scale using the identity matrix. You can even chain various kinds of matrix manipulations (Rotate, Scale, Location).

I hope to have time to give examples. The documentation shows how to do things, but it assumes you know Matrices and Vectors well enough to understand the terms:

docs: mathutils.Matrix


Ideasman points out that object.scale can be used. This is a convenient way if all you need is to rescale, it lets you scale directly using a vector (or tuple.. or list..as long as there's 3 elements).

obj = bpy.data.objects['Cube']
obj.scale = (0.5, 0.3, 1.2)

# will return all dimensions to their original value
obj.scale = (1, 1, 1)  

You mention in your Question about rotation. Another convenient way to rotate an Object can be found in the set of attributes starting with .rotation_*: see Docs for a description of:

obj.rotation_axis_angle
obj.rotation_euler
obj.rotation_mode
obj.rotation_quaternion

# ---- needed imports to use euler and math module
import math
from mathutils import Euler

obj.rotation_euler = Euler((0, 0, math.radians(45)), 'XYZ')
$\endgroup$
  • 2
    $\begingroup$ Or for basic cases you can change object.scale directly. $\endgroup$ – ideasman42 Apr 26 '15 at 16:02
  • $\begingroup$ @zeffii, @ideasman42 mentioned the obj.scale part, this solved my problem. The rotation was only for clarification, although I use it in my project. But I feel like bpy.ops.transform.rotate does the job quite well. $\endgroup$ – Nightfly Apr 26 '15 at 19:25
  • $\begingroup$ @Nightfly I'm just curious about how does this apply to images ? $\endgroup$ – Chebhou Apr 26 '15 at 19:40
  • $\begingroup$ @zeffii I couldn't tell because transform.resize() works in almost all contexts ! $\endgroup$ – Chebhou Apr 26 '15 at 20:28
  • $\begingroup$ @Chebhou, my intention was little different to what the title says, my post was edited, especially the title. My question was not to resize images using python. I think my question without the title says what i tried to do. The problem was that bpy.ops.transform.resize(value=(a,b,c)) was not undone by bpy.ops.transform.resize(value=(1/a,1/b,1/c)) the object.scale does what I wanted. @zeffi no problem, I think your way is just a bit to complicated for the simple problem, but thanks for your answer. $\endgroup$ – Nightfly Apr 26 '15 at 20:47

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.