[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3049] contrib/py/scripts/addons/ io_export_marmalade.py: Marmalade Exporter, initial version in Contrib

benoit.muller at laposte.net benoit.muller at laposte.net
Sat Mar 3 02:03:55 CET 2012


Hi Campbell,

Many thanks for the review, I will commit the changes.
I'm C++ developper and I learned python for this script, that's why I'm sometimes 
missing some good python shortcuts or optimizations you have mentioned.

I couldn't find simple explanations for the self.as_keywords syntax, so it is not yet 
done.

About the Image convertion, I initially tried to do it with Blender, but Image object 
does not have a SaveAs or SaveCopy method. There is an operator on image that allows 
to save_as, but I was unable to use it because I was not in the right context...

The other way would be to enhance the Native Image object implementation, but then it 
is in the Blender core and no more in extensions.

Have you a design in mind to implement the image conversion in Blender ?

Thanks again for all your good advices
Regards
Benoit



> Message du 02/03/12 14:46
> De : "Campbell Barton" 
> A : bf-extensions-cvs at blender.org
> Copie à : benoit.muller at laposte.net
> Objet : Re: [Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3049] 
contrib/py/scripts/addons/ io_export_marmalade.py: Marmalade Exporter, initial version 
in Contrib
>
> Hi Benoit, great to see your script in contrib - had a quick look over
> it and some suggestions.
> 
> ---
> Rather then relying on "convert.exe" - blender could do the
> conversion, you can load, save and free and image, would be nice one
> to add to bpy_extras.image_utils module.
> - will make the script more portable too since it looks like the
> script assumes windows at the moment.
> 
> 
> ---
> Notice you transform the mesh multiple times:
> Mesh.transform(Object.matrix_world)
> Mesh.transform(SCALE_MAT)
> Mesh.transform(X_ROT)
> 
> Better multiply the mat's together and transform once.
> 
> ---
> 
> For classes with many instances - CGeoIndexList, CGeoPoly - suggest
> using __slots__ to save some memory. (also I find this better practice
> and prevents assigning invalid values).
> 
> ---
> if len(self.vnList) > 0:
> can be:
> if self.vnList:
> ---
> 
> matList = list()
> for matName in self.MaterialsDict.keys():
> matList.append(matName)
> return matList
> 
> can be
> return list(self.MaterialsDict.keys())
> ---
> Looks like a typo in GetMaterialByName :
> return none
> 
> ----
> 
> lines over 200 length in WriteMeshPoly() could be broken up, just
> style preference.
> 
> ---
> 
> (MatSpecularColor[0] * 255, MatSpecularColor[1] * 255,
> MatSpecularColor[2] * 255)
> 
> can be...
> (MatSpecularColor * 255)[:]
> 
> ---
> 
> Large multiline comments in WriteKeyedAnimationSet(), nicer to use """
> """'s (again personal preference).
> 
> ---
> 
> in WriteKeyedAnimationSet - better to store scene as a var rather then
> access as bpy.context.scene.
> 
> ---
> # Exports all frames
> for i in
> range(bpy.context.scene.frame_start,bpy.context.scene.frame_end + 1,
> 1):
> keyframeTimes.add(i)
> 
> Can be...
> 
> keyframeTimes.update(range(scene.frame_start, scene.frame_end + 1, 1))
> 
> ---
> 
> when calling MarmaladeExporterSettings() looks like you could use
> operator method:
> 
> self.as_keywords()
> ... since theres a 1:1 mapping from settings to keyword args.
> 
> ---
> 
> Regards
> 
> - Campbell
> 
> On Fri, Mar 2, 2012 at 6:39 PM, Benoit Muller  wrote:
> > Revision: 3049
> >          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-
extensions&revision=3049
> > Author:   benoitmuller
> > Date:     2012-03-02 07:38:55 +0000 (Fri, 02 Mar 2012)
> > Log Message:
> > -----------
> > Marmalade Exporter, initial version in Contrib
> > Allows to export animated characters and Scene For Marmalade SDK.
> > Marmalade allows to build IPhone, Android, BlackBerry, Badda Applications/Games in 
C++.
> >
> > Added Paths:
> > -----------
> >    contrib/py/scripts/addons/io_export_marmalade.py
> >
> > Added: contrib/py/scripts/addons/io_export_marmalade.py
> > ===================================================================
> > --- contrib/py/scripts/addons/io_export_marmalade.py                           
 (rev 0)
> > +++ contrib/py/scripts/addons/io_export_marmalade.py    2012-03-02 07:38:55 UTC 
(rev 3049)
> > @@ -0,0 +1,1733 @@
> > +# ***** 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 3 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, see .
> > +# All rights reserved.
> > +# ***** GPL LICENSE BLOCK *****
> > +
> > +# Marmalade SDK is not responsible in any case of the following code.
> > +# This Blender add-on is freely shared for the Blender and Marmalade user 
communities.
> > +
> > +
> > +bl_info = {
> > +    "name": "Marmalade Cross-platform Apps (.group)",
> > +    "author": "Benoit Muller",
> > +    "version": (0, 5, 0),
> > +    "blender": (2, 6, 0),
> > +    "api": 37702,
> > +    "location": "File > Export > Marmalade cross-platform Apps (.group)",
> > +    "description": "Export Marmalade Format files (.group)",
> > +    "warning": "",
> > +    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
> > +        "Scripts/Import-Export/Marmalade_Exporter",
> > +    "tracker_url": "https://projects.blender.org/tracker/index.php?"\
> > +        "",
> > +    "category": "Import-Export"}
> > +
> > +import os
> > +import shutil
> > +from math import radians
> > +
> > +import bpy
> > +from mathutils import Matrix
> > +
> > +import mathutils
> > +import math
> > +
> > +import datetime
> > +
> > +import subprocess
> > +
> > +
> > +#Container for the exporter settings
> > +class MarmaladeExporterSettings:
> > +
> > +    def __init__(self,
> > +                 context,
> > +                 FilePath,
> > +                 Optimized=True,
> > +                 CoordinateSystem=1,
> > +                 FlipNormals=False,
> > +                 ApplyModifiers=False,
> > +                 Scale=100,
> > +                 AnimFPS=30,
> > +                 ExportVertexColors=True,
> > +                 ExportMaterialColors=True,
> > +                 ExportTextures=True,
> > +                 CopyTextureFiles=True,
> > +                 ExportArmatures=False,
> > +                 ExportAnimation=0,
> > +                 ExportMode=1,
> > +                 MergeModes=0,
> > +                 Verbose=False):
> > +        self.context = context
> > +        self.FilePath = FilePath
> > +        self.Optimized = Optimized
> > +        self.CoordinateSystem = int(CoordinateSystem)
> > +        self.FlipNormals = FlipNormals
> > +        self.ApplyModifiers = ApplyModifiers
> > +        self.Scale = Scale
> > +        self.AnimFPS = AnimFPS
> > +        self.ExportVertexColors = ExportVertexColors
> > +        self.ExportMaterialColors = ExportMaterialColors
> > +        self.ExportTextures = ExportTextures
> > +        self.CopyTextureFiles = CopyTextureFiles
> > +        self.ExportArmatures = ExportArmatures
> > +        self.ExportAnimation = int(ExportAnimation)
> > +        self.ExportMode = int(ExportMode)
> > +        self.MergeModes = int(MergeModes)
> > +        self.Verbose = Verbose
> > +        self.WarningList = list()
> > +
> > +
> > +def ExportMadeWithMarmaladeGroup(Config):
> > +    print("----------\nExporting to {}".format(Config.FilePath))
> > +    if Config.Verbose:
> > +        print("Opening File...")
> > +    Config.File = open(Config.FilePath, "w")
> > +
> > +    if Config.Verbose:
> > +        print("Done")
> > +
> > +    if Config.MergeModes > 0:
> > +        # Merge mode only work with Optimised setting
> > +        Config.Optimized = True
> > +
> > +    if Config.Verbose:
> > +        print("writing group header")
> > +
> > +    Config.File.write('// Marmalade group file exported from : %s\n' % 
bpy.data.filepath)
> > +    Config.File.write('// Exported %s\n' % str(datetime.datetime.now()))
> > +    Config.File.write("CIwResGroup\n{\n\tname \"%s\"\n" % 
bpy.path.display_name_from_filepath(Config.FilePath))
> > +
> > +    if Config.Verbose:
> > +        print("Generating Object list for export... (Root parents only)")
> > +    if Config.ExportMode == 1:
> > +        Config.ExportList = [Object for Object in Config.context.scene.objects
> > +                             if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}
> > +                             and Object.parent is None]
> > +    else:
> > +        ExportList = [Object for Object in Config.context.selected_objects
> > +                      if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}]
> > +        Config.ExportList = [Object for Object in ExportList
> > +                             if Object.parent not in ExportList]
> > +    if Config.Verbose:
> > +        print("  List: {}\nDone".format(Config.ExportList))
> > +
> > +    if Config.Verbose:
> > +        print("Setting up...")
> > +
> > +    if Config.ExportAnimation:
> > +        if Config.Verbose:
> > +            print(bpy.context.scene)
> > +            print(bpy.context.scene.frame_current)
> > +        CurrentFrame = bpy.context.scene.frame_current
> > +        #comment because it crashes Blender on some old blend file: 
bpy.context.scene.frame_current = bpy.context.scene.frame_current
> > +    if Config.Verbose:
> > +        print("Done")
> > +
> > +    Config.ObjectList = []
> > +    if Config.Verbose:
> > +        print("Writing Objects...")
> > +    WriteObjects(Config, Config.ExportList)
> > +    if Config.Verbose:
> > +        print("Done")
> > +
> > +    if Config.Verbose:
> > +        print("Objects Exported: {}".format(Config.ExportList))
> > +
> > +    if Config.ExportAnimation:
> > +        if Config.Verbose:
> > +            print("Writing Animation...")
> > +        WriteKeyedAnimationSet(Config)
> > +        bpy.context.scene.frame_current = CurrentFrame
> > +        if Config.Verbose:
> > +            print("Done")
> > +    Config.File.write("}\n")
> > +    CloseFile(Config)
> > +    print("Finished")
> > +
> > +
> > +def GetObjectChildren(Parent):
> > +    return [Object for Object in Parent.children
> > +            if Object.type in {'ARMATURE', 'EMPTY', 'MESH'}]
> > +
> > +
> > +#Returns the vertex count of Mesh in not optimized version, counting each vertex 
for every face.
> > +def GetNonOptimizedMeshVertexCount(Mesh):
> > +    VertexCount = 0
> > +    for Face in Mesh.faces:
> > +        VertexCount += len(Face.vertices)
> > +    return VertexCount
> > +
> > +
> > +#Returns the file path of first image texture from Material.
> > +def GetMaterialTextureFullPath(Config, Material):
> > +    if Material:
> > +        #Create a list of Textures that have type "IMAGE"
> > +        ImageTextures = [Material.texture_slots[TextureSlot].texture for 
TextureSlot in Material.texture_slots.keys() if 
Material.texture_slots[TextureSlot].texture.type == "IMAGE"]
> > +        #Refine a new list with only image textures that have a file source
> > +        TexImages = [Texture.image for Texture in ImageTextures if 
getattr(Texture.image, "source", "") == "FILE"]
> > +        ImageFiles = [Texture.image.filepath for Texture in ImageTextures if 
getattr(Texture.image, "source", "") == "FILE"]
> > +        if TexImages:
> > +            filepath = TexImages[0].filepath
> > +            if TexImages[0].packed_file:
> > +                TexImages[0].unpack()
> > +            if not os.path.exists(filepath):
> > +                #try relative path to the blend file
> > +                filepath = os.path.dirname(bpy.data.filepath) + filepath
> > +            #Marmalade doesn't like jpeg/tif so try to convert in png on the fly
> > +            if (TexImages[0].file_format == 'JPEG' or TexImages[0].file_format == 
'TIFF') and os.path.exists(filepath):
> > +                marmaladeConvert = 
os.path.expandvars("%S3E_DIR%\\..\\tools\\ImageMagick\\win32\\convert.exe")
> > +                if (os.path.exists(marmaladeConvert)):
> > +                    srcImagefilepath = filepath
> > +                    filepath = os.path.splitext(filepath)[0] + '.png'
> > +                    if Config.Verbose:
> > +                        print("  /!\\ Converting Texture %s in PNG: %s{}..." % 
(TexImages[0].file_format, filepath))
> > +                        print('"%s" "%s" "%s"' % (marmaladeConvert, 
srcImagefilepath, filepath))
> > +                    subprocess.call([marmaladeConvert, srcImagefilepath, 
filepath])
> > +            return filepath
> > +    return None
> > +
> > +
> > +def WriteObjects(Config, ObjectList, geoFile=None, mtlFile=None, GeoModel=None, 
 bChildObjects=False):
> > +    Config.ObjectList += ObjectList
> > +
> > +    if bChildObjects == False and Config.MergeModes > 0:
> > +        if geoFile == None:
> > +            #we merge objects, so use name of group file for the name of Geo
> > +            geoFile, mtlFile = CreateGeoMtlFiles(Config, 
bpy.path.display_name_from_filepath(Config.FilePath))
> > +            GeoModel = 
CGeoModel(bpy.path.display_name_from_filepath(Config.FilePath))
> > +
> > +    for Object in ObjectList:
> > +        if Config.Verbose:
> > +            print("  Writing Object: {}...".format(Object.name))
> > +
> > +        if Config.ExportArmatures and Object.type == "ARMATURE":
> > +            Armature = Object.data
> > +            ParentList = [Bone for Bone in Armature.bones if Bone.parent is None]
> > +            if Config.Verbose:
> > +                print("    Writing Armature Bones...")
> > +            #Create the skel file
> > +            skelfullname = os.path.dirname(Config.FilePath) + "\models\%s.skel" % 
(StripName(Object.name))
> > +            ensure_dir(skelfullname)
> > +            if Config.Verbose:
> > +                print("      Creating skel file %s" % (skelfullname))
> > +
> > +            skelFile = open(skelfullname, "w")
> > +            skelFile.write('// skel file exported from : %r\n' % 
os.path.basename(bpy.data.filepath))
> > +            skelFile.write("CIwAnimSkel\n")
> > +            skelFile.write("{\n")
> > +            skelFile.write("\tnumBones %d\n" % (len(Armature.bones)))
> > +            Config.File.write("\t\".\models\%s.skel\"\n" % 
(StripName(Object.name)))
> > +
> > +            WriteArmatureParentRootBones(Config, Object, ParentList, skelFile)
> > +
> > +            skelFile.write("}\n")
> > +            skelFile.close()
> > +            if Config.Verbose:
> > +                print("    Done")
> > +
> > +        ChildList = GetObjectChildren(Object)
> > +        if Config.ExportMode == 2:  # Selected Objects Only
> > +            ChildList = [Child for Child in ChildList
> > +                         if Child in Config.context.selected_objects]
> > +        if Config.Verbose:
> > +            print("    Writing Children...")
> > +        WriteObjects(Config, ChildList, geoFile, mtlFile, GeoModel, True)
> >
> > @@ 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
> 

Une messagerie gratuite, garantie à vie et des services en plus, ça vous tente ?
Je crée ma boîte mail www.laposte.net


More information about the Bf-extensions-cvs mailing list