1

I have an old export script that worked in Blender 2.5. Now I wanted to update it to 2.9. My export uses vertex based animation as the MD2 file format uses it, so I need the vertex per animation frame position.

It works, but the mesh is not animated. I only get the vertex positions from the non-animated mesh, repeated for each frame.

# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

bl_info = { "name": "GLBasic dda", "author": "Gernot Frisch", "version": (1,2), "blender": (2, 80, 0), "location": "File > Import/Export > GLBasic dda ", "description": "Export GLBasic DDA 3D mesh with animation (.dda format)", "warning": "", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
"Scripts/File_I-O/GLBasic", "tracker_url": "https://projects.blender.org/tracker/index.php?"
"func=detail&aid=21733&group_id=153&atid=469", "category": "Import/Export" }

if "bpy" in locals():

import importlib

if "export_dda" in locals():

importlib.reload(export_dda)

import os import bpy from bpy.types import Operator, TOPBAR_MT_file_export from bpy.props import BoolProperty, EnumProperty, FloatProperty,
FloatVectorProperty, StringProperty from bpy_extras.io_utils import ExportHelper

def export_dda(filename, context):

try:
    file = open(filename, 'w')
except:
    # error = "IOError #%s: %s" % (errno, strerror)
    # REPORT_DATA['errors'].append("Saving failed - %s." % error)
    # ERROR_MSG = "Couldn't save file!%%t|%s" % error
    print ("Exception during open out file")
    raise

print ("--------------------\nEXPORT v1.2\n---------------------------\n")
scene = context.scene
scene.frame_set(1)
mesh_obj = context.object
mesh = mesh_obj.data

mesh.calc_loop_triangles()
file.write("DDDA 1.1\n")

# (1) UV coordinates for each polygon
UVCoordinates = None
for UV in mesh.uv_layers:
    if UV.active_render:
        UVCoordinates = UV.data
        break

# build uv-dictionary
tex_list = {}
tex_count=0
for uvcoo in UVCoordinates:
    uv_key = (uvcoo.uv[0], uvcoo.uv[1] )
    if not (uv_key in tex_list): # .has_key(tex_key):
        tex_list[ uv_key ]=tex_count
        tex_count=tex_count+1

file.write("%d # tex count\n" % tex_count)
file.write("# id u v\n")
for i in range(0, tex_count):
    for coord in tex_list:
        if tex_list[coord] == i:
            file.write("%.3f %.3f # uv\n" % (coord[0], (1.0-coord[1]) ) )

# file.write("%d # tex count\n" % len(UVCoordinates))
# file.write("# id u v\n")
# for i in range(0, len(UVCoordinates)):
#     coord = UVCoordinates[i].uv
#     file.write("%.3f %.3f # uv\n" % (coord[0], (1.0-coord[1]) ) )



# (2) polygon node indices
file.write("%d # num_faces\n" % (len(mesh.loop_triangles)) )
file.write("# r g b / npts / id1 id2 id3 ... iduv1 iduv2 ...\n")
iface=-1
for face in mesh.loop_triangles:
    iface=iface+1
    vert_in_face = len(face.loops)

    if face.material_index<len(mesh.materials):
        mat = mesh.materials[face.material_index]
        # print "rgb=" ,mat.R, mat.G, mat.B
        file.write("%d %d %d #col\n" % ( (int)(mat.diffuse_color[0]*255), (int)(mat.diffuse_color[1]*255), (int)(mat.diffuse_color[2]*255) ))
    else:
        print ("no material")
        file.write("255 255 255 # no mat color\n")

    file.write("%d   " % vert_in_face) # == 3

    # print("face:")
    # for each vertex of that face
    for i in range (vert_in_face-1, -1, -1): # reverse faces
        # find the x,y,z node index
        vert_index=face.vertices[i]
        # print("node " + str(vert_index))
        file.write("%d " % (vert_index))

        # find the uv coord index for that vertex
        if (len(UVCoordinates) > iface):
            u = UVCoordinates[i].uv[0]
            v = UVCoordinates[i].uv[1]
            uvkey = (u, v)
            if not (uvkey in tex_list):
                file.write("0 ")
            else:
                file.write("%d " % tex_list[uv_key]);
        else:
            file.write("0 ")

    file.write("\n")


# (3) per frame vertex coordinates

"""
#We only have to do this once:
ob = bpy.context.active_object #getting the object we want.
dg = bpy.context.evaluated_depsgraph_get() #getting the dependency graph

#This has to be done every time the object updates:
ob = ob.evaluated_get(dg) #this gives us the evaluated version of the object. Aka with all modifiers and deformations applied.
me = ob.to_mesh() #turn it into the mesh data block we want.
"""
graph = bpy.context.evaluated_depsgraph_get() #getting the dependency graph

startFrame = scene.frame_start
endFrame   = scene.frame_end
file.write("%d #n keyframes\n" % (endFrame-startFrame+1))
file.write("# vertices: x y z nx ny nz\n")

vert_count = len(mesh.vertices);
for frameIndex in range(startFrame, endFrame+1):
    file.write("# frame %d\n" % frameIndex)
    #update the mesh objects vertex positions for the animation
    #set blender to the correct frame
    scene.frame_set(frameIndex)

    mesh_obj.evaluated_get(graph)
    mesh = mesh_obj.to_mesh()

    # get the vertices modified by the animation
    # animesh= mesh_obj.create_mesh(scene, True, 'PREVIEW') # FAILS
    # animesh.calc_normals()
    file.write("%d # nvertices, keyframe %d\n" % (vert_count, frameIndex))

    #now for the vertices
    for vert_counter in range(0, vert_count):
        #XYZ
        # vecpos = animesh.vertices[vert_counter].co * mesh_obj.matrix_world.transpose()
        vecpos = mesh.vertices[vert_counter].co #  * mesh_obj.matrix_world.transpose()

        #Normal
        # vecnor = animesh.vertices[vert_counter].normal # * mesh_obj.matrix_world.transpose()
        vecnor = mesh.vertices[vert_counter].normal
        # vecnor = unify_vec3 (mesh_obj.matrix_world.invert().transpose()*vecnor)

        new_x=-vecpos[1]
        new_y= vecpos[2] # swap y/z
        new_z=-vecpos[0]
        nor_x= -vecnor[1]
        nor_y=  vecnor[2] # swap y/z
        nor_z= -vecnor[0]

        file.write("%.3f %.3f %.3f %.3f %.3f %.3f\n" % (new_x, new_y, new_z, nor_x, nor_y, nor_z))

file.flush()
file.close()
print ("done.\n\n")


class ddaExporter(bpy.types.Operator, ExportHelper): """Save GLBasic 3D model""" # Tooltip bl_idname = "export_scene.id_export_dda" bl_label = "Export .dda" filename_ext = '.dda'

filepath = StringProperty(name="File Path", description="Filepath used for exporting the dda file", maxlen= 1024, default= "")
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})

def execute(self, context):
    export_dda(str(self.filepath), context)
    return {'FINISHED'}





def menu_func_export(self, context): from io_glbasic import export_dda import os default_path = str(os.path.splitext(bpy.data.filepath)[0] + ".dda") self.layout.operator(export_dda.ddaExporter.bl_idname, text='GLBasic dda (.dda)')

def register(): bpy.utils.register_class(ddaExporter) TOPBAR_MT_file_export.append(menu_func_export)

def unregister(): bpy.utils.unregister_class(ddaExporter) TOPBAR_MT_file_export.remove(menu_func_export)

if name == "main": register()

KungPhoo
  • 111
  • 2

0 Answers0