Skip to content
Snippets Groups Projects
export_fbx.py 115 KiB
Newer Older
  • Learn to ignore specific revisions
  •             do_light = not (light.use_only_shadow or (not light.use_diffuse and not light.use_specular))
    
                do_shadow = (light.shadow_method in {'RAY_SHADOW', 'BUFFER_SHADOW'})
    
    Campbell Barton's avatar
    Campbell Barton committed
            # scale = abs(global_matrix.to_scale()[0])  # scale is always uniform in this case  #  UNUSED
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
            fw('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
            fw('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
            fw('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
            fw('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
            fw('\n\t\t\tProperty: "GoboProperty", "object", ""')
            fw('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1')
            fw('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy * 100.0, 200.0)))  # clamp below 200
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % math.degrees(light.spot_size))
            fw('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
            fw('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.color))
    
            fw('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (min(light.energy * 100.0, 200.0)))  # clamp below 200
    
            fw('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
            fw('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
            fw('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light)
            fw('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
            fw('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
            fw('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
            fw('\n\t\t\tProperty: "GoboProperty", "object", ""')
            fw('\n\t\t\tProperty: "DecayType", "enum", "",0')
            fw('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.distance)
    
            fw('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0'
               '\n\t\t\tProperty: "NearAttenuationStart", "double", "",0'
               '\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0'
               '\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0'
               '\n\t\t\tProperty: "FarAttenuationStart", "double", "",0'
               '\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0'
               )
    
            fw('\n\t\t\tProperty: "CastShadows", "bool", "",%i' % do_shadow)
            fw('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1')
            fw('\n\t\t}')
    
            fw('\n\t\tMultiLayer: 0'
               '\n\t\tMultiTake: 0'
               '\n\t\tShading: Y'
               '\n\t\tCulling: "CullingOff"'
               '\n\t\tTypeFlags: "Light"'
               '\n\t\tGeometryVersion: 124'
               '\n\t}'
               )
    
    
        # matrixOnly is not used at the moment
    
        def write_null(my_null=None, fbxName=None, fbxType="Null", fbxTypeFlags="Null"):
    
            if not fbxName:
                fbxName = my_null.fbxName
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tModel: "Model::%s", "%s" {' % (fbxName, fbxType))
            fw('\n\t\tVersion: 232')
    
            if my_null:
                poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3]
            else:
                poseMatrix = write_object_props()[3]
    
    
            pose_items.append((fbxName, poseMatrix))
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t}'
               '\n\t\tMultiLayer: 0'
               '\n\t\tMultiTake: 1'
               '\n\t\tShading: Y'
               '\n\t\tCulling: "CullingOff"'
               )
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tTypeFlags: "%s"' % fbxTypeFlags)
            fw('\n\t}')
    
        if world:
            world_amb = world.ambient_color[:]
        else:
            world_amb = 0.0, 0.0, 0.0  # default value
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tMaterial: "Material::%s", "" {' % matname)
    
    
            # Todo, add more material Properties.
            if mat:
                mat_cold = tuple(mat.diffuse_color)
                mat_cols = tuple(mat.specular_color)
                #mat_colm = tuple(mat.mirCol) # we wont use the mirror color
                mat_colamb = world_amb
    
                mat_dif = mat.diffuse_intensity
                mat_amb = mat.ambient
    
                mat_hard = (float(mat.specular_hardness) - 1.0) / 5.10
                mat_spec = mat.specular_intensity / 2.0
    
                mat_alpha = mat.alpha
                mat_emit = mat.emit
                mat_shadeless = mat.use_shadeless
                if mat_shadeless:
                    mat_shader = 'Lambert'
                else:
                    if mat.diffuse_shader == 'LAMBERT':
                        mat_shader = 'Lambert'
                    else:
                        mat_shader = 'Phong'
            else:
                mat_cols = mat_cold = 0.8, 0.8, 0.8
    
                # mat_colm
                mat_dif = 1.0
                mat_amb = 0.5
                mat_hard = 20.0
                mat_spec = 0.2
                mat_alpha = 1.0
                mat_emit = 0.0
                mat_shadeless = False
                mat_shader = 'Phong'
    
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tVersion: 102')
            fw('\n\t\tShadingModel: "%s"' % mat_shader.lower())
            fw('\n\t\tMultiLayer: 0')
    
            fw('\n\t\tProperties60:  {')
            fw('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader)
            fw('\n\t\t\tProperty: "MultiLayer", "bool", "",0')
            fw('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold)  # emit and diffuse color are he same in blender
            fw('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_emit)
    
            fw('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb)
            fw('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb)
            fw('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold)
            fw('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_dif)
            fw('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0')
            fw('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1')
            fw('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha))
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cols)
                fw('\n\t\t\tProperty: "SpecularFactor", "double", "",%.4f' % mat_spec)
                fw('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0')
                fw('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0')
                fw('\n\t\t\tProperty: "ReflectionFactor", "double", "",1')
            fw('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0')
            fw('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb)
            fw('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold)
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t\tProperty: "Specular", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols)
                fw('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard)
            fw('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha)
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t\tProperty: "Reflectivity", "double", "",0')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t}')
            fw('\n\t}')
    
    
        # tex is an Image (Arystan)
        def write_video(texname, tex):
            # Same as texture really!
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tVideo: "Video::%s", "Clip" {' % texname)
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    		Type: "Clip"
    		Properties60:  {
    			Property: "FrameRate", "double", "",0
    			Property: "LastFrame", "int", "",0
    			Property: "Width", "int", "",0
    			Property: "Height", "int", "",0''')
    
                fname_rel = bpy_extras.io_utils.path_reference(tex.filepath, base_src, base_dst, path_mode, "", copy_set, tex.library)
    
                fname_strip = bpy.path.basename(fname_rel)
    
                fname_strip = fname_rel = ""
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip)
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    			Property: "StartFrame", "int", "",0
    			Property: "StopFrame", "int", "",0
    			Property: "PlaySpeed", "double", "",1
    			Property: "Offset", "KTime", "",0
    			Property: "InterlaceMode", "enum", "",0
    			Property: "FreeRunning", "bool", "",0
    			Property: "Loop", "bool", "",0
    			Property: "AccessMode", "enum", "",0
    		}
    		UseMipMap: 0''')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tFilename: "%s"' % fname_strip)
            fw('\n\t\tRelativeFilename: "%s"' % fname_rel)  # make relative
            fw('\n\t}')
    
    
        def write_texture(texname, tex, num):
            # if tex is None then this is a dummy tex
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tTexture: "Texture::%s", "TextureVideoClip" {' % texname)
            fw('\n\t\tType: "TextureVideoClip"')
            fw('\n\t\tVersion: 202')
    
            # TODO, rare case _empty_ exists as a name.
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tTextureName: "Texture::%s"' % texname)
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    		Properties60:  {
    			Property: "Translation", "Vector", "A+",0,0,0
    			Property: "Rotation", "Vector", "A+",0,0,0
    			Property: "Scaling", "Vector", "A+",1,1,1''')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num)
    
    
            # WrapModeU/V 0==rep, 1==clamp, TODO add support
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    			Property: "TextureTypeUse", "enum", "",0
    			Property: "CurrentTextureBlendMode", "enum", "",1
    			Property: "UseMaterial", "bool", "",0
    			Property: "UseMipMap", "bool", "",0
    			Property: "CurrentMappingType", "enum", "",0
    			Property: "UVSwap", "bool", "",0''')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t\tProperty: "WrapModeU", "enum", "",%i' % tex.use_clamp_x)
            fw('\n\t\t\tProperty: "WrapModeV", "enum", "",%i' % tex.use_clamp_y)
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    			Property: "TextureRotationPivot", "Vector3D", "",0,0,0
    			Property: "TextureScalingPivot", "Vector3D", "",0,0,0
    			Property: "VideoProperty", "object", ""
    		}''')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tMedia: "Video::%s"' % texname)
    
                fname_rel = bpy_extras.io_utils.path_reference(tex.filepath, base_src, base_dst, path_mode, "", copy_set, tex.library)
                fname_strip = bpy.path.basename(fname_rel)
    
                fname_strip = fname_rel = ""
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tFileName: "%s"' % fname_strip)
            fw('\n\t\tRelativeFilename: "%s"' % fname_rel)  # need some make relative command
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    		ModelUVTranslation: 0,0
    		ModelUVScaling: 1,1
    		Texture_Alpha_Source: "None"
    		Cropping: 0,0,0,0
    	}''')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname)
            fw('''
    
    		Version: 100
    		MultiLayer: 0
    		Type: "Skin"
    		Properties60:  {
    		}
    		Link_DeformAcuracy: 50
    	}''')
    
    
        # in the example was 'Bip01 L Thigh_2'
        def write_sub_deformer_skin(my_mesh, my_bone, weights):
    
    
            Each subdeformer is specific to a mesh, but the bone it links to can be used by many sub-deformers
    
            So the SubDeformer needs the mesh-object name as a prefix to make it unique
    
            Its possible that there is no matching vgroup in this mesh, in that case no verts are in the subdeformer,
            a but silly but dosnt really matter
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {' % (my_mesh.fbxName, my_bone.fbxName))
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    		Version: 100
    		MultiLayer: 0
    		Type: "Cluster"
    		Properties60:  {
    			Property: "SrcModel", "object", ""
    			Property: "SrcModelReference", "object", ""
    		}
    		UserData: "", ""''')
    
    
            # Support for bone parents
            if my_mesh.fbxBoneParent:
                if my_mesh.fbxBoneParent == my_bone:
                    # TODO - this is a bit lazy, we could have a simple write loop
                    # for this case because all weights are 1.0 but for now this is ok
                    # Parent Bones arent used all that much anyway.
                    vgroup_data = [(j, 1.0) for j in range(len(my_mesh.blenData.vertices))]
                else:
                    # This bone is not a parent of this mesh object, no weights
                    vgroup_data = []
    
            else:
                # Normal weight painted mesh
                if my_bone.blenName in weights[0]:
    
                    group_index = weights[0].index(my_bone.blenName)
                    vgroup_data = [(j, weight[group_index]) for j, weight in enumerate(weights[1]) if weight[group_index]]
                else:
                    vgroup_data = []
    
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tIndexes: ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('%i' % vg[0])
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw(',%i' % vg[0])
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tWeights: ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('%.8f' % vg[1])
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw(',%.8f' % vg[1])
    
            # Set TransformLink to the global transform of the bone and Transform
            # equal to the mesh's transform in bone space.
            # http://area.autodesk.com/forum/autodesk-fbx/fbx-sdk/why-the-values-return-by-fbxcluster-gettransformmatrix-x-not-same-with-the-value-in-ascii-fbx-file/
    
            global_bone_matrix = (my_bone.fbxArm.matrixWorld * my_bone.restMatrix) * mtx4_z90
            global_mesh_matrix = my_mesh.matrixWorld
            transform_matrix = (global_bone_matrix.inverted() * global_mesh_matrix)
    
            global_bone_matrix_string = mat4x4str(global_bone_matrix )
            transform_matrix_string = mat4x4str(transform_matrix )
    
            fw('\n\t\tTransform: %s' % transform_matrix_string)
            fw('\n\t\tTransformLink: %s' % global_bone_matrix_string)
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t}')
    
    
        def write_mesh(my_mesh):
    
            me = my_mesh.blenData
    
            # if there are non NULL materials on this mesh
            do_materials = bool(my_mesh.blenMaterials)
            do_textures = bool(my_mesh.blenTextures)
    
            do_uvs = bool(me.tessface_uv_textures)
    
            do_shapekeys = (my_mesh.blenObject.type == 'MESH' and
                            my_mesh.blenObject.data.shape_keys and
                            len(my_mesh.blenObject.data.vertices) == len(me.vertices))
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName)
            fw('\n\t\tVersion: 232')  # newline is added in write_object_props
    
    
            # convert into lists once.
            me_vertices = me.vertices[:]
    
            me_edges = me.edges[:] if use_mesh_edges else ()
    
    
            poseMatrix = write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())[3]
    
    
            # Calculate the global transform for the mesh in the bind pose the same way we do
            # in write_sub_deformer_skin
            globalMeshBindPose = my_mesh.matrixWorld * mtx4_z90
            pose_items.append((my_mesh.fbxName, globalMeshBindPose))
    
            if do_shapekeys:
                for kb in my_mesh.blenObject.data.shape_keys.key_blocks[1:]:
                    fw('\n\t\t\tProperty: "%s", "Number", "AN",0' % kb.name)
    
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t}')
    
            fw('\n\t\tMultiLayer: 0'
               '\n\t\tMultiTake: 1'
               '\n\t\tShading: Y'
               '\n\t\tCulling: "CullingOff"'
               )
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tVertices: ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('%.6f,%.6f,%.6f' % v.co[:])
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw(',%.6f,%.6f,%.6f' % v.co[:])
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tPolygonVertexIndex: ')
    
            for f in me_faces:
                fi = f.vertices[:]
    
                # last index XORd w. -1 indicates end of face
                if i == -1:
                    if len(fi) == 3:
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('%i,%i,%i' % (fi[0], fi[1], fi[2] ^ -1))
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('%i,%i,%i,%i' % (fi[0], fi[1], fi[2], fi[3] ^ -1))
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw(',%i,%i,%i' % (fi[0], fi[1], fi[2] ^ -1))
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw(',%i,%i,%i,%i' % (fi[0], fi[1], fi[2], fi[3] ^ -1))
    
                i += 1
    
            # write loose edges as faces.
            for ed in me_edges:
                if ed.is_loose:
                    ed_val = ed.vertices[:]
                    ed_val = ed_val[0], ed_val[-1] ^ -1
    
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('%i,%i' % ed_val)
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('\n\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw(',%i,%i' % ed_val)
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tEdges: ')
    
                if i == -1:
                    fw('%i,%i' % (ed.vertices[0], ed.vertices[1]))
                    i = 0
                else:
                    if i == 13:
                        fw('\n\t\t')
    
                    fw(',%i,%i' % (ed.vertices[0], ed.vertices[1]))
                i += 1
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\tGeometryVersion: 124')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    		LayerElementNormal: 0 {
    			Version: 101
    			Name: ""
    			MappingInformationType: "ByVertice"
    			ReferenceInformationType: "Direct"
    			Normals: ''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('%.15f,%.15f,%.15f' % v.normal[:])
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\t\t ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw(',%.15f,%.15f,%.15f' % v.normal[:])
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('''
    
    		LayerElementSmoothing: 0 {
    			Version: 102
    			Name: ""
    			MappingInformationType: "ByPolygon"
    			ReferenceInformationType: "Direct"
    			Smoothing: ''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('%i' % f.use_smooth)
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('\n\t\t\t ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw(',%i' % f.use_smooth)
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('''
    
    		LayerElementSmoothing: 0 {
    			Version: 101
    			Name: ""
    			MappingInformationType: "ByEdge"
    			ReferenceInformationType: "Direct"
    			Smoothing: ''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('%i' % (ed.use_edge_sharp))
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('\n\t\t\t ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw(',%i' % ed.use_edge_sharp)
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t}')
    
            elif mesh_smooth_type == 'OFF':
                pass
            else:
                raise Exception("invalid mesh_smooth_type: %r" % mesh_smooth_type)
    
    
            # Write VertexColor Layers
            # note, no programs seem to use this info :/
            collayers = []
    
            if len(me.tessface_vertex_colors):
                collayers = me.tessface_vertex_colors
    
                for colindex, collayer in enumerate(collayers):
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\tLayerElementColor: %i {' % colindex)
                    fw('\n\t\t\tVersion: 101')
                    fw('\n\t\t\tName: "%s"' % collayer.name)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('''
    
    			MappingInformationType: "ByPolygonVertex"
    			ReferenceInformationType: "IndexToDirect"
    			Colors: ''')
    
                    ii = 0  # Count how many Colors we write
    
                    print(len(me_faces), len(collayer.data))
    
                    for fi, cf in enumerate(collayer.data):
                        if len(me_faces[fi].vertices) == 4:
                            colors = cf.color1[:], cf.color2[:], cf.color3[:], cf.color4[:]
                        else:
                            colors = cf.color1[:], cf.color2[:], cf.color3[:]
    
                        for col in colors:
    
    Campbell Barton's avatar
    Campbell Barton committed
                                fw('%.4f,%.4f,%.4f,1' % col)
    
    Campbell Barton's avatar
    Campbell Barton committed
                                    fw('\n\t\t\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                                fw(',%.4f,%.4f,%.4f,1' % col)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t\tColorIndex: ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('%i' % j)
    
    Campbell Barton's avatar
    Campbell Barton committed
                                fw('\n\t\t\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw(',%i' % j)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t}')
    
    
            # Write UV and texture layers.
            uvlayers = []
            if do_uvs:
    
                uvlayers = me.tessface_uv_textures
                for uvindex, uvlayer in enumerate(me.tessface_uv_textures):
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\tLayerElementUV: %i {' % uvindex)
                    fw('\n\t\t\tVersion: 101')
                    fw('\n\t\t\tName: "%s"' % uvlayer.name)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('''
    
    			MappingInformationType: "ByPolygonVertex"
    			ReferenceInformationType: "IndexToDirect"
    			UV: ''')
    
                    ii = 0  # Count how many UVs we write
    
    
                    for uf in uvlayer.data:
                        # workaround, since uf.uv iteration is wrong atm
                        for uv in uf.uv:
    
    Campbell Barton's avatar
    Campbell Barton committed
                                fw('%.6f,%.6f' % uv[:])
    
    Campbell Barton's avatar
    Campbell Barton committed
                                    fw('\n\t\t\t ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                                fw(',%.6f,%.6f' % uv[:])
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t\tUVIndex: ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('%i' % j)
    
    Campbell Barton's avatar
    Campbell Barton committed
                                fw('\n\t\t\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw(',%i' % j)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\tLayerElementTexture: %i {' % uvindex)
                        fw('\n\t\t\tVersion: 101')
                        fw('\n\t\t\tName: "%s"' % uvlayer.name)
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('\n\t\t\tMappingInformationType: "AllSame"')
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('\n\t\t\tMappingInformationType: "ByPolygon"')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\t\tReferenceInformationType: "IndexToDirect"')
                        fw('\n\t\t\tBlendMode: "Translucent"')
                        fw('\n\t\t\tTextureAlpha: 1')
                        fw('\n\t\t\tTextureId: ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('0')
    
                            texture_mapping_local = {None: -1}
    
                            for tex in my_mesh.blenTextures:
    
    Campbell Barton's avatar
    Campbell Barton committed
                                    fw('%s' % texture_mapping_local[img_key])
    
    Campbell Barton's avatar
    Campbell Barton committed
                                        fw('\n			 ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                                    fw(',%s' % texture_mapping_local[img_key])
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('''
    
    		LayerElementTexture: 0 {
    			Version: 101
    			Name: ""
    			MappingInformationType: "NoMappingInformation"
    			ReferenceInformationType: "IndexToDirect"
    			BlendMode: "Translucent"
    			TextureAlpha: 1
    			TextureId: ''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\tLayerElementMaterial: 0 {')
                fw('\n\t\t\tVersion: 101')
                fw('\n\t\t\tName: ""')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t\tMappingInformationType: "AllSame"')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t\tMappingInformationType: "ByPolygon"')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t\tReferenceInformationType: "IndexToDirect"')
                fw('\n\t\t\tMaterials: ')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('0')
    
                else:
                    # Build a material mapping for this
    
                    material_mapping_local = {}  # local-mat & tex : global index.
    
    
                    for j, mat_tex_pair in enumerate(my_mesh.blenMaterials):
                        material_mapping_local[mat_tex_pair] = j
    
                    mats = my_mesh.blenMaterialList
    
    
                    if me.tessface_uv_textures.active:
                        uv_faces = me.tessface_uv_textures.active.data
    
                    for f, uf in zip(me_faces, uv_faces):
    
                        try:
                            mat = mats[f.material_index]
                        except:
                            mat = None
    
                        if do_uvs:
                            tex = uf.image  # WARNING - MULTI UV LAYER IMAGES NOT SUPPORTED :/
                        else:
                            tex = None
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw('%s' % material_mapping_local[mat, tex])  # None for mat or tex is ok
    
    Campbell Barton's avatar
    Campbell Barton committed
                                fw('\n\t\t\t\t')
    
    Campbell Barton's avatar
    Campbell Barton committed
                            fw(',%s' % material_mapping_local[mat, tex])
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('\n\t\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    		Layer: 0 {
    			Version: 100
    			LayerElement:  {
    				Type: "LayerElementNormal"
    				TypedIndex: 0
    			}''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('''
    
    			LayerElement:  {
    				Type: "LayerElementMaterial"
    				TypedIndex: 0
    			}''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('''
    
    			LayerElement:  {
    				Type: "LayerElementSmoothing"
    				TypedIndex: 0
    			}''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('''
    
    			LayerElement:  {
    				Type: "LayerElementTexture"
    				TypedIndex: 0
    			}''')
    
            if me.tessface_vertex_colors:
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('''
    
    			LayerElement:  {
    				Type: "LayerElementColor"
    				TypedIndex: 0
    			}''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                fw('''
    
    			LayerElement:  {
    				Type: "LayerElementUV"
    				TypedIndex: 0
    			}''')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t\t}')
    
    
            if len(uvlayers) > 1:
                for i in range(1, len(uvlayers)):
    
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\tLayer: %i {' % i)
                    fw('\n\t\t\tVersion: 100')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('''
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t\t\tTypedIndex: %i' % i)
                    fw('\n\t\t\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('''
    
    			LayerElement:  {
    				Type: "LayerElementTexture"''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                        fw('\n\t\t\t\tTypedIndex: %i' % i)
                        fw('\n\t\t\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t}')
    
    
            if len(collayers) > 1:
                # Take into account any UV layers
                layer_offset = 0
    
                if uvlayers:
                    layer_offset = len(uvlayers) - 1
    
                for i in range(layer_offset, len(collayers) + layer_offset):
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\tLayer: %i {' % i)
                    fw('\n\t\t\tVersion: 100')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('''
    
    			LayerElement:  {
    				Type: "LayerElementColor"''')
    
    Campbell Barton's avatar
    Campbell Barton committed
                    fw('\n\t\t\t\tTypedIndex: %i' % i)
                    fw('\n\t\t\t}')
                    fw('\n\t\t}')
    
            if do_shapekeys:
                key_blocks = my_mesh.blenObject.data.shape_keys.key_blocks[:]
                for kb in key_blocks[1:]:
    
                    fw('\n\t\tShape: "%s" {' % kb.name)
                    fw('\n\t\t\tIndexes: ')
    
                    basis_verts = key_blocks[0].data
                    range_verts = []
                    delta_verts = []
                    i = -1
                    for j, kv in enumerate(kb.data):
                        delta = kv.co - basis_verts[j].co
                        if delta.length > 0.000001:
                            if i == -1:
                                fw('%d' % j)
                            else:
                                if i == 7:
                                    fw('\n\t\t\t')
                                    i = 0
                                fw(',%d' % j)
                            delta_verts.append(delta[:])
                            i += 1
    
                    fw('\n\t\t\tVertices: ')
                    i = -1
                    for dv in delta_verts:
                        if i == -1:
    
                            fw("%.6f,%.6f,%.6f" % dv)
    
                        else:
                            if i == 4:
                                fw('\n\t\t\t')
                                i = 0
    
                            fw(",%.6f,%.6f,%.6f" % dv)
    
                        i += 1
    
                    # all zero, why? - campbell
                    fw('\n\t\t\tNormals: ')
                    for j in range(len(delta_verts)):
                        if i == -1:
                            fw("0,0,0")
                        else:
                            if i == 4:
                                fw('\n\t\t\t')
                                i = 0
                            fw(",0,0,0")
                        i += 1
                    fw('\n\t\t}')
    
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\t}')
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('\n\tGroupSelection: "GroupSelection::%s", "Default" {' % name)
    
    Campbell Barton's avatar
    Campbell Barton committed
            fw('''
    
    		Properties60:  {
    			Property: "MultiLayer", "bool", "",0
    			Property: "Pickable", "bool", "",1
    			Property: "Transformable", "bool", "",1
    			Property: "Show", "bool", "",1
    		}
    		MultiLayer: 0
    	}''')
    
    
        # add meshes here to clear because they are not used anywhere.
        meshes_to_clear = []
    
        ob_meshes = []
        ob_lights = []
        ob_cameras = []
        # in fbx we export bones as children of the mesh
        # armatures not a part of a mesh, will be added to ob_arms
        ob_bones = []
        ob_arms = []
    
    
        # List of types that have blender objects (not bones)
        ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null]
    
    
        groups = []  # blender groups, only add ones that have objects in the selections
        materials = {}  # (mat, image) keys, should be a set()
        textures = {}  # should be a set()
    
        tmp_ob_type = None  # in case no objects are exported, so as not to raise an error
    
    Campbell Barton's avatar
    Campbell Barton committed
    ## XXX
    
            # This is needed so applying modifiers dosnt apply the armature deformation, its also needed
            # ...so mesh objects return their rest worldspace matrix when bone-parents are exported as weighted meshes.
            # set every armature to its rest, backup the original values so we done mess up the scene
            ob_arms_orig_rest = [arm.pose_position for arm in bpy.data.armatures]
    
            for arm in bpy.data.armatures:
                arm.pose_position = 'REST'
    
            if ob_arms_orig_rest:
                for ob_base in bpy.data.objects:
                    if ob_base.type == 'ARMATURE':
    
                        ob_base.update_tag()
    
    
                # This causes the makeDisplayList command to effect the mesh
                scene.frame_set(scene.frame_current)
    
    
        for ob_base in context_objects:
    
            if ob_base.parent and ob_base.parent.dupli_type in {'VERTS', 'FACES'}:
    
            obs = [(ob_base, ob_base.matrix_world.copy())]
    
            if ob_base.dupli_type != 'NONE':
    
                ob_base.dupli_list_create(scene)
    
                obs = [(dob.object, dob.matrix.copy()) for dob in ob_base.dupli_list]
    
    
            for ob, mtx in obs:
                tmp_ob_type = ob.type
                if tmp_ob_type == 'CAMERA':
    
                        ob_cameras.append(my_object_generic(ob, mtx))
                elif tmp_ob_type == 'LAMP':
    
                        ob_lights.append(my_object_generic(ob, mtx))
                elif tmp_ob_type == 'ARMATURE':
    
                        # TODO - armatures dont work in dupligroups!
    
                        if ob not in ob_arms:
                            ob_arms.append(ob)
    
                        # ob_arms.append(ob) # replace later. was "ob_arms.append(sane_obname(ob), ob)"
                elif tmp_ob_type == 'EMPTY':
    
                        ob_null.append(my_object_generic(ob, mtx))
    
                    origData = True
                    if tmp_ob_type != 'MESH':
    
                            me = ob.to_mesh(scene, True, 'PREVIEW')
    
                            mats = me.materials
                            origData = False
                    else:
                        # Mesh Type!
    
                            me = ob.to_mesh(scene, True, 'PREVIEW')
    
    
                            # print ob, me, me.getVertGroupNames()
    
                            origData = False
                            mats = me.materials
                        else:
                            me = ob.data
    
                            mats = me.materials
    
    # 						# Support object colors
    # 						tmp_colbits = ob.colbits
    # 						if tmp_colbits:
    # 							tmp_ob_mats = ob.getMaterials(1) # 1 so we get None's too.
    # 							for i in xrange(16):
    # 								if tmp_colbits & (1<<i):
    # 									mats[i] = tmp_ob_mats[i]
    # 							del tmp_ob_mats
    # 						del tmp_colbits
    
                    if me:
    
    # 					# This WILL modify meshes in blender if use_mesh_modifiers is disabled.
    
    # 					# so strictly this is bad. but only in rare cases would it have negative results
    # 					# say with dupliverts the objects would rotate a bit differently
    # 					if EXP_MESH_HQ_NORMALS:
    # 						BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
    
                        texture_mapping_local = {}
                        material_mapping_local = {}
    
                        if me.tessface_uv_textures:
                            for uvlayer in me.tessface_uv_textures:
    
                                for f, uf in zip(me.tessfaces, uvlayer.data):
    
                                    tex = uf.image
                                    textures[tex] = texture_mapping_local[tex] = None