int SelectRingToolCmd2::navigateFace( const MDagPath &dagPath, const int faceIndex, const int edgeIndex, const Location loc ) { int prevIndex; MItMeshPolygon polyIter( dagPath ); polyIter.setIndex( faceIndex, prevIndex ); // Get the face's edges MIntArray edges; polyIter.getEdges( edges ); // Find the edge in the current face unsigned int i; for( i=0; i < edges.length(); i++ ) { if( edgeIndex == edges[i] ) { int offset; if( loc == OPPOSITE ) offset = edges.length() / 2; else offset = (loc == NEXT) ? 1 : -1; return edges[ (i + offset) % edges.length() ]; } } return -1; // Should never reach here }
MStatus meshInfo3::doIt( const MArgList& args ) { MStatus stat = MS::kSuccess; MSelectionList selection; MGlobal::getActiveSelectionList( selection ); MDagPath dagPath; MObject component; int i, polyCount, polyIndex, vertCount; MPoint p; MString txt; MItSelectionList iter( selection ); for ( ; !iter.isDone(); iter.next() ) { iter.getDagPath( dagPath, component ); MItMeshPolygon polyIter( dagPath, component, &stat ); if( stat == MS::kSuccess ) { txt += MString( "Object: " ) + dagPath.fullPathName() + "\n"; polyCount = polyIter.count(); txt += MString("# Polygons: ") + polyCount + "\n"; for( ; !polyIter.isDone(); polyIter.next() ) { polyIndex = polyIter.index(); txt += MString("Poly ") + polyIndex + "\n"; vertCount = polyIter.polygonVertexCount(); txt += MString(" # Verts: ") + vertCount + "\n"; for( i=0; i < vertCount; i++ ) { p = polyIter.point( i, MSpace::kWorld ); txt += MString(" (") + p.x + ", " + p.y + ", " + p.z + ")"; } txt += "\n"; } } } MGlobal::displayInfo( txt ); return MS::kSuccess; }
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 visualizeMeshNode::draw( M3dView & view, const MDagPath & path, M3dView::DisplayStyle style, M3dView::DisplayStatus status ) //----------------------------------------------------------------------- { // cout << "cvColor::draw\n"; MStatus stat; MObject thisNode = thisMObject(); MPlug plug(thisNode, drawingEnabled) ; //soll überhaupt etwas gezeichnet werden? bool doDraw; plug.getValue(doDraw); if (!doDraw) return; //Okay, also die restlichen Daten extrahieren //Lokale Variablen float fPointSize; //PointSize holen plug.setAttribute(pointSize); plug.getValue(fPointSize); bool allowBeautyMode = true; // Jetzt das Plug auslesen um herauszufinden, ob man schön zeichnen darf oder nicht // TODO /* // Test HDC dc; dc = view.deviceContext(); PIXELFORMATDESCRIPTOR pfd; int iPixelFormat; // get the current pixel format index iPixelFormat = GetPixelFormat(dc); // obtain a detailed description of that pixel format int returnVal = DescribePixelFormat(dc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); //cout<<pfd.nSize<<endl; //cout<<sizeof(PIXELFORMATDESCRIPTOR)<<endl; cout<<pfd.iPixelType<<" = ReturnVal"<<endl; cout<<returnVal<<" = ReturnVal"<<endl; cout<<iPixelFormat<<" = PixelFormat"<<endl; */ //Farbe holen -> Diese Schreibweise hat den (hier unbedeutenden) Vorteil, dass Objekte automatisch zerstört werden - sie existieren nur innerhalb der Klammern { MColor tmpColor; plug.setAttribute(vtxColorObj); MObject colorObj; plug.getValue(colorObj); MFnNumericData numDataFn(colorObj); numDataFn.getData(tmpColor.r, tmpColor.g, tmpColor.b); //wenn sich die Farben verändert haben, dann die liste updaten - und alles neuzeichnen if(tmpColor != vtxColor) { vtxColor = tmpColor; listNeedsUpdate = true; } plug.setAttribute(vtxColorObj2); plug.getValue(colorObj); numDataFn.setObject(colorObj); numDataFn.getData(tmpColor.r, tmpColor.g, tmpColor.b); if(tmpColor != vtxColor2) { vtxColor2 = tmpColor; listNeedsUpdate = true; } } //jetzt noch die Node ermuntern, die comuteMethode aufzurufen plug.setAttribute(vtxLocations); bool dummy; plug.getValue(dummy); //vtxWeights müssen gesetzt sein if(vtxWeightArray.length() == 0) return; //MeshData holen plug.setAttribute(inputMesh); MObject meshData; plug.getValue(meshData); visualizeMeshNode::meshStatus mStat = getMeshStatus(); // Wenn sich der Anezigstatus des Meshes ändert, dann muss die DisplayList neu erstellt werden // Nur um den PolygonOffset zu aktualisieren if(mStat != lastStat) { lastStat = mStat; listNeedsUpdate; } //if( mStat == kNone) // Nichts zeichnen, wenn nix selected // return; view.beginGL(); // view.beginOverlayDrawing(); //Im PointMode werden PointsGezeigt, und wenn das Objekt selected ist (dann funzt shaded nicht mehr) if( style == M3dView::kPoints || (mStat == kSelected ) || wasInCompute || !allowBeautyMode) { //VertiIter initialisieren MItMeshVertex vertIter(meshData); drawPoints(vertIter, fPointSize); // Das updaten der DisplayLists ist zu langsam, weshalb automatisch vtxMode genommen wird wasInCompute = false; } else {//in diesem Modus werden Faces gezeichnet, mit entsprechenden alphawerten als zeichen ihrer Farbe MItMeshPolygon polyIter(meshData); MItMeshVertex vertIter(meshData); //Die displayList prüfen if( (listNeedsUpdate & !wasInCompute) || lastDMode != style ) {//neue Liste erzeugen - wird eigentlich nur einmal pro drawAktion gemacht lastDMode = style; if( list != 450000 ) //alte liste löschen glDeleteLists(list, 1); list = glGenLists(1); if(glIsList(list)) { listNeedsUpdate = wasInCompute = false; //####################### //NEUE LISTE AUFZEICHNEN //####################### glNewList(list, GL_COMPILE_AND_EXECUTE); //drawShaded(polyIter, vertIter, style, mStat); drawShadedTriangles(polyIter, vertIter, style, mStat); //####################### //ENDE LISTE AUFZEICHNEN //####################### glEndList(); } else { //fehler, also alles ohne displayList zeichnen //drawShaded(polyIter, vertIter, style, mStat); drawShadedTriangles(polyIter, vertIter, style, mStat); } } else { glCallList(list); wasInCompute = false; } } view.endGL(); // view.endOverlayDrawing(); }
// Private Methods // bool splitUV::validateUVs() // // Description: // // Validate the UVs for the splitUV operation. UVs are valid only if they are shared // by more than one face. While the splitUVNode is smart enough to not process the // split if a UV is not splittable, a splitUV node is still created by the polyModifierCmd. // So call this method to validate the UVs before calling doModifyPoly(). // // validateUVs() will return true so long as there is at least one valid UV. It will // also prune out any invalid UVs from both the component list and UVId array. // { // Get the mesh that we are operating on // MDagPath dagPath = getMeshNode(); MObject mesh = dagPath.node(); // Get the number of faces sharing the selected UVs // MFnMesh meshFn( mesh ); MItMeshPolygon polyIter( mesh ); MIntArray selUVFaceCountArray; int i; int j; int count = 0; int selUVsCount = fSelUVs.length(); for( i = 0; i < selUVsCount; i++ ) { for( ; !polyIter.isDone(); polyIter.next() ) { if( polyIter.hasUVs() ) { int polyVertCount = polyIter.polygonVertexCount(); for( j = 0; j < polyVertCount; j++ ) { int UVIndex = 0; polyIter.getUVIndex(j, UVIndex); if( UVIndex == fSelUVs[i] ) { count++; break; } } } } selUVFaceCountArray.append(count); } // Now, check to make sure that at least one UV is being shared by more than one // face. So long as we have one UV that we can operate on, we should proceed and let // the splitUVNode ignore the UVs which are only shared by one face. // bool isValid = false; MIntArray validUVIndices; for( i = 0; i < selUVsCount; i++ ) { if( selUVFaceCountArray[i] > 1 ) { isValid = true; validUVIndices.append(i); } } if( isValid ) { pruneUVs( validUVIndices ); } return isValid; }
MStatus skinClusterWeights::redoIt() { MStatus status; unsigned int ptr = 0; MSelectionList selList; int geomLen = geometryArray.length(); fDagPathArray.setLength(geomLen); fComponentArray.setLength(geomLen); fInfluenceIndexArrayPtrArray = new MIntArray[geomLen]; fWeightsPtrArray = new MDoubleArray[geomLen]; for (int i = 0; i < geomLen; i++) { MDagPath dagPath; MObject component; selList.clear(); selList.add(geometryArray[i]); MStatus status = selList.getDagPath(0, dagPath, component); if (status != MS::kSuccess) { continue; } if (component.isNull()) dagPath.extendToShape(); MObject skinCluster = findSkinCluster(dagPath); if (!isSkinClusterIncluded(skinCluster)) { continue; } MFnSkinCluster skinClusterFn(skinCluster, &status); if (status != MS::kSuccess) { continue; } MIntArray influenceIndexArray; populateInfluenceIndexArray(skinClusterFn, influenceIndexArray); unsigned numInf = influenceIndexArray.length(); if (numInf == 0) continue; unsigned numCV = 0; if (dagPath.node().hasFn(MFn::kMesh)) { MItMeshVertex polyIter(dagPath, component, &status); if (status == MS::kSuccess) { numCV = polyIter.count(); } } else if (dagPath.node().hasFn(MFn::kNurbsSurface)) { MItSurfaceCV nurbsIter(dagPath, component, true, &status); if (status == MS::kSuccess) { while (!nurbsIter.isDone()) { numCV++; nurbsIter.next(); } } } else if (dagPath.node().hasFn(MFn::kNurbsCurve)) { MItCurveCV curveIter(dagPath, component, &status); if (status == MS::kSuccess) { while (!curveIter.isDone()) { numCV++; curveIter.next(); } } } unsigned numEntry = numCV * numInf; if (numEntry > 0) { MDoubleArray weights(numEntry); unsigned int numWeights = weightArray.length(); if (assignAllToSingle) { if (numInf <= numWeights) { for (unsigned j = 0; j < numEntry; j++) { weights[j] = weightArray[j % numInf]; } } else { MGlobal::displayError("Not enough weights specified\n"); return MS::kFailure; } } else { for (unsigned j = 0; j < numEntry; j++, ptr++) { if (ptr < numWeights) { weights[j] = weightArray[ptr]; } else { MGlobal::displayError("Not enough weights specified\n"); return MS::kFailure; } } } // support for undo fDagPathArray[i] = dagPath; fComponentArray[i] = component; fInfluenceIndexArrayPtrArray[i] = influenceIndexArray; MDoubleArray oldWeights; skinClusterFn.getWeights(dagPath, component, influenceIndexArray, oldWeights); fWeightsPtrArray[i] = oldWeights; skinClusterFn.setWeights(dagPath, component, influenceIndexArray, weights); } } return MS::kSuccess; }
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 splitUVFty::doIt() // // Description: // Performs the actual splitUV operation on the given object and UVs // { MStatus status = MS::kSuccess; ////////////////////////////////////// // Declare our processing variables // ////////////////////////////////////// MString selUVSet; // Face Id and Face Offset map to the selected UVs // MIntArray selUVFaceIdMap; MIntArray selUVFaceOffsetMap; // Local Vertex Index map to the selected UVs // MIntArray selUVLocalVertIdMap; /////////////////////////////////////////////////// // Collect necessary information for the splitUV // // // // - uvSet // // - faceIds / localVertIds per selected UV // /////////////////////////////////////////////////// MFnMesh meshFn( fMesh ); meshFn.getCurrentUVSetName( selUVSet ); int i; int j; int offset = 0; int selUVsCount = fSelUVs.length(); MItMeshPolygon polyIter( fMesh ); for( i = 0; i < selUVsCount; i++ ) { selUVFaceOffsetMap.append(offset); for( polyIter.reset(); !polyIter.isDone(); polyIter.next() ) { if( polyIter.hasUVs() ) { int polyVertCount = polyIter.polygonVertexCount(); for( j = 0; j < polyVertCount; j++ ) { int UVIndex = 0; polyIter.getUVIndex(j, UVIndex); if( UVIndex == fSelUVs[i] ) { selUVFaceIdMap.append( polyIter.index() ); selUVLocalVertIdMap.append(j); offset++; break; } } } } } // Store total length of the faceId map in the last element of // the offset map so that there is a way to get the number of faces // sharing each of the selected UVs // selUVFaceOffsetMap.append(offset); ///////////////////////////////// // Begin the splitUV operation // ///////////////////////////////// int currentUVCount = meshFn.numUVs( selUVSet ); for( i = 0; i < selUVsCount; i++ ) { // Get the current FaceId map offset // offset = selUVFaceOffsetMap[i]; // Get the U and V values of the current UV // float u; float v; int uvId = fSelUVs[i]; meshFn.getUV( uvId, u, v, &selUVSet ); // Get the number of faces sharing the current UV // int faceCount = selUVFaceOffsetMap[i + 1] - selUVFaceOffsetMap[i]; // Arbitrarily choose that the last faceId in the list of faces // sharing this UV, will keep the original UV. // for( j = 0; j < faceCount - 1; j++ ) { meshFn.setUV( currentUVCount, u, v, &selUVSet ); int localVertId = selUVLocalVertIdMap[offset]; int faceId = selUVFaceIdMap[offset]; meshFn.assignUV( faceId, localVertId, currentUVCount, &selUVSet ); currentUVCount++; offset++; } } return status; }
//-------------------------------------------------------------------------------------- void componentConverter::vtxToConnectedFaceVtx(const MIntArray& vtxIDs, MIntArray& outVtxIDs) //-------------------------------------------------------------------------------------- { // Wandelt die vtxSelection in die connecteten faceVtx um (die Vertizen der verbundenen Faces) // Die gegebenen Vtx werden nicht mit hinzugefuegt outVtxIDs.setLength(0); outVtxIDs.setSizeIncrement(vtxIDs.length() / 4); MItMeshVertex vertIter(mesh); MItMeshPolygon polyIter(mesh); BPT_BA allFaces(polyIter.count(), true); BPT_BA allVtx(vertIter.count(), true); // BA mit den vtxIDs initialisieren // Die vtxIds bereits jetzt false setzen allVtx.setBits(vtxIDs, false); MIntArray conFaces; // hlt die verbundenen Faces MIntArray conVtx; // Im face enthaltene Vtx uint i, x, y , l2,l3, l = vtxIDs.length(); for(i = 0; i < l; i++) { vertIter .setIndex(vtxIDs[i], tmp); vertIter.getConnectedFaces(conFaces); // Jetzt die gueltigen conFaces holen conFaces = allFaces & conFaces; // Jetzt die conFaces false setzen, danit diese nicht wieder bearbeitet werden allFaces.setBits(conFaces, false); l2 = conFaces.length(); // jetzt die restlichen Faces on the fly in Vtx umwandeln for(x = 0; x < l2; x++) { // Jetzt die vertizen des Faces holen und auf Array packen, wenn sie einzigartig sind polyIter.setIndex(conFaces[x], tmp); polyIter.getVertices(conVtx); // Checken, ob Vtx einzigartig sind conVtx = allVtx & conVtx; // Das was uebrig bleibt im BitArray deaktivieren und zum outArray hinzufuegen allVtx.setBits(conVtx, false); l3 = conVtx.length(); for(y = 0; y < l3; y++) { outVtxIDs.append(conVtx[y]); } } } }