// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #include #include #include #include #include #include "shaveCheckObjectVisibility.h" #include "shaveIO.h" #include "shaveUtil.h" bool isObjectVisible( const MDagPath& path, bool andNotTemplated, bool ignorePrimaryVisibility, bool ignoreTransparency, bool ignoreOverrideTemplating, bool& overridesEnabled ) // // Description: // Check if the given object is visible // { MStatus status; MFnDagNode fnDN(path); MPlug plug; // // Are layer overrides enabled? // plug = fnDN.findPlug("overrideEnabled"); plug.getValue(overridesEnabled); // // If the object isn't visible, then it's not visible. :-) // bool isSet; plug = fnDN.findPlug("visibility"); plug.getValue(isSet); if (!isSet) return false; if (!ignorePrimaryVisibility) { plug = fnDN.findPlug("primaryVisibility"); plug.getValue(isSet); if (!isSet) return false; } // // If any part of the object is being shaded by a shader with non-zero // transparency, or whose transparency is driven by a connection, then // we will consider the object to be transparent and return false. // if (!ignoreTransparency) { // // Get all of the shading groups to which this instance of this // object, or any of its components, is assigned. // MObjectArray shadingGroups; shaveUtil::getShadingGroups(path, shadingGroups); // // Step through each shading group and see if its associated // shader has non-zero transparency. // float transparency; unsigned int i; unsigned int j; unsigned int k; unsigned int numShadingGroups = shadingGroups.length(); MPlugArray conns; char* plugNames[] = { "surfaceShader", "volumeShader" }; char* transpNames[] = { "transparency", "transparencyR", "transparencyG", "transparencyB" }; for (i = 0; i < numShadingGroups; i++) { MFnDependencyNode groupFn(shadingGroups[i]); for (j = 0; j < 2; j++) { plug = groupFn.findPlug(plugNames[j], &status); if (status) { // // If this port on the shading group has a shader // connected to it, then we need to check the shader's // transparency. // // Unless this is a layered shader, then we ignore // transparency because layered shaders *always* have // transparency but are rarely transparent overall. // plug.connectedTo(conns, true, false); if ((conns.length() > 0) && !conns[0].node().hasFn(MFn::kLayeredShader)) { MFnDependencyNode shaderFn(conns[0].node()); // // Does the shader have a transparency attribute? // for (k = 0; k < 4; k++) { plug = shaderFn.findPlug(transpNames[k], &status); if (status) { // // If the transparency attribute has an // incoming connection, then the // transparency value may change during the // course of a render. So we treat the // shader as being transparent and return // true. // plug.connectedTo(conns, true, false); if (conns.length() > 0) return false; // // If the shader's transparency is anything // other than zero, we treat it as // transparent and return true. // plug.getValue(transparency); if (transparency > 0.0f) return false; } } } } } } } // // If the object is an intermediate object (e.g. in the middle of a // chaini of deformations) then it's not visible. // plug = fnDN.findPlug("intermediateObject"); plug.getValue(isSet); if (isSet) return false; // // Are we treating templated objects as if they're invisible? // if (andNotTemplated) { plug = fnDN.findPlug("template"); plug.getValue(isSet); if (isSet) return false; } if (overridesEnabled) { // // Now we do the same checks, but this time for the layer // overrides. // // First, visibility. // plug = fnDN.findPlug("overrideVisibility"); plug.getValue(isSet); if (!isSet) return false; // // Templating. // if (andNotTemplated && !ignoreOverrideTemplating) { int displayMode; plug = fnDN.findPlug("overrideDisplayType"); plug.getValue(displayMode); if (displayMode == 1) return false; } } return true; } bool areObjectAndParentsVisible( const MDagPath& path, bool andNotTemplated, bool ignorePrimaryVisibility, bool ignoreTransparency ) // // Description: // Check if this object and all of its parents are visible. In Maya, // visibility is determined by heirarchy. So, if one of a node's // parents is invisible, then so is the node. // { bool ignoreOverrideTemplating = false; bool isVisible = true; bool overridesEnabled; MDagPath searchPath(path); while (isVisible) { isVisible = isObjectVisible( searchPath, andNotTemplated, ignorePrimaryVisibility, ignoreTransparency, ignoreOverrideTemplating, overridesEnabled ); if (searchPath.length() == 1) break; // // One exception to the hierarchical rule is override templating. // That's handled by the lowest node which has overrides enabled. // So once we've hit a node which has overrides enabled, then we // must ignore override templating in any nodes above that in the // hierarchy. // if (overridesEnabled) ignoreOverrideTemplating = true; searchPath.pop(); } return isVisible; }