Switching between materials on linked library objects ... easily

(sundialsvc4) #1

I’m thinking to myself that there’s probably a cleaner way to do this, than I’ve presently come up with …

I’m modeling a very complex piece of machinery – hundreds of parts – which right now is composed of assets in a library file, which is linked to color-swatches in another library file. These color-swatches include both, say, “solid red” and “transparent red.” There’s also, “solid iron,” which is used in establishing shots. There is a lot of animation associated with the base library model, painfully worked-out by reverse engineering of this (historical …) machine.

What I need to very easily do is to put together illustrative shots which show how this machine works, one part at a time, by setting un-related parts to “transparent” (the camera isn’t moving between the shots, so you can easily see which parts have been “grayed out”), while the active parts are solid … and colorful.

The forum software readily reminds me that my question is not new, but I’d like to hear thoughts as to what you think would be the cleanest way to do this. I have associated each part in the library-file with all of the materials that it could need – three material-links each.

Right now my basic shot-file structure consists of a base scene, which links to the assets (including the camera) but which is not otherwise used, and several linked-scenes one per shot. I’m looking for the easiest, quickest, and most-reliable way to switch the materials of any given object, per-scene. (Given that, in the base library, all possible materials are already associated with each object.)

Recommendations yours?

Color based on an angle between camera and object's origin?
(Lumpengnom) #2

So just that I understood this correctly:

  1. So your assets are in a separate file each
  2. You assembled your assets in scene files
  3. You want to make objects transparent from within the scene file quckly
  4. 3 is the problem because you can not change the material on a linked object

Can you turn the objects you want to change the material of into proxies? If so you could set your materials up so that switching the object index from 0 to 1 turns the material from solid to transparent.

If you need to switch between more than one material states simply set it up so that you can switch between multiple states with the help of a color ramp.

(sundialsvc4) #3

The assets are in a linked file – the entire machine, fully worked-out, with three materials associated with each piece (e.g. “iron,” “red,” “transparent red”).

Shots are done in shot-files with one base scene that links to the assets (and contains the camera), with individual shots in scenes linked to this.

I’m looking for the simplest possible way to switch the entire object from, say, red to tranparent-red, on a per-scene basis, while preserving the ability to “go back upstream” and edit the linked machine if, during the process of creating the illustrations, I discover that there was something wrong with it.

The machine in question is a belt-driven, Victorian-era, mass-production metalworking machine which was controlled by multiple cams, gears and levers. (It’s rather amazing what those engineers cooked-up in those days.) I had to figure out what it would look like “in motion” by piecing together and animating its various primary and then motions, more or less one frame at a time. I’m sure that I will find that I forgot something or made some mistake, so I don’t want to – for example – duplicate objects anywhere. I want to be damn-sure that I make the change in one place and it carries forward because it took me a full two weeks to work out the animations and shapes so-far.

(Lumpengnom) #4

Then I think the proxy method mentioned above should work.

(sundialsvc4) #5

I’d appreciate a quick explanation of how changes to the object index would trigger a change of material-ID.

I’m not sure that a color-ramp would be best here because I think that I want “distinct materials.” I want to specify three distinct materials – any of which I can then change throughout the project by editing the color-swatches file –and to switch between them.

I’m already using proxies. Can you please show me exactly how to set up the (Eevee …) materials so that a change of the object-ID attribute will cause a change of material? (That’s very appealing to me because it would mean that I’m not replicating the magic of causing the material-change, which is a very major concern here.)

The documentation is rather sparse as to what can be edited in a proxy and what cannot.

(sundialsvc4) #6

P.S. I am keenly watching this “sister thread” that has just appeared:

… where “node groups” (which I understand) are being used, in that case to achieve commonality among changes in the various multiple-materials that are attached to a single object. This sounds appealingly-close to what I think you were suggesting earlier in this thread … “a single material that can change hats,” so to speak.

For instance: one node-based material, where each “material” is defined as a node-group, and an ID mask network (linked to Object-ID) selects only one of the three materials to be output – at the cost, of course, of most-likely generating all three and throwing two of them away.

But … what was your recommendation, exactly?

(Lumpengnom) #7

It wouldn´t trigger a change of material ID. It would change a Mix Shader based on the object index.
With the color ramp you would set it to solid, so you´d get rid of the ramp part of the color ramp. However, since you only have three different materials it is probably simpler to set it up with math nodes and set them to “greater than”.
Instead of the diffuse shaders in the image you would of course use your solid red, transparent red and your third shader.

(sundialsvc4) #8

Interesting that they didn’t define a “Between” math-node. Thanks for the tip.

(Lumpengnom) #9

You can make an “between” with a color ramp.
Since a color ramp ranges only from 0 to 1 you have to use a math node to divide your object index so that the result lies within the range from 0 to 1. In this case i mulitplied by 0.1.
then you set the positions in the color ramp between which you want your passes to use the second slot of the mix shader, in this case 0,3 and 0,7.
Then you set your object IDs, in this case 2, 5 and 8.

2 * 0.1 = 0.2
0.2 is lower than 0.3 which means that the cylinder with object ID will be purple.

Note that this techique is also very useful when used with the particles info node.

(sundialsvc4) #10

I think that the trouble with that idea is that some of the materials are quite different from the others.

What I’d really like to be able to do most-easily is to globally choose which material-index to use. Assign three (in the linked library file containing the model), then dynamically choose among those three.

(Lumpengnom) #11

I don´t think that is possible. The material index of each face is wired to the mesh, not the object. Since you link the mesh from another file you have no access to the mesh data.

There is a way to switch between two materials, though.
If you proxified your object go to the Materials tab. Right next to the material drop down you can chose if a material is connected to the object or the data. You can chose different materials for data and object and in this way at least switch between two materials.

If you do find a way how to do that I´d be interested as this could be immensly useful.


(Lumpengnom) #12

Hmm… It appears that it sort of does work if you use a Python script. If you don´t proxify your objects it gives unexpected results when switching to MatIndex 0, though, so be sure to proxyfy them.

Also be aware that since it influences the mesh data it will switch ALL linked objects of that type.
So for example if you use one screw 50 times in your scene it will switch all screws from red to transparent red.

Perhaps it can still be useful, though, so here is the script. You have to select all objects you want to change, then set your desired index in the second line “new Index =” and then run the script:

import bpy

newIndex = 0

mySelection = bpy.context.selected_objects

for object in mySelection:
    myMesh = object.data
    for polygon in myMesh.polygons:
        polygon.material_index = newIndex

(sundialsvc4) #13

I’m experimenting right now with materials connected to the object. The faces appear to contain a material index but I can change what material that index-number refers to. I’ll continue looking at this and report back as to what I settled on. (I don’t want to fool around with Python scripts or to copy any significant data into the linked files.)

I’ve dropped-back to a slightly simpler machine with fewer parts so that I can dry-run the process. (It’s not that I can’t do this, but the process I’ve used feels very cumbersome, leading me to suspect – and now, to see – that there is a better aproach. Thanks all, folks.)