Precomputation in a custom Node/Deformer

Hi guys!
I’ve been developing a deformer in C++, and I have a workflow question before moving forward. i need to precompute a very large matrix (a Beltrami Laplacian) and some additional custom attribute data, but this should only happen once when the user clicks on something like “compute” in the deformer’s attribute editor.

I’m not sure about the best way to do this. I was thinking about using a custom attribute (I already have quite a few) and store the Eigen matrix there along with the other data, though I’m not sure how I’d handle readASCII readBinary in that case with Eigen.

Another option is to save it as a file alongside the Maya scene file, like xgen legacy does, but I feel like there might be a more Mayaish way to handle this.

Keep in mind, it’s not just the large matrix, there are multiple custom attributes as well.
If you guys have any suggestions or ideas, I’d really appreciate your input.
Thanks!

You could store the matrix in ascii as a maya string attribute, and the same for the custom attributes (if you have them working as attributes already, they should be serialised properly in the Maya scene) - Maya nodes also have the concept of internal attributes, if you want to hide it from the scene. In the node’s creator() function you can reload the matrix, or when the mesh plug is connected, check it still matches the incoming topology, or however your logic is.

I would strongly not advise writing out and reading a separate file - since this will be per-mesh that your deformer acts on, and either that’s potentially a lot of random files to suddenly vomit out alongside a scene, or you have to deal with the logic of reading, writing, partially updating etc. Unless there’s something you can’t feasibly store on the node, don’t do it.

1 Like

I’m not sure I understand… does your node need to use data not calculated from what’s in the scene? I’m not sure why you would load a matrix for a deformer; it should provide attributes and be connected to everything it needs to calculate the math.

The way I’ve done this sort of thing is using a flag (ex. isCachedMatrixValid). Set the flag outside of the compute based on your deformer’s requirements (preEvaluation, setDependentsDirty, etc..) checking dirty plugs. Then based on the flag’s state, either retrieve or recalculate the matrix in the compute method.

1 Like

Yes, something like that. Certain data should be calculated only once during the deformer setup

When you register your plug-in, register both an MPxNode and an MPxCommand.

When the user clicks their create button, call the command, which can create the node, compute the matrix, and store it on the node in a big float array. Then your node compute is simple. You just read the float array attribute. If the user needs to reapply / recalculate the matrix, your command can optionally take in an existing node with an edit flag, to recompute / modify the stored matrix.

This fits with the paradigm of how other Maya commands work, how other deformers are created, and avoids all the mess you get by trying to cram the matrix computation into the node’s compute, or trying to shoehorn in some file io (which IMO should probably be done using file nodes if it is ever actually justified. Just store values on nodes if you can help it).

Jo beat me to it. But what he said!