Script for saving/exporting global coordinates from objects to a text file

Hi everyone,

I work as a match moving artist and use 3DEqualizer for the actual tracking and blender for reconstructing the set geometry and aligning the scene. Whem I’m done in blender and import the modeled geometry I also need to read out every global coordinate of every marker in the scene so I can translate these coordinates to the markers in 3DE so that the scene is also aligned there and the modeled geometry is exactly where I want it to be. Until now I always had to extract those coordinates manually which can take ages when you have more than 40 markers and is REALLY axhausting! :frowning:

So I thought with blenders python API there has to be a way to do this automatically with a script. So I googled and found only tutorials for python itself and one scrips that is only for blender 2.5 and doesnt work with 2.7 anymore.

As I am no programmer I thought that I could use a little help. Maybe someone here is able and willing to help me :slight_smile:

This is the script that I found:


timport Blender
from Blender import *


print "# Start of Skript. #################################"

must_be_contained = "marker"     
ob = Blender.Object.Get () #all objects will be written to list ob


f = file('C:/tmp/output.txt','w')  #creates a file in write mode
   
for i in range(len(ob)):
   if must_be_contained in ob[i].getName(): #checks if marker can be found in objectname

      print ob[i].getName(), ob[i].LocX, ob[i].LocZ,ob[i].LocY, " ", \
      ob[i].RotX, ob[i].RotZ, ob[i].RotY, "   ", \
      ob[i].SizeX, ob[i].SizeZ, ob[i].SizeY, "
"
         
      #Output in file, Y and Z are swapped
      f.write(ob[i].getName() + "	" + \
      str(ob[i].LocX) + "	" + str(ob[i].LocZ) + "	" + str(ob[i].LocY) + "	" + \
      str(ob[i].RotZ) + "	" + \
      str(ob[i].SizeY) + '
')
     
f.close() #close file
print "# End of Skript. ###################################"

In the forum I found this script the author said that doing this was pretty easy but since I am no programmer at all and completely new to python I would really appreciate every help! :slight_smile: It would save me soooo many time and frustration if I would get this thing to work!

So my thanks in advance for every help!

Lukas

This is quite pythonic:

import bpy

with open(r"C:	emp\output.txt", "w") as file:
    for ob in bpy.context.scene.objects:
        if "marker" in ob.name:
            mat = ob.matrix_world
            loc = mat.translation.xzy[:]
            rot = mat.to_euler()[:]
            scale = mat.to_scale()[:]
            
            print(ob.name, "	".join(map(str, loc + rot + scale)))
            
            file.write("	".join(map(str, (ob.name,) + loc + rot + scale)))
            file.write("
")

Not sure if Euler angles are really what you need, but I guess so.

I suggest to round off the floats however (not in original script, but Python 2.x might also handle this differently):

import bpy

with open(r"C:	emp\output.txt", "w") as file:
    for ob in bpy.context.scene.objects:
        if "marker" in ob.name:
            mat = ob.matrix_world
            loc = mat.translation.xzy[:]
            rot = mat.to_euler()[:]
            scale = mat.to_scale()[:]
            
            print(ob.name, ("	%f" * 9) % (loc + rot + scale))
            
            file.write(ob.name)
            file.write(("	%f" * 9) % (loc + rot + scale))
            file.write("
")

Very good answer, CoDEmanX! Interesting…hum hum…Ha Thks.

Thank you so much!! =) The script works like a charm! =)

But I have two last questions :o

In case I only want the location data to be written to the file I changed the first code without rounding like this:


import bpy

with open(r"C:\Users\lis\Documents\survey.txt", "w") as file:
    for ob in bpy.context.scene.objects:
        if "p" in ob.name:
            mat = ob.matrix_world
            loc = mat.translation.xzy[:]
            rot = mat.to_euler()[:]
            scale = mat.to_scale()[:]
            
            print(ob.name, "	".join(map(str, loc)))
            
            file.write("	".join(map(str, (ob.name,) + loc)))
            file.write("
")

Everything works and only the location is written. But when I do the same thing in the second code with rounding, blender says that the script fails… :frowning: What do I have to do?

And my second question is:
I have to multiply every unit with 100 because 1m in blender is 1cm after the transfere in 3DE. How can I accomplish that? Thank you so much in andvance! I should really hear this as my wakeup call to learn python myself…

I found the answere to my second question myself! :slight_smile:

I just added this: loc = (mat.translation.xzy * 100)[:]

Now that I actually used the survey file, I found out that I also have to multiply only the x-axis with -1 because somehow 3DE uses this axis swapped in comparison to blender. But whe I do something like this:

loc = (mat.translation.(x*(-1))zy *100)[:]

I get a syntax error…

You need to do the inversion in a separate step:

import bpy

with open(r"C:	emp\output.txt", "w") as file:
    for ob in bpy.context.scene.objects:
        if "marker" in ob.name:
            mat = ob.matrix_world
            loc = mat.translation.xzy * 100
            loc.x *= -1
            
            print(ob.name, ("	%f" * 3) % loc[:])
            
            file.write(ob.name)
            file.write(("	%f" * 3) % loc[:])
            file.write("
")