Below is an example demonstrating how you can create texture modifiers for material properties that are mappable and have images assigned to them, and cause the color of those images to toggle between normal/inverted.
// Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ /*********************************************************************/ // Boolean : A function for testing whether or not a QObject instance // inherits one of a list of types function inheritsType( oObject, aTypeNames ) { // If the object does not define the 'inherits' function if( !oObject || typeof( oObject.inherits ) != "function" ){ // We are done... it is not a QObject return false; } // Iterate over the list of type names for( var i = 0, nTypes = aTypeNames.length; i < nTypes; i += 1 ){ // If the object does not inherit the 'current' type if( !oObject.inherits( aTypeNames[i] ) ){ // Next!! continue; } // Return the result return true; } // Return the result return false; }; /*********************************************************************/ // DzTextureModifier : A function for getting/creating a texture modifier // for a property that has a map function getTextureModifier( oProperty, bCreate ) { // Initialize var oTextureModifier = null; // If the application version is less than 4.6.4.80 if( App.version64 < 0x0004000600040050 ){ // We are done... DzTextureModifier did not exist return oTextureModifier; } // If we have a numeric property that can be, and is, mapped if( inheritsType( oProperty, [ "DzNumericProperty" ] ) && oProperty.isMappable() && oProperty.isMapped() ){ // Get the texture modifier oTextureModifier = oProperty.getTextureModifier(); // If we do not have a texture modifier and want to create one if( !oTextureModifier && bCreate ){ // Create a texture modifier oTextureModifier = new DzTextureModifier(); // Assign the modifier to the property oProperty.setTextureModifier( oTextureModifier ); } // If we have an image property and it has a texture assigned } else if( inheritsType( oProperty, [ "DzImageProperty" ] ) && oProperty.getValue() ){ // Get the texture modifier oTextureModifier = oProperty.getTextureModifier(); // If we do not have a texture modifier and want to create one if( !oTextureModifier && bCreate ){ // Create a texture modifier oTextureModifier = new DzTextureModifier(); // Assign the modifier to the property oProperty.setTextureModifier( oTextureModifier ); } } // Return the result return oTextureModifier; }; /*********************************************************************/ // Array<DzProperty> : A function for getting a list of the properties in a group function getGroupProperties( oGroup, bTraverse, bRecurse ) { // Declare an array to hold properties var aProperties = []; // If a group is not passed in if( !oGroup ){ // We are done, return an empty array return aProperties; } // Get the number of proeprties in the group var nProperties = oGroup.getNumProperties(); // Pre-size the properties array aProperties = new Array( nProperties ); // Iterate over the properties, setting each element in the array for( var i = 0; i < nProperties; i += 1 ){ // Assign the property to the position in the array aProperties[ i ] = oGroup.getProperty( i ); } // If we are recursing if( bRecurse ){ // Concatenate the properties array from child groups aProperties = aProperties.concat( getGroupProperties( oGroup.getFirstChild(), true, bRecurse ) ); } // If we are traversing if( bTraverse ){ // Concatenate the properties array from sibling groups aProperties = aProperties.concat( getGroupProperties( oGroup.getNextSibling(), bTraverse, bRecurse ) ); } // Return the array of properties return aProperties; }; /*********************************************************************/ // Array<DzProperty> : A function for getting the list properties for an element function getElementProperties( oElement, bTraverse, bRecurse ) { // Get the property group tree for the element var oPropertyGroupTree = oElement.getPropertyGroups(); // If the application version is 4.9.4.101 or newer and we want all properties if( App.version64 >= 0x0004000900040065 && bTraverse && bRecurse ){ // Return the properties for the element return oPropertyGroupTree.getAllProperties(); } // Get the first group in the tree var oPropertyGroup = oPropertyGroupTree.getFirstChild(); // Return the properties for the element return getGroupProperties( oPropertyGroup, bTraverse, bRecurse ); }; /*********************************************************************/ // DzProperty : A function for finding a property associated with an element function findElementProperty( oElement, sProperty, bUseLabel ) { // Declare a working variable var oProperty; // Create a scene helper object var oSceneHelper = new DzSceneHelper(); // If we are using the label if( bUseLabel ){ // If DzSceneHelper::findPropertyByLabel() exists if( typeof( oSceneHelper.findPropertyByLabel ) == "function" ){ // Get the property on the element with the label oProperty = oSceneHelper.findPropertyByLabel( sProperty, oElement ); // If the element is a node and DzSceneHelper::findPropertyOnNodeByLabel() exists } else if( inheritsType( oElement, ["DzNode"] && typeof( oSceneHelper.findPropertyOnNodeByLabel ) == "function" ) ){ // Get the property on the node with the label oProperty = oSceneHelper.findPropertyOnNodeByLabel( sProperty, oElement ); } // If we are NOT using the label } else { // Find the property by internal name on the node oProperty = oSceneHelper.findPropertyByInternalName( sProperty, oElement ); // If DzSceneHelper::findPropertyByLabel() exists if( typeof( oSceneHelper.findPropertyByInternalName ) == "function" ){ // Get the property on the element with the label oProperty = oSceneHelper.findPropertyByInternalName( sProperty, oElement ); // If the element is a node and DzSceneHelper::findPropertyOnNodeByLabel() exists } else if( inheritsType( oElement, ["DzNode"] && typeof( oSceneHelper.findPropertyOnNodeByInternalName ) == "function" ) ){ // Get the property on the node with the label oProperty = oSceneHelper.findPropertyOnNodeByInternalName( sProperty, oElement ); } } // Clean up; do not leak memory oSceneHelper.deleteLater(); // If we found a property if( oProperty ){ // We are done, return it return oProperty; } // Whether or not to use optimizations; 4.7.1.44 or newer var bUseOptimization = (App.version64 >= 0x000400070001002c); // If the application version is 4.7.1.44 or newer and we are not using // the label to find, or the application version is 4.11.0.166 or newer if( (bUseOptimization && !bUseLabel) || App.version64 >= 0x0004000b000000a6 ){ // Get the property group tree for the element var oPropertyGroupTree = oElement.getPropertyGroups(); // If we are using the label if( bUseLabel ){ // Attempt to find the property oProperty = oPropertyGroupTree.findPropertyByLabel( sProperty ); // If we are not using the label } else { // Attempt to find the property oProperty = oPropertyGroupTree.findProperty( sProperty ); } // If we found a property if( oProperty ){ // We are done, return it return oProperty; } // Otherwise } else { // Get the properties of the element var aProperties = getElementProperties( oElement, true, true ); // Iterate over the properties for( var i = 0; i < aProperties.length; i += 1 ){ // Get the 'current' property oProperty = aProperties[i]; // If we are using the label if( bUseLabel ){ // If the label of the property is the one we are looking for if( oProperty.getLabel() == sProperty ){ // We are done, return it return oProperty; } // If we are not using the label } else { // If the name of the property is the one we are looking for if( oProperty.name == sProperty ){ // We are done, return it return oProperty; } } } } return null; }; /*********************************************************************/ // Array<DzProperty> : A function for getting the list properties for an element function getElementPropertiesInPath( oElement, sPath, bRecurse ) { // If the path is empty if( !sPath ){ // Return the properties for the element return getElementProperties( oElement, true, bRecurse ); } // Initialize var oGroup = oElement.getPropertyGroups(); var sName = ""; var nIdx = -1; var sSubPath = sPath; // While the remaining path is not empty while( oGroup && !sSubPath.isEmpty() ){ // Get the index of the first slash nIdx = sSubPath.indexOf( "/" ); // If a slash was not found if( nIdx < 0 ){ // The group name is the path sName = sSubPath; // Break the loop on the next evaluation sSubPath = ""; // If a slash was found } else { // The group name is before the slash sName = sSubPath.left( nIdx ); // Get the remaining path sSubPath = sSubPath.right( sSubPath.length - nIdx - 1 ); } // Get the sub group oGroup = oGroup ? oGroup.findChild( sName ) : null; } // Return the properties for the element return getGroupProperties( oGroup, false, bRecurse ); }; /*********************************************************************/ // DzNode : A function for getting the root of a node function getRootNode( oNode ) { // If we have a node and it is a bone if( oNode && inheritsType( oNode, ["DzBone"] ) ){ // We want the skeleton return oNode.getSkeleton(); } // Return the original node return oNode; }; /*********************************************************************/ // DzObject : A function for getting the object for a node function getObjectForNode( oNode, bRoot ) { // Get the node var oContextNode = bRoot ? getRootNode( oNode ) : oNode; // If we do not have a root node if( !oContextNode ){ // We are done... return null; } // Get the object of the root node var oObject = oContextNode.getObject(); // If we do not have an object if( !oObject ){ // We are done... return null; } // Return the object return oObject; }; /*********************************************************************/ // DzShape : A function for getting the shape for a node function getShapeForNode( oNode, bRoot ) { // Get the object of the node var oObject = getObjectForNode( oNode, bRoot ); // If we do not have an object if( !oObject ){ // We are done... return null; } // Get the shape of the root node var oShape = oObject.getCurrentShape(); // If we do not have a shape if( !oShape ){ // We are done... return null; } // Return the shape return oShape; }; /*********************************************************************/ // Get the primary selection var oNode = Scene.getPrimarySelection(); // If nothing is selected if( !oNode ){ // We are done... return; } // Get the current shape for the object var oShape = getShapeForNode( oNode, true ); // If we do not have a shape if( !oShape ){ // We are done.. return; } // Get the selected materials var aMaterials = oShape.getAllSelectedMaterials(); // If we do not have any selected materials if( aMaterials.length < 1 ){ // Get all of the materials aMaterials = oShape.getAllMaterials(); } // Define the property(ies) we are looking for var sProperty = "Diffuse Color"; var sPropertyPath = "Base/Diffuse/Reflection"; // Initialize a list of properties var aProperties = []; // Declare working variables var oMaterial, var oProperty; // Iterate over the materials for( var i = 0; i < aMaterials.length; i += 1 ){ // Get the 'current' material oMaterial = aMaterials[ i ]; // If a property name is defined if( !sProperty.isEmpty() ){ // Find the property by name on the material oProperty = findElementProperty( oMaterial, sProperty, false ); // If the property is found if( oProperty ){ // Collect the property aProperties.push( oProperty ); } // If a property path is defined } else if( !sPropertyPath.isEmpty() ){ // Collect the properties at the specified path on the material aProperties = aProperties.concat( getElementPropertiesInPath( oMaterial, sPropertyPath, true ) ); // If neither a property name nor a property path is defined } else { // Collect the properties on the material aProperties = aProperties.concat( getElementProperties( oMaterial, true, true ) ); } } // Declare working variable var oTextureModifier; // Iterate over the collected properties for( var i = 0; i < aProperties.length; i += 1 ){ // Get the 'current' property oProperty = aProperties[ i ]; // Get a texture modifier for the property oTextureModifier = getTextureModifier( oProperty, true ); // If we do not have a texture modifier and could not create one if( !oTextureModifier ){ // Next!! continue; } // Toggle inversion of the texture color oTextureModifier.invert = !oTextureModifier.invert; } // Finalize the function and invoke })();