Blender: Dynamic workflow for Modeling > Rigging > Layout > Animation using linked libraries

Blender: Dynamic workflow for Modeling > Rigging > Layout > Animation using linked libraries

State of the art

Reading the blender docs and testing the system, the workflow to rig a model is not consistent and doesn’t take advantage of the power of Blender library link.

Creating a model in OP puts the objects under an empty. This is not an usual way to create a model hierarchy, the main approach is to parent the sub-objects to the main object. Furthermore, placing an empty before the first model disallow to use the parenting operators of Blender, the modifiers won’t be created neither auto weights and vertex groups… If we use the workflow described in the creating rigs doc, it changes the parent from the empty to the armature and breaks the hierarchy and the update.

Proposal

The proposed workflow deals only with .blend files.
The model creator must keep the objects hierarchy, it means to drop the parenting to an empty when creating an instance, and rely on collections and custom properties data. This system has been designed with 2.93, doesn’t work for 2.83 and is compatible with 3.x series. Depending on your Blender versions support policy, some extra steps can be added for older versions (making all local, adding an empty to replace the collection…).
The publish part remains untouched, I’d like to add the possibility to enable/disable the formats to export, but that’s another topic.

Modeling

Create

The modeling remains the same: create the model as you like. Creating the instance will put everything under a collection considered as the root.

After creating the instance, the hierarchy would look like that:

All information currently associated to the root object is now stored in the collection’s custom properties.

Load

Link model will act like a usual Blender Link... with an automatic Make library override... and not create a disturbing set of AVALON_ collections. This way the scene looks like that:

model_load

Rigging

Create

For both advanced and basic rigs, the process is the same as creating a model, a collection is created to be the root of the rig, we don’t change the hierarchy.

In Blender, rigging implies to paint the weights or assign vertex groups for example, the user can make the object and some datablocks local, we could ease that by adding an operator somewhere, the datablocks are always the same for the rig task (this system will be usable for a later shading/render/lighting design). For a fully non-destructive workflow, I suggest to update the actual model version with this new rig-ready mesh, this way later modeling modifications can be done without having to redo all the rigging work.

Load

Same as loading a model.

rig_load

Layout/Set dressing

Create

In a layout scene, you load rigs and models. You can move them around using the Armature or the controllers you set for your rig. It is not recommended to move the collection but this is not an big issue. Rigs and objects (like cameras) can be posed and animated roughly. Once you’re done, you create a Layout instance.

Load

Loads all objects under the Layout collection.

Animation

Create

You load a layout, link any other rig you need, and then create the Animation instance. This way, if any addition is made in the Layout it’s updated in the Animation collection without any intervention.

NB: Actions (actual animation data) are associated to the object, then modifying the armature/rig doesn’t affect the animated parts, unless an animated element has been deleted.

Load

Same as layout.

Update subset

Versions

The subset update would rely only on custom properties data and not deal with any arbitrary hierarchy (apart from collections) and try to use as much as possible the libraries if the entity has not been made local. Then it would only change library paths, or link the datablocks and assign then to the objects.

Hero

If the target library is the hero version, the update is automatic and transparent, without any code to run on the OP side.

Made local case

As mentioned above, making something local make the update less easy and we can evaluate some study cases to try automating as much as possible, relying on custom properties. But we cannot deal with all manipulations or dirty workflows/crisis fixes, this will require human intervention. At least, this system has a very flexible design with a turnkey workflow.

Beyond

This system is valable for next tasks but tests have to be done to make as few make local as possible and keep the most as links. This part deals with POCs for some use cases we have identified as major, which are not currently supported by the Blender implementation.

Look

Basic

In blender the material (a.k.a shader) can be associated to the mesh data or to the object, I propose to associate it to the object, therefore the object have to be made local to work with the subset and the mesh data is still linked to the model. Creating a look will reference all the materials associated to the object. Publishing a look will create a .blend file with the materials, considered as the materials library to be targeted and linked for other tasks.

Several materials for different faces

It may happen you assign different materials to a bunch of faces. This case forces you to toggle to Edit mode and then requires the mesh data to be local. I’d handle it by updating the model with the modified mesh data to be the new reference, this is the same problem/solution as for the rigging task.

Workflow diagram

Here is a schema to sum up!

OpenPype_Blender_Workflow drawio

NB: Lighting (or some other steps) are not indicated because we haven’t discussed them, but the essential must be there, feel free to raise any concern.

Test data

Here are my test data, librairies linked with relative paths:
OP_BL_Workflow_2.93.zip

If I understand this correctly (Blender noob here) the make local operation is the same as importing?
In which case I would suggest that its outside of Pype’s responsibility to be able to update the assets when imported.

Exactly, and that’s how the current system work.

I want to state up front that I have close to no Blender knowledge.

Thanks for starting the discussion. All sounds super great and I’m not hearing any obvious issues.

Versions
The subset update would rely only on custom properties data and not deal with any arbitrary hierarchy (apart from collections) and try to use as much as possible the libraries if the entity has not been made local. Then it would only change library paths, or link the datablocks and assign then to the objects.

Yes - that sounds perfect. Basically a Link sounds like a Maya Reference. However, when I originally tried playing with those you couldn’t really ‘edit what you’d like’ on those linked files - it needed to have specific things exposed as to what could be altered. As a simple example, you couldn’t override the assigned shader for a linked file. (When I was testing that, I think Blender 2.7 or 2.8)

In a layout scene, you load rigs and models. You can move them around

If it’s very explicit for a linked assets what you can actually “edit”, like moving around. How do you move a loaded Model that has no rig? (Probably a very stupid question.)


The proposed workflow deals only with .blend files.

Am I right in understanding that all the described logic only works for .blend files? Or can you actually link e.g. an .abc file the same way?

How do you move a loaded Model that has no rig?

It’s an usual object, like if it was an empty.

Am I right in understanding that all the described logic only works for .blend files? Or can you actually link e.g. an .abc file the same way?

I’ve looked around a bit and it doesn’t seem possible…

It’s an usual object, like if it was an empty.

But if you late need to replace it with new version that could potentially have more geometry, you can’t, can you? I mean without storing the transforms and re-applying them to the new model (where you might have to guess what is what)

The model without a rig is stored in a collection which is linked, then adding any new object in this collection in the source .blend will be updated to the scenes referencing this collection, and keep the collection’s position.

I have similar points to @BigRoy, but will add some context for some of the current design decisions. Keep in mind that we’ve actually redone all of this at least twice I believe in the past year, so clearly we’re not set on “best practice” here. I feel that mostly because, we’ve yet to see a “best practice” in blender for a bigger production, so all of these suggestions and insights from you are invaluable.

The subset update would rely only on custom properties data and not deal with any arbitrary hierarchy

That is indeed ideal, we just didn’t quite manage to make it work, so I’d love to see it work.

In a layout scene, you load rigs and models. You can move them around

One of the main reasons why we group under an empty is to mimick the maya and houdini layouting options where you can move loaded models around and then possibly export this layout to other host in a standardised way, be it via json as we do to unreal, or as alembic hierarchy or even USD eventually. The point is that you have a transform above your loaded subset. Also it allows to change that subset to something else (different asset, or just version), while keeping all of the layout transforms. I’m not sure how possible that is using collection alone.

For bigger scenes especially some reasonable hierarchy in the scene becomes quite important.

You load a layout, link any other rig you need, and then create the Animation instance. All elements are moved to the collection, and the Layout collection is deleted to avoid useless hierarchy overhead.

Maybe my misunderstanding here, but I’d be a bit worried about removing the layout info from the scenes. Aren’t you cutting off the option of updating it later on? In our eyes, it is best to separate animation and layout as much as possible to allow for updating it later on. I can imagine moving the characters to the animation collection, and leaving the rest in layout, but I’d have to see what how it’s really behaving probably.

Quite common production example is, where you need to start animating way before scene layout is fully finished, say we only layout with proxies to give some spatial awareness to the animator and then keep updating the layout with final version of the assets. In may it’s easy thanks to referencing. With blender links… I imagine it should be as well if we keep the layout as a link inside the animation scene and keep the animation on top.

One of the main reasons why we group under an empty is to mimick the maya and houdini layouting options where you can move loaded models around and then possibly export this layout to other host in a standardised way, be it via json as we do to unreal, or as alembic hierarchy or even USD eventually. The point is that you have a transform above your loaded subset. Also it allows to change that subset to something else (different asset, or just version), while keeping all of the layout transforms. I’m not sure how possible that is using collection alone.

I understand your point, but in Blender the object is not bound to the mesh data. The geometry can be changed while keeping the position information, it acts like an empty with a geometry parented to it.

Maybe my misunderstanding here, but I’d be a bit worried about removing the layout info from the scenes. Aren’t you cutting off the option of updating it later on?

This point is one about I need to make sure removing Layout collection is not a big deal. I proposed that because when I push this system further, in several tasks the hierarchy will look like Render > Lighting > FX > Animation > Layout… And it doesn’t look elegant to me. But on the other hand, it shows explicitly the tasks process and can highlight any defect in the workflow.

In the case we remove the Layout, I’d keep the source Layout in Animation collection’s custom properties. Thinking more about that it seems too error prone… Then I’d prefer to keep all collections in the hierarchy.

I changed the description to illustrate this part.