void dumpInfo( MObject fileNode, MFnDependencyNode& nodeFn, MObjectArray& nodePath ) { MObject currentNode; MObject fileAttr = nodeFn.attribute("fileTextureName"); MPlug plugToFile( fileNode, fileAttr ); MFnDependencyNode dgFn; MStatus stat; cerr << "Name: " << nodeFn.name() << endl; MObject fnameValue; stat = plugToFile.getValue( fnameValue ); if ( !stat ) { stat.perror("error getting value from plug"); } else { MFnStringData stringFn( fnameValue ); cerr << "Texture: " << stringFn.string() << endl; } cerr << "Path: "; for ( int i = nodePath.length()-1; i >= 0; i-- ) { currentNode = nodePath[i]; dgFn.setObject( currentNode ); cerr << dgFn.name() << "(" << dgFn.typeName() << ")"; if ( i > 0) cerr << " ->\n "; } cerr << endl; }
//--------------------------------------------------------------- String EffectTextureExporter::exportImage ( const MObject &texture ) { // Retrieve the texture filename MFnDependencyNode textureNode ( texture ); MString mayaName = textureNode.name(); MPlug filenamePlug = textureNode.findPlug ( ATTR_FILE_TEXTURE_NAME ); // Get the maya image id. String mayaImageId = DocumentExporter::mayaNameToColladaName ( textureNode.name() ); // Generate a COLLADA id for the new light object String colladaImageId; // Check if there is an extra attribute "colladaId" and use this as export id. MString attributeValue; DagHelper::getPlugValue ( texture, COLLADA_ID_ATTRIBUTE_NAME, attributeValue ); if ( attributeValue != EMPTY_CSTRING ) { // Generate a valid collada name, if necessary. colladaImageId = mDocumentExporter->mayaNameToColladaName ( attributeValue, false ); } else { // Generate a COLLADA id for the new light object colladaImageId = DocumentExporter::mayaNameToColladaName ( textureNode.name() ); } // Make the id unique and store it in a map for refernences. colladaImageId = mImageIdList.addId ( colladaImageId ); mMayaIdColladaImageId [mayaImageId] = colladaImageId; // Get the maya filename with the path to the file. MString mayaFileName; filenamePlug.getValue ( mayaFileName ); if ( mayaFileName.length () == 0 ) return NULL; String sourceFile = mayaFileName.asChar (); COLLADASW::URI sourceFileUri ( COLLADASW::URI::nativePathToUri ( sourceFile ) ); if ( sourceFileUri.getScheme ().empty () ) sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE ); COLLADASW::Image* colladaImage = exportImage ( mayaImageId, colladaImageId, sourceFileUri ); if ( colladaImage == NULL ) return NULL; // Export the node type, because PSD textures don't behave the same as File textures. String nodeType = texture.hasFn ( MFn::kPsdFileTexture ) ? MAYA_TEXTURE_PSDTEXTURE : MAYA_TEXTURE_FILETEXTURE; colladaImage->addExtraTechniqueParameter ( PROFILE_MAYA, MAYA_TEXTURE_NODETYPE, nodeType ); // Export whether this image is in fact an image sequence MPlug imgSeqPlug = textureNode.findPlug ( ATTR_IMAGE_SEQUENCE ); bool isImgSeq = false; imgSeqPlug.getValue ( isImgSeq ); colladaImage->addExtraTechniqueParameter ( PROFILE_MAYA, MAYA_TEXTURE_IMAGE_SEQUENCE, isImgSeq ); return colladaImage->getImageId(); }
MString AppleseedRenderer::defineColor(MFnDependencyNode& shader, MString& attributeName, MString colorSpace = "srgb", float intensity = 1.0f) { MColor col(0,0,0); if(!getColor(attributeName, shader, col)) { logger.error(MString("Unable to get color values from node: ") + shader.name()); return ""; } MString colorName = shader.name() + "_" + attributeName; defineColor(colorName, col, intensity, colorSpace); return colorName; }
// -------------------------------------------------------- COLLADASW::PrimitivesBase* GeometryPolygonExporter::preparePrimitivesBase( const MFnMesh &fnMesh, const uint numPolygons, const uint exportType ) { // Just create a polylist, if there are polygons to export // If we have holes in the polygon, we have to use <polygons> instead of <polylist>. // If we want to export as triangles, we have to use <triangles>. COLLADASW::PrimitivesBase* primitivesBasePoly = createPrimitivesBase ( exportType ); // Begin to write. primitivesBasePoly->openPrimitiveElement(); // Check if the material should be set uint realShaderCount = ( uint ) mShaders.length(); if ( mShaderPosition < realShaderCount ) { // Add shader-specific parameters (TexCoords sets). // Add symbolic name for the material used on this polygon set. MFnDependencyNode shaderFn ( mShaders[mShaderPosition] ); String shaderName = shaderFn.name().asChar(); String materialName = DocumentExporter::mayaNameToColladaName ( shaderFn.name() ); primitivesBasePoly->appendMaterial ( materialName ); } // Set the number of polygons primitivesBasePoly->appendCount ( numPolygons ); // Get the polygon input list COLLADASW::InputList& inputList = primitivesBasePoly->getInputList(); getPolygonInputAttributes ( inputList ); primitivesBasePoly->appendInputList(); // Set the vertex count list, if we have a POLYLIST if ( exportType == PolygonSource::POLYLIST ) { // Retrieve the vertex count list for the polylist element. primitivesBasePoly->openVertexCountListElement(); writeVertexCountList ( primitivesBasePoly, fnMesh ); primitivesBasePoly->closeElement(); } if ( exportType != PolygonSource::POLYGONS ) { // Prepare the list for add the vertex indexes primitivesBasePoly->openPolylistElement(); } return primitivesBasePoly; }
void EntityNode::UnloadArt() { MStatus stat; // remove anything currently imported/referenced MFnDagNode dagFn( thisMObject() ); while( dagFn.childCount() ) { stat = MGlobal::deleteNode( dagFn.child( 0 ) ); MContinueErr( stat, ("Unable to delete" + dagFn.fullPathName() ).asChar() ); } ClearInstances(); MObjectArray forDelete; GetImportNodes( forDelete ); MFnDependencyNode depFn; u32 num = forDelete.length(); for( u32 i = 0; i < num; ++i ) { MObject& node = forDelete[i]; MObjectHandle handle( node ); if( !handle.isValid() ) continue; depFn.setObject( node ); stat = MGlobal::deleteNode( node ); MContinueErr( stat, ("Unable to delete" + depFn.name() ).asChar() ); } forDelete.clear(); }
// ------------------------------------------------------------ void SceneGraph::appendForcedNodeToList ( const MDagPath& dagPath ) { // Attach a function set MFnDependencyNode fn ( dagPath.node() ); String theNodeName = fn.name().asChar(); MDagPath dagPathCopy = dagPath; while ( dagPathCopy.length() > 0 && !isForcedNode ( dagPathCopy ) ) { // Attach a function set MFnDependencyNode fn ( dagPathCopy.node() ); String theNodeName = fn.name().asChar(); mForcedNodes.append ( dagPathCopy ); dagPathCopy.pop(); } }
//--------------------------- String DocumentExporter::dagPathToColladaName ( const MDagPath& dagPath ) { // Get a COLLADA suitable node name from a DAG path // For import/export symmetry, this should be exactly the // Maya node name. If we include any more of the path, we'll // get viral node names after repeated import/export. MFnDependencyNode node ( dagPath.node() ); return mayaNameToColladaName ( node.name(), true ); }
std::string CMayaNode::GetName() { MStatus status; MFnDependencyNode depNode (m_dagPath.node(), &status); if (status != MS::kSuccess) return ""; return depNode.name ().asChar(); }
//--------------------------------------------------- // set the bind pose for a transform // MStatus DagHelper::setBindPoseInverse ( const MObject& node, const MMatrix& bindPoseInverse ) { MStatus status; MFnDependencyNode dgFn ( node ); MPlug bindPosePlug = dgFn.findPlug ( "bindPose", &status ); if ( status != MS::kSuccess ) { MGlobal::displayWarning ( MString ( "No bindPose found on node " ) + dgFn.name() ); return status; } MFnMatrixData matrixFn; MObject val = matrixFn.create ( bindPoseInverse.inverse(), &status ); MObject invval = matrixFn.create ( bindPoseInverse, &status ); if ( status != MS::kSuccess ) { MGlobal::displayWarning ( MString ( "Error setting bindPose on node " ) + dgFn.name() ); return status; } // set the bind pose on the joint itself bindPosePlug.setValue ( val ); // Now, perhaps more significantly, see if there's a // skinCluster using this bone and update its bind // pose (as the joint bind pose is not connected to // the skin - it's set at bind time from the joint's // current position, and our importer may not want to // disturb the current scene state just to put bones // in a bind position before creating skin clusters) MObject _node ( node ); MItDependencyGraph it ( _node, MFn::kSkinClusterFilter ); while ( !it.isDone() ) { MPlug plug = it.thisPlug(); unsigned int idx = plug.logicalIndex(); MFnDependencyNode skinFn ( plug.node() ); MPlug skinBindPosePlug = skinFn.findPlug ( "bindPreMatrix", &status ); if ( status == MS::kSuccess ) { // The skinCluster stores inverse inclusive matrix // so notice we use invval (the MObject created off // the inverse matrix here) skinBindPosePlug = skinBindPosePlug.elementByLogicalIndex ( idx ); skinBindPosePlug.setValue ( invval ); } it.next(); } return status; }
// ------------------------------------------- const String& SceneElement::getNodeName() const { if ( mNodeName.empty() ) { const MObject & _node = getNode(); // Attach a function set MFnDependencyNode fn ( _node ); mNodeName = DocumentExporter::mayaNameToColladaName ( fn.name() ); } return mNodeName; }
//--------------------------------------------------- // // Find a node connected to a node's array attribute // bool DagHelper::getPlugArrayConnectedTo ( const MObject& node, const MString& attribute, MPlug& connectedPlug ) { MStatus status; MFnDependencyNode dgFn ( node ); MPlug plug = dgFn.findPlug ( attribute, &status ); if ( status != MS::kSuccess ) { MGlobal::displayWarning ( MString ( "couldn't find plug on attribute " ) + attribute + MString ( " on object " ) + dgFn.name() ); return false; } if ( plug.numElements() < 1 ) { MGlobal::displayWarning ( MString ( "plug array doesn't have any connection on attribute " ) + attribute + MString ( " on object " ) + dgFn.name() ); return false; } MPlug firstElementPlug = plug.connectionByPhysicalIndex ( 0 ); // Get the connection - there can be at most one input to a plug // MPlugArray connections; firstElementPlug.connectedTo ( connections, true, true ); if ( connections.length() == 0 ) { MGlobal::displayWarning ( MString ( "plug connected to an empty array on attribute " ) + attribute + MString ( " on object " ) + dgFn.name() ); return false; } connectedPlug = connections[0]; return true; }
// ------------------------------------------------------------ SceneElement* SceneGraph::createSceneElement ( const MDagPath &dagPath, SceneElement* parentSceneElement ) { // Create a new scene element SceneElement* sceneElement = new SceneElement ( dagPath ); // Attach a function set MFnDependencyNode fn ( dagPath.node() ); // Check for multiple instances. bool isInstanced = dagPath.isInstanced (); if ( parentSceneElement == 0 ) { // dagPath.getAllPathsTo ( ) () } // Get the node name String nodeName = DocumentExporter::mayaNameToColladaName ( fn.name() ); sceneElement->setNodeName ( nodeName ); // Check if it's a node to export and // tell the scene node to be transformed or not. bool isForced = false; bool isVisible = false; bool isExportNode = getIsExportNode ( dagPath, isForced, isVisible ); sceneElement->setIsForced ( isForced ); sceneElement->setIsVisible ( isVisible ); // Check for a file reference MFnDagNode dagFn ( dagPath ); bool isLocal = !dagFn.isFromReferencedFile(); if ( ExportOptions::exportXRefs() && ExportOptions::dereferenceXRefs()) isLocal = true; if ( !isLocal && !ExportOptions::exportXRefs() ) isExportNode = false; sceneElement->setIsExportNode ( isExportNode ); sceneElement->setIsLocal ( isLocal ); if ( parentSceneElement != NULL ) { if ( !sceneElement->containsParentElement ( parentSceneElement ) ) sceneElement->addParentElement ( parentSceneElement ); if ( !parentSceneElement->containsChildElement ( sceneElement ) ) parentSceneElement->addChildElement ( sceneElement ); } return sceneElement; }
//for each animation layer we have, write out the name of the layer //we will later write out the layer like a depend node and write out //each attribute, but we do this seperately so that on import we //can quickly see what layers are in the ATOM file so that we can //create them if they are missing void atomAnimLayers::writeAnimLayers(ofstream &animFile, atomWriter &writer) { if(mAnimLayers.length() > 0) // at least one Layer { animFile <<kAnimLayers << " { "; for(unsigned int k = 0; k < mAnimLayers.length(); ++k) { if(mAnimLayers[k].hasFn (MFn::kDependencyNode)) { MFnDependencyNode fnNode (mAnimLayers[k]); MString layerName = fnNode.name(); animFile <<" " << layerName; } } animFile << " }\n"; } }
//this function will pass in all anim layer objects found on a particular plug. since we want them to be //kept in order, but don't want ALL of the anim layers to be specified if they aren't used we bool atomAnimLayers::addAnimLayers(MObjectArray &layers) { if(mOrderedAnimLayerNames.length() > 0) { //first time called set up the mAnimLayers object array. if(mAnimLayers.length() != mOrderedAnimLayerNames.length()) { mAnimLayers.setLength(mOrderedAnimLayerNames.length()); MObject nullObject; //initialize with nulls for(unsigned int k = 0; k < mAnimLayers.length(); ++k) { mAnimLayers[k] = nullObject; } } } //if here we have the ordered name list and the anim layer object list //now we just need to set the objects passed in correctly for(unsigned int k = 0; k < layers.length(); ++k) { if(layers[k].hasFn (MFn::kDependencyNode)) { MFnDependencyNode fnNode (layers[k]); MString layerName = fnNode.name(); for(unsigned int z = 0; z < mOrderedAnimLayerNames.length();++z) { if(layerName == mOrderedAnimLayerNames[z]) { mAnimLayers[z] = layers[k]; break; } } } } return true; }
//------------------------------------------------------ void MaterialExporter::exportMaterialsByShaderPlug() { // Get all shaders, which are in the default shader list. MObject defaultShaderList = DagHelper::getNode ( ATTR_DEFAULT_SHADER_LIST1 ); MPlug defaultShadersPlug = MFnDependencyNode ( defaultShaderList ).findPlug ( ATTR_SHADERS ); uint shaderCount = defaultShadersPlug.evaluateNumElements(); for ( uint i = 0; i < shaderCount; ++i ) { MObject shader = DagHelper::getNodeConnectedTo ( defaultShadersPlug.elementByPhysicalIndex ( i ) ); MFnDependencyNode shadingEngineFn ( shader ); // Get the name of the current material (this is the maya material id) String mayaMaterialId = DocumentExporter::mayaNameToColladaName ( shadingEngineFn.name(), true ); bool doExportMaterial = true; bool isFromReferencedFile = shadingEngineFn.isFromReferencedFile(); // bool isDefaulNode = shadingEngineFn.isDefaultNode(); // if ( isDefaulNode ) // { // doExportMaterial = false; // } // else if ( isFromReferencedFile ) if ( isFromReferencedFile ) { if ( ExportOptions::exportXRefs() && ExportOptions::dereferenceXRefs() ) doExportMaterial = true; else doExportMaterial = false; } if ( doExportMaterial ) { MObject shadingEngine = ShaderHelper::getShadingEngine ( shader ); exportMaterial ( shadingEngine ); } } }
//for this attribute on this node add the following layer nodes and plugs it's associated with void atomNodeWithAnimLayers::addPlugWithLayer(MPlug &attrPlug, MObjectArray &layers, MPlugArray &plugs) { if(plugs.length() == layers.length()) { MObject attrObj = attrPlug.attribute(); MFnAttribute fnLeafAttr (attrObj); std::string attrStd(std::string(fnLeafAttr.name().asChar())); PlugsAndLayers plugsAndLayers; for(unsigned int i =0; i < layers.length(); ++i) { if(plugs[i].isNull()==false) //it's possible to not have a plug for the specified layer { if(layers[i].hasFn (MFn::kDependencyNode)) { MFnDependencyNode fnNode (layers[i]); MString layerName = fnNode.name(); plugsAndLayers.mLayerNames.append(layerName); plugsAndLayers.mPlugs.append(plugs[i]); fAttrLayers[attrStd] = plugsAndLayers; } } } } }
void CScriptedShapeTranslator::RunScripts(AtNode *atNode, unsigned int step, bool update) { std::map<std::string, CScriptedTranslator>::iterator translatorIt; MFnDependencyNode fnNode(GetMayaObject()); translatorIt = gTranslators.find(fnNode.typeName().asChar()); if (translatorIt == gTranslators.end()) { AiMsgError("[mtoa.scriptedTranslators] No command to export node \"%s\" of type %s.", fnNode.name().asChar(), fnNode.typeName().asChar()); return; } MString exportCmd = translatorIt->second.exportCmd; MString cleanupCmd = translatorIt->second.cleanupCmd; MFnDagNode node(m_dagPath.node()); bool isMasterDag = false; bool transformBlur = IsMotionBlurEnabled(MTOA_MBLUR_OBJECT) && IsLocalMotionBlurEnabled(); bool deformBlur = IsMotionBlurEnabled(MTOA_MBLUR_DEFORM) && IsLocalMotionBlurEnabled(); char buffer[64]; MString command = exportCmd; command += "("; sprintf(buffer, "%f", GetExportFrame()); command += buffer; command += ", "; sprintf(buffer, "%d", step); command += buffer; command += ", "; // current sample frame sprintf(buffer, "%f", GetSampleFrame(m_session, step)); command += buffer; command += ", "; // List of arnold attributes the custom shape export command has overriden MStringArray attrs; if (!m_masterNode) { command += "(\"" + m_dagPath.partialPathName() + "\", \""; command += AiNodeGetName(atNode); command += "\"), None)"; isMasterDag = true; } else { command += "(\"" + m_dagPath.partialPathName() + "\", \""; command += AiNodeGetName(atNode); command += "\"), (\"" + GetMasterInstance().partialPathName() + "\", \""; command += AiNodeGetName(m_masterNode); command += "\"))"; } MStatus status = MGlobal::executePythonCommand(command, attrs); if (!status) { AiMsgError("[mtoa.scriptedTranslators] Failed to export node \"%s\".", node.name().asChar()); return; } // Build set of attributes already processed std::set<std::string> attrsSet; for (unsigned int i=0; i<attrs.length(); ++i) { attrsSet.insert(attrs[i].asChar()); } std::set<std::string>::iterator attrsEnd = attrsSet.end(); // Should be getting displacement shader from master instance only // as arnold do not support displacement shader overrides for ginstance MFnDependencyNode masterShadingEngine; MFnDependencyNode shadingEngine; float dispPadding = -AI_BIG; float dispHeight = 1.0f; float dispZeroValue = 0.0f; bool dispAutobump = false; bool outputDispPadding = false; bool outputDispHeight = false; bool outputDispZeroValue = false; bool outputDispAutobump = false; const AtNodeEntry *anodeEntry = AiNodeGetNodeEntry(atNode); GetShapeInstanceShader(m_dagPath, shadingEngine); if (!IsMasterInstance()) { GetShapeInstanceShader(GetMasterInstance(), masterShadingEngine); } else { masterShadingEngine.setObject(shadingEngine.object()); } AtMatrix matrix; MMatrix mmatrix = m_dagPath.inclusiveMatrix(); ConvertMatrix(matrix, mmatrix); // Set transformation matrix if (attrsSet.find("matrix") == attrsEnd) { if (HasParameter(anodeEntry, "matrix")) { if (transformBlur) { if (step == 0) { AtArray* matrices = AiArrayAllocate(1, GetNumMotionSteps(), AI_TYPE_MATRIX); AiArraySetMtx(matrices, step, matrix); AiNodeSetArray(atNode, "matrix", matrices); } else { AtArray* matrices = AiNodeGetArray(atNode, "matrix"); AiArraySetMtx(matrices, step, matrix); } } else { AiNodeSetMatrix(atNode, "matrix", matrix); } } } // Set bounding box if (attrsSet.find("min") == attrsEnd && attrsSet.find("max") == attrsEnd) { // Now check if min and max parameters are valid parameter names on arnold node if (HasParameter(anodeEntry, "min") != 0 && HasParameter(anodeEntry, "max") != 0) { if (step == 0) { MBoundingBox bbox = node.boundingBox(); MPoint bmin = bbox.min(); MPoint bmax = bbox.max(); AiNodeSetPnt(atNode, "min", static_cast<float>(bmin.x), static_cast<float>(bmin.y), static_cast<float>(bmin.z)); AiNodeSetPnt(atNode, "max", static_cast<float>(bmax.x), static_cast<float>(bmax.y), static_cast<float>(bmax.z)); } else { if (transformBlur || deformBlur) { AtPoint cmin = AiNodeGetPnt(atNode, "min"); AtPoint cmax = AiNodeGetPnt(atNode, "max"); MBoundingBox bbox = node.boundingBox(); MPoint bmin = bbox.min(); MPoint bmax = bbox.max(); if (bmin.x < cmin.x) cmin.x = static_cast<float>(bmin.x); if (bmin.y < cmin.y) cmin.y = static_cast<float>(bmin.y); if (bmin.z < cmin.z) cmin.z = static_cast<float>(bmin.z); if (bmax.x > cmax.x) cmax.x = static_cast<float>(bmax.x); if (bmax.y > cmax.y) cmax.y = static_cast<float>(bmax.y); if (bmax.z > cmax.z) cmax.z = static_cast<float>(bmax.z); AiNodeSetPnt(atNode, "min", cmin.x, cmin.y, cmin.z); AiNodeSetPnt(atNode, "max", cmax.x, cmax.y, cmax.z); } } } } if (step == 0) { // Set common attributes MPlug plug; if (AiNodeIs(atNode, "procedural")) { // Note: it is up to the procedural to properly forward (or not) those parameters to the node // it creates if (attrsSet.find("subdiv_type") == attrsEnd) { plug = FindMayaPlug("subdiv_type"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivType"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_type", atNode, "constant INT")) { AiNodeSetInt(atNode, "subdiv_type", plug.asInt()); } } if (attrsSet.find("subdiv_iterations") == attrsEnd) { plug = FindMayaPlug("subdiv_iterations"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivIterations"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_iterations", atNode, "constant BYTE")) { AiNodeSetByte(atNode, "subdiv_iterations", plug.asInt()); } } if (attrsSet.find("subdiv_adaptive_metric") == attrsEnd) { plug = FindMayaPlug("subdiv_adaptive_metric"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivAdaptiveMetric"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_adaptive_metric", atNode, "constant INT")) { AiNodeSetInt(atNode, "subdiv_adaptive_metric", plug.asInt()); } } if (attrsSet.find("subdiv_pixel_error") == attrsEnd) { plug = FindMayaPlug("subdiv_pixel_error"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivPixelError"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_pixel_error", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "subdiv_pixel_error", plug.asFloat()); } } if (attrsSet.find("subdiv_dicing_camera") == attrsEnd) { plug = FindMayaPlug("subdiv_dicing_camera"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivDicingCamera"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_dicing_camera", atNode, "constant NODE")) { AtNode *cameraNode = NULL; MPlugArray plugs; plug.connectedTo(plugs, true, false); if (plugs.length() == 1) { MFnDagNode camDag(plugs[0].node()); MDagPath camPath; if (camDag.getPath(camPath) == MS::kSuccess) { cameraNode = ExportDagPath(camPath); } } AiNodeSetPtr(atNode, "subdiv_dicing_camera", cameraNode); } } if (attrsSet.find("subdiv_uv_smoothing") == attrsEnd) { plug = FindMayaPlug("subdiv_uv_smoothing"); if (plug.isNull()) { plug = FindMayaPlug("aiSubdivUvSmoothing"); } if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_uv_smoothing", atNode, "constant INT")) { AiNodeSetInt(atNode, "subdiv_uv_smoothing", plug.asInt()); } } if (attrsSet.find("subdiv_smooth_derivs") == attrsEnd) { plug = FindMayaPlug("aiSubdivSmoothDerivs"); if (!plug.isNull() && HasParameter(anodeEntry, "subdiv_smooth_derivs", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "subdiv_smooth_derivs", plug.asBool()); } } if (attrsSet.find("smoothing") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("smoothShading"); if (!plug.isNull() && HasParameter(anodeEntry, "smoothing", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "smoothing", plug.asBool()); } } if (attrsSet.find("disp_height") == attrsEnd) { plug = FindMayaPlug("aiDispHeight"); if (!plug.isNull()) { outputDispHeight = true; dispHeight = plug.asFloat(); } } if (attrsSet.find("disp_zero_value") == attrsEnd) { plug = FindMayaPlug("aiDispZeroValue"); if (!plug.isNull()) { outputDispZeroValue = true; dispZeroValue = plug.asFloat(); } } if (attrsSet.find("disp_autobump") == attrsEnd) { plug = FindMayaPlug("aiDispAutobump"); if (!plug.isNull()) { outputDispAutobump = true; dispAutobump = plug.asBool(); } } if (attrsSet.find("disp_padding") == attrsEnd) { plug = FindMayaPlug("aiDispPadding"); if (!plug.isNull()) { outputDispPadding = true; dispPadding = MAX(dispPadding, plug.asFloat()); } } // Set diplacement shader if (attrsSet.find("disp_map") == attrsEnd) { if (masterShadingEngine.object() != MObject::kNullObj) { MPlugArray shaderConns; MPlug shaderPlug = masterShadingEngine.findPlug("displacementShader"); shaderPlug.connectedTo(shaderConns, true, false); if (shaderConns.length() > 0) { MFnDependencyNode dispNode(shaderConns[0].node()); plug = dispNode.findPlug("aiDisplacementPadding"); if (!plug.isNull()) { outputDispPadding = true; dispPadding = MAX(dispPadding, plug.asFloat()); } plug = dispNode.findPlug("aiDisplacementAutoBump"); if (!plug.isNull()) { outputDispAutobump = true; dispAutobump = dispAutobump || plug.asBool(); } if (HasParameter(anodeEntry, "disp_map", atNode, "constant ARRAY NODE")) { AtNode *dispImage = ExportNode(shaderConns[0]); AiNodeSetArray(atNode, "disp_map", AiArrayConvert(1, 1, AI_TYPE_NODE, &dispImage)); } } } } if (outputDispHeight && HasParameter(anodeEntry, "disp_height", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "disp_height", dispHeight); } if (outputDispZeroValue && HasParameter(anodeEntry, "disp_zero_value", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "disp_zero_value", dispZeroValue); } if (outputDispPadding && HasParameter(anodeEntry, "disp_padding", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "disp_padding", dispPadding); } if (outputDispAutobump && HasParameter(anodeEntry, "disp_autobump", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "disp_autobump", dispAutobump); } // Old point based SSS parameter if (attrsSet.find("sss_sample_distribution") == attrsEnd) { plug = FindMayaPlug("sss_sample_distribution"); if (plug.isNull()) { plug = FindMayaPlug("aiSssSampleDistribution"); } if (!plug.isNull() && HasParameter(anodeEntry, "sss_sample_distribution", atNode, "constant INT")) { AiNodeSetInt(atNode, "sss_sample_distribution", plug.asInt()); } } // Old point based SSS parameter if (attrsSet.find("sss_sample_spacing") == attrsEnd) { plug = FindMayaPlug("sss_sample_spacing"); if (plug.isNull()) { plug = FindMayaPlug("aiSssSampleSpacing"); } if (!plug.isNull() && HasParameter(anodeEntry, "sss_sample_spacing", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "sss_sample_spacing", plug.asFloat()); } } if (attrsSet.find("min_pixel_width") == attrsEnd) { plug = FindMayaPlug("aiMinPixelWidth"); if (!plug.isNull() && HasParameter(anodeEntry, "min_pixel_width", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "min_pixel_width", plug.asFloat()); } } if (attrsSet.find("mode") == attrsEnd) { plug = FindMayaPlug("aiMode"); if (!plug.isNull() && HasParameter(anodeEntry, "mode", atNode, "constant INT")) { AiNodeSetInt(atNode, "mode", plug.asShort()); } } if (attrsSet.find("basis") == attrsEnd) { plug = FindMayaPlug("aiBasis"); if (!plug.isNull() && HasParameter(anodeEntry, "basis", atNode, "constant INT")) { AiNodeSetInt(atNode, "basis", plug.asShort()); } } } if (AiNodeIs(atNode, "ginstance")) { if (attrsSet.find("node") == attrsEnd) { AiNodeSetPtr(atNode, "node", m_masterNode); } if (attrsSet.find("inherit_xform") == attrsEnd) { AiNodeSetBool(atNode, "inherit_xform", false); } } else { // box or procedural if (attrsSet.find("step_size") == attrsEnd) { plug = FindMayaPlug("step_size"); if (plug.isNull()) { plug = FindMayaPlug("aiStepSize"); } if (!plug.isNull() && HasParameter(anodeEntry, "step_size", atNode, "constant FLOAT")) { AiNodeSetFlt(atNode, "step_size", plug.asFloat()); } } } if (attrsSet.find("sidedness") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("doubleSided"); if (!plug.isNull() && HasParameter(anodeEntry, "sidedness", atNode, "constant BYTE")) { AiNodeSetByte(atNode, "sidedness", plug.asBool() ? AI_RAY_ALL : 0); // Only set invert_normals if doubleSided attribute could be found if (!plug.asBool() && attrsSet.find("invert_normals") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("opposite"); if (!plug.isNull() && HasParameter(anodeEntry, "invert_normals", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "invert_normals", plug.asBool()); } } } } if (attrsSet.find("receive_shadows") == attrsEnd) { // Use maya shape built-in attribute plug = FindMayaPlug("receiveShadows"); if (!plug.isNull() && HasParameter(anodeEntry, "receive_shadows", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "receive_shadows", plug.asBool()); } } if (attrsSet.find("self_shadows") == attrsEnd) { plug = FindMayaPlug("self_shadows"); if (plug.isNull()) { plug = FindMayaPlug("aiSelfShadows"); } if (!plug.isNull() && HasParameter(anodeEntry, "self_shadows", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "self_shadows", plug.asBool()); } } if (attrsSet.find("opaque") == attrsEnd) { plug = FindMayaPlug("opaque"); if (plug.isNull()) { plug = FindMayaPlug("aiOpaque"); } if (!plug.isNull() && HasParameter(anodeEntry, "opaque", atNode, "constant BOOL")) { AiNodeSetBool(atNode, "opaque", plug.asBool()); } } if (attrsSet.find("visibility") == attrsEnd) { if (HasParameter(anodeEntry, "visibility", atNode, "constant BYTE")) { int visibility = AI_RAY_ALL; // Use maya shape built-in attribute plug = FindMayaPlug("castsShadows"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_SHADOW; } // Use maya shape built-in attribute plug = FindMayaPlug("primaryVisibility"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_CAMERA; } // Use maya shape built-in attribute plug = FindMayaPlug("visibleInReflections"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_REFLECTED; } // Use maya shape built-in attribute plug = FindMayaPlug("visibleInRefractions"); if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_REFRACTED; } plug = FindMayaPlug("diffuse_visibility"); if (plug.isNull()) { plug = FindMayaPlug("aiVisibleInDiffuse"); } if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_DIFFUSE; } plug = FindMayaPlug("glossy_visibility"); if (plug.isNull()) { plug = FindMayaPlug("aiVisibleInGlossy"); } if (!plug.isNull() && !plug.asBool()) { visibility &= ~AI_RAY_GLOSSY; } AiNodeSetByte(atNode, "visibility", visibility & 0xFF); } } if (attrsSet.find("sss_setname") == attrsEnd) { plug = FindMayaPlug("aiSssSetname"); if (!plug.isNull() && plug.asString().length() > 0) { if (HasParameter(anodeEntry, "sss_setname", atNode, "constant STRING")) { AiNodeSetStr(atNode, "sss_setname", plug.asString().asChar()); } } } // Set surface shader if (HasParameter(anodeEntry, "shader", atNode, "constant NODE")) { if (attrsSet.find("shader") == attrsEnd) { if (shadingEngine.object() != MObject::kNullObj) { AtNode *shader = ExportNode(shadingEngine.findPlug("message")); if (shader != NULL) { const AtNodeEntry *entry = AiNodeGetNodeEntry(shader); if (AiNodeEntryGetType(entry) != AI_NODE_SHADER) { MGlobal::displayWarning("[mtoaScriptedTranslators] Node generated from \"" + shadingEngine.name() + "\" of type " + shadingEngine.typeName() + " for shader is not a shader but a " + MString(AiNodeEntryGetTypeName(entry))); } else { AiNodeSetPtr(atNode, "shader", shader); if (AiNodeLookUpUserParameter(atNode, "mtoa_shading_groups") == 0) { AiNodeDeclare(atNode, "mtoa_shading_groups", "constant ARRAY NODE"); AiNodeSetArray(atNode, "mtoa_shading_groups", AiArrayConvert(1, 1, AI_TYPE_NODE, &shader)); } } } } } } } ExportLightLinking(atNode); MPlug plug = FindMayaPlug("aiTraceSets"); if (!plug.isNull()) { ExportTraceSets(atNode, plug); } // Call cleanup command on last export step if (!IsMotionBlurEnabled() || !IsLocalMotionBlurEnabled() || int(step) >= (int(GetNumMotionSteps()) - 1)) { if (HasParameter(anodeEntry, "disp_padding", atNode)) { float padding = AiNodeGetFlt(atNode, "disp_padding"); AtPoint cmin = AiNodeGetPnt(atNode, "min"); AtPoint cmax = AiNodeGetPnt(atNode, "max"); cmin.x -= padding; cmin.y -= padding; cmin.z -= padding; cmax.x += padding; cmax.y += padding; cmax.z += padding; AiNodeSetPnt(atNode, "min", cmin.x, cmin.y, cmin.z); AiNodeSetPnt(atNode, "max", cmax.x, cmax.y, cmax.z); } if (cleanupCmd != "") { command = cleanupCmd += "((\"" + m_dagPath.partialPathName() + "\", \""; command += AiNodeGetName(atNode); command += "\"), "; if (!m_masterNode) { command += "None)"; } else { command += "(\"" + GetMasterInstance().partialPathName() + "\", \""; command += AiNodeGetName(m_masterNode); command += "\"))"; } status = MGlobal::executePythonCommand(command); if (!status) { AiMsgError("[mtoa.scriptedTranslators] Failed to cleanup node \"%s\".", node.name().asChar()); } } } }
bool tm_polyExtract::extractFaces_Func( MSelectionList &selectionList, MStringArray &node_names) { MStatus status; MObject meshObj; status = selectionList.getDependNode( 0, meshObj); if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func: Can't find object !");return false;} MFnMesh meshFn( meshObj, &status); if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func: Non mesh object founded !");return false;} MDagPath meshDagPath_first, meshDagPath; selectionList.getDagPath( 0, meshDagPath_first); MObject multiFaceComponent; MIntArray inputFacesArray; inputFacesArray.clear(); inputFacesArray.setSizeIncrement( 4096); MFnComponentListData compListFn; compListFn.create(); for (MItSelectionList faceComponentIter(selectionList, MFn::kMeshPolygonComponent); !faceComponentIter.isDone(); faceComponentIter.next()) { faceComponentIter.getDagPath(meshDagPath, multiFaceComponent); if(!(meshDagPath_first == meshDagPath)) { MGlobal::displayError("tm_polyExtract::extractFaces_Func: Different meshes faces founded !"); return false; } if (!multiFaceComponent.isNull()) { for (MItMeshPolygon faceIter(meshDagPath, multiFaceComponent); !faceIter.isDone(); faceIter.next()) { int faceIndex = faceIter.index(); #ifdef _DEBUG infoMStr += faceIndex; infoMStr += " "; #endif inputFacesArray.append( faceIndex); compListFn.add( multiFaceComponent ); } } } if( inputFacesArray.length() == 0) { MGlobal::displayError("tm_polyExtract::extractFaces_Func: No faces founded !"); return false; } #ifdef _DEBUG MGlobal::displayInfo( infoMStr); #endif meshFn.setObject( meshDagPath_first); meshObj = meshFn.object(); // MDagModifier dagModifier; MFnDagNode meshDagNodeFn; MFnDependencyNode depNodeFn; meshDagNodeFn.setObject( meshDagPath_first); MString meshName = meshDagNodeFn.name(); MObject outMesh_attrObject = meshDagNodeFn.attribute( "outMesh"); // ----------------------------------- duplicate shape MObject duplicated_meshObjectA; MObject duplicated_meshObjectB; MObject inMesh_attrObjectA; MObject inMesh_attrObjectB; /* MStringArray commandResult; MSelectionList selList; MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1); selList.add( commandResult[0]); selList.getDependNode( 0, duplicated_meshObjectA); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_tA"); duplicated_meshObjectA = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_sA"); inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh"); meshDagNodeFn.setObject( meshDagPath_first); selList.clear(); MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1); selList.add( commandResult[0]); selList.getDependNode( 0, duplicated_meshObjectB); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_tB"); duplicated_meshObjectB = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_sB"); inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh"); */ duplicated_meshObjectA = meshDagNodeFn.duplicate(); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_tA"); duplicated_meshObjectA = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_sA"); inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh"); meshDagNodeFn.setObject( meshDagPath_first); duplicated_meshObjectB = meshDagNodeFn.duplicate(); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_tB"); duplicated_meshObjectB = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_sB"); inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh"); // ----------------------------------- create node deleteComponent MDGModifier dgModifier; MObject deleteComponent_nodeObjectA = dgModifier.createNode( MString("deleteComponent")); depNodeFn.setObject( deleteComponent_nodeObjectA ); MObject deleteComponent_attrObjectA( depNodeFn.attribute( "deleteComponents" )); MObject inputGeometry_attrObjectA( depNodeFn.attribute( "inputGeometry" )); MObject outputGeometry_attrObjectA( depNodeFn.attribute( "outputGeometry" )); dgModifier.doIt(); depNodeFn.setName( "dfA_" + meshName); node_names.append( depNodeFn.name()); MObject deleteComponent_nodeObjectB = dgModifier.createNode( MString("deleteComponent")); depNodeFn.setObject( deleteComponent_nodeObjectB ); MObject deleteComponent_attrObjectB( depNodeFn.attribute( "deleteComponents" )); MObject inputGeometry_attrObjectB( depNodeFn.attribute( "inputGeometry" )); MObject outputGeometry_attrObjectB( depNodeFn.attribute( "outputGeometry" )); dgModifier.doIt(); depNodeFn.setName( "dfB_" + meshName); node_names.append( depNodeFn.name()); // ----------------------------------- set attribute deleteComponent.deleteComponents MObject componentList_object = compListFn.object(); MPlug deleteComponents_plugA( deleteComponent_nodeObjectA, deleteComponent_attrObjectA ); status = deleteComponents_plugA.setValue( componentList_object ); MIntArray invertedFaces; int numPolygons = meshFn.numPolygons(); invertedFaces.setLength( numPolygons - inputFacesArray.length()); int selFace = 0; int invFace = 0; for( int f = 0; f < numPolygons; f++) { if( f == inputFacesArray[selFace]) selFace++; else invertedFaces[invFace++] = f; } MFnSingleIndexedComponent singleIndexedComponentFn( meshObj); singleIndexedComponentFn.create( MFn::kMeshPolygonComponent); singleIndexedComponentFn.addElements( invertedFaces); compListFn.clear(); compListFn.create(); componentList_object = singleIndexedComponentFn.object(); compListFn.add( componentList_object); componentList_object = compListFn.object(); MPlug deleteComponents_plugB( deleteComponent_nodeObjectB, deleteComponent_attrObjectB ); status = deleteComponents_plugB.setValue( componentList_object ); // ------------------------------------- connecting plugs /**/ dgModifier.connect( meshObj, outMesh_attrObject, deleteComponent_nodeObjectA, inputGeometry_attrObjectA ); dgModifier.connect( deleteComponent_nodeObjectA, outputGeometry_attrObjectA, duplicated_meshObjectA, inMesh_attrObjectA ); dgModifier.connect( meshObj, outMesh_attrObject, deleteComponent_nodeObjectB, inputGeometry_attrObjectB ); dgModifier.connect( deleteComponent_nodeObjectB, outputGeometry_attrObjectB, duplicated_meshObjectB, inMesh_attrObjectB ); dgModifier.doIt(); // ---------------------------------- assigning shading group /**/ meshDagNodeFn.setObject( meshDagPath_first); MObject instObjGroups_attrObject = meshDagNodeFn.attribute( "instObjGroups"); MPlug instObjGroups_plug( meshObj, instObjGroups_attrObject); instObjGroups_plug = instObjGroups_plug.elementByPhysicalIndex(0); MPlugArray instObjGroups_plug_connectionsArray; instObjGroups_plug.connectedTo( instObjGroups_plug_connectionsArray, false, true); if( instObjGroups_plug_connectionsArray.length() > 0) { MPlug dagSetMembers_plug = instObjGroups_plug_connectionsArray[0]; MObject shadingSetNode_object = dagSetMembers_plug.node(); MFnSet setFn( shadingSetNode_object); setFn.addMember( duplicated_meshObjectA); setFn.addMember( duplicated_meshObjectB); //depNodeFn.setObject(shadingSetNode_object); //MGlobal::displayInfo( depNodeFn.name()); } // ------------------------------------------------------------ return true; }
// ------------------------------------------------------------ bool SceneGraph::retrieveExportNodes() { // Create a selection list containing only the root nodes (implies export all!) MSelectionList allTargets; for ( MItDag it ( MItDag::kBreadthFirst ); it.depth()<=1 && it.item()!=MObject::kNullObj; it.next() ) { MDagPath path; MStatus status = it.getPath ( path ); String pathName = path.fullPathName().asChar(); // Attach a function set MFnDependencyNode fn ( path.node() ); String theNodeName = fn.name().asChar(); // Check if it's the world node if ( it.depth() == 0 ) continue; if ( status == MStatus::kSuccess ) { if ( mExportSelectedOnly ) allTargets.add ( path ); else mTargets.add ( path ); } } // now fill in the targets, either the same as allTargets, or it is export selection only if ( mExportSelectedOnly ) { // Export the selection: // Grab the selected DAG components if ( MStatus::kFailure == MGlobal::getActiveSelectionList ( mTargets ) ) { std::cerr << "MGlobal::getActiveSelectionList" << std::endl; return false; } // For all the non-transforms selected, make sure to extend to the transforms underneath. MDagPathArray additions; MIntArray removals; for ( uint32 i = 0; i < mTargets.length(); ++i ) { MDagPath itemPath; mTargets.getDagPath ( i, itemPath ); if ( !itemPath.node().hasFn ( MFn::kTransform ) ) { MDagPath transformPath = itemPath; while ( transformPath.length() > 0 ) { transformPath.pop(); if ( !mTargets.hasItem ( transformPath ) ) { additions.append ( transformPath ); break; } } removals.append ( i ); } } for ( uint32 i = 0; i < removals.length(); ++i ) mTargets.remove ( removals[i] - i ); for ( uint32 i = 0; i < additions.length(); ++i ) mTargets.add ( additions[i] ); // Add all the forced nodes to the list. uint32 forceNodeCount = mForcedNodes.length(); for ( uint32 i = 0; i < forceNodeCount; ++i ) { MDagPath p = mForcedNodes[i]; if ( mTargets.hasItem ( p ) ) continue; mTargets.add ( p ); } // Add additional selection paths for any objects in our // selection which have been instanced (either directly, or // via instancing of an ancestor) - as otherwise, the selection // will only include ONE of the DAG paths // addInstancedDagPaths ( mTargets ); // remove any selected nodes CONTAINED within other selected // hierarchies (to ensure we don't export subtrees multiple times) // removeMultiplyIncludedDagPaths ( mTargets ); } return true; }
MStatus Maya::SetNodeID( const MObject& node, const Helium::TUID& id ) { MStatus status; MFnDependencyNode nodeFn (node); // make sure we have the dynamic attribute to store our id created MObject attr = nodeFn.attribute(MString (s_TUIDAttributeName), &status); if (status == MS::kFailure) { // check to see if we are a locked node bool nodeWasLocked = nodeFn.isLocked(); if ( nodeWasLocked ) { // turn off any node locking so an attribute can be added nodeFn.setLocked( false ); } // create the attribute MFnTypedAttribute attrFn; attr = attrFn.create(MString (s_TUIDAttributeName), MString (s_TUIDAttributeName), MFnData::kString); status = nodeFn.addAttribute(attr); // reset to the prior state of wasLocked if ( nodeWasLocked ) { nodeFn.setLocked( nodeWasLocked ); } // error check if (status == MS::kFailure) { MGlobal::displayError(MString ("Unable to create TUID attribute on maya node: ") + nodeFn.name()); return status; } } MPlug plug (node, nodeFn.attribute(MString (s_TUIDAttributeName))); plug.setLocked(false); tstring s; id.ToString(s); plug.setValue(MString(s.c_str())); plug.setLocked(true); return status; }
// Description: // implements redo for the MEL cgfxShader command. // // This method is called when the user has undone a command of this type // and then redoes it. No arguments are passed in as all of the necessary // information is cached by the doIt method. // // Return Value: // MS::kSuccess - command succeeded // MS::kFailure - redoIt failed. this is a serious problem that will // likely cause the undo queue to be purged MStatus cgfxShaderCmd::redoCmd( MObject& oNode, MFnDependencyNode& fnNode, cgfxShaderNode* pNode ) { MStatus status; if (!fOldAttrDefList.empty()) { // Release the textures from the innactive attribute list to // save memory. NodeAttrDefList::iterator it = fOldAttrDefList.begin(); NodeAttrDefList::iterator itEnd = fOldAttrDefList.end(); for(; it != itEnd; ++it) { cgfxRCPtr<cgfxAttrDefList> &attrDefList = it->second; if(!attrDefList.isNull()) attrDefList->releaseTextures(); } } if (fFxFile) { // cgfxAttrDef list may contain MObject references to dynamic attrs // that are about to disappear. Clean up those references before // they become invalid, so they don't cause an exception later. pNode->setAttrDefList( cgfxRCPtr<cgfxAttrDefList>() ); cgfxRCPtr<cgfxAttrDefList> currNodeAttrDefList; // Actually update the node. status = fDagMod->doIt(); M_CHECK( status ); cgfxShaderNode::NodeList nodes; // getNodesToUpdate will return the list of nodes that will need to be updated : // if the new fx file is the same as the old fx file, the action is considered a reload, // we'll gather all the nodes that are using the old effect and reload them all. // else the effect file is different and only the current node will be updated. getNodesToUpdate(fOldEffect, pNode, nodes); cgfxShaderNode::NodeList::const_iterator it = nodes.begin(); cgfxShaderNode::NodeList::const_iterator itEnd = nodes.end(); for(; it != itEnd; ++it) { cgfxShaderNode* node = *it; MStringArray &attributeList = fNewAttributeList[node]; cgfxRCPtr<cgfxAttrDefList> &attrDefList = fNewAttrDefList[node]; if(node == pNode) currNodeAttrDefList = attrDefList; node->setAttributeList(attributeList); node->setAttrDefList(attrDefList); // Notice: Must setShaderFxFileChanged before setEffect node->setShaderFxFileChanged(true); node->setEffect(fNewEffect); } cgfxAttrDef::initializeAttributes( oNode, currNodeAttrDefList, false, fDagMod); fnNode.findPlug( cgfxShaderNode::sShader ).setValue( fNewFxFile ); } else { // Actually update the node. status = fDagMod->doIt(); M_CHECK( status ); } if (fTechnique) { fnNode.findPlug( cgfxShaderNode::sTechnique ).setValue( fNewTechnique ); } if (fProfile) { fnNode.findPlug( cgfxShaderNode::sProfile ).setValue( fNewProfile ); } if ( !fIsEdit ) { // Save the actual node name (in case user did not specify a // name, or in case Maya altered the name to make it unique.) fNodeName = fnNode.name(); // Finally, if we created a new node, select it. I don't do // status checking here because I don't want the command to fail // merely because the selection might fail. In other words, I'm // not checking because I don't care. // MSelectionList selList; selList.add(oNode); MGlobal::setActiveSelectionList(selList); } return MS::kSuccess; } // cgfxShaderCmd::redoCmd
MStatus simulateBoids::doIt( const MArgList& args ) { // Description: implements the MEL boids command // Arguments: args - the argument list that was passes to the command from MEL MStatus status = MS::kSuccess; /**************************************** * building thread/dll data structure * ****************************************/ InfoCache infoCache; SimulationParameters simParams; RulesParameters *applyingRules; double progressBar=0; double aov=pi/3; int i,numberOfDesires=0; // params retrievement MSelectionList sel; MObject node; MFnDependencyNode nodeFn; MFnTransform locatorFn; MPlug plug; // simulation params int simulationLengthValue; // [int] in seconds int framesPerSecondValue; // [int] int startFrameValue; // [int] int boidsNumberValue; // [int] // export params MString logFilePathValue; // [char *] MString logFileNameValue; // [char *] int logFileTypeValue; // 0 = nCache; 1 = log file; 2 = XML; // locomotion params int locomotionModeValue; // [int] double maxSpeedValue; // [double] double maxForceValue; // [double] // double mass=1; // [double] MTime currentTime, maxTime; MPlug plugX, plugY, plugZ; double tx, ty, tz; int frameLength ; Vector * leader = NULL; MStatus leaderFound=MStatus::kFailure; MGlobal::getActiveSelectionList(sel); for ( MItSelectionList listIter(sel); !listIter.isDone(); listIter.next() ) { listIter.getDependNode(node); switch(node.apiType()) { case MFn::kTransform: // get locator transform to follow leaderFound=locatorFn.setObject(node); cout << locatorFn.name().asChar() << " is selected as locator" << endl; break; case MFn::kPluginDependNode: nodeFn.setObject(node); cout << nodeFn.name().asChar() << " is selected as brain" << endl; break; default: break; } cout<< node.apiTypeStr()<<endl; } // rules params setRuleVariables(alignment); setRuleVariables(cohesion); setRuleVariables(separation); setRuleVariables(follow); getPlugValue(simulationLength); getPlugValue(framesPerSecond); getPlugValue(startFrame); getPlugValue(boidsNumber); getPlugValue(logFileType); getRulePlugValue(alignment); getRulePlugValue(cohesion); getRulePlugValue(separation); getRulePlugValue(follow); getPlugValue(locomotionMode); getPlugValue(maxSpeed); getPlugValue(maxForce); getTypePlugValue(logFilePath); getTypePlugValue(logFileName); // counting active rules number if(alignmentActiveValue) numberOfDesires++; if(cohesionActiveValue) numberOfDesires++; if(separationActiveValue) numberOfDesires++; if(followActiveValue) numberOfDesires++; currentTime = MTime((double)startFrameValue); // MAnimControl::minTime(); maxTime = MTime((double)(startFrameValue + (simulationLengthValue * framesPerSecondValue))); // MAnimControl::maxTime(); cout << "time unit enum (6 is 24 fps): " << currentTime.unit() << endl; plugX = locatorFn.findPlug( MString( "translateX" ), &status ); plugY = locatorFn.findPlug( MString( "translateY" ), &status ); plugZ = locatorFn.findPlug( MString( "translateZ" ), &status ); frameLength = simulationLengthValue * framesPerSecondValue; if(leaderFound==MS::kSuccess) { leader = new Vector[frameLength]; while ( currentTime < maxTime ) { { int index = (int)currentTime.value() - startFrameValue; /* MGlobal::viewFrame(currentTime); pos = locatorFn.getTranslation(MSpace::kWorld); cout << "pos: " << pos.x << " " << pos.y << " " << pos.z << endl; */ status = plugX.getValue( tx, MDGContext(currentTime) ); status = plugY.getValue( ty, MDGContext(currentTime) ); status = plugZ.getValue( tz, MDGContext(currentTime) ); leader[index].x = tx; leader[index].y = ty; leader[index].z = tz; //cout << "pos at time " << currentTime.value() << " has x: " << tx << " y: " << ty << " z: " << tz << endl; currentTime++; } } } simParams.fps=framesPerSecondValue; simParams.lenght=simulationLengthValue; simParams.numberOfBoids=boidsNumberValue; simParams.maxAcceleration=maxForceValue; simParams.maxVelocity=maxSpeedValue; simParams.simplifiedLocomotion=TRUE; applyingRules=new RulesParameters[numberOfDesires]; // cache settings MString saveString; saveString = logFilePathValue+"/"+logFileNameValue; infoCache.fileName=new char[saveString.length()+1]; memcpy(infoCache.fileName,saveString.asChar(),sizeof(char)*(saveString.length()+1)); infoCache.cacheFormat=ONEFILE; infoCache.fps=framesPerSecondValue; infoCache.start=startFrameValue/framesPerSecondValue; infoCache.end=simulationLengthValue+infoCache.start; infoCache.loging=FALSE; infoCache.option=POSITIONVELOCITY; infoCache.particleSysName="BoidsNParticles"; infoCache.saveMethod=MAYANCACHE; for(i=0;i<numberOfDesires;i++) { applyingRules[i].enabled=TRUE; applyingRules[i].precedence=1; applyingRules[i].aov=aov; applyingRules[i].visibilityOption=FALSE; } if(cohesionActiveValue==0) applyingRules[COHESIONRULE].enabled=FALSE; else { applyingRules[COHESIONRULE].ruleName=COHESIONRULE; applyingRules[COHESIONRULE].ruleFactor=cohesionFactorValue; applyingRules[COHESIONRULE].ruleRadius=cohesionRadiusValue; applyingRules[COHESIONRULE].ruleWeight=cohesionWeightValue; } if(separationActiveValue==0) applyingRules[SEPARATIONRULE].enabled=FALSE; else { applyingRules[SEPARATIONRULE].ruleName=SEPARATIONRULE; applyingRules[SEPARATIONRULE].ruleFactor=separationFactorValue; applyingRules[SEPARATIONRULE].ruleRadius=separationRadiusValue; applyingRules[SEPARATIONRULE].ruleWeight=separationWeightValue; } if(alignmentActiveValue==0) applyingRules[ALIGNMENTRULE].enabled=FALSE; else { applyingRules[ALIGNMENTRULE].ruleName=ALIGNMENTRULE; applyingRules[ALIGNMENTRULE].ruleFactor=alignmentFactorValue; applyingRules[ALIGNMENTRULE].ruleRadius=alignmentRadiusValue; applyingRules[ALIGNMENTRULE].ruleWeight=alignmentWeightValue; } if(followActiveValue==0) applyingRules[FOLLOWRULE].enabled=FALSE; else { applyingRules[FOLLOWRULE].ruleName=FOLLOWRULE; applyingRules[FOLLOWRULE].ruleRadius=followRadiusValue; applyingRules[FOLLOWRULE].ruleFactor=followFactorValue; applyingRules[FOLLOWRULE].ruleWeight=followWeightValue; } // initializing simulation parameters boidInit(numberOfDesires, applyingRules, simParams , infoCache, leader); DLLData datadll; // preparing threads pool status = MThreadPool::init(); if (status==MStatus::kSuccess) { MThreadPool::newParallelRegion(ThreadsCreator, &datadll); setResult( "Command executed!\n" ); CHECK_MSTATUS(MProgressWindow::endProgress()); MThreadPool::release(); } switch(datadll.result) { case 0: status=MS::kSuccess; break; default: status=MS::kFailure; } MThreadPool::release(); return status; }
bool atomExport::setUpAnimLayers(MSelectionList &sList,atomAnimLayers &animLayers, std::vector<atomNodeWithAnimLayers *> &nodesWithAnimLayers, std::set<std::string> &attrStrings, atomTemplateReader &templateReader) { unsigned int numObjects = sList.length(); nodesWithAnimLayers.resize(numObjects); bool somethingIsAnimLayered = false; for (unsigned int i = 0; i < numObjects; i++) { atomNodeWithAnimLayers *nodeWithLayer = NULL; //make sure it's a NULL, and preset it in case we skip this node nodesWithAnimLayers[i] = nodeWithLayer; MDagPath path; MObject node; if (sList.getDagPath (i, path) == MS::kSuccess) { MString name = path.partialPathName(); //if the name is in the template, only then write it out... if(templateReader.findNode(name)== false) { continue; } node = path.node(); } else if (sList.getDependNode (i, node) == MS::kSuccess) { if (!node.hasFn (MFn::kDependencyNode)) { continue; } MFnDependencyNode fnNode (node); MString name = fnNode.name(); if(templateReader.findNode(name)== false) { continue; } } if(node.isNull()==false) { MSelectionList localList; localList.add(node); MPlugArray animatablePlugs; MAnimUtil::findAnimatablePlugs(localList,animatablePlugs); unsigned int numPlugs = animatablePlugs.length(); MPlugArray cachedPlugs; for (unsigned int k = 0; k < numPlugs; k++) { MPlug plug = animatablePlugs[k]; MObjectArray layers; MPlugArray plugs; if(MAnimUtil::findAnimationLayers(plug,layers,plugs) && layers.length() > 0) { bool layerAdded = animLayers.addAnimLayers(layers); if(layerAdded) { if(nodeWithLayer == NULL) nodeWithLayer = new atomNodeWithAnimLayers(); nodeWithLayer->addPlugWithLayer(plug,layers,plugs); } somethingIsAnimLayered = somethingIsAnimLayered == false ? layerAdded : true; } } nodesWithAnimLayers[i] = nodeWithLayer; } } return somethingIsAnimLayered; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::undoCachedMesh() // -------------------------------------------------------------------------------------------- { MStatus status; // Only need to restore the cached mesh if there was no history. Also // check to make sure that we are in the record history state. // MStatusAssert( (fHasRecordHistory), "fHasRecordHistory == true" ); if( !fHasHistory ) { MFnDependencyNode depNodeFn; MString meshNodeName; MObject meshNodeShape; MPlug meshNodeDestPlug; MPlug meshNodeOutMeshPlug; MObject dupMeshNodeShape; MPlug dupMeshNodeSrcPlug; meshNodeShape = fDagPath.node(); dupMeshNodeShape = fDuplicateDagPath.node(); depNodeFn.setObject( meshNodeShape ); meshNodeName = depNodeFn.name(); meshNodeDestPlug = depNodeFn.findPlug( "inMesh", &status ); MCheckStatus( status, "Could not retrieve inMesh" ); meshNodeOutMeshPlug = depNodeFn.findPlug( "outMesh", &status ); MCheckStatus( status, "Could not retrieve outMesh" ); depNodeFn.setObject( dupMeshNodeShape ); dupMeshNodeSrcPlug = depNodeFn.findPlug( "outMesh", &status ); MCheckStatus( status, "Could not retrieve outMesh" ); // For the case with tweaks, we cannot write the mesh directly back onto // the cachedInMesh, since the shape can have out of date information from the // cachedInMesh, thus we temporarily connect the duplicate mesh shape to the // mesh shape and force a DG evaluation. // // For the case without tweaks, we can simply write onto the outMesh, since // the shape relies solely on an outMesh when there is no history nor tweaks. // if( fHasTweaks ) { MDGModifier dgModifier; dgModifier.connect( dupMeshNodeSrcPlug, meshNodeDestPlug ); status = dgModifier.doIt(); MCheckStatus( status, "Could not connect dupMeshNode -> meshNode" ); // Need to force a DG evaluation now that the input has been changed. // MString cmd( "dgeval -src " ); cmd += meshNodeName; cmd += ".outMesh"; //outMesh statt inMesh, damit undo (ohne history) funzt status = MGlobal::executeCommand( cmd, false, false ); MCheckStatus( status, "Could not force DG eval" ); // Disconnect the duplicate meshNode now // dgModifier.undoIt(); } else { MObject meshData; status = dupMeshNodeSrcPlug.getValue( meshData ); MCheckStatus( status, "Could not retrieve meshData" ); status = meshNodeOutMeshPlug.setValue( meshData ); MCheckStatus( status, "Could not set outMesh" ); } } return status; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::processUpstreamNode( modifyPolyData& data ) // -------------------------------------------------------------------------------------------- { MStatus status = MS::kSuccess; // Declare our function sets - Although dagNodeFn derives from depNodeFn, we need // both since dagNodeFn can only refer to DAG objects. // We will use depNodeFn for all times other when dealing // with the DAG. // MFnDependencyNode depNodeFn; MFnDagNode dagNodeFn; // Use the selected node's plug connections to find the upstream plug. // Since we are looking at the selected node's inMesh attribute, it will // always have only one connection coming in if it has history, and none // otherwise. // // If there is no history, copy the selected node and place it ahead of the // modifierNode as the new upstream node so that the modifierNode has an // input mesh to operate on. // //save the meshDagPath for later use MDagPath::getAPathTo(data.meshNodeShape,myMeshPath); MPlugArray tempPlugArray; if( fHasHistory ) { // Since we have history, look for what connections exist on the // meshNode "inMesh" plug. "inMesh" plugs should only ever have one // connection. // data.meshNodeDestPlug.connectedTo( tempPlugArray, true, false); // ASSERT: Only one connection should exist on meshNodeShape.inMesh! // MStatusAssert( (tempPlugArray.length() == 1), "tempPlugArray.length() == 1 -- 0 or >1 connections on meshNodeShape.inMesh" ); data.upstreamNodeSrcPlug = tempPlugArray[0]; // Construction history only deals with shapes, so we can grab the // upstreamNodeShape off of the source plug. // // Dieser Bereich muss bleiben, weil diese Attribute noch bentigt werden data.upstreamNodeShape = data.upstreamNodeSrcPlug.node(); depNodeFn.setObject( data.upstreamNodeShape ); data.upstreamNodeSrcAttr = data.upstreamNodeSrcPlug.attribute(); // Disconnect the upstream node and the selected node, so we can // replace them with our own connections below. // MPlug nodePlug(data.meshNodeShape,data.meshNodeDestAttr ) ; INVIS(cout<<data.upstreamNodeSrcPlug.name().asChar()<<" --|-- "<<nodePlug.name().asChar()<<endl); status = fDGModifier.disconnect( data.upstreamNodeSrcPlug, nodePlug ); MCheckStatus( status, "Disconnect Upstream mit meshNode" ); } else // No History (!fHasHistory) { // Use the DAG node function set to duplicate the shape of the meshNode. // The duplicate method will return an MObject handle to the transform // of the duplicated shape, so traverse the dag to locate the shape. Store // this duplicate shape as our "upstream" node to drive the input for the // modifierNode. // depNodeFn.setObject( data.meshNodeShape ); data.upstreamNodeTransform = createDuplicate.createNode("mesh"); createDuplicate.doIt(); dagNodeFn.setObject( data.upstreamNodeTransform ); // Ensure that our upstreamNode is pointing to a shape. // MStatusAssert( (0 < dagNodeFn.childCount()), "0 < dagNodeFn.childCount() -- Duplicate meshNode transform has no shape." ); data.upstreamNodeShape = dagNodeFn.child(0); MPlug outMeshPlug = depNodeFn.findPlug("outMesh"); depNodeFn.setObject(data.upstreamNodeShape); //jetzt inMesh upstreamNodeShape mit outMesh meshShape füllen MDGModifier tempMod; tempMod.connect(outMeshPlug,depNodeFn.findPlug("inMesh")); tempMod.doIt(); //force DGEVAL MString cmd = "dgeval -src "; cmd += depNodeFn.name(); cmd += ".outMesh"; MGlobal::executeCommand(cmd,false,false); tempMod.undoIt(); // Re-parent the upstreamNodeShape under our original transform // reparentDuplicate.reparentNode( data.upstreamNodeShape, data.meshNodeTransform ); reparentDuplicate.doIt(); deleteDuplicate.deleteNode( data.upstreamNodeTransform ); deleteDuplicate.doIt(); /* status = fDagModifier.reparentNode( data.upstreamNodeShape, data.meshNodeTransform ); MCheckStatus( status, "reparentNode" ); // Perform the DAG re-parenting // // Note: This reparent must be performed before the deleteNode() is called. // See polyModifierCmd.h (see definition of fDagModifier) for more details. // status = fDagModifier.doIt(); MCheckStatus( status, "fDagModifier.doIt()" ); */ // Mark the upstreamNodeShape (the original shape) as an intermediate object // (making it invisible to the user) // dagNodeFn.setObject( data.upstreamNodeShape ); dagNodeFn.setIntermediateObject( true ); // Get the upstream node source attribute // data.upstreamNodeSrcAttr = dagNodeFn.attribute( "outMesh" ); data.upstreamNodeSrcPlug = MPlug(data.upstreamNodeShape, data.upstreamNodeSrcAttr); /* // Remove the duplicated transform node (clean up) // status = fDagModifier.deleteNode( data.upstreamNodeTransform ); MCheckStatus( status, "deleteNode" ); // Perform the DAG delete node // // Note: This deleteNode must be performed after the reparentNode() method is // completed. See polyModifierCmd.h (see definition of fDagModifier) for // details. // status = fDagModifier.doIt(); MCheckStatus( status, "fDagModifier.doIt()" ); */ // Cache the DAG path to the duplicate shape // dagNodeFn.getPath( fDuplicateDagPath ); //finally delete the tweaks to avoid double transformation deleteTweaks(); } return status; }
// -------------------------------------------------------------------------------------------- MStatus polyModifierCmd::undoDirectModifier() // -------------------------------------------------------------------------------------------- { MStatus status; MFnDependencyNode depNodeFn; MFnDagNode dagNodeFn; MObject meshNode = fDagPath.node(); depNodeFn.setObject( meshNode ); // For the case with tweaks, we cannot write the mesh directly back onto // the cachedInMesh, since the shape can have out of date information from the // cachedInMesh. Thus we temporarily create an duplicate mesh, place our // old mesh on the outMesh attribute of our duplicate mesh, connect the // duplicate mesh shape to the mesh shape, and force a DG evaluation. // // For the case without tweaks, we can simply write onto the outMesh, since // the shape relies solely on an outMesh when there is no history nor tweaks. // if( fHasTweaks ) { // Retrieve the inMesh and name of our mesh node (for the DG eval) // depNodeFn.setObject( meshNode ); MPlug meshNodeInMeshPlug = depNodeFn.findPlug( "inMesh", &status ); MCheckStatus( status, "Could not retrieve inMesh" ); MString meshNodeName = depNodeFn.name(); // Duplicate our current mesh // dagNodeFn.setObject( meshNode ); MObject dupMeshNode = dagNodeFn.duplicate(); // The dagNodeFn::duplicate() returns a transform, but we need a shape // so retrieve the DAG path and extend it to the shape. // MDagPath dupMeshDagPath; MDagPath::getAPathTo( dupMeshNode, dupMeshDagPath ); dupMeshDagPath.extendToShape(); // Retrieve the outMesh of the duplicate mesh and set our mesh data back // on it. // depNodeFn.setObject( dupMeshDagPath.node() ); MPlug dupMeshNodeOutMeshPlug = depNodeFn.findPlug( "outMesh", &status ); MCheckStatus( status, "Could not retrieve outMesh" ); status = dupMeshNodeOutMeshPlug.setValue( fMeshData ); // Temporarily connect the duplicate mesh node to our mesh node // MDGModifier dgModifier; dgModifier.connect( dupMeshNodeOutMeshPlug, meshNodeInMeshPlug ); status = dgModifier.doIt(); MCheckStatus( status, "Could not connect dupMeshNode -> meshNode" ); // Need to force a DG evaluation now that the input has been changed. // MString cmd("dgeval -src "); cmd += meshNodeName; cmd += ".inMesh"; status = MGlobal::executeCommand( cmd, false, false ); MCheckStatus( status, "Could not force DG eval" ); // Disconnect and delete the duplicate mesh node now // dgModifier.undoIt(); MGlobal::deleteNode( dupMeshNode ); // Restore the tweaks on the mesh // status = undoTweakProcessing(); } else { // Restore the original mesh by writing the old mesh data (fMeshData) back // onto the outMesh of our meshNode // depNodeFn.setObject( meshNode ); MPlug meshNodeOutMeshPlug = depNodeFn.findPlug( "outMesh", &status ); MCheckStatus( status, "Could not retrieve outMesh" ); status = meshNodeOutMeshPlug.setValue( fMeshData ); MCheckStatus( status, "Could not set meshData" ); } return status; }
bool atomExport::setUpCache(MSelectionList &sList, std::vector<atomCachedPlugs *> &cachedPlugs,atomAnimLayers &animLayers, bool sdk, bool constraint, bool layers, std::set<std::string> &attrStrings, atomTemplateReader &templateReader, MTime &startTime, MTime &endTime, MAngle::Unit angularUnit, MDistance::Unit linearUnit) { if(endTime<startTime) return false; //should never happen but just in case. unsigned int numObjects = sList.length(); cachedPlugs.resize(numObjects); double dStart = startTime.value(); double dEnd = endTime.value() + (.0000001); //little nudge in case of round off errors MTime::Unit unit = startTime.unit(); double tickStep = MTime(1.0,unit).value(); unsigned int numItems = ((unsigned int)((dEnd - dStart)/tickStep)) + 1; bool somethingIsCached = false; //if nothing get's cached no reason to run computation loop for (unsigned int i = 0; i < numObjects; i++) { atomCachedPlugs *plug = NULL; //make sure it's a NULL, and preset it in case we skip this node cachedPlugs[i] = plug; MDagPath path; MObject node; MString name; if (sList.getDagPath (i, path) == MS::kSuccess) { node = path.node(); name = path.partialPathName(); } else if (sList.getDependNode (i, node) == MS::kSuccess) { if (!node.hasFn (MFn::kDependencyNode)) { continue; } MFnDependencyNode fnNode (node); name = fnNode.name(); } if(node.isNull()==false) { if(i< animLayers.length()) { MPlugArray plugs; animLayers.getPlugs(i,plugs); std::set<std::string> tempAttrStrings; atomTemplateReader tempTemplateReader; plug = new atomCachedPlugs(name,node,plugs,sdk,constraint,layers, tempAttrStrings,tempTemplateReader,numItems,angularUnit, linearUnit); if(plug->hasCached() ==false) delete plug; else { cachedPlugs[i] = plug; somethingIsCached = true; } } else { if(templateReader.findNode(name)== false) { continue; } MSelectionList localList; localList.add(node); MPlugArray animatablePlugs; MAnimUtil::findAnimatablePlugs(localList,animatablePlugs); plug = new atomCachedPlugs(name,node,animatablePlugs,sdk,constraint,layers,attrStrings,templateReader,numItems,angularUnit, linearUnit); if(plug->hasCached() ==false) delete plug; else { cachedPlugs[i] = plug; somethingIsCached = true; } } } } bool computationFinished = true; //if no interrupt happens we will finish the computation if(somethingIsCached) { bool hasActiveProgress = false; if (MProgressWindow::reserve()) { hasActiveProgress = true; MProgressWindow::setInterruptable(true); MProgressWindow::startProgress(); MProgressWindow::setProgressRange(0, numObjects); MProgressWindow::setProgress(0); MStatus stringStat; MString msg = MStringResource::getString(kBakingProgress, stringStat); if(stringStat == MS::kSuccess) MProgressWindow::setTitle(msg); } unsigned int count =0; for(double tick = dStart; tick <= dEnd; tick += tickStep) { if(hasActiveProgress) MProgressWindow::setProgress(count); MTime time(tick,unit); MDGContext ctx(time); for(unsigned int z = 0; z< cachedPlugs.size(); ++z) { if(cachedPlugs[z]) cachedPlugs[z]->calculateValue(ctx,count); } if (hasActiveProgress && MProgressWindow::isCancelled()) { computationFinished = false; break; } ++count; } if(hasActiveProgress) MProgressWindow::endProgress(); } return computationFinished; }
// -------------------------------------- void ReferenceManager::processReference ( const MObject& referenceNode ) { MStatus status; MFnDependencyNode referenceNodeFn ( referenceNode, &status ); if (status != MStatus::kSuccess) return; #if MAYA_API_VERSION >= 600 MString referenceNodeName = MFnDependencyNode( referenceNode ).name(); Reference* reference = new Reference(); reference->referenceNode = referenceNode; mReferences.push_back ( reference ); // Get the paths of the root transforms included in this reference MObjectArray subReferences; getRootObjects ( referenceNode, reference->paths, subReferences ); uint pathCount = reference->paths.length(); // Process the sub-references first uint subReferenceCount = subReferences.length(); for (uint i = 0; i < subReferenceCount; ++i) { MObject& subReference = subReferences[i]; if ( subReference != MObject::kNullObj ) processReference ( subReference ); } // Retrieve the reference node's filename MString command = MString("reference -rfn \"") + referenceNodeFn.name() + MString("\" -q -filename;"); MString filename; status = MGlobal::executeCommand ( command, filename ); if (status != MStatus::kSuccess || filename.length() == 0) return; // Strip the filename of the multiple file token int stripIndex = filename.index('{'); if (stripIndex != -1) filename = filename.substring(0, stripIndex - 1); // Avoid transform look-ups on COLLADA references. int extLocation = filename.rindex('.'); if (extLocation > 0) { MString ext = filename.substring(extLocation + 1, filename.length() - 1).toLowerCase(); if (ext == "dae" || ext == "xml") return; } // Check for already existing file information // Otherwise create a new file information sheet with current node names for ( ReferenceFileList::iterator it = mFiles.begin(); it != mFiles.end(); ++it ) { if ((*it)->filename == filename) { reference->file = (*it); break; } } if ( reference->file == NULL ) reference->file = processReferenceFile(filename); // Get the list of the root transform's first child's unreferenced parents. // This is a list of the imported nodes! for (uint j = 0; j < pathCount; ++j) { MDagPath path = reference->paths[j]; if (path.childCount() > 0) { path.push ( path.child(0) ); MFnDagNode childNode ( path ); if (!childNode.object().hasFn(MFn::kTransform)) continue; uint parentCount = childNode.parentCount(); for (uint k = 0; k < parentCount; ++k) { MFnDagNode parentNode(childNode.parent(k)); if (parentNode.object() == MObject::kNullObj || parentNode.isFromReferencedFile()) continue; MDagPath parentPath = MDagPath::getAPathTo(parentNode.object()); if (parentPath.length() > 0) { ReferenceRootList::iterator it = reference->reroots.insert( reference->reroots.end(), ReferenceRoot() ); (*it).index = j; (*it).reroot = parentPath; } } } } #endif }
MStatus atomExport::exportSelected( ofstream &animFile, MString ©Flags, std::set<std::string> &attrStrings, bool includeChildren, bool useSpecifiedTimes, MTime &startTime, MTime &endTime, bool statics, bool cached, bool sdk, bool constraint, bool layers, const MString& exportEditsFile, atomTemplateReader &templateReader) { MStatus status = MS::kFailure; // If the selection list is empty, then there are no anim curves // to export. // MSelectionList sList; std::vector<unsigned int> depths; SelectionGetter::getSelectedObjects(includeChildren,sList,depths); if (sList.isEmpty()) { MString msg = MStringResource::getString(kNothingSelected, status); MGlobal::displayError(msg); return (MS::kFailure); } // Copy any anim curves to the API clipboard. // MString command(copyFlags); // Always write out header if (!fWriter.writeHeader(animFile,useSpecifiedTimes, startTime,endTime)) { return (MS::kFailure); } atomAnimLayers animLayers; std::vector<atomNodeWithAnimLayers *> nodesWithAnimLayers; if(layers) { bool hasAnimLayers = animLayers.getOrderedAnimLayers(); //any layers in the scene? hasAnimLayers = setUpAnimLayers(sList,animLayers, nodesWithAnimLayers,attrStrings,templateReader); //any layers on our selection? if(hasAnimLayers) { //add the layers to the sList... unsigned int oldLength = sList.length(); animLayers.addLayersToStartOfSelectionList(sList); unsigned int diffLength = sList.length() - oldLength; atomNodeWithAnimLayers * nullPad = NULL; for(unsigned int k =0 ;k < diffLength;++k) //need to pad the beginning of the nodesWithAnimlayers with any layer that was added { nodesWithAnimLayers.insert(nodesWithAnimLayers.begin(),nullPad); depths.insert(depths.begin(),0); } } } //if caching is on, we pre iterate through the objects, find //each plug that's cached and then cache the data all at once std::vector<atomCachedPlugs *> cachedPlugs; if(cached) { bool passed = setUpCache(sList,cachedPlugs,animLayers,sdk, constraint, layers, attrStrings,templateReader,startTime, endTime, fWriter.getAngularUnit(), fWriter.getLinearUnit()); //this sets it up and runs the cache; if(passed == false) //failed for some reason, one reason is that the user canceled the computation { //first delete everything though //delete any cachedPlugs objects that we created. for(unsigned int z = 0; z< cachedPlugs.size(); ++z) { if(cachedPlugs[z]) delete cachedPlugs[z]; } //and delete any any layers too for(unsigned int zz = 0; zz< nodesWithAnimLayers.size(); ++zz) { if(nodesWithAnimLayers[zz]) delete nodesWithAnimLayers[zz]; } MString msg = MStringResource::getString(kCachingCanceled, status); MGlobal::displayError(msg); return (MS::kFailure); } } unsigned int numObjects = sList.length(); bool computationFinished = true; //not sure if in a headless mode we may want to not show the progress, should //still run if that's the case bool hasActiveProgress = false; if (MProgressWindow::reserve()) { hasActiveProgress = true; MProgressWindow::setInterruptable(true); MProgressWindow::startProgress(); MProgressWindow::setProgressRange(0, numObjects); MProgressWindow::setProgress(0); MStatus stringStat; MString msg = MStringResource::getString(kExportProgress, stringStat); if(stringStat == MS::kSuccess) MProgressWindow::setTitle(msg); } if (exportEditsFile.length() > 0) { fWriter.writeExportEditsFilePresent(animFile); } if(layers) { animLayers.writeAnimLayers(animFile,fWriter); } bool haveAnyAnimatableStuff = false; //will remain false if no curves or statics for (unsigned int i = 0; i < numObjects; i++) { if(hasActiveProgress) MProgressWindow::setProgress(i); MString localCommand; bool haveAnimatedCurves = false; //local flag, if true this node has animated curves bool haveAnimatableChannels = false; //local flag, if true node has some animatable statics MDagPath path; MObject node; if (sList.getDagPath (i, path) == MS::kSuccess) { MString name = path.partialPathName(); //if the name is in the template, only then write it out... if(templateReader.findNode(name)== false) continue; //we use this to both write out the cached plugs for this node but for also to not write out //the plugs which are cached when writing anim curves. atomCachedPlugs * cachedPlug = NULL; if(cached && i < cachedPlugs.size()) cachedPlug = cachedPlugs[i]; atomNodeWithAnimLayers *layerPlug = NULL; if(layers && i < nodesWithAnimLayers.size()) layerPlug = nodesWithAnimLayers[i]; unsigned int depth = depths[i]; unsigned int childCount = path.childCount(); MObject object = path.node(); atomNodeNameReplacer::NodeType nodeType = (object.hasFn(MFn::kShape)) ? atomNodeNameReplacer::eShape : atomNodeNameReplacer::eDag; fWriter.writeNodeStart(animFile,nodeType,name,depth,childCount); MPlugArray animatablePlugs; MSelectionList localList; localList.add(object); MAnimUtil::findAnimatablePlugs(localList,animatablePlugs); if(writeAnimCurves(animFile,name,cachedPlug, layerPlug, command, haveAnimatedCurves,templateReader) != MS::kSuccess ) { return (MS::kFailure); } else if(haveAnimatedCurves) { haveAnyAnimatableStuff = true; } if(statics||cached) { writeStaticAndCached (animatablePlugs,cachedPlug,statics,cached,animFile,attrStrings,name,depth,childCount, haveAnimatableChannels,templateReader); } fWriter.writeNodeEnd(animFile); } else if (sList.getDependNode (i, node) == MS::kSuccess) { if (!node.hasFn (MFn::kDependencyNode)) { return (MS::kFailure); } MPlugArray animatablePlugs; MFnDependencyNode fnNode (node, &status); MString name = fnNode.name(); atomNodeNameReplacer::NodeType nodeType = atomNodeNameReplacer::eDepend; atomNodeWithAnimLayers *layerPlug = NULL; //if a layer we get our own attrs if(i< animLayers.length()) { MPlugArray plugs; animLayers.getPlugs(i,animatablePlugs); nodeType = atomNodeNameReplacer::eAnimLayer; } else { if(templateReader.findNode(name)== false) { continue; } MSelectionList localList; localList.add(node); MAnimUtil::findAnimatablePlugs(localList,animatablePlugs); if(layers && i < nodesWithAnimLayers.size()) layerPlug = nodesWithAnimLayers[i]; } //we use this to both write out the cached plugs for this node but for also to not write out //the plugs which are cached when writing anim curves. atomCachedPlugs * cachedPlug = NULL; if(cached && i < cachedPlugs.size()) cachedPlug = cachedPlugs[i]; fWriter.writeNodeStart(animFile,nodeType,name); if(writeAnimCurves(animFile,name, cachedPlug,layerPlug,command, haveAnimatedCurves,templateReader) != MS::kSuccess ) { return (MS::kFailure); } else if(haveAnimatedCurves) { haveAnyAnimatableStuff = true; } if(statics||cached) { writeStaticAndCached (animatablePlugs,cachedPlug,statics,cached,animFile,attrStrings,name,0,0,haveAnimatableChannels,templateReader); } fWriter.writeNodeEnd(animFile); } if(haveAnimatableChannels==true) haveAnyAnimatableStuff = true; if (hasActiveProgress && MProgressWindow::isCancelled()) { computationFinished = false; break; } } if (exportEditsFile.length() > 0) { fWriter.writeExportEditsFile(animFile,exportEditsFile); } //delete any cachedPlugs objects that we created. for(unsigned int z = 0; z< cachedPlugs.size(); ++z) { if(cachedPlugs[z]) delete cachedPlugs[z]; } //and delete any any layers too for(unsigned int zz = 0; zz< nodesWithAnimLayers.size(); ++zz) { if(nodesWithAnimLayers[zz]) delete nodesWithAnimLayers[zz]; } if(computationFinished == false) //failed for some reason, one reason is that the user canceled the computation { MString msg = MStringResource::getString(kSavingCanceled, status); MGlobal::displayError(msg); return (MS::kFailure); } if(hasActiveProgress) MProgressWindow::endProgress(); if(haveAnyAnimatableStuff == false) { MString msg = MStringResource::getString(kAnimCurveNotFound, status); MGlobal::displayError(msg); return (MS::kFailure); } else return (MS::kSuccess); }
Corona::SharedPtr<Corona::Abstract::Map> getOslTexMap(MString& attributeName, MFnDependencyNode& depFn, ShadingNetwork& sn) { MStatus status; OSL::OSLShadingNetworkRenderer *oslRenderer; MayaTo::MayaToWorld::WorldRenderType rType = MayaTo::getWorldPtr()->getRenderType(); if ((rType == MayaTo::MayaToWorld::WorldRenderType::SWATCHRENDER)) { oslRenderer = (OSL::OSLShadingNetworkRenderer *)MayaTo::getObjPtr("oslSwatchRenderer"); } else{ oslRenderer = (OSL::OSLShadingNetworkRenderer *)MayaTo::getObjPtr("oslRenderer"); } size_t numNodes = sn.shaderList.size(); MString OSLInterfaceName = depFn.name() + "_" + attributeName + "_OSLInterface"; MString shaderGroupName = depFn.name() + "_" + attributeName + "_OSLShadingGroup"; OSL::ShaderGroupRef shaderGroup = oslRenderer->shadingsys->ShaderGroupBegin(shaderGroupName.asChar()); MObject thisMObject = depFn.object(); MString outPlugName; MString connectedObjectName = getObjectName(getOtherSideSourceNode(attributeName, thisMObject, true, outPlugName)); Logging::debug(MString("getOslTexMap: ") + connectedObjectName + "." + outPlugName + " is connected with " + depFn.name() + "." + attributeName); MPlug shaderPlug = depFn.findPlug(attributeName); MAYATO_OSL::createOSLProjectionNodes(shaderPlug); for (int shadingNodeId = 0; shadingNodeId < numNodes; shadingNodeId++) { ShadingNode snode = sn.shaderList[shadingNodeId]; Logging::debug(MString("ShadingNode Id: ") + shadingNodeId + " ShadingNode name: " + snode.fullName); MAYATO_OSL::createOSLHelperNodes(sn.shaderList[shadingNodeId]); MAYATO_OSL::createOSLShadingNode(sn.shaderList[shadingNodeId]); MAYATO_OSL::connectProjectionNodes(sn.shaderList[shadingNodeId].mobject); if (snode.fullName == connectedObjectName.asChar()) { MAYATO_OSL::createOSLHelperNodes(sn.shaderList[sn.shaderList.size() - 1]); Logging::debug(MString("connected node found: ") + snode.fullName + " search output attr."); for (size_t outId = 0; outId < snode.outputAttributes.size(); outId++) { ShaderAttribute& sa = snode.outputAttributes[outId]; if (MString(sa.name.c_str()) == outPlugName) { Logging::debug(MString("connected out attr found: ") + sa.name.c_str() + " "); MString destParam; MString sourceParam = outPlugName; MString sourceNode = connectedObjectName; if ((sa.type == "color") || (sa.type == "vector")) { // lets see if we have a color helper node MString helperNodeName = MAYATO_OSL::createPlugHelperNodeName(attributeName.asChar(), thisMObject, false); Logging::debug(MString("Interface connection - color/vector attribute ") + sa.name.c_str() + " search for helper node " + helperNodeName); if (MAYATO_OSL::doesOSLNodeAlreadyExist(helperNodeName)) { Logging::debug(MString("Found helper node name.")); sourceParam = "outputValue"; sourceNode = helperNodeName; } destParam = "inVector"; } if (sa.type == "float") { destParam = "inFloat"; } if (sa.type == "int") { destParam = "inInt"; } if (sa.type == "bool") { destParam = "inBool"; } if (sourceParam == "output") sourceParam = "outOutput"; // if we have a color/vector input, try to find a multiplier attribute MString multiplierName = attributeName + "Multiplier"; MPlug multiplierAttribute = depFn.findPlug(multiplierName, true, &status); if (status) { Logging::debug(MString("Found multiplier attribute: ") + multiplierName); float multiplier = multiplierAttribute.asFloat(); float offset = 0.0f; if ((attributeName == "refractionIndex") || (attributeName == "reflectionIor")) { offset = -1.0f; } oslRenderer->shadingsys->Parameter("multiplier", OSL::TypeDesc::TypeFloat, &multiplier); oslRenderer->shadingsys->Parameter("offset", OSL::TypeDesc::TypeFloat, &offset); } Logging::debug(MString("creating OSLInterface shader ") + OSLInterfaceName); bool success = oslRenderer->shadingsys->Shader("surface", "OSLInterface", OSLInterfaceName.asChar()); Logging::debug(MString("connecting ") + sourceNode + "." + sourceParam + " -> " + OSLInterfaceName + "." + destParam); success = oslRenderer->shadingsys->ConnectShaders(sourceNode.asChar(), sourceParam.asChar(), OSLInterfaceName.asChar(), destParam.asChar()); break; } } break; } } if (!oslRenderer->shadingsys->ShaderGroupEnd()) { Logging::debug("Problem finishing shader group"); } std::string serialized; oslRenderer->shadingsys->getattribute(shaderGroup.get(), "pickle", serialized); Logging::debug(MString("Serialized: ") + serialized.c_str()); Corona::SharedPtr<Corona::Abstract::Map> oslMapp = new OSLMap; OSLMap *oslMap = (OSLMap *)oslMapp.getReference(); oslMap->oslRenderer = oslRenderer; oslMap->shaderGroup = shaderGroup; if (depFn.object().hasFn(MFn::kLight)) oslMap->isLightMap = true; if (attributeName == "normalCamera") { oslMap->bumpType = OSLMap::NONE; // we only support direct bumpmap connections MPlug ncPlug = depFn.findPlug("normalCamera"); if (ncPlug.isConnected()) { MPlugArray pa; ncPlug.connectedTo(pa, true, false); if (pa.length() > 0) { for (uint pId = 0; pId < pa.length(); pId++) { if (pa[pId].node().hasFn(MFn::kBump) || pa[pId].node().hasFn(MFn::kBump3d)) { MFnDependencyNode bumpFn(pa[pId].node()); MPlug interpPlug = bumpFn.findPlug("bumpInterp"); if (interpPlug.asInt() == 0) oslMap->bumpType = OSLMap::BUMP; if (interpPlug.asInt() == 1) oslMap->bumpType = OSLMap::NORMALTANGENT; if (interpPlug.asInt() == 2) oslMap->bumpType = OSLMap::NORMALOBJECT; if (pa[pId].node().hasFn(MFn::kBump3d)) oslMap->bumpType = OSLMap::BUMP3D; } } } } } return oslMapp; }