[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2723] contrib/py/scripts/addons:

Campbell Barton ideasman42 at gmail.com
Mon Dec 5 19:56:38 CET 2011


Hi Michael, nice work on these scripts!

Since 2.61 is our big camera tracker release would be nice to have
these in trunk though looks like its pushing it since we're up to
`important bugfix only` - part of release.

2 minor points...

- Better have as 1 addon, committing move next *(addon for import and
other to export isn't nice for users to manage IMHO), Ill do the move.


This comment,
            #I've found via the experiments that this is a blenders
            #default sensor size (in mm)
            sensor_x = 32.0

Why not use obj.data.sensor_width ?

On Tue, Dec 6, 2011 at 2:10 AM, Michael Krupa <kroopson at wp.pl> wrote:
> Revision: 2723
>          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2723
> Author:   kroopson
> Date:     2011-12-05 15:09:57 +0000 (Mon, 05 Dec 2011)
> Log Message:
> -----------
>
>
> Added Paths:
> -----------
>    contrib/py/scripts/addons/io_export_chan.py
>    contrib/py/scripts/addons/io_import_chan.py
>
> Added: contrib/py/scripts/addons/io_export_chan.py
> ===================================================================
> --- contrib/py/scripts/addons/io_export_chan.py                         (rev 0)
> +++ contrib/py/scripts/addons/io_export_chan.py 2011-12-05 15:09:57 UTC (rev 2723)
> @@ -0,0 +1,161 @@
> +# ##### BEGIN GPL LICENSE BLOCK #####
> +#
> +#  This program is free software; you can redistribute it and/or
> +#  modify it under the terms of the GNU General Public License
> +#  as published by the Free Software Foundation; either version 2
> +#  of the License, or (at your option) any later version.
> +#
> +#  This program is distributed in the hope that it will be useful,
> +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
> +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +#  GNU General Public License for more details.
> +#
> +#  You should have received a copy of the GNU General Public License
> +#  along with this program; if not, write to the Free Software Foundation,
> +#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> +#
> +# ##### END GPL LICENSE BLOCK #####
> +bl_info = {
> +    "name": "Export animation to nuke (.chan)",
> +    "author": "Michael Krupa",
> +    "version": (1, 0),
> +    "blender": (2, 6, 0),
> +    "api": 36079,
> +    "location": "File > Export > Nuke (.chan)",
> +    "description": "Export object's animation to nuke",
> +    "warning": "",
> +    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
> +        "Scripts/Import-Export/Nuke",
> +    "tracker_url": "http://projects.blender.org/tracker/?"\
> +        "func=detail&atid=467&aid=28368&group_id=153",
> +    "category": "Import-Export"}
> +
> +""" This script is an exporter to the nuke's .chan files.
> +It takes the currently active object and writes it's transformation data
> +into a text file with .chan extension."""
> +
> +import bpy
> +from mathutils import Matrix
> +from mathutils import Euler
> +from math import radians
> +from math import degrees
> +from math import atan
> +from math import tan
> +
> +
> +def save_chan(context, filepath, y_up, rot_ord):
> +    #check if we have anything selected, if not, finish without doing anything.
> +    if not bpy.context.active_object:
> +        return {'FINISHED'}
> +
> +    #get the active object
> +    obj = bpy.context.active_object
> +
> +    #get the range of an animation
> +    f_start = bpy.context.scene.frame_start
> +    f_end = bpy.context.scene.frame_end
> +
> +    #get the resolution (needed by nuke)
> +    res_x = bpy.context.scene.render.resolution_x
> +    res_y = bpy.context.scene.render.resolution_y
> +    res_ratio = res_y / res_x
> +
> +    #prepare the correcting matrix
> +    rot_mat = Matrix.Rotation(radians(-90), 4, "X").to_4x4()
> +
> +    f = open(filepath, 'w')
> +    #iterate the frames
> +    for a in range(f_start, f_end, 1):
> +        #reset the new line of a chan file
> +        export_string = []
> +
> +        #set the current frame
> +        bpy.context.scene.frame_set(a)
> +
> +        #get the objects world matrix
> +        mat = obj.matrix_world
> +
> +        #if the setting is proper use the rotation matrix
> +        #to flip the Z and Y axis
> +        if y_up:
> +            mat = rot_mat * mat
> +
> +        #create the first component of a new line, the frame number
> +        export_string.append("%i\t" % a)
> +
> +        #create transform component
> +        t = mat.to_translation()
> +        export_string.append("%f\t%f\t%f\t" % t[:])
> +
> +        #create rotation component
> +        r = mat.to_euler(rot_ord)
> +
> +        #export_string += "%f\t%f\t%f\t" % (r[0], r[1], r[2])
> +        export_string.append("%f\t%f\t%f\t" % (degrees(r[0]),
> +                                           degrees(r[1]),
> +                                           degrees(r[2])))
> +
> +        #if we have a camera, add the focal length
> +        if obj.type == 'CAMERA':
> +            vfov = degrees(2 * atan(tan((obj.data.angle / 2.0) * res_ratio)))
> +            export_string.append("%f\n" % vfov)
> +
> +        #when all is set and done write the new line
> +        f.write("".join(export_string))
> +
> +    #after the whole loop close the file
> +    f.close()
> +
> +    return {'FINISHED'}
> +
> +
> +from bpy_extras.io_utils import ExportHelper
> +from bpy.props import StringProperty, BoolProperty, EnumProperty
> +
> +
> +class ExportChan(bpy.types.Operator, ExportHelper):
> +    '''Export the animation to .chan file, readable by nuke and houdini.
> +    The exporter uses frames from the frames range'''
> +    bl_idname = "export.export_chan"
> +    bl_label = "Export chan file"
> +    filename_ext = ".chan"
> +    filter_glob = StringProperty(default="*.chan", options={'HIDDEN'})
> +    y_up = BoolProperty(name="Make Y up",
> +                       description="Switch the Y and Z axis",
> +                       default=True)
> +    rot_ord = EnumProperty(items=(('XYZ', "XYZ", "XYZ"),
> +                               ('XZY', "XZY", "XZY"),
> +                               ('YXZ', "YXZ", "YXZ"),
> +                               ('YZX', "YZX", "YZX"),
> +                               ('ZXY', "ZXY", "ZXY"),
> +                               ('ZYX', "ZYX", "ZYX"),
> +                               ),
> +                        name="Rotation order",
> +                        description="Choose the export rotation order",
> +                        default='XYZ')
> +    settings = {"y_up": y_up, "rot_ord": rot_ord}
> +
> +    @classmethod
> +    def poll(cls, context):
> +        return context.active_object != None
> +
> +    def execute(self, context):
> +        return save_chan(context, self.filepath, self.y_up, self.rot_ord)
> +
> +
> +def menu_func_export(self, context):
> +    self.layout.operator(ExportChan.bl_idname, text="Nuke (.chan)")
> +
> +
> +def register():
> +    bpy.utils.register_class(ExportChan)
> +    bpy.types.INFO_MT_file_export.append(menu_func_export)
> +
> +
> +def unregister():
> +    bpy.utils.unregister_class(ExportChan)
> +    bpy.types.INFO_MT_file_export.remove(menu_func_export)
> +
> +
> +if __name__ == "__main__":
> +    register()
>
> Added: contrib/py/scripts/addons/io_import_chan.py
> ===================================================================
> --- contrib/py/scripts/addons/io_import_chan.py                         (rev 0)
> +++ contrib/py/scripts/addons/io_import_chan.py 2011-12-05 15:09:57 UTC (rev 2723)
> @@ -0,0 +1,189 @@
> +# ##### BEGIN GPL LICENSE BLOCK #####
> +#
> +#  This program is free software; you can redistribute it and/or
> +#  modify it under the terms of the GNU General Public License
> +#  as published by the Free Software Foundation; either version 2
> +#  of the License, or (at your option) any later version.
> +#
> +#  This program is distributed in the hope that it will be useful,
> +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
> +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +#  GNU General Public License for more details.
> +#
> +#  You should have received a copy of the GNU General Public License
> +#  along with this program; if not, write to the Free Software Foundation,
> +#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> +#
> +# ##### END GPL LICENSE BLOCK #####
> +bl_info = {
> +    "name": "Import animation from chan file (.chan)",
> +    "author": "Michael Krupa",
> +    "version": (1, 0),
> +    "blender": (2, 6, 0),
> +    "api": 36079,
> +    "location": "File > Import > Nuke (.chan)",
> +    "description": "Import object's animation from nuke",
> +    "warning": "",
> +    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
> +        "Scripts/Import-Export/Nuke",
> +    "tracker_url": "http://projects.blender.org/tracker/index.php?"\
> +        "func=detail&atid=467&aid=28368&group_id=153",
> +    "category": "Import-Export"}
> +
> +""" This script is an importer for the nuke's .chan files"""
> +
> +import bpy
> +from mathutils import Matrix
> +from mathutils import Euler
> +from mathutils import Vector
> +from math import radians
> +from math import degrees
> +from math import atan
> +from math import tan
> +
> +
> +def read_chan(context, filepath, Zup, rot_ord):
> +    #check if we have anything selected, if not, finish without doing anything.
> +    if not bpy.context.active_object:
> +        return {'FINISHED'}
> +
> +    #get the active object
> +    obj = bpy.context.active_object
> +
> +    #get the resolution (needed to calculate the camera lens)
> +    res_x = bpy.context.scene.render.resolution_x
> +    res_y = bpy.context.scene.render.resolution_y
> +    res_ratio = res_y / res_x
> +
> +    #prepare the correcting matrix
> +    rot_mat = Matrix.Rotation(radians(90), 4, "X").to_4x4()
> +
> +    #read the file
> +    f = open(filepath, 'r')
> +
> +    #iterate throug the files lines
> +    for line in f.readlines():
> +        #reset the target objects matrix
> +        #(the one from whitch one we'll extract the final transforms)
> +        m_trans_mat = Matrix()
> +        m_trans_mat.to_4x4()
> +
> +        #strip the line
> +        data = line.split()
> +
> +        #test if the line is not commented out
> +        if data[0] != "#":
> +
> +            #set the frame number basing on the chan file
> +            bpy.context.scene.frame_set(int(data[0]))
> +
> +            #read the translation values from the first three columns of line
> +            v_transl = Vector([float(data[1]), float(data[2]), float(data[3])])
> +            translation_mat = Matrix.Translation(v_transl)
> +            translation_mat.to_4x4()
> +
> +            #read the rotations, and set the rotation order basing on the order
> +            #set during the export (it's not being saved in the chan file
> +            #you have to keep it noted somewhere
> +            #the actual objects rotation order doesn't matter since the
> +            #rotations are being extracted from the matrix afterwards
> +            e_rot = Euler([radians(float(data[4])),
> +                            radians(float(data[5])),
> +                            radians(float(data[6]))])
> +            e_rot.order = rot_ord
> +            mrot_mat = e_rot.to_matrix()
> +            mrot_mat.resize_4x4()
> +
> +            #merge the rotation and translation
> +            m_trans_mat = translation_mat * mrot_mat
> +
> +            #correct the world space
> +            #(nuke's and blenders scene spaces are different)
> +            if Zup:
> +                m_trans_mat = rot_mat * m_trans_mat
> +
> +            #break the matrix into a set of the coordinates
> +            trns = m_trans_mat.decompose()
> +
> +            #set the location and the location's keyframe
> +            obj.location = trns[0]
> +            obj.keyframe_insert('location')
> +
> +            #convert the rotation to euler angles (or not)
> +            #basing on the objects rotation mode
>
> @@ Diff output truncated at 10240 characters. @@
> _______________________________________________
> Bf-extensions-cvs mailing list
> Bf-extensions-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-extensions-cvs



-- 
- Campbell


More information about the Bf-extensions-cvs mailing list