1
$\begingroup$

Many thanks to Martynas Žiemys for his answer here:

how can I export object position info from blender to text file?

which basically works for me, however I have an issue when the very last object prints.

@batFINGER helped by pointing out fstrings; I then went away to condense and clarify the problem, but it got more bizarre! Here's the test code:

import bpy

def Export() :
    count = 0
    print ( "Export:" )
    for obj in bpy.context.scene.objects:
        count += 1
        print(f"{count} {obj.name} {' '.join(map(str, obj.dimensions))}")

def CreateObject ( i ) :
    bpy.ops.mesh.primitive_cube_add ( location = ( i * 10 , 0 , 0 ) )
    obj = bpy.context.active_object
    obj.dimensions = ( i * 2 , 1 , 1 )
    obj.name = "obj_%d" % i
    print(f"{i} {obj.name} {' '.join(map(str, obj.dimensions))}")

print ( "Blender version: %s" % bpy.app.version_string )

# delete all objects from any previous run
bpy.ops.object.mode_set(mode = 'OBJECT')
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False, confirm=False)

print ( "Create first 3 objects:" )
for i in range ( 1 , 4 ) :
    CreateObject ( i )
Export()
print ( "Create extra object (4th):" )
CreateObject ( 4 )
print ( "Create extra object (5th):" )
CreateObject ( 5 )
Export()

I'm printing each object twice: during creation and at export. Here's the terminal output:

Blender version: 2.93.1
Info: Deleted 5 object(s)
Create first 3 objects:
1 obj_1 2.0 2.0 2.0
2 obj_2 2.0 2.0 2.0
3 obj_3 2.0 2.0 2.0
Export:
1 obj_1 2.0 1.0 1.0
2 obj_2 4.0 1.0 1.0
3 obj_3 2.0 2.0 2.0
Create extra object (4th):
4 obj_4 2.0 2.0 2.0
Create extra object (5th):
5 obj_5 2.0 2.0 2.0
Export:
1 obj_1 2.0 1.0 1.0
2 obj_2 4.0 1.0 1.0
3 obj_3 6.0 1.0 1.0
4 obj_4 8.0 1.0 1.0
5 obj_5 2.0 2.0 2.0

All of the creation reports are wrong. All but the last export report are correct.

$\endgroup$
4
  • $\begingroup$ Thanks @batFINGER; using fstrings, terminal window shows the same issue. It doesn't appear due to output to file. I'll condense down to minimum code, see if it still happens $\endgroup$ Commented Aug 10, 2021 at 23:35
  • $\begingroup$ Potted the problem, here's the code: $\endgroup$ Commented Aug 10, 2021 at 23:50
  • $\begingroup$ Potted the problem, it gets weirder. Printing during create is all wrong; exporting, all OK except last one: Create: 1 obj_1 2.0 2.0 2.0 2 obj_2 2.0 2.0 2.0 3 obj_3 2.0 2.0 2.0 Export: 1 obj_1 2.0 1.0 1.0 2 obj_2 4.0 1.0 1.0 3 obj_3 2.0 2.0 2.0 How can I post the test code? Limited to 600 characters here. $\endgroup$ Commented Aug 11, 2021 at 0:02
  • $\begingroup$ The dimensions property in blender is calculated from the scale of the object and the dimensions of its mesh. The issue here looks like it's associated. Often this can be remedied with a scene update (via depsgraph or viewlayer in 2.8+) However, in this case would make the simple calculation, knowing a default cube has 2 x 2 x 2 and set the scale when you create. (btw the fstring formatting was not suggested as a fix, rather to replace prior Q code. Best Practices $\endgroup$
    – batFINGER
    Commented Aug 11, 2021 at 6:10

1 Answer 1

1
$\begingroup$

The data is not updated.

The dimensions property in blender is calculated from the scale of the object and the dimensions of its mesh. The issue here looks like it's associated. The new scale is calculated, but delayed until the next update.. Often this can be remedied with a scene update (via depsgraph or viewlayer in 2.8+)

After an operator it throws a scene update, explaining the behaviour above. No operator is called after creating the last object to update the scene.

Example adding a view layer update after setting dimension in create.

def CreateObject(i):
    bpy.ops.mesh.primitive_cube_add(location=(i * 10, 0, 0))
    obj = bpy.context.active_object
    obj.dimensions = (i * 2, 1 , 1)
    bpy.context.view_layer.update()

or, to limit to one call, as first line in Export

Set scale not dimension.

However, in this case would make the simple calculation, knowing a default cube has dimensions 2 x 2 x 2 set the scale on creation. A good example is add a plane. Set its dimensions to (4, 4, 4) vs its scale to (2, 2, 2). The plane is 2D, its mesh bounding box z dim is zero. The result, in both cases, is a plane with dimensions (4, 4, 0), the calculated scale using former is (2, 2, 1). Non-uniform scale is possibly one of the biggest causes of issues, especially with constraints.

$\endgroup$
2
  • 2
    $\begingroup$ Absoluetly spot-on @batFINGER, on both counts: CreateDimensionedObject: 1 obj_1 size 1 dim (1.0 1.0 1.0) CreateScaledObject: 2 obj_2 size 1 dim (4.0 1.0 1.0) Export: 1 obj_1 2.0 1.0 1.0 2 obj_2 4.0 1.0 1.0 Re: scale: it does seem counter-intuitive to set scale, not dimension though. I had read that already but followed alternative advice, which didn't mention the need for scene update $\endgroup$ Commented Aug 12, 2021 at 11:14
  • $\begingroup$ Cheers. Prattled on about this in an answer to why the default cube isn't (1, 1, 1) in both dimension and scale, which it was argued would take away any confusion between the two. The dimension depends on the mesh, the scale doesn't. $\endgroup$
    – batFINGER
    Commented Aug 12, 2021 at 12:01

You must log in to answer this question.

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