From 7de55b86c16b2fbef45d9114031fb3b88044fc4f Mon Sep 17 00:00:00 2001 From: Nobody Really Date: Sat, 9 Jul 2016 11:33:08 +0200 Subject: Whitespace fix --- tools/export/blender25/godot_export_manager.py | 19 +- tools/export/blender25/io_scene_dae/__init__.py | 128 +- tools/export/blender25/io_scene_dae/export_dae.py | 3190 ++++++++++----------- 3 files changed, 1623 insertions(+), 1714 deletions(-) diff --git a/tools/export/blender25/godot_export_manager.py b/tools/export/blender25/godot_export_manager.py index a249611c71..504fdb7934 100644 --- a/tools/export/blender25/godot_export_manager.py +++ b/tools/export/blender25/godot_export_manager.py @@ -36,6 +36,7 @@ import os from bpy.app.handlers import persistent from mathutils import Vector, Matrix + class godot_export_manager(bpy.types.Panel): bl_label = "Godot Export Manager" bl_space_type = 'PROPERTIES' @@ -62,13 +63,10 @@ class godot_export_manager(bpy.types.Panel): op = col.operator("scene.godot_delete_objects_from_group",text="Delete selected objects from Group",icon="PASTEDOWN") - - row = layout.row() col = row.column() col.label(text="Export Groups:") - row = layout.row() col = row.column() @@ -114,6 +112,7 @@ class godot_export_manager(bpy.types.Panel): col.prop(group,"anim_optimize_precision") col.prop(group,"use_metadata") + ### Custom template_list look class UI_List_Godot(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): @@ -150,7 +149,6 @@ class add_objects_to_group(bpy.types.Operator): else: objects_str += ", "+object.name - self.report({'INFO'}, objects_str + " added to group." ) if self.undo: bpy.ops.ed.undo_push(message="Objects added to group") @@ -178,14 +176,12 @@ class del_objects_from_group(bpy.types.Operator): if node.name in selected_objects: scene.godot_export_groups[scene.godot_export_groups_index].nodes.remove(i) - if j == 0: objects_str += object.name else: objects_str += ", "+object.name j+=1 - self.report({'INFO'}, objects_str + " deleted from group." ) bpy.ops.ed.undo_push(message="Objects deleted from group") else: @@ -209,6 +205,7 @@ class select_group_objects(bpy.types.Operator): context.scene.objects.active = bpy.data.objects[node.name] return{'FINISHED'} + class export_groups_autosave(bpy.types.Operator): bl_idname = "scene.godot_export_groups_autosave" bl_label = "Export All Groups" @@ -224,6 +221,7 @@ class export_groups_autosave(bpy.types.Operator): bpy.ops.ed.undo_push(message="Export all Groups") return{'FINISHED'} + class export_all_groups(bpy.types.Operator): bl_idname = "scene.godot_export_all_groups" bl_label = "Export All Groups" @@ -247,7 +245,6 @@ class export_group(bpy.types.Operator): idx = IntProperty(default=0) export_all = BoolProperty(default=False) - def copy_object_recursive(self,ob,parent,single_user = True): new_ob = bpy.data.objects[ob.name].copy() if single_user or ob.type=="ARMATURE": @@ -310,7 +307,6 @@ class export_group(bpy.types.Operator): context.scene.layers = [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] - if group[self.idx].export_name.endswith(".dae"): path = os.path.join(path,group[self.idx].export_name) else: @@ -363,6 +359,7 @@ class export_group(bpy.types.Operator): self.report({'INFO'}, "Define Export Name and Export Path." ) return{'FINISHED'} + class add_export_group(bpy.types.Operator): bl_idname = "scene.godot_add_export_group" bl_label = "Adds a new export Group" @@ -380,6 +377,7 @@ class add_export_group(bpy.types.Operator): bpy.ops.ed.undo_push(message="Create New Export Group") return{'FINISHED'} + class del_export_group(bpy.types.Operator): bl_idname = "scene.godot_delete_export_group" bl_label = "Delets the selected export Group" @@ -398,9 +396,11 @@ class del_export_group(bpy.types.Operator): bpy.ops.ed.undo_push(message="Delete Export Group") return{'FINISHED'} + class godot_node_list(bpy.types.PropertyGroup): name = StringProperty() + class godot_export_groups(bpy.types.PropertyGroup): name = StringProperty(name="Group Name") export_name = StringProperty(name="scene_name") @@ -431,6 +431,7 @@ class godot_export_groups(bpy.types.PropertyGroup): use_metadata = BoolProperty(name="Use Metadata",default=True,options={'HIDDEN'}) use_include_particle_duplicates = BoolProperty(name="Include Particle Duplicates",default=True) + def register(): bpy.utils.register_class(godot_export_manager) bpy.utils.register_class(godot_node_list) @@ -448,6 +449,7 @@ def register(): bpy.types.Scene.godot_export_groups = CollectionProperty(type=godot_export_groups) bpy.types.Scene.godot_export_groups_index = IntProperty(default=0,min=0) + def unregister(): bpy.utils.unregister_class(godot_export_manager) bpy.utils.unregister_class(godot_node_list) @@ -462,6 +464,7 @@ def unregister(): bpy.utils.unregister_class(select_group_objects) bpy.utils.unregister_class(UI_List_Godot) + @persistent def auto_export(dummy): bpy.ops.scene.godot_export_groups_autosave() diff --git a/tools/export/blender25/io_scene_dae/__init__.py b/tools/export/blender25/io_scene_dae/__init__.py index a1a0eabbbe..89c1f009c2 100644 --- a/tools/export/blender25/io_scene_dae/__init__.py +++ b/tools/export/blender25/io_scene_dae/__init__.py @@ -59,90 +59,88 @@ class ExportDAE(bpy.types.Operator, ExportHelper): # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. - object_types = EnumProperty( - name="Object Types", - options={'ENUM_FLAG'}, - items=(('EMPTY', "Empty", ""), - ('CAMERA', "Camera", ""), - ('LAMP', "Lamp", ""), - ('ARMATURE', "Armature", ""), - ('MESH', "Mesh", ""), - ('CURVE', "Curve", ""), - ), - default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH','CURVE'}, - ) + name="Object Types", + options={'ENUM_FLAG'}, + items=(('EMPTY', "Empty", ""), + ('CAMERA', "Camera", ""), + ('LAMP', "Lamp", ""), + ('ARMATURE', "Armature", ""), + ('MESH', "Mesh", ""), + ('CURVE', "Curve", ""), + ), + default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH','CURVE'}, + ) use_export_selected = BoolProperty( - name="Selected Objects", - description="Export only selected objects (and visible in active layers if that applies).", - default=False, - ) + name="Selected Objects", + description="Export only selected objects (and visible in active layers if that applies).", + default=False, + ) use_mesh_modifiers = BoolProperty( - name="Apply Modifiers", - description="Apply modifiers to mesh objects (on a copy!).", - default=False, - ) + name="Apply Modifiers", + description="Apply modifiers to mesh objects (on a copy!).", + default=False, + ) use_tangent_arrays = BoolProperty( - name="Tangent Arrays", - description="Export Tangent and Binormal arrays (for normalmapping).", - default=False, - ) + name="Tangent Arrays", + description="Export Tangent and Binormal arrays (for normalmapping).", + default=False, + ) use_triangles = BoolProperty( - name="Triangulate", - description="Export Triangles instead of Polygons.", - default=False, - ) - + name="Triangulate", + description="Export Triangles instead of Polygons.", + default=False, + ) use_copy_images = BoolProperty( - name="Copy Images", - description="Copy Images (create images/ subfolder)", - default=False, - ) + name="Copy Images", + description="Copy Images (create images/ subfolder)", + default=False, + ) use_active_layers = BoolProperty( - name="Active Layers", - description="Export only objects on the active layers.", - default=True, - ) + name="Active Layers", + description="Export only objects on the active layers.", + default=True, + ) use_anim = BoolProperty( - name="Export Animation", - description="Export keyframe animation", - default=False, - ) + name="Export Animation", + description="Export keyframe animation", + default=False, + ) use_anim_action_all = BoolProperty( - name="All Actions", - description=("Export all actions for the first armature found in separate DAE files"), - default=False, - ) + name="All Actions", + description=("Export all actions for the first armature found in separate DAE files"), + default=False, + ) use_anim_skip_noexp = BoolProperty( - name="Skip (-noexp) Actions", - description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.", - default=True, - ) + name="Skip (-noexp) Actions", + description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.", + default=True, + ) use_anim_optimize = BoolProperty( - name="Optimize Keyframes", - description="Remove double keyframes", - default=True, - ) + name="Optimize Keyframes", + description="Remove double keyframes", + default=True, + ) anim_optimize_precision = FloatProperty( - name="Precision", - description=("Tolerence for comparing double keyframes " - "(higher for greater accuracy)"), - min=1, max=16, - soft_min=1, soft_max=16, - default=6.0, - ) + name="Precision", + description=("Tolerence for comparing double keyframes " + "(higher for greater accuracy)"), + min=1, max=16, + soft_min=1, soft_max=16, + default=6.0, + ) use_metadata = BoolProperty( - name="Use Metadata", - default=True, - options={'HIDDEN'}, - ) + name="Use Metadata", + default=True, + options={'HIDDEN'}, + ) @property def check_extension(self): - return True#return self.batch_mode == 'OFF' + return True # return self.batch_mode == 'OFF' def check(self, context): return True diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 2f7d1ddd86..047c8a063d 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -46,7 +46,7 @@ import bpy import bmesh from mathutils import Vector, Matrix -#according to collada spec, order matters +# according to collada spec, order matters S_ASSET=0 S_IMGS=1 S_FX=2 @@ -64,1661 +64,1569 @@ S_ANIM=12 CMP_EPSILON=0.0001 def snap_tup(tup): - ret=() - for x in tup: - ret+=( x-math.fmod(x,0.0001), ) + ret=() + for x in tup: + ret+=( x-math.fmod(x,0.0001), ) - return tup + return tup def strmtx(mtx): - s=" " - for x in range(4): - for y in range(4): - s+=str(mtx[x][y]) - s+=" " - s+=" " - return s + s=" " + for x in range(4): + for y in range(4): + s+=str(mtx[x][y]) + s+=" " + s+=" " + return s def numarr(a,mult=1.0): - s=" " - for x in a: - s+=" "+str(x*mult) - s+=" " - return s - -def numarr_alpha(a,mult=1.0): - s=" " - for x in a: - s+=" "+str(x*mult) - if len(a) == 3: - s+=" 1.0" - s+=" " - return s - -def strarr(arr): - s=" " - for x in arr: - s+=" "+str(x) - s+=" " - return s - -class DaeExporter: - - def validate_id(self,d): - if (d.find("id-")==0): - return "z"+d - return d - - - def new_id(self,t): - self.last_id+=1 - return "id-"+t+"-"+str(self.last_id) - - class Vertex: - - def close_to(v): - if ( (self.vertex-v.vertex).length() > CMP_EPSILON ): - return False - if ( (self.normal-v.normal).length() > CMP_EPSILON ): - return False - if ( (self.uv-v.uv).length() > CMP_EPSILON ): - return False - if ( (self.uv2-v.uv2).length() > CMP_EPSILON ): - return False - - return True - - def get_tup(self): - tup = (self.vertex.x,self.vertex.y,self.vertex.z,self.normal.x,self.normal.y,self.normal.z) - for t in self.uv: - tup = tup + (t.x,t.y) - if (self.color!=None): - tup = tup + (self.color.x,self.color.y,self.color.z) - if (self.tangent!=None): - tup = tup + (self.tangent.x,self.tangent.y,self.tangent.z) - if (self.bitangent!=None): - tup = tup + (self.bitangent.x,self.bitangent.y,self.bitangent.z) - for t in self.bones: - tup = tup + (float(t),) - for t in self.weights: - tup = tup + (float(t),) - - return tup - - def __init__(self): - self.vertex = Vector( (0.0,0.0,0.0) ) - self.normal = Vector( (0.0,0.0,0.0) ) - self.tangent = None - self.bitangent = None - self.color = None - self.uv = [] - self.uv2 = Vector( (0.0,0.0) ) - self.bones=[] - self.weights=[] - - - def writel(self,section,indent,text): - if (not (section in self.sections)): - self.sections[section]=[] - line="" - for x in range(indent): - line+="\t" - line+=text - self.sections[section].append(line) - - - def export_image(self,image): - if (image in self.image_cache): - return self.image_cache[image] - - imgpath = image.filepath - if (imgpath.find("//")==0 or imgpath.find("\\\\")==0): - #if relative, convert to absolute - imgpath = bpy.path.abspath(imgpath) - - #path is absolute, now do something! - - if (self.config["use_copy_images"]): - #copy image - basedir = os.path.dirname(self.path)+"/images" - if (not os.path.isdir(basedir)): - os.makedirs(basedir) - - if os.path.isfile(imgpath): - dstfile=basedir+"/"+os.path.basename(imgpath) - - if (not os.path.isfile(dstfile)): - shutil.copy(imgpath,dstfile) - imgpath="images/"+os.path.basename(imgpath) - else: - ### if file is not found save it as png file in the destination folder - img_tmp_path = image.filepath - if img_tmp_path.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): - image.filepath = basedir+"/"+os.path.basename(img_tmp_path) - else: - image.filepath = basedir+"/"+image.name+".png" - - dstfile=basedir+"/"+os.path.basename(image.filepath) - - if (not os.path.isfile(dstfile)): - - image.save() - imgpath="images/"+os.path.basename(image.filepath) - image.filepath = img_tmp_path - - else: - #export relative, always, no one wants absolute paths. - try: - imgpath = os.path.relpath(imgpath,os.path.dirname(self.path)).replace("\\","/") # export unix compatible always - - except: - pass #fails sometimes, not sure why - - - imgid = self.new_id("image") - - print("FOR: "+imgpath) - -# if (not os.path.isfile(imgpath)): -# print("NOT FILE?") -# if imgpath.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): -# imgpath="images/"+os.path.basename(imgpath) -# else: -# imgpath="images/"+image.name+".png" - - self.writel(S_IMGS,1,'') - self.writel(S_IMGS,2,''+imgpath+'') - self.writel(S_IMGS,1,'') - self.image_cache[image]=imgid - return imgid - - def export_material(self,material,double_sided_hint=True): - - if (material in self.material_cache): - return self.material_cache[material] - - fxid = self.new_id("fx") - self.writel(S_FX,1,'') - self.writel(S_FX,2,'') - - #Find and fetch the textures and create sources - sampler_table={} - diffuse_tex=None - specular_tex=None - emission_tex=None - normal_tex=None - for i in range(len(material.texture_slots)): - ts=material.texture_slots[i] - if (not ts): - continue - if (not ts.use): - continue - if (not ts.texture): - continue - if (ts.texture.type!="IMAGE"): - continue - - if (ts.texture.image==None): - continue - - #image - imgid = self.export_image(ts.texture.image) - - #surface - surface_sid = self.new_id("fx_surf") - self.writel(S_FX,3,'') - self.writel(S_FX,4,'') - self.writel(S_FX,5,''+imgid+'') #this is sooo weird - self.writel(S_FX,5,'A8R8G8B8') - self.writel(S_FX,4,'') - self.writel(S_FX,3,'') - #sampler, collada sure likes it difficult - sampler_sid = self.new_id("fx_sampler") - self.writel(S_FX,3,'') - self.writel(S_FX,4,'') - self.writel(S_FX,5,''+surface_sid+'') - self.writel(S_FX,4,'') - self.writel(S_FX,3,'') - sampler_table[i]=sampler_sid - - if (ts.use_map_color_diffuse and diffuse_tex==None): - diffuse_tex=sampler_sid - if (ts.use_map_color_spec and specular_tex==None): - specular_tex=sampler_sid - if (ts.use_map_emit and emission_tex==None): - emission_tex=sampler_sid - if (ts.use_map_normal and normal_tex==None): - normal_tex=sampler_sid - - self.writel(S_FX,3,'') - shtype="blinn" - self.writel(S_FX,4,'<'+shtype+'>') - #ambient? from where? - - self.writel(S_FX,5,'') - if (emission_tex!=None): - self.writel(S_FX,6,'') - else: - self.writel(S_FX,6,''+numarr_alpha(material.diffuse_color,material.emit)+' ') # not totally right but good enough - self.writel(S_FX,5,'') - - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+numarr_alpha(self.scene.world.ambient_color,material.ambient)+' ') - self.writel(S_FX,5,'') - - self.writel(S_FX,5,'') - if (diffuse_tex!=None): - self.writel(S_FX,6,'') - else: - self.writel(S_FX,6,''+numarr_alpha(material.diffuse_color,material.diffuse_intensity)+'') - self.writel(S_FX,5,'') - - self.writel(S_FX,5,'') - if (specular_tex!=None): - self.writel(S_FX,6,'') - else: - self.writel(S_FX,6,''+numarr_alpha(material.specular_color,material.specular_intensity)+'') - self.writel(S_FX,5,'') - - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+str(material.specular_hardness)+'') - self.writel(S_FX,5,'') - - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+numarr_alpha(material.mirror_color)+'') - self.writel(S_FX,5,'') - - if (material.use_transparency): - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+str(material.alpha)+'') - self.writel(S_FX,5,'') - - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+str(material.specular_ior)+'') - self.writel(S_FX,5,'') - - self.writel(S_FX,4,'') - - self.writel(S_FX,4,'') - self.writel(S_FX,5,'') - if (normal_tex): - self.writel(S_FX,6,'') - self.writel(S_FX,7,'') - self.writel(S_FX,6,'') - - self.writel(S_FX,5,'') - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+["0","1"][double_sided_hint]+"") - self.writel(S_FX,5,'') - - if (material.use_shadeless): - self.writel(S_FX,5,'') - self.writel(S_FX,6,'1') - self.writel(S_FX,5,'') - - self.writel(S_FX,4,'') - - self.writel(S_FX,3,'') - self.writel(S_FX,2,'') - self.writel(S_FX,1,'') - - # Also export blender material in all it's glory (if set as active) - - - #Material - matid = self.new_id("material") - self.writel(S_MATS,1,'') - self.writel(S_MATS,2,'') - self.writel(S_MATS,1,'') - - self.material_cache[material]=matid - return matid - - - def export_mesh(self,node,armature=None,skeyindex=-1,skel_source=None,custom_name=None): - - mesh = node.data - - - if (node.data in self.mesh_cache): - return self.mesh_cache[mesh] - - if (skeyindex==-1 and mesh.shape_keys!=None and len(mesh.shape_keys.key_blocks)): - values=[] - morph_targets=[] - md=None - for k in range(0,len(mesh.shape_keys.key_blocks)): - shape = node.data.shape_keys.key_blocks[k] - values+=[shape.value] #save value - shape.value=0 - - mid = self.new_id("morph") - - for k in range(0,len(mesh.shape_keys.key_blocks)): - - shape = node.data.shape_keys.key_blocks[k] - node.show_only_shape_key=True - node.active_shape_key_index = k - shape.value = 1.0 - mesh.update() - """ - oldval = shape.value - shape.value = 1.0 - - """ - p = node.data - v = node.to_mesh(bpy.context.scene, True, "RENDER") - node.data = v -# self.export_node(node,il,shape.name) - node.data.update() - if (armature and k==0): - md=self.export_mesh(node,armature,k,mid,shape.name) - else: - md=self.export_mesh(node,None,k,None,shape.name) - - node.data = p - node.data.update() - shape.value = 0.0 - morph_targets.append(md) - - """ - shape.value = oldval - """ - node.show_only_shape_key=False - node.active_shape_key_index = 0 - - - self.writel(S_MORPH,1,'') - #if ("skin_id" in morph_targets[0]): - # self.writel(S_MORPH,2,'') - #else: - self.writel(S_MORPH,2,'') - - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,4,'') - marr="" - warr="" - for i in range(len(morph_targets)): - if (i==0): - continue - elif (i>1): - marr+=" " - - if ("skin_id" in morph_targets[i]): - marr+=morph_targets[i]["skin_id"] - else: - marr+=morph_targets[i]["id"] - - warr+=" 0" - - self.writel(S_MORPH,5,marr) - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,6,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,3,'') - - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,5,warr) - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,6,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,3,'') - - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,2,'') - self.writel(S_MORPH,1,'') - if (armature!=None): - - self.armature_for_morph[node]=armature - - meshdata={} - if (armature): - meshdata = morph_targets[0] - meshdata["morph_id"]=mid - else: - meshdata["id"]=morph_targets[0]["id"] - meshdata["morph_id"]=mid - meshdata["material_assign"]=morph_targets[0]["material_assign"] - - - - self.mesh_cache[node.data]=meshdata - return meshdata - - apply_modifiers = len(node.modifiers) and self.config["use_mesh_modifiers"] - - name_to_use = mesh.name - #print("name to use: "+mesh.name) - if (custom_name!=None and custom_name!=""): - name_to_use=custom_name - - mesh=node.to_mesh(self.scene,apply_modifiers,"RENDER") #is this allright? - - triangulate=self.config["use_triangles"] - if (triangulate): - bm = bmesh.new() - bm.from_mesh(mesh) - bmesh.ops.triangulate(bm, faces=bm.faces) - bm.to_mesh(mesh) - bm.free() - - - mesh.update(calc_tessface=True) - vertices=[] - vertex_map={} - surface_indices={} - materials={} - - materials={} - - si=None - if (armature!=None): - si=self.skeleton_info[armature] - - has_uv=False - has_uv2=False - has_weights=armature!=None - has_tangents=self.config["use_tangent_arrays"] # could detect.. - has_colors=len(mesh.vertex_colors) - mat_assign=[] - - uv_layer_count=len(mesh.uv_textures) - if (has_tangents and len(mesh.uv_textures)): - try: - mesh.calc_tangents() - except: - self.operator.report({'WARNING'},'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.') - #uv_layer_count=0 - mesh.calc_normals_split() - has_tangents=False - - else: - mesh.calc_normals_split() - has_tangents=False - - - for fi in range(len(mesh.polygons)): - f=mesh.polygons[fi] - - if (not (f.material_index in surface_indices)): - surface_indices[f.material_index]=[] - #print("Type: "+str(type(f.material_index))) - #print("IDX: "+str(f.material_index)+"/"+str(len(mesh.materials))) - - try: - #Bizarre blender behavior i don't understand, so catching exception - mat = mesh.materials[f.material_index] - except: - mat= None - - if (mat!=None): - materials[f.material_index]=self.export_material( mat,mesh.show_double_sided ) - else: - materials[f.material_index]=None #weird, has no material? - - indices = surface_indices[f.material_index] - vi=[] - #vertices always 3 - """ - if (len(f.vertices)==3): - vi.append(0) - vi.append(1) - vi.append(2) - elif (len(f.vertices)==4): - #todo, should use shortest path - vi.append(0) - vi.append(1) - vi.append(2) - vi.append(0) - vi.append(2) - vi.append(3) - """ - - for lt in range(f.loop_total): - loop_index = f.loop_start + lt - ml = mesh.loops[loop_index] - mv = mesh.vertices[ml.vertex_index] - - v = self.Vertex() - v.vertex = Vector( mv.co ) - - for xt in mesh.uv_layers: - v.uv.append( Vector( xt.data[loop_index].uv ) ) - - if (has_colors): - v.color = Vector( mesh.vertex_colors[0].data[loop_index].color ) - - v.normal = Vector( ml.normal ) - - if (has_tangents): - v.tangent = Vector( ml.tangent ) - v.bitangent = Vector( ml.bitangent ) - - - # if (armature): - # v.vertex = node.matrix_world * v.vertex - - #v.color=Vertex(mv. ??? - - if (armature!=None): - wsum=0.0 - zero_bones=[] - - for vg in mv.groups: - if vg.group >= len(node.vertex_groups): - continue; - name = node.vertex_groups[vg.group].name - - if (name in si["bone_index"]): - #could still put the weight as 0.0001 maybe - if (vg.weight>0.001): #blender has a lot of zero weight stuff - v.bones.append(si["bone_index"][name]) - v.weights.append(vg.weight) - wsum+=vg.weight - if (wsum==0.0): - if not self.wrongvtx_report: - self.operator.report({'WARNING'},'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.') - self.wrongvtx_report=True - - #blender can have bones assigned that weight zero so they remain local - #this is the best it can be done? - v.bones.append(0) - v.weights.append(1) - - - - - tup = v.get_tup() - idx = 0 - if (skeyindex==-1 and tup in vertex_map): #do not optmize if using shapekeys - idx = vertex_map[tup] - else: - idx = len(vertices) - vertices.append(v) - vertex_map[tup]=idx - - vi.append(idx) - - if (len(vi)>2): - #only triangles and above - indices.append(vi) - - - meshid = self.new_id("mesh") - self.writel(S_GEOM,1,'') - - self.writel(S_GEOM,2,'') - - - # Vertex Array - self.writel(S_GEOM,3,'') - float_values="" - for v in vertices: - float_values+=" "+str(v.vertex.x)+" "+str(v.vertex.y)+" "+str(v.vertex.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - # Normal Array - - self.writel(S_GEOM,3,'') - float_values="" - for v in vertices: - float_values+=" "+str(v.normal.x)+" "+str(v.normal.y)+" "+str(v.normal.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - if (has_tangents): - self.writel(S_GEOM,3,'') - float_values="" - for v in vertices: - float_values+=" "+str(v.tangent.x)+" "+str(v.tangent.y)+" "+str(v.tangent.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') - float_values="" - for v in vertices: - float_values+=" "+str(v.bitangent.x)+" "+str(v.bitangent.y)+" "+str(v.bitangent.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - - - # UV Arrays - - for uvi in range(uv_layer_count): - - self.writel(S_GEOM,3,'') - float_values="" - for v in vertices: - try: - float_values+=" "+str(v.uv[uvi].x)+" "+str(v.uv[uvi].y) - except: - # I don't understand this weird multi-uv-layer API, but with this it seems to works - float_values+=" 0 0 " - - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - # Color Arrays - - if (has_colors): - self.writel(S_GEOM,3,'') - float_values="" - for v in vertices: - float_values+=" "+str(v.color.x)+" "+str(v.color.y)+" "+str(v.color.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - # Triangle Lists - self.writel(S_GEOM,3,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - prim_type="" - if (triangulate): - prim_type="triangles" - else: - prim_type="polygons" - - - for m in surface_indices: - indices = surface_indices[m] - mat = materials[m] - - if (mat!=None): - matref = self.new_id("trimat") - self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'" material="'+matref+'">') # todo material - mat_assign.append( (mat,matref) ) - else: - self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'">') # todo material - - - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - - for uvi in range(uv_layer_count): - self.writel(S_GEOM,4,'') - - if (has_colors): - self.writel(S_GEOM,4,'') - if (has_tangents): - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - - if (triangulate): - int_values="

" - for p in indices: - for i in p: - int_values+=" "+str(i) - int_values+="

" - self.writel(S_GEOM,4,int_values) - else: - for p in indices: - int_values="

" - for i in p: - int_values+=" "+str(i) - int_values+="

" - self.writel(S_GEOM,4,int_values) - - self.writel(S_GEOM,3,'') - - - self.writel(S_GEOM,2,'
') - self.writel(S_GEOM,1,'
') - - - meshdata={} - meshdata["id"]=meshid - meshdata["material_assign"]=mat_assign - if (skeyindex==-1): - self.mesh_cache[node.data]=meshdata - - - # Export armature data (if armature exists) - - if (armature!=None and (skel_source!=None or skeyindex==-1)): - - contid = self.new_id("controller") - - self.writel(S_SKIN,1,'') - if (skel_source!=None): - self.writel(S_SKIN,2,'') - else: - self.writel(S_SKIN,2,'') - - self.writel(S_SKIN,3,''+strmtx(node.matrix_world)+'') - #Joint Names - self.writel(S_SKIN,3,'') - name_values="" - for v in si["bone_names"]: - name_values+=" "+v - - self.writel(S_SKIN,4,''+name_values+'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,5,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') - #Pose Matrices! - self.writel(S_SKIN,3,'') - pose_values="" - for v in si["bone_bind_poses"]: - pose_values+=" "+strmtx(v) - - self.writel(S_SKIN,4,''+pose_values+'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,5,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') - #Skin Weights! - self.writel(S_SKIN,3,'') - skin_weights="" - skin_weights_total=0 - for v in vertices: - skin_weights_total+=len(v.weights) - for w in v.weights: - skin_weights+=" "+str(w) - - self.writel(S_SKIN,4,''+skin_weights+'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,5,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') - - - self.writel(S_SKIN,3,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') - self.writel(S_SKIN,3,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - vcounts="" - vs="" - vcount=0 - for v in vertices: - vcounts+=" "+str(len(v.weights)) - for b in v.bones: - vs+=" "+str(b) - vs+=" "+str(vcount) - vcount+=1 - self.writel(S_SKIN,4,''+vcounts+'') - self.writel(S_SKIN,4,''+vs+'') - self.writel(S_SKIN,3,'') - - - self.writel(S_SKIN,2,'') - self.writel(S_SKIN,1,'') - meshdata["skin_id"]=contid - - - return meshdata - - - def export_mesh_node(self,node,il): - - if (node.data==None): - return - armature=None - armcount=0 - for n in node.modifiers: - if (n.type=="ARMATURE"): - armcount+=1 - - if (node.parent!=None): - if (node.parent.type=="ARMATURE"): - armature=node.parent - if (armcount>1): - self.operator.report({'WARNING'},'Object "'+node.name+'" refers to more than one armature! This is unsupported.') - if (armcount==0): - self.operator.report({'WARNING'},'Object "'+node.name+'" is child of an armature, but has no armature modifier.') - - - if (armcount>0 and not armature): - self.operator.report({'WARNING'},'Object "'+node.name+'" has armature modifier, but is not a child of an armature. This is unsupported.') - - - if (node.data.shape_keys!=None): - sk = node.data.shape_keys - if (sk.animation_data): - #print("HAS ANIM") - #print("DRIVERS: "+str(len(sk.animation_data.drivers))) - for d in sk.animation_data.drivers: - if (d.driver): - for v in d.driver.variables: - for t in v.targets: - if (t.id!=None and t.id.name in self.scene.objects): - #print("LINKING "+str(node)+" WITH "+str(t.id.name)) - self.armature_for_morph[node]=self.scene.objects[t.id.name] - - - meshdata = self.export_mesh(node,armature) - close_controller=False - - if ("skin_id" in meshdata): - close_controller=True - self.writel(S_NODES,il,'') - for sn in self.skeleton_info[armature]["skeleton_nodes"]: - self.writel(S_NODES,il+1,'#'+sn+'') - elif ("morph_id" in meshdata): - self.writel(S_NODES,il,'') - close_controller=True - elif (armature==None): - self.writel(S_NODES,il,'') - - - if (len(meshdata["material_assign"])>0): - - self.writel(S_NODES,il+1,'') - self.writel(S_NODES,il+2,'') - for m in meshdata["material_assign"]: - self.writel(S_NODES,il+3,'') - - self.writel(S_NODES,il+2,'') - self.writel(S_NODES,il+1,'') - - if (close_controller): - self.writel(S_NODES,il,'') - else: - self.writel(S_NODES,il,'') - - - def export_armature_bone(self,bone,il,si): - boneid = self.new_id("bone") - boneidx = si["bone_count"] - si["bone_count"]+=1 - bonesid = si["id"]+"-"+str(boneidx) - if (bone.name in self.used_bones): - if (self.config["use_anim_action_all"]): - self.operator.report({'WARNING'},'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.') - else: - self.used_bones.append(bone.name) - - si["bone_index"][bone.name]=boneidx - si["bone_ids"][bone]=boneid - si["bone_names"].append(bonesid) - self.writel(S_NODES,il,'') - il+=1 - xform = bone.matrix_local - si["bone_bind_poses"].append((si["armature_xform"] * xform).inverted()) - - if (bone.parent!=None): - xform = bone.parent.matrix_local.inverted() * xform - else: - si["skeleton_nodes"].append(boneid) - - self.writel(S_NODES,il,''+strmtx(xform)+'') - for c in bone.children: - self.export_armature_bone(c,il,si) - il-=1 - self.writel(S_NODES,il,'') - - - def export_armature_node(self,node,il): - - if (node.data==None): - return - - self.skeletons.append(node) - - armature = node.data - self.skeleton_info[node]={ "bone_count":0, "id":self.new_id("skelbones"),"name":node.name, "bone_index":{},"bone_ids":{},"bone_names":[],"bone_bind_poses":[],"skeleton_nodes":[],"armature_xform":node.matrix_world } - - - - for b in armature.bones: - if (b.parent!=None): - continue - self.export_armature_bone(b,il,self.skeleton_info[node]) - - if (node.pose): - for b in node.pose.bones: - for x in b.constraints: - if (x.type=='ACTION'): - self.action_constraints.append(x.action) - - - def export_camera_node(self,node,il): - - if (node.data==None): - return - - camera=node.data - camid=self.new_id("camera") - self.writel(S_CAMS,1,'') - self.writel(S_CAMS,2,'') - self.writel(S_CAMS,3,'') - if (camera.type=="PERSP"): - self.writel(S_CAMS,4,'') - self.writel(S_CAMS,5,' '+str(math.degrees(camera.angle))+' ') # I think? - self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') - self.writel(S_CAMS,4,'') - else: - self.writel(S_CAMS,4,'') - self.writel(S_CAMS,5,' '+str(camera.ortho_scale*0.5)+' ') # I think? - self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') - self.writel(S_CAMS,4,'') - - self.writel(S_CAMS,3,'') - self.writel(S_CAMS,2,'') - self.writel(S_CAMS,1,'') - - - self.writel(S_NODES,il,'') - - def export_lamp_node(self,node,il): - - if (node.data==None): - return - - light=node.data - lightid=self.new_id("light") - self.writel(S_LAMPS,1,'') - #self.writel(S_LAMPS,2,'') - self.writel(S_LAMPS,3,'') - - if (light.type=="POINT"): - self.writel(S_LAMPS,4,'') - self.writel(S_LAMPS,5,''+strarr(light.color)+'') - att_by_distance = 2.0 / light.distance # convert to linear attenuation - self.writel(S_LAMPS,5,''+str(att_by_distance)+'') - if (light.use_sphere): - self.writel(S_LAMPS,5,''+str(light.distance)+'') - - self.writel(S_LAMPS,4,'') - elif (light.type=="SPOT"): - self.writel(S_LAMPS,4,'') - self.writel(S_LAMPS,5,''+strarr(light.color)+'') - att_by_distance = 2.0 / light.distance # convert to linear attenuation - self.writel(S_LAMPS,5,''+str(att_by_distance)+'') - self.writel(S_LAMPS,5,''+str(math.degrees(light.spot_size/2))+'') - self.writel(S_LAMPS,4,'') - - - else: #write a sun lamp for everything else (not supported) - self.writel(S_LAMPS,4,'') - self.writel(S_LAMPS,5,''+strarr(light.color)+'') - self.writel(S_LAMPS,4,'') - - - self.writel(S_LAMPS,3,'') - #self.writel(S_LAMPS,2,'') - self.writel(S_LAMPS,1,'') - - - self.writel(S_NODES,il,'') - - def export_empty_node(self,node,il): - - self.writel(S_NODES,4,'') - self.writel(S_NODES,5,'') - self.writel(S_NODES,6,''+node.empty_draw_type+'') - self.writel(S_NODES,5,'') - self.writel(S_NODES,4,'') - - - def export_curve(self,curve): - - splineid = self.new_id("spline") - - self.writel(S_GEOM,1,'') - self.writel(S_GEOM,2,'') - - points=[] - interps=[] - handles_in=[] - handles_out=[] - tilts=[] - - for cs in curve.splines: - - if (cs.type=="BEZIER"): - for s in cs.bezier_points: - points.append(s.co[0]) - points.append(s.co[1]) - points.append(s.co[2]) - - - handles_in.append(s.handle_left[0]) - handles_in.append(s.handle_left[1]) - handles_in.append(s.handle_left[2]) - - handles_out.append(s.handle_right[0]) - handles_out.append(s.handle_right[1]) - handles_out.append(s.handle_right[2]) - - - tilts.append(s.tilt) - interps.append("BEZIER") - else: - - for s in cs.points: - points.append(s.co[0]) - points.append(s.co[1]) - points.append(s.co[2]) - handles_in.append(s.co[0]) - handles_in.append(s.co[1]) - handles_in.append(s.co[2]) - handles_out.append(s.co[0]) - handles_out.append(s.co[1]) - handles_out.append(s.co[2]) - tilts.append(s.tilt) - interps.append("LINEAR") - - - - - self.writel(S_GEOM,3,'') - position_values="" - for x in points: - position_values+=" "+str(x) - self.writel(S_GEOM,4,''+position_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') - intangent_values="" - for x in handles_in: - intangent_values+=" "+str(x) - self.writel(S_GEOM,4,''+intangent_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') - outtangent_values="" - for x in handles_out: - outtangent_values+=" "+str(x) - self.writel(S_GEOM,4,''+outtangent_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') - interpolation_values="" - for x in interps: - interpolation_values+=" "+x - self.writel(S_GEOM,4,''+interpolation_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - - self.writel(S_GEOM,3,'') - tilt_values="" - for x in tilts: - tilt_values+=" "+str(x) - self.writel(S_GEOM,4,''+tilt_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - - self.writel(S_GEOM,2,'') - self.writel(S_GEOM,1,'') - - return splineid - - def export_curve_node(self,node,il): - - if (node.data==None): - return - curveid = self.export_curve(node.data) - - self.writel(S_NODES,il,'') - self.writel(S_NODES,il,'') - - - - def export_node(self,node,il): - if (not node in self.valid_nodes): - return - prev_node = bpy.context.scene.objects.active - bpy.context.scene.objects.active = node - - self.writel(S_NODES,il,'') - il+=1 - - self.writel(S_NODES,il,''+strmtx(node.matrix_local)+'') - #print("NODE TYPE: "+node.type+" NAME: "+node.name) - if (node.type=="MESH"): - self.export_mesh_node(node,il) - elif (node.type=="CURVE"): - self.export_curve_node(node,il) - elif (node.type=="ARMATURE"): - self.export_armature_node(node,il) - elif (node.type=="CAMERA"): - self.export_camera_node(node,il) - elif (node.type=="LAMP"): - self.export_lamp_node(node,il) - elif (node.type=="EMPTY"): - self.export_empty_node(node,il) - - for x in node.children: - self.export_node(x,il) - - il-=1 - self.writel(S_NODES,il,'') - bpy.context.scene.objects.active = prev_node #make previous node active again - - def is_node_valid(self,node): - if (not node.type in self.config["object_types"]): - return False - if (self.config["use_active_layers"]): - valid=False - #print("NAME: "+node.name) - for i in range(20): - if (node.layers[i] and self.scene.layers[i]): - valid=True - break - if (not valid): - return False - - if (self.config["use_export_selected"] and not node.select): - return False - - return True - - - def export_scene(self): - - - self.writel(S_NODES,0,'') - self.writel(S_NODES,1,'') - - #validate nodes - for obj in self.scene.objects: - if (obj in self.valid_nodes): - continue - if (self.is_node_valid(obj)): - n = obj - while (n!=None): - if (not n in self.valid_nodes): - self.valid_nodes.append(n) - n=n.parent - - - - for obj in self.scene.objects: - if (obj in self.valid_nodes and obj.parent==None): - self.export_node(obj,2) - - self.writel(S_NODES,1,'') - self.writel(S_NODES,0,'') - - def export_asset(self): - - - self.writel(S_ASSET,0,'') - # Why is this time stuff mandatory?, no one could care less... - self.writel(S_ASSET,1,'') - self.writel(S_ASSET,2,' Anonymous ') #Who made Collada, the FBI ? - self.writel(S_ASSET,2,' Collada Exporter for Blender 2.6+, by Juan Linietsky (juan@codenix.com) ') #Who made Collada, the FBI ? - self.writel(S_ASSET,1,'') - self.writel(S_ASSET,1,''+time.strftime("%Y-%m-%dT%H:%M:%SZ ")+'') - self.writel(S_ASSET,1,''+time.strftime("%Y-%m-%dT%H:%M:%SZ")+'') - self.writel(S_ASSET,1,'') - self.writel(S_ASSET,1,'Z_UP') - self.writel(S_ASSET,0,'') - - - def export_animation_transform_channel(self,target,keys,matrices=True): - - frame_total=len(keys) - anim_id=self.new_id("anim") - self.writel(S_ANIM,1,'') - source_frames = "" - source_transforms = "" - source_interps = "" - - for k in keys: - source_frames += " "+str(k[0]) - if (matrices): - source_transforms += " "+strmtx(k[1]) - else: - source_transforms += " "+str(k[1]) - - source_interps +=" LINEAR" - - - # Time Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_frames+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') - - if (matrices): - # Transform Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_transforms+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') - else: - # Value Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_transforms+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') - - # Interpolation Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_interps+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') - - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') - if (matrices): - self.writel(S_ANIM,2,'') - else: - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,1,'') - - return [anim_id] - - - def export_animation(self,start,end,allowed=None): - - #Blender -> Collada frames needs a little work - #Collada starts from 0, blender usually from 1 - #The last frame must be included also - - frame_orig = self.scene.frame_current - - frame_len = 1.0 / self.scene.render.fps - frame_total = end - start + 1 - frame_sub = 0 - if (start>0): - frame_sub=start*frame_len - - tcn = [] - xform_cache={} - blend_cache={} - # Change frames first, export objects last - # This improves performance enormously - - #print("anim from: "+str(start)+" to "+str(end)+" allowed: "+str(allowed)) - for t in range(start,end+1): - self.scene.frame_set(t) - key = t * frame_len - frame_sub -# print("Export Anim Frame "+str(t)+"/"+str(self.scene.frame_end+1)) - - for node in self.scene.objects: - - if (not node in self.valid_nodes): - continue - if (allowed!=None and not (node in allowed)): - if (node.type=="MESH" and node.data!=None and (node in self.armature_for_morph) and (self.armature_for_morph[node] in allowed)): - pass #all good you pass with flying colors for morphs inside of action - else: - #print("fail "+str((node in self.armature_for_morph))) - continue - if (node.type=="MESH" and node.data!=None and node.data.shape_keys!=None and (node.data in self.mesh_cache) and len(node.data.shape_keys.key_blocks)): - target = self.mesh_cache[node.data]["morph_id"] - for i in range(len(node.data.shape_keys.key_blocks)): - - if (i==0): - continue - - name=target+"-morph-weights("+str(i-1)+")" - if (not (name in blend_cache)): - blend_cache[name]=[] - - blend_cache[name].append( (key,node.data.shape_keys.key_blocks[i].value) ) - - - if (node.type=="MESH" and node.parent and node.parent.type=="ARMATURE"): - - continue #In Collada, nodes that have skin modifier must not export animation, animate the skin instead. - - if (len(node.constraints)>0 or node.animation_data!=None): - #If the node has constraints, or animation data, then export a sampled animation track - name=self.validate_id(node.name) - if (not (name in xform_cache)): - xform_cache[name]=[] - - mtx = node.matrix_world.copy() - if (node.parent): - mtx = node.parent.matrix_world.inverted() * mtx - - xform_cache[name].append( (key,mtx) ) - - if (node.type=="ARMATURE"): - #All bones exported for now - - for bone in node.data.bones: - - bone_name=self.skeleton_info[node]["bone_ids"][bone] - - if (not (bone_name in xform_cache)): - #print("has bone: "+bone_name) - xform_cache[bone_name]=[] - - posebone = node.pose.bones[bone.name] - parent_posebone=None - - mtx = posebone.matrix.copy() - if (bone.parent): - parent_posebone=node.pose.bones[bone.parent.name] - parent_invisible=False - - for i in range(3): - if (parent_posebone.scale[i]==0.0): - parent_invisible=True - - if (not parent_invisible): - mtx = parent_posebone.matrix.inverted() * mtx - - - xform_cache[bone_name].append( (key,mtx) ) - - self.scene.frame_set(frame_orig) - - #export animation xml - for nid in xform_cache: - tcn+=self.export_animation_transform_channel(nid,xform_cache[nid],True) - for nid in blend_cache: - tcn+=self.export_animation_transform_channel(nid,blend_cache[nid],False) - - return tcn - - def export_animations(self): - tmp_mat = [] - for s in self.skeletons: - tmp_bone_mat = [] - for bone in s.pose.bones: - tmp_bone_mat.append(Matrix(bone.matrix_basis)) - bone.matrix_basis = Matrix() - tmp_mat.append([Matrix(s.matrix_local),tmp_bone_mat]) - - self.writel(S_ANIM,0,'') + s=" " + for x in a: + s+=" "+str(x*mult) + s+=" " + return s - if (self.config["use_anim_action_all"] and len(self.skeletons)): - - cached_actions = {} - - for s in self.skeletons: - if s.animation_data and s.animation_data.action: - cached_actions[s] = s.animation_data.action.name - - - self.writel(S_ANIM_CLIPS,0,'') - - for x in bpy.data.actions[:]: - if x.users==0 or x in self.action_constraints: - continue - if (self.config["use_anim_skip_noexp"] and x.name.endswith("-noexp")): - continue - - bones=[] - #find bones used - for p in x.fcurves: - dp = str(p.data_path) - base = "pose.bones[\"" - if (dp.find(base)==0): - dp=dp[len(base):] - if (dp.find('"')!=-1): - dp=dp[:dp.find('"')] - if (not dp in bones): - bones.append(dp) - - allowed_skeletons=[] - for i,y in enumerate(self.skeletons): - if (y.animation_data): - for z in y.pose.bones: - if (z.bone.name in bones): - if (not y in allowed_skeletons): - allowed_skeletons.append(y) - y.animation_data.action=x; - - y.matrix_local = tmp_mat[i][0] - for j,bone in enumerate(s.pose.bones): - bone.matrix_basis = Matrix() - - - #print("allowed skeletons "+str(allowed_skeletons)) - - #print(str(x)) - - tcn = self.export_animation(int(x.frame_range[0]),int(x.frame_range[1]+0.5),allowed_skeletons) - framelen=(1.0/self.scene.render.fps) - start = x.frame_range[0]*framelen - end = x.frame_range[1]*framelen - #print("Export anim: "+x.name) - self.writel(S_ANIM_CLIPS,1,'') - for z in tcn: - self.writel(S_ANIM_CLIPS,2,'') - self.writel(S_ANIM_CLIPS,1,'') - if (len(tcn)==0): - self.operator.report({'WARNING'},'Animation clip "'+x.name+'" contains no tracks.') - - - - self.writel(S_ANIM_CLIPS,0,'') - - - for i,s in enumerate(self.skeletons): - if (s.animation_data==None): - continue - if s in cached_actions: - s.animation_data.action = bpy.data.actions[cached_actions[s]] - else: - s.animation_data.action = None - for j,bone in enumerate(s.pose.bones): - bone.matrix_basis = tmp_mat[i][1][j] - - else: - self.export_animation(self.scene.frame_start,self.scene.frame_end) - - - - self.writel(S_ANIM,0,'') - - def export(self): - - self.writel(S_GEOM,0,'') - self.writel(S_CONT,0,'') - self.writel(S_CAMS,0,'') - self.writel(S_LAMPS,0,'') - self.writel(S_IMGS,0,'') - self.writel(S_MATS,0,'') - self.writel(S_FX,0,'') - - - self.skeletons=[] - self.action_constraints=[] - self.export_asset() - self.export_scene() - - self.writel(S_GEOM,0,'') - - #morphs always go before skin controllers - if S_MORPH in self.sections: - for l in self.sections[S_MORPH]: - self.writel(S_CONT,0,l) - del self.sections[S_MORPH] - - #morphs always go before skin controllers - if S_SKIN in self.sections: - for l in self.sections[S_SKIN]: - self.writel(S_CONT,0,l) - del self.sections[S_SKIN] - - self.writel(S_CONT,0,'') - self.writel(S_CAMS,0,'') - self.writel(S_LAMPS,0,'') - self.writel(S_IMGS,0,'') - self.writel(S_MATS,0,'') - self.writel(S_FX,0,'') - - if (self.config["use_anim"]): - self.export_animations() - - try: - f = open(self.path,"wb") - except: - return False - - f.write(bytes('\n',"UTF-8")) - f.write(bytes('\n',"UTF-8")) - - - s=[] - for x in self.sections.keys(): - s.append(x) - s.sort() - for x in s: - for l in self.sections[x]: - f.write(bytes(l+"\n","UTF-8")) - - f.write(bytes('\n',"UTF-8")) - f.write(bytes('\t\n',"UTF-8")) - f.write(bytes('\n',"UTF-8")) - f.write(bytes('\n',"UTF-8")) - return True - - def __init__(self,path,kwargs,operator): - self.operator=operator - self.scene=bpy.context.scene - self.last_id=0 - self.scene_name=self.new_id("scene") - self.sections={} - self.path=path - self.mesh_cache={} - self.curve_cache={} - self.material_cache={} - self.image_cache={} - self.skeleton_info={} - self.config=kwargs - self.valid_nodes=[] - self.armature_for_morph={} - self.used_bones=[] - self.wrongvtx_report=False +def numarr_alpha(a,mult=1.0): + s=" " + for x in a: + s+=" "+str(x*mult) + if len(a) == 3: + s+=" 1.0" + s+=" " + return s +def strarr(arr): + s=" " + for x in arr: + s+=" "+str(x) + s+=" " + return s +class DaeExporter: + def validate_id(self,d): + if (d.find("id-")==0): + return "z"+d + return d + + def new_id(self,t): + self.last_id+=1 + return "id-"+t+"-"+str(self.last_id) + + class Vertex: + + def close_to(v): + if ( (self.vertex-v.vertex).length() > CMP_EPSILON ): + return False + if ( (self.normal-v.normal).length() > CMP_EPSILON ): + return False + if ( (self.uv-v.uv).length() > CMP_EPSILON ): + return False + if ( (self.uv2-v.uv2).length() > CMP_EPSILON ): + return False + + return True + + def get_tup(self): + tup = (self.vertex.x,self.vertex.y,self.vertex.z,self.normal.x,self.normal.y,self.normal.z) + for t in self.uv: + tup = tup + (t.x,t.y) + if (self.color!=None): + tup = tup + (self.color.x,self.color.y,self.color.z) + if (self.tangent!=None): + tup = tup + (self.tangent.x,self.tangent.y,self.tangent.z) + if (self.bitangent!=None): + tup = tup + (self.bitangent.x,self.bitangent.y,self.bitangent.z) + for t in self.bones: + tup = tup + (float(t),) + for t in self.weights: + tup = tup + (float(t),) + + return tup + + def __init__(self): + self.vertex = Vector( (0.0,0.0,0.0) ) + self.normal = Vector( (0.0,0.0,0.0) ) + self.tangent = None + self.bitangent = None + self.color = None + self.uv = [] + self.uv2 = Vector( (0.0,0.0) ) + self.bones=[] + self.weights=[] + + def writel(self,section,indent,text): + if (not (section in self.sections)): + self.sections[section]=[] + line="" + for x in range(indent): + line+="\t" + line+=text + self.sections[section].append(line) + + def export_image(self,image): + if (image in self.image_cache): + return self.image_cache[image] + + imgpath = image.filepath + if (imgpath.find("//")==0 or imgpath.find("\\\\")==0): + #if relative, convert to absolute + imgpath = bpy.path.abspath(imgpath) + + #path is absolute, now do something! + if (self.config["use_copy_images"]): + #copy image + basedir = os.path.dirname(self.path)+"/images" + if (not os.path.isdir(basedir)): + os.makedirs(basedir) + + if os.path.isfile(imgpath): + dstfile=basedir+"/"+os.path.basename(imgpath) + + if (not os.path.isfile(dstfile)): + shutil.copy(imgpath,dstfile) + imgpath="images/"+os.path.basename(imgpath) + else: + ### if file is not found save it as png file in the destination folder + img_tmp_path = image.filepath + if img_tmp_path.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): + image.filepath = basedir+"/"+os.path.basename(img_tmp_path) + else: + image.filepath = basedir+"/"+image.name+".png" + + dstfile=basedir+"/"+os.path.basename(image.filepath) + + if (not os.path.isfile(dstfile)): + + image.save() + imgpath="images/"+os.path.basename(image.filepath) + image.filepath = img_tmp_path + + else: + #export relative, always, no one wants absolute paths. + try: + imgpath = os.path.relpath(imgpath,os.path.dirname(self.path)).replace("\\","/") # export unix compatible always + + except: + pass #fails sometimes, not sure why + + imgid = self.new_id("image") + + print("FOR: "+imgpath) + +# if (not os.path.isfile(imgpath)): +# print("NOT FILE?") +# if imgpath.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): +# imgpath="images/"+os.path.basename(imgpath) +# else: +# imgpath="images/"+image.name+".png" + + self.writel(S_IMGS,1,'') + self.writel(S_IMGS,2,''+imgpath+'') + self.writel(S_IMGS,1,'') + self.image_cache[image]=imgid + return imgid + + def export_material(self,material,double_sided_hint=True): + if (material in self.material_cache): + return self.material_cache[material] + + fxid = self.new_id("fx") + self.writel(S_FX,1,'') + self.writel(S_FX,2,'') + + #Find and fetch the textures and create sources + sampler_table={} + diffuse_tex=None + specular_tex=None + emission_tex=None + normal_tex=None + for i in range(len(material.texture_slots)): + ts=material.texture_slots[i] + if (not ts): + continue + if (not ts.use): + continue + if (not ts.texture): + continue + if (ts.texture.type!="IMAGE"): + continue + + if (ts.texture.image==None): + continue + + #image + imgid = self.export_image(ts.texture.image) + + #surface + surface_sid = self.new_id("fx_surf") + self.writel(S_FX,3,'') + self.writel(S_FX,4,'') + self.writel(S_FX,5,''+imgid+'') #this is sooo weird + self.writel(S_FX,5,'A8R8G8B8') + self.writel(S_FX,4,'') + self.writel(S_FX,3,'') + #sampler, collada sure likes it difficult + sampler_sid = self.new_id("fx_sampler") + self.writel(S_FX,3,'') + self.writel(S_FX,4,'') + self.writel(S_FX,5,''+surface_sid+'') + self.writel(S_FX,4,'') + self.writel(S_FX,3,'') + sampler_table[i]=sampler_sid + + if (ts.use_map_color_diffuse and diffuse_tex==None): + diffuse_tex=sampler_sid + if (ts.use_map_color_spec and specular_tex==None): + specular_tex=sampler_sid + if (ts.use_map_emit and emission_tex==None): + emission_tex=sampler_sid + if (ts.use_map_normal and normal_tex==None): + normal_tex=sampler_sid + + self.writel(S_FX,3,'') + shtype="blinn" + self.writel(S_FX,4,'<'+shtype+'>') + #ambient? from where? + + self.writel(S_FX,5,'') + if (emission_tex!=None): + self.writel(S_FX,6,'') + else: + self.writel(S_FX,6,''+numarr_alpha(material.diffuse_color,material.emit)+' ') # not totally right but good enough + self.writel(S_FX,5,'') + + self.writel(S_FX,5,'') + self.writel(S_FX,6,''+numarr_alpha(self.scene.world.ambient_color,material.ambient)+' ') + self.writel(S_FX,5,'') + + self.writel(S_FX,5,'') + if (diffuse_tex!=None): + self.writel(S_FX,6,'') + else: + self.writel(S_FX,6,''+numarr_alpha(material.diffuse_color,material.diffuse_intensity)+'') + self.writel(S_FX,5,'') + + self.writel(S_FX,5,'') + if (specular_tex!=None): + self.writel(S_FX,6,'') + else: + self.writel(S_FX,6,''+numarr_alpha(material.specular_color,material.specular_intensity)+'') + self.writel(S_FX,5,'') + + self.writel(S_FX,5,'') + self.writel(S_FX,6,''+str(material.specular_hardness)+'') + self.writel(S_FX,5,'') + + self.writel(S_FX,5,'') + self.writel(S_FX,6,''+numarr_alpha(material.mirror_color)+'') + self.writel(S_FX,5,'') + + if (material.use_transparency): + self.writel(S_FX,5,'') + self.writel(S_FX,6,''+str(material.alpha)+'') + self.writel(S_FX,5,'') + + self.writel(S_FX,5,'') + self.writel(S_FX,6,''+str(material.specular_ior)+'') + self.writel(S_FX,5,'') + + self.writel(S_FX,4,'') + + self.writel(S_FX,4,'') + self.writel(S_FX,5,'') + if (normal_tex): + self.writel(S_FX,6,'') + self.writel(S_FX,7,'') + self.writel(S_FX,6,'') + + self.writel(S_FX,5,'') + self.writel(S_FX,5,'') + self.writel(S_FX,6,''+["0","1"][double_sided_hint]+"") + self.writel(S_FX,5,'') + + if (material.use_shadeless): + self.writel(S_FX,5,'') + self.writel(S_FX,6,'1') + self.writel(S_FX,5,'') + + self.writel(S_FX,4,'') + + self.writel(S_FX,3,'') + self.writel(S_FX,2,'') + self.writel(S_FX,1,'') + + # Also export blender material in all it's glory (if set as active) + + # Material + matid = self.new_id("material") + self.writel(S_MATS,1,'') + self.writel(S_MATS,2,'') + self.writel(S_MATS,1,'') + + self.material_cache[material]=matid + return matid + + def export_mesh(self,node,armature=None,skeyindex=-1,skel_source=None,custom_name=None): + mesh = node.data + + if (node.data in self.mesh_cache): + return self.mesh_cache[mesh] + + if (skeyindex==-1 and mesh.shape_keys!=None and len(mesh.shape_keys.key_blocks)): + values=[] + morph_targets=[] + md=None + for k in range(0,len(mesh.shape_keys.key_blocks)): + shape = node.data.shape_keys.key_blocks[k] + values+=[shape.value] #save value + shape.value=0 + + mid = self.new_id("morph") + + for k in range(0,len(mesh.shape_keys.key_blocks)): + + shape = node.data.shape_keys.key_blocks[k] + node.show_only_shape_key=True + node.active_shape_key_index = k + shape.value = 1.0 + mesh.update() + """ + oldval = shape.value + shape.value = 1.0 + + """ + p = node.data + v = node.to_mesh(bpy.context.scene, True, "RENDER") + node.data = v +# self.export_node(node,il,shape.name) + node.data.update() + if (armature and k==0): + md=self.export_mesh(node,armature,k,mid,shape.name) + else: + md=self.export_mesh(node,None,k,None,shape.name) + + node.data = p + node.data.update() + shape.value = 0.0 + morph_targets.append(md) + + """ + shape.value = oldval + """ + node.show_only_shape_key=False + node.active_shape_key_index = 0 + + self.writel(S_MORPH,1,'') + #if ("skin_id" in morph_targets[0]): + # self.writel(S_MORPH,2,'') + #else: + self.writel(S_MORPH,2,'') + + self.writel(S_MORPH,3,'') + self.writel(S_MORPH,4,'') + marr="" + warr="" + for i in range(len(morph_targets)): + if (i==0): + continue + elif (i>1): + marr+=" " + + if ("skin_id" in morph_targets[i]): + marr+=morph_targets[i]["skin_id"] + else: + marr+=morph_targets[i]["id"] + + warr+=" 0" + + self.writel(S_MORPH,5,marr) + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,5,'') + self.writel(S_MORPH,6,'') + self.writel(S_MORPH,5,'') + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,3,'') + + self.writel(S_MORPH,3,'') + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,5,warr) + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,5,'') + self.writel(S_MORPH,6,'') + self.writel(S_MORPH,5,'') + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,3,'') + + self.writel(S_MORPH,3,'') + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,4,'') + self.writel(S_MORPH,3,'') + self.writel(S_MORPH,2,'') + self.writel(S_MORPH,1,'') + if (armature!=None): + + self.armature_for_morph[node]=armature + + meshdata={} + if (armature): + meshdata = morph_targets[0] + meshdata["morph_id"]=mid + else: + meshdata["id"]=morph_targets[0]["id"] + meshdata["morph_id"]=mid + meshdata["material_assign"]=morph_targets[0]["material_assign"] + + self.mesh_cache[node.data]=meshdata + return meshdata + + apply_modifiers = len(node.modifiers) and self.config["use_mesh_modifiers"] + + name_to_use = mesh.name + #print("name to use: "+mesh.name) + if (custom_name!=None and custom_name!=""): + name_to_use=custom_name + + mesh=node.to_mesh(self.scene,apply_modifiers,"RENDER") #is this allright? + + triangulate=self.config["use_triangles"] + if (triangulate): + bm = bmesh.new() + bm.from_mesh(mesh) + bmesh.ops.triangulate(bm, faces=bm.faces) + bm.to_mesh(mesh) + bm.free() + + mesh.update(calc_tessface=True) + vertices=[] + vertex_map={} + surface_indices={} + materials={} + + materials={} + + si=None + if (armature!=None): + si=self.skeleton_info[armature] + + has_uv=False + has_uv2=False + has_weights=armature!=None + has_tangents=self.config["use_tangent_arrays"] # could detect.. + has_colors=len(mesh.vertex_colors) + mat_assign=[] + + uv_layer_count=len(mesh.uv_textures) + if (has_tangents and len(mesh.uv_textures)): + try: + mesh.calc_tangents() + except: + self.operator.report({'WARNING'},'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.') + #uv_layer_count=0 + mesh.calc_normals_split() + has_tangents=False + + else: + mesh.calc_normals_split() + has_tangents=False + + for fi in range(len(mesh.polygons)): + f=mesh.polygons[fi] + + if (not (f.material_index in surface_indices)): + surface_indices[f.material_index]=[] + #print("Type: "+str(type(f.material_index))) + #print("IDX: "+str(f.material_index)+"/"+str(len(mesh.materials))) + + try: + #Bizarre blender behavior i don't understand, so catching exception + mat = mesh.materials[f.material_index] + except: + mat= None + + if (mat!=None): + materials[f.material_index]=self.export_material( mat,mesh.show_double_sided ) + else: + materials[f.material_index]=None #weird, has no material? + + indices = surface_indices[f.material_index] + vi=[] + #vertices always 3 + """ + if (len(f.vertices)==3): + vi.append(0) + vi.append(1) + vi.append(2) + elif (len(f.vertices)==4): + #todo, should use shortest path + vi.append(0) + vi.append(1) + vi.append(2) + vi.append(0) + vi.append(2) + vi.append(3) + """ + + for lt in range(f.loop_total): + loop_index = f.loop_start + lt + ml = mesh.loops[loop_index] + mv = mesh.vertices[ml.vertex_index] + + v = self.Vertex() + v.vertex = Vector( mv.co ) + + for xt in mesh.uv_layers: + v.uv.append( Vector( xt.data[loop_index].uv ) ) + + if (has_colors): + v.color = Vector( mesh.vertex_colors[0].data[loop_index].color ) + + v.normal = Vector( ml.normal ) + + if (has_tangents): + v.tangent = Vector( ml.tangent ) + v.bitangent = Vector( ml.bitangent ) + + # if (armature): + # v.vertex = node.matrix_world * v.vertex + + #v.color=Vertex(mv. ??? + + if (armature!=None): + wsum=0.0 + zero_bones=[] + + for vg in mv.groups: + if vg.group >= len(node.vertex_groups): + continue; + name = node.vertex_groups[vg.group].name + + if (name in si["bone_index"]): + #could still put the weight as 0.0001 maybe + if (vg.weight>0.001): #blender has a lot of zero weight stuff + v.bones.append(si["bone_index"][name]) + v.weights.append(vg.weight) + wsum+=vg.weight + if (wsum==0.0): + if not self.wrongvtx_report: + self.operator.report({'WARNING'},'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.') + self.wrongvtx_report=True + + #blender can have bones assigned that weight zero so they remain local + #this is the best it can be done? + v.bones.append(0) + v.weights.append(1) + + tup = v.get_tup() + idx = 0 + if (skeyindex==-1 and tup in vertex_map): #do not optmize if using shapekeys + idx = vertex_map[tup] + else: + idx = len(vertices) + vertices.append(v) + vertex_map[tup]=idx + + vi.append(idx) + + if (len(vi)>2): + #only triangles and above + indices.append(vi) + + meshid = self.new_id("mesh") + self.writel(S_GEOM,1,'') + + self.writel(S_GEOM,2,'') + + # Vertex Array + self.writel(S_GEOM,3,'') + float_values="" + for v in vertices: + float_values+=" "+str(v.vertex.x)+" "+str(v.vertex.y)+" "+str(v.vertex.z) + self.writel(S_GEOM,4,''+float_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + # Normal Array + + self.writel(S_GEOM,3,'') + float_values="" + for v in vertices: + float_values+=" "+str(v.normal.x)+" "+str(v.normal.y)+" "+str(v.normal.z) + self.writel(S_GEOM,4,''+float_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + if (has_tangents): + self.writel(S_GEOM,3,'') + float_values="" + for v in vertices: + float_values+=" "+str(v.tangent.x)+" "+str(v.tangent.y)+" "+str(v.tangent.z) + self.writel(S_GEOM,4,''+float_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,3,'') + float_values="" + for v in vertices: + float_values+=" "+str(v.bitangent.x)+" "+str(v.bitangent.y)+" "+str(v.bitangent.z) + self.writel(S_GEOM,4,''+float_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + # UV Arrays + for uvi in range(uv_layer_count): + + self.writel(S_GEOM,3,'') + float_values="" + for v in vertices: + try: + float_values+=" "+str(v.uv[uvi].x)+" "+str(v.uv[uvi].y) + except: + # I don't understand this weird multi-uv-layer API, but with this it seems to works + float_values+=" 0 0 " + + self.writel(S_GEOM,4,''+float_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + # Color Arrays + + if (has_colors): + self.writel(S_GEOM,3,'') + float_values="" + for v in vertices: + float_values+=" "+str(v.color.x)+" "+str(v.color.y)+" "+str(v.color.z) + self.writel(S_GEOM,4,''+float_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + # Triangle Lists + self.writel(S_GEOM,3,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + prim_type="" + if (triangulate): + prim_type="triangles" + else: + prim_type="polygons" + + for m in surface_indices: + indices = surface_indices[m] + mat = materials[m] + + if (mat!=None): + matref = self.new_id("trimat") + self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'" material="'+matref+'">') # todo material + mat_assign.append( (mat,matref) ) + else: + self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'">') # todo material + + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + + for uvi in range(uv_layer_count): + self.writel(S_GEOM,4,'') + + if (has_colors): + self.writel(S_GEOM,4,'') + if (has_tangents): + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + + if (triangulate): + int_values="

" + for p in indices: + for i in p: + int_values+=" "+str(i) + int_values+="

" + self.writel(S_GEOM,4,int_values) + else: + for p in indices: + int_values="

" + for i in p: + int_values+=" "+str(i) + int_values+="

" + self.writel(S_GEOM,4,int_values) + + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,2,'
') + self.writel(S_GEOM,1,'
') + + meshdata={} + meshdata["id"]=meshid + meshdata["material_assign"]=mat_assign + if (skeyindex==-1): + self.mesh_cache[node.data]=meshdata + + # Export armature data (if armature exists) + if (armature!=None and (skel_source!=None or skeyindex==-1)): + + contid = self.new_id("controller") + + self.writel(S_SKIN,1,'') + if (skel_source!=None): + self.writel(S_SKIN,2,'') + else: + self.writel(S_SKIN,2,'') + + self.writel(S_SKIN,3,''+strmtx(node.matrix_world)+'') + #Joint Names + self.writel(S_SKIN,3,'') + name_values="" + for v in si["bone_names"]: + name_values+=" "+v + + self.writel(S_SKIN,4,''+name_values+'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,5,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,3,'') + #Pose Matrices! + self.writel(S_SKIN,3,'') + pose_values="" + for v in si["bone_bind_poses"]: + pose_values+=" "+strmtx(v) + + self.writel(S_SKIN,4,''+pose_values+'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,5,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,3,'') + #Skin Weights! + self.writel(S_SKIN,3,'') + skin_weights="" + skin_weights_total=0 + for v in vertices: + skin_weights_total+=len(v.weights) + for w in v.weights: + skin_weights+=" "+str(w) + + self.writel(S_SKIN,4,''+skin_weights+'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,5,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,3,'') + + self.writel(S_SKIN,3,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,3,'') + self.writel(S_SKIN,3,'') + self.writel(S_SKIN,4,'') + self.writel(S_SKIN,4,'') + vcounts="" + vs="" + vcount=0 + for v in vertices: + vcounts+=" "+str(len(v.weights)) + for b in v.bones: + vs+=" "+str(b) + vs+=" "+str(vcount) + vcount+=1 + self.writel(S_SKIN,4,''+vcounts+'') + self.writel(S_SKIN,4,''+vs+'') + self.writel(S_SKIN,3,'') + + self.writel(S_SKIN,2,'') + self.writel(S_SKIN,1,'') + meshdata["skin_id"]=contid + + return meshdata + + def export_mesh_node(self,node,il): + if (node.data==None): + return + + armature=None + armcount=0 + for n in node.modifiers: + if (n.type=="ARMATURE"): + armcount+=1 + + if (node.parent!=None): + if (node.parent.type=="ARMATURE"): + armature=node.parent + if (armcount>1): + self.operator.report({'WARNING'},'Object "'+node.name+'" refers to more than one armature! This is unsupported.') + if (armcount==0): + self.operator.report({'WARNING'},'Object "'+node.name+'" is child of an armature, but has no armature modifier.') + + if (armcount>0 and not armature): + self.operator.report({'WARNING'},'Object "'+node.name+'" has armature modifier, but is not a child of an armature. This is unsupported.') + + if (node.data.shape_keys!=None): + sk = node.data.shape_keys + if (sk.animation_data): + #print("HAS ANIM") + #print("DRIVERS: "+str(len(sk.animation_data.drivers))) + for d in sk.animation_data.drivers: + if (d.driver): + for v in d.driver.variables: + for t in v.targets: + if (t.id!=None and t.id.name in self.scene.objects): + #print("LINKING "+str(node)+" WITH "+str(t.id.name)) + self.armature_for_morph[node]=self.scene.objects[t.id.name] + + meshdata = self.export_mesh(node,armature) + close_controller=False + + if ("skin_id" in meshdata): + close_controller=True + self.writel(S_NODES,il,'') + for sn in self.skeleton_info[armature]["skeleton_nodes"]: + self.writel(S_NODES,il+1,'#'+sn+'') + elif ("morph_id" in meshdata): + self.writel(S_NODES,il,'') + close_controller=True + elif (armature==None): + self.writel(S_NODES,il,'') + + if (len(meshdata["material_assign"])>0): + + self.writel(S_NODES,il+1,'') + self.writel(S_NODES,il+2,'') + for m in meshdata["material_assign"]: + self.writel(S_NODES,il+3,'') + + self.writel(S_NODES,il+2,'') + self.writel(S_NODES,il+1,'') + + if (close_controller): + self.writel(S_NODES,il,'') + else: + self.writel(S_NODES,il,'') + + def export_armature_bone(self,bone,il,si): + boneid = self.new_id("bone") + boneidx = si["bone_count"] + si["bone_count"]+=1 + bonesid = si["id"]+"-"+str(boneidx) + if (bone.name in self.used_bones): + if (self.config["use_anim_action_all"]): + self.operator.report({'WARNING'},'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.') + else: + self.used_bones.append(bone.name) + + si["bone_index"][bone.name]=boneidx + si["bone_ids"][bone]=boneid + si["bone_names"].append(bonesid) + self.writel(S_NODES,il,'') + il+=1 + xform = bone.matrix_local + si["bone_bind_poses"].append((si["armature_xform"] * xform).inverted()) + + if (bone.parent!=None): + xform = bone.parent.matrix_local.inverted() * xform + else: + si["skeleton_nodes"].append(boneid) + + self.writel(S_NODES,il,''+strmtx(xform)+'') + for c in bone.children: + self.export_armature_bone(c,il,si) + il-=1 + self.writel(S_NODES,il,'') + + def export_armature_node(self,node,il): + if (node.data==None): + return + + self.skeletons.append(node) + + armature = node.data + self.skeleton_info[node]={ "bone_count":0, "id":self.new_id("skelbones"),"name":node.name, "bone_index":{},"bone_ids":{},"bone_names":[],"bone_bind_poses":[],"skeleton_nodes":[],"armature_xform":node.matrix_world } + + for b in armature.bones: + if (b.parent!=None): + continue + self.export_armature_bone(b,il,self.skeleton_info[node]) + + if (node.pose): + for b in node.pose.bones: + for x in b.constraints: + if (x.type=='ACTION'): + self.action_constraints.append(x.action) + + def export_camera_node(self,node,il): + if (node.data==None): + return + + camera=node.data + camid=self.new_id("camera") + self.writel(S_CAMS,1,'') + self.writel(S_CAMS,2,'') + self.writel(S_CAMS,3,'') + if (camera.type=="PERSP"): + self.writel(S_CAMS,4,'') + self.writel(S_CAMS,5,' '+str(math.degrees(camera.angle))+' ') # I think? + self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') + self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') + self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') + self.writel(S_CAMS,4,'') + else: + self.writel(S_CAMS,4,'') + self.writel(S_CAMS,5,' '+str(camera.ortho_scale*0.5)+' ') # I think? + self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') + self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') + self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') + self.writel(S_CAMS,4,'') + + self.writel(S_CAMS,3,'') + self.writel(S_CAMS,2,'') + self.writel(S_CAMS,1,'') + + self.writel(S_NODES,il,'') + + def export_lamp_node(self,node,il): + if (node.data==None): + return + + light=node.data + lightid=self.new_id("light") + self.writel(S_LAMPS,1,'') + #self.writel(S_LAMPS,2,'') + self.writel(S_LAMPS,3,'') + + if (light.type=="POINT"): + self.writel(S_LAMPS,4,'') + self.writel(S_LAMPS,5,''+strarr(light.color)+'') + att_by_distance = 2.0 / light.distance # convert to linear attenuation + self.writel(S_LAMPS,5,''+str(att_by_distance)+'') + if (light.use_sphere): + self.writel(S_LAMPS,5,''+str(light.distance)+'') + + self.writel(S_LAMPS,4,'') + elif (light.type=="SPOT"): + self.writel(S_LAMPS,4,'') + self.writel(S_LAMPS,5,''+strarr(light.color)+'') + att_by_distance = 2.0 / light.distance # convert to linear attenuation + self.writel(S_LAMPS,5,''+str(att_by_distance)+'') + self.writel(S_LAMPS,5,''+str(math.degrees(light.spot_size/2))+'') + self.writel(S_LAMPS,4,'') + + else: #write a sun lamp for everything else (not supported) + self.writel(S_LAMPS,4,'') + self.writel(S_LAMPS,5,''+strarr(light.color)+'') + self.writel(S_LAMPS,4,'') + + self.writel(S_LAMPS,3,'') + #self.writel(S_LAMPS,2,'') + self.writel(S_LAMPS,1,'') + + self.writel(S_NODES,il,'') + + def export_empty_node(self,node,il): + self.writel(S_NODES,4,'') + self.writel(S_NODES,5,'') + self.writel(S_NODES,6,''+node.empty_draw_type+'') + self.writel(S_NODES,5,'') + self.writel(S_NODES,4,'') + + def export_curve(self,curve): + splineid = self.new_id("spline") + + self.writel(S_GEOM,1,'') + self.writel(S_GEOM,2,'') + + points=[] + interps=[] + handles_in=[] + handles_out=[] + tilts=[] + + for cs in curve.splines: + + if (cs.type=="BEZIER"): + for s in cs.bezier_points: + points.append(s.co[0]) + points.append(s.co[1]) + points.append(s.co[2]) + + handles_in.append(s.handle_left[0]) + handles_in.append(s.handle_left[1]) + handles_in.append(s.handle_left[2]) + + handles_out.append(s.handle_right[0]) + handles_out.append(s.handle_right[1]) + handles_out.append(s.handle_right[2]) + + tilts.append(s.tilt) + interps.append("BEZIER") + else: + + for s in cs.points: + points.append(s.co[0]) + points.append(s.co[1]) + points.append(s.co[2]) + handles_in.append(s.co[0]) + handles_in.append(s.co[1]) + handles_in.append(s.co[2]) + handles_out.append(s.co[0]) + handles_out.append(s.co[1]) + handles_out.append(s.co[2]) + tilts.append(s.tilt) + interps.append("LINEAR") + + self.writel(S_GEOM,3,'') + position_values="" + for x in points: + position_values+=" "+str(x) + self.writel(S_GEOM,4,''+position_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,3,'') + intangent_values="" + for x in handles_in: + intangent_values+=" "+str(x) + self.writel(S_GEOM,4,''+intangent_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,3,'') + outtangent_values="" + for x in handles_out: + outtangent_values+=" "+str(x) + self.writel(S_GEOM,4,''+outtangent_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,3,'') + interpolation_values="" + for x in interps: + interpolation_values+=" "+x + self.writel(S_GEOM,4,''+interpolation_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,3,'') + tilt_values="" + for x in tilts: + tilt_values+=" "+str(x) + self.writel(S_GEOM,4,''+tilt_values+'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,5,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,3,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,4,'') + self.writel(S_GEOM,3,'') + + self.writel(S_GEOM,2,'') + self.writel(S_GEOM,1,'') + + return splineid + + def export_curve_node(self,node,il): + if (node.data==None): + return + + curveid = self.export_curve(node.data) + + self.writel(S_NODES,il,'') + self.writel(S_NODES,il,'') + + def export_node(self,node,il): + if (not node in self.valid_nodes): + return + + prev_node = bpy.context.scene.objects.active + bpy.context.scene.objects.active = node + + self.writel(S_NODES,il,'') + il+=1 + + self.writel(S_NODES,il,''+strmtx(node.matrix_local)+'') + #print("NODE TYPE: "+node.type+" NAME: "+node.name) + if (node.type=="MESH"): + self.export_mesh_node(node,il) + elif (node.type=="CURVE"): + self.export_curve_node(node,il) + elif (node.type=="ARMATURE"): + self.export_armature_node(node,il) + elif (node.type=="CAMERA"): + self.export_camera_node(node,il) + elif (node.type=="LAMP"): + self.export_lamp_node(node,il) + elif (node.type=="EMPTY"): + self.export_empty_node(node,il) + + for x in node.children: + self.export_node(x,il) + + il-=1 + self.writel(S_NODES,il,'') + bpy.context.scene.objects.active = prev_node #make previous node active again + + def is_node_valid(self,node): + if (not node.type in self.config["object_types"]): + return False + + if (self.config["use_active_layers"]): + valid=False + # print("NAME: "+node.name) + for i in range(20): + if (node.layers[i] and self.scene.layers[i]): + valid=True + break + if (not valid): + return False + + if (self.config["use_export_selected"] and not node.select): + return False + + return True + + def export_scene(self): + self.writel(S_NODES,0,'') + self.writel(S_NODES,1,'') + + # validate nodes + for obj in self.scene.objects: + if (obj in self.valid_nodes): + continue + if (self.is_node_valid(obj)): + n = obj + while (n!=None): + if (not n in self.valid_nodes): + self.valid_nodes.append(n) + n=n.parent + + for obj in self.scene.objects: + if (obj in self.valid_nodes and obj.parent==None): + self.export_node(obj,2) + + self.writel(S_NODES,1,'') + self.writel(S_NODES,0,'') + + def export_asset(self): + self.writel(S_ASSET,0,'') + # Why is this time stuff mandatory?, no one could care less... + self.writel(S_ASSET,1,'') + self.writel(S_ASSET,2,' Anonymous ') #Who made Collada, the FBI ? + self.writel(S_ASSET,2,' Collada Exporter for Blender 2.6+, by Juan Linietsky (juan@codenix.com) ') #Who made Collada, the FBI ? + self.writel(S_ASSET,1,'') + self.writel(S_ASSET,1,''+time.strftime("%Y-%m-%dT%H:%M:%SZ ")+'') + self.writel(S_ASSET,1,''+time.strftime("%Y-%m-%dT%H:%M:%SZ")+'') + self.writel(S_ASSET,1,'') + self.writel(S_ASSET,1,'Z_UP') + self.writel(S_ASSET,0,'') + + def export_animation_transform_channel(self,target,keys,matrices=True): + frame_total=len(keys) + anim_id=self.new_id("anim") + self.writel(S_ANIM,1,'') + source_frames = "" + source_transforms = "" + source_interps = "" + + for k in keys: + source_frames += " "+str(k[0]) + if (matrices): + source_transforms += " "+strmtx(k[1]) + else: + source_transforms += " "+str(k[1]) + + source_interps +=" LINEAR" + + # Time Source + self.writel(S_ANIM,2,'') + self.writel(S_ANIM,3,''+source_frames+'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,5,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,2,'') + + if (matrices): + # Transform Source + self.writel(S_ANIM,2,'') + self.writel(S_ANIM,3,''+source_transforms+'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,5,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,2,'') + else: + # Value Source + self.writel(S_ANIM,2,'') + self.writel(S_ANIM,3,''+source_transforms+'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,5,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,2,'') + + # Interpolation Source + self.writel(S_ANIM,2,'') + self.writel(S_ANIM,3,''+source_interps+'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,5,'') + self.writel(S_ANIM,4,'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,2,'') + + self.writel(S_ANIM,2,'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,3,'') + self.writel(S_ANIM,2,'') + if (matrices): + self.writel(S_ANIM,2,'') + else: + self.writel(S_ANIM,2,'') + self.writel(S_ANIM,1,'') + + return [anim_id] + + def export_animation(self,start,end,allowed=None): + # Blender -> Collada frames needs a little work + # Collada starts from 0, blender usually from 1 + # The last frame must be included also + + frame_orig = self.scene.frame_current + + frame_len = 1.0 / self.scene.render.fps + frame_total = end - start + 1 + frame_sub = 0 + if (start>0): + frame_sub=start*frame_len + + tcn = [] + xform_cache={} + blend_cache={} + # Change frames first, export objects last + # This improves performance enormously + + #print("anim from: "+str(start)+" to "+str(end)+" allowed: "+str(allowed)) + for t in range(start,end+1): + self.scene.frame_set(t) + key = t * frame_len - frame_sub +# print("Export Anim Frame "+str(t)+"/"+str(self.scene.frame_end+1)) + + for node in self.scene.objects: + + if (not node in self.valid_nodes): + continue + if (allowed!=None and not (node in allowed)): + if (node.type=="MESH" and node.data!=None and (node in self.armature_for_morph) and (self.armature_for_morph[node] in allowed)): + pass #all good you pass with flying colors for morphs inside of action + else: + #print("fail "+str((node in self.armature_for_morph))) + continue + if (node.type=="MESH" and node.data!=None and node.data.shape_keys!=None and (node.data in self.mesh_cache) and len(node.data.shape_keys.key_blocks)): + target = self.mesh_cache[node.data]["morph_id"] + for i in range(len(node.data.shape_keys.key_blocks)): + + if (i==0): + continue + + name=target+"-morph-weights("+str(i-1)+")" + if (not (name in blend_cache)): + blend_cache[name]=[] + + blend_cache[name].append( (key,node.data.shape_keys.key_blocks[i].value) ) + + if (node.type=="MESH" and node.parent and node.parent.type=="ARMATURE"): + + continue #In Collada, nodes that have skin modifier must not export animation, animate the skin instead. + + if (len(node.constraints)>0 or node.animation_data!=None): + #If the node has constraints, or animation data, then export a sampled animation track + name=self.validate_id(node.name) + if (not (name in xform_cache)): + xform_cache[name]=[] + + mtx = node.matrix_world.copy() + if (node.parent): + mtx = node.parent.matrix_world.inverted() * mtx + + xform_cache[name].append( (key,mtx) ) + + if (node.type=="ARMATURE"): + #All bones exported for now + + for bone in node.data.bones: + + bone_name=self.skeleton_info[node]["bone_ids"][bone] + + if (not (bone_name in xform_cache)): + #print("has bone: "+bone_name) + xform_cache[bone_name]=[] + + posebone = node.pose.bones[bone.name] + parent_posebone=None + + mtx = posebone.matrix.copy() + if (bone.parent): + parent_posebone=node.pose.bones[bone.parent.name] + parent_invisible=False + + for i in range(3): + if (parent_posebone.scale[i]==0.0): + parent_invisible=True + + if (not parent_invisible): + mtx = parent_posebone.matrix.inverted() * mtx + + xform_cache[bone_name].append( (key,mtx) ) + + self.scene.frame_set(frame_orig) + + #export animation xml + for nid in xform_cache: + tcn+=self.export_animation_transform_channel(nid,xform_cache[nid],True) + for nid in blend_cache: + tcn+=self.export_animation_transform_channel(nid,blend_cache[nid],False) + + return tcn + + def export_animations(self): + tmp_mat = [] + for s in self.skeletons: + tmp_bone_mat = [] + for bone in s.pose.bones: + tmp_bone_mat.append(Matrix(bone.matrix_basis)) + bone.matrix_basis = Matrix() + tmp_mat.append([Matrix(s.matrix_local),tmp_bone_mat]) + + self.writel(S_ANIM,0,'') + + if (self.config["use_anim_action_all"] and len(self.skeletons)): + cached_actions = {} + + for s in self.skeletons: + if s.animation_data and s.animation_data.action: + cached_actions[s] = s.animation_data.action.name + + self.writel(S_ANIM_CLIPS,0,'') + + for x in bpy.data.actions[:]: + if x.users==0 or x in self.action_constraints: + continue + if (self.config["use_anim_skip_noexp"] and x.name.endswith("-noexp")): + continue + + bones=[] + #find bones used + for p in x.fcurves: + dp = str(p.data_path) + base = "pose.bones[\"" + if (dp.find(base)==0): + dp=dp[len(base):] + if (dp.find('"')!=-1): + dp=dp[:dp.find('"')] + if (not dp in bones): + bones.append(dp) + + allowed_skeletons=[] + for i,y in enumerate(self.skeletons): + if (y.animation_data): + for z in y.pose.bones: + if (z.bone.name in bones): + if (not y in allowed_skeletons): + allowed_skeletons.append(y) + y.animation_data.action=x; + + y.matrix_local = tmp_mat[i][0] + for j,bone in enumerate(s.pose.bones): + bone.matrix_basis = Matrix() + + # print("allowed skeletons "+str(allowed_skeletons)) + + # print(str(x)) + + tcn = self.export_animation(int(x.frame_range[0]),int(x.frame_range[1]+0.5),allowed_skeletons) + framelen=(1.0/self.scene.render.fps) + start = x.frame_range[0]*framelen + end = x.frame_range[1]*framelen + #print("Export anim: "+x.name) + self.writel(S_ANIM_CLIPS,1,'') + for z in tcn: + self.writel(S_ANIM_CLIPS,2,'') + self.writel(S_ANIM_CLIPS,1,'') + if (len(tcn)==0): + self.operator.report({'WARNING'},'Animation clip "'+x.name+'" contains no tracks.') + + self.writel(S_ANIM_CLIPS,0,'') + + for i,s in enumerate(self.skeletons): + if (s.animation_data==None): + continue + if s in cached_actions: + s.animation_data.action = bpy.data.actions[cached_actions[s]] + else: + s.animation_data.action = None + for j,bone in enumerate(s.pose.bones): + bone.matrix_basis = tmp_mat[i][1][j] + + else: + self.export_animation(self.scene.frame_start,self.scene.frame_end) + + self.writel(S_ANIM,0,'') + + def export(self): + self.writel(S_GEOM,0,'') + self.writel(S_CONT,0,'') + self.writel(S_CAMS,0,'') + self.writel(S_LAMPS,0,'') + self.writel(S_IMGS,0,'') + self.writel(S_MATS,0,'') + self.writel(S_FX,0,'') + + self.skeletons=[] + self.action_constraints=[] + self.export_asset() + self.export_scene() + + self.writel(S_GEOM,0,'') + + #morphs always go before skin controllers + if S_MORPH in self.sections: + for l in self.sections[S_MORPH]: + self.writel(S_CONT,0,l) + del self.sections[S_MORPH] + + #morphs always go before skin controllers + if S_SKIN in self.sections: + for l in self.sections[S_SKIN]: + self.writel(S_CONT,0,l) + del self.sections[S_SKIN] + + self.writel(S_CONT,0,'') + self.writel(S_CAMS,0,'') + self.writel(S_LAMPS,0,'') + self.writel(S_IMGS,0,'') + self.writel(S_MATS,0,'') + self.writel(S_FX,0,'') + + if (self.config["use_anim"]): + self.export_animations() + + try: + f = open(self.path,"wb") + except: + return False + + f.write(bytes('\n',"UTF-8")) + f.write(bytes('\n',"UTF-8")) + + s=[] + for x in self.sections.keys(): + s.append(x) + s.sort() + for x in s: + for l in self.sections[x]: + f.write(bytes(l+"\n","UTF-8")) + + f.write(bytes('\n',"UTF-8")) + f.write(bytes('\t\n',"UTF-8")) + f.write(bytes('\n',"UTF-8")) + f.write(bytes('\n',"UTF-8")) + return True + + def __init__(self,path,kwargs,operator): + self.operator=operator + self.scene=bpy.context.scene + self.last_id=0 + self.scene_name=self.new_id("scene") + self.sections={} + self.path=path + self.mesh_cache={} + self.curve_cache={} + self.material_cache={} + self.image_cache={} + self.skeleton_info={} + self.config=kwargs + self.valid_nodes=[] + self.armature_for_morph={} + self.used_bones=[] + self.wrongvtx_report=False def save(operator, context, - filepath="", - use_selection=False, - **kwargs - ): - - exp = DaeExporter(filepath,kwargs,operator) - exp.export() - - - - return {'FINISHED'} # so the script wont run after we have batch exported. + filepath="", + use_selection=False, + **kwargs + ): + exp = DaeExporter(filepath,kwargs,operator) + exp.export() + return {'FINISHED'} # so the script wont run after we have batch exported. -- cgit v1.2.3 From 52fdc65a5df71af98af5f54ccb2db972084bbec1 Mon Sep 17 00:00:00 2001 From: Nobody Really Date: Sat, 9 Jul 2016 12:10:36 +0200 Subject: Comma fix --- tools/export/blender25/godot_export_manager.py | 146 +-- tools/export/blender25/io_scene_dae/__init__.py | 2 +- tools/export/blender25/io_scene_dae/export_dae.py | 1002 ++++++++++----------- 3 files changed, 575 insertions(+), 575 deletions(-) diff --git a/tools/export/blender25/godot_export_manager.py b/tools/export/blender25/godot_export_manager.py index 504fdb7934..293e0173e9 100644 --- a/tools/export/blender25/godot_export_manager.py +++ b/tools/export/blender25/godot_export_manager.py @@ -55,13 +55,13 @@ class godot_export_manager(bpy.types.Panel): row = layout.row() col = row.column() - col.prop(scene,"godot_export_on_save",text="Export Groups on save") + col.prop(scene, "godot_export_on_save", text="Export Groups on save") row = layout.row() col = row.column(align=True) - op = col.operator("scene.godot_add_objects_to_group",text="Add selected objects to Group",icon="COPYDOWN") + op = col.operator("scene.godot_add_objects_to_group", text="Add selected objects to Group", icon="COPYDOWN") - op = col.operator("scene.godot_delete_objects_from_group",text="Delete selected objects from Group",icon="PASTEDOWN") + op = col.operator("scene.godot_delete_objects_from_group", text="Delete selected objects from Group", icon="PASTEDOWN") row = layout.row() col = row.column() @@ -70,20 +70,20 @@ class godot_export_manager(bpy.types.Panel): row = layout.row() col = row.column() - col.template_list("UI_List_Godot","dummy",scene, "godot_export_groups", scene, "godot_export_groups_index",rows=1,maxrows=10,type='DEFAULT') + col.template_list("UI_List_Godot", "dummy", scene, "godot_export_groups", scene, "godot_export_groups_index", rows=1, maxrows=10, type='DEFAULT') col = row.column(align=True) - col.operator("scene.godot_add_export_group",text="",icon="ZOOMIN") - col.operator("scene.godot_delete_export_group",text="",icon="ZOOMOUT") - col.operator("scene.godot_export_all_groups",text="",icon="EXPORT") + col.operator("scene.godot_add_export_group", text="", icon="ZOOMIN") + col.operator("scene.godot_delete_export_group", text="", icon="ZOOMOUT") + col.operator("scene.godot_export_all_groups", text="", icon="EXPORT") if len(scene.godot_export_groups) > 0: row = layout.row() col = row.column() group = scene.godot_export_groups[scene.godot_export_groups_index] - col.prop(group,"name",text="Group Name") - col.prop(group,"export_name",text="Export Name") - col.prop(group,"export_path",text="Export Filepath") + col.prop(group, "name", text="Group Name") + col.prop(group, "export_name", text="Export Name") + col.prop(group, "export_path", text="Export Filepath") row = layout.row() col = row.column() @@ -92,25 +92,25 @@ class godot_export_manager(bpy.types.Panel): col.label(text="Export Settings:") col = col.row(align=True) - col.prop(group,"apply_loc",toggle=True,icon="MAN_TRANS") - col.prop(group,"apply_rot",toggle=True,icon="MAN_ROT") - col.prop(group,"apply_scale",toggle=True,icon="MAN_SCALE") + col.prop(group, "apply_loc", toggle=True, icon="MAN_TRANS") + col.prop(group, "apply_rot", toggle=True, icon="MAN_ROT") + col.prop(group, "apply_scale", toggle=True, icon="MAN_SCALE") row = layout.row() col = row.column() - col.prop(group,"use_include_particle_duplicates") - col.prop(group,"use_mesh_modifiers") - col.prop(group,"use_tangent_arrays") - col.prop(group,"use_triangles") - col.prop(group,"use_copy_images") - col.prop(group,"use_active_layers") - col.prop(group,"use_anim") - col.prop(group,"use_anim_action_all") - col.prop(group,"use_anim_skip_noexp") - col.prop(group,"use_anim_optimize") - col.prop(group,"anim_optimize_precision") - col.prop(group,"use_metadata") + col.prop(group, "use_include_particle_duplicates") + col.prop(group, "use_mesh_modifiers") + col.prop(group, "use_tangent_arrays") + col.prop(group, "use_triangles") + col.prop(group, "use_copy_images") + col.prop(group, "use_active_layers") + col.prop(group, "use_anim") + col.prop(group, "use_anim_action_all") + col.prop(group, "use_anim_skip_noexp") + col.prop(group, "use_anim_optimize") + col.prop(group, "anim_optimize_precision") + col.prop(group, "use_metadata") ### Custom template_list look @@ -120,12 +120,12 @@ class UI_List_Godot(bpy.types.UIList): slot = item col = layout.row(align=True) - col.label(text=item.name,icon="GROUP") - col.prop(item,"active",text="") + col.label(text=item.name, icon="GROUP") + col.prop(item, "active", text="") - op = col.operator("scene.godot_select_group_objects",text="",emboss=False,icon="RESTRICT_SELECT_OFF") + op = col.operator("scene.godot_select_group_objects", text="", emboss=False, icon="RESTRICT_SELECT_OFF") op.idx = index - op = col.operator("scene.godot_export_group",text="",emboss=False,icon="EXPORT") + op = col.operator("scene.godot_export_group", text="", emboss=False, icon="EXPORT") op.idx = index class add_objects_to_group(bpy.types.Operator): @@ -135,12 +135,12 @@ class add_objects_to_group(bpy.types.Operator): undo = BoolProperty(default=True) - def execute(self,context): + def execute(self, context): scene = context.scene objects_str = "" if len(scene.godot_export_groups) > 0: - for i,object in enumerate(context.selected_objects): + for i, object in enumerate(context.selected_objects): if object.name not in scene.godot_export_groups[scene.godot_export_groups_index].nodes: node = scene.godot_export_groups[scene.godot_export_groups_index].nodes.add() node.name = object.name @@ -161,7 +161,7 @@ class del_objects_from_group(bpy.types.Operator): bl_label = "Delete Objects from Group" bl_description = "Delets the selected Objects from the active group below." - def execute(self,context): + def execute(self, context): scene = context.scene if len(scene.godot_export_groups) > 0: @@ -172,7 +172,7 @@ class del_objects_from_group(bpy.types.Operator): objects_str = "" j = 0 - for i,node in enumerate(scene.godot_export_groups[scene.godot_export_groups_index].nodes): + for i, node in enumerate(scene.godot_export_groups[scene.godot_export_groups_index].nodes): if node.name in selected_objects: scene.godot_export_groups[scene.godot_export_groups_index].nodes.remove(i) @@ -195,7 +195,7 @@ class select_group_objects(bpy.types.Operator): idx = IntProperty() - def execute(self,context): + def execute(self, context): scene = context.scene for object in context.scene.objects: object.select = False @@ -211,7 +211,7 @@ class export_groups_autosave(bpy.types.Operator): bl_label = "Export All Groups" bl_description = "Exports all groups to Collada." - def execute(self,context): + def execute(self, context): scene = context.scene if scene.godot_export_on_save: for i in range(len(scene.godot_export_groups)): @@ -227,11 +227,11 @@ class export_all_groups(bpy.types.Operator): bl_label = "Export All Groups" bl_description = "Exports all groups to Collada." - def execute(self,context): + def execute(self, context): scene = context.scene - for i in range(0,len(scene.godot_export_groups)): - bpy.ops.scene.godot_export_group(idx=i,export_all=True) + for i in range(0, len(scene.godot_export_groups)): + bpy.ops.scene.godot_export_group(idx=i, export_all=True) self.report({'INFO'}, "All Groups exported." ) return{'FINISHED'} @@ -245,7 +245,7 @@ class export_group(bpy.types.Operator): idx = IntProperty(default=0) export_all = BoolProperty(default=False) - def copy_object_recursive(self,ob,parent,single_user = True): + def copy_object_recursive(self, ob, parent, single_user = True): new_ob = bpy.data.objects[ob.name].copy() if single_user or ob.type=="ARMATURE": new_mesh_data = new_ob.data.copy() @@ -258,22 +258,22 @@ class export_group(bpy.types.Operator): new_ob.parent = None for child in ob.children: - self.copy_object_recursive(child,new_ob,single_user) + self.copy_object_recursive(child, new_ob, single_user) new_ob.select = True return new_ob - def delete_object(self,ob): + def delete_object(self, ob): if ob != None: for child in ob.children: self.delete_object(child) bpy.context.scene.objects.unlink(ob) bpy.data.objects.remove(ob) - def convert_group_to_node(self,group): + def convert_group_to_node(self, group): if group.dupli_group != None: for object in group.dupli_group.objects: if object.parent == None: - object = self.copy_object_recursive(object,object,True) + object = self.copy_object_recursive(object, object, True) matrix = Matrix(object.matrix_local) object.matrix_local = Matrix() object.matrix_local *= group.matrix_local @@ -281,7 +281,7 @@ class export_group(bpy.types.Operator): self.delete_object(group) - def execute(self,context): + def execute(self, context): scene = context.scene group = context.scene.godot_export_groups @@ -289,7 +289,7 @@ class export_group(bpy.types.Operator): if not group[self.idx].active and self.export_all: return{'FINISHED'} - for i,object in enumerate(group[self.idx].nodes): + for i, object in enumerate(group[self.idx].nodes): if object.name in bpy.data.objects: pass else: @@ -300,17 +300,17 @@ class export_group(bpy.types.Operator): if (path.find("//")==0 or path.find("\\\\")==0): #if relative, convert to absolute path = bpy.path.abspath(path) - path = path.replace("\\","/") + path = path.replace("\\", "/") ### if path exists and group export name is set the group will be exported if os.path.exists(path) and group[self.idx].export_name != "": - context.scene.layers = [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] + context.scene.layers = [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] if group[self.idx].export_name.endswith(".dae"): - path = os.path.join(path,group[self.idx].export_name) + path = os.path.join(path, group[self.idx].export_name) else: - path = os.path.join(path,group[self.idx].export_name+".dae") + path = os.path.join(path, group[self.idx].export_name+".dae") hide_select = [] for object in context.scene.objects: @@ -322,7 +322,7 @@ class export_group(bpy.types.Operator): ### make particle duplicates, parent and select them nodes_to_be_added = [] if group[self.idx].use_include_particle_duplicates: - for i,object in enumerate(group[self.idx].nodes): + for i, object in enumerate(group[self.idx].nodes): if bpy.data.objects[object.name].type != "EMPTY": context.scene.objects.active = bpy.data.objects[object.name] bpy.data.objects[object.name].select = True @@ -339,7 +339,7 @@ class export_group(bpy.types.Operator): object.select = True ### select all other nodes from the group - for i,object in enumerate(group[self.idx].nodes): + for i, object in enumerate(group[self.idx].nodes): if bpy.data.objects[object.name].type == "EMPTY": self.convert_group_to_node(bpy.data.objects[object.name]) else: @@ -365,7 +365,7 @@ class add_export_group(bpy.types.Operator): bl_label = "Adds a new export Group" bl_description = "Creates a new Export Group with the selected Objects assigned to it." - def execute(self,context): + def execute(self, context): scene = context.scene item = scene.godot_export_groups.add() @@ -385,9 +385,9 @@ class del_export_group(bpy.types.Operator): def invoke(self, context, event): wm = context.window_manager - return wm.invoke_confirm(self,event) + return wm.invoke_confirm(self, event) - def execute(self,context): + def execute(self, context): scene = context.scene scene.godot_export_groups.remove(scene.godot_export_groups_index) @@ -406,30 +406,30 @@ class godot_export_groups(bpy.types.PropertyGroup): export_name = StringProperty(name="scene_name") nodes = CollectionProperty(type=godot_node_list) export_path = StringProperty(subtype="DIR_PATH") - active = BoolProperty(default=True,description="Export Group") + active = BoolProperty(default=True, description="Export Group") - object_types = EnumProperty(name="Object Types",options={'ENUM_FLAG'},items=(('EMPTY', "Empty", ""),('CAMERA', "Camera", ""),('LAMP', "Lamp", ""),('ARMATURE', "Armature", ""),('MESH', "Mesh", ""),('CURVE', "Curve", ""),),default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH','CURVE'}) + object_types = EnumProperty(name="Object Types", options={'ENUM_FLAG'}, items=(('EMPTY', "Empty", ""), ('CAMERA', "Camera", ""), ('LAMP', "Lamp", ""), ('ARMATURE', "Armature", ""), ('MESH', "Mesh", ""), ('CURVE', "Curve", ""), ), default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH', 'CURVE'}) - apply_scale = BoolProperty(name="Apply Scale",description="Apply Scale before export.",default=False) - apply_rot = BoolProperty(name="Apply Rotation",description="Apply Rotation before export.",default=False) - apply_loc = BoolProperty(name="Apply Location",description="Apply Location before export.",default=False) + apply_scale = BoolProperty(name="Apply Scale", description="Apply Scale before export.", default=False) + apply_rot = BoolProperty(name="Apply Rotation", description="Apply Rotation before export.", default=False) + apply_loc = BoolProperty(name="Apply Location", description="Apply Location before export.", default=False) - use_export_selected = BoolProperty(name="Selected Objects",description="Export only selected objects (and visible in active layers if that applies).",default=True) - use_mesh_modifiers = BoolProperty(name="Apply Modifiers",description="Apply modifiers to mesh objects (on a copy!).",default=True) - use_tangent_arrays = BoolProperty(name="Tangent Arrays",description="Export Tangent and Binormal arrays (for normalmapping).",default=False) - use_triangles = BoolProperty(name="Triangulate",description="Export Triangles instead of Polygons.",default=False) + use_export_selected = BoolProperty(name="Selected Objects", description="Export only selected objects (and visible in active layers if that applies).", default=True) + use_mesh_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers to mesh objects (on a copy!).", default=True) + use_tangent_arrays = BoolProperty(name="Tangent Arrays", description="Export Tangent and Binormal arrays (for normalmapping).", default=False) + use_triangles = BoolProperty(name="Triangulate", description="Export Triangles instead of Polygons.", default=False) - use_copy_images = BoolProperty(name="Copy Images",description="Copy Images (create images/ subfolder)",default=False) - use_active_layers = BoolProperty(name="Active Layers",description="Export only objects on the active layers.",default=True) - use_anim = BoolProperty(name="Export Animation",description="Export keyframe animation",default=False) - use_anim_action_all = BoolProperty(name="All Actions",description=("Export all actions for the first armature found in separate DAE files"),default=False) - use_anim_skip_noexp = BoolProperty(name="Skip (-noexp) Actions",description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.",default=True) - use_anim_optimize = BoolProperty(name="Optimize Keyframes",description="Remove double keyframes",default=True) + use_copy_images = BoolProperty(name="Copy Images", description="Copy Images (create images/ subfolder)", default=False) + use_active_layers = BoolProperty(name="Active Layers", description="Export only objects on the active layers.", default=True) + use_anim = BoolProperty(name="Export Animation", description="Export keyframe animation", default=False) + use_anim_action_all = BoolProperty(name="All Actions", description=("Export all actions for the first armature found in separate DAE files"), default=False) + use_anim_skip_noexp = BoolProperty(name="Skip (-noexp) Actions", description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.", default=True) + use_anim_optimize = BoolProperty(name="Optimize Keyframes", description="Remove double keyframes", default=True) - anim_optimize_precision = FloatProperty(name="Precision",description=("Tolerence for comparing double keyframes (higher for greater accuracy)"),min=1, max=16,soft_min=1, soft_max=16,default=6.0) + anim_optimize_precision = FloatProperty(name="Precision", description=("Tolerence for comparing double keyframes (higher for greater accuracy)"), min=1, max=16, soft_min=1, soft_max=16, default=6.0) - use_metadata = BoolProperty(name="Use Metadata",default=True,options={'HIDDEN'}) - use_include_particle_duplicates = BoolProperty(name="Include Particle Duplicates",default=True) + use_metadata = BoolProperty(name="Use Metadata", default=True, options={'HIDDEN'}) + use_include_particle_duplicates = BoolProperty(name="Include Particle Duplicates", default=True) def register(): @@ -447,7 +447,7 @@ def register(): bpy.utils.register_class(UI_List_Godot) bpy.types.Scene.godot_export_groups = CollectionProperty(type=godot_export_groups) - bpy.types.Scene.godot_export_groups_index = IntProperty(default=0,min=0) + bpy.types.Scene.godot_export_groups_index = IntProperty(default=0, min=0) def unregister(): diff --git a/tools/export/blender25/io_scene_dae/__init__.py b/tools/export/blender25/io_scene_dae/__init__.py index 89c1f009c2..3bde01f2df 100644 --- a/tools/export/blender25/io_scene_dae/__init__.py +++ b/tools/export/blender25/io_scene_dae/__init__.py @@ -69,7 +69,7 @@ class ExportDAE(bpy.types.Operator, ExportHelper): ('MESH', "Mesh", ""), ('CURVE', "Curve", ""), ), - default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH','CURVE'}, + default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH', 'CURVE'}, ) use_export_selected = BoolProperty( diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 047c8a063d..0b90a60eb8 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -66,7 +66,7 @@ CMP_EPSILON=0.0001 def snap_tup(tup): ret=() for x in tup: - ret+=( x-math.fmod(x,0.0001), ) + ret+=( x-math.fmod(x, 0.0001), ) return tup @@ -80,7 +80,7 @@ def strmtx(mtx): s+=" " return s -def numarr(a,mult=1.0): +def numarr(a, mult=1.0): s=" " for x in a: s+=" "+str(x*mult) @@ -88,7 +88,7 @@ def numarr(a,mult=1.0): return s -def numarr_alpha(a,mult=1.0): +def numarr_alpha(a, mult=1.0): s=" " for x in a: s+=" "+str(x*mult) @@ -108,12 +108,12 @@ def strarr(arr): class DaeExporter: - def validate_id(self,d): + def validate_id(self, d): if (d.find("id-")==0): return "z"+d return d - def new_id(self,t): + def new_id(self, t): self.last_id+=1 return "id-"+t+"-"+str(self.last_id) @@ -132,34 +132,34 @@ class DaeExporter: return True def get_tup(self): - tup = (self.vertex.x,self.vertex.y,self.vertex.z,self.normal.x,self.normal.y,self.normal.z) + tup = (self.vertex.x, self.vertex.y, self.vertex.z, self.normal.x, self.normal.y, self.normal.z) for t in self.uv: - tup = tup + (t.x,t.y) + tup = tup + (t.x, t.y) if (self.color!=None): - tup = tup + (self.color.x,self.color.y,self.color.z) + tup = tup + (self.color.x, self.color.y, self.color.z) if (self.tangent!=None): - tup = tup + (self.tangent.x,self.tangent.y,self.tangent.z) + tup = tup + (self.tangent.x, self.tangent.y, self.tangent.z) if (self.bitangent!=None): - tup = tup + (self.bitangent.x,self.bitangent.y,self.bitangent.z) + tup = tup + (self.bitangent.x, self.bitangent.y, self.bitangent.z) for t in self.bones: - tup = tup + (float(t),) + tup = tup + (float(t), ) for t in self.weights: - tup = tup + (float(t),) + tup = tup + (float(t), ) return tup def __init__(self): - self.vertex = Vector( (0.0,0.0,0.0) ) - self.normal = Vector( (0.0,0.0,0.0) ) + self.vertex = Vector( (0.0, 0.0, 0.0) ) + self.normal = Vector( (0.0, 0.0, 0.0) ) self.tangent = None self.bitangent = None self.color = None self.uv = [] - self.uv2 = Vector( (0.0,0.0) ) + self.uv2 = Vector( (0.0, 0.0) ) self.bones=[] self.weights=[] - def writel(self,section,indent,text): + def writel(self, section, indent, text): if (not (section in self.sections)): self.sections[section]=[] line="" @@ -168,7 +168,7 @@ class DaeExporter: line+=text self.sections[section].append(line) - def export_image(self,image): + def export_image(self, image): if (image in self.image_cache): return self.image_cache[image] @@ -188,12 +188,12 @@ class DaeExporter: dstfile=basedir+"/"+os.path.basename(imgpath) if (not os.path.isfile(dstfile)): - shutil.copy(imgpath,dstfile) + shutil.copy(imgpath, dstfile) imgpath="images/"+os.path.basename(imgpath) else: ### if file is not found save it as png file in the destination folder img_tmp_path = image.filepath - if img_tmp_path.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): + if img_tmp_path.endswith((".bmp", ".rgb", ".png", ".jpeg", ".jpg", ".jp2", ".tga", ".cin", ".dpx", ".exr", ".hdr", ".tif")): image.filepath = basedir+"/"+os.path.basename(img_tmp_path) else: image.filepath = basedir+"/"+image.name+".png" @@ -209,7 +209,7 @@ class DaeExporter: else: #export relative, always, no one wants absolute paths. try: - imgpath = os.path.relpath(imgpath,os.path.dirname(self.path)).replace("\\","/") # export unix compatible always + imgpath = os.path.relpath(imgpath, os.path.dirname(self.path)).replace("\\", "/") # export unix compatible always except: pass #fails sometimes, not sure why @@ -220,24 +220,24 @@ class DaeExporter: # if (not os.path.isfile(imgpath)): # print("NOT FILE?") -# if imgpath.endswith((".bmp",".rgb",".png",".jpeg",".jpg",".jp2",".tga",".cin",".dpx",".exr",".hdr",".tif")): +# if imgpath.endswith((".bmp", ".rgb", ".png", ".jpeg", ".jpg", ".jp2", ".tga", ".cin", ".dpx", ".exr", ".hdr", ".tif")): # imgpath="images/"+os.path.basename(imgpath) # else: # imgpath="images/"+image.name+".png" - self.writel(S_IMGS,1,'') - self.writel(S_IMGS,2,''+imgpath+'') - self.writel(S_IMGS,1,'') + self.writel(S_IMGS, 1, '') + self.writel(S_IMGS, 2, ''+imgpath+'') + self.writel(S_IMGS, 1, '') self.image_cache[image]=imgid return imgid - def export_material(self,material,double_sided_hint=True): + def export_material(self, material, double_sided_hint=True): if (material in self.material_cache): return self.material_cache[material] fxid = self.new_id("fx") - self.writel(S_FX,1,'') - self.writel(S_FX,2,'') + self.writel(S_FX, 1, '') + self.writel(S_FX, 2, '') #Find and fetch the textures and create sources sampler_table={} @@ -264,19 +264,19 @@ class DaeExporter: #surface surface_sid = self.new_id("fx_surf") - self.writel(S_FX,3,'') - self.writel(S_FX,4,'') - self.writel(S_FX,5,''+imgid+'') #this is sooo weird - self.writel(S_FX,5,'A8R8G8B8') - self.writel(S_FX,4,'') - self.writel(S_FX,3,'') + self.writel(S_FX, 3, '') + self.writel(S_FX, 4, '') + self.writel(S_FX, 5, ''+imgid+'') #this is sooo weird + self.writel(S_FX, 5, 'A8R8G8B8') + self.writel(S_FX, 4, '') + self.writel(S_FX, 3, '') #sampler, collada sure likes it difficult sampler_sid = self.new_id("fx_sampler") - self.writel(S_FX,3,'') - self.writel(S_FX,4,'') - self.writel(S_FX,5,''+surface_sid+'') - self.writel(S_FX,4,'') - self.writel(S_FX,3,'') + self.writel(S_FX, 3, '') + self.writel(S_FX, 4, '') + self.writel(S_FX, 5, ''+surface_sid+'') + self.writel(S_FX, 4, '') + self.writel(S_FX, 3, '') sampler_table[i]=sampler_sid if (ts.use_map_color_diffuse and diffuse_tex==None): @@ -288,90 +288,90 @@ class DaeExporter: if (ts.use_map_normal and normal_tex==None): normal_tex=sampler_sid - self.writel(S_FX,3,'') + self.writel(S_FX, 3, '') shtype="blinn" - self.writel(S_FX,4,'<'+shtype+'>') + self.writel(S_FX, 4, '<'+shtype+'>') #ambient? from where? - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') if (emission_tex!=None): - self.writel(S_FX,6,'') + self.writel(S_FX, 6, '') else: - self.writel(S_FX,6,''+numarr_alpha(material.diffuse_color,material.emit)+' ') # not totally right but good enough - self.writel(S_FX,5,'') + self.writel(S_FX, 6, ''+numarr_alpha(material.diffuse_color, material.emit)+' ') # not totally right but good enough + self.writel(S_FX, 5, '') - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+numarr_alpha(self.scene.world.ambient_color,material.ambient)+' ') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') + self.writel(S_FX, 6, ''+numarr_alpha(self.scene.world.ambient_color, material.ambient)+' ') + self.writel(S_FX, 5, '') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') if (diffuse_tex!=None): - self.writel(S_FX,6,'') + self.writel(S_FX, 6, '') else: - self.writel(S_FX,6,''+numarr_alpha(material.diffuse_color,material.diffuse_intensity)+'') - self.writel(S_FX,5,'') + self.writel(S_FX, 6, ''+numarr_alpha(material.diffuse_color, material.diffuse_intensity)+'') + self.writel(S_FX, 5, '') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') if (specular_tex!=None): - self.writel(S_FX,6,'') + self.writel(S_FX, 6, '') else: - self.writel(S_FX,6,''+numarr_alpha(material.specular_color,material.specular_intensity)+'') - self.writel(S_FX,5,'') + self.writel(S_FX, 6, ''+numarr_alpha(material.specular_color, material.specular_intensity)+'') + self.writel(S_FX, 5, '') - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+str(material.specular_hardness)+'') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') + self.writel(S_FX, 6, ''+str(material.specular_hardness)+'') + self.writel(S_FX, 5, '') - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+numarr_alpha(material.mirror_color)+'') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') + self.writel(S_FX, 6, ''+numarr_alpha(material.mirror_color)+'') + self.writel(S_FX, 5, '') if (material.use_transparency): - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+str(material.alpha)+'') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') + self.writel(S_FX, 6, ''+str(material.alpha)+'') + self.writel(S_FX, 5, '') - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+str(material.specular_ior)+'') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') + self.writel(S_FX, 6, ''+str(material.specular_ior)+'') + self.writel(S_FX, 5, '') - self.writel(S_FX,4,'') + self.writel(S_FX, 4, '') - self.writel(S_FX,4,'') - self.writel(S_FX,5,'') + self.writel(S_FX, 4, '') + self.writel(S_FX, 5, '') if (normal_tex): - self.writel(S_FX,6,'') - self.writel(S_FX,7,'') - self.writel(S_FX,6,'') + self.writel(S_FX, 6, '') + self.writel(S_FX, 7, '') + self.writel(S_FX, 6, '') - self.writel(S_FX,5,'') - self.writel(S_FX,5,'') - self.writel(S_FX,6,''+["0","1"][double_sided_hint]+"") - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') + self.writel(S_FX, 5, '') + self.writel(S_FX, 6, ''+["0", "1"][double_sided_hint]+"") + self.writel(S_FX, 5, '') if (material.use_shadeless): - self.writel(S_FX,5,'') - self.writel(S_FX,6,'1') - self.writel(S_FX,5,'') + self.writel(S_FX, 5, '') + self.writel(S_FX, 6, '1') + self.writel(S_FX, 5, '') - self.writel(S_FX,4,'') + self.writel(S_FX, 4, '') - self.writel(S_FX,3,'') - self.writel(S_FX,2,'') - self.writel(S_FX,1,'') + self.writel(S_FX, 3, '') + self.writel(S_FX, 2, '') + self.writel(S_FX, 1, '') # Also export blender material in all it's glory (if set as active) # Material matid = self.new_id("material") - self.writel(S_MATS,1,'') - self.writel(S_MATS,2,'') - self.writel(S_MATS,1,'') + self.writel(S_MATS, 1, '') + self.writel(S_MATS, 2, '') + self.writel(S_MATS, 1, '') self.material_cache[material]=matid return matid - def export_mesh(self,node,armature=None,skeyindex=-1,skel_source=None,custom_name=None): + def export_mesh(self, node, armature=None, skeyindex=-1, skel_source=None, custom_name=None): mesh = node.data if (node.data in self.mesh_cache): @@ -381,14 +381,14 @@ class DaeExporter: values=[] morph_targets=[] md=None - for k in range(0,len(mesh.shape_keys.key_blocks)): + for k in range(0, len(mesh.shape_keys.key_blocks)): shape = node.data.shape_keys.key_blocks[k] values+=[shape.value] #save value shape.value=0 mid = self.new_id("morph") - for k in range(0,len(mesh.shape_keys.key_blocks)): + for k in range(0, len(mesh.shape_keys.key_blocks)): shape = node.data.shape_keys.key_blocks[k] node.show_only_shape_key=True @@ -403,12 +403,12 @@ class DaeExporter: p = node.data v = node.to_mesh(bpy.context.scene, True, "RENDER") node.data = v -# self.export_node(node,il,shape.name) +# self.export_node(node, il, shape.name) node.data.update() if (armature and k==0): - md=self.export_mesh(node,armature,k,mid,shape.name) + md=self.export_mesh(node, armature, k, mid, shape.name) else: - md=self.export_mesh(node,None,k,None,shape.name) + md=self.export_mesh(node, None, k, None, shape.name) node.data = p node.data.update() @@ -421,14 +421,14 @@ class DaeExporter: node.show_only_shape_key=False node.active_shape_key_index = 0 - self.writel(S_MORPH,1,'') + self.writel(S_MORPH, 1, '') #if ("skin_id" in morph_targets[0]): - # self.writel(S_MORPH,2,'') + # self.writel(S_MORPH, 2, '') #else: - self.writel(S_MORPH,2,'') + self.writel(S_MORPH, 2, '') - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,4,'') + self.writel(S_MORPH, 3, '') + self.writel(S_MORPH, 4, '') marr="" warr="" for i in range(len(morph_targets)): @@ -444,32 +444,32 @@ class DaeExporter: warr+=" 0" - self.writel(S_MORPH,5,marr) - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,6,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,3,'') - - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,5,warr) - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,6,'') - self.writel(S_MORPH,5,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,3,'') - - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,4,'') - self.writel(S_MORPH,3,'') - self.writel(S_MORPH,2,'') - self.writel(S_MORPH,1,'') + self.writel(S_MORPH, 5, marr) + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 5, '') + self.writel(S_MORPH, 6, '') + self.writel(S_MORPH, 5, '') + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 3, '') + + self.writel(S_MORPH, 3, '') + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 5, warr) + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 5, '') + self.writel(S_MORPH, 6, '') + self.writel(S_MORPH, 5, '') + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 3, '') + + self.writel(S_MORPH, 3, '') + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 3, '') + self.writel(S_MORPH, 2, '') + self.writel(S_MORPH, 1, '') if (armature!=None): self.armature_for_morph[node]=armature @@ -493,7 +493,7 @@ class DaeExporter: if (custom_name!=None and custom_name!=""): name_to_use=custom_name - mesh=node.to_mesh(self.scene,apply_modifiers,"RENDER") #is this allright? + mesh=node.to_mesh(self.scene, apply_modifiers, "RENDER") #is this allright? triangulate=self.config["use_triangles"] if (triangulate): @@ -527,7 +527,7 @@ class DaeExporter: try: mesh.calc_tangents() except: - self.operator.report({'WARNING'},'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.') + self.operator.report({'WARNING'}, 'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.') #uv_layer_count=0 mesh.calc_normals_split() has_tangents=False @@ -551,7 +551,7 @@ class DaeExporter: mat= None if (mat!=None): - materials[f.material_index]=self.export_material( mat,mesh.show_double_sided ) + materials[f.material_index]=self.export_material( mat, mesh.show_double_sided ) else: materials[f.material_index]=None #weird, has no material? @@ -615,7 +615,7 @@ class DaeExporter: wsum+=vg.weight if (wsum==0.0): if not self.wrongvtx_report: - self.operator.report({'WARNING'},'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.') + self.operator.report({'WARNING'}, 'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.') self.wrongvtx_report=True #blender can have bones assigned that weight zero so they remain local @@ -639,74 +639,74 @@ class DaeExporter: indices.append(vi) meshid = self.new_id("mesh") - self.writel(S_GEOM,1,'') + self.writel(S_GEOM, 1, '') - self.writel(S_GEOM,2,'') + self.writel(S_GEOM, 2, '') # Vertex Array - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') float_values="" for v in vertices: float_values+=" "+str(v.vertex.x)+" "+str(v.vertex.y)+" "+str(v.vertex.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+float_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') # Normal Array - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') float_values="" for v in vertices: float_values+=" "+str(v.normal.x)+" "+str(v.normal.y)+" "+str(v.normal.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+float_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') if (has_tangents): - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') float_values="" for v in vertices: float_values+=" "+str(v.tangent.x)+" "+str(v.tangent.y)+" "+str(v.tangent.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+float_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + + self.writel(S_GEOM, 3, '') float_values="" for v in vertices: float_values+=" "+str(v.bitangent.x)+" "+str(v.bitangent.y)+" "+str(v.bitangent.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+float_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') # UV Arrays for uvi in range(uv_layer_count): - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') float_values="" for v in vertices: try: @@ -715,36 +715,36 @@ class DaeExporter: # I don't understand this weird multi-uv-layer API, but with this it seems to works float_values+=" 0 0 " - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+float_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') # Color Arrays if (has_colors): - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') float_values="" for v in vertices: float_values+=" "+str(v.color.x)+" "+str(v.color.y)+" "+str(v.color.z) - self.writel(S_GEOM,4,''+float_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+float_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') # Triangle Lists - self.writel(S_GEOM,3,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') prim_type="" if (triangulate): @@ -758,22 +758,22 @@ class DaeExporter: if (mat!=None): matref = self.new_id("trimat") - self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'" material="'+matref+'">') # todo material - mat_assign.append( (mat,matref) ) + self.writel(S_GEOM, 3, '<'+prim_type+' count="'+str(int(len(indices)))+'" material="'+matref+'">') # todo material + mat_assign.append( (mat, matref) ) else: - self.writel(S_GEOM,3,'<'+prim_type+' count="'+str(int(len(indices)))+'">') # todo material + self.writel(S_GEOM, 3, '<'+prim_type+' count="'+str(int(len(indices)))+'">') # todo material - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') for uvi in range(uv_layer_count): - self.writel(S_GEOM,4,'') + self.writel(S_GEOM, 4, '') if (has_colors): - self.writel(S_GEOM,4,'') + self.writel(S_GEOM, 4, '') if (has_tangents): - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') if (triangulate): int_values="

" @@ -781,19 +781,19 @@ class DaeExporter: for i in p: int_values+=" "+str(i) int_values+="

" - self.writel(S_GEOM,4,int_values) + self.writel(S_GEOM, 4, int_values) else: for p in indices: int_values="

" for i in p: int_values+=" "+str(i) int_values+="

" - self.writel(S_GEOM,4,int_values) + self.writel(S_GEOM, 4, int_values) - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') - self.writel(S_GEOM,2,'
') - self.writel(S_GEOM,1,'
') + self.writel(S_GEOM, 2, '') + self.writel(S_GEOM, 1, '
') meshdata={} meshdata["id"]=meshid @@ -806,41 +806,41 @@ class DaeExporter: contid = self.new_id("controller") - self.writel(S_SKIN,1,'') + self.writel(S_SKIN, 1, '') if (skel_source!=None): - self.writel(S_SKIN,2,'') + self.writel(S_SKIN, 2, '') else: - self.writel(S_SKIN,2,'') + self.writel(S_SKIN, 2, '') - self.writel(S_SKIN,3,''+strmtx(node.matrix_world)+'') + self.writel(S_SKIN, 3, ''+strmtx(node.matrix_world)+'') #Joint Names - self.writel(S_SKIN,3,'') + self.writel(S_SKIN, 3, '') name_values="" for v in si["bone_names"]: name_values+=" "+v - self.writel(S_SKIN,4,''+name_values+'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,5,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') + self.writel(S_SKIN, 4, ''+name_values+'') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 5, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 3, '') #Pose Matrices! - self.writel(S_SKIN,3,'') + self.writel(S_SKIN, 3, '') pose_values="" for v in si["bone_bind_poses"]: pose_values+=" "+strmtx(v) - self.writel(S_SKIN,4,''+pose_values+'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,5,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') + self.writel(S_SKIN, 4, ''+pose_values+'') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 5, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 3, '') #Skin Weights! - self.writel(S_SKIN,3,'') + self.writel(S_SKIN, 3, '') skin_weights="" skin_weights_total=0 for v in vertices: @@ -848,21 +848,21 @@ class DaeExporter: for w in v.weights: skin_weights+=" "+str(w) - self.writel(S_SKIN,4,''+skin_weights+'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,5,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') - - self.writel(S_SKIN,3,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,3,'') - self.writel(S_SKIN,3,'') - self.writel(S_SKIN,4,'') - self.writel(S_SKIN,4,'') + self.writel(S_SKIN, 4, ''+skin_weights+'') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 5, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 3, '') + + self.writel(S_SKIN, 3, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 3, '') + self.writel(S_SKIN, 3, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') vcounts="" vs="" vcount=0 @@ -872,17 +872,17 @@ class DaeExporter: vs+=" "+str(b) vs+=" "+str(vcount) vcount+=1 - self.writel(S_SKIN,4,''+vcounts+'') - self.writel(S_SKIN,4,''+vs+'') - self.writel(S_SKIN,3,'') + self.writel(S_SKIN, 4, ''+vcounts+'') + self.writel(S_SKIN, 4, ''+vs+'') + self.writel(S_SKIN, 3, '') - self.writel(S_SKIN,2,'') - self.writel(S_SKIN,1,'') + self.writel(S_SKIN, 2, '') + self.writel(S_SKIN, 1, '') meshdata["skin_id"]=contid return meshdata - def export_mesh_node(self,node,il): + def export_mesh_node(self, node, il): if (node.data==None): return @@ -896,12 +896,12 @@ class DaeExporter: if (node.parent.type=="ARMATURE"): armature=node.parent if (armcount>1): - self.operator.report({'WARNING'},'Object "'+node.name+'" refers to more than one armature! This is unsupported.') + self.operator.report({'WARNING'}, 'Object "'+node.name+'" refers to more than one armature! This is unsupported.') if (armcount==0): - self.operator.report({'WARNING'},'Object "'+node.name+'" is child of an armature, but has no armature modifier.') + self.operator.report({'WARNING'}, 'Object "'+node.name+'" is child of an armature, but has no armature modifier.') if (armcount>0 and not armature): - self.operator.report({'WARNING'},'Object "'+node.name+'" has armature modifier, but is not a child of an armature. This is unsupported.') + self.operator.report({'WARNING'}, 'Object "'+node.name+'" has armature modifier, but is not a child of an armature. This is unsupported.') if (node.data.shape_keys!=None): sk = node.data.shape_keys @@ -916,50 +916,50 @@ class DaeExporter: #print("LINKING "+str(node)+" WITH "+str(t.id.name)) self.armature_for_morph[node]=self.scene.objects[t.id.name] - meshdata = self.export_mesh(node,armature) + meshdata = self.export_mesh(node, armature) close_controller=False if ("skin_id" in meshdata): close_controller=True - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') for sn in self.skeleton_info[armature]["skeleton_nodes"]: - self.writel(S_NODES,il+1,'#'+sn+'') + self.writel(S_NODES, il+1, '#'+sn+'') elif ("morph_id" in meshdata): - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') close_controller=True elif (armature==None): - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') if (len(meshdata["material_assign"])>0): - self.writel(S_NODES,il+1,'') - self.writel(S_NODES,il+2,'') + self.writel(S_NODES, il+1, '') + self.writel(S_NODES, il+2, '') for m in meshdata["material_assign"]: - self.writel(S_NODES,il+3,'') + self.writel(S_NODES, il+3, '') - self.writel(S_NODES,il+2,'') - self.writel(S_NODES,il+1,'') + self.writel(S_NODES, il+2, '') + self.writel(S_NODES, il+1, '') if (close_controller): - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') else: - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') - def export_armature_bone(self,bone,il,si): + def export_armature_bone(self, bone, il, si): boneid = self.new_id("bone") boneidx = si["bone_count"] si["bone_count"]+=1 bonesid = si["id"]+"-"+str(boneidx) if (bone.name in self.used_bones): if (self.config["use_anim_action_all"]): - self.operator.report({'WARNING'},'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.') + self.operator.report({'WARNING'}, 'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.') else: self.used_bones.append(bone.name) si["bone_index"][bone.name]=boneidx si["bone_ids"][bone]=boneid si["bone_names"].append(bonesid) - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') il+=1 xform = bone.matrix_local si["bone_bind_poses"].append((si["armature_xform"] * xform).inverted()) @@ -969,25 +969,25 @@ class DaeExporter: else: si["skeleton_nodes"].append(boneid) - self.writel(S_NODES,il,''+strmtx(xform)+'') + self.writel(S_NODES, il, ''+strmtx(xform)+'') for c in bone.children: - self.export_armature_bone(c,il,si) + self.export_armature_bone(c, il, si) il-=1 - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') - def export_armature_node(self,node,il): + def export_armature_node(self, node, il): if (node.data==None): return self.skeletons.append(node) armature = node.data - self.skeleton_info[node]={ "bone_count":0, "id":self.new_id("skelbones"),"name":node.name, "bone_index":{},"bone_ids":{},"bone_names":[],"bone_bind_poses":[],"skeleton_nodes":[],"armature_xform":node.matrix_world } + self.skeleton_info[node]={ "bone_count":0, "id":self.new_id("skelbones"), "name":node.name, "bone_index":{}, "bone_ids":{}, "bone_names":[], "bone_bind_poses":[], "skeleton_nodes":[], "armature_xform":node.matrix_world } for b in armature.bones: if (b.parent!=None): continue - self.export_armature_bone(b,il,self.skeleton_info[node]) + self.export_armature_bone(b, il, self.skeleton_info[node]) if (node.pose): for b in node.pose.bones: @@ -995,86 +995,86 @@ class DaeExporter: if (x.type=='ACTION'): self.action_constraints.append(x.action) - def export_camera_node(self,node,il): + def export_camera_node(self, node, il): if (node.data==None): return camera=node.data camid=self.new_id("camera") - self.writel(S_CAMS,1,'') - self.writel(S_CAMS,2,'') - self.writel(S_CAMS,3,'') + self.writel(S_CAMS, 1, '') + self.writel(S_CAMS, 2, '') + self.writel(S_CAMS, 3, '') if (camera.type=="PERSP"): - self.writel(S_CAMS,4,'') - self.writel(S_CAMS,5,' '+str(math.degrees(camera.angle))+' ') # I think? - self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') - self.writel(S_CAMS,4,'') + self.writel(S_CAMS, 4, '') + self.writel(S_CAMS, 5, ' '+str(math.degrees(camera.angle))+' ') # I think? + self.writel(S_CAMS, 5, ' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') + self.writel(S_CAMS, 5, ' '+str(camera.clip_start)+' ') + self.writel(S_CAMS, 5, ' '+str(camera.clip_end)+' ') + self.writel(S_CAMS, 4, '') else: - self.writel(S_CAMS,4,'') - self.writel(S_CAMS,5,' '+str(camera.ortho_scale*0.5)+' ') # I think? - self.writel(S_CAMS,5,' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_start)+' ') - self.writel(S_CAMS,5,' '+str(camera.clip_end)+' ') - self.writel(S_CAMS,4,'') + self.writel(S_CAMS, 4, '') + self.writel(S_CAMS, 5, ' '+str(camera.ortho_scale*0.5)+' ') # I think? + self.writel(S_CAMS, 5, ' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') + self.writel(S_CAMS, 5, ' '+str(camera.clip_start)+' ') + self.writel(S_CAMS, 5, ' '+str(camera.clip_end)+' ') + self.writel(S_CAMS, 4, '') - self.writel(S_CAMS,3,'') - self.writel(S_CAMS,2,'') - self.writel(S_CAMS,1,'') + self.writel(S_CAMS, 3, '') + self.writel(S_CAMS, 2, '') + self.writel(S_CAMS, 1, '') - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') - def export_lamp_node(self,node,il): + def export_lamp_node(self, node, il): if (node.data==None): return light=node.data lightid=self.new_id("light") - self.writel(S_LAMPS,1,'') - #self.writel(S_LAMPS,2,'') - self.writel(S_LAMPS,3,'') + self.writel(S_LAMPS, 1, '') + #self.writel(S_LAMPS, 2, '') + self.writel(S_LAMPS, 3, '') if (light.type=="POINT"): - self.writel(S_LAMPS,4,'') - self.writel(S_LAMPS,5,''+strarr(light.color)+'') + self.writel(S_LAMPS, 4, '') + self.writel(S_LAMPS, 5, ''+strarr(light.color)+'') att_by_distance = 2.0 / light.distance # convert to linear attenuation - self.writel(S_LAMPS,5,''+str(att_by_distance)+'') + self.writel(S_LAMPS, 5, ''+str(att_by_distance)+'') if (light.use_sphere): - self.writel(S_LAMPS,5,''+str(light.distance)+'') + self.writel(S_LAMPS, 5, ''+str(light.distance)+'') - self.writel(S_LAMPS,4,'') + self.writel(S_LAMPS, 4, '') elif (light.type=="SPOT"): - self.writel(S_LAMPS,4,'') - self.writel(S_LAMPS,5,''+strarr(light.color)+'') + self.writel(S_LAMPS, 4, '') + self.writel(S_LAMPS, 5, ''+strarr(light.color)+'') att_by_distance = 2.0 / light.distance # convert to linear attenuation - self.writel(S_LAMPS,5,''+str(att_by_distance)+'') - self.writel(S_LAMPS,5,''+str(math.degrees(light.spot_size/2))+'') - self.writel(S_LAMPS,4,'') + self.writel(S_LAMPS, 5, ''+str(att_by_distance)+'') + self.writel(S_LAMPS, 5, ''+str(math.degrees(light.spot_size/2))+'') + self.writel(S_LAMPS, 4, '') else: #write a sun lamp for everything else (not supported) - self.writel(S_LAMPS,4,'') - self.writel(S_LAMPS,5,''+strarr(light.color)+'') - self.writel(S_LAMPS,4,'') + self.writel(S_LAMPS, 4, '') + self.writel(S_LAMPS, 5, ''+strarr(light.color)+'') + self.writel(S_LAMPS, 4, '') - self.writel(S_LAMPS,3,'') - #self.writel(S_LAMPS,2,'') - self.writel(S_LAMPS,1,'') + self.writel(S_LAMPS, 3, '') + #self.writel(S_LAMPS, 2, '') + self.writel(S_LAMPS, 1, '') - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') - def export_empty_node(self,node,il): - self.writel(S_NODES,4,'') - self.writel(S_NODES,5,'') - self.writel(S_NODES,6,''+node.empty_draw_type+'') - self.writel(S_NODES,5,'') - self.writel(S_NODES,4,'') + def export_empty_node(self, node, il): + self.writel(S_NODES, 4, '') + self.writel(S_NODES, 5, '') + self.writel(S_NODES, 6, ''+node.empty_draw_type+'') + self.writel(S_NODES, 5, '') + self.writel(S_NODES, 4, '') - def export_curve(self,curve): + def export_curve(self, curve): splineid = self.new_id("spline") - self.writel(S_GEOM,1,'') - self.writel(S_GEOM,2,'') + self.writel(S_GEOM, 1, '') + self.writel(S_GEOM, 2, '') points=[] interps=[] @@ -1115,122 +1115,122 @@ class DaeExporter: tilts.append(s.tilt) interps.append("LINEAR") - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 3, '') position_values="" for x in points: position_values+=" "+str(x) - self.writel(S_GEOM,4,''+position_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+position_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + + self.writel(S_GEOM, 3, '') intangent_values="" for x in handles_in: intangent_values+=" "+str(x) - self.writel(S_GEOM,4,''+intangent_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+intangent_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + + self.writel(S_GEOM, 3, '') outtangent_values="" for x in handles_out: outtangent_values+=" "+str(x) - self.writel(S_GEOM,4,''+outtangent_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+outtangent_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + + self.writel(S_GEOM, 3, '') interpolation_values="" for x in interps: interpolation_values+=" "+x - self.writel(S_GEOM,4,''+interpolation_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') + self.writel(S_GEOM, 4, ''+interpolation_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + + self.writel(S_GEOM, 3, '') tilt_values="" for x in tilts: tilt_values+=" "+str(x) - self.writel(S_GEOM,4,''+tilt_values+'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,5,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,3,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,4,'') - self.writel(S_GEOM,3,'') - - self.writel(S_GEOM,2,'') - self.writel(S_GEOM,1,'') + self.writel(S_GEOM, 4, ''+tilt_values+'') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 5, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + + self.writel(S_GEOM, 3, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + + self.writel(S_GEOM, 2, '') + self.writel(S_GEOM, 1, '') return splineid - def export_curve_node(self,node,il): + def export_curve_node(self, node, il): if (node.data==None): return curveid = self.export_curve(node.data) - self.writel(S_NODES,il,'') - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') + self.writel(S_NODES, il, '') - def export_node(self,node,il): + def export_node(self, node, il): if (not node in self.valid_nodes): return prev_node = bpy.context.scene.objects.active bpy.context.scene.objects.active = node - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') il+=1 - self.writel(S_NODES,il,''+strmtx(node.matrix_local)+'') + self.writel(S_NODES, il, ''+strmtx(node.matrix_local)+'') #print("NODE TYPE: "+node.type+" NAME: "+node.name) if (node.type=="MESH"): - self.export_mesh_node(node,il) + self.export_mesh_node(node, il) elif (node.type=="CURVE"): - self.export_curve_node(node,il) + self.export_curve_node(node, il) elif (node.type=="ARMATURE"): - self.export_armature_node(node,il) + self.export_armature_node(node, il) elif (node.type=="CAMERA"): - self.export_camera_node(node,il) + self.export_camera_node(node, il) elif (node.type=="LAMP"): - self.export_lamp_node(node,il) + self.export_lamp_node(node, il) elif (node.type=="EMPTY"): - self.export_empty_node(node,il) + self.export_empty_node(node, il) for x in node.children: - self.export_node(x,il) + self.export_node(x, il) il-=1 - self.writel(S_NODES,il,'') + self.writel(S_NODES, il, '') bpy.context.scene.objects.active = prev_node #make previous node active again - def is_node_valid(self,node): + def is_node_valid(self, node): if (not node.type in self.config["object_types"]): return False @@ -1250,8 +1250,8 @@ class DaeExporter: return True def export_scene(self): - self.writel(S_NODES,0,'') - self.writel(S_NODES,1,'') + self.writel(S_NODES, 0, '') + self.writel(S_NODES, 1, '') # validate nodes for obj in self.scene.objects: @@ -1266,28 +1266,28 @@ class DaeExporter: for obj in self.scene.objects: if (obj in self.valid_nodes and obj.parent==None): - self.export_node(obj,2) + self.export_node(obj, 2) - self.writel(S_NODES,1,'') - self.writel(S_NODES,0,'') + self.writel(S_NODES, 1, '') + self.writel(S_NODES, 0, '') def export_asset(self): - self.writel(S_ASSET,0,'') + self.writel(S_ASSET, 0, '') # Why is this time stuff mandatory?, no one could care less... - self.writel(S_ASSET,1,'') - self.writel(S_ASSET,2,' Anonymous ') #Who made Collada, the FBI ? - self.writel(S_ASSET,2,' Collada Exporter for Blender 2.6+, by Juan Linietsky (juan@codenix.com) ') #Who made Collada, the FBI ? - self.writel(S_ASSET,1,'') - self.writel(S_ASSET,1,''+time.strftime("%Y-%m-%dT%H:%M:%SZ ")+'') - self.writel(S_ASSET,1,''+time.strftime("%Y-%m-%dT%H:%M:%SZ")+'') - self.writel(S_ASSET,1,'') - self.writel(S_ASSET,1,'Z_UP') - self.writel(S_ASSET,0,'') - - def export_animation_transform_channel(self,target,keys,matrices=True): + self.writel(S_ASSET, 1, '') + self.writel(S_ASSET, 2, ' Anonymous ') #Who made Collada, the FBI ? + self.writel(S_ASSET, 2, ' Collada Exporter for Blender 2.6+, by Juan Linietsky (juan@codenix.com) ') #Who made Collada, the FBI ? + self.writel(S_ASSET, 1, '') + self.writel(S_ASSET, 1, ''+time.strftime("%Y-%m-%dT%H:%M:%SZ ")+'') + self.writel(S_ASSET, 1, ''+time.strftime("%Y-%m-%dT%H:%M:%SZ")+'') + self.writel(S_ASSET, 1, '') + self.writel(S_ASSET, 1, 'Z_UP') + self.writel(S_ASSET, 0, '') + + def export_animation_transform_channel(self, target, keys, matrices=True): frame_total=len(keys) anim_id=self.new_id("anim") - self.writel(S_ANIM,1,'') + self.writel(S_ANIM, 1, '') source_frames = "" source_transforms = "" source_interps = "" @@ -1302,60 +1302,60 @@ class DaeExporter: source_interps +=" LINEAR" # Time Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_frames+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, ''+source_frames+'') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 5, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 2, '') if (matrices): # Transform Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_transforms+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, ''+source_transforms+'') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 5, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 2, '') else: # Value Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_transforms+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, ''+source_transforms+'') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 5, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 2, '') # Interpolation Source - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,''+source_interps+'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,5,'') - self.writel(S_ANIM,4,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') - - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,3,'') - self.writel(S_ANIM,2,'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, ''+source_interps+'') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 5, '') + self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 2, '') + + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 2, '') if (matrices): - self.writel(S_ANIM,2,'') + self.writel(S_ANIM, 2, '') else: - self.writel(S_ANIM,2,'') - self.writel(S_ANIM,1,'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 1, '') return [anim_id] - def export_animation(self,start,end,allowed=None): + def export_animation(self, start, end, allowed=None): # Blender -> Collada frames needs a little work # Collada starts from 0, blender usually from 1 # The last frame must be included also @@ -1375,7 +1375,7 @@ class DaeExporter: # This improves performance enormously #print("anim from: "+str(start)+" to "+str(end)+" allowed: "+str(allowed)) - for t in range(start,end+1): + for t in range(start, end+1): self.scene.frame_set(t) key = t * frame_len - frame_sub # print("Export Anim Frame "+str(t)+"/"+str(self.scene.frame_end+1)) @@ -1401,7 +1401,7 @@ class DaeExporter: if (not (name in blend_cache)): blend_cache[name]=[] - blend_cache[name].append( (key,node.data.shape_keys.key_blocks[i].value) ) + blend_cache[name].append( (key, node.data.shape_keys.key_blocks[i].value) ) if (node.type=="MESH" and node.parent and node.parent.type=="ARMATURE"): @@ -1417,7 +1417,7 @@ class DaeExporter: if (node.parent): mtx = node.parent.matrix_world.inverted() * mtx - xform_cache[name].append( (key,mtx) ) + xform_cache[name].append( (key, mtx) ) if (node.type=="ARMATURE"): #All bones exported for now @@ -1445,15 +1445,15 @@ class DaeExporter: if (not parent_invisible): mtx = parent_posebone.matrix.inverted() * mtx - xform_cache[bone_name].append( (key,mtx) ) + xform_cache[bone_name].append( (key, mtx) ) self.scene.frame_set(frame_orig) #export animation xml for nid in xform_cache: - tcn+=self.export_animation_transform_channel(nid,xform_cache[nid],True) + tcn+=self.export_animation_transform_channel(nid, xform_cache[nid], True) for nid in blend_cache: - tcn+=self.export_animation_transform_channel(nid,blend_cache[nid],False) + tcn+=self.export_animation_transform_channel(nid, blend_cache[nid], False) return tcn @@ -1464,9 +1464,9 @@ class DaeExporter: for bone in s.pose.bones: tmp_bone_mat.append(Matrix(bone.matrix_basis)) bone.matrix_basis = Matrix() - tmp_mat.append([Matrix(s.matrix_local),tmp_bone_mat]) + tmp_mat.append([Matrix(s.matrix_local), tmp_bone_mat]) - self.writel(S_ANIM,0,'') + self.writel(S_ANIM, 0, '') if (self.config["use_anim_action_all"] and len(self.skeletons)): cached_actions = {} @@ -1475,7 +1475,7 @@ class DaeExporter: if s.animation_data and s.animation_data.action: cached_actions[s] = s.animation_data.action.name - self.writel(S_ANIM_CLIPS,0,'') + self.writel(S_ANIM_CLIPS, 0, '') for x in bpy.data.actions[:]: if x.users==0 or x in self.action_constraints: @@ -1496,7 +1496,7 @@ class DaeExporter: bones.append(dp) allowed_skeletons=[] - for i,y in enumerate(self.skeletons): + for i, y in enumerate(self.skeletons): if (y.animation_data): for z in y.pose.bones: if (z.bone.name in bones): @@ -1505,87 +1505,87 @@ class DaeExporter: y.animation_data.action=x; y.matrix_local = tmp_mat[i][0] - for j,bone in enumerate(s.pose.bones): + for j, bone in enumerate(s.pose.bones): bone.matrix_basis = Matrix() # print("allowed skeletons "+str(allowed_skeletons)) # print(str(x)) - tcn = self.export_animation(int(x.frame_range[0]),int(x.frame_range[1]+0.5),allowed_skeletons) + tcn = self.export_animation(int(x.frame_range[0]), int(x.frame_range[1]+0.5), allowed_skeletons) framelen=(1.0/self.scene.render.fps) start = x.frame_range[0]*framelen end = x.frame_range[1]*framelen #print("Export anim: "+x.name) - self.writel(S_ANIM_CLIPS,1,'') + self.writel(S_ANIM_CLIPS, 1, '') for z in tcn: - self.writel(S_ANIM_CLIPS,2,'') - self.writel(S_ANIM_CLIPS,1,'') + self.writel(S_ANIM_CLIPS, 2, '') + self.writel(S_ANIM_CLIPS, 1, '') if (len(tcn)==0): - self.operator.report({'WARNING'},'Animation clip "'+x.name+'" contains no tracks.') + self.operator.report({'WARNING'}, 'Animation clip "'+x.name+'" contains no tracks.') - self.writel(S_ANIM_CLIPS,0,'') + self.writel(S_ANIM_CLIPS, 0, '') - for i,s in enumerate(self.skeletons): + for i, s in enumerate(self.skeletons): if (s.animation_data==None): continue if s in cached_actions: s.animation_data.action = bpy.data.actions[cached_actions[s]] else: s.animation_data.action = None - for j,bone in enumerate(s.pose.bones): + for j, bone in enumerate(s.pose.bones): bone.matrix_basis = tmp_mat[i][1][j] else: - self.export_animation(self.scene.frame_start,self.scene.frame_end) + self.export_animation(self.scene.frame_start, self.scene.frame_end) - self.writel(S_ANIM,0,'') + self.writel(S_ANIM, 0, '') def export(self): - self.writel(S_GEOM,0,'') - self.writel(S_CONT,0,'') - self.writel(S_CAMS,0,'') - self.writel(S_LAMPS,0,'') - self.writel(S_IMGS,0,'') - self.writel(S_MATS,0,'') - self.writel(S_FX,0,'') + self.writel(S_GEOM, 0, '') + self.writel(S_CONT, 0, '') + self.writel(S_CAMS, 0, '') + self.writel(S_LAMPS, 0, '') + self.writel(S_IMGS, 0, '') + self.writel(S_MATS, 0, '') + self.writel(S_FX, 0, '') self.skeletons=[] self.action_constraints=[] self.export_asset() self.export_scene() - self.writel(S_GEOM,0,'') + self.writel(S_GEOM, 0, '') #morphs always go before skin controllers if S_MORPH in self.sections: for l in self.sections[S_MORPH]: - self.writel(S_CONT,0,l) + self.writel(S_CONT, 0, l) del self.sections[S_MORPH] #morphs always go before skin controllers if S_SKIN in self.sections: for l in self.sections[S_SKIN]: - self.writel(S_CONT,0,l) + self.writel(S_CONT, 0, l) del self.sections[S_SKIN] - self.writel(S_CONT,0,'') - self.writel(S_CAMS,0,'') - self.writel(S_LAMPS,0,'') - self.writel(S_IMGS,0,'') - self.writel(S_MATS,0,'') - self.writel(S_FX,0,'') + self.writel(S_CONT, 0, '') + self.writel(S_CAMS, 0, '') + self.writel(S_LAMPS, 0, '') + self.writel(S_IMGS, 0, '') + self.writel(S_MATS, 0, '') + self.writel(S_FX, 0, '') if (self.config["use_anim"]): self.export_animations() try: - f = open(self.path,"wb") + f = open(self.path, "wb") except: return False - f.write(bytes('\n',"UTF-8")) - f.write(bytes('\n',"UTF-8")) + f.write(bytes('\n', "UTF-8")) + f.write(bytes('\n', "UTF-8")) s=[] for x in self.sections.keys(): @@ -1593,15 +1593,15 @@ class DaeExporter: s.sort() for x in s: for l in self.sections[x]: - f.write(bytes(l+"\n","UTF-8")) + f.write(bytes(l+"\n", "UTF-8")) - f.write(bytes('\n',"UTF-8")) - f.write(bytes('\t\n',"UTF-8")) - f.write(bytes('\n',"UTF-8")) - f.write(bytes('\n',"UTF-8")) + f.write(bytes('\n', "UTF-8")) + f.write(bytes('\t\n', "UTF-8")) + f.write(bytes('\n', "UTF-8")) + f.write(bytes('\n', "UTF-8")) return True - def __init__(self,path,kwargs,operator): + def __init__(self, path, kwargs, operator): self.operator=operator self.scene=bpy.context.scene self.last_id=0 @@ -1626,7 +1626,7 @@ def save(operator, context, **kwargs ): - exp = DaeExporter(filepath,kwargs,operator) + exp = DaeExporter(filepath, kwargs, operator) exp.export() return {'FINISHED'} # so the script wont run after we have batch exported. -- cgit v1.2.3 From c973f3a1da9fbb7ba816455b761c6cc3f9535b78 Mon Sep 17 00:00:00 2001 From: Nobody Really Date: Sat, 9 Jul 2016 12:25:21 +0200 Subject: Flake8 compliance (except for unused variables) --- tools/export/blender25/godot_export_manager.py | 257 ++-- tools/export/blender25/io_scene_dae/__init__.py | 33 +- tools/export/blender25/io_scene_dae/export_dae.py | 1527 ++++++++++++--------- 3 files changed, 1105 insertions(+), 712 deletions(-) diff --git a/tools/export/blender25/godot_export_manager.py b/tools/export/blender25/godot_export_manager.py index 293e0173e9..c91f55b51c 100644 --- a/tools/export/blender25/godot_export_manager.py +++ b/tools/export/blender25/godot_export_manager.py @@ -18,24 +18,27 @@ # Script copyright (c) Andreas Esau +import bpy +from bpy.props import (StringProperty, BoolProperty, EnumProperty, + FloatProperty, IntProperty, CollectionProperty) +import os +from bpy.app.handlers import persistent +from mathutils import Matrix + bl_info = { "name": "Godot Export Manager", "author": "Andreas Esau", "version": (1, 0), "blender": (2, 7, 0), "location": "Scene Properties > Godot Export Manager", - "description": "Godot Export Manager uses the Better Collada Exporter to manage Export Groups and automatically export the objects groups to Collada Files.", + "description": "Godot Export Manager uses the Better Collada Exporter" + "to manage Export Groups and automatically export the objects groups" + "to Collada Files.", "warning": "", "wiki_url": ("http://www.godotengine.org"), "tracker_url": "", "category": "Import-Export"} -import bpy -from bpy.props import StringProperty, BoolProperty, EnumProperty, FloatProperty, FloatVectorProperty, IntProperty, CollectionProperty, PointerProperty -import os -from bpy.app.handlers import persistent -from mathutils import Vector, Matrix - class godot_export_manager(bpy.types.Panel): bl_label = "Godot Export Manager" @@ -45,8 +48,8 @@ class godot_export_manager(bpy.types.Panel): bpy.types.Scene.godot_export_on_save = BoolProperty(default=False) - ### draw function for all ui elements def draw(self, context): + """ Draw function for all ui elements """ layout = self.layout split = self.layout.split() scene = bpy.data.scenes[0] @@ -59,9 +62,13 @@ class godot_export_manager(bpy.types.Panel): row = layout.row() col = row.column(align=True) - op = col.operator("scene.godot_add_objects_to_group", text="Add selected objects to Group", icon="COPYDOWN") + op = col.operator("scene.godot_add_objects_to_group", + text="Add selected objects to Group", + icon="COPYDOWN") - op = col.operator("scene.godot_delete_objects_from_group", text="Delete selected objects from Group", icon="PASTEDOWN") + op = col.operator("scene.godot_delete_objects_from_group", + text="Delete selected objects from Group", + icon="PASTEDOWN") row = layout.row() col = row.column() @@ -70,11 +77,15 @@ class godot_export_manager(bpy.types.Panel): row = layout.row() col = row.column() - col.template_list("UI_List_Godot", "dummy", scene, "godot_export_groups", scene, "godot_export_groups_index", rows=1, maxrows=10, type='DEFAULT') + col.template_list("UI_List_Godot", "dummy", scene, + "godot_export_groups", scene, + "godot_export_groups_index", rows=1, maxrows=10, + type='DEFAULT') col = row.column(align=True) col.operator("scene.godot_add_export_group", text="", icon="ZOOMIN") - col.operator("scene.godot_delete_export_group", text="", icon="ZOOMOUT") + col.operator("scene.godot_delete_export_group", text="", + icon="ZOOMOUT") col.operator("scene.godot_export_all_groups", text="", icon="EXPORT") if len(scene.godot_export_groups) > 0: @@ -113,9 +124,10 @@ class godot_export_manager(bpy.types.Panel): col.prop(group, "use_metadata") -### Custom template_list look class UI_List_Godot(bpy.types.UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + """ Custom template_list look """ + def draw_item(self, context, layout, data, item, icon, active_data, + active_propname, index): ob = data slot = item col = layout.row(align=True) @@ -123,11 +135,14 @@ class UI_List_Godot(bpy.types.UIList): col.label(text=item.name, icon="GROUP") col.prop(item, "active", text="") - op = col.operator("scene.godot_select_group_objects", text="", emboss=False, icon="RESTRICT_SELECT_OFF") + op = col.operator("scene.godot_select_group_objects", + text="", emboss=False, icon="RESTRICT_SELECT_OFF") op.idx = index - op = col.operator("scene.godot_export_group", text="", emboss=False, icon="EXPORT") + op = col.operator("scene.godot_export_group", text="", emboss=False, + icon="EXPORT") op.idx = index + class add_objects_to_group(bpy.types.Operator): bl_idname = "scene.godot_add_objects_to_group" bl_label = "Add Objects to Group" @@ -141,20 +156,24 @@ class add_objects_to_group(bpy.types.Operator): objects_str = "" if len(scene.godot_export_groups) > 0: for i, object in enumerate(context.selected_objects): - if object.name not in scene.godot_export_groups[scene.godot_export_groups_index].nodes: - node = scene.godot_export_groups[scene.godot_export_groups_index].nodes.add() + if object.name not in scene.godot_export_groups[ + scene.godot_export_groups_index].nodes: + node = scene.godot_export_groups[ + scene.godot_export_groups_index].nodes.add() node.name = object.name if i == 0: objects_str += object.name else: objects_str += ", "+object.name - self.report({'INFO'}, objects_str + " added to group." ) + self.report({'INFO'}, objects_str + " added to group.") if self.undo: bpy.ops.ed.undo_push(message="Objects added to group") else: - self.report({'WARNING'}, "Create a group first." ) - return{'FINISHED'} + self.report({'WARNING'}, "Create a group first.") + + return {'FINISHED'} + class del_objects_from_group(bpy.types.Operator): bl_idname = "scene.godot_delete_objects_from_group" @@ -172,21 +191,25 @@ class del_objects_from_group(bpy.types.Operator): objects_str = "" j = 0 - for i, node in enumerate(scene.godot_export_groups[scene.godot_export_groups_index].nodes): + for i, node in enumerate(scene.godot_export_groups[ + scene.godot_export_groups_index].nodes): if node.name in selected_objects: - scene.godot_export_groups[scene.godot_export_groups_index].nodes.remove(i) + scene.godot_export_groups[ + scene.godot_export_groups_index].nodes.remove(i) if j == 0: objects_str += object.name else: objects_str += ", "+object.name - j+=1 + j += 1 - self.report({'INFO'}, objects_str + " deleted from group." ) + self.report({'INFO'}, objects_str + " deleted from group.") bpy.ops.ed.undo_push(message="Objects deleted from group") else: - self.report({'WARNING'}, "There is no group to delete from." ) - return{'FINISHED'} + self.report({'WARNING'}, "There is no group to delete from.") + + return {'FINISHED'} + class select_group_objects(bpy.types.Operator): bl_idname = "scene.godot_select_group_objects" @@ -203,7 +226,8 @@ class select_group_objects(bpy.types.Operator): if node.name in bpy.data.objects: bpy.data.objects[node.name].select = True context.scene.objects.active = bpy.data.objects[node.name] - return{'FINISHED'} + + return {'FINISHED'} class export_groups_autosave(bpy.types.Operator): @@ -217,9 +241,10 @@ class export_groups_autosave(bpy.types.Operator): for i in range(len(scene.godot_export_groups)): if scene.godot_export_groups[i].active: bpy.ops.scene.godot_export_group(idx=i) - self.report({'INFO'}, "All Groups exported." ) + self.report({'INFO'}, "All Groups exported.") bpy.ops.ed.undo_push(message="Export all Groups") - return{'FINISHED'} + + return {'FINISHED'} class export_all_groups(bpy.types.Operator): @@ -233,46 +258,49 @@ class export_all_groups(bpy.types.Operator): for i in range(0, len(scene.godot_export_groups)): bpy.ops.scene.godot_export_group(idx=i, export_all=True) - self.report({'INFO'}, "All Groups exported." ) - return{'FINISHED'} + self.report({'INFO'}, "All Groups exported.") + + return {'FINISHED'} class export_group(bpy.types.Operator): bl_idname = "scene.godot_export_group" bl_label = "Export Group" - bl_description = "Exports the active group to destination folder as Collada file." + bl_description = "Exports the active group to destination folder"\ + " as Collada file." idx = IntProperty(default=0) export_all = BoolProperty(default=False) - def copy_object_recursive(self, ob, parent, single_user = True): + def copy_object_recursive(self, ob, parent, single_user=True): new_ob = bpy.data.objects[ob.name].copy() - if single_user or ob.type=="ARMATURE": + if single_user or ob.type == "ARMATURE": new_mesh_data = new_ob.data.copy() new_ob.data = new_mesh_data bpy.context.scene.objects.link(new_ob) if ob != parent: - new_ob.parent = parent + new_ob.parent = parent else: new_ob.parent = None for child in ob.children: self.copy_object_recursive(child, new_ob, single_user) new_ob.select = True + return new_ob def delete_object(self, ob): - if ob != None: + if ob is not None: for child in ob.children: self.delete_object(child) bpy.context.scene.objects.unlink(ob) bpy.data.objects.remove(ob) def convert_group_to_node(self, group): - if group.dupli_group != None: + if group.dupli_group is not None: for object in group.dupli_group.objects: - if object.parent == None: + if object.parent is None: object = self.copy_object_recursive(object, object, True) matrix = Matrix(object.matrix_local) object.matrix_local = Matrix() @@ -297,15 +325,16 @@ class export_group(bpy.types.Operator): bpy.ops.ed.undo_push(message="Clear not existent Group Nodes.") path = group[self.idx].export_path - if (path.find("//")==0 or path.find("\\\\")==0): - #if relative, convert to absolute + if (path.find("//") == 0 or path.find("\\\\") == 0): + # If relative, convert to absolute path = bpy.path.abspath(path) path = path.replace("\\", "/") - ### if path exists and group export name is set the group will be exported - if os.path.exists(path) and group[self.idx].export_name != "": + # If path exists and group export name is set the group will be + # exported + if os.path.exists(path) and group[self.idx].export_name != "": - context.scene.layers = [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] + context.scene.layers = [True] * 20 if group[self.idx].export_name.endswith(".dae"): path = os.path.join(path, group[self.idx].export_name) @@ -319,17 +348,19 @@ class export_group(bpy.types.Operator): object.select = False context.scene.objects.active = None - ### make particle duplicates, parent and select them + # Make particle duplicates, parent and select them nodes_to_be_added = [] if group[self.idx].use_include_particle_duplicates: for i, object in enumerate(group[self.idx].nodes): if bpy.data.objects[object.name].type != "EMPTY": - context.scene.objects.active = bpy.data.objects[object.name] + context.scene.objects.active = bpy.data.objects[ + object.name] bpy.data.objects[object.name].select = True bpy.ops.object.duplicates_make_real() for object in context.selected_objects: nodes_to_be_added.append(object) - bpy.ops.object.parent_set(type="OBJECT", keep_transform=False) + bpy.ops.object.parent_set(type="OBJECT", + keep_transform=False) for object in context.selected_objects: object.select = False @@ -338,17 +369,35 @@ class export_group(bpy.types.Operator): for object in nodes_to_be_added: object.select = True - ### select all other nodes from the group + # Select all other nodes from the group for i, object in enumerate(group[self.idx].nodes): if bpy.data.objects[object.name].type == "EMPTY": self.convert_group_to_node(bpy.data.objects[object.name]) else: bpy.data.objects[object.name].select = True - bpy.ops.object.transform_apply(location=group[self.idx].apply_loc, rotation=group[self.idx].apply_rot, scale=group[self.idx].apply_scale) - bpy.ops.export_scene.dae(check_existing=True, filepath=path, filter_glob="*.dae", object_types=group[self.idx].object_types, use_export_selected=group[self.idx].use_export_selected, use_mesh_modifiers=group[self.idx].use_mesh_modifiers, use_tangent_arrays=group[self.idx].use_tangent_arrays, use_triangles=group[self.idx].use_triangles, use_copy_images=group[self.idx].use_copy_images, use_active_layers=group[self.idx].use_active_layers, use_anim=group[self.idx].use_anim, use_anim_action_all=group[self.idx].use_anim_action_all, use_anim_skip_noexp=group[self.idx].use_anim_skip_noexp, use_anim_optimize=group[self.idx].use_anim_optimize, anim_optimize_precision=group[self.idx].anim_optimize_precision, use_metadata=group[self.idx].use_metadata) - - self.report({'INFO'}, '"'+group[self.idx].name+'"' + " Group exported." ) + bpy.ops.object.transform_apply(location=group[self.idx].apply_loc, + rotation=group[self.idx].apply_rot, + scale=group[self.idx].apply_scale) + bpy.ops.export_scene.dae( + check_existing=True, filepath=path, filter_glob="*.dae", + object_types=group[self.idx].object_types, + use_export_selected=group[self.idx].use_export_selected, + use_mesh_modifiers=group[self.idx].use_mesh_modifiers, + use_tangent_arrays=group[self.idx].use_tangent_arrays, + use_triangles=group[self.idx].use_triangles, + use_copy_images=group[self.idx].use_copy_images, + use_active_layers=group[self.idx].use_active_layers, + use_anim=group[self.idx].use_anim, + use_anim_action_all=group[self.idx].use_anim_action_all, + use_anim_skip_noexp=group[self.idx].use_anim_skip_noexp, + use_anim_optimize=group[self.idx].use_anim_optimize, + anim_optimize_precision=group[ + self.idx].anim_optimize_precision, + use_metadata=group[self.idx].use_metadata) + + self.report({'INFO'}, + '"' + group[self.idx].name + '" Group exported.') msg = "Export Group "+group[self.idx].name bpy.ops.ed.undo_push(message="") @@ -356,14 +405,16 @@ class export_group(bpy.types.Operator): bpy.ops.ed.undo_push(message=msg) else: - self.report({'INFO'}, "Define Export Name and Export Path." ) + self.report({'INFO'}, "Define Export Name and Export Path.") + return{'FINISHED'} class add_export_group(bpy.types.Operator): bl_idname = "scene.godot_add_export_group" bl_label = "Adds a new export Group" - bl_description = "Creates a new Export Group with the selected Objects assigned to it." + bl_description = "Creates a new Export Group with the selected"\ + " Objects assigned to it." def execute(self, context): scene = context.scene @@ -375,6 +426,7 @@ class add_export_group(bpy.types.Operator): node.name = object.name scene.godot_export_groups_index = len(scene.godot_export_groups)-1 bpy.ops.ed.undo_push(message="Create New Export Group") + return{'FINISHED'} @@ -385,6 +437,7 @@ class del_export_group(bpy.types.Operator): def invoke(self, context, event): wm = context.window_manager + return wm.invoke_confirm(self, event) def execute(self, context): @@ -394,7 +447,8 @@ class del_export_group(bpy.types.Operator): if scene.godot_export_groups_index > 0: scene.godot_export_groups_index -= 1 bpy.ops.ed.undo_push(message="Delete Export Group") - return{'FINISHED'} + + return {'FINISHED'} class godot_node_list(bpy.types.PropertyGroup): @@ -408,28 +462,74 @@ class godot_export_groups(bpy.types.PropertyGroup): export_path = StringProperty(subtype="DIR_PATH") active = BoolProperty(default=True, description="Export Group") - object_types = EnumProperty(name="Object Types", options={'ENUM_FLAG'}, items=(('EMPTY', "Empty", ""), ('CAMERA', "Camera", ""), ('LAMP', "Lamp", ""), ('ARMATURE', "Armature", ""), ('MESH', "Mesh", ""), ('CURVE', "Curve", ""), ), default={'EMPTY', 'CAMERA', 'LAMP', 'ARMATURE', 'MESH', 'CURVE'}) - - apply_scale = BoolProperty(name="Apply Scale", description="Apply Scale before export.", default=False) - apply_rot = BoolProperty(name="Apply Rotation", description="Apply Rotation before export.", default=False) - apply_loc = BoolProperty(name="Apply Location", description="Apply Location before export.", default=False) - - use_export_selected = BoolProperty(name="Selected Objects", description="Export only selected objects (and visible in active layers if that applies).", default=True) - use_mesh_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers to mesh objects (on a copy!).", default=True) - use_tangent_arrays = BoolProperty(name="Tangent Arrays", description="Export Tangent and Binormal arrays (for normalmapping).", default=False) - use_triangles = BoolProperty(name="Triangulate", description="Export Triangles instead of Polygons.", default=False) - - use_copy_images = BoolProperty(name="Copy Images", description="Copy Images (create images/ subfolder)", default=False) - use_active_layers = BoolProperty(name="Active Layers", description="Export only objects on the active layers.", default=True) - use_anim = BoolProperty(name="Export Animation", description="Export keyframe animation", default=False) - use_anim_action_all = BoolProperty(name="All Actions", description=("Export all actions for the first armature found in separate DAE files"), default=False) - use_anim_skip_noexp = BoolProperty(name="Skip (-noexp) Actions", description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.", default=True) - use_anim_optimize = BoolProperty(name="Optimize Keyframes", description="Remove double keyframes", default=True) - - anim_optimize_precision = FloatProperty(name="Precision", description=("Tolerence for comparing double keyframes (higher for greater accuracy)"), min=1, max=16, soft_min=1, soft_max=16, default=6.0) - - use_metadata = BoolProperty(name="Use Metadata", default=True, options={'HIDDEN'}) - use_include_particle_duplicates = BoolProperty(name="Include Particle Duplicates", default=True) + object_types = EnumProperty(name="Object Types", options={'ENUM_FLAG'}, + items=(('EMPTY', "Empty", ""), + ('CAMERA', "Camera", ""), + ('LAMP', "Lamp", ""), + ('ARMATURE', "Armature", ""), + ('MESH', "Mesh", ""), + ('CURVE', "Curve", ""), ), + default={'EMPTY', 'CAMERA', 'LAMP', + 'ARMATURE', 'MESH', 'CURVE'}) + + apply_scale = BoolProperty(name="Apply Scale", + description="Apply Scale before export.", + default=False) + apply_rot = BoolProperty(name="Apply Rotation", + description="Apply Rotation before export.", + default=False) + apply_loc = BoolProperty(name="Apply Location", + description="Apply Location before export.", + default=False) + + use_export_selected = BoolProperty(name="Selected Objects", + description="Export only selected" + "objects (and visible in active layers " + "if that applies).", default=True) + use_mesh_modifiers = BoolProperty(name="Apply Modifiers", + description="Apply modifiers to mesh" + " objects (on a copy!).", default=True) + use_tangent_arrays = BoolProperty(name="Tangent Arrays", + description="Export Tangent and Binormal" + " arrays (for normalmapping).", + default=False) + use_triangles = BoolProperty(name="Triangulate", + description="Export Triangles instead of" + " Polygons.", default=False) + + use_copy_images = BoolProperty(name="Copy Images", + description="Copy Images (create images/ " + "subfolder)", default=False) + use_active_layers = BoolProperty(name="Active Layers", + description="Export only objects on the" + " active layers.", default=True) + use_anim = BoolProperty(name="Export Animation", + description="Export keyframe animation", + default=False) + use_anim_action_all = BoolProperty(name="All Actions", + description=("Export all actions for " + "the first armature found" + " in separate DAE files"), + default=False) + use_anim_skip_noexp = BoolProperty(name="Skip (-noexp) Actions", + description="Skip exporting of" + " actions whose name end in (-noexp)." + " Useful to skip control animations.", + default=True) + use_anim_optimize = BoolProperty(name="Optimize Keyframes", + description="Remove double keyframes", + default=True) + + anim_optimize_precision = FloatProperty( + name="Precision", description=("Tolerence for comparing double " + "keyframes (higher for greater " + "accuracy)"), min=1, max=16, + soft_min=1, soft_max=16, default=6.0) + + use_metadata = BoolProperty(name="Use Metadata", default=True, + options={'HIDDEN'}) + use_include_particle_duplicates = BoolProperty( + name="Include Particle Duplicates", default=True) def register(): @@ -446,7 +546,8 @@ def register(): bpy.utils.register_class(select_group_objects) bpy.utils.register_class(UI_List_Godot) - bpy.types.Scene.godot_export_groups = CollectionProperty(type=godot_export_groups) + bpy.types.Scene.godot_export_groups = CollectionProperty( + type=godot_export_groups) bpy.types.Scene.godot_export_groups_index = IntProperty(default=0, min=0) diff --git a/tools/export/blender25/io_scene_dae/__init__.py b/tools/export/blender25/io_scene_dae/__init__.py index 3bde01f2df..0b82e1537b 100644 --- a/tools/export/blender25/io_scene_dae/__init__.py +++ b/tools/export/blender25/io_scene_dae/__init__.py @@ -18,35 +18,30 @@ # +import bpy +from bpy.props import StringProperty, BoolProperty, FloatProperty, EnumProperty + +from bpy_extras.io_utils import ExportHelper bl_info = { "name": "Better Collada Exporter", "author": "Juan Linietsky", "blender": (2, 5, 8), "api": 38691, "location": "File > Import-Export", - "description": ("Export DAE Scenes, This plugin actually works better! otherwise contact me."), + "description": ("Export DAE Scenes, This plugin actually works better! " + "otherwise contact me."), "warning": "", "wiki_url": ("http://www.godotengine.org"), "tracker_url": "", "support": 'OFFICIAL', "category": "Import-Export"} - if "bpy" in locals(): import imp if "export_dae" in locals(): imp.reload(export_dae) -import bpy -from bpy.props import StringProperty, BoolProperty, FloatProperty, EnumProperty - -from bpy_extras.io_utils import (ExportHelper, - path_reference_mode, - axis_conversion, - ) - - class ExportDAE(bpy.types.Operator, ExportHelper): '''Selection to DAE''' bl_idname = "export_scene.dae" @@ -74,7 +69,8 @@ class ExportDAE(bpy.types.Operator, ExportHelper): use_export_selected = BoolProperty( name="Selected Objects", - description="Export only selected objects (and visible in active layers if that applies).", + description="Export only selected objects (and visible in active " + "layers if that applies).", default=False, ) use_mesh_modifiers = BoolProperty( @@ -84,7 +80,8 @@ class ExportDAE(bpy.types.Operator, ExportHelper): ) use_tangent_arrays = BoolProperty( name="Tangent Arrays", - description="Export Tangent and Binormal arrays (for normalmapping).", + description="Export Tangent and Binormal arrays " + "(for normalmapping).", default=False, ) use_triangles = BoolProperty( @@ -92,6 +89,7 @@ class ExportDAE(bpy.types.Operator, ExportHelper): description="Export Triangles instead of Polygons.", default=False, ) + use_copy_images = BoolProperty( name="Copy Images", description="Copy Images (create images/ subfolder)", @@ -109,12 +107,14 @@ class ExportDAE(bpy.types.Operator, ExportHelper): ) use_anim_action_all = BoolProperty( name="All Actions", - description=("Export all actions for the first armature found in separate DAE files"), + description=("Export all actions for the first armature found " + "in separate DAE files"), default=False, ) use_anim_skip_noexp = BoolProperty( name="Skip (-noexp) Actions", - description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.", + description="Skip exporting of actions whose name end in (-noexp)." + " Useful to skip control animations.", default=True, ) use_anim_optimize = BoolProperty( @@ -140,7 +140,8 @@ class ExportDAE(bpy.types.Operator, ExportHelper): @property def check_extension(self): - return True # return self.batch_mode == 'OFF' + # return self.batch_mode == 'OFF' + return True def check(self, context): return True diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 0b90a60eb8..9f8458c0da 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -46,101 +46,105 @@ import bpy import bmesh from mathutils import Vector, Matrix -# according to collada spec, order matters -S_ASSET=0 -S_IMGS=1 -S_FX=2 -S_MATS=3 -S_GEOM=4 -S_MORPH=5 -S_SKIN=6 -S_CONT=7 -S_CAMS=8 -S_LAMPS=9 -S_ANIM_CLIPS=10 -S_NODES=11 -S_ANIM=12 - -CMP_EPSILON=0.0001 +# According to collada spec, order matters +S_ASSET = 0 +S_IMGS = 1 +S_FX = 2 +S_MATS = 3 +S_GEOM = 4 +S_MORPH = 5 +S_SKIN = 6 +S_CONT = 7 +S_CAMS = 8 +S_LAMPS = 9 +S_ANIM_CLIPS = 10 +S_NODES = 11 +S_ANIM = 12 + +CMP_EPSILON = 0.0001 + def snap_tup(tup): - ret=() + ret = () for x in tup: - ret+=( x-math.fmod(x, 0.0001), ) + ret += (x - math.fmod(x, 0.0001), ) return tup def strmtx(mtx): - s=" " + s = " " for x in range(4): for y in range(4): - s+=str(mtx[x][y]) - s+=" " - s+=" " + s += str(mtx[x][y]) + s += " " + s += " " return s + def numarr(a, mult=1.0): - s=" " + s = " " for x in a: - s+=" "+str(x*mult) - s+=" " + s += " " + str(x * mult) + s += " " return s def numarr_alpha(a, mult=1.0): - s=" " + s = " " for x in a: - s+=" "+str(x*mult) + s += " " + str(x * mult) if len(a) == 3: - s+=" 1.0" - s+=" " + s += " 1.0" + s += " " return s def strarr(arr): - s=" " + s = " " for x in arr: - s+=" "+str(x) - s+=" " + s += " " + str(x) + s += " " return s class DaeExporter: def validate_id(self, d): - if (d.find("id-")==0): - return "z"+d + if (d.find("id-") == 0): + return "z" + d return d def new_id(self, t): - self.last_id+=1 - return "id-"+t+"-"+str(self.last_id) + self.last_id += 1 + return "id-" + t + "-" + str(self.last_id) class Vertex: - def close_to(v): - if ( (self.vertex-v.vertex).length() > CMP_EPSILON ): + def close_to(self, v): + if self.vertex - v.vertex.length() > CMP_EPSILON: return False - if ( (self.normal-v.normal).length() > CMP_EPSILON ): + if self.normal - v.normal.length() > CMP_EPSILON: return False - if ( (self.uv-v.uv).length() > CMP_EPSILON ): + if self.uv - v.uv.length() > CMP_EPSILON: return False - if ( (self.uv2-v.uv2).length() > CMP_EPSILON ): + if self.uv2 - v.uv2.length() > CMP_EPSILON: return False return True def get_tup(self): - tup = (self.vertex.x, self.vertex.y, self.vertex.z, self.normal.x, self.normal.y, self.normal.z) + tup = (self.vertex.x, self.vertex.y, self.vertex.z, self.normal.x, + self.normal.y, self.normal.z) for t in self.uv: tup = tup + (t.x, t.y) - if (self.color!=None): + if self.color is not None: tup = tup + (self.color.x, self.color.y, self.color.z) - if (self.tangent!=None): + if self.tangent is not None: tup = tup + (self.tangent.x, self.tangent.y, self.tangent.z) - if (self.bitangent!=None): - tup = tup + (self.bitangent.x, self.bitangent.y, self.bitangent.z) + if self.bitangent is not None: + tup = tup + (self.bitangent.x, self.bitangent.y, + self.bitangent.z) for t in self.bones: tup = tup + (float(t), ) for t in self.weights: @@ -149,23 +153,23 @@ class DaeExporter: return tup def __init__(self): - self.vertex = Vector( (0.0, 0.0, 0.0) ) - self.normal = Vector( (0.0, 0.0, 0.0) ) + self.vertex = Vector((0.0, 0.0, 0.0)) + self.normal = Vector((0.0, 0.0, 0.0)) self.tangent = None self.bitangent = None self.color = None self.uv = [] - self.uv2 = Vector( (0.0, 0.0) ) - self.bones=[] - self.weights=[] + self.uv2 = Vector((0.0, 0.0)) + self.bones = [] + self.weights = [] def writel(self, section, indent, text): if (not (section in self.sections)): - self.sections[section]=[] - line="" + self.sections[section] = [] + line = "" for x in range(indent): - line+="\t" - line+=text + line += "\t" + line += text self.sections[section].append(line) def export_image(self, image): @@ -173,62 +177,72 @@ class DaeExporter: return self.image_cache[image] imgpath = image.filepath - if (imgpath.find("//")==0 or imgpath.find("\\\\")==0): - #if relative, convert to absolute + if (imgpath.find("//") == 0 or imgpath.find("\\\\") == 0): + # If relative, convert to absolute imgpath = bpy.path.abspath(imgpath) - #path is absolute, now do something! + # Path is absolute, now do something! + if (self.config["use_copy_images"]): - #copy image - basedir = os.path.dirname(self.path)+"/images" + # copy image + basedir = os.path.dirname(self.path) + "/images" if (not os.path.isdir(basedir)): os.makedirs(basedir) if os.path.isfile(imgpath): - dstfile=basedir+"/"+os.path.basename(imgpath) + dstfile = basedir + "/" + os.path.basename(imgpath) - if (not os.path.isfile(dstfile)): + if not os.path.isfile(dstfile): shutil.copy(imgpath, dstfile) - imgpath="images/"+os.path.basename(imgpath) + imgpath = "images/" + os.path.basename(imgpath) else: - ### if file is not found save it as png file in the destination folder + # If file is not found save it as png file in the destination + # folder img_tmp_path = image.filepath - if img_tmp_path.endswith((".bmp", ".rgb", ".png", ".jpeg", ".jpg", ".jp2", ".tga", ".cin", ".dpx", ".exr", ".hdr", ".tif")): - image.filepath = basedir+"/"+os.path.basename(img_tmp_path) + if img_tmp_path.endswith((".bmp", ".rgb", ".png", ".jpeg", + ".jpg", ".jp2", ".tga", ".cin", + ".dpx", ".exr", ".hdr", ".tif")): + image.filepath = basedir + "/" + \ + os.path.basename(img_tmp_path) else: - image.filepath = basedir+"/"+image.name+".png" - - dstfile=basedir+"/"+os.path.basename(image.filepath) + image.filepath = basedir + "/" + image.name + ".png" - if (not os.path.isfile(dstfile)): + dstfile = basedir + "/" + os.path.basename(image.filepath) + if not os.path.isfile(dstfile): image.save() - imgpath="images/"+os.path.basename(image.filepath) + imgpath = "images/" + os.path.basename(image.filepath) image.filepath = img_tmp_path else: - #export relative, always, no one wants absolute paths. + # Export relative, always, no one wants absolute paths. try: - imgpath = os.path.relpath(imgpath, os.path.dirname(self.path)).replace("\\", "/") # export unix compatible always + # Export unix compatible always + imgpath = os.path.relpath( + imgpath, os.path.dirname(self.path)).replace("\\", "/") except: - pass #fails sometimes, not sure why + # Fails sometimes, not sure why + pass imgid = self.new_id("image") - print("FOR: "+imgpath) + print("FOR: " + imgpath) # if (not os.path.isfile(imgpath)): # print("NOT FILE?") -# if imgpath.endswith((".bmp", ".rgb", ".png", ".jpeg", ".jpg", ".jp2", ".tga", ".cin", ".dpx", ".exr", ".hdr", ".tif")): +# if imgpath.endswith((".bmp", ".rgb", ".png", ".jpeg", ".jpg", +# ".jp2", ".tga", ".cin", ".dpx", ".exr", +# ".hdr", ".tif")): # imgpath="images/"+os.path.basename(imgpath) # else: # imgpath="images/"+image.name+".png" - self.writel(S_IMGS, 1, '') - self.writel(S_IMGS, 2, ''+imgpath+'') + self.writel(S_IMGS, 1, '') + self.writel(S_IMGS, 2, '' + imgpath + '') self.writel(S_IMGS, 1, '') - self.image_cache[image]=imgid + self.image_cache[image] = imgid return imgid def export_material(self, material, double_sided_hint=True): @@ -236,117 +250,136 @@ class DaeExporter: return self.material_cache[material] fxid = self.new_id("fx") - self.writel(S_FX, 1, '') + self.writel(S_FX, 1, '') self.writel(S_FX, 2, '') - #Find and fetch the textures and create sources - sampler_table={} - diffuse_tex=None - specular_tex=None - emission_tex=None - normal_tex=None + # Find and fetch the textures and create sources + sampler_table = {} + diffuse_tex = None + specular_tex = None + emission_tex = None + normal_tex = None for i in range(len(material.texture_slots)): - ts=material.texture_slots[i] - if (not ts): + ts = material.texture_slots[i] + if not ts: continue - if (not ts.use): + if not ts.use: continue - if (not ts.texture): + if not ts.texture: continue - if (ts.texture.type!="IMAGE"): + if ts.texture.type != "IMAGE": continue - if (ts.texture.image==None): + if ts.texture.image is None: continue - #image + # Image imgid = self.export_image(ts.texture.image) - #surface + # Surface surface_sid = self.new_id("fx_surf") - self.writel(S_FX, 3, '') + self.writel(S_FX, 3, '') self.writel(S_FX, 4, '') - self.writel(S_FX, 5, ''+imgid+'') #this is sooo weird + # This is sooo weird + self.writel(S_FX, 5, '' + imgid + '') self.writel(S_FX, 5, 'A8R8G8B8') self.writel(S_FX, 4, '') self.writel(S_FX, 3, '') - #sampler, collada sure likes it difficult + # Sampler, collada sure likes it difficult sampler_sid = self.new_id("fx_sampler") - self.writel(S_FX, 3, '') + self.writel(S_FX, 3, '') self.writel(S_FX, 4, '') - self.writel(S_FX, 5, ''+surface_sid+'') + self.writel(S_FX, 5, '' + surface_sid + '') self.writel(S_FX, 4, '') self.writel(S_FX, 3, '') - sampler_table[i]=sampler_sid + sampler_table[i] = sampler_sid - if (ts.use_map_color_diffuse and diffuse_tex==None): - diffuse_tex=sampler_sid - if (ts.use_map_color_spec and specular_tex==None): - specular_tex=sampler_sid - if (ts.use_map_emit and emission_tex==None): - emission_tex=sampler_sid - if (ts.use_map_normal and normal_tex==None): - normal_tex=sampler_sid + if ts.use_map_color_diffuse and diffuse_tex is None: + diffuse_tex = sampler_sid + if ts.use_map_color_spec and specular_tex is None: + specular_tex = sampler_sid + if ts.use_map_emit and emission_tex is None: + emission_tex = sampler_sid + if ts.use_map_normal and normal_tex is None: + normal_tex = sampler_sid self.writel(S_FX, 3, '') - shtype="blinn" - self.writel(S_FX, 4, '<'+shtype+'>') - #ambient? from where? + shtype = "blinn" + self.writel(S_FX, 4, '<' + shtype + '>') + # Ambient? from where? self.writel(S_FX, 5, '') - if (emission_tex!=None): - self.writel(S_FX, 6, '') + if emission_tex is not None: + self.writel(S_FX, 6, '') else: - self.writel(S_FX, 6, ''+numarr_alpha(material.diffuse_color, material.emit)+' ') # not totally right but good enough + self.writel(S_FX, 6, '' + + numarr_alpha(material.diffuse_color, material.emit) + + ' ') # not totally right but good enough self.writel(S_FX, 5, '') self.writel(S_FX, 5, '') - self.writel(S_FX, 6, ''+numarr_alpha(self.scene.world.ambient_color, material.ambient)+' ') + self.writel(S_FX, 6, '' + + numarr_alpha(self.scene.world.ambient_color, + material.ambient) + ' ') self.writel(S_FX, 5, '') self.writel(S_FX, 5, '') - if (diffuse_tex!=None): - self.writel(S_FX, 6, '') + if diffuse_tex is not None: + self.writel(S_FX, 6, '') else: - self.writel(S_FX, 6, ''+numarr_alpha(material.diffuse_color, material.diffuse_intensity)+'') + self.writel(S_FX, 6, + '' + numarr_alpha(material.diffuse_color, + material.diffuse_intensity) + + '') self.writel(S_FX, 5, '') self.writel(S_FX, 5, '') - if (specular_tex!=None): - self.writel(S_FX, 6, '') + if specular_tex is not None: + self.writel(S_FX, 6, '') else: - self.writel(S_FX, 6, ''+numarr_alpha(material.specular_color, material.specular_intensity)+'') + self.writel(S_FX, 6, '' + numarr_alpha( + material.specular_color, material.specular_intensity) + + '') self.writel(S_FX, 5, '') self.writel(S_FX, 5, '') - self.writel(S_FX, 6, ''+str(material.specular_hardness)+'') + self.writel(S_FX, 6, '' + str(material.specular_hardness) + + '') self.writel(S_FX, 5, '') self.writel(S_FX, 5, '') - self.writel(S_FX, 6, ''+numarr_alpha(material.mirror_color)+'') + self.writel(S_FX, 6, '' + numarr_alpha(material.mirror_color) + + '') self.writel(S_FX, 5, '') if (material.use_transparency): self.writel(S_FX, 5, '') - self.writel(S_FX, 6, ''+str(material.alpha)+'') + self.writel(S_FX, 6, '' + str(material.alpha) + '') self.writel(S_FX, 5, '') self.writel(S_FX, 5, '') - self.writel(S_FX, 6, ''+str(material.specular_ior)+'') + self.writel(S_FX, 6, '' + str(material.specular_ior) + + '') self.writel(S_FX, 5, '') - self.writel(S_FX, 4, '') + self.writel(S_FX, 4, '') self.writel(S_FX, 4, '') self.writel(S_FX, 5, '') if (normal_tex): self.writel(S_FX, 6, '') - self.writel(S_FX, 7, '') + self.writel(S_FX, 7, '') self.writel(S_FX, 6, '') self.writel(S_FX, 5, '') self.writel(S_FX, 5, '') - self.writel(S_FX, 6, ''+["0", "1"][double_sided_hint]+"") + self.writel(S_FX, 6, '' + ["0", "1"][double_sided_hint] + + "") self.writel(S_FX, 5, '') if (material.use_shadeless): @@ -364,34 +397,37 @@ class DaeExporter: # Material matid = self.new_id("material") - self.writel(S_MATS, 1, '') - self.writel(S_MATS, 2, '') + self.writel(S_MATS, 1, '') + self.writel(S_MATS, 2, '') self.writel(S_MATS, 1, '') - self.material_cache[material]=matid + self.material_cache[material] = matid return matid - def export_mesh(self, node, armature=None, skeyindex=-1, skel_source=None, custom_name=None): + def export_mesh(self, node, armature=None, skeyindex=-1, skel_source=None, + custom_name=None): mesh = node.data if (node.data in self.mesh_cache): return self.mesh_cache[mesh] - if (skeyindex==-1 and mesh.shape_keys!=None and len(mesh.shape_keys.key_blocks)): - values=[] - morph_targets=[] - md=None + if (skeyindex == -1 and mesh.shape_keys is not None and len( + mesh.shape_keys.key_blocks)): + values = [] + morph_targets = [] + md = None for k in range(0, len(mesh.shape_keys.key_blocks)): shape = node.data.shape_keys.key_blocks[k] - values+=[shape.value] #save value - shape.value=0 + values += [shape.value] # save value + shape.value = 0 mid = self.new_id("morph") for k in range(0, len(mesh.shape_keys.key_blocks)): shape = node.data.shape_keys.key_blocks[k] - node.show_only_shape_key=True + node.show_only_shape_key = True node.active_shape_key_index = k shape.value = 1.0 mesh.update() @@ -405,10 +441,10 @@ class DaeExporter: node.data = v # self.export_node(node, il, shape.name) node.data.update() - if (armature and k==0): - md=self.export_mesh(node, armature, k, mid, shape.name) + if (armature and k == 0): + md = self.export_mesh(node, armature, k, mid, shape.name) else: - md=self.export_mesh(node, None, k, None, shape.name) + md = self.export_mesh(node, None, k, None, shape.name) node.data = p node.data.update() @@ -418,84 +454,103 @@ class DaeExporter: """ shape.value = oldval """ - node.show_only_shape_key=False + node.show_only_shape_key = False node.active_shape_key_index = 0 - self.writel(S_MORPH, 1, '') - #if ("skin_id" in morph_targets[0]): - # self.writel(S_MORPH, 2, '') - #else: - self.writel(S_MORPH, 2, '') - - self.writel(S_MORPH, 3, '') - self.writel(S_MORPH, 4, '') - marr="" - warr="" + self.writel(S_MORPH, 1, '') + # if ("skin_id" in morph_targets[0]): + # self.writel(S_MORPH, 2, '') + # else: + self.writel(S_MORPH, 2, '') + + self.writel(S_MORPH, 3, '') + self.writel(S_MORPH, 4, '') + marr = "" + warr = "" for i in range(len(morph_targets)): - if (i==0): + if (i == 0): continue - elif (i>1): - marr+=" " + elif (i > 1): + marr += " " if ("skin_id" in morph_targets[i]): - marr+=morph_targets[i]["skin_id"] + marr += morph_targets[i]["skin_id"] else: - marr+=morph_targets[i]["id"] + marr += morph_targets[i]["id"] - warr+=" 0" + warr += " 0" self.writel(S_MORPH, 5, marr) self.writel(S_MORPH, 4, '') self.writel(S_MORPH, 4, '') - self.writel(S_MORPH, 5, '') - self.writel(S_MORPH, 6, '') + self.writel(S_MORPH, 5, '') + self.writel( + S_MORPH, 6, '') self.writel(S_MORPH, 5, '') self.writel(S_MORPH, 4, '') self.writel(S_MORPH, 3, '') - self.writel(S_MORPH, 3, '') - self.writel(S_MORPH, 4, '') + self.writel(S_MORPH, 3, '') + self.writel(S_MORPH, 4, '') self.writel(S_MORPH, 5, warr) self.writel(S_MORPH, 4, '') self.writel(S_MORPH, 4, '') - self.writel(S_MORPH, 5, '') - self.writel(S_MORPH, 6, '') + self.writel(S_MORPH, 5, '') + self.writel( + S_MORPH, 6, '') self.writel(S_MORPH, 5, '') self.writel(S_MORPH, 4, '') self.writel(S_MORPH, 3, '') self.writel(S_MORPH, 3, '') - self.writel(S_MORPH, 4, '') - self.writel(S_MORPH, 4, '') + self.writel( + S_MORPH, 4, '') + self.writel( + S_MORPH, 4, '') self.writel(S_MORPH, 3, '') self.writel(S_MORPH, 2, '') self.writel(S_MORPH, 1, '') - if (armature!=None): + if armature is not None: - self.armature_for_morph[node]=armature + self.armature_for_morph[node] = armature - meshdata={} + meshdata = {} if (armature): meshdata = morph_targets[0] - meshdata["morph_id"]=mid + meshdata["morph_id"] = mid else: - meshdata["id"]=morph_targets[0]["id"] - meshdata["morph_id"]=mid - meshdata["material_assign"]=morph_targets[0]["material_assign"] + meshdata["id"] = morph_targets[0]["id"] + meshdata["morph_id"] = mid + meshdata["material_assign"] = morph_targets[ + 0]["material_assign"] - self.mesh_cache[node.data]=meshdata + self.mesh_cache[node.data] = meshdata return meshdata - apply_modifiers = len(node.modifiers) and self.config["use_mesh_modifiers"] + apply_modifiers = len(node.modifiers) and self.config[ + "use_mesh_modifiers"] name_to_use = mesh.name - #print("name to use: "+mesh.name) - if (custom_name!=None and custom_name!=""): - name_to_use=custom_name + # print("name to use: "+mesh.name) + if (custom_name is not None and custom_name != ""): + name_to_use = custom_name - mesh=node.to_mesh(self.scene, apply_modifiers, "RENDER") #is this allright? + mesh = node.to_mesh(self.scene, apply_modifiers, + "RENDER") # is this allright? - triangulate=self.config["use_triangles"] + triangulate = self.config["use_triangles"] if (triangulate): bm = bmesh.new() bm.from_mesh(mesh) @@ -504,60 +559,66 @@ class DaeExporter: bm.free() mesh.update(calc_tessface=True) - vertices=[] - vertex_map={} - surface_indices={} - materials={} - - materials={} - - si=None - if (armature!=None): - si=self.skeleton_info[armature] - - has_uv=False - has_uv2=False - has_weights=armature!=None - has_tangents=self.config["use_tangent_arrays"] # could detect.. - has_colors=len(mesh.vertex_colors) - mat_assign=[] - - uv_layer_count=len(mesh.uv_textures) - if (has_tangents and len(mesh.uv_textures)): + vertices = [] + vertex_map = {} + surface_indices = {} + materials = {} + + materials = {} + + si = None + if armature is not None: + si = self.skeleton_info[armature] + + has_uv = False + has_uv2 = False + has_weights = armature is not None + has_tangents = self.config["use_tangent_arrays"] # could detect.. + has_colors = len(mesh.vertex_colors) + mat_assign = [] + + uv_layer_count = len(mesh.uv_textures) + if has_tangents and len(mesh.uv_textures): try: mesh.calc_tangents() except: - self.operator.report({'WARNING'}, 'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.') - #uv_layer_count=0 + self.operator.report( + {'WARNING'}, 'CalcTangets failed for mesh "' + mesh.name + + '", no tangets will be exported.') + # uv_layer_count=0 mesh.calc_normals_split() - has_tangents=False + has_tangents = False else: mesh.calc_normals_split() - has_tangents=False + has_tangents = False for fi in range(len(mesh.polygons)): - f=mesh.polygons[fi] + f = mesh.polygons[fi] - if (not (f.material_index in surface_indices)): - surface_indices[f.material_index]=[] - #print("Type: "+str(type(f.material_index))) - #print("IDX: "+str(f.material_index)+"/"+str(len(mesh.materials))) + if not (f.material_index in surface_indices): + surface_indices[f.material_index] = [] + # print("Type: " + str(type(f.material_index))) + # print("IDX: " + str(f.material_index) + "/" + str( + # len(mesh.materials))) try: - #Bizarre blender behavior i don't understand, so catching exception + # Bizarre blender behavior i don't understand, + # so catching exception mat = mesh.materials[f.material_index] except: - mat= None + mat = None - if (mat!=None): - materials[f.material_index]=self.export_material( mat, mesh.show_double_sided ) + if (mat is not None): + materials[f.material_index] = self.export_material( + mat, mesh.show_double_sided) else: - materials[f.material_index]=None #weird, has no material? + # weird, has no material? + materials[f.material_index] = None indices = surface_indices[f.material_index] - vi=[] - #vertices always 3 + vi = [] + # Vertices always 3 """ if (len(f.vertices)==3): vi.append(0) @@ -579,78 +640,92 @@ class DaeExporter: mv = mesh.vertices[ml.vertex_index] v = self.Vertex() - v.vertex = Vector( mv.co ) + v.vertex = Vector(mv.co) for xt in mesh.uv_layers: - v.uv.append( Vector( xt.data[loop_index].uv ) ) + v.uv.append(Vector(xt.data[loop_index].uv)) if (has_colors): - v.color = Vector( mesh.vertex_colors[0].data[loop_index].color ) + v.color = Vector( + mesh.vertex_colors[0].data[loop_index].color) - v.normal = Vector( ml.normal ) + v.normal = Vector(ml.normal) if (has_tangents): - v.tangent = Vector( ml.tangent ) - v.bitangent = Vector( ml.bitangent ) + v.tangent = Vector(ml.tangent) + v.bitangent = Vector(ml.bitangent) - # if (armature): - # v.vertex = node.matrix_world * v.vertex + # if (armature): + # v.vertex = node.matrix_world * v.vertex - #v.color=Vertex(mv. ??? + # v.color=Vertex(mv. ??? - if (armature!=None): - wsum=0.0 - zero_bones=[] + if armature is not None: + wsum = 0.0 + zero_bones = [] for vg in mv.groups: if vg.group >= len(node.vertex_groups): - continue; + continue name = node.vertex_groups[vg.group].name if (name in si["bone_index"]): - #could still put the weight as 0.0001 maybe - if (vg.weight>0.001): #blender has a lot of zero weight stuff + # could still put the weight as 0.0001 maybe + # blender has a lot of zero weight stuff + if (vg.weight > 0.001): v.bones.append(si["bone_index"][name]) v.weights.append(vg.weight) - wsum+=vg.weight - if (wsum==0.0): + wsum += vg.weight + if (wsum == 0.0): if not self.wrongvtx_report: - self.operator.report({'WARNING'}, 'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.') - self.wrongvtx_report=True - - #blender can have bones assigned that weight zero so they remain local - #this is the best it can be done? + self.operator.report( + {'WARNING'}, 'Mesh for object "' + node.name + + '" has unassigned weights. ' + 'This may look wrong in exported model.') + self.wrongvtx_report = True + + # blender can have bones assigned that weight zero + # so they remain local + # this is the best it can be done? v.bones.append(0) v.weights.append(1) tup = v.get_tup() idx = 0 - if (skeyindex==-1 and tup in vertex_map): #do not optmize if using shapekeys + # do not optmize if using shapekeys + if (skeyindex == -1 and tup in vertex_map): idx = vertex_map[tup] else: idx = len(vertices) vertices.append(v) - vertex_map[tup]=idx + vertex_map[tup] = idx vi.append(idx) - if (len(vi)>2): - #only triangles and above + if (len(vi) > 2): + # only triangles and above indices.append(vi) meshid = self.new_id("mesh") - self.writel(S_GEOM, 1, '') + self.writel(S_GEOM, 1, '') self.writel(S_GEOM, 2, '') # Vertex Array - self.writel(S_GEOM, 3, '') - float_values="" + self.writel(S_GEOM, 3, '') + float_values = "" for v in vertices: - float_values+=" "+str(v.vertex.x)+" "+str(v.vertex.y)+" "+str(v.vertex.z) - self.writel(S_GEOM, 4, ''+float_values+'') + float_values += " " + str(v.vertex.x) + " " + \ + str(v.vertex.y) + " " + str(v.vertex.z) + self.writel(S_GEOM, 4, '' + float_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') @@ -660,13 +735,19 @@ class DaeExporter: # Normal Array - self.writel(S_GEOM, 3, '') - float_values="" + self.writel(S_GEOM, 3, '') + float_values = "" for v in vertices: - float_values+=" "+str(v.normal.x)+" "+str(v.normal.y)+" "+str(v.normal.z) - self.writel(S_GEOM, 4, ''+float_values+'') + float_values += " " + str(v.normal.x) + " " + \ + str(v.normal.y) + " " + str(v.normal.z) + self.writel(S_GEOM, 4, '' + float_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') @@ -675,13 +756,20 @@ class DaeExporter: self.writel(S_GEOM, 3, '') if (has_tangents): - self.writel(S_GEOM, 3, '') - float_values="" + self.writel(S_GEOM, 3, '') + float_values = "" for v in vertices: - float_values+=" "+str(v.tangent.x)+" "+str(v.tangent.y)+" "+str(v.tangent.z) - self.writel(S_GEOM, 4, ''+float_values+'') + float_values += " " + \ + str(v.tangent.x) + " " + \ + str(v.tangent.y) + " " + str(v.tangent.z) + self.writel(S_GEOM, 4, '' + float_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') @@ -689,13 +777,20 @@ class DaeExporter: self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 3, '') - self.writel(S_GEOM, 3, '') - float_values="" + self.writel(S_GEOM, 3, '') + float_values = "" for v in vertices: - float_values+=" "+str(v.bitangent.x)+" "+str(v.bitangent.y)+" "+str(v.bitangent.z) - self.writel(S_GEOM, 4, ''+float_values+'') + float_values += " " + \ + str(v.bitangent.x) + " " + \ + str(v.bitangent.y) + " " + str(v.bitangent.z) + self.writel(S_GEOM, 4, '' + float_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') @@ -704,20 +799,30 @@ class DaeExporter: self.writel(S_GEOM, 3, '') # UV Arrays + for uvi in range(uv_layer_count): - self.writel(S_GEOM, 3, '') - float_values="" + self.writel(S_GEOM, 3, '') + float_values = "" for v in vertices: try: - float_values+=" "+str(v.uv[uvi].x)+" "+str(v.uv[uvi].y) + float_values += " " + \ + str(v.uv[uvi].x) + " " + str(v.uv[uvi].y) except: - # I don't understand this weird multi-uv-layer API, but with this it seems to works - float_values+=" 0 0 " - - self.writel(S_GEOM, 4, ''+float_values+'') + # I don't understand this weird multi-uv-layer API, but + # with this it seems to works + float_values += " 0 0 " + + self.writel(S_GEOM, 4, '' + + float_values + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 4, '') @@ -727,13 +832,20 @@ class DaeExporter: # Color Arrays if (has_colors): - self.writel(S_GEOM, 3, '') - float_values="" + self.writel(S_GEOM, 3, '') + float_values = "" for v in vertices: - float_values+=" "+str(v.color.x)+" "+str(v.color.y)+" "+str(v.color.z) - self.writel(S_GEOM, 4, ''+float_values+'') + float_values += " " + \ + str(v.color.x) + " " + \ + str(v.color.y) + " " + str(v.color.z) + self.writel(S_GEOM, 4, '' + float_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') @@ -742,203 +854,257 @@ class DaeExporter: self.writel(S_GEOM, 3, '') # Triangle Lists - self.writel(S_GEOM, 3, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 3, '') + self.writel( + S_GEOM, 4, '') self.writel(S_GEOM, 3, '') - prim_type="" + prim_type = "" if (triangulate): - prim_type="triangles" + prim_type = "triangles" else: - prim_type="polygons" + prim_type = "polygons" for m in surface_indices: indices = surface_indices[m] mat = materials[m] - if (mat!=None): + if (mat is not None): matref = self.new_id("trimat") - self.writel(S_GEOM, 3, '<'+prim_type+' count="'+str(int(len(indices)))+'" material="'+matref+'">') # todo material - mat_assign.append( (mat, matref) ) + self.writel(S_GEOM, 3, '<' + prim_type + ' count="' + str( + int(len(indices))) + '" material="' + matref + + '">') # todo material + mat_assign.append((mat, matref)) else: - self.writel(S_GEOM, 3, '<'+prim_type+' count="'+str(int(len(indices)))+'">') # todo material + self.writel(S_GEOM, 3, '<' + prim_type + ' count="' + + str(int(len(indices))) + '">') # todo material - self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') for uvi in range(uv_layer_count): - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') if (has_colors): - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') if (has_tangents): - self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, + '') + self.writel(S_GEOM, 4, + '') if (triangulate): - int_values="

" + int_values = "

" for p in indices: for i in p: - int_values+=" "+str(i) - int_values+="

" + int_values += " " + str(i) + int_values += "

" self.writel(S_GEOM, 4, int_values) else: for p in indices: - int_values="

" + int_values = "

" for i in p: - int_values+=" "+str(i) - int_values+="

" + int_values += " " + str(i) + int_values += "

" self.writel(S_GEOM, 4, int_values) - self.writel(S_GEOM, 3, '') + self.writel(S_GEOM, 3, '') self.writel(S_GEOM, 2, '
') self.writel(S_GEOM, 1, '
') - meshdata={} - meshdata["id"]=meshid - meshdata["material_assign"]=mat_assign - if (skeyindex==-1): - self.mesh_cache[node.data]=meshdata + meshdata = {} + meshdata["id"] = meshid + meshdata["material_assign"] = mat_assign + if (skeyindex == -1): + self.mesh_cache[node.data] = meshdata # Export armature data (if armature exists) - if (armature!=None and (skel_source!=None or skeyindex==-1)): + + if (armature is not None and ( + skel_source is not None or skeyindex == -1)): contid = self.new_id("controller") - self.writel(S_SKIN, 1, '') - if (skel_source!=None): - self.writel(S_SKIN, 2, '') + self.writel(S_SKIN, 1, '') + if (skel_source is not None): + self.writel(S_SKIN, 2, '') else: - self.writel(S_SKIN, 2, '') + self.writel(S_SKIN, 2, '') - self.writel(S_SKIN, 3, ''+strmtx(node.matrix_world)+'') - #Joint Names - self.writel(S_SKIN, 3, '') - name_values="" + self.writel(S_SKIN, 3, '' + + strmtx(node.matrix_world) + '') + # Joint Names + self.writel(S_SKIN, 3, '') + name_values = "" for v in si["bone_names"]: - name_values+=" "+v + name_values += " " + v - self.writel(S_SKIN, 4, ''+name_values+'') + self.writel(S_SKIN, 4, '' + name_values + + '') self.writel(S_SKIN, 4, '') - self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 5, '') self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 3, '') - #Pose Matrices! - self.writel(S_SKIN, 3, '') - pose_values="" + # Pose Matrices! + self.writel(S_SKIN, 3, '') + pose_values = "" for v in si["bone_bind_poses"]: - pose_values+=" "+strmtx(v) + pose_values += " " + strmtx(v) - self.writel(S_SKIN, 4, ''+pose_values+'') + self.writel(S_SKIN, 4, '' + + pose_values + '') self.writel(S_SKIN, 4, '') - self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 5, '') self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 3, '') - #Skin Weights! - self.writel(S_SKIN, 3, '') - skin_weights="" - skin_weights_total=0 + # Skin Weights! + self.writel(S_SKIN, 3, '') + skin_weights = "" + skin_weights_total = 0 for v in vertices: - skin_weights_total+=len(v.weights) + skin_weights_total += len(v.weights) for w in v.weights: - skin_weights+=" "+str(w) + skin_weights += " " + str(w) - self.writel(S_SKIN, 4, ''+skin_weights+'') + self.writel(S_SKIN, 4, '' + skin_weights + + '') self.writel(S_SKIN, 4, '') - self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 5, '') self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 4, '') self.writel(S_SKIN, 3, '') self.writel(S_SKIN, 3, '') - self.writel(S_SKIN, 4, '') - self.writel(S_SKIN, 4, '') + self.writel( + S_SKIN, 4, '') + self.writel( + S_SKIN, 4, '') self.writel(S_SKIN, 3, '') - self.writel(S_SKIN, 3, '') - self.writel(S_SKIN, 4, '') - self.writel(S_SKIN, 4, '') - vcounts="" - vs="" - vcount=0 + self.writel(S_SKIN, 3, '') + self.writel(S_SKIN, 4, '') + self.writel(S_SKIN, 4, '') + vcounts = "" + vs = "" + vcount = 0 for v in vertices: - vcounts+=" "+str(len(v.weights)) + vcounts += " " + str(len(v.weights)) for b in v.bones: - vs+=" "+str(b) - vs+=" "+str(vcount) - vcount+=1 - self.writel(S_SKIN, 4, ''+vcounts+'') - self.writel(S_SKIN, 4, ''+vs+'') + vs += " " + str(b) + vs += " " + str(vcount) + vcount += 1 + self.writel(S_SKIN, 4, '' + vcounts + '') + self.writel(S_SKIN, 4, '' + vs + '') self.writel(S_SKIN, 3, '') self.writel(S_SKIN, 2, '') self.writel(S_SKIN, 1, '') - meshdata["skin_id"]=contid + meshdata["skin_id"] = contid return meshdata def export_mesh_node(self, node, il): - if (node.data==None): + if (node.data is None): return - armature=None - armcount=0 + armature = None + armcount = 0 for n in node.modifiers: - if (n.type=="ARMATURE"): - armcount+=1 - - if (node.parent!=None): - if (node.parent.type=="ARMATURE"): - armature=node.parent - if (armcount>1): - self.operator.report({'WARNING'}, 'Object "'+node.name+'" refers to more than one armature! This is unsupported.') - if (armcount==0): - self.operator.report({'WARNING'}, 'Object "'+node.name+'" is child of an armature, but has no armature modifier.') - - if (armcount>0 and not armature): - self.operator.report({'WARNING'}, 'Object "'+node.name+'" has armature modifier, but is not a child of an armature. This is unsupported.') - - if (node.data.shape_keys!=None): - sk = node.data.shape_keys - if (sk.animation_data): - #print("HAS ANIM") - #print("DRIVERS: "+str(len(sk.animation_data.drivers))) - for d in sk.animation_data.drivers: - if (d.driver): - for v in d.driver.variables: - for t in v.targets: - if (t.id!=None and t.id.name in self.scene.objects): - #print("LINKING "+str(node)+" WITH "+str(t.id.name)) - self.armature_for_morph[node]=self.scene.objects[t.id.name] + if (n.type == "ARMATURE"): + armcount += 1 + + if (node.parent is not None): + if (node.parent.type == "ARMATURE"): + armature = node.parent + if (armcount > 1): + self.operator.report({'WARNING'}, 'Object "' + node.name + + '" refers to more than one armature! ' + 'This is unsupported.') + if (armcount == 0): + self.operator.report({'WARNING'}, 'Object "' + node.name + + '" is child of an armature, but has ' + 'no armature modifier.') + + if (armcount > 0 and not armature): + self.operator.report({'WARNING'}, 'Object "' + node.name + + '" has armature modifier, but is not a child ' + 'of an armature. This is unsupported.') + + if (node.data.shape_keys is not None): + sk = node.data.shape_keys + if (sk.animation_data): + # print("HAS ANIM") + # print("DRIVERS: "+str(len(sk.animation_data.drivers))) + for d in sk.animation_data.drivers: + if (d.driver): + for v in d.driver.variables: + for t in v.targets: + if (t.id is not None and + t.id.name in self.scene.objects): + # print("LINKING " + str(node) + " WITH " + + # str(t.id.name)) + self.armature_for_morph[ + node] = self.scene.objects[t.id.name] meshdata = self.export_mesh(node, armature) - close_controller=False + close_controller = False if ("skin_id" in meshdata): - close_controller=True - self.writel(S_NODES, il, '') + close_controller = True + self.writel(S_NODES, il, '') for sn in self.skeleton_info[armature]["skeleton_nodes"]: - self.writel(S_NODES, il+1, '#'+sn+'') + self.writel(S_NODES, il + 1, '#' + + sn + '') elif ("morph_id" in meshdata): - self.writel(S_NODES, il, '') - close_controller=True - elif (armature==None): - self.writel(S_NODES, il, '') + self.writel(S_NODES, il, '') + close_controller = True + elif (armature is None): + self.writel(S_NODES, il, '') - if (len(meshdata["material_assign"])>0): + if (len(meshdata["material_assign"]) > 0): - self.writel(S_NODES, il+1, '') - self.writel(S_NODES, il+2, '') + self.writel(S_NODES, il + 1, '') + self.writel(S_NODES, il + 2, '') for m in meshdata["material_assign"]: - self.writel(S_NODES, il+3, '') + self.writel(S_NODES, il + 3, '') - self.writel(S_NODES, il+2, '') - self.writel(S_NODES, il+1, '') + self.writel(S_NODES, il + 2, '') + self.writel(S_NODES, il + 1, '') if (close_controller): self.writel(S_NODES, il, '') @@ -948,143 +1114,179 @@ class DaeExporter: def export_armature_bone(self, bone, il, si): boneid = self.new_id("bone") boneidx = si["bone_count"] - si["bone_count"]+=1 - bonesid = si["id"]+"-"+str(boneidx) + si["bone_count"] += 1 + bonesid = si["id"] + "-" + str(boneidx) if (bone.name in self.used_bones): if (self.config["use_anim_action_all"]): - self.operator.report({'WARNING'}, 'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.') + self.operator.report({'WARNING'}, 'Bone name "' + bone.name + + '" used in more than one skeleton. ' + 'Actions might export wrong.') else: self.used_bones.append(bone.name) - si["bone_index"][bone.name]=boneidx - si["bone_ids"][bone]=boneid + si["bone_index"][bone.name] = boneidx + si["bone_ids"][bone] = boneid si["bone_names"].append(bonesid) - self.writel(S_NODES, il, '') - il+=1 + self.writel(S_NODES, il, '') + il += 1 xform = bone.matrix_local si["bone_bind_poses"].append((si["armature_xform"] * xform).inverted()) - if (bone.parent!=None): + if (bone.parent is not None): xform = bone.parent.matrix_local.inverted() * xform else: si["skeleton_nodes"].append(boneid) - self.writel(S_NODES, il, ''+strmtx(xform)+'') + self.writel(S_NODES, il, '' + + strmtx(xform) + '') for c in bone.children: self.export_armature_bone(c, il, si) - il-=1 + il -= 1 self.writel(S_NODES, il, '') def export_armature_node(self, node, il): - if (node.data==None): + if (node.data is None): return self.skeletons.append(node) armature = node.data - self.skeleton_info[node]={ "bone_count":0, "id":self.new_id("skelbones"), "name":node.name, "bone_index":{}, "bone_ids":{}, "bone_names":[], "bone_bind_poses":[], "skeleton_nodes":[], "armature_xform":node.matrix_world } + self.skeleton_info[node] = { + "bone_count": 0, + "id": self.new_id("skelbones"), + "name": node.name, "bone_index": {}, + "bone_ids": {}, "bone_names": [], "bone_bind_poses": [], + "skeleton_nodes": [], + "armature_xform": node.matrix_world} for b in armature.bones: - if (b.parent!=None): + if (b.parent is not None): continue self.export_armature_bone(b, il, self.skeleton_info[node]) if (node.pose): for b in node.pose.bones: for x in b.constraints: - if (x.type=='ACTION'): + if (x.type == 'ACTION'): self.action_constraints.append(x.action) def export_camera_node(self, node, il): - if (node.data==None): + if (node.data is None): return - camera=node.data - camid=self.new_id("camera") - self.writel(S_CAMS, 1, '') + camera = node.data + camid = self.new_id("camera") + self.writel(S_CAMS, 1, '') self.writel(S_CAMS, 2, '') self.writel(S_CAMS, 3, '') - if (camera.type=="PERSP"): + if (camera.type == "PERSP"): self.writel(S_CAMS, 4, '') - self.writel(S_CAMS, 5, ' '+str(math.degrees(camera.angle))+' ') # I think? - self.writel(S_CAMS, 5, ' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') - self.writel(S_CAMS, 5, ' '+str(camera.clip_start)+' ') - self.writel(S_CAMS, 5, ' '+str(camera.clip_end)+' ') + self.writel(S_CAMS, 5, ' ' + + # I think? + str(math.degrees(camera.angle)) + ' ') + self.writel(S_CAMS, 5, ' ' + + str(self.scene.render.resolution_x / + self.scene.render.resolution_y) + + ' ') + self.writel(S_CAMS, 5, ' ' + + str(camera.clip_start) + ' ') + self.writel(S_CAMS, 5, ' ' + + str(camera.clip_end) + ' ') self.writel(S_CAMS, 4, '') else: self.writel(S_CAMS, 4, '') - self.writel(S_CAMS, 5, ' '+str(camera.ortho_scale*0.5)+' ') # I think? - self.writel(S_CAMS, 5, ' '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' ') - self.writel(S_CAMS, 5, ' '+str(camera.clip_start)+' ') - self.writel(S_CAMS, 5, ' '+str(camera.clip_end)+' ') + self.writel(S_CAMS, 5, ' ' + + str(camera.ortho_scale * 0.5) + ' ') # I think? + self.writel(S_CAMS, 5, ' ' + str( + self.scene.render.resolution_x / + self.scene.render.resolution_y) + ' ') + self.writel(S_CAMS, 5, ' ' + + str(camera.clip_start) + ' ') + self.writel(S_CAMS, 5, ' ' + + str(camera.clip_end) + ' ') self.writel(S_CAMS, 4, '') self.writel(S_CAMS, 3, '') self.writel(S_CAMS, 2, '') self.writel(S_CAMS, 1, '') - self.writel(S_NODES, il, '') + self.writel(S_NODES, il, '') def export_lamp_node(self, node, il): - if (node.data==None): + if (node.data is None): return - light=node.data - lightid=self.new_id("light") - self.writel(S_LAMPS, 1, '') - #self.writel(S_LAMPS, 2, '') + light = node.data + lightid = self.new_id("light") + self.writel(S_LAMPS, 1, '') + # self.writel(S_LAMPS, 2, '') self.writel(S_LAMPS, 3, '') - if (light.type=="POINT"): + if (light.type == "POINT"): self.writel(S_LAMPS, 4, '') - self.writel(S_LAMPS, 5, ''+strarr(light.color)+'') - att_by_distance = 2.0 / light.distance # convert to linear attenuation - self.writel(S_LAMPS, 5, ''+str(att_by_distance)+'') + self.writel(S_LAMPS, 5, '' + + strarr(light.color) + '') + # convert to linear attenuation + att_by_distance = 2.0 / light.distance + self.writel(S_LAMPS, 5, '' + + str(att_by_distance) + '') if (light.use_sphere): - self.writel(S_LAMPS, 5, ''+str(light.distance)+'') + self.writel(S_LAMPS, 5, '' + + str(light.distance) + '') self.writel(S_LAMPS, 4, '') - elif (light.type=="SPOT"): + elif (light.type == "SPOT"): self.writel(S_LAMPS, 4, '') - self.writel(S_LAMPS, 5, ''+strarr(light.color)+'') - att_by_distance = 2.0 / light.distance # convert to linear attenuation - self.writel(S_LAMPS, 5, ''+str(att_by_distance)+'') - self.writel(S_LAMPS, 5, ''+str(math.degrees(light.spot_size/2))+'') + self.writel(S_LAMPS, 5, '' + + strarr(light.color) + '') + # convert to linear attenuation + att_by_distance = 2.0 / light.distance + self.writel(S_LAMPS, 5, '' + + str(att_by_distance) + '') + self.writel(S_LAMPS, 5, '' + + str(math.degrees(light.spot_size / 2)) + + '') self.writel(S_LAMPS, 4, '') - else: #write a sun lamp for everything else (not supported) + else: # write a sun lamp for everything else (not supported) self.writel(S_LAMPS, 4, '') - self.writel(S_LAMPS, 5, ''+strarr(light.color)+'') + self.writel(S_LAMPS, 5, '' + + strarr(light.color) + '') self.writel(S_LAMPS, 4, '') self.writel(S_LAMPS, 3, '') - #self.writel(S_LAMPS, 2, '') + # self.writel(S_LAMPS, 2, '') self.writel(S_LAMPS, 1, '') - self.writel(S_NODES, il, '') + self.writel(S_NODES, il, '') def export_empty_node(self, node, il): self.writel(S_NODES, 4, '') self.writel(S_NODES, 5, '') - self.writel(S_NODES, 6, ''+node.empty_draw_type+'') + self.writel(S_NODES, 6, '' + + node.empty_draw_type + '') self.writel(S_NODES, 5, '') self.writel(S_NODES, 4, '') def export_curve(self, curve): splineid = self.new_id("spline") - self.writel(S_GEOM, 1, '') + self.writel(S_GEOM, 1, '') self.writel(S_GEOM, 2, '') - points=[] - interps=[] - handles_in=[] - handles_out=[] - tilts=[] + points = [] + interps = [] + handles_in = [] + handles_out = [] + tilts = [] for cs in curve.splines: - if (cs.type=="BEZIER"): + if (cs.type == "BEZIER"): for s in cs.bezier_points: points.append(s.co[0]) points.append(s.co[1]) @@ -1115,73 +1317,103 @@ class DaeExporter: tilts.append(s.tilt) interps.append("LINEAR") - self.writel(S_GEOM, 3, '') - position_values="" + self.writel(S_GEOM, 3, '') + position_values = "" for x in points: - position_values+=" "+str(x) - self.writel(S_GEOM, 4, ''+position_values+'') + position_values += " " + str(x) + self.writel(S_GEOM, 4, '' + position_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 3, '') - self.writel(S_GEOM, 3, '') - intangent_values="" + self.writel(S_GEOM, 3, '') + intangent_values = "" for x in handles_in: - intangent_values+=" "+str(x) - self.writel(S_GEOM, 4, ''+intangent_values+'') + intangent_values += " " + str(x) + self.writel(S_GEOM, 4, '' + intangent_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 3, '') - self.writel(S_GEOM, 3, '') - outtangent_values="" + self.writel(S_GEOM, 3, '') + outtangent_values = "" for x in handles_out: - outtangent_values+=" "+str(x) - self.writel(S_GEOM, 4, ''+outtangent_values+'') + outtangent_values += " " + str(x) + self.writel(S_GEOM, 4, '' + outtangent_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 3, '') - self.writel(S_GEOM, 3, '') - interpolation_values="" + self.writel(S_GEOM, 3, '') + interpolation_values = "" for x in interps: - interpolation_values+=" "+x - self.writel(S_GEOM, 4, ''+interpolation_values+'') + interpolation_values += " " + x + self.writel(S_GEOM, 4, '' + interpolation_values + + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 3, '') - self.writel(S_GEOM, 3, '') - tilt_values="" + self.writel(S_GEOM, 3, '') + tilt_values = "" for x in tilts: - tilt_values+=" "+str(x) - self.writel(S_GEOM, 4, ''+tilt_values+'') + tilt_values += " " + str(x) + self.writel(S_GEOM, 4, '' + tilt_values + '') self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 5, '') self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 3, '') self.writel(S_GEOM, 3, '') - self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') - self.writel(S_GEOM, 4, '') + self.writel( + S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') + self.writel(S_GEOM, 4, '') self.writel(S_GEOM, 3, '') self.writel(S_GEOM, 2, '') @@ -1190,56 +1422,59 @@ class DaeExporter: return splineid def export_curve_node(self, node, il): - if (node.data==None): + if (node.data is None): return curveid = self.export_curve(node.data) - self.writel(S_NODES, il, '') + self.writel(S_NODES, il, '') self.writel(S_NODES, il, '') def export_node(self, node, il): - if (not node in self.valid_nodes): + if (node not in self.valid_nodes): return prev_node = bpy.context.scene.objects.active bpy.context.scene.objects.active = node - self.writel(S_NODES, il, '') - il+=1 + self.writel(S_NODES, il, '') + il += 1 - self.writel(S_NODES, il, ''+strmtx(node.matrix_local)+'') - #print("NODE TYPE: "+node.type+" NAME: "+node.name) - if (node.type=="MESH"): + self.writel(S_NODES, il, '' + + strmtx(node.matrix_local) + '') + # print("NODE TYPE: "+node.type+" NAME: "+node.name) + if (node.type == "MESH"): self.export_mesh_node(node, il) - elif (node.type=="CURVE"): + elif (node.type == "CURVE"): self.export_curve_node(node, il) - elif (node.type=="ARMATURE"): + elif (node.type == "ARMATURE"): self.export_armature_node(node, il) - elif (node.type=="CAMERA"): + elif (node.type == "CAMERA"): self.export_camera_node(node, il) - elif (node.type=="LAMP"): + elif (node.type == "LAMP"): self.export_lamp_node(node, il) - elif (node.type=="EMPTY"): + elif (node.type == "EMPTY"): self.export_empty_node(node, il) for x in node.children: self.export_node(x, il) - il-=1 + il -= 1 self.writel(S_NODES, il, '') - bpy.context.scene.objects.active = prev_node #make previous node active again + # make previous node active again + bpy.context.scene.objects.active = prev_node def is_node_valid(self, node): - if (not node.type in self.config["object_types"]): + if (node.type not in self.config["object_types"]): return False if (self.config["use_active_layers"]): - valid=False + valid = False # print("NAME: "+node.name) for i in range(20): - if (node.layers[i] and self.scene.layers[i]): - valid=True + if (node.layers[i] and self.scene.layers[i]): + valid = True break if (not valid): return False @@ -1251,7 +1486,8 @@ class DaeExporter: def export_scene(self): self.writel(S_NODES, 0, '') - self.writel(S_NODES, 1, '') + self.writel(S_NODES, 1, '') # validate nodes for obj in self.scene.objects: @@ -1259,13 +1495,13 @@ class DaeExporter: continue if (self.is_node_valid(obj)): n = obj - while (n!=None): - if (not n in self.valid_nodes): + while (n is not None): + if (n not in self.valid_nodes): self.valid_nodes.append(n) - n=n.parent + n = n.parent for obj in self.scene.objects: - if (obj in self.valid_nodes and obj.parent==None): + if (obj in self.valid_nodes and obj.parent is None): self.export_node(obj, 2) self.writel(S_NODES, 1, '') @@ -1275,37 +1511,47 @@ class DaeExporter: self.writel(S_ASSET, 0, '') # Why is this time stuff mandatory?, no one could care less... self.writel(S_ASSET, 1, '') - self.writel(S_ASSET, 2, ' Anonymous ') #Who made Collada, the FBI ? - self.writel(S_ASSET, 2, ' Collada Exporter for Blender 2.6+, by Juan Linietsky (juan@codenix.com) ') #Who made Collada, the FBI ? + # Who made Collada, the FBI ? + self.writel(S_ASSET, 2, ' Anonymous ') + # Who made Collada, the FBI ? + self.writel( + S_ASSET, 2, ' Collada Exporter for Blender 2.6+, ' + 'by Juan Linietsky (juan@codenix.com) ') self.writel(S_ASSET, 1, '') - self.writel(S_ASSET, 1, ''+time.strftime("%Y-%m-%dT%H:%M:%SZ ")+'') - self.writel(S_ASSET, 1, ''+time.strftime("%Y-%m-%dT%H:%M:%SZ")+'') + self.writel(S_ASSET, 1, '' + + time.strftime("%Y-%m-%dT%H:%M:%SZ ") + '') + self.writel(S_ASSET, 1, '' + + time.strftime("%Y-%m-%dT%H:%M:%SZ") + '') self.writel(S_ASSET, 1, '') self.writel(S_ASSET, 1, 'Z_UP') self.writel(S_ASSET, 0, '') def export_animation_transform_channel(self, target, keys, matrices=True): - frame_total=len(keys) - anim_id=self.new_id("anim") - self.writel(S_ANIM, 1, '') + frame_total = len(keys) + anim_id = self.new_id("anim") + self.writel(S_ANIM, 1, '') source_frames = "" source_transforms = "" source_interps = "" for k in keys: - source_frames += " "+str(k[0]) + source_frames += " " + str(k[0]) if (matrices): - source_transforms += " "+strmtx(k[1]) + source_transforms += " " + strmtx(k[1]) else: - source_transforms += " "+str(k[1]) + source_transforms += " " + str(k[1]) - source_interps +=" LINEAR" + source_interps += " LINEAR" # Time Source - self.writel(S_ANIM, 2, '') - self.writel(S_ANIM, 3, ''+source_frames+'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, '' + source_frames + '') self.writel(S_ANIM, 3, '') - self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 5, '') self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 3, '') @@ -1313,44 +1559,66 @@ class DaeExporter: if (matrices): # Transform Source - self.writel(S_ANIM, 2, '') - self.writel(S_ANIM, 3, ''+source_transforms+'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, '' + source_transforms + + '') self.writel(S_ANIM, 3, '') - self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 5, '') self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 3, '') self.writel(S_ANIM, 2, '') else: # Value Source - self.writel(S_ANIM, 2, '') - self.writel(S_ANIM, 3, ''+source_transforms+'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, '' + source_transforms + + '') self.writel(S_ANIM, 3, '') - self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 5, '') self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 3, '') self.writel(S_ANIM, 2, '') # Interpolation Source - self.writel(S_ANIM, 2, '') - self.writel(S_ANIM, 3, ''+source_interps+'') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, '' + source_interps + '') self.writel(S_ANIM, 3, '') - self.writel(S_ANIM, 4, '') + self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 5, '') self.writel(S_ANIM, 4, '') self.writel(S_ANIM, 3, '') self.writel(S_ANIM, 2, '') - self.writel(S_ANIM, 2, '') - self.writel(S_ANIM, 3, '') - self.writel(S_ANIM, 3, '') - self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 3, '') + self.writel(S_ANIM, 3, '') self.writel(S_ANIM, 2, '') if (matrices): - self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 2, '') else: - self.writel(S_ANIM, 2, '') + self.writel(S_ANIM, 2, '') self.writel(S_ANIM, 1, '') return [anim_id] @@ -1365,95 +1633,111 @@ class DaeExporter: frame_len = 1.0 / self.scene.render.fps frame_total = end - start + 1 frame_sub = 0 - if (start>0): - frame_sub=start*frame_len + if (start > 0): + frame_sub = start * frame_len tcn = [] - xform_cache={} - blend_cache={} + xform_cache = {} + blend_cache = {} # Change frames first, export objects last # This improves performance enormously - #print("anim from: "+str(start)+" to "+str(end)+" allowed: "+str(allowed)) - for t in range(start, end+1): + # print("anim from: " + str(start) + " to " + str(end) + " allowed: " + + # str(allowed)) + for t in range(start, end + 1): self.scene.frame_set(t) key = t * frame_len - frame_sub # print("Export Anim Frame "+str(t)+"/"+str(self.scene.frame_end+1)) for node in self.scene.objects: - if (not node in self.valid_nodes): + if (node not in self.valid_nodes): continue - if (allowed!=None and not (node in allowed)): - if (node.type=="MESH" and node.data!=None and (node in self.armature_for_morph) and (self.armature_for_morph[node] in allowed)): - pass #all good you pass with flying colors for morphs inside of action + if (allowed is not None and not (node in allowed)): + if (node.type == "MESH" and node.data is not None and + (node in self.armature_for_morph) and ( + self.armature_for_morph[node] in allowed)): + # all good you pass with flying colors for morphs + # inside of action + pass else: - #print("fail "+str((node in self.armature_for_morph))) + # print("fail "+str((node in self.armature_for_morph))) continue - if (node.type=="MESH" and node.data!=None and node.data.shape_keys!=None and (node.data in self.mesh_cache) and len(node.data.shape_keys.key_blocks)): + if (node.type == "MESH" and node.data is not None and + node.data.shape_keys is not None and ( + node.data in self.mesh_cache) and len( + node.data.shape_keys.key_blocks)): target = self.mesh_cache[node.data]["morph_id"] for i in range(len(node.data.shape_keys.key_blocks)): - if (i==0): + if (i == 0): continue - name=target+"-morph-weights("+str(i-1)+")" + name = target + "-morph-weights(" + str(i - 1) + ")" if (not (name in blend_cache)): - blend_cache[name]=[] + blend_cache[name] = [] - blend_cache[name].append( (key, node.data.shape_keys.key_blocks[i].value) ) + blend_cache[name].append( + (key, node.data.shape_keys.key_blocks[i].value)) - if (node.type=="MESH" and node.parent and node.parent.type=="ARMATURE"): + if (node.type == "MESH" and node.parent and + node.parent.type == "ARMATURE"): - continue #In Collada, nodes that have skin modifier must not export animation, animate the skin instead. + # In Collada, nodes that have skin modifier must not export + # animation, animate the skin instead. + continue - if (len(node.constraints)>0 or node.animation_data!=None): - #If the node has constraints, or animation data, then export a sampled animation track - name=self.validate_id(node.name) + if (len(node.constraints) > 0 or + node.animation_data is not None): + # If the node has constraints, or animation data, then + # export a sampled animation track + name = self.validate_id(node.name) if (not (name in xform_cache)): - xform_cache[name]=[] + xform_cache[name] = [] mtx = node.matrix_world.copy() if (node.parent): mtx = node.parent.matrix_world.inverted() * mtx - xform_cache[name].append( (key, mtx) ) + xform_cache[name].append((key, mtx)) - if (node.type=="ARMATURE"): - #All bones exported for now + if (node.type == "ARMATURE"): + # All bones exported for now for bone in node.data.bones: - bone_name=self.skeleton_info[node]["bone_ids"][bone] + bone_name = self.skeleton_info[node]["bone_ids"][bone] if (not (bone_name in xform_cache)): - #print("has bone: "+bone_name) - xform_cache[bone_name]=[] + # print("has bone: " + bone_name) + xform_cache[bone_name] = [] posebone = node.pose.bones[bone.name] - parent_posebone=None + parent_posebone = None mtx = posebone.matrix.copy() if (bone.parent): - parent_posebone=node.pose.bones[bone.parent.name] - parent_invisible=False + parent_posebone = node.pose.bones[bone.parent.name] + parent_invisible = False for i in range(3): - if (parent_posebone.scale[i]==0.0): - parent_invisible=True + if (parent_posebone.scale[i] == 0.0): + parent_invisible = True if (not parent_invisible): mtx = parent_posebone.matrix.inverted() * mtx - xform_cache[bone_name].append( (key, mtx) ) + xform_cache[bone_name].append((key, mtx)) self.scene.frame_set(frame_orig) - #export animation xml + # export animation xml for nid in xform_cache: - tcn+=self.export_animation_transform_channel(nid, xform_cache[nid], True) + tcn += self.export_animation_transform_channel( + nid, xform_cache[nid], True) for nid in blend_cache: - tcn+=self.export_animation_transform_channel(nid, blend_cache[nid], False) + tcn += self.export_animation_transform_channel( + nid, blend_cache[nid], False) return tcn @@ -1469,6 +1753,7 @@ class DaeExporter: self.writel(S_ANIM, 0, '') if (self.config["use_anim_action_all"] and len(self.skeletons)): + cached_actions = {} for s in self.skeletons: @@ -1478,31 +1763,32 @@ class DaeExporter: self.writel(S_ANIM_CLIPS, 0, '') for x in bpy.data.actions[:]: - if x.users==0 or x in self.action_constraints: + if x.users == 0 or x in self.action_constraints: continue - if (self.config["use_anim_skip_noexp"] and x.name.endswith("-noexp")): + if (self.config["use_anim_skip_noexp"] and + x.name.endswith("-noexp")): continue - bones=[] - #find bones used + bones = [] + # find bones used for p in x.fcurves: dp = str(p.data_path) base = "pose.bones[\"" - if (dp.find(base)==0): - dp=dp[len(base):] - if (dp.find('"')!=-1): - dp=dp[:dp.find('"')] - if (not dp in bones): + if (dp.find(base) == 0): + dp = dp[len(base):] + if (dp.find('"') != -1): + dp = dp[:dp.find('"')] + if (dp not in bones): bones.append(dp) - allowed_skeletons=[] + allowed_skeletons = [] for i, y in enumerate(self.skeletons): if (y.animation_data): for z in y.pose.bones: if (z.bone.name in bones): - if (not y in allowed_skeletons): + if (y not in allowed_skeletons): allowed_skeletons.append(y) - y.animation_data.action=x; + y.animation_data.action = x y.matrix_local = tmp_mat[i][0] for j, bone in enumerate(s.pose.bones): @@ -1512,25 +1798,32 @@ class DaeExporter: # print(str(x)) - tcn = self.export_animation(int(x.frame_range[0]), int(x.frame_range[1]+0.5), allowed_skeletons) - framelen=(1.0/self.scene.render.fps) - start = x.frame_range[0]*framelen - end = x.frame_range[1]*framelen - #print("Export anim: "+x.name) - self.writel(S_ANIM_CLIPS, 1, '') + tcn = self.export_animation(int(x.frame_range[0]), int( + x.frame_range[1] + 0.5), allowed_skeletons) + framelen = (1.0 / self.scene.render.fps) + start = x.frame_range[0] * framelen + end = x.frame_range[1] * framelen + # print("Export anim: "+x.name) + self.writel( + S_ANIM_CLIPS, 1, '') for z in tcn: - self.writel(S_ANIM_CLIPS, 2, '') + self.writel(S_ANIM_CLIPS, 2, + '') self.writel(S_ANIM_CLIPS, 1, '') - if (len(tcn)==0): - self.operator.report({'WARNING'}, 'Animation clip "'+x.name+'" contains no tracks.') + if (len(tcn) == 0): + self.operator.report( + {'WARNING'}, 'Animation clip "' + x.name + + '" contains no tracks.') self.writel(S_ANIM_CLIPS, 0, '') for i, s in enumerate(self.skeletons): - if (s.animation_data==None): + if (s.animation_data is None): continue if s in cached_actions: - s.animation_data.action = bpy.data.actions[cached_actions[s]] + s.animation_data.action = bpy.data.actions[ + cached_actions[s]] else: s.animation_data.action = None for j, bone in enumerate(s.pose.bones): @@ -1550,20 +1843,20 @@ class DaeExporter: self.writel(S_MATS, 0, '') self.writel(S_FX, 0, '') - self.skeletons=[] - self.action_constraints=[] + self.skeletons = [] + self.action_constraints = [] self.export_asset() self.export_scene() self.writel(S_GEOM, 0, '') - #morphs always go before skin controllers + # morphs always go before skin controllers if S_MORPH in self.sections: for l in self.sections[S_MORPH]: self.writel(S_CONT, 0, l) del self.sections[S_MORPH] - #morphs always go before skin controllers + # morphs always go before skin controllers if S_SKIN in self.sections: for l in self.sections[S_SKIN]: self.writel(S_CONT, 0, l) @@ -1585,47 +1878,45 @@ class DaeExporter: return False f.write(bytes('\n', "UTF-8")) - f.write(bytes('\n', "UTF-8")) + f.write(bytes( + '\n', "UTF-8")) - s=[] + s = [] for x in self.sections.keys(): s.append(x) s.sort() for x in s: for l in self.sections[x]: - f.write(bytes(l+"\n", "UTF-8")) + f.write(bytes(l + "\n", "UTF-8")) f.write(bytes('\n', "UTF-8")) - f.write(bytes('\t\n', "UTF-8")) + f.write(bytes('\t\n', "UTF-8")) f.write(bytes('\n', "UTF-8")) f.write(bytes('\n', "UTF-8")) return True def __init__(self, path, kwargs, operator): - self.operator=operator - self.scene=bpy.context.scene - self.last_id=0 - self.scene_name=self.new_id("scene") - self.sections={} - self.path=path - self.mesh_cache={} - self.curve_cache={} - self.material_cache={} - self.image_cache={} - self.skeleton_info={} - self.config=kwargs - self.valid_nodes=[] - self.armature_for_morph={} - self.used_bones=[] - self.wrongvtx_report=False - - -def save(operator, context, - filepath="", - use_selection=False, - **kwargs - ): - + self.operator = operator + self.scene = bpy.context.scene + self.last_id = 0 + self.scene_name = self.new_id("scene") + self.sections = {} + self.path = path + self.mesh_cache = {} + self.curve_cache = {} + self.material_cache = {} + self.image_cache = {} + self.skeleton_info = {} + self.config = kwargs + self.valid_nodes = [] + self.armature_for_morph = {} + self.used_bones = [] + self.wrongvtx_report = False + + +def save(operator, context, filepath="", use_selection=False, **kwargs): exp = DaeExporter(filepath, kwargs, operator) exp.export() -- cgit v1.2.3