Forum Moderators: Staff
Poser Technical F.A.Q (Last Updated: 2024 Nov 13 12:50 am)
Welcome to the Poser Technical Forum.
Where computer nerds can Pull out their slide rules and not get laughed at. Pocket protectors are not required. ;-)
This is the place you come to ask questions and share new ideas about using the internal file structure of Poser to push the program past it's normal limits.
New users are encouraged to read the FAQ sections here and on the Poser forum before asking questions.
Okay, I think I've got a script that's streamlined enough to unleash onto a courageous few beta testers - a.k.a. whoever still follows this thread.
Get the code as a ZIP file from here or for git users, clone from https://github.com/odf/pydeltamesh.git.
Vague instructions:
A) Exporting the unmorphed mesh:
In Poser, load the figure, set to unimesh and the desired subdivision level, then export as OBJ with "As Morph Target" checked (sorry, no post-transform support at this point).
B) Making the morph:
In your favorite tool, import the OBJ from A), sculpt it to your heart's desire and export as OBJ again. Important: make sure to keep the vertex order and also (for now) the disconnected vertices intact.
C) Loading the morph:
Back in Poser, load the figure with the same settings as when exporting and make sure it's selected, then start the script via "Run Python Script" in the file menu. The path to use for the script is pydeltamesh/poser/loadSubdMorph.py within the unzipped folder.
The script asks for a name to give to the morph (if none given, the OBJ file name is used) and then pops up a file selection box where you can pick the OBJ created in B). After that, my Poser just seems to sit there for a few seconds before even showing a progress spinner, but eventually you should see a text box pop up with some diagnostics, and a dial for the new morph should appear.
-- End of vague instructions --
That's it for now. Undoubtedly there will be many bugs, so please be gentle with me.
-- I'm not mad at you, just Westphalian.
primorge posted at 7:18 AM Fri, 14 January 2022 - #4433229
Which unwelded bit are you referring to? There is no part of what I described that requires or would work with an unwelded mesh.The unwelded bit is a no go.
Will this work with a prop version of the figure, subdivided, in scene? That is, in order to skip the unwelding bit. Transferring the working fbm from the prop to the figure, or even cleaning up any local empties, is trivial.
If you are interpreting “disconnected vertices” as unwelded, my apologies. I mean that Poser exports a mesh with some vertices that are not in any faces, and you need to leave those in. Blender does that with “keep vertex order,” if it is a problem with other software, I can fix that.
-- I'm not mad at you, just Westphalian.
Loaded LaFemme Pro "out of the box" (no morphs). Saved it as ob-file with subD 2.(Slowwww.....).
Loaded the object into Blender. Made some changes and exported to another file.
Started your script: loadSubdMorph. Got an error message, because Python 2.7 doesn't know "Process time". Changed that to "time" and restarted. After a long while I got this with an error at the end:
Loading mesh from \\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\Data\untitled_blender.obj...
Loaded mesh with 387296 vertices and 383752 faces.
Subdividing for baking...
Subdivided 3 times.
Finding deltas for level 0
Found a total of 11565 deltas for 83 actors.
Subdividing morph for level 1...
Subdividing for baking...
Subdivided 2 times.
Computing vertex normals...
\\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\makeSubdivisionMorph.py:294: RuntimeWarning: invalid value encountered in divide
return ns / ds
Finding deltas for level 1...
Found 2884 deltas.
Subdividing morph for level 2...
Subdividing for baking...
Subdivided 1 times.
Computing vertex normals...
Finding deltas for level 2...
Found 10077 deltas.
Subdividing morph for level 3...
Computing vertex normals...
Finding deltas for level 3...
Traceback (most recent call last):
File "\\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\poser\loadSubdMorph.py", line 66, in <module>
loadSubdMorph(name, path)
File "\\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\poser\loadSubdMorph.py", line 27, in loadSubdMorph
targets = makeTargets(name, unwelded, welded, morph, used, verbose=True)
File "\\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\makeSubdivisionMorph.py", line 94, in makeTargets
name, weldedMorphed, morph, complexes, verbose
File "\\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\makeSubdivisionMorph.py", line 254, in makeSubdTarget
deltas, displacements = findSubdDeltas(verts, morphedVerts, normals)
File "\\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\makeSubdivisionMorph.py", line 269, in findSubdDeltas
diffs = morphedVertices[: len(baseVertices)] - baseVertices
ValueError: operands could not be broadcast together with shapes (387296,3) (1539199,3)
adp001 posted at 1:46 PM Fri, 14 January 2022 - #4433255
It's certainly numpy that's complaining, but the problem is with the inputs, namely here that the morphedVertices array does not have enough rows (i.e. vertices). So the actual error would have happened earlier, possibly in a different numpy operation, but it could also be something else.ValueError: operands could not be broadcast together with shapes (387296,3) (1539199,3)
Smells like a numpy error :)I found this hint:
This error occurs when you attempt to perform matrix multiplication using a multiplication sign (*) in Python instead of the numpy.dot() function.
My hope is that I made a last minute change that I forgot to check for Python 2.7 safety, because that would be easy to reproduce and debug. If it's a P11 versus P12 thing, things will be trickier.
PS: By "weird error" I didn't mean that I was unfamiliar with this kind of error message. I'm very familiar, it's basically numpy's way of saying hello. I meant it's weird specifically that this kind of error happened on that line.
-- I'm not mad at you, just Westphalian.
Oops, I just noticed: you used LaFemme at subD 2 but my script subdivided the subD 0 mesh it grabbed from Poser three times. That hints at either a mismatch between the two meshes or some edge case in the subdivision algorithm that I haven't covered. If it's something about LaFemme's mesh (and assuming the Pro version, which I don't have, doesn't use a modified mesh), I should see the same problem appear in P12.
I'll have a go at this after breakfast.
-- I'm not mad at you, just Westphalian.
So, I've tried it with LaFemme. Works in Poser 12, works in Python 2.7 on the command line. But I'm getting different numbers for the mesh:
Loaded mesh with 386835 vertices and 383504 faces.
Whereas you had:
Loaded mesh with 387296 vertices and 383752 faces.
So I'm still not sure if that's a P11 versus P12 thing, or LaFemme versus LaFemme Pro. It might be interesting to try a different figure. And it's probably useful if I add some more diagnostics and make the script bail out right away if the face counts don't match.
-- I'm not mad at you, just Westphalian.
With a loaded LaFemme:
fig=sc.CurrentFigure()
[ac.Name() for ac in fig.Actors() if not ac.IsBodyPart()]
[u'CenterOfMass', u'GoalCenterOfMass', u'rThumb0Con', u'rIndex0Con', u'rMid0Con', u'rPinky0Con', u'rRing0Con', u'lThumb0Con', u'lIndex0Con', u'lMid0Con', u'lRing0Con', u'lPinky0Con', u'UpperBrowCon', u'RightOuterBrowCon', u'LeftOuterBrowCon', u'MidBrowCon', u'RightInnerBrowCon', u'LeftInnerBrowCon', u'RightUpperEyeLidCon', u'LeftUpperEyeLidCon', u'RightLowerEyeLidCon', u'RightUpperCheekCon', u'LeftUpperCheekCon', u'RightLowerCheekCon', u'LeftLowerCheekCon', u'NoseCon', u'RightNostrilCon', u'LeftNostrilCon', u'UpperLipCon', u'RightUpperLipCon', u'RightLipCon', u'LeftUpperLipCon', u'LeftLipCon', u'RightEarCon', u'RightEarLobeCon', u'LeftEarLobeCon', u'LeftEarCon', u'LeftLowerEyeLidCon', u'RightBreastCon', u'LeftBreastCon', u'RightGluteCon', u'LeftGluteCon', u'LowerLipCon 1', u'RightLowerLipCon 1', u'LeftLowerLipCon 1', u'JawCon', u'RightLabiaCon', u'LeftLabiaCon', u'MonsPubisCon']
All this actor are not bodyparts. But they will be exported and interfere a lot when sculping in Blender.
odf posted at 4:28 PM Fri, 14 January 2022 - #4433264
LaFemme Pro shouldn't make a difference.So, I've tried it with LaFemme. Works in Poser 12, works in Python 2.7 on the command line. But I'm getting different numbers for the mesh:
Loaded mesh with 386835 vertices and 383504 faces.
Whereas you had:
Loaded mesh with 387296 vertices and 383752 faces.
So I'm still not sure if that's a P11 versus P12 thing, or LaFemme versus LaFemme Pro. It might be interesting to try a different figure. And it's probably useful if I add some more diagnostics and make the script bail out right away if the face counts don't match.
I tried with Bella too. Same errors.
Do any of these have geometry? I tried to export some from P12 and got empty files. Maybe P11 handles them differently.With a loaded LaFemme:
fig=sc.CurrentFigure()
[ac.Name() for ac in fig.Actors() if not ac.IsBodyPart()]
[u'CenterOfMass', u'GoalCenterOfMass', u'rThumb0Con', u'rIndex0Con', u'rMid0Con', u'rPinky0Con', u'rRing0Con', u'lThumb0Con', u'lIndex0Con', u'lMid0Con', u'lRing0Con', u'lPinky0Con', u'UpperBrowCon', u'RightOuterBrowCon', u'LeftOuterBrowCon', u'MidBrowCon', u'RightInnerBrowCon', u'LeftInnerBrowCon', u'RightUpperEyeLidCon', u'LeftUpperEyeLidCon', u'RightLowerEyeLidCon', u'RightUpperCheekCon', u'LeftUpperCheekCon', u'RightLowerCheekCon', u'LeftLowerCheekCon', u'NoseCon', u'RightNostrilCon', u'LeftNostrilCon', u'UpperLipCon', u'RightUpperLipCon', u'RightLipCon', u'LeftUpperLipCon', u'LeftLipCon', u'RightEarCon', u'RightEarLobeCon', u'LeftEarLobeCon', u'LeftEarCon', u'LeftLowerEyeLidCon', u'RightBreastCon', u'LeftBreastCon', u'RightGluteCon', u'LeftGluteCon', u'LowerLipCon 1', u'RightLowerLipCon 1', u'LeftLowerLipCon 1', u'JawCon', u'RightLabiaCon', u'LeftLabiaCon', u'MonsPubisCon']
All this actor are not bodyparts. But they will be exported and interfere a lot when sculping in Blender.
-- I'm not mad at you, just Westphalian.
At the moment, the script keeps subdividing the base level mesh as long as it has fewer faces than the mesh that was loaded in from file. So if the latter has extra polys that shouldn't be there, an additional subdivision level will result. That's obviously not a very robust strategy, so I'll change it and throw an exception instead.I definitely set SubD 2 (also for Bella), and your script tells something about "Subdividing morph for level 3".
-- I'm not mad at you, just Westphalian.
I'm soooo sorry! All good! Works!
Loading mesh from \\VBOXSVR\Poser\Poser\Python\Rendo\pydeltamesh\Data\untitled_blender.obj...
Loaded mesh with 386835 vertices and 383504 faces.
Subdividing for baking...
Subdivided 2 times.
Finding deltas for level 0
Found a total of 24478 deltas for 83 actors.
Subdividing morph for level 1...
Subdividing for baking...
Subdivided 1 times.
Computing vertex normals...
Finding deltas for level 1...
Found 3193 deltas.
Subdividing morph for level 2...
Computing vertex normals...
Finding deltas for level 2...
Found 9408 deltas.
Morph loaded in 23.4530000687 seconds.
Problem was here. I changed Blender from 2.9 to 3. But had not yet adjusted my preferences.
Threw an error from 11 to Mubox. Figure is Nova with 2 levels subdivision. Might be a Mudbox thing though, honestly I don't think I've ever morphed in Mudbox without using the PML exporter. I've been using it so long that my memory is vague on that. I'll have to test that particular with a regular FBM without PML exporter. In any case I'll test via Blender 2.92 and report back. Here's the test morph imported into Poser from Mudbox as a prop. Here's the Python Error message.
I do have one question however, you didn't mention whether 'Include Existing Groups in Polygon Groups' was requirement during initial export. In this instance all I checked was 'as Morph Target' as you stated in your instructions...
Tested FBM from Mudbox via both unwelded scene export ang geometries import. Without PML the FBMs do not translate working into Poser. Looks like the groups are borked. Single actor morph targets work fine however, no wrong # verts error or winding order explosions.
So for Mudbox it's very likely not your scripts fault. Looks like PML will stay my method for morphing with MB.
For my usage, bear in mind I have Zbrush, this will be useful for Blender SubD morphs only. Going to test Blender now...
Threw an error from 11 to Mubox. Figure is Nova with 2 levels subdivision. Might be a Mudbox thing though, honestly I don't think I've ever morphed in Mudbox without using the PML exporter. I've been using it so long that my memory is vague on that. I'll have to test that particular with a regular FBM without PML exporter. In any case I'll test via Blender 2.92 and report back. Here's the test morph imported into Poser from Mudbox as a prop. Here's the Python Error message.
That looks like Mudbox might be removing isolated vertices. If I'm right, the second (larger) number in the error message should be the vertex count of the mesh exported from Poser, and the first (smaller) one should be what comes out of Mudbox. Also, both meshes should have the same number of polygons.
The requirement that the isolated vertices must be preserved is a relic from my original command line script. Within Poser I can easily add code that fixes the numbering for that specific case. Unless you're very eager to get the Mudbox test working, I might defer that until after I've finished the post-transform option (i.e. probably tomorrow).
I do have one question however, you didn't mention whether 'Include Existing Groups in Polygon Groups' was requirement during initial export. In this instance all I checked was 'as Morph Target' as you stated in your instructions...
No, that's not a requirement, unless you want access to the group info in your modeler. My script doesn't use the groups.
-- I'm not mad at you, just Westphalian.
We shouldn't give up on Mudbox that quickly. Unless PML does something unconceivably clever, if it can deal with your MB outputs, my script should be able to, too, possibly after some small adjustments.Tested FBM from Mudbox via both unwelded scene export ang geometries import. Without PML the FBMs do not translate working into Poser. Looks like the groups are borked. Single actor morph targets work fine however, no wrong # verts error or winding order explosions.
So for Mudbox it's very likely not your scripts fault. Looks like PML will stay my method for morphing with MB.
For my usage, bear in mind I have Zbrush, this will be useful for Blender SubD morphs only. Going to test Blender now...
-- I'm not mad at you, just Westphalian.
Tried same with Blender. Received a different error this time. Error screencap, morph prop screencap...
Yes, she's still recognizable. It's the nose and the lips, I didn't morph them at all for these tests.
Anyway. Not having much luck... not blaming your script either. Could be so many things. I did follow the instructions however. I'll try again later. Sorry I couldn't help.
Not at all! That's very helpful. Sorry about the frustrating experience so far, but every error message makes the script a little better.Anyway. Not having much luck... not blaming your script either. Could be so many things. I did follow the instructions however. I'll try again later. Sorry I couldn't help.
-- I'm not mad at you, just Westphalian.
End-of-day update: post/pre transform morphs both seem to be working now, and I have two improvements to OBJ loading on my list for tomorrow.
primorge: I think your Blender exports should work if you export with normals and/or UVs, but that would be silly as a restriction, seeing as the script does not use either. Easy to fix, though!
-- I'm not mad at you, just Westphalian.
So, a new version is up at the same location with the following three changes:
1) There is now an additional dialog that lets one choose between creating a pre- or a post-transform morph.
2) The OBJ file for the morph can now contain "f" lines without slashes, so e.g. Blender exports with neither normals nor UVs should now work. That fixes an oversight of mine that tripped up primorge's Blender test.
3) The input mesh is no longer required to have isolated vertices preserved from the original Poser export. Of course the order of the remaining (non-isolated) vertices still needs to be kept intact. This might fix the problem with the Mudbox export, but without looking at the actual OBJ files that is of course just a guess.
Hopefully this version will prove more successful.
-- I'm not mad at you, just Westphalian.
Also, I might take a break from this project for a bit, apart from bug fixes and urgent feature requests. I'm pretty happy with how it turned out so far, and it's probably best to let real usage experience drive further developments.
Maybe I'll spend a few days with just sculpting and/or clothes making practice...
-- I'm not mad at you, just Westphalian.
odf posted at 5:53 PM Sat, 15 January 2022 - #4433335
Sounds great. I've gone down a rabbithole with painting eye maps so haven't had time to test further, but I have off tomorrow so I'll take a break from texturing and give the new version a spin, the additional tweaks sound great... crossing fingers. If the mudbox export throws an error I'll save the example obj for you to look at via PM link.So, a new version is up at the same location with the following three changes:
1) There is now an additional dialog that lets one choose between creating a pre- or a post-transform morph.
2) The OBJ file for the morph can now contain "f" lines without slashes, so e.g. Blender exports with neither normals nor UVs should now work. That fixes an oversight of mine that tripped up primorge's Blender test.
3) The input mesh is no longer required to have isolated vertices preserved from the original Poser export. Of course the order of the remaining (non-isolated) vertices still needs to be kept intact. This might fix the problem with the Mudbox export, but without looking at the actual OBJ files that is of course just a guess.
Hopefully this version will prove more successful.
Thanks for all your hard work on this.
If the mudbox export throws an error I'll save the example obj for you to look at via PM link.
That would be great. The original Poser export too, please.
Thanks for all your hard work on this.
Gladly! It's what I do for fun in these parts.
-- I'm not mad at you, just Westphalian.
primorge posted at 5:47 PM Mon, 17 January 2022 - #4433421
Argh! I forgot that print is not function in Python 2. Sorry! If you feel adventurous, you can just change that line to "log = None" for now (don't change the line indentation, though).Tried again, latest ver., with MB... got an invalid syntax error.
The fixVertexOrder script will have the same problem. I'll have an updated download for both up shortly.
ETA: The fixed version is now up.
-- I'm not mad at you, just Westphalian.
Thanks again for the timely support... starting to feel like a nag lol.
It's not like my efforts at learning MD are particularly time-critical. My response times will increase significantly when I'm back at my day job.
-- I'm not mad at you, just Westphalian.
This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.
Daily update: I appear to have successfully implanted the script into Poser. Grabbing the correct mesh data from the API (as in, matching what Poser would produce in unwelded/welded OBJ exports) proved more tricky than expected, but I got that working literally fifteen minutes ago.
Tests and cleanups to be scheduled for tomorrow. Also I'll see if I can get profiling to work from inside Poser so that I have a better idea of which parts take how much time. The general impression though is that the script is not significantly slower than the command line version.
ETA: Probably time to move to the Poser Python forum soon, since from here on I suspect it'll be mostly about GUIs and APIs.
-- I'm not mad at you, just Westphalian.