Transfer shape keys does not work for figures that are exported with a non-zero world transform
If I move a figure to somewhere that is not the 0,0,0 in world coordinates and export, then transfer shape keys in blender does not work. Reason is that all shape keys are skipped because this:
if self.outsideBox(srcboxes[sname], trgbox):
print(" 0", sname)
continue
will be true for all of them. When you export you use var geom = obj.getCachedGeom();
and then get the vertices from that, but getCachedGeom
returns:
- The final world-space transformed mesh for the current shape.
and so the vertices will be different depending on where the figure is located. Why not just use getGeometry
? The script also sets the LOD to 0 for the figure so that the mesh is exported without subd applied, so it shouldn’t make a difference if getGeometry
was used. Alternatively the script should apply the inverse world transform of the object to every vertex. Or maybe just move the figure to 0,0,0 (and rotation and scale) before exporting the vertices.
Comments (12)
-
reporter -
reporter Also I found one other problem while investigating the problem, in merge.py, in reparentObjects, you call setWorldMatrix. That will update the world matrix of the figure mesh and then the transfer code will complain about the world transform not being applied to the mesh. So if you merge the face controls, and then try to transfer shapes it won’t work. I fixed that temporarily by writing a check so that
setWorldMatrix(ob, wmat)
is only called when the parent actually changed, otherwise I don’t actually see why you would want to set the world matrix in there?def reparentObjects(self, info, rig, adds, hdadds, removes): for ob,data in info.objects: partype, parbone = data if partype in ['VERTEX', 'VERTEX_3', 'VERTEX_TRI']: continue parentIsDifferent = ob.parent != rig if partype == 'BONE': if parbone in rig.pose.bones.keys(): parentIsDifferent = parentIsDifferent or ob.parent_bone != parbone else: parentIsDifferent = parentIsDifferent or ob.parent_bone != info.getBoneKey(parbone) wmat = ob.matrix_world.copy() ob.parent = rig ob.parent_type = partype if parbone is None: pass elif parbone in rig.data.bones.keys(): ob.parent_bone = parbone else: ob.parent_bone = info.getBoneKey(parbone) if parentIsDifferent: setWorldMatrix(ob, wmat) self.addToCollections(ob, adds, hdadds, removes)
-
reporter Oh, now I tried
getGeometry
and I see what the problem is. The mesh is not where is should be then when importing, so the code relies on the vertices being in world space when the scene is build in blender, so that armature and mesh line up correctly. Ok then. -
- changed status to open
-
repo owner Sorry, but I don’t understand. A DS object doesn’t have a method called getGeometry as far as I know (I tried and the script failed). The cached geometry at LOD = 0 is used because it gives the figure with all morphs applied and transferred to clothes. At least I didn’t find another way to achieve that. Other methods return the unmorphed mesh, but I don’t need that because it is already available in the dsf files.
-
reporter The shape has a method getGeometry: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/shape_dz#a_1aa9deb3323e1489d3ce5f771dba7cb7fe And you actually use that in the script for exporting HD meshes: https://bitbucket.org/Diffeomorphic/import_daz/src/1a683b034517db81fb67d557ba6de20193cab486/to_daz_studio/Scripts/Diffeomorphic/export_highdef_to_blender.dsa#lines-206
-
repo owner But that method returns the unmorphed mesh. The morphed armature is found in the duf file, but the morphed mesh is normally not. Here what I get when I replace obj.getCachedGeom with shape.getGeometry:
-
repo owner Note that in the HD script, the only thing that shape.getGeometry is used for is to get the number of vertices of the base mesh, not the vertex locations.
-
reporter Ok, trying to reproduce the issue manually by doing all the steps I do in my addon actually fails. So I can figure this one out by going through what I do differently when importing and transfering shape keys programmatically. I do just call the diffeo operators usually, so that is why I thought there is a bug.
-
reporter Alright, my problem is I call apply_rest_pose after importing (don’t remember why though), and that resets the object pivot to the world root. And I assume that then throws off the bounding box calculation.
-
reporter - changed status to resolved
I'll close since the actual issue is not a bug in diffeo.
-
- changed status to invalid
not a bug
- Log in to comment
Moving the figure to 0,0,0 before exporting is a bad idea, it would mean you need to get the cached geometry again, so lets ignore that.