Problems exporting shape keys to text file

Hello, I’ve had some success getting shape keys out of Blender and into a CSV text format recently, but I’ve run into a problem that may take me awhile to solve. If anyone could be of assistance, I’d greatly appreciate it.

I’ll explain my goal first. I’d like to be able to export meshes from Blender, and then add shape keys to those exported meshes at a later date as I see fit by importing shape keys from Blender as csv files in another application. However, I’m going to export the models to PMX format, which means they will be triangulated and split, as the programs I’m exporting them for are designed to operate in real time.

This presents a problem to me because while I’ve figured out how to get the information I need to put into the CSV file for the mesh as it appears in Blender, when the mesh is exported, new vertices are created at UV seams. Because shape keys are highly dependent on vertex order, this throws a wrench into my entire plan. I need to know how to predict what the new vertex index order will be in order for this to work.

I’m guessing what the vertex order is after export is fully dependent on the programming of the exporter, so common sense tells me to study the exporter script. Am I wrong in this idea? Unfortunately, I am very new to Python and programming in general, so it’s not easy for me to tell what’s going on at all. The particular exporter I’m using is available for free here:

although it’s a little complicated to use and the instructions are written in Japanese.

In any case, if anyone thinks they could help a poor soul out I’d greatly appreciate it. Perhaps the best solution would be to simply split the mesh along its seams using the Edge Split modifier inside of Blender before exporting? Does anyone know for sure if the Edge Split modifier is 100% consistent in the vertex order it produces(using the split by sharp setting)? I really know almost nothing about vertex order in Blender.

But, ideally, I would like to be able to predict the vertex order that’s going to result from an export and use that information to simply make a csv file tailored to the exported model.

Apologies if I’ve been unclear.

From your explanation, it sounds like you should adapt the original export script so that it outputs shape key data along with the model. It’s still a complicated task I guess.

Thanks for your response. Unfortunately, that wasn’t quite the solution I was looking for, partially because unforunately that exporter consumes a ton of memory if you’ve got a lot of shape keys. And also because I wanted a way to just quickly export a single shape key in a way that it could be imported to an existing model in a different program.

However, I was able to write some code that actually exports shape keys to a CSV file. I was also able to make it do a few other things too, like reset the transform value of vertices whose transform values are too small to be significant, which is a problem when merging shapes from .obj files after editing them in applications like Zbrush.

If anyone’s interested this is the actual function I made for it. With slight modification you can make it export single shape keys to a CSV file.
There’s also some formatting information in there, which is just there to make the CSV file compatible with PMXEditor’s morph importer.

def MorphstoCSV(cutoff,morfile):
morfile = open(str(morfile) + “.csv”,“w”)
obj =
#data path of the basis shape key; a collection. in other words, the shape key’s data itself?
basis = shapes[0].data
for shape in shapes:

    morphName =
    premorphString1 = "Morph,"+"\""+morphName+"\""","+"\""+morphName+"\""+","+"4,1" + "

morphString = “VertexMorph,”+"""+morphName+"","
for vert in
#gets the coordinates of the vertex in basis shape
cobasis = basis[vert.index].co
#gets the coordinates of the vertex in the morphed state
comorphed =[vert.index].co

        delta = comorphed - cobasis
        if delta.length > cutoff:
            moco = delta.xzy
            print (moco)
            mocostr = ",".join(map(str,((array(moco)).tolist()))) + "

morfile.write(morphString + str(vert.index) + “,” + mocostr)
else:[vert.index].co = basis[vert.index].co


Where morfile=filename and cutoff=a float value for the minimum delta of vertices to be kept in the morph(phrased differently, the cutoff point for total transform value on XYZ for the vertex; any vertex that doesn’t transform this much is cut off from the shape key).

If anyone’s got criticism of the code/suggestions I’d be happy to hear it, although I pretty much just wrote it for personal use so it’s pretty messy. Either way, I’m a beginner so I imagine it’s full of problems.