bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MObject& shadingGroup) { // if obj is a light, simply return the mobject if (shapeObjectDP.hasFn(MFn::kLight)) shadingGroup = shapeObjectDP.node(); if (shapeObjectDP.hasFn(MFn::kMesh)) { // Find the Shading Engines Connected to the SourceNode MFnMesh fnMesh(shapeObjectDP.node()); // A ShadingGroup will have a MFnSet MObjectArray sets, comps; fnMesh.getConnectedSetsAndMembers(shapeObjectDP.instanceNumber(), sets, comps, true); // Each set is a Shading Group. Loop through them for (unsigned int i = 0; i < sets.length(); ++i) { shadingGroup = sets[i]; return true; } } if (shapeObjectDP.hasFn(MFn::kNurbsSurface)||shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MObject instObjGroupsAttr; if (shapeObjectDP.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface fnNurbs(shapeObjectDP.node()); instObjGroupsAttr = fnNurbs.attribute("instObjGroups"); } if (shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MFnParticleSystem fnPart(shapeObjectDP.node()); instObjGroupsAttr = fnPart.attribute("instObjGroups"); } MPlug instPlug(shapeObjectDP.node(), instObjGroupsAttr); // Get the instance that our node is referring to; // In other words get the Plug for instObjGroups[intanceNumber]; MPlug instPlugElem = instPlug.elementByLogicalIndex(shapeObjectDP.instanceNumber()); // Find the ShadingGroup plugs that we are connected to as Source MPlugArray SGPlugArray; instPlugElem.connectedTo(SGPlugArray, false, true); // Loop through each ShadingGroup Plug for (unsigned int i=0; i < SGPlugArray.length(); ++i) { shadingGroup = SGPlugArray[i].node(); return true; } } return false; }
//----------------------------------------------------------------------------- // This is here for reference. It isn't currently used //----------------------------------------------------------------------------- void CVsSkinnerCmd::DoConnectGeometry( const MDagPath &skinnerPath, const MDagPath &gDagPath ) { MObject skinnerObj( skinnerPath.node() ); const MFnDependencyNode vsSkinnerFn( skinnerObj ); const MFnMesh meshFn( gDagPath ); // Connect things up MPlug sP; MPlug dP; MDagModifier &mDagModifier( m_undo.DagModifier() ); // Connect mesh.worldMatrix[#] vsSkinner.geometryWorldMatrix sP = meshFn.findPlug( "worldMatrix" ); sP = sP.elementByLogicalIndex( gDagPath.instanceNumber() ); dP = vsSkinnerFn.findPlug( "geometryWorldMatrix" ); mDagModifier.connect( sP, dP ); sP = meshFn.findPlug( "outMesh" ); dP = vsSkinnerFn.findPlug( "inputGeometry" ); mDagModifier.connect( sP, dP ); mDagModifier.doIt(); // Add the default volume MSelectionList emptyList; MGlobal::setActiveSelectionList( DoNewVolumes( skinnerPath, emptyList ), MGlobal::kReplaceList ); }
//----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- void ConnectIntWeld( vm::CUndo &undo, const MObject &weldNodeObj, const MDagPath &toWeldPath, int nType, int nIntValue, const MMatrix &offsetMatrix ) { MFnDependencyNode weldFn( weldNodeObj ); MFnDagNode toWeldFn( toWeldPath ); MPlug wiAP = weldFn.findPlug( CVstWeldNode::m_iaWeldInput ); const uint nWeldIndex = vm::NextAvailable( wiAP ); MPlug wiP = wiAP.elementByLogicalIndex( nWeldIndex ); undo.SetAttr( wiP.child( CVstWeldNode::m_iaType ), nType ); undo.SetAttr( wiP.child( CVstWeldNode::m_iaInt ), nIntValue ); MFnMatrixData dFn; MObject mdObj = dFn.create( offsetMatrix ); undo.SetAttr( wiP.child( CVstWeldNode::m_iaOffsetMatrix ), mdObj ); undo.Connect( toWeldFn.findPlug( "parentInverseMatrix" ).elementByLogicalIndex( toWeldPath.instanceNumber() ), wiP.child( CVstWeldNode::m_iaInverseParentSpace ), true ); undo.Connect( toWeldFn.findPlug( "rotateOrder" ), wiP.child( CVstWeldNode::m_iaRotateOrder ), true ); MPlug woAP = weldFn.findPlug( CVstWeldNode::m_oaWeldOutput ); MPlug woP = woAP.elementByLogicalIndex( nWeldIndex ); MPlug tP = woP.child( CVstWeldNode::m_oaTranslate ); undo.Connect( tP.child( CVstWeldNode::m_oaTranslateX ), toWeldFn.findPlug( "translateX" ) ); undo.Connect( tP.child( CVstWeldNode::m_oaTranslateY ), toWeldFn.findPlug( "translateY" ) ); undo.Connect( tP.child( CVstWeldNode::m_oaTranslateZ ), toWeldFn.findPlug( "translateZ" ) ); MPlug rP = woP.child( CVstWeldNode::m_oaRotate ); undo.Connect( rP.child( CVstWeldNode::m_oaRotateX ), toWeldFn.findPlug( "rotateX" ) ); undo.Connect( rP.child( CVstWeldNode::m_oaRotateY ), toWeldFn.findPlug( "rotateY" ) ); undo.Connect( rP.child( CVstWeldNode::m_oaRotateZ ), toWeldFn.findPlug( "rotateZ" ) ); }
// -------------------------------------------------------------------- MStatus SceneGraph::addInstancedDagPaths ( MSelectionList& selectionList ) { MStatus status; int length = selectionList.length ( &status ); if ( status != MStatus::kSuccess ) return MStatus::kFailure; for ( int i=0; i<length; i++ ) { MDagPath dagPath; if ( selectionList.getDagPath ( i, dagPath ) != MStatus::kSuccess ) return MStatus::kFailure; if ( dagPath.isInstanced() ) { int includedInstance=dagPath.instanceNumber ( &status ); if ( status != MStatus::kSuccess ) return MStatus::kFailure; MObject object=dagPath.node ( &status ); if ( status != MStatus::kSuccess ) return MStatus::kFailure; MDagPathArray paths; if ( MDagPath::getAllPathsTo ( object, paths ) != MStatus::kSuccess ) return MStatus::kFailure; int numPaths=paths.length(); for ( int p=0; p<numPaths; p++ ) if ( p!=includedInstance ) selectionList.add ( paths[p] ); } } return MStatus::kSuccess; }
void printMaterials(const MDagPath& dagPath) { MFnMesh fnMesh(dagPath); unsigned instanceNumber = dagPath.instanceNumber(); MObjectArray sets; MObjectArray comps; fnMesh.getConnectedSetsAndMembers( instanceNumber, sets, comps, true ); // Print Material Names for(unsigned int i = 0; i < sets.length(); ++i) { MFnDependencyNode fnDepSGNode(sets[i]); std::cout << fnDepSGNode.name() << std::endl; } }
// In order to correctly extract skinweights we first // need to go into bindpose. (and we need to remember the current // pose, to be able to undo it). // // I know: nearly no error-checking. void BindPoseTool::GoIntoBindPose() { MStatus status; std::cout << " Going into bindpose "; // == turn IK off // save current state undoInfo.ikSnap = MIkSystem::isGlobalSnap(&status); undoInfo.ikSolve = MIkSystem::isGlobalSolve(); // turn it off MIkSystem::setGlobalSnap(false); MIkSystem::setGlobalSolve(false); // == put joints into bindPose for (MItDag dagIt(MItDag::kDepthFirst, MFn::kJoint); !dagIt.isDone(); dagIt.next()) { std::cout << "."; MDagPath jointPath; dagIt.getPath(jointPath); if (jointPath.isInstanced()) { // we only work on the first instance of an instanced joint. if (jointPath.instanceNumber() != 0) continue; } BindPoseUndoInformation::JointMatrixVector::value_type joint2transform; MFnIkJoint joint(jointPath.node()); MTransformationMatrix currentTransform = joint.transformation(&status); joint2transform.first = jointPath.node(); joint2transform.second = currentTransform; undoInfo.savedTransforms.push_back(joint2transform); MMatrix bindPoseMatrix = getBindPoseMatrix(joint); joint.set(bindPoseMatrix); } std::cout << std::endl; //cout << "bindPose end" << endl; // don't know, if this is really necessary, but MS xporttranslator // does it... syncMeshes(); // remember the change inBindPose = true; }
IECore::ObjectPtr FromMayaTransformConverter::doConversion( const MDagPath &dagPath, IECore::ConstCompoundObjectPtr operands ) const { MTransformationMatrix transform; if( m_spaceParameter->getNumericValue()==Local ) { MFnTransform fnT( dagPath ); transform = fnT.transformation(); } else { unsigned instIndex = dagPath.instanceNumber(); MObject dagNode = dagPath.node(); MFnDependencyNode fnN( dagNode ); MPlug plug = fnN.findPlug( "worldMatrix" ); MPlug instPlug = plug.elementByLogicalIndex( instIndex ); MObject matrix; instPlug.getValue( matrix ); MFnMatrixData fnM( matrix ); transform = fnM.transformation(); if ( m_spaceParameter->getNumericValue() == Custom ) { // multiply world transform by the inverse of the custom space matrix. transform = transform.asMatrix() * IECore::convert< MMatrix, Imath::M44f >( operands->member< IECore::M44fData >("customSpace", true)->readable().inverse() ); } } if( m_zeroPivotsParameter->getTypedValue() ) { transform.setScalePivot( MPoint( 0, 0, 0 ), MSpace::kTransform, true ); transform.setRotatePivot( MPoint( 0, 0, 0 ), MSpace::kTransform, true ); } if( m_eulerFilterParameter->getTypedValue() && m_lastRotationValid ) { transform.rotateTo( transform.eulerRotation().closestSolution( m_lastRotation ) ); } m_lastRotation = transform.eulerRotation(); m_lastRotationValid = true; return new IECore::TransformationMatrixdData( IECore::convert<IECore::TransformationMatrixd, MTransformationMatrix>( transform ) ); }
//------------------------------ void MaterialExporter::exportConnectedMaterials ( SceneElement* sceneElement ) { // If we have a external reference, we don't need to export the data here. if ( !sceneElement->getIsLocal() ) return; if ( !sceneElement->getIsExportNode () ) return; // Check if it is a mesh object and an export node if ( sceneElement->getType() == SceneElement::MESH ) { MDagPath dagPath = sceneElement->getPath(); // Attach a function set MStatus status; MFnMesh fnMesh ( dagPath.node(), &status ); if ( status != MStatus::kSuccess ) return; // Find how many shaders are used by this instance of the mesh MObjectArray shaders; MIntArray shaderIndices; unsigned instanceNumber = dagPath.instanceNumber(); fnMesh.getConnectedShaders ( instanceNumber, shaders, shaderIndices ); // Find the polygons that correspond to each materials and export them uint realShaderCount = ( uint ) shaders.length(); uint numShaders = ( uint ) std::max ( ( size_t ) 1, ( size_t ) shaders.length() ); for ( uint shaderPosition = 0; shaderPosition < numShaders; ++shaderPosition ) { if ( shaderPosition < realShaderCount ) { // Add shader-specific parameters (TexCoords sets). // Add symbolic name for the material used on this polygon set. MObject shadingEngine = shaders[shaderPosition]; exportMaterial ( shadingEngine ); } } } // recursive call for all the child elements for ( uint i=0; i<sceneElement->getChildCount(); ++i ) { SceneElement* childElement = sceneElement->getChild ( i ); exportConnectedMaterials ( childElement ); } }
MFnMesh* GDExporter::GetSelectedMesh(void) { MSelectionList currSelection; MGlobal::getActiveSelectionList(currSelection); unsigned int selectionCount = currSelection.length(); MFnMesh* exportingMesh = 0; for(unsigned int selectionIndex = 0; selectionIndex < selectionCount; ++selectionIndex ) { MDagPath currPath; currSelection.getDagPath(selectionIndex, currPath); if( currPath.apiType() != MFn::kTransform ) continue; MFnTransform currTransform(currPath); unsigned int childCount = currTransform.childCount(); for(unsigned int childIndex = 0; childIndex < childCount; ++childIndex) { MObject childObject = currTransform.child(childIndex); if( childObject.apiType() == MFn::kMesh ) { MFnDagNode dagNode; dagNode.setObject(childObject); MDagPath childPath; dagNode.getPath(childPath); MFnMesh* pChildMesh = new MFnMesh(childPath); if( pChildMesh->isIntermediateObject() ) continue; bool bExportMesh = true; if( pChildMesh->isInstanced(false) ) if( childPath.instanceNumber() != 0 ) bExportMesh = false; if( bExportMesh ) { if( exportingMesh != 0 ) { delete exportingMesh; delete pChildMesh; MGlobal::displayError(MString("GDExporter - More than one mesh object selected.")); return 0; } exportingMesh = pChildMesh; } } } } if( exportingMesh == 0 ) { MGlobal::displayError(MString("GDExporter - No mesh objects currently selected.")); return 0; } return exportingMesh; }
MStatus findTexturesPerPolygon::doIt( const MArgList& ) // // Description: // Find the texture files that apply to the color of each polygon of // a selected shape if the shape has its polygons organized into sets. // { // Get the selection and choose the first path on the selection list. // MStatus status; MDagPath path; MObject cmp; MSelectionList slist; MGlobal::getActiveSelectionList(slist); slist.getDagPath(0, path, cmp); // Have to make the path include the shape below it so that // we can determine if the underlying shape node is instanced. // By default, dag paths only include transform nodes. // path.extendToShape(); // If the shape is instanced then we need to determine which // instance this path refers to. // int instanceNum = 0; if (path.isInstanced()) instanceNum = path.instanceNumber(); // Get a list of all sets pertaining to the selected shape and the // members of those sets. // MFnMesh fnMesh(path); MObjectArray sets; MObjectArray comps; if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true)) cerr << "ERROR: MFnMesh::getConnectedSetsAndMembers\n"; // Loop through all the sets. If the set is a polygonal set, find the // shader attached to the and print out the texture file name for the // set along with the polygons in the set. // for ( unsigned i=0; i<sets.length(); i++ ) { MObject set = sets[i]; MObject comp = comps[i]; MFnSet fnSet( set, &status ); if (status == MS::kFailure) { cerr << "ERROR: MFnSet::MFnSet\n"; continue; } // Make sure the set is a polygonal set. If not, continue. MItMeshPolygon piter(path, comp, &status); if ((status == MS::kFailure) || comp.isNull()) continue; // Find the texture that is applied to this set. First, get the // shading node connected to the set. Then, if there is an input // attribute called "color", search upstream from it for a texture // file node. // MObject shaderNode = findShader(set); if (shaderNode == MObject::kNullObj) continue; MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug("color", &status); if (status == MS::kFailure) continue; MItDependencyGraph dgIt(colorPlug, MFn::kFileTexture, MItDependencyGraph::kUpstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &status); if (status == MS::kFailure) continue; dgIt.disablePruningOnFilter(); // If no texture file node was found, just continue. // if (dgIt.isDone()) continue; // Print out the texture node name and texture file that it references. // MObject textureNode = dgIt.thisNode(); MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName"); MString textureName; filenamePlug.getValue(textureName); cerr << "Set: " << fnSet.name() << endl; cerr << "Texture Node Name: " << MFnDependencyNode(textureNode).name() << endl; cerr << "Texture File Name: " << textureName.asChar() << endl; // Print out the set of polygons that are contained in the current set. // for ( ; !piter.isDone(); piter.next() ) cerr << " poly component: " << piter.index() << endl; } return MS::kSuccess; }
// -------------------------------------------------------------------- bool SceneGraph::getIsExportNode ( const MDagPath& dagPath, bool& isForced, bool& isVisible ) { // Does this dagPath already exist? If so, only recurse if FollowInstancedChildren() is set. MFnDagNode dagFn ( dagPath ); String dagNodeName = dagFn.name().asChar(); bool isSceneRoot = dagPath.length() == 0; // Ignore default and intermediate nodes (history items) bool isIntermediateObject = dagFn.isIntermediateObject(); if ( ( dagFn.isDefaultNode() && !isSceneRoot ) || isIntermediateObject ) { return false; } MString nodeName = dagPath.partialPathName(); if ( nodeName == MString ( NIMA_INTERNAL_PHYSIKS ) ) { // Skip this node, which is only used // by Nima as a work-around for a Maya bug. return false; } // If we are not already forcing this node, its children // check whether we should be forcing it (skinning of hidden joints). isForced = isForcedNode ( dagPath ); DagHelper::getPlugValue ( dagPath.node(), ATTR_VISIBILITY, isVisible ); bool isInstanced = dagPath.isInstanced(); uint instanceNumber = dagPath.instanceNumber(); if ( !isForced ) { // Check for visibility if ( !ExportOptions::exportInvisibleNodes() && !isVisible ) { // Check if the visibility of the element is animated. AnimationSampleCache* animationCache = mDocumentExporter->getAnimationCache(); if ( !AnimationHelper::isAnimated ( animationCache, dagPath.node(), ATTR_VISIBILITY ) ) { return false; } } else if ( !isVisible && !ExportOptions::exportDefaultCameras() ) { // Check for the default camera transform names. if ( nodeName == CAMERA_PERSP || nodeName == CAMERA_TOP || nodeName == CAMERA_SIDE || nodeName == CAMERA_FRONT || nodeName == CAMERA_PERSP_SHAPE || nodeName == CAMERA_TOP_SHAPE || nodeName == CAMERA_SIDE_SHAPE || nodeName == CAMERA_FRONT_SHAPE ) return false; } } isForced &= !isVisible; if ( !isForced ) { // We don't want to process manipulators if ( dagPath.hasFn ( MFn::kManipulator ) || dagPath.hasFn ( MFn::kViewManip ) ) return false; // Check for constraints which are not exported //if ( !ExportOptions::exportConstraints() && dagPath.hasFn ( MFn::kConstraint ) ) return false; if ( dagPath.hasFn ( MFn::kConstraint ) ) return false; // Check set membership exclusion/inclusion if ( SetHelper::isExcluded ( dagPath ) ) return false; } return true; }
bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MIntArray& perFaceAssignments, MObjectArray& shadingGroups, bool needsPerFaceInfo=true) { // if obj is a light, simply return the mobject if (shapeObjectDP.node().hasFn(MFn::kLight)) { perFaceAssignments.clear(); shadingGroups.clear(); shadingGroups.append(shapeObjectDP.node()); return true; } if (shapeObjectDP.node().hasFn(MFn::kMesh)) { // Find the Shading Engines Connected to the SourceNode MFnMesh meshFn(shapeObjectDP.node()); perFaceAssignments.clear(); shadingGroups.clear(); MObjectArray comps; // this one seems to be extremly much faster if we need no per face informations. // e.g. for a sphere with 90000 faces, the non per face method needs 0.05 sec. whereas the // method with per face info needs about 20 sec. if (!needsPerFaceInfo) { meshFn.getConnectedSetsAndMembers(shapeObjectDP.instanceNumber(), shadingGroups, comps, true); return true; } meshFn.getConnectedShaders(shapeObjectDP.instanceNumber(), shadingGroups, perFaceAssignments); if (!meshFn.findPlug("displaySmoothMesh").asBool()) return true; MIntArray indices; indices = perFaceAssignments; int subdivs = 0; int multiplier = 0; if (meshFn.findPlug("displaySmoothMesh").asBool()) { MMeshSmoothOptions options; MStatus status = meshFn.getSmoothMeshDisplayOptions(options); if (status) { if (!meshFn.findPlug("useSmoothPreviewForRender", false, &status).asBool()) { int smoothLevel = meshFn.findPlug("renderSmoothLevel", false, &status).asInt(); options.setDivisions(smoothLevel); } subdivs = options.divisions(); if (subdivs > 0) multiplier = static_cast<int> (pow(4.0f, (subdivs - 1))); } } if (multiplier > 0) perFaceAssignments.clear(); for (unsigned int i = 0; i < indices.length(); i++) { int subdivisions = multiplier * meshFn.polygonVertexCount(i); int index = 0 > indices[i] ? 0 : indices[i]; // non assigned has -1, but we want 0 perFaceAssignments.append(index); // simply replicate the index for all subdiv faces for (int k = 0; k < subdivisions - 1; k++) perFaceAssignments.append(index); } return true; } if (shapeObjectDP.node().hasFn(MFn::kNurbsSurface)||shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MObject instObjGroupsAttr; if (shapeObjectDP.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface fnNurbs(shapeObjectDP.node()); instObjGroupsAttr = fnNurbs.attribute("instObjGroups"); } if (shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MFnParticleSystem fnPart(shapeObjectDP.node()); instObjGroupsAttr = fnPart.attribute("instObjGroups"); } MPlug instPlug(shapeObjectDP.node(), instObjGroupsAttr); // Get the instance that our node is referring to; // In other words get the Plug for instObjGroups[intanceNumber]; MPlug instPlugElem = instPlug.elementByLogicalIndex(shapeObjectDP.instanceNumber()); // Find the ShadingGroup plugs that we are connected to as Source MPlugArray SGPlugArray; instPlugElem.connectedTo(SGPlugArray, false, true); perFaceAssignments.clear(); shadingGroups.clear(); // Loop through each ShadingGroup Plug for (unsigned int i=0; i < SGPlugArray.length(); ++i) { shadingGroups.append(SGPlugArray[i].node()); return true; } } return false; }
void extractPolygons(Model* model) { MStatus stat; MItDag dagIter(MItDag::kBreadthFirst, MFn::kInvalid); for (; !dagIter.isDone(); dagIter.next()) { MDagPath dagPath; stat = dagIter.getPath(dagPath); if (!stat) { continue; }; MFnDagNode dagNode(dagPath, &stat); if (dagNode.isIntermediateObject()) continue; if (!dagPath.hasFn( MFn::kMesh )) continue; if (dagPath.hasFn( MFn::kTransform)) continue; if (!dagPath.isVisible()) continue; MFnMesh fnMesh(dagPath); MStringArray UVSets; stat = fnMesh.getUVSetNames( UVSets ); // Get all UVs for the first UV set. MFloatArray u, v; fnMesh.getUVs(u, v, &UVSets[0]); MPointArray vertexList; fnMesh.getPoints(vertexList, MSpace::kObject); MFloatVectorArray meshNormals; fnMesh.getNormals(meshNormals); unsigned instanceNumber = dagPath.instanceNumber(); MObjectArray sets; MObjectArray comps; fnMesh.getConnectedSetsAndMembers( instanceNumber, sets, comps, true ); //printMaterials(dagPath); unsigned int comlength = comps.length(); for (unsigned int compi = 0; compi < comlength; compi++) { SubMesh submesh; MItMeshPolygon itPolygon(dagPath, comps[compi]); unsigned int polyCount = 0; for (; !itPolygon.isDone(); itPolygon.next()) { polyCount++; MIntArray polygonVertices; itPolygon.getVertices(polygonVertices); int count; itPolygon.numTriangles(count); for (; count > -1; count--) { MPointArray nonTweaked; MIntArray triangleVertices; MIntArray localIndex; MStatus status; status = itPolygon.getTriangle(count, nonTweaked, triangleVertices, MSpace::kObject); if (status == MS::kSuccess) { VertexDefinition vertex1; VertexDefinition vertex2; VertexDefinition vertex3; { // vertices int vertexCount = vertexList.length(); { int vertexIndex0 = triangleVertices[0]; MPoint point0 = vertexList[vertexIndex0]; vertex1.vertex.x = (float)point0.x; vertex1.vertex.y = (float)point0.y; vertex1.vertex.z = (float)point0.z; } { int vertexIndex0 = triangleVertices[1]; MPoint point0 = vertexList[vertexIndex0]; vertex2.vertex.x = (float)point0.x; vertex2.vertex.y = (float)point0.y; vertex2.vertex.z = (float)point0.z; } { int vertexIndex0 = triangleVertices[2]; MPoint point0 = vertexList[vertexIndex0]; vertex3.vertex.x = (float)point0.x; vertex3.vertex.y = (float)point0.y; vertex3.vertex.z = (float)point0.z; } } { // normals // Get face-relative vertex indices for this triangle localIndex = GetLocalIndex(polygonVertices, triangleVertices); { int index0 = itPolygon.normalIndex(localIndex[0]); MPoint point0 = meshNormals[index0]; vertex1.normal.x = (float)point0.x; vertex1.normal.y = (float)point0.y; vertex1.normal.z = (float)point0.z; } { int index0 = itPolygon.normalIndex(localIndex[1]); MPoint point0 = meshNormals[index0]; vertex2.normal.x = (float)point0.x; vertex2.normal.y = (float)point0.y; vertex2.normal.z = (float)point0.z; } { int index0 = itPolygon.normalIndex(localIndex[2]); MPoint point0 = meshNormals[index0]; vertex3.normal.x = (float)point0.x; vertex3.normal.y = (float)point0.y; vertex3.normal.z = (float)point0.z; } } { // uvs int uvID[3]; MStatus uvFetchStatus; for (unsigned int vtxInPolygon = 0; vtxInPolygon < 3; vtxInPolygon++) { uvFetchStatus = itPolygon.getUVIndex(localIndex[vtxInPolygon], uvID[vtxInPolygon]); } if (uvFetchStatus == MStatus::kSuccess) { { int index0 = uvID[0]; float uvu = u[index0]; float uvv = v[index0]; vertex1.uv.x = uvu; vertex1.uv.y = 1.0f - uvv; } { int index0 = uvID[1]; float uvu = u[index0]; float uvv = v[index0]; vertex2.uv.x = uvu; vertex2.uv.y = 1.0f - uvv; } { int index0 = uvID[2]; float uvu = u[index0]; float uvv = v[index0]; vertex3.uv.x = uvu; vertex3.uv.y = 1.0f - uvv; // directx } } } submesh.addVertex(vertex1); submesh.addVertex(vertex2); submesh.addVertex(vertex3); } } } { Material material; { MObjectArray shaders; MIntArray indices; fnMesh.getConnectedShaders(0, shaders, indices); unsigned int shaderCount = shaders.length(); MPlugArray connections; MFnDependencyNode shaderGroup(shaders[compi]); MPlug shaderPlug = shaderGroup.findPlug("surfaceShader"); shaderPlug.connectedTo(connections, true, false); for(unsigned int u = 0; u < connections.length(); u++) { if(connections[u].node().hasFn(MFn::kLambert)) { MFnLambertShader lambertShader(connections[u].node()); MPlugArray plugs; lambertShader.findPlug("color").connectedTo(plugs, true, false); for (unsigned int p = 0; p < plugs.length(); p++) { MPlug object = plugs[p]; if (!object.isNull()) { MObject node = object.node(); if (node.hasFn(MFn::kFileTexture)) { MFnDependencyNode* diffuseMapNode = new MFnDependencyNode(node); MPlug filenamePlug = diffuseMapNode->findPlug ("fileTextureName"); MString mayaFileName; filenamePlug.getValue (mayaFileName); std::string diffuseMapFileName = mayaFileName.asChar(); std::string diffuseMapAssetPath = extractAssetPath(diffuseMapFileName); material.addTexture("ColorMap", diffuseMapAssetPath); } } } MColor color = lambertShader.color(); MString materialNameRaw = lambertShader.name(); std::string materialName = materialNameRaw.asChar(); material.setName(materialName); Vector4MaterialParameter* diffuseColorParameter = new Vector4MaterialParameter("DiffuseColor"); diffuseColorParameter->value.x = color.r; diffuseColorParameter->value.y = color.g; diffuseColorParameter->value.z = color.b; diffuseColorParameter->value.w = color.a; material.addParameter(diffuseColorParameter); } } } { if (material.hasTextures()) { material.setEffect("shaders/deferred_render_colormap_normal_depth.cg"); } else { material.setEffect("shaders/deferred_render_color_normal_depth.cg"); } } { FloatMaterialParameter* specularPowerParameter = new FloatMaterialParameter("SpecularPower"); specularPowerParameter->value = 1.0; material.addParameter(specularPowerParameter); } { FloatMaterialParameter* specularIntensityParameter = new FloatMaterialParameter("SpecularIntensity"); specularIntensityParameter->value = 1.0f; material.addParameter(specularIntensityParameter); } { FloatMaterialParameter* diffusePowerParameter = new FloatMaterialParameter("DiffusePower"); diffusePowerParameter->value = 1.0f; material.addParameter(diffusePowerParameter); } submesh.setMaterial(material); } model->addSubMesh(submesh); } } }
MStatus CVstAimCmd::redoIt() { MStatus mStatus; if ( !mStatus ) { setResult( MString( "Cannot parse command line" ) + mStatus.errorString() ); return MS::kFailure; } if ( m_mArgDatabase->isFlagSet( kHelp ) ) { PrintHelp(); } else { // See if there are two object specified MDagPath mDagPath; MSelectionList optSelectionList; // Validate specified items to whole dag nodes { MSelectionList tmpSelectionList; m_mArgDatabase->getObjects( tmpSelectionList ); for ( MItSelectionList sIt( tmpSelectionList, MFn::kDagNode ); !sIt.isDone(); sIt.next() ) { if ( sIt.getDagPath( mDagPath ) ) { optSelectionList.add( mDagPath, MObject::kNullObj, true ); } } } if ( m_mArgDatabase->isFlagSet( "create" ) || optSelectionList.length() >= 2 && m_mArgDatabase->numberOfFlagsUsed() == 0 ) { // Error if there aren't at least two if ( optSelectionList.length() < 2 ) { displayError( GetName() + " needs at least two objects specified or selected when -create is used" ); return MS::kFailure; } // Get name command line arg MString optName; if ( m_mArgDatabase->isFlagSet( "name" ) ) { m_mArgDatabase->getFlagArgument( "name", 0, optName ); } m_undoable = true; m_mDagModifier = new MDagModifier; MObject vstAimObj( m_mDagModifier->MDGModifier::createNode( GetName() ) ); if ( m_mDagModifier->doIt() != MS::kSuccess ) { displayError( MString( "Couldn't create " ) + GetName() + " node" ); m_mDagModifier->undoIt(); delete m_mDagModifier; m_mDagModifier = NULL; m_undoable = false; return MS::kFailure; } m_mDagModifier->renameNode( vstAimObj, optName.length() ? optName : GetName() ); if ( m_mDagModifier->doIt() != MS::kSuccess ) { if ( optName.length() ) { displayWarning( MString( "Couldn't rename newly created vstNode \"" ) + optName + "\"" ); } } // Set options on the newly create vstAim node MFnDependencyNode vstAimFn( vstAimObj ); MPlug sP; MPlug dP; if ( m_mArgDatabase->isFlagSet( kAim ) ) { MVector aim; m_mArgDatabase->getFlagArgument( kAim, 0, aim.x ); m_mArgDatabase->getFlagArgument( kAim, 1, aim.y ); m_mArgDatabase->getFlagArgument( kAim, 2, aim.z ); sP = vstAimFn.findPlug( "aimX" ); sP.setValue( aim.x ); sP = vstAimFn.findPlug( "aimY" ); sP.setValue( aim.y ); sP = vstAimFn.findPlug( "aimZ" ); sP.setValue( aim.z ); } if ( m_mArgDatabase->isFlagSet( kUp ) ) { MVector up; m_mArgDatabase->getFlagArgument( kUp, 0, up.x ); m_mArgDatabase->getFlagArgument( kUp, 1, up.y ); m_mArgDatabase->getFlagArgument( kUp, 2, up.z ); sP = vstAimFn.findPlug( "upX" ); sP.setValue( up.x ); sP = vstAimFn.findPlug( "upY" ); sP.setValue( up.y ); sP = vstAimFn.findPlug( "upZ" ); sP.setValue( up.z ); } // Now connect up the newly created vstAim node MDagPath toAim; optSelectionList.getDagPath( 1, toAim ); const MFnDagNode toAimFn( toAim ); if ( toAim.hasFn( MFn::kJoint ) ) { MPlug joP( toAimFn.findPlug( "jointOrient" ) ); if ( !joP.isNull() ) { MAngle jox, joy, joz; joP.child( 0 ).getValue( jox ); joP.child( 1 ).getValue( joy ); joP.child( 2 ).getValue( joz ); if ( abs( jox.value() ) > FLT_EPSILON || abs( joy.value() ) > FLT_EPSILON || abs( joz.value() ) > FLT_EPSILON ) { mwarn << "Joint orient on node being constrained is non-zero ( " << jox.asDegrees() << " " << joy.asDegrees() << " " << joz.asDegrees() << " ), setting to 0" << std::endl; joP.child( 0 ).setValue( MAngle( 0.0 ) ); joP.child( 1 ).setValue( MAngle( 0.0 ) ); joP.child( 2 ).setValue( MAngle( 0.0 ) ); } } } if ( toAim.hasFn( MFn::kTransform ) ) { MPlug mP( toAimFn.findPlug( "rotateAxis" ) ); if ( !mP.isNull() ) { MAngle rx, ry, rz; mP.child( 0 ).getValue( rx ); mP.child( 1 ).getValue( ry ); mP.child( 2 ).getValue( rz ); if ( abs( rx.value() ) > FLT_EPSILON || abs( ry.value() ) > FLT_EPSILON || abs( rz.value() ) > FLT_EPSILON ) { mwarn << "Rotate Axis on node being constrained is non-zero ( " << rx.asDegrees() << " " << ry.asDegrees() << " " << rz.asDegrees() << " ), setting to 0" << std::endl; mP.child( 0 ).setValue( MAngle( 0.0 ) ); mP.child( 1 ).setValue( MAngle( 0.0 ) ); mP.child( 2 ).setValue( MAngle( 0.0 ) ); } } } MDagPath aimAt; optSelectionList.getDagPath( 0, aimAt ); const MFnDagNode aimAtFn( aimAt ); // toAim.rotateOrder -> vstAim.rotateOrder sP = toAimFn.findPlug( "rotateOrder" ); dP = vstAimFn.findPlug( "rotateOrder" ); m_mDagModifier->connect( sP, dP ); // toAim.translate -> vstAim.translate sP = toAimFn.findPlug( "translate" ); dP = vstAimFn.findPlug( "translate" ); m_mDagModifier->connect( sP, dP ); // toAim.parentMatrix[ instance ] -> vstAim.parentSpace sP = toAimFn.findPlug( "parentMatrix" ); sP = sP.elementByLogicalIndex( toAim.instanceNumber() ); dP = vstAimFn.findPlug( "parentSpace" ); m_mDagModifier->connect( sP, dP ); // aimAt.worldMatrix[ instance ] -> vstAim.aimSpace sP = aimAtFn.findPlug( "worldMatrix" ); sP = sP.elementByLogicalIndex( aimAt.instanceNumber() ); dP = vstAimFn.findPlug( "aimSpace" ); m_mDagModifier->connect( sP, dP ); // vstAim.rotation -> toAim.rotation // These have to be connected individually because Maya plays stupid tricks // with rotateOrder if they aren't sP = vstAimFn.findPlug( "rotateX" ); dP = toAimFn.findPlug( "rotateX" ); m_mDagModifier->connect( sP, dP ); sP = vstAimFn.findPlug( "rotateY" ); dP = toAimFn.findPlug( "rotateY" ); m_mDagModifier->connect( sP, dP ); sP = vstAimFn.findPlug( "rotateZ" ); dP = toAimFn.findPlug( "rotateZ" ); m_mDagModifier->connect( sP, dP ); if ( m_mDagModifier->doIt() != MS::kSuccess ) { displayWarning( MString( GetName() ) + ": Couldn't connect everything when creating" ); } // Save the current selection just in case we want to undo stuff MGlobal::getActiveSelectionList( m_mSelectionList ); MGlobal::select( vstAimObj, MGlobal::kReplaceList ); setResult( vstAimFn.name() ); } else if ( m_mArgDatabase->isFlagSet( "select" ) ) { MSelectionList mSelectionList; MDagPath mDagPath; for ( MItDag dagIt; !dagIt.isDone(); dagIt.next() ) { if ( MFnDependencyNode( dagIt.item() ).typeName() == GetName() ) { dagIt.getPath( mDagPath ); mSelectionList.add( mDagPath, MObject::kNullObj, true ); } } if ( mSelectionList.length() ) { m_undoable = true; // Save the current selection just in case we want to undo stuff MGlobal::getActiveSelectionList( m_mSelectionList ); MGlobal::setActiveSelectionList( mSelectionList, MGlobal::kReplaceList ); } } else { displayError( GetName() + ": No valid operation specified via command line arguments\n" ); } } return MS::kSuccess; }
// Get shading engine // void CScriptedShapeTranslator::GetShapeInstanceShader(MDagPath& dagPath, MFnDependencyNode &shadingEngineNode) { // Get instance shadingEngine shadingEngineNode.setObject(MObject::kNullObj); // First try the usual way MPlug shadingGroupPlug = GetNodeShadingGroup(dagPath.node(), (dagPath.isInstanced() ? dagPath.instanceNumber() : 0)); if (!shadingGroupPlug.isNull()) { shadingEngineNode.setObject(shadingGroupPlug.node()); return; } char buffer[64]; // Check connection from any shadingEngine on shape MStringArray connections; MGlobal::executeCommand("listConnections -s 1 -d 0 -c 1 -type shadingEngine "+dagPath.fullPathName(), connections); MSelectionList sl; if (connections.length() == 0) { // Check for direct surface shader connection MGlobal::executeCommand("listConnections -s 1 -d 0 -c 1 "+dagPath.fullPathName(), connections); for (unsigned int cidx=0; cidx<connections.length(); cidx+=2) { MString srcNode = connections[cidx+1]; // Get node classification, if can find arnold/shader/surface -> got it MStringArray rv; MGlobal::executeCommand("getClassification `nodeType "+srcNode+"`", rv); if (rv.length() > 0 && rv[0].indexW("arnold/shader/surface") != -1) { connections.clear(); MGlobal::executeCommand("listConnections -s 0 -d 1 -c 1 -type shadingEngine "+srcNode, connections); if (connections.length() == 2) { sl.add(connections[1]); } break; } } } else if (connections.length() == 2) { // Single connection, use same shader for all instances sl.add(connections[1]); } else if (connections.length() > 2) { // Many connections, expects the destination plug in shape to be an array // Use instance number as logical index, if this fails, use first shadingEngine in list bool found = false; sprintf(buffer, "[%d]", dagPath.instanceNumber()); MString iidx = buffer; for (unsigned int cidx = 0; cidx < connections.length(); cidx += 2) { MString conn = connections[cidx]; if (conn.length() < iidx.length()) { continue; } if (conn.substring(conn.length() - iidx.length(), conn.length() - 1) != iidx) { continue; } sl.add(connections[cidx+1]); found = true; break; } if (!found) { MGlobal::displayWarning("[mtoaScriptedTranslators] Instance shader plug not found, use first found shadingEngine \"" + connections[1] + "\""); sl.add(connections[1]); } } if (sl.length() == 1) { MObject shadingEngineObj; if (sl.getDependNode(0, shadingEngineObj) == MS::kSuccess && shadingEngineObj.apiType() == MFn::kShadingEngine) { shadingEngineNode.setObject(shadingEngineObj); } else { if (shadingEngineObj != MObject::kNullObj) { MFnDependencyNode dn(shadingEngineObj); MGlobal::displayWarning("[mtoaScriptedTranslators] Not a shading engine \"" + dn.name() + "\""); } } } }
MStatus CXRayObjectExport::ExportPart(CEditableObject* O, MDagPath& mdagPath, MObject& mComponent) { MStatus stat = MS::kSuccess; MSpace::Space space = MSpace::kWorld; MFnMesh fnMesh( mdagPath, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MFnMesh initialization.\n"); return MS::kFailure; } MString mdagPathNodeName = fnMesh.name(); MFnDagNode dagNode1(mdagPath); u32 pc = dagNode1.parentCount(); for(u32 ip=0;ip<pc;++ip) { MObject object_parent = dagNode1.parent(ip, &stat); if(object_parent.hasFn(MFn::kTransform)) { MFnTransform parent_transform(object_parent,&stat); if ( MS::kSuccess == stat) { mdagPathNodeName = parent_transform.name(); break; } } } MItMeshPolygon meshPoly( mdagPath, mComponent, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MItMeshPolygon initialization.\n"); return MS::kFailure; } MItMeshVertex vtxIter( mdagPath, mComponent, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MItMeshVertex initialization.\n"); return MS::kFailure; } // If the shape is instanced then we need to determine which // instance this path refers to. // int instanceNum = 0; if (mdagPath.isInstanced()) instanceNum = mdagPath.instanceNumber(); // Get a list of all shaders attached to this mesh MObjectArray rgShaders; MIntArray texMap; MStatus status; status = fnMesh.getConnectedShaders (instanceNum, rgShaders, texMap); if (status == MStatus::kFailure) { Log("! Unable to load shaders for mesh"); return (MStatus::kFailure); } XRShaderDataVec xr_data; { for ( int i=0; i<(int)rgShaders.length(); i++ ) { MObject shader = rgShaders[i]; xr_data.push_back(SXRShaderData()); SXRShaderData& D = xr_data.back(); status = parseShader(shader, D); if (status == MStatus::kFailure) { status.perror ("Unable to retrieve filename of texture"); continue; } } } CEditableMesh* MESH = new CEditableMesh(O); MESH->SetName(mdagPathNodeName.asChar()); O->AppendMesh(MESH); int objectIdx, length; // Find i such that objectGroupsTablePtr[i] corresponds to the // object node pointed to by mdagPath length = objectNodeNamesArray.length(); { for( int i=0; i<length; i++ ) { if( objectNodeNamesArray[i] == mdagPathNodeName ) { objectIdx = i; break; } } } // Reserve uv table { VMapVec& _vmaps = MESH->m_VMaps; _vmaps.resize (1); st_VMap*& VM = _vmaps.back(); VM = new st_VMap("Texture",vmtUV,false); } // write faces { using FaceVec = xr_vector<st_Face>; using FaceIt = FaceVec::iterator; VMapVec& _vmaps = MESH->m_VMaps; SurfFaces& _surf_faces = MESH->m_SurfFaces; VMRefsVec& _vmrefs = MESH->m_VMRefs; // temp variables FvectorVec _points; FaceVec _faces; U32Vec _sgs; int f_cnt = fnMesh.numPolygons(); _sgs.reserve (f_cnt); _faces.reserve (f_cnt); _vmrefs.reserve (f_cnt*3); // int lastSmoothingGroup = INITIALIZE_SMOOTHING; MPointArray rgpt; MIntArray rgint; PtLookupMap ptMap; CSurface* surf = 0; for ( ; !meshPoly.isDone(); meshPoly.next()){ // Write out the smoothing group that this polygon belongs to // We only write out the smoothing group if it is different // from the last polygon. // int compIdx = meshPoly.index(); int smoothingGroup = polySmoothingGroups[ compIdx ]; // for each polygon, first setup the reverse mapping // between object-relative vertex indices and face-relative // vertex indices ptMap.clear(); for (int i=0; i<(int)meshPoly.polygonVertexCount(); i++) ptMap.insert (PtLookupMap::value_type(meshPoly.vertexIndex(i), i) ); // verify polygon zero area if (meshPoly.zeroArea()){ status = MS::kFailure; Log("! polygon have zero area:",meshPoly.index()); return status; } // verify polygon zero UV area /* if (meshPoly.zeroUVArea()){ status = MS::kFailure; Log("! polygon have zero UV area:",meshPoly.index()); return status; } */ // verify polygon has UV information if (!meshPoly.hasUVs (&status)) { status = MS::kFailure; Log("! polygon is missing UV information:",meshPoly.index()); return status; } int cTri; // now iterate through each triangle on this polygon and create a triangle object in our list status = meshPoly.numTriangles (cTri); if (!status) { Log("! can't getting triangle count"); return status; } for (int i=0; i < cTri; i++) { // for each triangle, first get the triangle data rgpt.clear();//triangle vertices rgint.clear();//triangle vertex indices // triangles that come from object are retrieved in world space status = meshPoly.getTriangle (i, rgpt, rgint, MSpace::kWorld); if (!status) { Log("! can't getting triangle for mesh poly"); return status; } if ((rgpt.length() != 3) || (rgint.length() != 3)) { Msg("! 3 points not returned for triangle"); return MS::kFailure; } // Write out vertex/uv index information // R_ASSERT2(fnMesh.numUVs()>0,"Can't find uvmaps."); _faces.push_back(st_Face()); _sgs.push_back(smoothingGroup); //set_smooth set_smoth_flags( _sgs.back(), rgint ); st_Face& f_it = _faces.back(); for ( int vtx=0; vtx<3; vtx++ ) { // get face-relative vertex PtLookupMap::iterator mapIt; int vtLocal, vtUV; int vt = rgint[vtx]; mapIt = ptMap.find(vt); Fvector2 uv; if (mapIt == ptMap.end()){ Msg("! Can't find local index."); return MS::kFailure; } vtLocal = (*mapIt).second; status = meshPoly.getUVIndex (vtLocal, vtUV, uv.x, uv.y); if (!status) { Msg("! error getting UV Index for local vertex '%d' and object vertex '%d'",vtLocal,vt); return status; } // flip v-part uv.y=1.f-uv.y; f_it.pv[2-vtx].pindex = AppendVertex(_points,rgpt[vtx]); f_it.pv[2-vtx].vmref = _vmrefs.size(); _vmrefs.push_back (st_VMapPtLst()); st_VMapPtLst& vm_lst = _vmrefs.back(); vm_lst.count = 1; vm_lst.pts = xr_alloc<st_VMapPt>(vm_lst.count); vm_lst.pts[0].vmap_index= 0; vm_lst.pts[0].index = AppendUV(_vmaps.back(),uv); } // out face material int iTexture = texMap[meshPoly.index()]; if (iTexture<0) xrDebug::Fatal(DEBUG_INFO,"Can't find material for polygon: %d",meshPoly.index()); SXRShaderData& D= xr_data[iTexture]; int compIdx = meshPoly.index(); surf = MESH->Parent()->CreateSurface(getMaterialName(mdagPath, compIdx, objectIdx),D); if (!surf) return MStatus::kFailure; _surf_faces[surf].push_back(_faces.size()-1); } } { // copy from temp MESH->m_VertCount = _points.size(); MESH->m_FaceCount = _faces.size(); MESH->m_Vertices = xr_alloc<Fvector>(MESH->m_VertCount); Memory.mem_copy (MESH->m_Vertices,&*_points.begin(),MESH->m_VertCount*sizeof(Fvector)); MESH->m_Faces = xr_alloc<st_Face>(MESH->m_FaceCount); Memory.mem_copy (MESH->m_Faces,&*_faces.begin(),MESH->m_FaceCount*sizeof(st_Face)); MESH->m_SmoothGroups = xr_alloc<u32>(MESH->m_FaceCount); Memory.mem_copy (MESH->m_SmoothGroups,&*_sgs.begin(),MESH->m_FaceCount*sizeof(u32)); MESH->RecomputeBBox (); } if ((MESH->GetVertexCount()<4)||(MESH->GetFaceCount()<2)) { Log ("! Invalid mesh: '%s'. Faces<2 or Verts<4",*MESH->Name()); return MS::kFailure; } } return stat; }
//--------------------------------------------------------------- void LightExporter::exportLights ( SceneElement* sceneElement ) { // If we have a external reference, we don't need to export the data here. if ( !sceneElement->getIsLocal() ) return; if ( !sceneElement->getIsExportNode () ) return; // Check if it is a light. SceneElement::Type sceneElementType = sceneElement->getType(); if ( sceneElementType == SceneElement::LIGHT ) { // Get the current dag path MDagPath dagPath = sceneElement->getPath(); // Check if the current scene element isn't already exported. SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); if ( sceneGraph->findExportedElement ( dagPath ) ) return; // Check if the current element is an instance. // We don't need to export instances, because we export the original instanced element. bool isInstance = ( dagPath.isInstanced() && dagPath.instanceNumber() > 0 ); // If the original instanced element isn't already exported, we have to export it now. if ( isInstance ) { // Get the original instanced element. MDagPath instancedPath; dagPath.getPath ( instancedPath, 0 ); // Check if the original instanced element is already exported. SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); SceneElement* exportedElement = sceneGraph->findExportedElement ( instancedPath ); if (exportedElement == 0) { // Export the original instanced element and push it in the exported scene graph. if (exportLight(instancedPath)) { SceneElement* instancedSceneElement = sceneGraph->findElement(instancedPath); SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); sceneGraph->addExportedElement(instancedSceneElement); } } } else { // Export the element and push it in the exported scene graph. if ( exportLight ( dagPath ) ) { SceneGraph* sceneGraph = mDocumentExporter->getSceneGraph(); sceneGraph->addExportedElement( sceneElement ); } } } // Recursive call for all the child elements for ( uint i=0; i<sceneElement->getChildCount(); ++i ) { SceneElement* childElement = sceneElement->getChild ( i ); exportLights ( childElement ); } }
MStatus closestPointOnCurveCommand::redoIt() { // DOUBLE-CHECK TO MAKE SURE THERE'S A SPECIFIED OBJECT TO EVALUATE ON: if (sList.length() == 0) { MStatus stat; MString msg = MStringResource::getString(kNoValidObject, stat); displayError(msg); return MStatus::kFailure; } // RETRIEVE THE SPECIFIED OBJECT AS A DAGPATH: MDagPath curveDagPath; sList.getDagPath(0, curveDagPath); // CHECK FOR INVALID NODE-TYPE INPUT WHEN SPECIFIED/SELECTED NODE IS *NOT* A "CURVE" NOR "CURVE TRANSFORM": if (!curveDagPath.node().hasFn(MFn::kNurbsCurve) && !(curveDagPath.node().hasFn(MFn::kTransform) && curveDagPath.hasFn(MFn::kNurbsCurve))) { MStatus stat; MString msg; // Use format to place variable string into message MString msgFmt = MStringResource::getString(kInvalidType, stat); MStringArray selectionStrings; sList.getSelectionStrings(0, selectionStrings); msg.format(msgFmt, selectionStrings[0]); displayError(msg); return MStatus::kFailure; } // WHEN COMMAND *NOT* IN "QUERY MODE" (I.E. "CREATION MODE"), CREATE AND CONNECT A "closestPointOnCurve" NODE AND RETURN ITS NODE NAME: if (!queryFlagSet) { // CREATE THE NODE: MFnDependencyNode depNodeFn; if (closestPointOnCurveNodeName == "") depNodeFn.create("closestPointOnCurve"); else depNodeFn.create("closestPointOnCurve", closestPointOnCurveNodeName); closestPointOnCurveNodeName = depNodeFn.name(); // SET THE ".inPosition" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (inPositionFlagSet) { MPlug inPositionXPlug = depNodeFn.findPlug("inPositionX"); inPositionXPlug.setValue(inPosition.x); MPlug inPositionYPlug = depNodeFn.findPlug("inPositionY"); inPositionYPlug.setValue(inPosition.y); MPlug inPositionZPlug = depNodeFn.findPlug("inPositionZ"); inPositionZPlug.setValue(inPosition.z); } // MAKE SOME ADJUSTMENTS WHEN THE SPECIFIED NODE IS A "TRANSFORM" OF A CURVE SHAPE: unsigned instanceNumber=0; if (curveDagPath.node().hasFn(MFn::kTransform)) { // EXTEND THE DAGPATH TO ITS CURVE "SHAPE" NODE: curveDagPath.extendToShape(); // TRANSFORMS ARE *NOT* NECESSARILY THE "FIRST" INSTANCE TRANSFORM OF A CURVE SHAPE: instanceNumber = curveDagPath.instanceNumber(); } // CONNECT THE NODES: MPlug worldCurvePlug, inCurvePlug; inCurvePlug = depNodeFn.findPlug("inCurve"); depNodeFn.setObject(curveDagPath.node()); worldCurvePlug = depNodeFn.findPlug("worldSpace"); worldCurvePlug = worldCurvePlug.elementByLogicalIndex(instanceNumber); MDGModifier dgModifier; dgModifier.connect(worldCurvePlug, inCurvePlug); dgModifier.doIt(); // SET COMMAND RESULT TO BE NEW NODE'S NAME, AND RETURN: setResult(closestPointOnCurveNodeName); return MStatus::kSuccess; } // OTHERWISE, WE'RE IN THE COMMAND'S "QUERY MODE": else { // COMPUTE THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE, USING THE *FIRST* INSTANCE TRANSFORM WHEN CURVE IS SPECIFIED AS A "SHAPE": MPoint position; MVector normal, tangent; double paramU, distance; closestTangentUAndDistance(curveDagPath, inPosition, position, normal, tangent, paramU, distance); // WHEN NO QUERYABLE FLAG IS SPECIFIED, INDICATE AN ERROR: if (!positionFlagSet && !normalFlagSet && !tangentFlagSet && !paramUFlagSet && !distanceFlagSet) { MStatus stat; MString msg = MStringResource::getString(kNoQueryFlag, stat); displayError(msg); return MStatus::kFailure; } // WHEN JUST THE "DISTANCE" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND: else if (distanceFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || paramUFlagSet)) setResult(distance); // WHEN JUST THE "PARAMETER-U" IS QUERIED, RETURN A SINGLE "FLOAT" INSTEAD OF AN ENTIRE FLOAT ARRAY FROM THE COMMAND: else if (paramUFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || distanceFlagSet)) setResult(paramU); // OTHERWISE, SET THE RETURN VALUE OF THE COMMAND'S RESULT TO A "COMPOSITE ARRAY OF FLOATS": else { // HOLDS FLOAT ARRAY RESULT: MDoubleArray floatArrayResult; // APPEND THE RESULTS OF THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE VALUES TO THE FLOAT ARRAY RESULT: if (positionFlagSet) { floatArrayResult.append(position.x); floatArrayResult.append(position.y); floatArrayResult.append(position.z); } if (normalFlagSet) { floatArrayResult.append(normal.x); floatArrayResult.append(normal.y); floatArrayResult.append(normal.z); } if (tangentFlagSet) { floatArrayResult.append(tangent.x); floatArrayResult.append(tangent.y); floatArrayResult.append(tangent.z); } if (paramUFlagSet) floatArrayResult.append(paramU); if (distanceFlagSet) floatArrayResult.append(distance); // FINALLY, SET THE COMMAND'S RESULT: setResult(floatArrayResult); } return MStatus::kSuccess; } }
bool DX11ViewportRenderer::drawSurface( const MDagPath &dagPath, bool active, bool templated) { bool drewSurface = false; if ( !dagPath.hasFn( MFn::kMesh )) { MMatrix matrix = dagPath.inclusiveMatrix(); MFnDagNode dagNode(dagPath); MBoundingBox box = dagNode.boundingBox(); float color[3] = {0.6f, 0.3f, 0.0f}; if (active) { color[0] = 1.0f; color[1] = 1.0f; color[2] = 1.0f; } else if (templated) { color[0] = 1.0f; color[1] = 0.686f; color[2] = 0.686f; } drawBounds( matrix, box, color); return true; } if ( dagPath.hasFn( MFn::kMesh )) { MMatrix matrix = dagPath.inclusiveMatrix(); MFnDagNode dagNode(dagPath); // Look for any hardware shaders which can draw D3D first. // bool drewWithHwShader = false; { MFnMesh fnMesh(dagPath); MObjectArray sets; MObjectArray comps; unsigned int instanceNum = dagPath.instanceNumber(); if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true)) MGlobal::displayError("ERROR : MFnMesh::getConnectedSetsAndMembers"); for ( unsigned i=0; i<sets.length(); i++ ) { MObject set = sets[i]; MObject comp = comps[i]; MStatus status; MFnSet fnSet( set, &status ); if (status == MS::kFailure) { MGlobal::displayError("ERROR: MFnSet::MFnSet"); continue; } MObject shaderNode = findShader(set); if (shaderNode != MObject::kNullObj) { MPxHardwareShader * hwShader = MPxHardwareShader::getHardwareShaderPtr( shaderNode ); if (hwShader) { const MRenderProfile & profile = hwShader->profile(); if (profile.hasRenderer( MRenderProfile::kMayaD3D)) { // Render a Maya D3D hw shader here.... //printf("Found a D3D hw shader\n"); //drewWithHwShader = true; } } } } } // Get the geometry buffers for this bad boy and render them D3DGeometry* Geometry = m_resourceManager.getGeometry( dagPath, m_pD3DDevice); if( Geometry) { // Transform from object to world space // XMMATRIX objectToWorld = XMMATRIX ( (float)matrix.matrix[0][0], (float)matrix.matrix[0][1], (float)matrix.matrix[0][2], (float)matrix.matrix[0][3], (float)matrix.matrix[1][0], (float)matrix.matrix[1][1], (float)matrix.matrix[1][2], (float)matrix.matrix[1][3], (float)matrix.matrix[2][0], (float)matrix.matrix[2][1], (float)matrix.matrix[2][2], (float)matrix.matrix[2][3], (float)matrix.matrix[3][0], (float)matrix.matrix[3][1], (float)matrix.matrix[3][2], (float)matrix.matrix[3][3] ); FixedFunctionConstants cb; if (!drewWithHwShader) { // Get material properties for shader associated with mesh // // 1. Try to draw with the sample internal programmable shader bool drewGeometryWithShader = false; // 2. Draw with fixed function shader if (!drewGeometryWithShader) { // Set up a default material, just in case there is none. // float diffuse[3]; if (active) { if (templated) { m_pD3DDeviceCtx->RSSetState( m_pWireframeRS ); diffuse[0] = 1.0f; diffuse[1] = 0.686f; diffuse[2] = 0.686f; } else { m_pD3DDeviceCtx->RSSetState( m_pNormalRS ); diffuse[0] = 0.6f; diffuse[1] = 0.6f; diffuse[2] = 0.6f; } } else { if (templated) { m_pD3DDeviceCtx->RSSetState( m_pWireframeRS ); diffuse[0] = 1.0f; diffuse[1] = 0.686f; diffuse[2] = 0.686f; } else { m_pD3DDeviceCtx->RSSetState( m_pNormalRS ); diffuse[0] = 0.5f; diffuse[1] = 0.5f; diffuse[2] = 0.5f; } } // Set constant buffer XMVECTOR det; cb.wvIT = XMMatrixInverse( &det, objectToWorld * m_currentViewMatrix ); cb.wvp = XMMatrixTranspose( objectToWorld * m_currentViewMatrix * m_currentProjectionMatrix ); cb.wv = XMMatrixTranspose( objectToWorld * m_currentViewMatrix ); cb.lightDir = XMFLOAT4( 0.0f, 0.0f, 1.0f, 0.0f ); cb.lightColor = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f ); cb.ambientLight = XMFLOAT4( 0.2f, 0.2f, 0.2f, 0.0f ); cb.diffuseMaterial = XMFLOAT4( diffuse[0], diffuse[1], diffuse[2], 0.0f ); cb.specularColor = XMFLOAT4( 0.2f, 0.2f, 0.2f, 0.0f ); cb.diffuseCoeff = 1.0f; cb.shininess = 16.0f; cb.transparency = 1.0f; m_pD3DDeviceCtx->UpdateSubresource( m_pFixedFunctionConstantBuffer, 0, NULL, &cb, 0, 0 ); // get shader SurfaceEffectItemList::const_iterator it = m_resourceManager.getSurfaceEffectItemList().find( "Maya_fixedFunction" ); if ( it == m_resourceManager.getSurfaceEffectItemList().end() ) return false; const SurfaceEffectItem* sei = it->second; // bind shaders m_pD3DDeviceCtx->VSSetShader( sei->fVertexShader, NULL, 0 ); m_pD3DDeviceCtx->VSSetConstantBuffers( 0, 1, &m_pFixedFunctionConstantBuffer ); m_pD3DDeviceCtx->IASetInputLayout( sei->fInputLayout ); m_pD3DDeviceCtx->PSSetShader( sei->fPixelShader, NULL, 0 ); m_pD3DDeviceCtx->PSSetConstantBuffers( 0, 1, &m_pFixedFunctionConstantBuffer ); Geometry->Render( m_pD3DDeviceCtx ); drewSurface = true; } } // Draw wireframe on top // if ( drewSurface && active ) { bool drawActiveWithBounds = false; if (drawActiveWithBounds) { MBoundingBox box = dagNode.boundingBox(); float color[3] = {1.0f, 1.0f, 1.0f}; drawBounds( matrix, box, color ); } else { cb.lightColor = XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ); cb.ambientLight = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f ); cb.diffuseMaterial = XMFLOAT4( 1.0f, 1.0f, 1.0f, 0.0f ); cb.specularColor = XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ); m_pD3DDeviceCtx->UpdateSubresource( m_pFixedFunctionConstantBuffer, 0, NULL, &cb, 0, 0 ); m_pD3DDeviceCtx->RSSetState( m_pWireframeRS ); Geometry->Render( m_pD3DDeviceCtx ); } } } // If Geometry } return drewSurface; }
MStatus pointOnMeshCommand::redoIt() { // WHEN NO MESH IS SPECIFIED IN THE COMMAND, GET THE FIRST SELECTED MESH FROM THE SELECTION LIST: MSelectionList sList; if (meshNodeName=="") { MGlobal::getActiveSelectionList(sList); if (sList.length()==0) { displayError("No mesh or mesh transform specified!"); return MS::kFailure; } } // OTHERWISE, USE THE NODE NAME SPECIFIED IN THE LAST ARGUMENT OF THE COMMAND: else if (sList.add(meshNodeName) == MS::kInvalidParameter) { displayError("Specified mesh does not exist!"); return MS::kFailure; } // RETRIEVE THE FIRST ITEM FROM THE SELECTION LIST: MDagPath meshDagPath; sList.getDagPath(0, meshDagPath); // CREATE AND CONNECT A "pointOnMeshInfo" NODE, OR GET THE POINT AND NORMAL ACCORDING TO // WHETHER THE "-position/-p" AND/OR "-normal/-nr" FLAGS WERE SPECIFIED, AND WHETHER THE MESH // "SHAPE" OR ITS "TRANSFORM" WAS SPECIFIED/SELECTED: MPoint point; MVector normal; // WHEN THE SPECIFIED NODE IS THE MESH "SHAPE": if (meshDagPath.node().hasFn(MFn::kMesh)) { // WHEN NEITHER "-position/-p" NOR "-normal/-nr" ARE SPECIFIED, CREATE AND CONNECT A "pointOnMeshInfo" NODE AND RETURN ITS NODE NAME: if (!positionSpecified && !normalSpecified) { // CREATE THE NODE: nodeCreated = true; MFnDependencyNode depNodeFn; if (pointOnMeshInfoName == "") depNodeFn.create("pointOnMeshInfo"); else depNodeFn.create("pointOnMeshInfo", pointOnMeshInfoName); pointOnMeshInfoName = depNodeFn.name(); // SET THE ".faceIndex" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (faceIndexSpecified) { MPlug faceIndexPlug = depNodeFn.findPlug("faceIndex"); faceIndexPlug.setValue(faceIndex); } // SET THE ".relative" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (relativeSpecified) { MPlug relativePlug = depNodeFn.findPlug("relative"); relativePlug.setValue(relative); } // SET THE ".parameterU" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterUSpecified) { MPlug parameterUPlug = depNodeFn.findPlug("parameterU"); parameterUPlug.setValue(parameterU); } // SET THE ".parameterV" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterVSpecified) { MPlug parameterVPlug = depNodeFn.findPlug("parameterV"); parameterVPlug.setValue(parameterV); } // CONNECT THE NODES: MPlug worldMeshPlug, inMeshPlug; inMeshPlug = depNodeFn.findPlug("inMesh"); depNodeFn.setObject(meshDagPath.node()); worldMeshPlug = depNodeFn.findPlug("worldMesh"); worldMeshPlug = worldMeshPlug.elementByLogicalIndex(0); // ASSUME THE *FIRST* INSTANCE OF THE MESH IS REQUESTED FOR MESH SHAPES. MDGModifier dgModifier; dgModifier.connect(worldMeshPlug, inMeshPlug); dgModifier.doIt(); // SET COMMAND RESULT AND RETURN: setResult(pointOnMeshInfoName); return MStatus::kSuccess; } // OTHERWISE, COMPUTE THE POINT-POSITION AND NORMAL, USING THE *FIRST* INSTANCE'S TRANSFORM: else getPointAndNormal(meshDagPath, faceIndex, relative, parameterU, parameterV, point, normal); } // WHEN THE SPECIFIED NODE IS A "TRANSFORM" OF A MESH SHAPE: else if (meshDagPath.node().hasFn(MFn::kTransform) && meshDagPath.hasFn(MFn::kMesh)) { // WHEN NEITHER "-position/-p" NOR "-normal/-nr" ARE SPECIFIED, CREATE AND CONNECT A "pointOnMeshInfo" NODE AND RETURN ITS NODE NAME: if (!positionSpecified && !normalSpecified) { // CREATE THE NODE: nodeCreated = true; meshDagPath.extendToShape(); MFnDependencyNode depNodeFn; if (pointOnMeshInfoName == "") depNodeFn.create("pointOnMeshInfo"); else depNodeFn.create("pointOnMeshInfo", pointOnMeshInfoName); pointOnMeshInfoName = depNodeFn.name(); // SET THE ".faceIndex" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (faceIndexSpecified) { MPlug faceIndexPlug = depNodeFn.findPlug("faceIndex"); faceIndexPlug.setValue(faceIndex); } // SET THE ".relative" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (relativeSpecified) { MPlug relativePlug = depNodeFn.findPlug("relative"); relativePlug.setValue(relative); } // SET THE ".parameterU" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterUSpecified) { MPlug parameterUPlug = depNodeFn.findPlug("parameterU"); parameterUPlug.setValue(parameterU); } // SET THE ".parameterV" ATTRIBUTE, IF SPECIFIED IN THE COMMAND: if (parameterVSpecified) { MPlug parameterVPlug = depNodeFn.findPlug("parameterV"); parameterVPlug.setValue(parameterV); } // CONNECT THE NODES: MPlug worldMeshPlug, inMeshPlug; inMeshPlug = depNodeFn.findPlug("inMesh"); depNodeFn.setObject(meshDagPath.node()); worldMeshPlug = depNodeFn.findPlug("worldMesh"); worldMeshPlug = worldMeshPlug.elementByLogicalIndex(meshDagPath.instanceNumber()); MDGModifier dgModifier; dgModifier.connect(worldMeshPlug, inMeshPlug); dgModifier.doIt(); // SET COMMAND RESULT AND RETURN: setResult(pointOnMeshInfoName); return MStatus::kSuccess; } // OTHERWISE, COMPUTE THE POINT-POSITION AND NORMAL: else getPointAndNormal(meshDagPath, faceIndex, relative, parameterU, parameterV, point, normal); } // INVALID INPUT WHEN SPECIFIED/SELECTED NODE IS NOT A MESH NOR TRANSFORM: else { displayError("Invalid type! Only a mesh or its transform can be specified!"); return MStatus::kFailure; } // SET THE RETURN VALUES OF THE COMMAND'S RESULT TO BE AN ARRAY OF FLOATS OUTPUTTING THE POSITION AND/OR NORMAL: MDoubleArray result; if (positionSpecified) { result.append(point.x); result.append(point.y); result.append(point.z); } if (normalSpecified) { result.append(normal.x); result.append(normal.y); result.append(normal.z); } setResult(result); return MStatus::kSuccess; }