//--------------------------------------------------------------------------- void componentConverter::getConnectedFaces(MIntArray& edgeIDs, MIntArray& result ) //--------------------------------------------------------------------------- { MItMeshEdge edgeIter(mesh); MIntArray connectedFaces; result.clear(); unsigned int l = edgeIDs.length(); for(unsigned int i = 0; i < l; i++) { edgeIter.setIndex(edgeIDs[i],tmp); edgeIter.getConnectedFaces(connectedFaces); for(unsigned int x = 0; x < connectedFaces.length();x++) { result.append(connectedFaces[x]); } } }
static float calculateAverageGraphEdgeLength(const TileMap::NavGraph& navGraph) { float totalLength = 0; int numEdgesCounted = 0; TileMap::NavGraph::ConstNodeIterator nodeIter(navGraph); for (const TileMap::NavGraph::Node* pNode = nodeIter.begin(); !nodeIter.end(); pNode = nodeIter.next()) { TileMap::NavGraph::ConstEdgeIterator edgeIter(navGraph, pNode->getIndex()); for (const TileMap::NavGraph::Edge* pEdge = edgeIter.begin(); !edgeIter.end(); pEdge = edgeIter.next()) { ++numEdgesCounted; totalLength += distance(navGraph.getNode(pEdge->getFrom()).getPosition(), navGraph.getNode(pEdge->getTo()).getPosition()); } } return totalLength / numEdgesCounted; }
MStatus SelectRingToolCmd2::redoIt() { //MGlobal::displayInfo( "redoIt" ); MItMeshPolygon polyIter( selEdgeObject ); MItMeshEdge edgeIter( selEdgeObject, selEdgeComp ); //MFnSingleIndexedComponent si( selEdgeComp ); //MGlobal::displayInfo( MString("doing stuff on ") + selEdgeObject.fullPathName() + " " + si.element(0) ); MFnSingleIndexedComponent indexedCompFn; MObject newComponent; MSelectionList newSel; MIntArray edges; MIntArray faces; unsigned int i; const int initEdgeIndex = edgeIter.index(); int initFaceIndex; int prevIndex, lastIndex; int faceIndex, edgeIndex; int newFaceIndex, newEdgeIndex; int nInitEdgeVisits; MIntArray remainFaces; MIntArray remainEdges; if( selType == RING ) { nInitEdgeVisits = 0; // Push the face+edge combo on both sides // of the current edge onto the stack edgeIter.getConnectedFaces( faces ); if( faces.length() > 1 ) { remainFaces.append( faces[1] ); remainEdges.append( initEdgeIndex ); } initFaceIndex = faces[0]; remainFaces.append( initFaceIndex ); remainEdges.append( initEdgeIndex ); while( remainFaces.length() ) { // Pop the face and edge indices lastIndex = remainFaces.length() - 1; faceIndex = remainFaces[ lastIndex ]; edgeIndex = remainEdges[ lastIndex ]; remainFaces.remove( lastIndex ); remainEdges.remove( lastIndex ); // If the current edge the initial edge if( faceIndex == initFaceIndex && edgeIndex == initEdgeIndex ) { // Reached back to the initial edge, so the loop is closed if( ++nInitEdgeVisits == 2 ) break; } // Add edge to the new selection list if( selEdges ) { newComponent = indexedCompFn.create( MFn::kMeshEdgeComponent ); indexedCompFn.addElement( edgeIndex ); newSel.add( selEdgeObject, newComponent ); } // Add vertices to the new selection list if( selVertices ) { newComponent = indexedCompFn.create( MFn::kMeshVertComponent ); edgeIter.setIndex( edgeIndex, prevIndex ); indexedCompFn.addElement( edgeIter.index(0) ); indexedCompFn.addElement( edgeIter.index(1) ); newSel.add( selEdgeObject, newComponent ); } if( faceIndex != -1 ) // Not a boundary edge { // Add face to the new selection list if( selFaces ) { newComponent = indexedCompFn.create( MFn::kMeshPolygonComponent ); indexedCompFn.addElement( faceIndex ); newSel.add( selEdgeObject, newComponent ); } // Get edge opposite the current edge // newEdgeIndex = navigateFace( selEdgeObject, faceIndex, edgeIndex, OPPOSITE ); // Get the face on the other side of the opposite edge // edgeIter.setIndex( newEdgeIndex, prevIndex ); edgeIter.getConnectedFaces( faces ); newFaceIndex = -1; // Initialize to a boundary edge if( faces.length() > 1 ) newFaceIndex = (faceIndex == faces[0]) ? faces[1] : faces[0]; // Push face and edge onto list remainFaces.append( newFaceIndex ); remainEdges.append( newEdgeIndex ); } } } else // Ring { int reflEdgeIndex; int newReflEdgeIndex; int initReflEdgeIndex; MIntArray remainReflEdges; nInitEdgeVisits = 0; // Push the face+edge+reflect combo on both sides // of the current edge onto the stack //edgeIter.setIndex( initEdgeIndex, prevIndex ); edgeIter.getConnectedFaces( faces ); initFaceIndex = faces[0]; for( i=0; i < 2; i++ ) { remainFaces.append( initFaceIndex ); remainEdges.append( initEdgeIndex ); remainReflEdges.append( navigateFace( selEdgeObject, initFaceIndex, initEdgeIndex, (i == 0) ? PREVIOUS : NEXT ) ); } initReflEdgeIndex = remainReflEdges[1]; while( remainFaces.length() ) { // Pop the face, edge, and reflEdge indices lastIndex = remainFaces.length() - 1; faceIndex = remainFaces[ lastIndex ]; edgeIndex = remainEdges[ lastIndex ]; reflEdgeIndex = remainReflEdges[ lastIndex ]; remainFaces.remove( lastIndex ); remainEdges.remove( lastIndex ); remainReflEdges.remove( lastIndex ); //MGlobal::displayInfo( MString("Face: ") + faceIndex + " edge: " + edgeIndex + " reflEdgeIndex: " + reflEdgeIndex ); // If the current edge the initial edge if( faceIndex == initFaceIndex && edgeIndex == initEdgeIndex && reflEdgeIndex == initReflEdgeIndex ) { // Reached back to the initial edge, so the ring is closed if( ++nInitEdgeVisits == 2 ) break; } // Add edge to the new selection list if( selEdges ) { newComponent = indexedCompFn.create( MFn::kMeshEdgeComponent ); indexedCompFn.addElement( edgeIndex ); newSel.add( selEdgeObject, newComponent ); } // Add vertices to the new selection list if( selVertices ) { newComponent = indexedCompFn.create( MFn::kMeshVertComponent ); edgeIter.setIndex( edgeIndex, prevIndex ); indexedCompFn.addElement( edgeIter.index(0) ); indexedCompFn.addElement( edgeIter.index(1) ); newSel.add( selEdgeObject, newComponent ); } // Add face to the new selection list if( selFaces ) { newComponent = indexedCompFn.create( MFn::kMeshPolygonComponent ); indexedCompFn.addElement( faceIndex ); newSel.add( selEdgeObject, newComponent ); } // Get the face on opposite side of reflEdge edgeIter.setIndex( reflEdgeIndex, prevIndex ); edgeIter.getConnectedFaces( faces ); // Only if there are two faces can their be an opposite face if( faces.length() > 1 ) { newFaceIndex = (faceIndex == faces[0]) ? faces[1] : faces[0]; int edgePrev = navigateFace( selEdgeObject, newFaceIndex, reflEdgeIndex, PREVIOUS ); int edgeNext = navigateFace( selEdgeObject, newFaceIndex, reflEdgeIndex, NEXT ); // Determine which of the edges touches the original edge // edgeIter.setIndex( edgeIndex, prevIndex ); if( edgeIter.connectedToEdge( edgePrev ) ) { newEdgeIndex = edgePrev; newReflEdgeIndex = navigateFace( selEdgeObject, newFaceIndex, newEdgeIndex, PREVIOUS ); } else { newEdgeIndex = edgeNext; newReflEdgeIndex = navigateFace( selEdgeObject, newFaceIndex, newEdgeIndex, NEXT ); } // Push face, edge, and reflEdge onto list remainFaces.append( newFaceIndex ); remainEdges.append( newEdgeIndex ); remainReflEdges.append( newReflEdgeIndex ); } } } // Set the active selection to the one previous to edge loop selection MGlobal::setActiveSelectionList( prevSel, MGlobal::kReplaceList ); // Update this selection based on the list adjustment setting MGlobal::selectCommand( newSel, listAdjust ); return MS::kSuccess; }
MStatus BPTfty_NH::doIt() { SPEED(" MACHE NON- TOPO - CHANGE AKTION "); switch(mode) { case 1: { //erstmal alle Edges holen MIntArray allEdges; MIntArray edgeLoops; //enthält die fertige EL auswahl zum anwählen // cout<<"MAIN: "<<"hole alle edgeIndices"<<endl; getAllEdgeIndices(allEdges); // cout<<"MAIN: "<<"finde edgeLoops"<<endl; findEdgeLoops(allEdges,edgeLoops); // cout<<"MAIN: "<<"Wähle Komponenten an"<<endl; selectComponents(edgeLoops,"edges"); switchComponentModeIfNeeded(); break; } //edgeRing auswählen case 2: { MIntArray allEdges; MIntArray edgeRings; // cout<<"MAIN: "<<"hole alle edgeIndices"<<endl; getAllEdgeIndices(allEdges); // cout<<"MAIN: "<<"finde edgeRings"<<endl; findEdgeRings(allEdges,edgeRings); // cout<<"MAIN: "<<"Wähle Komponenten an"<<endl; selectComponents(edgeRings,"edges"); switchComponentModeIfNeeded(); break; } //boundary erstellen case 3: { MStatus status; MItMeshPolygon polyIter(fMesh,&status); convertAllToFaces(polyIDs,vertIDs,edgeIDs); INVIS(if(status == MS::kFailure)) INVIS(cout <<"FEHLER, fMesh ist nicht angekommen in fty"<<endl;) MIntArray EdgeTmp; //invertSelection(polyIDs, polyIter.count(),inverted); faceGetContainedEdgeIndices(polyIDs, EdgeTmp); //faceGetContainedEdgeIndices(inverted, Edge2Tmp); MIntArray outline; helper.memoryPrune(EdgeTmp,outline); //outline finalisieren durch : allEdges - inner edges (in outline momentan) helper.memoryArrayRemove(EdgeTmp,outline); selectComponents(EdgeTmp,"edges"); //selectComponents(memoryMatch(EdgeTmp,Edge2Tmp),"edges"); switchComponentModeIfNeeded(); break; } case 7: { MPRINT("WILL GROWEN") SPEED(" GROWING "); MItMeshVertex vertIter(fMesh); MItMeshPolygon polyIter(fMesh); MItMeshEdge edgeIter(fMesh); if(vertIDs.length() != 0) { growVtxSelection(vertIDs,vertIter,polyIter, true); } else if(edgeIDs.length() != 0) { growEdgeSelection(edgeIDs,edgeIter,0); } else if(polyIDs.length() != 0) {//jetzt muss faceIDs an der reihe sein, da ja eine auswahl vorhanden sein muss, wenn er in fty ist //->diese auswahl koennen aber auch UVs sein growFaceSelection(polyIDs,edgeIter,polyIter.count()); } break; } case 8: { MPRINT("will shrinken") SPEED(" SHRINKING "); MItMeshVertex vertIter(fMesh); MItMeshPolygon polyIter(fMesh); MItMeshEdge edgeIter(fMesh); MIntArray allVtx; if(vertIDs.length() != 0) { schrinkVtxSelection(vertIDs,vertIter,polyIter, true); } else if(edgeIDs.length() != 0) { shrinkEdgeSelection(edgeIDs,edgeIter,polyIter.count()); } else if(polyIDs.length() != 0) {//jetzt muss faceIDs an der reihe sein, da ja eine auswahl vorhanden sein muss, wenn er in fty ist shrinkFaceSelection(polyIDs,edgeIter,polyIter.count()); } break; } }
void EdgeRetrieverJumpBin:: advanceEdge() { typedef SVLocusEdgesType::const_iterator edgeiter_t; const bool isFilterNodes(_graphNodeMaxEdgeCount>0); // advance to next edge unless this is the first iteration: if (0 != _edgeIndex) _edge.nodeIndex2++; while (_edge.locusIndex < _set.size()) { const SVLocus& locus(_set.getLocus(_edge.locusIndex)); while (_edge.nodeIndex1<locus.size()) { const SVLocusNode& node1(locus.getNode(_edge.nodeIndex1)); const bool isEdgeFilterNode1(isFilterNodes && (node1.size()>_graphNodeMaxEdgeCount)); const SVLocusEdgeManager node1Manager(node1.getEdgeManager()); edgeiter_t edgeIter(node1Manager.getMap().lower_bound(_edge.nodeIndex2)); const edgeiter_t edgeIterEnd(node1Manager.getMap().cend()); for (; edgeIter != edgeIterEnd; ++edgeIter) { _edge.nodeIndex2 = edgeIter->first; // if both nodes have high edge counts we filter out the edge: if (isEdgeFilterNode1) { const SVLocusNode& node2(locus.getNode(_edge.nodeIndex2)); const bool isEdgeFilterNode2(node2.size()>_graphNodeMaxEdgeCount); if (isEdgeFilterNode2) { #ifdef DEBUG_EDGER log_os << "EDGER: advance filtering @ index: " << _edgeIndex << "\n"; #endif continue; } } const unsigned firstTargetBin(_edgeIndex%_binCount); unsigned targetBin(firstTargetBin); do { if (_binTotalCount[targetBin] < _avgBinTotalCount) break; targetBin=((targetBin+1)%_binCount); } while (targetBin != firstTargetBin); #ifdef DEBUG_EDGER log_os << "EDGER: edgeIndex,ftarget,target,binIndex " << _edgeIndex << " " << firstTargetBin << " " << targetBin << " " << _binIndex << "\n"; #endif _edgeIndex++; if (targetBin == _binIndex) { // get edge count: unsigned edgeCount(edgeIter->second.getCount()); { const bool isSelfEdge(edgeIter->first == _edge.nodeIndex1); if (! isSelfEdge) edgeCount += locus.getEdge(edgeIter->first,_edge.nodeIndex1).getCount(); } _binTotalCount[targetBin] += edgeCount; return; } } ++_edge.nodeIndex1; _edge.nodeIndex2=_edge.nodeIndex1; } ++_edge.locusIndex; _edge.nodeIndex1=0; _edge.nodeIndex2=0; } }
MStatus Molecule3Cmd::redoIt() { MStatus stat; MDagPath dagPath; MFnMesh meshFn; // Create a ball int nBallPolys; MPointArray ballVerts; MIntArray ballPolyCounts; MIntArray ballPolyConnects; MFloatArray ballUCoords; MFloatArray ballVCoords; MIntArray ballFvUVIDs; genBall( MPoint::origin, ballRodRatio * radius.value(), segs, nBallPolys, ballVerts, ballPolyCounts, ballPolyConnects, true, ballUCoords, ballVCoords, ballFvUVIDs ); unsigned int i, j, vertOffset; MPointArray meshVerts; MPoint p0, p1; MObject objTransform; // Setup for rods int nRodPolys; MPointArray rodVerts; MIntArray rodPolyCounts; MIntArray rodPolyConnects; MFloatArray rodUCoords; MFloatArray rodVCoords; MIntArray rodFvUVIDs; // Setup for newMesh int nNewPolys; MPointArray newVerts; MIntArray newPolyCounts; MIntArray newPolyConnects; MFloatArray newUCoords; MFloatArray newVCoords; MIntArray newFvUVIDs; int uvOffset; MDagModifier dagMod; MFnDagNode dagFn; objTransforms.clear(); // Iterate over the meshes unsigned int mi; for( mi=0; mi < selMeshes.length(); mi++ ) { dagPath = selMeshes[mi]; meshFn.setObject( dagPath ); uvOffset = 0; nNewPolys = 0; newVerts.clear(); newPolyCounts.clear(); newPolyConnects.clear(); newUCoords.clear(); newVCoords.clear(); newFvUVIDs.clear(); // Generate balls meshFn.getPoints( meshVerts, MSpace::kWorld ); for( i=0; i < meshVerts.length(); i++ ) { vertOffset = newVerts.length(); // Add the ball to the new mesh nNewPolys += nBallPolys; // Move the ball vertices to the mesh vertex. Add it to the newMesh for( j=0; j < ballVerts.length(); j++ ) newVerts.append( meshVerts[i] + ballVerts[j] ); for( j=0; j < ballPolyCounts.length(); j++ ) newPolyCounts.append( ballPolyCounts[j] ); for( j=0; j < ballPolyConnects.length(); j++ ) newPolyConnects.append( vertOffset + ballPolyConnects[j] ); // Only add the uv coordinates once, since they are shared // by all balls if( i == 0 ) { for( j=0; j < ballUCoords.length(); j++ ) { newUCoords.append( ballUCoords[j] ); newVCoords.append( ballVCoords[j] ); } } for( j=0; j < ballFvUVIDs.length(); j++ ) { newFvUVIDs.append( uvOffset + ballFvUVIDs[j] ); } } uvOffset = newUCoords.length(); // Generate rods int nRods = 0; MItMeshEdge edgeIter( dagPath ); for( ; !edgeIter.isDone(); edgeIter.next(), nRods++ ) { p0 = edgeIter.point( 0, MSpace::kWorld ); p1 = edgeIter.point( 1, MSpace::kWorld ); // N.B. Generate the uv coordinates only once since they // are referenced by all rods genRod( p0, p1, radius.value(), segs, nRodPolys, rodVerts, rodPolyCounts, rodPolyConnects, nRods == 0, rodUCoords, rodVCoords, rodFvUVIDs ); vertOffset = newVerts.length(); // Add the rod to the mesh nNewPolys += nRodPolys; for( i=0; i < rodVerts.length(); i++ ) newVerts.append( rodVerts[i] ); for( i=0; i < rodPolyCounts.length(); i++ ) newPolyCounts.append( rodPolyCounts[i] ); for( i=0; i < rodPolyConnects.length(); i++ ) newPolyConnects.append( vertOffset + rodPolyConnects[i] ); // First rod if( nRods == 0 ) { // Add rod's uv coordinates to the list for( i=0; i < rodUCoords.length(); i++ ) { newUCoords.append( rodUCoords[i] ); newVCoords.append( rodVCoords[i] ); } } // Set the face-vertex-uvIDs for( i=0; i < rodFvUVIDs.length(); i++ ) { newFvUVIDs.append( uvOffset + rodFvUVIDs[i] ); } } objTransform = meshFn.create( newVerts.length(), nNewPolys, newVerts, newPolyCounts, newPolyConnects, newUCoords, newVCoords, MObject::kNullObj, &stat ); if( !stat ) { MGlobal::displayError( MString( "Unable to create mesh: " ) + stat.errorString() ); return stat; } objTransforms.append( objTransform ); meshFn.assignUVs( newPolyCounts, newFvUVIDs ); meshFn.updateSurface(); // Rename transform node dagFn.setObject( objTransform ); dagFn.setName( "molecule" ); // Put mesh into the initial shading group dagMod.commandToExecute( MString( "sets -e -fe initialShadingGroup " ) + meshFn.name() ); } // Select all the newly created molecule meshes MString cmd( "select -r" ); for( i=0; i < objTransforms.length(); i++ ) { dagFn.setObject( objTransforms[i] ); cmd += " " + dagFn.name(); } dagMod.commandToExecute( cmd ); return dagMod.doIt(); }
MStatus convertVerticesToContainedEdgesCommand::redoIt() { MSelectionList finalEdgesSelection; MDagPath meshDagPath; MObject multiVertexComponent, singleVertexComponent; int dummyIndex; // ITERATE THROUGH EACH "VERTEX COMPONENT" THAT IS CURRENTLY SELECTED: for (MItSelectionList vertexComponentIter(previousSelectionList, MFn::kMeshVertComponent); !vertexComponentIter.isDone(); vertexComponentIter.next()) { // STORE THE DAGPATH, COMPONENT OBJECT AND MESH NAME OF THE CURRENT VERTEX COMPONENT: vertexComponentIter.getDagPath(meshDagPath, multiVertexComponent); MString meshName = meshDagPath.fullPathName(); // VERTEX COMPONENT HAS TO CONTAIN AT LEAST ONE VERTEX: if (!multiVertexComponent.isNull()) { // ITERATE THROUGH EACH "VERTEX" IN THE CURRENT VERTEX COMPONENT: for (MItMeshVertex vertexIter(meshDagPath, multiVertexComponent); !vertexIter.isDone(); vertexIter.next()) { // FOR STORING THE EDGES CONNECTED TO EACH VERTEX: MIntArray connectedEdgesIndices; vertexIter.getConnectedEdges(connectedEdgesIndices); // ITERATE THROUGH EACH EDGE CONNECTED TO THE CURRENT VERTEX: MItMeshEdge edgeIter(meshDagPath); for (unsigned i=0; i<connectedEdgesIndices.length(); i++) { // FIND AND STORE THE *FIRST* "END VERTEX" OF THE CURRENT EDGE: edgeIter.setIndex(connectedEdgesIndices[i], dummyIndex); MSelectionList singleVertexList; MString vertexName = meshName; vertexName += ".vtx["; vertexName += edgeIter.index(0); vertexName += "]"; singleVertexList.add(vertexName); singleVertexList.getDagPath(0, meshDagPath, singleVertexComponent); // SEE WHETHER THE VERTEX BELONGS TO THE ORIGINAL SELECTION, AND IF IT DOES PROCEED TO CHECK NEXT END VERTEX: if (!singleVertexComponent.isNull() && previousSelectionList.hasItem(meshDagPath, singleVertexComponent)) { // FIND AND STORE THE *SECOND* "END VERTEX" OF THE CURRENT EDGE: singleVertexList.clear(); vertexName = meshName; vertexName += ".vtx["; vertexName += edgeIter.index(1); vertexName += "]"; singleVertexList.add(vertexName); singleVertexList.getDagPath(0, meshDagPath, singleVertexComponent); // SEE WHETHER THE VERTEX BELONGS TO THE ORIGINAL SELECTION, AND IF IT DOES, ADD THE EDGE TO THE FINAL CONTAINED EDGES LIST: if (!singleVertexComponent.isNull() && previousSelectionList.hasItem(meshDagPath, singleVertexComponent)) { MString edgeName = meshName; edgeName += ".e["; edgeName += connectedEdgesIndices[i]; edgeName += "]"; finalEdgesSelection.add(edgeName); } } } } } } // FINALLY, MAKE THE NEW "CONTAINED EDGES", THE CURRENT SELECTION: MGlobal::setActiveSelectionList(finalEdgesSelection, MGlobal::kReplaceList); // RETURN NEW CONTAINED EDGES LIST FROM THE MEL COMMAND, AS AN ARRAY OF STRINGS: MStringArray containedEdgesArray; finalEdgesSelection.getSelectionStrings(containedEdgesArray); MPxCommand::setResult(containedEdgesArray); return MS::kSuccess; }
// write a normal mesh // MStatus vxCache::writeMesh(const char* filename, MDagPath meshDag, const MObject& meshObj) { struct meshInfo mesh; MString uvset("map1"); MStatus status; MFnMesh meshFn(meshDag, &status ); MItMeshPolygon faceIter( meshDag, MObject::kNullObj, &status ); MItMeshVertex vertIter(meshDag, MObject::kNullObj, &status); MItMeshEdge edgeIter(meshDag, MObject::kNullObj, &status); mesh.numPolygons = meshFn.numPolygons(); mesh.numVertices = meshFn.numVertices(); mesh.numFaceVertices = meshFn.numFaceVertices(); mesh.numUVs = meshFn.numUVs(uvset, &status); mesh.skip_interreflection = mesh.skip_scattering = 0; //if(zWorks::hasNamedAttribute(meshObj, "_prt_ig_intr") == 1) mesh.skip_interreflection = 1; //if(zWorks::hasNamedAttribute(meshObj, "_prt_ig_scat") == 1) mesh.skip_scattering = 1; //zWorks::displayIntParam("N Face", mesh.numPolygons); //zWorks::displayIntParam("N Vertex", mesh.numVertices); //zWorks::displayIntParam("N Facevertex", mesh.numFaceVertices); //zWorks::displayIntParam("N UV", mesh.numUVs); int *fcbuf = new int[mesh.numPolygons]; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { fcbuf[ faceIter.index() ] = faceIter.polygonVertexCount(); } int* vertex_id = new int[mesh.numFaceVertices]; int* uv_id = new int[mesh.numFaceVertices]; // output face loop int acc = 0; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { MIntArray vexlist; faceIter.getVertices ( vexlist ); for( unsigned int i=0; i < vexlist.length(); i++ ) { vertex_id[acc] = vexlist[i]; faceIter.getUVIndex ( i, uv_id[acc] ); acc++; } } // output vertices MPointArray pArray; if(worldSpace) meshFn.getPoints ( pArray, MSpace::kWorld); else meshFn.getPoints ( pArray, MSpace::kObject ); XYZ *pbuf = new XYZ[pArray.length()]; for( unsigned int i=0; i<pArray.length(); i++) { pbuf[i].x = pArray[i].x; pbuf[i].y = pArray[i].y; pbuf[i].z= pArray[i].z; } //output texture coordinate MFloatArray uArray, vArray; meshFn.getUVs ( uArray, vArray, &uvset ); double* ubuf = new double[mesh.numUVs]; double* vbuf = new double[mesh.numUVs]; for( unsigned int i=0; i<uArray.length(); i++) { ubuf[i] = uArray[i]; vbuf[i] = vArray[i]; } /* XYZ *norbuf = new XYZ[mesh.numVertices]; vertIter.reset(); MVector tnor; for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { if(worldSpace) vertIter.getNormal(tnor, MSpace::kWorld); else vertIter.getNormal(tnor, MSpace::kObject); tnor.normalize(); norbuf[i].x = tnor.x; norbuf[i].y = tnor.y; norbuf[i].z = tnor.z; } MStatus hasAttr; MString sColorSet("set_prt_attr"); meshFn.numColors( sColorSet, &hasAttr ); XYZ *colbuf = new XYZ[mesh.numVertices]; vertIter.reset(); if(hasAttr) { MColor col; for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray conn_face; vertIter.getConnectedFaces(conn_face); vertIter.getColor(col, conn_face[0], &sColorSet); colbuf[i].x = col.r; colbuf[i].y = col.g; colbuf[i].z = col.b; } } else { for( unsigned int i=0; i<vertIter.count(); i++ ) colbuf[i] = XYZ(1.0f); } vertIter.reset(); XYZ *vsbuf = new XYZ[mesh.numVertices]; for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray conn_face, conn_edge; vertIter.getConnectedFaces(conn_face); vertIter.getConnectedEdges(conn_edge); MPoint Q; for(unsigned j=0; j<conn_face.length(); j++) { int pre_id; faceIter.setIndex(conn_face[j],pre_id); Q += faceIter.center(MSpace::kWorld); } Q = Q/(double)conn_face.length(); MPoint R; for(unsigned j=0; j<conn_edge.length(); j++) { int pre_id; edgeIter.setIndex(conn_edge[j], pre_id); R += edgeIter.center(MSpace::kWorld); } R = R/(double)conn_edge.length(); MPoint S = vertIter.position(MSpace::kWorld); int nv = conn_edge.length(); MPoint nS = (Q + R*2 + S*(nv-3))/nv; vsbuf[i].x = nS.x; vsbuf[i].y = nS.y; vsbuf[i].z = nS.z; } XYZ *tangbuf = new XYZ[mesh.numVertices]; vertIter.reset(); for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray conn_face; MVector tang(0,0,0); vertIter.getConnectedFaces(conn_face); //for(int j = 0; j<conn_face.length(); j++) { MVector ttang; meshFn.getFaceVertexTangent (conn_face[0], i, ttang, MSpace::kWorld, &uvset); tang += ttang; } tang.normalize(); tangbuf[i].x = tang.x; tangbuf[i].y = tang.y; tangbuf[i].z = tang.z; tangbuf[i] = norbuf[i].cross(tangbuf[i]); tangbuf[i].normalize(); } */ FMCFMesh fmesh; fmesh.save(mesh.numVertices, mesh.numFaceVertices, mesh.numPolygons, mesh.numUVs, mesh.skip_interreflection, mesh.skip_scattering, fcbuf, vertex_id, uv_id, pbuf, //vsbuf, //norbuf, //tangbuf, //colbuf, ubuf, vbuf, filename); delete[] fcbuf; delete[] vertex_id; delete[] uv_id; delete[] pbuf; //delete[] vsbuf; //delete[] norbuf; //delete[] tangbuf; //delete[] colbuf; delete[] ubuf; delete[] vbuf; return MS::kSuccess; }
void EdgeRetrieverBin:: jumpToFirstEdge() { typedef SVLocusEdgesType::const_iterator edgeiter_t; const bool isFilterNodes(_graphNodeMaxEdgeCount>0); // first catch headCount up to the begin edge if required: while (true) { assert(_edge.locusIndex<_set.size()); const SVLocus& locus(_set.getLocus(_edge.locusIndex)); const unsigned locusObservationCount(locus.totalObservationCount()); if ((_headCount+locusObservationCount) > _beginCount) { while (true) { const SVLocusNode& node1(locus.getNode(_edge.nodeIndex1)); const bool isEdgeFilterNode1(isFilterNodes && (node1.size()>_graphNodeMaxEdgeCount)); const SVLocusEdgeManager node1Manager(node1.getEdgeManager()); edgeiter_t edgeIter(node1Manager.getMap().lower_bound(_edge.nodeIndex1)); const edgeiter_t edgeiterEnd(node1Manager.getMap().end()); for (; edgeIter != edgeiterEnd; ++edgeIter) { unsigned edgeCount(edgeIter->second.getCount()); const bool isSelfEdge(edgeIter->first == _edge.nodeIndex1); if (! isSelfEdge) edgeCount += locus.getEdge(edgeIter->first,_edge.nodeIndex1).getCount(); _headCount += edgeCount; if (_headCount > _beginCount) { _edge.nodeIndex2 = edgeIter->first; // if both nodes have high edge counts we filter out the edge: if (isEdgeFilterNode1) { const SVLocusNode& node2(locus.getNode(_edge.nodeIndex2)); const bool isEdgeFilterNode2(node2.size()>_graphNodeMaxEdgeCount); if (isEdgeFilterNode2) { #ifdef DEBUG_EDGER log_os << "EDGER: jump filtering @ hc: " << _headCount << "\n"; #endif continue; } } return; } } _edge.nodeIndex1++; } assert(_headCount >= _beginCount); } _headCount += locusObservationCount; _edge.locusIndex++; } assert(false && "jumpToFirstEdge: invalid state"); }
void EdgeRetrieverBin:: advanceEdge() { typedef SVLocusEdgesType::const_iterator edgeiter_t; const bool isFilterNodes(_graphNodeMaxEdgeCount>0); if (0 != _headCount) _edge.nodeIndex2++; bool isLastFiltered(false); while (true) { if (isLastFiltered && (_edge.locusIndex == _set.size())) { _headCount = (_endCount + 1); return; } assert(_edge.locusIndex<_set.size()); const SVLocus& locus(_set.getLocus(_edge.locusIndex)); while (_edge.nodeIndex1<locus.size()) { const SVLocusNode& node1(locus.getNode(_edge.nodeIndex1)); const bool isEdgeFilterNode1(isFilterNodes && (node1.size()>_graphNodeMaxEdgeCount)); const SVLocusEdgeManager node1Manager(node1.getEdgeManager()); edgeiter_t edgeIter(node1Manager.getMap().lower_bound(_edge.nodeIndex2)); const edgeiter_t edgeIterEnd(node1Manager.getMap().end()); for (; edgeIter != edgeIterEnd; ++edgeIter) { unsigned edgeCount(edgeIter->second.getCount()); const bool isSelfEdge(edgeIter->first == _edge.nodeIndex1); if (! isSelfEdge) edgeCount += locus.getEdge(edgeIter->first,_edge.nodeIndex1).getCount(); _headCount += edgeCount; _edge.nodeIndex2 = edgeIter->first; // if both nodes have high edge counts we filter out the edge: if (isEdgeFilterNode1) { const SVLocusNode& node2(locus.getNode(_edge.nodeIndex2)); const bool isEdgeFilterNode2(node2.size()>_graphNodeMaxEdgeCount); if (isEdgeFilterNode2) { #ifdef DEBUG_EDGER log_os << "EDGER: advance filtering @ hc: " << _headCount << "\n"; #endif isLastFiltered=true; continue; } } return; } ++_edge.nodeIndex1; _edge.nodeIndex2=_edge.nodeIndex1; } ++_edge.locusIndex; _edge.nodeIndex1=0; _edge.nodeIndex2=0; } assert(false && "advanceEdge: invalid state"); }
void ExportACache::save(const char* filename, int frameNumber, char bfirst) { MStatus status; FXMLScene xml_f; xml_f.begin(filename, frameNumber, bfirst); for(unsigned it=0; it<m_mesh_list.length(); it++) { m_mesh_list[it].extendToShape(); MString surface = m_mesh_list[it].partialPathName(); AHelper::validateFilePath(surface); MFnDependencyNode fnode(m_mesh_list[it].node()); MString smsg("prtMsg"); MStatus hasMsg; MPlug pmsg = fnode.findPlug( smsg, 1, &hasMsg ); char bNoChange = 0; if(hasMsg) { MObject oattrib; AHelper::getConnectedNode(oattrib, pmsg); fnode.setObject(oattrib); bool iattr = 0; AHelper::getBoolAttributeByName(fnode, "noChange", iattr); if(iattr) bNoChange = 1; } xml_f.meshBegin(surface.asChar(), bNoChange); MFnMesh meshFn(m_mesh_list[it], &status ); MItMeshPolygon faceIter(m_mesh_list[it], MObject::kNullObj, &status ); MItMeshVertex vertIter(m_mesh_list[it], MObject::kNullObj, &status); MItMeshEdge edgeIter(m_mesh_list[it], MObject::kNullObj, &status); int n_tri = 0; float f_area = 0; double area; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { MIntArray vexlist; faceIter.getVertices ( vexlist ); n_tri += vexlist.length() - 2; faceIter.getArea( area, MSpace::kWorld ); f_area += (float)area; } xml_f.triangleInfo(n_tri, f_area); float avg_grid = sqrt(f_area/n_tri)/2; double light_intensity = 1.0; if(hasMsg) { MObject oattrib; AHelper::getConnectedNode(oattrib, pmsg); fnode.setObject(oattrib); bool iattr = 0; AHelper::getBoolAttributeByName(fnode, "noChange", iattr); if(iattr) xml_f.addAttribute("noChange", 1); AHelper::getBoolAttributeByName(fnode, "skipIndirect", iattr); if(iattr) xml_f.addAttribute("skipIndirect", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "skipScatter", iattr); if(iattr) xml_f.addAttribute("skipScatter", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "skipBackscatter", iattr); if(iattr) xml_f.addAttribute("skipBackscatter", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "asLightsource", iattr); if(iattr) xml_f.addAttribute("asLightsource", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "asGhost", iattr); if(iattr) xml_f.addAttribute("invisible", 1); iattr = 0; AHelper::getBoolAttributeByName(fnode, "castNoShadow", iattr); if(iattr) xml_f.addAttribute("noShadow", 1); double td; if(AHelper::getDoubleAttributeByName(fnode, "lightIntensity", td)) light_intensity = td; fnode.setObject(m_mesh_list[it].node()); } xml_f.staticBegin(); int n_poly = meshFn.numPolygons(); int n_vert = meshFn.numVertices(); int* polycount = new int[n_poly]; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) polycount[ faceIter.index() ] = faceIter.polygonVertexCount(); xml_f.addFaceCount(n_poly, polycount); delete[] polycount; int n_facevertex = meshFn.numFaceVertices(); int* polyconnect = new int[n_facevertex]; int acc = 0; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { MIntArray vexlist; faceIter.getVertices ( vexlist ); for( int i=vexlist.length()-1; i >=0; i-- ) { polyconnect[acc] = vexlist[i]; acc++; } } xml_f.addFaceConnection(n_facevertex, polyconnect); delete[] polyconnect; int* triconnect = new int[3*n_tri]; acc = 0; faceIter.reset(); for( ; !faceIter.isDone(); faceIter.next() ) { MIntArray vexlist; faceIter.getVertices ( vexlist ); for( int i=vexlist.length()-2; i >0; i-- ) { triconnect[acc] = vexlist[vexlist.length()-1]; acc++; triconnect[acc] = vexlist[i]; acc++; triconnect[acc] = vexlist[i-1]; acc++; } } xml_f.addTriangleConnection(3*n_tri, triconnect); delete[] triconnect; if(meshFn.numUVSets() > 0) { MStringArray setNames; meshFn.getUVSetNames(setNames); for(unsigned i=0; i< setNames.length(); i++) { float* scoord = new float[n_facevertex]; float* tcoord = new float[n_facevertex]; acc = 0; faceIter.reset(); MFloatArray uarray, varray; if(faceIter.hasUVs (setNames[i], &status)) { for( ; !faceIter.isDone(); faceIter.next() ) { faceIter.getUVs ( uarray, varray, &setNames[i] ); for( int j=uarray.length()-1; j >=0 ; j-- ) { scoord[acc] = uarray[j]; tcoord[acc] = 1.0 - varray[j]; acc++; } } if(setNames[i] == "map1") { xml_f.uvSetBegin(setNames[i].asChar()); xml_f.addS("facevarying float s", meshFn.numFaceVertices(), scoord); xml_f.addT("facevarying float t", meshFn.numFaceVertices(), tcoord); xml_f.uvSetEnd(); } else { xml_f.uvSetBegin(setNames[i].asChar()); std::string paramname("facevarying float u_"); paramname.append(setNames[i].asChar()); xml_f.addS(paramname.c_str(), meshFn.numFaceVertices(), scoord); paramname = "facevarying float v_"; paramname.append(setNames[i].asChar()); xml_f.addT(paramname.c_str(), meshFn.numFaceVertices(), tcoord); xml_f.uvSetEnd(); } } else MGlobal::displayWarning(MString("Skip empty uv set: ") + setNames[i]); delete[] scoord; delete[] tcoord; } } MStringArray colorSetNames; meshFn.getColorSetNames (colorSetNames); for(unsigned int i=0; i<colorSetNames.length(); i++) { MStatus hasColor; XYZ *colors = new XYZ[n_vert]; vertIter.reset(); MString aset = colorSetNames[i]; MColor col; for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray conn_face; vertIter.getConnectedFaces(conn_face); vertIter.getColor(col, conn_face[0], &aset); colors[i].x = col.r*light_intensity; colors[i].y = col.g*light_intensity; colors[i].z = col.b*light_intensity; } xml_f.addVertexColor(aset.asChar(), n_vert, colors); delete[] colors; } //if(!bNoChange) { //} MPointArray p_vert; meshFn.getPoints ( p_vert, MSpace::kWorld ); MPoint corner_l(10e6, 10e6, 10e6); MPoint corner_h(-10e6, -10e6, -10e6); for( unsigned int i=0; i<p_vert.length(); i++) { if( p_vert[i].x < corner_l.x ) corner_l.x = p_vert[i].x; if( p_vert[i].y < corner_l.y ) corner_l.y = p_vert[i].y; if( p_vert[i].z < corner_l.z ) corner_l.z = p_vert[i].z; if( p_vert[i].x > corner_h.x ) corner_h.x = p_vert[i].x; if( p_vert[i].y > corner_h.y ) corner_h.y = p_vert[i].y; if( p_vert[i].z > corner_h.z ) corner_h.z = p_vert[i].z; } XYZ *cv = new XYZ[n_vert]; for( unsigned int i=0; i<p_vert.length(); i++) { cv[i].x = p_vert[i].x; cv[i].y = p_vert[i].y; cv[i].z= p_vert[i].z; } //if(!bNoChange) //else xml_f.addStaticP(n_vert, cv); XYZ *nor = new XYZ[n_vert]; XYZ *tang = new XYZ[n_vert]; vertIter.reset(); MVector vnor; for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { vertIter.getNormal(vnor, MSpace::kWorld); vnor.normalize(); nor[i].x = vnor.x; nor[i].y = vnor.y; nor[i].z = vnor.z; } MString uvset("map1"); vertIter.reset(); for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray conn_face; vertIter.getConnectedFaces(conn_face); MVector ctang(0,0,0); MVector ttang; for(unsigned j = 0; j<conn_face.length(); j++) { meshFn.getFaceVertexTangent (conn_face[j], i, ttang, MSpace::kWorld, &uvset); ttang.normalize(); ctang += ttang; } ctang.normalize(); tang[i].x = ctang.x; tang[i].y = ctang.y; tang[i].z = ctang.z; tang[i] = nor[i].cross(tang[i]); tang[i].normalize(); } //if(!bNoChange) //else xml_f.addStaticN(n_vert, nor); //xml_f.addTangent(n_vert, tang); // export per-vertex thickness float* vgrd = new float[n_vert]; int pidx; vertIter.reset(); for( unsigned int i=0; !vertIter.isDone(); vertIter.next(), i++ ) { MIntArray connfaces; vertIter.getConnectedFaces( connfaces ); float connarea = 0; for(unsigned j=0; j<connfaces.length(); j++) { faceIter.setIndex(connfaces[j], pidx); faceIter.getArea(area, MSpace::kWorld ); connarea += (float)area/faceIter.polygonVertexCount(); } vgrd[i] = sqrt(connarea)/2; if(vgrd[i] > avg_grid) vgrd[i] = avg_grid; } //if(!bNoChange) //else xml_f.addStaticGridSize(n_vert, vgrd); // //else xml_f.staticEnd(); if(!bNoChange) { xml_f.dynamicBegin(); xml_f.addP(n_vert, cv); xml_f.addN(n_vert, nor); xml_f.addGridSize(n_vert, vgrd); xml_f.dynamicEnd(); } delete[] cv; delete[] tang; delete[] nor; delete[] vgrd; xml_f.addBBox(corner_l.x, corner_l.y, corner_l.z, corner_h.x, corner_h.y, corner_h.z); xml_f.meshEnd(bNoChange); } /* disable nurbs for now float aspace[4][4]; for(unsigned it=0; it<m_nurbs_list.length(); it++) { MVector scale = AHelper::getTransformWorldNoScale(m_nurbs_list[it].fullPathName(), aspace); MString surfacename = m_nurbs_list[it].fullPathName(); AHelper::validateFilePath(surfacename); xml_f.transformBegin(surfacename.asChar(), aspace); xml_f.addScale(scale.x, scale.y, scale.z); m_nurbs_list[it].extendToShape(); surfacename = m_nurbs_list[it].fullPathName(); AHelper::validateFilePath(surfacename); MFnNurbsSurface fsurface(m_nurbs_list[it]); int degreeU = fsurface.degreeU(); int degreeV = fsurface.degreeV(); int formU, formV; if(fsurface.formInU() == MFnNurbsSurface::kOpen ) formU = 0; else if(fsurface.formInU() == MFnNurbsSurface::kClosed ) formU = 1; else formU = 2; if(fsurface.formInV() == MFnNurbsSurface::kOpen ) formV = 0; else if(fsurface.formInV() == MFnNurbsSurface::kClosed ) formV = 1; else formV = 2; xml_f.nurbssurfaceBegin(surfacename.asChar(), degreeU, degreeV, formU, formV); xml_f.staticBegin(); MPointArray p_cvs; fsurface.getCVs( p_cvs, MSpace::kObject ); unsigned n_cvs = p_cvs.length(); XYZ *cv = new XYZ[n_cvs]; for(unsigned i=0; i<n_cvs; i++) { cv[i].x = p_cvs[i].x; cv[i].y = p_cvs[i].y; cv[i].z= p_cvs[i].z; } xml_f.addStaticVec("cvs", n_cvs, cv); delete[] cv; MDoubleArray knotu, knotv; fsurface.getKnotsInU(knotu); fsurface.getKnotsInV(knotv); unsigned n_ku = knotu.length(); unsigned n_kv = knotv.length(); float *ku = new float[n_ku]; for(unsigned i=0; i<n_ku; i++) ku[i] = knotu[i]; float *kv = new float[n_kv]; for(unsigned i=0; i<n_kv; i++) kv[i] = knotv[i]; xml_f.addStaticFloat("knotu", n_ku, ku); xml_f.addStaticFloat("knotv", n_kv, kv); delete[] ku; delete[] kv; xml_f.staticEnd(); xml_f.nurbssurfaceEnd(); xml_f.transformEnd(); } */ xml_f.cameraBegin("backscat_camera", m_space); xml_f.cameraEnd(); xml_f.cameraBegin("eye_camera", m_eye); p_eye.extendToShape(); MFnCamera feye(p_eye); xml_f.addAttribute("focal_length", (float)feye.focalLength()); xml_f.addAttribute("horizontal_film_aperture", (float)feye.horizontalFilmAperture()); xml_f.addAttribute("vertical_film_aperture", (float)feye.verticalFilmAperture()); xml_f.addAttribute("near_clipping_plane", (float)feye.nearClippingPlane()); xml_f.addAttribute("far_clipping_plane", (float)feye.farClippingPlane()); xml_f.cameraEnd(); xml_f.end(filename); }
MStatus SelectRingContext1::doRelease( MEvent &event ) { // Get the mouse release position event.getPosition( releaseX, releaseY ); // Didn't select a single point if( abs(pressX - releaseX) > 1 || abs(pressY - releaseY) > 1 ) { MGlobal::displayWarning( "Click on a single edge" ); return MS::kFailure; } // Set the selection surface area int halfClickBoxSize = clickBoxSize / 2; pressX -= halfClickBoxSize; pressY -= halfClickBoxSize; releaseX = pressX + clickBoxSize; releaseY = pressY + clickBoxSize; /* // Record previous selection state prevSelMode = MGlobal::selectionMode(); prevCompMask = MGlobal::componentSelectionMask(); */ // Get the current selection MSelectionList curSel; MGlobal::getActiveSelectionList( curSel ); //MGlobal::displayInfo( MString("Dim: ") + start_x + " " + start_y + " " + last_x + " " + last_y ); // Change to object selection mode MGlobal::setSelectionMode( MGlobal::kSelectObjectMode ); MGlobal::setComponentSelectionMask( MSelectionMask( MSelectionMask::kSelectObjectsMask ) ); // Select the object under the selection area MGlobal::selectFromScreen( pressX, pressY, releaseX, releaseY, MGlobal::kReplaceList); MGlobal::executeCommand( "hilite" ); // Change selection mode to mesh edges MGlobal::setSelectionMode( MGlobal::kSelectComponentMode ); MGlobal::setComponentSelectionMask( MSelectionMask( MSelectionMask::kSelectMeshEdges ) ); // Select the edges MGlobal::selectFromScreen( pressX, pressY, releaseX, releaseY, MGlobal::kReplaceList ); // Get the list of selected edges MSelectionList origEdgesSel; MGlobal::getActiveSelectionList( origEdgesSel ); MSelectionList newEdgesSel; MDagPath dagPath; MObject component; // Only use the first edge in the selection MItSelectionList selIter( origEdgesSel, MFn::kMeshEdgeComponent ); if( !selIter.isDone() ) { selIter.getDagPath( dagPath, component ); MIntArray faces; MItMeshEdge edgeIter( dagPath, component ); MIntArray edgesVisited, facesVisited; int edgeIndex, faceIndex; int prevIndex; unsigned int i; bool finished = false; while( !finished ) { edgeIndex = edgeIter.index(); edgesVisited.append( edgeIndex ); // Create an edge component the current edge MFnSingleIndexedComponent indexedCompFn; MObject newComponent = indexedCompFn.create( MFn::kMeshEdgeComponent ); indexedCompFn.addElement( edgeIndex ); newEdgesSel.add( dagPath, newComponent ); //MGlobal::displayInfo( MString("ADDING: ") + edgeIter.index() ); edgeIter.getConnectedFaces( faces ); faceIndex = faces[0]; if( faces.length() > 1 ) { // Select the face that hasn't already been visited for( i=0; i < facesVisited.length(); i++ ) { if( faceIndex == facesVisited[i] ) { faceIndex = faces[1]; break; } } } //MGlobal::displayInfo( MString("FACE: ") + faceIndex ); facesVisited.append( faceIndex ); MItMeshPolygon polyIter( dagPath ); polyIter.setIndex( faceIndex, prevIndex ); //MGlobal::displayInfo( MString( "faces: " ) + faces[0] + " " + faces[1] ); MIntArray edges; polyIter.getEdges( edges ); // Determine the face-relative index of the current // edge unsigned int edgeFaceIndex = 0; for( i=0; i < edges.length(); i++ ) { if( edges[i] == edgeIter.index() ) { edgeFaceIndex = i; break; } } // Determine the edge that is opposite the current edge edgeIndex = edges[ (edgeFaceIndex + (edges.length() / 2) ) % edges.length() ]; //int index = edgeIter.index(); //MGlobal::displayInfo( MString( "sel edge index: " ) + index + " next edge: " + edgeIndex ); // Set the current edge to the opposite edge edgeIter.setIndex( edgeIndex, prevIndex ); // Determine if the edge has already been visited for( i=0; i < edgesVisited.length(); i++ ) { if( edgeIndex == edgesVisited[i] ) { finished = true; break; } } } } // Set the active selection to the one previous to edge loop selection MGlobal::setActiveSelectionList( curSel, MGlobal::kReplaceList); // Update this selection based on the list adjustment setting MGlobal::selectCommand( newEdgesSel, listAdjust ); return MS::kSuccess; }
MStatus lassoTool::doRelease( MEvent & /*event*/ ) // Selects objects within the lasso { MStatus stat; MSelectionList incomingList, boundingBoxList, newList; if (!firstDraw) { // Redraw the lasso to clear it. view.beginXorDrawing(true, true, 1.0f, M3dView::kStippleDashed); draw_lasso(); view.endXorDrawing(); } // We have a non-zero sized lasso. Close the lasso, and sort // all the points on it. append_lasso(lasso[0].h, lasso[0].v); qsort( &(lasso[0]), num_points, sizeof( coord ), (int (*)(const void *, const void *))xycompare); // Save the state of the current selections. The "selectFromSceen" // below will alter the active list, and we have to be able to put // it back. MGlobal::getActiveSelectionList(incomingList); // As a first approximation to the lasso, select all components with // the bounding box that just contains the lasso. MGlobal::selectFromScreen( min.h, min.v, max.h, max.v, MGlobal::kReplaceList ); // Get the list of selected items from within the bounding box // and create a iterator for them. MGlobal::getActiveSelectionList(boundingBoxList); // Restore the active selection list to what it was before we // the "selectFromScreen" MGlobal::setActiveSelectionList(incomingList, MGlobal::kReplaceList); // Iterate over the objects within the bounding box, extract the // ones that are within the lasso, and add those to newList. MItSelectionList iter(boundingBoxList); newList.clear(); bool foundEntireObjects = false; bool foundComponents = false; for ( ; !iter.isDone(); iter.next() ) { MDagPath dagPath; MObject component; MPoint point; coord pt; MObject singleComponent; iter.getDagPath( dagPath, component ); if (component.isNull()) { foundEntireObjects = true; continue; // not a component } foundComponents = true; switch (component.apiType()) { case MFn::kCurveCVComponent: { MItCurveCV curveCVIter( dagPath, component, &stat ); for ( ; !curveCVIter.isDone(); curveCVIter.next() ) { point = curveCVIter.position(MSpace::kWorld, &stat ); view.worldToView( point, pt.h, pt.v, &stat ); if (!stat) { stat.perror("Could not get position"); continue; } if ( point_in_lasso( pt ) ) { singleComponent = curveCVIter.cv(); newList.add (dagPath, singleComponent); } } break; } case MFn::kSurfaceCVComponent: { MItSurfaceCV surfCVIter( dagPath, component, true, &stat ); for ( ; !surfCVIter.isDone(); surfCVIter.next() ) { point = surfCVIter.position(MSpace::kWorld, &stat ); view.worldToView( point, pt.h, pt.v, &stat ); if (!stat) { stat.perror("Could not get position"); continue; } if ( point_in_lasso( pt ) ) { singleComponent = surfCVIter.cv(); newList.add (dagPath, singleComponent); } } break; } case MFn::kMeshVertComponent: { MItMeshVertex vertexIter( dagPath, component, &stat ); for ( ; !vertexIter.isDone(); vertexIter.next() ) { point = vertexIter.position(MSpace::kWorld, &stat ); view.worldToView( point, pt.h, pt.v, &stat ); if (!stat) { stat.perror("Could not get position"); continue; } if ( point_in_lasso( pt ) ) { singleComponent = vertexIter.vertex(); newList.add (dagPath, singleComponent); } } break; } case MFn::kMeshEdgeComponent: { MItMeshEdge edgeIter( dagPath, component, &stat ); for ( ; !edgeIter.isDone(); edgeIter.next() ) { point = edgeIter.center(MSpace::kWorld, &stat ); view.worldToView( point, pt.h, pt.v, &stat ); if (!stat) { stat.perror("Could not get position"); continue; } if ( point_in_lasso( pt ) ) { singleComponent = edgeIter.edge(); newList.add (dagPath, singleComponent); } } break; } case MFn::kMeshPolygonComponent: { MItMeshPolygon polygonIter( dagPath, component, &stat ); for ( ; !polygonIter.isDone(); polygonIter.next() ) { point = polygonIter.center(MSpace::kWorld, &stat ); view.worldToView( point, pt.h, pt.v, &stat ); if (!stat) { stat.perror("Could not get position"); continue; } if ( point_in_lasso( pt ) ) { singleComponent = polygonIter.polygon(); newList.add (dagPath, singleComponent); } } break; } default: #ifdef DEBUG cerr << "Selected unsupported type: (" << component.apiType() << "): " << component.apiTypeStr() << endl; #endif /* DEBUG */ continue; } } // Warn user if zie is trying to select objects rather than components. if (foundEntireObjects && !foundComponents) { MGlobal::displayWarning("lassoTool can only select components, not entire objects."); } // Update the selection list as indicated by the modifier keys. MGlobal::selectCommand(newList, listAdjustment); // Free the memory that held our lasso points. free(lasso); lasso = (coord*) 0; maxSize = 0; num_points = 0; return MS::kSuccess; }