29 Sep 2019

Revisiting Viewer’s Theming Coloring - Selective Cancelling, Deferred Rendering and Recursive Propagation


Note: All usage demonstrated hereby is based on Viewer v7.* and is subject to change for future versions!


When we talked about theming color (available via viewer.setThemingColor(dbid)) last time around it was a cheerful occasion and Viewer’s then new theming color feature really made our Easter Egg back then. So today, as we are up for another great day of commemoration - the Chinese National Day (which gives those in China mainland a week off), let’s echo the celebration of Easter and the advent of Viewer’s theming colors back then by visiting this feature and some of its highly sought-after usage.

List All Colored Objects

Never hurts to get one’s status quo right and to do so is straight forward enough - the mapping of color codes and object IDs is exposed via the db2ThemingColor handle:

const fragList = model.getFragmentList();

const colorMap = fragList.db2ThemingColor;

It'd be an object with dbids as keys and color codes as values:

sn

Clear Color of An Individual Object

Unfortunately it’s not exactly that straight forward to clear the color of a specific object and many raised questions about this over and again - we used to resort to clearing all the colors (NOP_VIEWER.clearThemingColors()) and set the ones we want back, tedious and had performance hits written all over it ... Now that agony is no more - check this out:

NOP_VIEWER.setThemingColor(dbid, null)

That's simple enough isn't it? But what if there are several objects to recover? Let's go back to the dbid-color mapping, simply remove the key to the objects we'd like to clear and be sure to manually trigger rendering afterwards:

delete colorMap[dbid1];
delete colorMap[dbid2];
//...
NOP_VIEWER.impl.invalidate(true) //trigger rerendering

 

Defer Rendering of Colors

By default Viewer dispatch the color code for rendering immediately after setThemingColor is called. Hence when applying colors to large numbers of objects we might end up with a perceivable performance hit so here is how to defer the rendering of these colors until all the codes to the objects and then render them altogether instead of re-render every time for each individual object:

model.setThemingColor(dbid1, THREE.Vector4); //calling setThemingColor on the model object only marks the object for coloring w/o triggering rendering immediately
model.setThemingColor(dbid2, THREE.Vector4);
//...
NOP_VIEWER.impl.invalidate(true)   //trigger rendering afterwards

Recursively Coloring for Child Objects

This might be repeating the same old New Orleans' tune again but in case you missed the our previous introduction of this flag here then here it is again:

NOP_VIEWER.setThemingColor(dbid, THREE.Vector4, null, true);
// db2ThemingColor: (59) [n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4, n.Vector4]

 

Translate RGBA or HEX Strings to 4D Vector Color Codes

If you ever wondered if there is a straight forward way to convert the RGBA or HEX color codes that we are more familiar with to the THREE.Vector4 objects that setThemingColor requires - well this brilliant library does exactly that and its usage is indeed pretty neat:

const color = colorToVec4(`#FF00FF`);
console.log(color); // [1, 0, 1, 1]

const color2 = colorToVec4(`rgba(255, 0, 0, .3)`);
console.log(color2); // [1, 0, 0, .3]

const color3 = colorToVec4(`rgb(200, 255, 0)`);
console.log(color3); // [0.7843137254901961, 1, 0, 1]

 

That’s it for today! See you around after the national day break and I will be back with all the rambling I promised about taking the game of WebAssembly to Viewer. Thanks and until next time!

Related Article