- edited description
better triax conversion
1.7.2.1794
The actual conversion from triax to general weight is unfortunately quite rude, both in daz studio and inside the addon. Once we import a G1 G2 figure and try to pose it we get spikes and artifacts around.
We can definitely improve the conversion by smoothing the weightmaps, not too much to avoid “jelly“ effects, the parameters below seem optimal to me. We may include an option in global settings to smooth triax, possibly with a smooth level default to 4.
steps:
- enter weight paint and smooth the pose bones, factor = 0.5, iterations = triax smooth in global settings
Below a comparison for G2F before and after the smooth. We see the deformations are effectively improved.
bug. triax warning. Actually the addon doesn’t warn for triax weight when we load a G2 figure. Oddly it warns for triax weight if I convert to general weight in daz studio. Some daz figures include both triax and general weight, that is “blended weight” that would use triax and general together, in this case we can approximate with general weight alone, essentially we lose the bulges from triax but this is minor.
Note that scale maps are always ignored with no warning since blender doesn’t support separate weightmaps for scale.
# weight conversion
if there’s general weight + triax maps
warn for blended weight
use general weight and ignore triax
else if there's general weight alone (G3 G8 G9)
no warnings
use general weight
else if there's triax alone (G1 G2)
warn for triax
do triax conversion and smoothing
else if there's no weight maps (old Poser content V3 V4)
warn for no weight maps
do automatic weight in blender
Comments (33)
-
reporter -
reporter Here’s some reference if you like to dig in.
-
reporter request. triax maps ?
Thomas, if we may have an option to import the triax maps, perhaps in the debug section. I’d like to do some tests to see if I can get some better conversion out of them. Otherwise I have no way to extract triax maps from daz figures.
-
repo owner I added a global option to generate all triax weights.
-
reporter Commit f23e9d4.
Now G2 warns for triax weights, thank you for the fix.
The global option for triax works wonderful, thank you. I see you only import xyz maps, for triax there’s also bulge maps that are important for some bones. If it is not a hassle it would be nice to have them imported to experiment with. Let me know.
I see you didn’t implement the triax smoothing. I understand we can do it by hand, but when we import a full G1 G2 figure with hair outfit and accessories, smoothing by hand every single mesh can be time consuming. Having a global option to do so would be handy. Let me know.
-
repo owner Triax smoothing and bulge groups are added in the last commit. You get scale groups too even though you didn’t ask for it. THe local and bulge groups are not smoothed since the don’t have associated bones.
-
reporter Commit 26cac7b.
The triax smooth is wonderful thank you for the fix. There’s no use for scale maps since blender doesn’t support separate weightmaps to scale bones, but for completeness they may be interesting to have.
p.s. Will leave this open for a while to see if I can come out with something, also if others want to contribute now that we have triax maps for testing.
possible bug. global settings. I noticed that, differently from before, when we change a global setting we have to restart blender for the new setting to apply. This may not be a bug but something to be aware of. Also a minor nuisance if we have to change some settings inside the work session.
-
repo owner You shouldn’t have to restart Blender for the new settings to take place. However, I had misspelled a few settings which meant that the settings dialog didn’t update the real settings when it was closed. Also, if there is a new setting, like Smooth Triax Weights today, it seems necessary to restart Blender.
Another thing that has happened to me is that the mouse hovered over a checkbox when I hit return. Then Blender changed the checkbox before saving the settings. Very irritating.
-
reporter update. exploring triax.
I will use this discussion to explore triax, with the goal to eventually provide some support for triax in blender. This would allow to use G1 G2 figures with deformations similar to daz studio. Also, now that Thomas made triax maps available, anyone can experiment and contribute.
1. dual quaternion. The first thing we notice is that triax is based on dual quaternion. While the triax maps provide independed axes and displacement, the base layer is dual quaternion. So it is good to keep "preserve volume" enabled when we import triax in blender.
Below there's a comparison where I only use the triax map for bending, it's the same in blender and daz.
2. bulge maps. These are necessary to sculpt deformations, for example for knees and elbows. The daz panel provides two parameters to define the bulge intensity, "positive" and "negative" are for positive and negative values of the axis euler rotation. Note that left and right maps are provided for each axis.
In my tests a 0.002 factor provides a good match for a 90 degree rotation that I normalize with.
# triax bulge, same for left right maps, same for x y z axes if rotation x > 0 displacement = x bulge left * x bulge positive left * 0.002 * abs(rotation x / 90) if rotation x < 0 displacement = x bulge left * x bulge negative left * 0.002 * abs(rotation x / 90)
note. bulge to jcm. Note that the displacement modifier could be baked to a shapekey and converted to a jcm with a driver, following the equations above. This way we could have triax bulges in blender.
Below an example where I used the bulge map for the thigh in blender.
Below another example where I used the bulge map for the forearm, always following the equations above. We get a nice triax elbow in blender.
3. independent axes. This is the most interesting part, and probably harder to get in blender. Will update on this.
-
reporter update. triax bulges implementation.
After some testing I believe the actual conversion with triax smoothed weights is not bad for practical use. What we really miss is to import the triax bulges for deformations, to avoid the “jelly joints“ look. This is equivalent to jcms for general weight, we could have a “import triax bulges“ tool in the morphs panel, eventually also added to easy import as default for G1 G2.
The implementation seems not hard. Basically we turn the bulge maps into shapekeys via displacement modifiers, then add drivers following the equations above. I did a test scene triax.blend where I implemented the bulges for the G2F left elbows and knees, that can be used as reference. Note that bulges can be implemented either with displacement or jcms, in the test scene I included both versions, but I believe jcms is the ideal solution since having lots of displacements in the figure is not common practice.
To generate shapekeys from displacement I used a -0.02 factor, since this gives a nice shapekey same as if it was sculpted by the artist. I believe it is important to have a nice visual feedback for the shapekey.
# triax bulge, same for left right maps, same for x y z axes if rotation x > 0 displacement = x bulge left * x bulge positive left * 0.002 * abs(rotation x / 90) if rotation x < 0 displacement = x bulge left * x bulge negative left * 0.002 * abs(rotation x / 90) # driver conversion for displacement, 1.571 is for radians x_bulge_positive_left * 0.002/1.571 * X if X > 0 else x_bulge_negative_left * -0.002/1.571 * X if X < 0 else 0 # driver conversion for shapekeys # we bake with a -0.02 factor for a nice shapekey, so 0.002/-0.02 = -0.1 x_bulge_positive_left * -0.1/1.571 * X if X > 0 else x_bulge_negative_left * 0.1/1.571 * X if X < 0 else 0
Below there’s the test scene with two G2F figures featuring displacement and jcm bulges. @Thomas Larsson let me know what you think if you can implement this, also of course if something is not clear. This would be a nice step forward for triax.
-
reporter - attached triax.blend
example of triax bulges with displacement or jcms.
-
reporter - marked as major
-
reporter note. shapekey limits.
For jcms I baked the bulge maps with a -2 cm offset that gives a nice shape sculpted on the base mesh. Now we don’t really know how much the bulge expression will push the bulge, so in the test scene I used +- 2 limits for the shapekeys that gives a max 4 cm offset from the base mesh. May be it’s better to use +- 5 limits for a max 10 cm offset that should be safe for any corrective bulge.
Note that the same bulge map can be used both with positive and negative offset by the bulge expression, depending on the positive or negative euler rotation, this is why we need both positive and negative limits.
Note that the limits don’t influence the expression itself, they’re just a “clamp“ for it.
-
repo owner Implemented in last commit. When the G2 character is imported, you have to press the Morphs > Create Bulges button to convert the vertex groups to shapekeys. Once we are confident that the bulges are correct, we might remove the button and create the bulge shapekeys directly when the character is imported.
I also removed the warning about triax weights.
-
reporter Commit 46ae3c3.
That’s AMAZING thank you for this. Below a couple notes, but I believe we’re essentially there.
1. bug. shapekeys baking. It looks like you didn’t bake the displacement right, probaly you used a 1cm factor instead of 2cm. This way the bulges are half the height. If you pin the shapekeys in the test scene you see that the actual implementation has lower bulges.
2. triax warning. While this is certainly a good improvement, we’re far from perfect in importing triax. I mean general weight is imported same as daz studio, while triax is a “not bad“ approximation. So a warning may make sense anyway, as for example “warning: triax approximation used“.
3. bulge conversion option. This is equivalent to jcms for general weight. So we may want to select the bulges to convert, same as we select the jcms to convert. This is useful to customize or optimize the figure, plus we may not want bulges for prebended figures imported as dbz.
Let me know, and thank you again.
-
repo owner The problem was that I missed to set the mid_level of the displace modifier, so it was set to the default 0.5. The other changes have also been made. The vertex groups are removed even if the bone is not selected, so you have only one chance to create the bulge shapekeys. I’m not sure that this is what we want, but we probably don’t want that a lot of unused vertex groups are left behind either.
-
reporter Thank you so much, I’m evaluating the new commit and will let you know. I can confirm the shapekey bug is fixed.
-
reporter 1.7.2.1825
update. triax twist implementation.
If we look at G2F in daz studio we can see that arms and legs twist nicely, sort of the twist bones in G8F, this is due to the triax twist maps. We can achieve something similar by adding twist bones to G2F and using the triax twist maps.
1. triax to general. The first step is to convert triax to general weight. Here we don't need twist because we deal with it later for specific bones. Also because the triax twist maps are not straightforward to use and require special treatement for each bone, as we'll see below.
Here we only use bend and side maps by average, then we smooth. Of course this is a simplification of triax.
# convert triax to general weight general weight = normalize(average(triax.bend,triax.side)) smooth
note. The bend and side for triax can be any axis depending on the bone. So we have to check the daz labels. Same for twist it can be any axis.
note. The actual implementation is not bad, but it leaves "artifacts" around and I'm not sure if this is because it also tries to integrate twist maps, that's not possible in the general case.
2. twist bones. Once we have the general weight in place we add the twist bones. Not all bones need a separate twist, we only add twist to arms and legs same as G8F. Again this is a simplification of triax, same as it was a simplification averaging bend and side.
In the procedure below, note that the twist bone takes the general weight map, while the original bone takes the twist map. This is sort of reversed, but we need this because the pose to copy from is in the original bone.
To convert the triax twist map to a general weight twist map we have to limit the twist to the range of the bend-side map, so we multiply. Below an example where we see that the twist map for the arm extends to the forearm, this can't work in general weight.
# add twist to arms and forearms, same for l/r duplicate bone lShldr to lShldr.TWIST copy rotation XZ from lShldr to lShldr.TWIST lShldr.TWIST map = general weight lShldr map = normalize(multiply(triax.twist,general weight)) duplicate bone lForeArm to lForeArm.TWIST copy rotation XZ from lForeArm to lForeArm.TWIST lForeArm.TWIST map = general weight lForeArm map = normalize(multiply(triax.twist,general weight)) # add twist to legs, same for l/r duplicate bone lThigh to lThigh.TWIST copy rotation XZ from lThigh to lThigh.TWIST lThigh.TWIST map = general weight lThigh map = normalize(multiply(triax.twist,general weight))
3. tweak for forearm twist. For the forearm twist map I used the twist map of the hand, this is because the twist map for the forearm doesn't extend to the wrist so we can't use it for general weight. Luckily the triax for G1 G2 is similar so we can use this same tweak for both.
4. final result. Below the final result, test scene included triax-twist.blend. I added twist to the left side and we can see the difference with the right side that doesn't include twist bones. The effect is similar to the triax twist.
Of course let me know if something is not clear.
-
reporter - attached triax-twist.blend
test scene for triax twist
-
reporter note. forearm twist and outfits.
I had a doubt about the forearm tweak for the twist bone, since we take it from the hand, that it may have issues with outfits. But, looking at some G2 outfits with long sleeves, it seems the hand twist map is always included for the sleeve, probably transferred from the base figure.
So the forearm tweak seems safe with outfits too.
-
repo owner I have implemented the first two steps above, but it probably doesn’t work because I don’t understand how the vertex mix modifier works. Quaternions must be disabled in the global settings for now.
-
reporter Commit c10c8b4.
Thank you for looking at this. I had a look at your code and I believe to understand what’s wrong, beware that I know very little of python and the blender api, so please verify. The documentation for the mix modifier can be found in the blender manual as usual. But I believe you confuse the modifier name with the map name, that is, the modifier affects “vertex group A“ as final result.
https://docs.blender.org/manual/en/latest/modeling/modifiers/modify/weight_mix.html
bug. general weight. I see you convert to general weight the twist bones. Here there are three errors. First this is to be done for all bones instead of the actual conversion, not only for twist, with smooth as a final pass. Second we have to assign the bend map to the bone first, that is, we have to rename the map from “bone:x” to “bone” to bind then use it as “vertex group A“, and “bone:z“ as “vertex group B“. Third we don’t know if bend is X and side is Z, in daz it can be any axis, we have to look at the daz labels or at the conversion table if there’s any.
bug. twist weight. Then when you convert twist there’s the same error. We don’t know if twist is Y.
bug. skinbinding. The weight mix must be done before the armature in the modifier stack, not after.
As for quaternion there shouldn’t be any trouble, apart we have to use the explicit euler order for copy rotation.
Let me know.
-
reporter As an example I’ll do lShldr.
steps for general weight, with smooth as final pass after all bones are done:
- rename the vertex group “llSldr:z“ to “lShldr“ since Z is the bend axis in daz, this binds the bone
- mix with “lShldr“ as “vertex group A“ and “lShldr:y“ as “vertex group B“ since Y is the side axis in daz
steps for twist, after general weight is done:
- rename the vertex group lShldr to lShldr.twist, since the twist bone takes the general weight
- rename the vertex group “lShldr:x“ to “lShldr“, since X is the twist axis in daz, this binds the main bone to the daz twist map
- mix with “lShldr“ as “vertex group A“ and “lShldr.twist“ as “vertex group B“
edit. errata corridge. I corrected the steps for twist.
p.s. Of course I used modifiers because I can’t code python, there may be functions in the blender api to do the same.
-
repo owner I made the changes but now it doesn’t work at all. This is strange because the vertex groups are present in weight paint mode. I made a commit so you can have a look.
-
reporter Commit 0add656.
The weightmaps look good, apart that we have to use the hand twist triax map instead of forearm twist as in point 3 above, please fix this. You just forgot to set the bones as “deform“ that’s why the mesh doesn’t move.
notes. important. I see you left the modifiers there in the last commit, I understand this is to let me see them. Of course you can apply the modifiers after mixing we don’t need them. Also we have to smooth after creating the general weights and before creating the twist weights, that you didn’t.
We may remove the triax smooth option from the global settings since smooth for general weight must be done, triax conversion is not good without smooth.
-
repo owner Things may be working now. I applied the vertex mix modifiers for general bones, but left them for twist bones for now. We can also remove the unused vertex groups (:z) once the modifiers have been applied.
-
reporter Commit 51604ea.
Thank you for your work and patience so far. This is what I found.
bug. forearm tweak. I see in the mix modifier that to get the forearm tweak you multiply the forearm twist map with the hand twist map. This is wrong, instead we need to multiply the forearm general weight map with the hand twist map.
# forearm tweak, same for l/r apply the general weight modifiers, this includes shldr.twist forearm.twist thigh.twist copy forearm.twist to forearm, this copies the general weight mix forearm with hand:x
bug. smooth. We can’t keep the mix modifiers, otherwise smooth doesn’t work because the mix comes in the way. It is important to apply all modifiers before smoothing. So smoothing comes as a last pass after all weights are computed and all mix modifiers are applied.
# smooth triax apply all mix modifiers smooth all
bug. G8. I get an error when I load g8f.
Loading C:\Users\Alessandro\Documents\DAZ 3D\Studio\My Library\Scenes\g8f-base.duf
Parsing data
Preprocessing...
Building objects...
Ignore <Instance Tonemapper%20Options-1 L:Tonemapper Options 0 N: Tonemapper Options P: None R: None>
Ignore <Instance Environment%20Options-1 L:Environment Options 0 N: Environment Options P: None R: None>
Add triax twist bones: Genesis 8 Female
Traceback (most recent call last):
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\error.py", line 223, in execute
self.run(context)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\main.py", line 286, in run
self.loadDazFile(filepath, context)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\main.py", line 180, in loadDazFile
asset.postbuild(context, inst)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\modifier.py", line 663, in postbuild
eb = rig.data.edit_bones[bname]
KeyError: 'bpy_prop_collection[key]: key "lShldr" not found'note. triax debug. If possible it would be useful to keep the triax debug option, otherwise there’s no way to do further experiments since the maps are lost when we load the figure. Ideally we need to always keep the original triax maps when the debug option is enabled.
note. minor. wire viewport ? I see you set wireframe in the object viewport display properties. This is unexpected and not necessary, I guess it is a leftover from debugging.
-
repo owner OK, everything should be fixed now. The new triax debug option does several things:
- Duplicate the local weights groups.
- Keep vertex group modifiers.
- No smoothing.
The forearm groups now has two modifiers, like this. When debugging is off the modifiers are applied from top to bottom.
I’m thinking about renaming the extra bones to .bend instead of .twist. After all, that’s what they do.
-
reporter Commit edfd478.
This works almost fine.
bug. quaternions. The twist bones are all quaternions, they must copy the rotation order from the original bone, this is especially important since they copy rotations. If quaternion is specified in the global settings then shoulders and thighs will be quaternions as usual, but not the twist bones.
fix. ik rigs. Now that we have twist bones for G1 G2, we can add the automatic twist for the forearm, same as G3 G8. Below the steps for simple ik, then mhx and rigify should provide the feature too. Test scene included g2-simple-ik.blend.
G1 G2 automatic forearm twist for simple ik:
- duplicate forearm to forearm.ik, where forearm.ik is non-deform
- assign the ik constraint to forearm.ik
- copy rotation from hand.ik to forearm with dumped track on y, as the picture below, note that we use the explicit rotation order of the target
note. As for the “twist” suffix it is not because they twist, indeed they bend, but it is because they serve the twist purpose. Adding extra bones with “bend“ suffix would be strange.
final notes. Once we fix the ik rigs the new triax is complete. It is not perfect by any means, the original daz triax is much better, but this is definitely an improved approximation from the original conversion and the daz one. We added a better general weight conversion with smoothing, plus bulges and twist.
-
reporter - attached g2-simple-ik.blend
g2 rig with forearm twist
-
repo owner The bugs should be fixed now. First I didn’t look at your file and implemented forearm twisting differently, but you way is better. It was also much easier to implement, since the code already existed for G8. Now all genesis versions, including G9, have the same extra bones.
-
reporter - changed status to resolved
Commit 32fcd6e works fine.
I'm closing as resolved. Eventually we can improve further if we find better ways to convert bulges or triax weights in general. But this first step is not bad if we want to use G1 G2 in blender.
Thank you Thomas for all your work on this.
-
reporter Issue
was marked as a duplicate of this issue.#1755There’s some fixes there.
- Log in to comment