Tuesday, May 20, 2025

Importing DBZ Files Directly

Getting the DAZ Importer up and running is a bit more complicated then using a normal importer. We must Copy Scripts folder to DAZ Studio, Save Scene in DAZ Studio, and Export To Blender. Those are the steps that any export script would need to do. But the DAZ Importer also required two extra steps, Save the DAZ root paths in DAZ Studio, and also Setting up the DAZ root paths in Blender. Those steps are necessary because the DAZ assets are not stored in the duf file. Instead the duf file contains pointers to the actual assets relative to the root paths. So knowing the root paths is necessary to find the assets.

However, the extra steps have been automated in the development version, which means that the DAZ Importer behaves more like a normal importer: export the dbz file from DAZ Studio and import it into Blender. The root paths are stored inside the dbz file, provided that you copy the latest version of the Export To Blender script a the DAZ Studio scripts folder. Older dbz files can also be imported, but in that case the root paths must be set up correctly first.

When we now press Easy Import DAZ or Import DAZ Manually, we notice two differences:

  • The file list contains dbz files instead of duf files and pictures.
  • The Mesh Fitting option is gone. 
The default root paths are probably not correct. Previously we had to set up the root paths manually, or export the root paths from DAZ Studio and load them into Blender. This is no longer necessary if we use the latest version of the Export To Blender script, because the root paths are now stored inside the dbz file. If we import an older dbz file it is still necessary to set up the correct root paths.

After the dbz file has been imported, the root paths are updated.

There are two new global settings that control the behaviour.

  • Only DBZ Files. If disabled the file selector looks like it used to, showing duf and dsf files and images. The Mesh Fitting option is also shown.
  • Root Paths From DBZ. If enabled the plugin uses the root paths in the dbz file, otherwise the root paths in the global settings are used.

Here is the file selector if DBZ Files Only is disabled. The file selector contains duf files and pictures. The Mesh Fitting options are shown.

Sunday, April 6, 2025

Diffeomorphic Add-ons Version 4.4.0 Released

Version 4.4.0 of the DAZ Importer, MHX Runtime System, and FBX and BVH Retargeter have been released. They can be downloaded from

The previous stable version 4.3.0 does not work with Blender 4.4 due to an API change.

Apart from working with Blender 4.4, there are also many bugfixes and some other changes.

Wednesday, March 19, 2025

Scripting Improvements

I have spent a log of time developing the DAZ Importer plugin, but I rarely use its scripting capabilities. However, every button becomes an operator that can be called from a script; a list of operators defined by the DAZ Importer can be found here. These operators are defined automatically and usually work out of the box, but there are some caveats regarding operators that act on multiple files, morphs or shapekeys.

Assume that we want to import a figure with Easy Import. We select the duf file (or the corresponding .png or .tip.png file) and press Easy Import DAZ. To do the same thing programatically, we could expect that the following script would work: 

bpy.ops.daz.easy_import_daz(
    filepath = "D:/home/scenes/victoria-rocker.duf"
)

However, nothing is imported. The reason is that the Easy Import tool can import several files at once. If we select the following three files, three different figures will be imported at once.

And here are the figures in Blender.
Importing multiple character in one stroke may not seem very useful, but we may want to import thirty different props from a single directory, and then it is easier to ímport thirty files at once than to press the Easy Import button thirty times and only import a single prop each time.

The old way to import multiple files uses the api.set_selection function, which needs to be called before easy_import_daz is invoked. Functions defined by the DAZ Importer plugin are documented here.

import bpy
from bl_ext.user_default.import_daz import api

api.set_selection([
    "D:/home/scenes/aiko-basic-wear.duf",
    "D:/home/scenes/victoria-rocker.duf",
    "D:/home/scenes/michael-basic-wear.duf"])
bpy.ops.daz.easy_import_daz()


Unfortunately, this does not work very well. Under the hood the set_selection function sets a global variable, and this leads to complications for operators that invoke other operators, like easy_import_daz does. Recently I learned from Rakete that there is another way to access multiple files which does not involve any global variables.

When a file selector exists, it sets two keyword arguments: the StringProperty "directory" and the CollectionProperty "files". An alternative way to import multiple files is like this:

bpy.ops.daz.easy_import_daz(
    directory = "D:/home/scenes",
    files = [{"name" : "aiko-basic-wear.duf"},
             {"name" : "victoria-rocker.duf"},
             {"name" : "michael-basic-wear.duf"}])


Actually, importing files in this way has always worked, but I was not aware of it. The "files" argument is a bit complicated; it is a list of dicts with the "name" keyword, which is how we specify a CollectionProperty in scripts.

To import a single file we simply let "files" be a list with a single argument.

bpy.ops.daz.easy_import_daz(
    directory = "D:/home/scenes",
    files = [{"name" : "victoria-rocker.duf"}])

    
This way of importing multiple files is not limited to Easy Import. The following script imports three poses to the active object. The second line turns on automatic keying.

import bpy
bpy.context.scene.tool_settings.use_keyframe_insert_auto = True
folder = "/people/genesis 8 female/poses/base poses/"
files = ["base pose kneeling a.duf",
         "base pose kneeling b.duf",
         "base pose kneeling c.duf"]         
bpy.ops.daz.import_pose(
   directory = api.get_absolute_path(folder),
   files = [{"name" : file} for file in files],
)


This script imports three poses to consequtive frames. 

Many tools opens another type of selector, which lets us select which morphs to import, which shapekeys to transfer, which materials to modify, etc. Such selections used to be made with the api.set_selection function as well, but now the preferred way is to use the "selection" keyword. Again the argument is a CollectionProperty, which corresponds to a list of dicts with the "name" keyword in scripts.

The following script import three units morphs:

files = ["eCTRLEyesClosed.dsf",
         "eCTRLEyesClosedL.dsf",
         "eCTRLEyesClosedR.dsf"]
bpy.ops.daz.import_units(
    selection = [{"name" : file} for file in files]
)

It is thus equivalent to the following selection in the Import Units dialog.

If the "selection" keywprd is omitted, or equivalently if selection = [], all elements are selected. Thus the line

bpy.ops.daz.import_visemes()

imports all available viseme morphs. We can then set the corresponding rig properties.

rig = bpy.context.object
rig["eCTRLvAA"] = 1.0
rig["eCTRLvOW"] = 0.4



Thursday, March 6, 2025

Mathjax Test

The formulas in the header.

[Lξ,Lη]=L[ξ,η]+12πidt q˙ρ(t)(c1 ρνξμ(q(t)) μην(q(t)) ++ c2 ρμξμ(q(t)) νην(q(t))),[Lξ,qμ(t)]=ξμ(q(t)),[qμ(t),qν(t)]=0.

If you use Firefox with NoScript, as I do, you need to whitelist jsdelivr.net and polyfill.io, otherwise only the uncompiled LaTex code will show up.

If anybody wonders, this is the Virasoro-like extension of the diffeomorphism algebra in multiple dimensions. e.g. on the d-dimensional torus. When d=1, both terms proportional to c1 and c2 reduce to the ordinary Virasoro algebra on the circle, a piece of mathematics that is popular e.g. in string theory and statistical physics. By the way, I discovered the c2 term myself a long time ago, which is something that I am still proud of (c1 was discovered by Rao and Moody).

When I started this blog almost a decade ago I had planned to write about this and how it in my opinion fits into physics, hence the name of the blog. I never got around to do that, but that might change in the future.

 

Tuesday, February 25, 2025

Adding Extra Bones to Rigify

Some character have non-standard bones, e.g. a rigged hair. When we convert such a rig to Rigify, the rigified rig contains those bones, but they may be inconvenient to pose individually.
 
Here we have a figure with a rigged ponytail. The ponytail bones belong to the Custom collection.,
And here the rig has been converted to Rigify, with the hair bones still in the Custom collection. Posing each of hair bone individually can be done but is inconvenient.There are a few things that we can do to make it easier to pose the ponytail.
We can Add IK Goals. This tool is located in the Rigging > Chains panel which requires that the Rigging Tools feature is enabled.
Alternatively, we can Add Winders.

However, Rigify is a modular rigging system and we may want to use some of the Rigify types. Previously that has not been so easy to do. In principle we can first generate the metarig, then add the custom bones to it, and finally rigify the modified metarig. However, that requires further postprocessing because the vertex groups must be renamed. In the last version of the DAZ Importer there is a much simpler way. Just select a bone in the original DAZ rig and add a Rigify type to it.

Let us give the ponytail the control of a basic Rigify tail. Select the bone that we want to be the root of the tail, and assign a suitable Rigify type to it. Here we choose spines.basic_tail.
The Rigify Type panel contains various option for the bone chain. By default a basic tail can only bend along the X axis.
Once a bone has been assigned a Rigify type, it is added to the metarig together with its descendants. Any parent bones that are not part of the standard Rigify armature are also added.
Now the rigified armature has a ponytail with the extra control bones.
The entire ponytail can now be posed by rotating the target bone at the end of chain.

Wednesday, February 12, 2025

MHX Properties are now ID Properties

As discussed in the post on Custom Properties Cleanup, custom properties used by the DAZ Importer are now combined into a single, complex property. However, there are two exceptions:

  1. Morph properties, because they are part of a web of drivers that would not be evaluated in the correct order if they were parts of a complex property.
  2. Properties that need to work when the add-on is disabled, e.g. at a render farm.

 The custom properties used by the MHX rig belong to the second category. 

There are two types of custom properties in Blender:RNA properties and ID properties, or properties that are defined by the system or by add-ons and those that are created on the fly. The problem with RNA properties is that they do not work properly if the add-on is disabled. MHX properties have nevertheless been implemented as RNA properties, because ID properties did not worked with file linking in some earlier  version of Blender. This problem has been fixed in recent Blender versions, and therefore there is no reason to use RNA properties anymore.

This change should be backwards compatible, almost. Even if the MHX rig was created in an earlier version of the DAZ Importer, where the MHX properties were RNA properties, it should still function correctly with the latest version. This works because RNA properties are automatically converted to ID properties if the API no longer defines them. The only thing that does not work is animations with dynamic FK/IK switching.

Here are the custom properties of a recent MHX rig. The MHX properies begin with "Mha" (there was a reason why they don't start with "Mhx", but I don't remember why anymore). Note the cogwheel to the right of the property value. This indicates that we deal with ID properties rather than RNA properties, which would have "API Defined" written to the right instead. 

Pressing the cogwheel brings up the Edit Property window. Note that MHX properties are Library Overridable at the bottom of the window.

Save the scene with the MHX rig, open a new file, and link the collection with the MHX character into the new scene. To make the character useful in the new scene, choose Object > Library Override > Make.
We can still access the custom properties, but they can not be edited. When we change a linked property it turns green.
Now do the following steps:

  1. Create an animation and save the file.
  2. Disable the DAZ Importer and MHX RTS add-ons.
  3. Restart Blender.

 We have now recreated the situation at a render farm, where the DAZ Importer and MHX RTS are not available. Nevertheless the animation works correctly, including the animation of custom properties needed e.g. for FK/IK switching.