[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3049] contrib/py/scripts/addons/ io_export_marmalade.py: Marmalade Exporter, initial version in Contrib
Campbell Barton
ideasman42 at gmail.com
Fri Mar 2 14:46:49 CET 2012
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 <benoit.muller at laposte.net> 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 <http://www.gnu.org/licenses/>.
> +# 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
More information about the Bf-extensions-cvs
mailing list