// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 /********************************************************************** *< FILE: shaveVrayCmd.cpp DESCRIPTION: Maya node HISTORY: created 01-04-2010 *> **********************************************************************/ #include "shaveRender.h" #include "shaveVrayNode.h" #include "shaveVrayCmd.h" #include "shaveVrayRenderer.h" #include "shaveVraySharedFunctions.h" #include "shaveHairShape.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef USE_VRAY /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ | Layer change callback | /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #if 0 static MCallbackId layerCbkId=0; static void shaveVrayLayerCbk(MNodeMessage::AttributeMessage msg, MPlug &plug, MPlug &otherPlug, void *clientData); #endif static std::vector cbkIds; static void shaveVrayShaderChangeCbk(MNodeMessage::AttributeMessage msg, MPlug &plug, MPlug &otherPlug, void *clientData); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ | Command | /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ MString shaveVrayCmd::cmd = "shaveVrayShader"; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ | Flags | /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ char* shaveVrayCmd::sf_create = "c"; char* shaveVrayCmd::lf_create = "create"; char* shaveVrayCmd::sf_delete = "d"; char* shaveVrayCmd::lf_delete = "delete"; char* shaveVrayCmd::sf_all = "all"; char* shaveVrayCmd::lf_all = "allShapes"; #if 0 char* shaveVrayCmd::sf_addCbk = "ac"; char* shaveVrayCmd::lf_addCbk = "addCallback"; char* shaveVrayCmd::sf_delCbk = "rc"; char* shaveVrayCmd::lf_delCbk = "removeCallback"; #endif //char* shaveVrayCmd::sf_shaveInit = "si"; //char* shaveVrayCmd::lf_shaveInit = "shaveInit"; // //char* shaveVrayCmd::sf_shaveClear= "sc"; //char* shaveVrayCmd::lf_shaveClear= "shaveClear"; //char* shaveVrayCmd::sf_frameStart= "fs"; //char* shaveVrayCmd::lf_frameStart= "frameStart"; // //char* shaveVrayCmd::sf_frameEnd = "fe"; //char* shaveVrayCmd::lf_frameEnd = "frameEnd"; //char* shaveVrayCmd::sf_shutterOpen = "so"; //char* shaveVrayCmd::lf_shutterOpen = "shutterOpen"; // //char* shaveVrayCmd::sf_shutterClose= "sc"; //char* shaveVrayCmd::lf_shutterClose= "shutterClose"; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ | Methods | /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ MStatus shaveVrayCmd::doIt(const MArgList &maList) { MStatus stat; setResult(0); // will be changed later. MArgDatabase parser(syntax(),maList,&stat); if(stat != MStatus::kSuccess) { MGlobal::displayError("shaveVray: can not parse arguments."); return stat; } { if(parser.isFlagSet(sf_create)) { if(parser.isFlagSet(sf_all)) { shaveVrayRenderer* renderer = dynamic_cast(shaveRender::getRenderer()); if (renderer == NULL) { MGlobal::displayError("'shaveVray -create -all' used when current renderer is not VRay"); return MS::kFailure; } MObjectArray shaveShapes; renderer->getRenderableShaveNodesByRenderMode(NULL, &shaveShapes); if(shaveShapes.length() > 0) { for(unsigned int i = 0; i < shaveShapes.length(); i++) { ////// MFnDependencyNode nodeFn(shaveShapes[i]); shaveHairShape* nodePtr = (shaveHairShape*)nodeFn.userNode(); MObject displayNode = nodePtr->getDisplayShape(); if (!displayNode.isNull()) { MFnDagNode dagNodeFn(displayNode); //visibility { MPlug plug = dagNodeFn.findPlug("visibility"); if(!plug.isNull()) { bool v; plug.getValue(v); if (!v) continue; } } //overriden visibility { MPlug plug = dagNodeFn.findPlug("overrideEnabled"); if(!plug.isNull()) { bool overridesEnabled; plug.getValue(overridesEnabled); if(overridesEnabled) { MPlug plug2 = dagNodeFn.findPlug("overrideVisibility"); if(!plug2.isNull()) { bool ovi; plug2.getValue(ovi); if(!ovi) continue; } } } } } if(!attachShaderTo(shaveShapes[i])) { MGlobal::displayError("shaveVray: can not attach the shader."); return MStatus::kNotFound; } }//for shapes /////////////////////////////////////// #if 0 { MObjectArray layers; MFnRenderLayer::listAllRenderLayers(layers); for(unsigned int oo = 0; oo < layers.length(); oo++) { MObjectArray members; MFnRenderLayer layerFn(layers[oo]); MGlobal::displayInfo(MString(" Layer ") + layerFn.name()); MGlobal::displayInfo("~~~~~~~~~~~~~~~~~~~~~~~~"); if(MStatus::kSuccess == layerFn.listMembers(members)) { for(unsigned int kk = 0; kk < members.length(); kk++) { MFnDependencyNode dFn(members[kk]); MGlobal::displayInfo(MString("member ") + dFn.name()); } } MGlobal::displayInfo("~~~~~~~~~~~~~~~~~~~~~~~~"); } } #endif ////////////////////////////////////// } } else { MObject shaveShape; if(FindCurrentShaveShape(shaveShape)) { if(attachShaderTo(shaveShape)) { setResult(1); return MStatus::kSuccess; } else { MGlobal::displayError("shaveVray: can not attach the shader."); return MStatus::kNotFound; } } else { MGlobal::displayError("shaveVray: select the hairShape to attach the shader."); return MStatus::kNotFound; } } } else if(parser.isFlagSet(sf_delete)) { deregisterShaderChangeCallacks(); if(parser.isFlagSet(sf_all)) { MObjectArray shaveShapes; if(FindAllShaveShapes(shaveShapes)) { for(unsigned int i = 0; i < shaveShapes.length(); i++) { if(!detachShaderFrom(shaveShapes[i])) { MGlobal::displayError("shaveVray: can not dettach the shader."); return MStatus::kNotFound; } } } } else { MObject shaveShape; if(FindCurrentShaveShape(shaveShape)) { if(detachShaderFrom(shaveShape)) { setResult(1); return MStatus::kSuccess; } else { MGlobal::displayError("shaveVray: can not dettach the shader."); return MStatus::kNotFound; } } else { MGlobal::displayError("shaveVray: select the hairShape to attach the shader."); return MStatus::kNotFound; } } } #if 0 else if(parser.isFlagSet(sf_addCbk)) { registerLayersCallback(); } else if(parser.isFlagSet(sf_delCbk)) { deregisterLayersCallack(); } #endif } setResult(1); return MStatus::kSuccess; } MSyntax shaveVrayCmd::newSyntax() { MSyntax syn; syn.enableQuery(true); syn.addFlag(sf_create, lf_create); syn.addFlag(sf_delete, lf_delete); syn.addFlag(sf_all, lf_all); #if 0 syn.addFlag(sf_addCbk, lf_addCbk); syn.addFlag(sf_delCbk, lf_delCbk); #endif return syn; } struct PlugPair { MPlug from; MPlug to; }; //static std::vector restore; bool shaveVrayCmd::attachShaderTo(MObject shaveShape) { #ifdef _DEBUG { MFnDependencyNode sFn(shaveShape); MGlobal::displayInfo(MString("shaveVrayCmd::attachShaderTo( ") + sFn.name() + " )"); } #endif MStatus stat; MFnDependencyNode shapeFn(shaveShape,&stat); if(stat == MStatus::kSuccess) { MPlug shaveStackIdxPlug = shapeFn.findPlug("stackIndex",&stat); if(stat == MStatus::kSuccess && !shaveStackIdxPlug.isNull()) { #if 0 /////////////////////////////////////////////// if(shaveStackIdxPlug.isConnected()) { MPlugArray plugs; if(shaveStackIdxPlug.connectedTo(plugs,false,true,&stat)) { for(unsigned int i = 0; i < plugs.length(); i++) { MObject shaderNode = plugs[i].node(); if(!shaderNode.isNull()) { MObjectArray nodes; EnumDownNodes(shaderNode,nodes); MDagModifier dagMod; for(unsigned int j = 0; j < nodes.length(); j++) { MFnDependencyNode dfn(nodes[j]); if(nodes[j].hasFn(MFn::kShape)) { MPlug visible = dfn.findPlug("visibility"); visible.setValue(true); setupLayers(shaveShape,nodes[j]); } } } } } return true; } #endif /////////////////////////////////////////////// MDGModifier dgMod; MObject vrayNode = dgMod.createNode(shaveVrayNode::typeId,&stat); if(stat == MStatus::kSuccess && !vrayNode.isNull()) { MFnDependencyNode vrayFn(vrayNode,&stat); if(stat == MStatus::kSuccess) { //connect stack index MPlug vrayStackIdxPlug = vrayFn.findPlug(shaveVrayNode::attr_stackIndex,&stat); if(stat == MStatus::kSuccess && !vrayStackIdxPlug.isNull()) { stat = dgMod.connect(shaveStackIdxPlug,vrayStackIdxPlug); if(stat == MStatus::kSuccess) { dgMod.doIt(); /// connect instancing status { MPlug shaveIsInstancedPlug = shapeFn.findPlug("instancingStatus",&stat); if(stat == MStatus::kSuccess && ! shaveIsInstancedPlug.isNull()) { MPlug vrayIsInstancedPlug = vrayFn.findPlug(shaveVrayNode::attr_isInstanced,&stat); if(stat == MStatus::kSuccess && ! vrayIsInstancedPlug.isNull()) { stat = dgMod.connect(shaveIsInstancedPlug,vrayIsInstancedPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect instacing status plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.isInstanced plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.instancingStatus plug."); } //// connect override surf shader flag { MPlug shaveOverrideShPlug = shapeFn.findPlug("overrideGeomShader",&stat); if(stat == MStatus::kSuccess && ! shaveOverrideShPlug.isNull()) { MPlug vrayOverrideShPlug = vrayFn.findPlug(shaveVrayNode::attr_ownshader,&stat); if(stat == MStatus::kSuccess && !vrayOverrideShPlug.isNull()) { stat = dgMod.connect(shaveOverrideShPlug,vrayOverrideShPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect overrideShader status plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.ownshader plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.overrideGeomShader plug."); } /////// connect tipfade plugs { MPlug shaveTipfadePlug = shapeFn.findPlug("tipFade",&stat); if(stat == MStatus::kSuccess && ! shaveTipfadePlug.isNull()) { MPlug vrayTipfadePlug = vrayFn.findPlug(shaveVrayNode::attr_tipfade,&stat); if(stat == MStatus::kSuccess && ! vrayTipfadePlug.isNull()) { stat = dgMod.connect(shaveTipfadePlug,vrayTipfadePlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect tipfade plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.tipfade plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.tipFade plug."); } /////// connect specular tint //////// { MPlug shavePlug = shapeFn.findPlug("specularTint",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_specTint,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect specular tint plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.specTint plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.specularTint plug."); } /////// connect specular tint 2 //////// { MPlug shavePlug = shapeFn.findPlug("specularTint2",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_specTint2,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect specular tint2 plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.specTint2 plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.specularTint2 plug."); } /////// connect squirrel plugs { MPlug shaveSquirrelPlug = shapeFn.findPlug("squirrel",&stat); if(stat == MStatus::kSuccess && ! shaveSquirrelPlug.isNull()) { MPlug vraySquirrelPlug = vrayFn.findPlug(shaveVrayNode::attr_squirrel,&stat); if(stat == MStatus::kSuccess && ! vraySquirrelPlug.isNull()) { stat = dgMod.connect(shaveSquirrelPlug,vraySquirrelPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect squirrel plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.squirrel plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.squirrel plug."); } /////// connect instance mesh { MPlug shaveInstancePlug = shapeFn.findPlug("instanceMesh",&stat); if(stat == MStatus::kSuccess && ! shaveInstancePlug.isNull()) { MPlug vrayInstancePlug = vrayFn.findPlug(shaveVrayNode::attr_instanceMesh,&stat); if(stat == MStatus::kSuccess && ! vrayInstancePlug.isNull()) { stat = dgMod.connect(shaveInstancePlug,vrayInstancePlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect instace mesh plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.instanceMesh plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.instanceMesh plug."); } /////// connect self shadow { MPlug shavePlug = shapeFn.findPlug("selfShadow",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_selfshadow,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect selfshadow plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.selfshadow plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.selfShadow plug."); } /////// connect cast shadow { MPlug shavePlug = shapeFn.findPlug("castsShadows",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_castshadow,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect castshadow plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.castshadow plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.castsShadows plug."); } /////// connect cast shadow { MPlug shavePlug = shapeFn.findPlug("receiveShadows",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_recvshadow,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect recvhadow plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.recvhadow plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.receiveShadows plug."); } /////// connect primary visibility { MPlug shavePlug = shapeFn.findPlug("primaryVisibility",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_primaryvis,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect prmary visibility plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.primaryvis plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.primaryVisibility plug."); } /// other attribs visibleInReflections visibleInRefractions castsShadows receiveShadows /////// connect visibility in reflectinss { MPlug shavePlug = shapeFn.findPlug("visibleInReflections",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_reflvis,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect refl visibility plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.reflvis plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.visibleInReflections plug."); } /////// connect visibility in refractinss { MPlug shavePlug = shapeFn.findPlug("visibleInRefractions",&stat); if(stat == MStatus::kSuccess && ! shavePlug.isNull()) { MPlug vrayPlug = vrayFn.findPlug(shaveVrayNode::attr_refrvis,&stat); if(stat == MStatus::kSuccess && ! vrayPlug.isNull()) { stat = dgMod.connect(shavePlug,vrayPlug); if(stat == MStatus::kSuccess) dgMod.doIt(); else MGlobal::displayError("shaveVrayCmd: can not connect refr visibility plugs."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveVrayNode.refrvis plug."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.visibleInRefractions plug."); } /// create dummy shape MCommandResult cmdResult; MGlobal::executeCommand("polyPrimitive", cmdResult, false); MStringArray resArray; cmdResult.getResult(resArray); MString node=resArray[0]; MString gen=resArray[1]; MObject nodeObj=getNodeByName(node.asChar()); MDagPath dagPath = MDagPath::getAPathTo(nodeObj); dagPath.extendToShape(); setupLayers(shaveShape,nodeObj); // Find where to connect the node to. We need to leave the groupParts nodes to give us face-mtl id info. MFnDependencyNode destNode(dagPath.node()); MPlug destPlug = destNode.findPlug("inMesh"); MPlug srcPlug; bool hasSource = false; while ((hasSource = getSourcePlugFromPlug(destPlug, srcPlug)) && srcPlug.node().apiType() == MFn::kGroupParts) { MFnDependencyNode srcNode(srcPlug.node()); destPlug = srcNode.findPlug("inputGeometry"); } // Make the necessary connections and set the attributes. if (hasSource) MGlobal::executeCommand("disconnectAttr " + srcPlug.name() + " " + destPlug.name() + ";"); MGlobal::executeCommand("connectAttr " + vrayFn.name() + ".output " + destPlug.name() + ";"); shaveHairShape* shaveUserNode = (shaveHairShape*)shapeFn.userNode(); if(shaveUserNode) { /// connect material MObject display = shaveUserNode->getDisplayShape(); registerShaderChangeCallback(display); MObject shader = shaveUserNode->getShader(); if(!shader.isNull()) { MFnDependencyNode shaderFn(shader); MPlug instGroups = destNode.findPlug("instObjGroups"); if(!instGroups.isNull()) { MPlug instGroups0 = instGroups.elementByPhysicalIndex(0); if(!instGroups0.isNull()) { if(instGroups0.isConnected()) { MPlugArray groupsTo; instGroups0.connectedTo(groupsTo,false,true); for(unsigned int k = 0; k < groupsTo.length(); k++) { MGlobal::executeCommand("disconnectAttr " +instGroups.name() + " " + groupsTo[k].name() + ";"); //dgMod.disconnect(instGroups0,groupsTo[k]); //dgMod.doIt(); } } MPlug dagSetPlug = shaderFn.findPlug("dagSetMembers"); if(!dagSetPlug.isNull()) { //int dagSetN = dagSetPlug.numElements(); //MPlug dagSetPlugK = dagSetPlug.elementByLogicalIndex(dagSetN+2); MPlug dagSetPlugK; for(int oo = 0; oo < 100000; oo++) { dagSetPlugK = dagSetPlug.elementByLogicalIndex(oo); if(!dagSetPlugK.isConnected()) break; } #ifdef _DEBUG MGlobal::displayInfo("connectAttr " + instGroups0.name() + " " + dagSetPlugK.name() + ";"); #endif MGlobal::executeCommand("connectAttr " + instGroups0.name() + " " + dagSetPlugK.name() + ";"); //MGlobal::executeCommand("connectAttr " + instGroups0.name() + " " + dagSetPlug.name() + ";"); //stat = dgMod.connect(instGroups0,dagSetPlugK); //if(stat == MStatus::kSuccess) // dgMod.doIt(); //else // MGlobal::displayError("shaveVrayCmd: can not connect surface shader."); } else MGlobal::displayError("shaveVrayCmd: can not find 'dagSetMembers'."); } else MGlobal::displayError("shaveVrayCmd: can not find 'instObjGroups0' plug."); } else MGlobal::displayError("shaveVrayCmd: can not find 'instObjGroups' plug."); } } else MGlobal::displayError("shaveVrayCmd: can not get 'userNode'."); printf("shaveVrayCmd::attachShaderTo(...) -- OK\n");fflush(stdout); return true; } else MGlobal::displayError("shaveVrayCmd: can not connect stack index plugs."); } else MGlobal::displayError("shaveVrayCmd: find shaveVrayNode.stackIndex plug."); } else MGlobal::displayError("shaveVrayCmd: can not attach MFnDependencyNode fucntion set to shaveVrayNode."); } else MGlobal::displayError("shaveVrayCmd: can not create shaveVrayNode."); } else MGlobal::displayError("shaveVrayCmd: can not find shaveHairShape.stackIndex plug."); } else MGlobal::displayError("shaveVrayCmd: can not attach MFnDependencyNode fucntion set to shaveHairShape node."); return false; } bool shaveVrayCmd::detachShaderFrom(MObject shShape) { #ifdef _DEBUG MGlobal::displayInfo("shaveVrayCmd::dettachShaderFrom(...)"); #endif MStatus stat; MFnDependencyNode shapeFn(shShape,&stat); if(stat == MStatus::kSuccess) { MPlug shavePlug = shapeFn.findPlug("stackIndex",&stat); if(stat == MStatus::kSuccess && !shavePlug.isNull()) { if(shavePlug.isConnected()) { MPlugArray plugs; if(shavePlug.connectedTo(plugs,false,true,&stat)) { for(unsigned int i = 0; i < plugs.length(); i++) { #if 1 MDGModifier dgMod; dgMod.disconnect(shavePlug,plugs[i]); dgMod.doIt(); #endif MObject shaderNode = plugs[i].node(); if(!shaderNode.isNull()) { MObjectArray nodes; EnumDownNodes(shaderNode,nodes); MDagModifier dagMod; for(unsigned int j = 0; j < nodes.length(); j++) { #if 0 MFnDependencyNode dfn(nodes[j]); if(nodes[j].hasFn(MFn::kShape)) { MPlug visible = dfn.findPlug("visibility"); visible.setValue(false); resetLayers(nodes[j]); } #endif #if 1 dagMod.deleteNode(nodes[j]); #endif } #if 1 dagMod.doIt(); #endif } } } } } } else return false; return true; } bool shaveVrayCmd::setupLayers(MObject shaveShape, MObject vrayShape) { MFnDependencyNode vrFn(vrayShape); MDagPath dagPath = MDagPath::getAPathTo(vrayShape); dagPath.extendToShape(); MFnDependencyNode destNode(dagPath.node()); MFnDependencyNode shapeFn(shaveShape); MFnDagNode shdagFn(shaveShape); MObject hair = shdagFn.parent(0); /////// set up same render layers as shave display shape ////// //// proably need to set up same as growth object ? { MObjectArray layers; shaveHairShape* nodePtr = (shaveHairShape*)shapeFn.userNode(); MObject displayNode = nodePtr->getDisplayShape(); MFnRenderLayer::listAllRenderLayers(layers); for(unsigned int oo = 0; oo < layers.length(); oo++) { MObjectArray members; MFnRenderLayer layerFn(layers[oo]); /////////////////// //MGlobal::displayInfo(MString(" ----- Checking layer ---- ") + layerFn.name() + "---dest--" + destNode.name()+"---"+vrFn.name()); ////////////////// if(MStatus::kSuccess == layerFn.listMembers(members)) { bool owner_found = false; bool dummy_found = false; int idx_to_remove = -1; for(unsigned int xx = 0; xx < members.length(); xx++) { MFnDependencyNode dFn(members[xx]); //////////////////// //MGlobal::displayInfo(dFn.name()); //////////////////// if(members[xx] == dagPath.node() || members[xx] == vrayShape) { dummy_found |= true; /////////////////// //MGlobal::displayInfo(MString("Dummy found ") + destNode.name() + " in " + layerFn.name() ); ////////////////// for(unsigned int kkk = 0; kkk < members.length(); kkk++) { if(members[kkk] == shaveShape || members[kkk] == displayNode || members[kkk] == hair) { owner_found |= true; break; } } idx_to_remove = xx; break; } } for(unsigned int kk = 0; kk < members.length(); kk++) { if(members[kk] == shaveShape || members[kk] == displayNode || members[kk] == hair) { /////////////////// //MFnDependencyNode dFn(members[kk]); //MGlobal::displayInfo(MString("Layer ") + layerFn.name() + " contains " + dFn.name()); ////////////////// bool found = false; for(unsigned int xx = 0; xx < members.length(); xx++) { if(members[xx] == dagPath.node()) { found = true; break; } } if(found) continue; /////////////////// //MGlobal::displayInfo(MString("Adding ") + destNode.name() + " to " + layerFn.name() ); ////////////////// MString cmd = MString("editRenderLayerMembers -noRecurse ") + layerFn.name() + MString(" ") + destNode.name(); MGlobal::executeCommand(cmd); } }//end for //need to remove if(!owner_found && dummy_found && idx_to_remove !=-1) { MFnDependencyNode dFn(members[idx_to_remove]); /////////////////// //MGlobal::displayInfo(MString("Removing ") + dFn.name() + " from " + layerFn.name() ); ////////////////// MString cmd = MString("editRenderLayerMembers -remove ") + layerFn.name() + MString(" ") + dFn.name(); MGlobal::executeCommand(cmd); } } } } /////// set up same display layers as shave display shape ////// { MObjectArray layers; MItDependencyNodes iter; for (; !iter.isDone(); iter.next()) { MObject node = iter.item(); if(node.hasFn(MFn::kDisplayLayer)) layers.append(node); } shaveHairShape* nodePtr = (shaveHairShape*)shapeFn.userNode(); MObject displayNode = nodePtr->getDisplayShape(); for(unsigned int oo = 0; oo < layers.length(); oo++) { MFnDependencyNode layerFn(layers[oo]); MPlug drPlug = layerFn.findPlug("drawInfo"); if(!drPlug.isNull()) { MStatus stat; MPlugArray members; if(drPlug.connectedTo(members,false,true,&stat) && stat == MStatus::kSuccess) { for(unsigned int kk = 0; kk < members.length(); kk++) { if(members[kk].node() == shaveShape || members[kk].node() == displayNode || members[kk].node() == hair) { bool found = false; for(unsigned int xx = 0; xx < members.length(); xx++) { if(members[xx].node() == dagPath.node()) { found = true; break; } } if(found) continue; MString cmd = MString("editDisplayLayerMembers -noRecurse ") + layerFn.name() + MString(" ") + destNode.name(); MGlobal::executeCommand(cmd); } } } } } } return true; } bool shaveVrayCmd::resetLayers(MObject vrayShape) { { //reset render layers MObjectArray layers; MFnRenderLayer::listAllRenderLayers(layers); for(unsigned int oo = 0; oo < layers.length(); oo++) { MObjectArray members; MFnRenderLayer layerFn(layers[oo]); if(layerFn.name() == "defaultRenderLayer") continue; if(MStatus::kSuccess == layerFn.listMembers(members)) { for(unsigned int kk = 0; kk < members.length(); kk++) { MFnDependencyNode mFn(members[kk]); if(members[kk] == vrayShape) { MString cmd = MString("editRenderLayerMembers -remove ") + layerFn.name() + MString(" ") + mFn.name(); MGlobal::executeCommand(cmd); } } } } } { //reset display layers MObjectArray layers; MItDependencyNodes iter; for (; !iter.isDone(); iter.next()) { MObject node = iter.item(); if(node.hasFn(MFn::kDisplayLayer)) layers.append(node); } for(unsigned int oo = 0; oo < layers.length(); oo++) { MFnDependencyNode layerFn(layers[oo]); MPlug drPlug = layerFn.findPlug("drawInfo"); if(!drPlug.isNull()) { MStatus stat; MPlugArray members; if(drPlug.connectedTo(members,false,true,&stat) && stat == MStatus::kSuccess) { for(unsigned int kk = 0; kk < members.length(); kk++) { MFnDependencyNode mFn(members[kk].node()); if(members[kk].node() == vrayShape) { MString cmd = MString("editRenderLayerMembers -remove ") + layerFn.name() + MString(" ") + mFn.name(); MGlobal::executeCommand(cmd); } } } } } } return true; } bool shaveVrayCmd::registerShaderChangeCallback(MObject shape) { MStatus stat; MCallbackId cbkId = MNodeMessage::addAttributeChangedCallback (shape, shaveVrayShaderChangeCbk, NULL, &stat); if(stat!=MStatus::kSuccess) { MGlobal::displayError("shaveVrayCmd: can not register attribute change callback."); return false; } cbkIds.push_back(cbkId); return true; } bool shaveVrayCmd::deregisterShaderChangeCallacks() { for(size_t i = 0; i < cbkIds.size(); i++) { MStatus stat = MNodeMessage::removeCallback(cbkIds[i]); if(stat != MStatus::kSuccess) MGlobal::displayError("shaveVrayCmd: can not deregister attribute change callback."); } cbkIds.clear(); return true; } void shaveVrayShaderChangeCbk(MNodeMessage::AttributeMessage msg, MPlug &plug, MPlug &otherPlug, void *clientData) { #ifdef _DEBUG MGlobal::displayInfo(MString("shaveVrayShaderChangeCbk( ")+ plug.name() + " ---> " + otherPlug.name()+" )"); #endif if( msg & MNodeMessage::kConnectionMade ) { std::string s(plug.name().asChar()); if(s.find("instObjGroups") != std::string::npos) { #ifdef _DEBUG MGlobal::displayInfo(plug.name()); #endif MObject display = plug.node(); MFnDependencyNode dFn(display); #ifdef _DEBUG MGlobal::displayInfo(MString("display node ") + dFn.name()); #endif MPlug msg = dFn.findPlug("message"); MPlugArray connections; msg.connectedTo(connections, false, true); #ifdef _DEBUG MGlobal::displayInfo("message connections"); for(int oo=0; oogetShader(); /////////////////////////////// MObject shader; { //MPlug dplug= dFn1.findPlug("displayNode"); //MPlugArray dconnections; //dplug.connectedTo(dconnections, true, false); #ifdef _DEBUG //if (dconnections.length() == 0) MGlobal::displayInfo(plug.name() + " does not have connection!!!!"); #endif //if (dconnections.length() > 0) { //MObject displayNode = dconnections[0].node(); //if (!displayNode.isNull()) { //MFnDependencyNode nodeFn(displayNode); //MPlug groupPlug = nodeFn.findPlug("instObjGroups"); //MPlug groupPlug = plug; MPlug groupPlug = dFn.findPlug("instObjGroups"); #ifdef _DEBUG MGlobal::displayInfo(groupPlug.name()); #endif if (groupPlug.numConnectedElements() > 0) { MPlugArray groupConnections; groupPlug .connectionByPhysicalIndex(0) .connectedTo(groupConnections, false, true); // // If we're connected to a shadingEngine node, then we're done. // if (groupConnections.length() > 0) { for(unsigned int i = 0; i < groupConnections.length(); i++) { MObject ashader = groupConnections[i].node(); if (ashader.hasFn(MFn::kShadingEngine)) { shader = ashader; #ifdef _DEBUG MGlobal::displayInfo("shader found..."); #endif break; } } } } } } } /////////////////////////////// MPlug stackIdxPlug = dFn1.findPlug("stackIndex"); MPlugArray connections1; stackIdxPlug.connectedTo(connections1, false, true); if(connections1.length() > 0) { #ifdef _DEBUG MGlobal::displayInfo(connections1[0].name()); #endif MObject vrayNode = connections1[0].node(); MFnDependencyNode dFn2(vrayNode); MPlug outputPlug = dFn2.findPlug("output"); MPlugArray connections2; outputPlug.connectedTo(connections2, false, true); if(connections2.length() > 0) { #ifdef _DEBUG MGlobal::displayInfo(connections2[0].name()); #endif MObject polyShape = connections2[0].node(); MFnDependencyNode destNode(polyShape); MFnDependencyNode shaderFn(shader); #ifdef _DEBUG MGlobal::displayInfo("shader name " + shaderFn.name()); #endif MPlug instGroups = destNode.findPlug("instObjGroups"); if(!instGroups.isNull()) { MPlug instGroups0 = instGroups.elementByPhysicalIndex(0); if(!instGroups0.isNull()) { if(instGroups0.isConnected()) { MPlugArray groupsTo; instGroups0.connectedTo(groupsTo,false,true); for(unsigned int k = 0; k < groupsTo.length(); k++) { MGlobal::executeCommand("disconnectAttr " +instGroups.name() + " " + groupsTo[k].name() + ";"); } } MPlug dagSetPlug = shaderFn.findPlug("dagSetMembers"); if(!dagSetPlug.isNull()) { MPlug dagSetPlugK; for(int oo = 0; oo < 100000; oo++) { dagSetPlugK = dagSetPlug.elementByLogicalIndex(oo); if(!dagSetPlugK.isConnected()) break; } #ifdef _DEBUG MGlobal::displayInfo("connectAttr " + instGroups0.name() + " " + dagSetPlugK.name() + ";"); #endif MGlobal::executeCommand("connectAttr " + instGroups0.name() + " " + dagSetPlugK.name() + ";"); } else MGlobal::displayError("shaveVrayShaderChangeCbk: can not find 'dagSetMembers'."); } else MGlobal::displayError("shaveVrayShaderChangeCbk: can not find 'instObjGroups0' plug."); } else MGlobal::displayError("shaveVrayShaderChangeCbk: can not find 'instObjGroups' plug."); } } #if 0 //works but create a lot of dumb looping MGlobal::executeCommand("shaveVrayShader -delete -all"); MGlobal::executeCommand("shaveVrayShader -create -all"); #endif } } } #if 0 bool shaveVrayCmd::registerLayersCallback() { MObjectArray lm; FindNodesByApiType(MFn::kRenderLayerManager,lm); if(lm.length() > 0) { MStatus stat; assert(layerCbkId==0); layerCbkId = MNodeMessage::addAttributeChangedCallback (lm[0], shaveVrayLayerCbk, NULL, &stat); if(stat!=MStatus::kSuccess) { MGlobal::displayError("shaveVrayCmd: can not register layer callback."); return false; } return true; } return false; } bool shaveVrayCmd::deregisterLayersCallack() { if(layerCbkId!=0) { MStatus stat = MNodeMessage::removeCallback(layerCbkId); layerCbkId = 0; if(stat != MStatus::kSuccess) { MGlobal::displayError("shaveVrayCmd: can not deregister layer callback."); return false; } return true; } return false; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~ callback ~~~~~~~~~~~~~~~~~~~~~~~~*/ void shaveVrayLayerCbk(MNodeMessage::AttributeMessage msg, MPlug &plug, MPlug &otherPlug, void *clientData) { //crap, correct shader is connected but it like //we a step backward if( msg & MNodeMessage::kAttributeSet ) { //this is called in time #ifdef _DEBUG MGlobal::displayInfo("shaveVrayLayerCbk"); #endif int v; plug.getValue(v); #ifdef _DEBUG MGlobal::displayInfo(plug.name() + " value " + v); #endif MObjectArray layers; MFnRenderLayer::listAllRenderLayers(layers); MFnDependencyNode dFn(layers[v]); #ifdef _DEBUG MGlobal::displayInfo("Layer " + dFn.name()); #endif //MGlobal::executeCommand("editRenderLayerGlobals -currentRenderLayer "+dFn.name()); //is it essencial? //if se do it on the place incorrect mtls are fetched becuse connections were not updated yet //if we do on idle correct materials are recived but we are too late MGlobal::executeCommandOnIdle("shaveVrayShader -delete -all"); MGlobal::executeCommandOnIdle("shaveVrayShader -create -all"); } } #endif #endif