Python Script operations dont works in sequence ? But woks in steps?

Hello, am i missing something or is a bug ?

I made this script to show the problem.
So i can set the variable DO to 4 , for making a sequence of code run.
The same code is splitted , to be done if the DO is 1, 2,3…

The Task is to rotate 2 cubes , Rotating only 1
So quickly parent and unparent them.

If i run all the code in the script using DO = 4, the script will ignore some code
Running the Code 3 times, with DO=1, DO=2, DO=3 , will do all the action .

What i am missing?

import bpy
import math
from math import radians
import mathutils
from mathutils import Matrix, Euler, Quaternion , Vector


A=bpy.data.objects["AAA"]
B=bpy.data.objects["BBB"]  

# set DO to 4 for doing all operations .........   Will not Rotate B
# set DO to ,1 and run, 2 and run... 3 and run ... Will rotate B too
DO=4 

if DO == 1:
    B.parent=A
    B.matrix_parent_inverse = A.matrix_world.inverted()
if DO == 2:
    EULER_WORLD = mathutils.Euler(   (0, math.radians(15.0) ,0)   ,'XYZ'  )                        
    A.rotation_euler.rotate( EULER_WORLD    )     
if DO == 3:
    matrixcopy = B.matrix_world.copy()
    B.parent=None
    B.matrix_world = matrixcopy
if DO == 4:
    B.parent=A
    B.matrix_parent_inverse = A.matrix_world.inverted()
    EULER_WORLD = mathutils.Euler(   (0, math.radians(15.0) ,0)   ,'XYZ'  )                        
    A.rotation_euler.rotate( EULER_WORLD    )     
    matrixcopy = B.matrix_world.copy()
    B.parent=None
    B.matrix_world = matrixcopy

Your understaing of code is wrong.
if functions check if given condition is true. If it is then it will execute its code otherwise skip it. If condition is wrong then it will not execute that part of code and go ahead.

Here Do is 4. Now if Do == 1 will check if Do is 1 but it is not. It is 4. So it will skip

    B.parent=A
    B.matrix_parent_inverse = A.matrix_world.inverted()

and go to if DO == 2 Again here it checks if Do is 2 but it is not and so on.
if DO == 4 here Do is 4 so it will execute these lines of code.

    B.parent=A
    B.matrix_parent_inverse = A.matrix_world.inverted()
    EULER_WORLD = mathutils.Euler(   (0, math.radians(15.0) ,0)   ,'XYZ'  )                        
    A.rotation_euler.rotate( EULER_WORLD    )     
    matrixcopy = B.matrix_world.copy()
    B.parent=None
    B.matrix_world = matrixcopy

Hope this makes sense.
I’m confused why you need if statement if you want everything to execute.

Hello est_fenix,

The world matrix is a dependent property, that depends on all local transformation matrices of the object’s ancestors. This dynamic property seems to be updated only when a dependency evaluation is done in scene update. If you run your script in steps, rendering takes place in between and this triggers dependency evaluation. Have a look at this stack overflow question (it’s from 2012, but it still seems valid)


Since a scene update would also calculate a lot of other dependencies, depending on your is case, it might be better to calculate the updated world matrix on your own (e.g. if you need to update the positions of a lot of objects inside of a loop).
Hope that helped.
1 Like

Thanks man, that is exactly what i mean to do ,
I split the complete code “4” , in 3 steps, 1,2,3
So i can run, all the code, with 4 (Dont Work)
or a piece at time , with 1,2,3, (This Work)

FrankFirsching point out that some things work only after the update of the scene.
So the update naturally happenz between run, but not in the “sequence”

Thanks man,
This explain also why i cant switch position of CubeA with CubeB !

The link provide a lot of useful information like how to force the update (but is costly)
Or how workaround with some Matrix based operations ( that should be better but complex )

Thanks again man, really appreciated !

Here the code from before, with added the Scene Update of blender 290.
This will parent, rotate , and unparent the cubes, correctly.
I cant do the complex matrix stuff : XD

from math import radians
import mathutils
from mathutils import Matrix, Euler, Quaternion , Vector


A=bpy.data.objects["AAA"]
B=bpy.data.objects["BBB"]  

B.parent=A
B.matrix_parent_inverse = A.matrix_world.inverted()

EULER_WORLD = mathutils.Euler(   (0, math.radians(15.0) ,0)   ,'XYZ'  )                        
A.rotation_euler.rotate( EULER_WORLD    )   

bpy.context.view_layer.update()  # UPDATE THE SCENE  BLENDER 290
matrixcopy = B.matrix_world.copy()

B.parent=None
B.matrix_world = matrixcopy