MStatus compute_halfedge_indices(MIntArray &nFV, MIntArray &F, MIntArray &selV, MIntArray &selF, MIntArray &selHE) { MIntArray F2H(nFV.length(), 0); size_t cumsum = 0; for (size_t k=0; k<nFV.length(); k++) { F2H[k] = cumsum; cumsum += nFV[k]; } selHE.setLength(selF.length()); for (size_t k=0; k<selF.length(); k++) { size_t cV = selV[k]; size_t cF = selF[k]; size_t cnFV = nFV[cF]; size_t cF2H = F2H[cF]; for (size_t kFV=0; kFV<cnFV; kFV++) { if (F[cF2H+kFV]==cV) { selHE[k] = cF2H + kFV; break; } } } return MS::kSuccess; }
// ---------------------------------------- bool GeometryPolygonExporter::getPolygonVertexCount( MItMeshPolygon &meshPolygonsIter, unsigned long &numVertices ) { bool addVertexCount = false; // Establish the number of vertexes in the polygon. // We don't need the vertex count list for triangulation if ( triangulated ) return addVertexCount; // The number of vertices numVertices = 0; // Retrieve the vertices and increment polygon count // Get the number of vertices in the current mesh's polygon unsigned long polygonVertexCount = meshPolygonsIter.polygonVertexCount(); if ( polygonVertexCount >= 3 ) { #ifdef VALIDATE_DATA // Skip over any duplicate vertices in this face. // Very rarely, a cunning user manages to corrupt // a face entry on the mesh and somehow configure // a face to include the same vertex multiple times. // This will cause the read-back of this data to // reject the face, and can crash other COLLADA // consumers, so better to lose the data here MIntArray vertexIndices; vertexIndices.setLength ( polygonVertexCount ); for ( int pv = 0; pv < polygonVertexCount; ++pv ) { vertexIndices[pv] = pv; } for ( uint n = 0; n < vertexIndices.length() - 1; ++n ) { for ( uint m = n + 1; m < vertexIndices.length(); ) { if ( vertexIndices[n] == vertexIndices[m] ) { vertexIndices.remove ( m ); } else ++m; } } // Get the number of vertices of the current polygon. numVertices = vertexIndices.length(); #else // Get the number of vertices of the current polygon. numVertices = polygonVertexCount; #endif addVertexCount = true; } return addVertexCount; }
void load_from_hds(HDS &hds, MFloatPointArray &points, MIntArray &nFV, MIntArray &F) { size_t nV = hds.nV(); size_t nF = hds.nF(); size_t nIHE = hds.nIHE(); points.setLength(nV); for (size_t k=0; k<nV; k++) { points[k](0) = hds.V[3*k+0]; points[k](1) = hds.V[3*k+1]; points[k](2) = hds.V[3*k+2]; } nFV.setLength(nF); for (size_t k=0; k<nF; k++) nFV[k] = hds.nFV[k]; F.setLength(nIHE); for (size_t k=0; k<nIHE; k++) F[k] = hds.tip[k]; }
void create_subdivided_face(int sdRes, int nV, double *uvs, double *itv, int Tidx, MFloatArray &uA, MFloatArray &vA, MIntArray &uvIdx) { HDS hds; hds.V.setDims(2, nV); memcpy(&hds.V.v[0], uvs, 2*nV*sizeof(double)); hds.nFV.setDims(1, 1); hds.nFV[0] = nV; hds.tip.setDims(1, nV); for (size_t k=0; k<nV; k++) { hds.tip[k] = k; } finalize_HDS(hds); size_t nHE = hds.nHE(), nIHE = hds.nIHE();⟵ hds.T.setDims(1, nHE); hds.itv.setDims(1, nHE); memset(&hds.T.v[0], 0, nHE*sizeof(bool)); if (nV==5) hds.T[Tidx] = 1; memcpy(&hds.itv.v[0], itv, nV*sizeof(double)); // border halfedge tags for (size_t k=nIHE; k<nHE; k++) { hds.itv[k] = hds.itv[hds.twin[k]]; } TCC_MAX::linear_subdivide(hds, sdRes); int sd_nV = hds.nV(); int sd_nIHE = hds.nIHE(); uA.setLength(sd_nV); vA.setLength(sd_nV); for (int k=0; k<sd_nV; k++) { uA[k] = hds.V[2*k+0]; vA[k] = hds.V[2*k+1]; } uvIdx.setLength(sd_nIHE); for (int k=0; k<sd_nIHE; k++) { uvIdx[k]=hds.tip[k]; } }
// Propagate objectGroups from inMesh to subdivided outMesh // Note: Currently only supporting facet groups (for per-facet shading) MStatus createSmoothMesh_objectGroups(const MFnMeshData &inMeshDat, int subdivisionLevel, MFnMeshData &newMeshDat) { MStatus returnStatus; int facesPerBaseFace = (int)(pow(4.0f, subdivisionLevel)); MIntArray newCompElems; for(unsigned int gi=0; gi < inMeshDat.objectGroupCount(); gi++) { unsigned int compId = inMeshDat.objectGroup(gi, &returnStatus); MCHECKERR(returnStatus, "cannot get objectGroup() comp ID."); MFn::Type compType = inMeshDat.objectGroupType(compId, &returnStatus); MCHECKERR(returnStatus, "cannot get objectGroupType()."); // get elements from inMesh objectGroupComponent MIntArray compElems; MFnSingleIndexedComponent compFn(inMeshDat.objectGroupComponent(compId), &returnStatus ); MCHECKERR(returnStatus, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent()."); compFn.getElements(compElems); // Only supporting kMeshPolygonComponent ObjectGroups at this time // Skip the other types if (compType == MFn::kMeshPolygonComponent) { // convert/populate newCompElems from compElems of inMesh // (with new face indices) to outMesh newCompElems.setLength( compElems.length() * facesPerBaseFace ); for (unsigned int i=0; i < compElems.length(); i++) { int startElemIndex = i * facesPerBaseFace; int startElemValue = compElems[i] * facesPerBaseFace; for (int j=0; j < facesPerBaseFace; j++) { newCompElems[startElemIndex+j] = startElemValue+j; } } // create comp createComp(newMeshDat, compType, compId, newCompElems); } } return MS::kSuccess; }
double SGIntersectFunction::getShapeIntersectDist(const SGShape& targetShape, const MMatrix& shapeMatrix, const MMatrix& camMatrix) { MPoint mousePoint(SGMouse::x, SGMouse::y, 0); MMatrix worldToView = SGMatrix::getWorldToViewMatrix(camMatrix); MPointArray points; points.setLength(targetShape.numPoints); for (int i = 0; i < targetShape.numPoints; i++) { float x = targetShape.points[i * 3 + 0]; float y = targetShape.points[i * 3 + 1]; float z = targetShape.points[i * 3 + 2]; MPoint point(x, y, z); points[i] = SGMatrix::getViewPointFromWorld(point * shapeMatrix, camMatrix, &worldToView ); } MIntArray indices; indices.setLength(targetShape.numPoly * targetShape.interval); for (int i = 0; i < targetShape.numPoly * targetShape.interval; i++){ indices[i] = targetShape.indices[i]; } double closeDist = 10000000.0; for (int i = 0; i < targetShape.numPoly; i++){ int index1 = indices[i*3]; int index2 = indices[i*3+1]; int index3 = indices[i*3+2]; double dist1 = SGMatrix::getLineDist(points[index1], points[index2], mousePoint); double dist2 = SGMatrix::getLineDist(points[index2], points[index3], mousePoint); double dist3 = SGMatrix::getLineDist(points[index3], points[index1], mousePoint); if (dist1 < closeDist) closeDist = dist1; if (dist2 < closeDist) closeDist = dist2; if (dist3 < closeDist) closeDist = dist3; } return closeDist; }
void CalculateSampleWeights(const std::map<int, double>& distances, double radius, MIntArray& vertexIds, MDoubleArray& weights) { std::map<int, double>::const_iterator itDistance; std::vector<std::pair<int, double> > samples; for (itDistance = distances.begin(); itDistance != distances.end(); itDistance++) { double x = itDistance->second; double w = 1.0 - (x/radius); samples.push_back(std::pair<int, double>(itDistance->first, w)); } // Make the samples a multiple of 4 so we can use fast intrinsics! int remainder = 4 - ((samples.size()-1) % 4); if (remainder != 4) { for (int i = 0; i < remainder; ++i) { samples.push_back(std::pair<int, double>(0, 0.0)); } } unsigned int length = (unsigned int)samples.size(); weights.setLength(length); vertexIds.setLength(length); std::sort(samples.begin(), samples.end(), SampleSort); std::vector<std::pair<int, double> >::iterator iter; int ii = 0; double sum = 0.0; for (iter = samples.begin(); iter != samples.end(); ++iter, ++ii) { vertexIds[ii] = (*iter).first; weights[ii] = (*iter).second; sum += (*iter).second; } assert(sum > 0.0); // Normalize the weights for (unsigned int i = 0; i < weights.length(); ++i) { weights[i] /= sum; } }
bool tm_polygon_edgestoring::calculate( MIntArray &edgesArray) { if(!objectIsSet) { MGlobal::displayError("tm_polygon_edgestoring::calculate - Object is not set."); return false; } MFnMesh meshFn( meshObject); MItMeshEdge edgeIt(meshObject); MItMeshPolygon faceIt(meshObject); unsigned numInputEdges = edgesArray.length(); int *visitedEdges = new int[numInputEdges]; for( unsigned e = 0; e < numInputEdges; e++) visitedEdges[e] = 0; std::list <int> ringEdgesList; int prevIndex; MIntArray faces; MIntArray edgeFaces; MIntArray faceEdges; int edgeIndex = edgesArray[0]; ringEdgesList.push_back( edgeIndex); visitedEdges[0] = 1; edgeIt.setIndex( edgeIndex, prevIndex); edgeIt.getConnectedFaces( faces); unsigned numFaces = faces.length(); unsigned numFaceEdges; for( unsigned face = 0; face < numFaces; face++) { edgeIndex = edgesArray[0]; int lastFace, newFace; if( face == 1) lastFace = faces[0]; else lastFace = -1; unsigned COUNTER = 0; while( COUNTER < 32000) { COUNTER++; edgeIt.setIndex( edgeIndex, prevIndex); edgeIt.getConnectedFaces( edgeFaces); if(edgeFaces.length() > 1) { if( edgeFaces[0] == lastFace) newFace = edgeFaces[1]; else newFace = edgeFaces[0]; } else newFace = edgeFaces[0]; faceIt.setIndex( newFace, prevIndex); lastFace = newFace; bool founded = false; for( unsigned e = 0; e < numInputEdges; e++) { if( edgesArray[e] == edgeIndex) continue; if( visitedEdges[e] == 1) continue; faceIt.getEdges( faceEdges); numFaceEdges = faceEdges.length(); for( unsigned fe = 0; fe < numFaceEdges; fe++) { if( faceEdges[fe] == edgesArray[e]) { founded = true; edgeIndex = edgesArray[e]; visitedEdges[e] = 1; if( face == 0) ringEdgesList.push_front( edgeIndex); else ringEdgesList.push_back( edgeIndex); } if( founded) break; } if( founded) break; } if(!founded) break; } } if (visitedEdges != NULL) delete [] visitedEdges; unsigned numRingEdges = (unsigned)ringEdgesList.size(); edgesArray.setLength( numRingEdges); for( unsigned e = 0; e < numRingEdges; e++) { edgesArray[e] = *ringEdgesList.begin(); ringEdgesList.pop_front(); } return true; }
void ToMayaMeshConverter::addUVSet( MFnMesh &fnMesh, const MIntArray &polygonCounts, IECore::ConstMeshPrimitivePtr mesh, const std::string &sPrimVarName, const std::string &tPrimVarName, const std::string &stIdPrimVarName, MString *uvSetName ) const { IECore::PrimitiveVariableMap::const_iterator sIt = mesh->variables.find( sPrimVarName ); bool haveS = sIt != mesh->variables.end(); IECore::PrimitiveVariableMap::const_iterator tIt = mesh->variables.find( tPrimVarName ); bool haveT = tIt != mesh->variables.end(); IECore::PrimitiveVariableMap::const_iterator stIdIt = mesh->variables.find( stIdPrimVarName ); bool haveSTId = stIdIt != mesh->variables.end(); if ( haveS && haveT ) { if ( sIt->second.interpolation != IECore::PrimitiveVariable::FaceVarying ) { IECore::msg( IECore::Msg::Warning,"ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported interpolation (expected FaceVarying).") % sPrimVarName ); return; } if ( tIt->second.interpolation != IECore::PrimitiveVariable::FaceVarying ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported interpolation (expected FaceVarying).") % tPrimVarName); return; } if ( !sIt->second.data ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has no data." ) % sPrimVarName ); } if ( !tIt->second.data ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has no data." ) % tPrimVarName ); } /// \todo Employ some M*Array converters to simplify this int numUVs = mesh->variableSize( IECore::PrimitiveVariable::FaceVarying ); IECore::ConstFloatVectorDataPtr u = IECore::runTimeCast<const IECore::FloatVectorData>(sIt->second.data); if ( !u ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported type \"%s\"." ) % sPrimVarName % sIt->second.data->typeName() ); return; } assert( (int)u->readable().size() == numUVs ); IECore::ConstFloatVectorDataPtr v = IECore::runTimeCast<const IECore::FloatVectorData>(tIt->second.data); if ( !v ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported type \"%s\"." ) % tPrimVarName % tIt->second.data->typeName() ); return; } assert( (int)v->readable().size() == numUVs ); const std::vector<float> &uAll = u->readable(); const std::vector<float> &vAll = v->readable(); if ( uvSetName ) { bool setExists = false; MStringArray existingSets; fnMesh.getUVSetNames( existingSets ); for ( unsigned i=0; i < existingSets.length(); ++i ) { if ( *uvSetName == existingSets[i] ) { fnMesh.clearUVs( uvSetName ); setExists = true; break; } } if ( !setExists ) { MDagPath dag; MStatus s = fnMesh.getPath( dag ); if ( s ) { fnMesh.createUVSetWithName( *uvSetName ); } else { fnMesh.createUVSetDataMeshWithName( *uvSetName ); } } } MIntArray uvIds; uvIds.setLength( numUVs ); MFloatArray uArray; MFloatArray vArray; if( haveSTId ) { // Get compressed uv values by matching them with their uvId. IECore::ConstIntVectorDataPtr uvId = IECore::runTimeCast<const IECore::IntVectorData>(stIdIt->second.data); if ( !uvId ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"%s\" has unsupported type \"%s\"." ) % stIdPrimVarName % stIdIt->second.data->typeName() ); return; } const std::vector<int> &uvIdData = uvId->readable(); assert( (int)uvIdData.size() == numUVs ); int highestId = 0; for ( int i = 0; i < numUVs; i++) { uvIds[i] = uvIdData[i]; if( uvIdData[i] > highestId ) { highestId = uvIdData[i]; } } // u and v arrays need only be as long as the number of unique uvIds uArray.setLength( highestId + 1 ); vArray.setLength( highestId + 1 ); for ( int i = 0; i < numUVs; i++ ) { uArray[ uvIds[i] ] = uAll[i]; // FromMayaMeshConverter does the opposite of this vArray[ uvIds[i] ] = 1 - vAll[i]; } } else { // If for some reason we cannot find the uv indices, set the UVs using the old way // the performances in maya won't be good (for weigth painting in particular) uArray.setLength( numUVs ); vArray.setLength( numUVs ); for ( int i = 0; i < numUVs; i++) { uArray[i] = u->readable()[i]; // FromMayaMeshConverter does the opposite of this vArray[i] = 1 - v->readable()[i]; } for ( int i = 0; i < numUVs; i++) { uvIds[i] = i; } } MStatus s = fnMesh.setUVs( uArray, vArray, uvSetName ); if ( !s ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to set UVs." ); return; } s = fnMesh.assignUVs( polygonCounts, uvIds, uvSetName ); if ( !s ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to assign UVs." ); return; } } else if ( haveS ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "Primitive variable \"%s\" found, but not \"%s\"." ) % sPrimVarName % tPrimVarName ); } else if ( haveT ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "Primitive variable \"%s\" found, but not \"%s\"." ) % tPrimVarName % sPrimVarName ); } else { assert( !uvSetName ); } }
bool ToMayaMeshConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const { MStatus s; IECore::ConstMeshPrimitivePtr mesh = IECore::runTimeCast<const IECore::MeshPrimitive>( from ); assert( mesh ); if ( !mesh->arePrimitiveVariablesValid() ) { return false; } MFloatPointArray vertexArray; MIntArray polygonCounts; MIntArray polygonConnects; MFnMesh fnMesh; int numVertices = 0; IECore::PrimitiveVariableMap::const_iterator it = mesh->variables.find("P"); if ( it != mesh->variables.end() ) { /// \todo Employ some M*Array converters to simplify this IECore::ConstV3fVectorDataPtr p = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data); if (p) { numVertices = p->readable().size(); vertexArray.setLength( numVertices ); for (int i = 0; i < numVertices; i++) { vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3f>( p->readable()[i] ); } } else { IECore::ConstV3dVectorDataPtr p = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data); if (p) { numVertices = p->readable().size(); vertexArray.setLength( numVertices ); for (int i = 0; i < numVertices; i++) { vertexArray[i] = IECore::convert<MFloatPoint, Imath::V3d>( p->readable()[i] ); } } else { // "P" is not convertible to an array of "points" return false; } } } IECore::ConstIntVectorDataPtr verticesPerFace = mesh->verticesPerFace(); assert( verticesPerFace ); int numPolygons = verticesPerFace->readable().size(); polygonCounts.setLength( numPolygons ); for (int i = 0; i < numPolygons; i++) { polygonCounts[i] = verticesPerFace->readable()[i]; } IECore::ConstIntVectorDataPtr vertexIds = mesh->vertexIds(); assert( vertexIds ); int numPolygonConnects = vertexIds->readable().size(); polygonConnects.setLength( numPolygonConnects ); for (int i = 0; i < numPolygonConnects; i++) { polygonConnects[i] = vertexIds->readable()[i]; } MObject mObj = fnMesh.create( numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, to, &s ); if (!s) { return false; } it = mesh->variables.find("N"); if ( it != mesh->variables.end() ) { if (it->second.interpolation == IECore::PrimitiveVariable::FaceVarying ) { /// \todo Employ some M*Array converters to simplify this MVectorArray vertexNormalsArray; IECore::ConstV3fVectorDataPtr n = IECore::runTimeCast<const IECore::V3fVectorData>(it->second.data); if (n) { int numVertexNormals = n->readable().size(); vertexNormalsArray.setLength( numVertexNormals ); for (int i = 0; i < numVertexNormals; i++) { vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3f>( n->readable()[i] ); } } else { IECore::ConstV3dVectorDataPtr n = IECore::runTimeCast<const IECore::V3dVectorData>(it->second.data); if (n) { int numVertexNormals = n->readable().size(); vertexNormalsArray.setLength( numVertexNormals ); for (int i = 0; i < numVertexNormals; i++) { vertexNormalsArray[i] = IECore::convert<MVector, Imath::V3d>( n->readable()[i] ); } } else { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", boost::format( "PrimitiveVariable \"N\" has unsupported type \"%s\"." ) % it->second.data->typeName() ); } } if ( vertexNormalsArray.length() ) { MStatus status; MItMeshPolygon itPolygon( mObj, &status ); if( status != MS::kSuccess ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Failed to create mesh iterator" ); } unsigned v = 0; MIntArray vertexIds; MIntArray faceIds; for ( ; !itPolygon.isDone(); itPolygon.next() ) { for ( v=0; v < itPolygon.polygonVertexCount(); ++v ) { faceIds.append( itPolygon.index() ); vertexIds.append( itPolygon.vertexIndex( v ) ); } } if( !fnMesh.setFaceVertexNormals( vertexNormalsArray, faceIds, vertexIds ) ) { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "Setting normals failed" ); } } } else { IECore::msg( IECore::Msg::Warning, "ToMayaMeshConverter::doConversion", "PrimitiveVariable \"N\" has unsupported interpolation (expected FaceVarying)." ); } } bool haveDefaultUVs = false; IECore::PrimitiveVariableMap::const_iterator sIt = mesh->variables.find( "s" ); IECore::RefCountedPtr sDataRef = ( sIt == mesh->variables.end() ) ? 0 : static_cast<IECore::RefCountedPtr>( sIt->second.data ); /// Add named UV sets std::set< std::string > uvSets; for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it ) { const std::string &sName = it->first; size_t suffixOffset = sName.rfind( "_s" ); if ( ( suffixOffset != std::string::npos) && ( suffixOffset == sName.length() - 2 ) ) { std::string uvSetNameStr = sName.substr( 0, suffixOffset ); if ( uvSetNameStr.size() ) { MString uvSetName = uvSetNameStr.c_str(); std::string tName = uvSetNameStr + "_t"; std::string stIdName = uvSetNameStr + "Indices"; addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName ); uvSets.insert( uvSetNameStr ); if ( sDataRef == static_cast<IECore::RefCountedPtr>( it->second.data ) ) { haveDefaultUVs = true; } } } } /// Add default UV set if it isn't just a reference to a named set if ( !haveDefaultUVs ) { addUVSet( fnMesh, polygonCounts, mesh, "s", "t", "stIndices" ); } // We do the search again, but looking for primvars ending "_t", so we can catch cases where either "UVSETNAME_s" or "UVSETNAME_t" is present, but not both, taking care // not to attempt adding any duplicate sets for ( it = mesh->variables.begin(); it != mesh->variables.end(); ++it ) { const std::string &tName = it->first; size_t suffixOffset = tName.rfind( "_t" ); if ( ( suffixOffset != std::string::npos) && ( suffixOffset == tName.length() - 2 ) ) { std::string uvSetNameStr = tName.substr( 0, suffixOffset ); if ( uvSetNameStr.size() && uvSets.find( uvSetNameStr ) == uvSets.end() ) { MString uvSetName = uvSetNameStr.c_str(); std::string sName = uvSetNameStr + "_s"; std::string stIdName = uvSetNameStr + "Indices"; addUVSet( fnMesh, polygonCounts, mesh, sName, tName, stIdName, &uvSetName ); uvSets.insert( uvSetNameStr ); } } } /// If we're making a mesh node (rather than a mesh data) then make sure it belongs /// to the default shading group and add the ieMeshInterpolation attribute. MObject oMesh = fnMesh.object(); if( oMesh.apiType()==MFn::kMesh ) { assignDefaultShadingGroup( oMesh ); setMeshInterpolationAttribute( oMesh, mesh->interpolation() ); } /// \todo Other primvars, e.g. vertex color ("Cs") return true; }
bool writeMeshStaticDataInCache(drn_writer_t * cache, DRNTDagNode & node, drn_scene::MeshContainer * meshContainer, DRNTHardEdge & he, MeshExportMode mode) { uint32_t drnStatus = 0; MStatus status; MFnMesh mesh(node.dagPath); if (mode == MESH_EXPORT_FULL_TOPOLOGY) { meshContainer->numPolygons = mesh.numPolygons(&status); meshContainer->numVertices = mesh.numVertices(&status); meshContainer->numNormals = mesh.numNormals(&status); } else { meshContainer->numPolygons = 0; meshContainer->numVertices = 0; meshContainer->numNormals = 0; } MIntArray vertexCount; MIntArray vertexList; MIntArray normalCount; MIntArray normalList; MIntArray uvCounts; MIntArray uvIds; mesh.getAssignedUVs(uvCounts, uvIds); MIntArray triangleCount; MIntArray triangleList; MIntArray triangleNList; MIntArray triangleUVList; mesh.getVertices(vertexCount, vertexList); mesh.getNormalIds(normalCount, normalList); mesh.getTriangles(triangleCount, triangleList); triangleNList.setLength(triangleList.length()); triangleUVList.setLength(triangleList.length()); meshContainer->numTriangles = triangleList.length() / 3; int * vcarray = new int[vertexCount.length()]; int * vlarray = new int[vertexList.length()]; int * ncarray = new int[normalCount.length()]; int * nlarray = new int[normalList.length()]; // Triangulation int poly_idx_offset = 0; int tri_idx_offset = 0; for (int i = 0; i < mesh.numPolygons(); ++i) { for (int j = 0; j < triangleCount[i]; ++j) { for(unsigned int k=0; k < 3; ++k) { int v_idx = triangleList[tri_idx_offset+j*3 + k]; int match = -1; int l = 0; while (match < 0 && l < vertexCount[i]) { if (vertexList[poly_idx_offset+l] == v_idx) match = l; ++l; } triangleNList[tri_idx_offset+j*3 + k] = normalList[poly_idx_offset+match]; int id = 0; if (uvIds.length() != 0) mesh.getPolygonUVid(i, match, id); triangleUVList[tri_idx_offset+j*3 + k] = id; } } poly_idx_offset += vertexCount[i]; tri_idx_offset += 3 * triangleCount[i]; } he.tlist.resize(triangleList.length(), -1); //he.itlist.resize(triangleList.length()); he.itlist.resize(triangleList.length()); //std::map<std::pair<int, int>, int> h; std::map<triplet, int> h; int idx = 0; for (int i = 0, n = triangleList.length(); i != n; ++i) { //std::pair<int, int> p = std::make_pair(triangleList[i], triangleNList[i]); triplet p(triangleList[i], triangleNList[i], triangleUVList[i]); //std::map<std::pair<int, int>, int>::const_iterator match = h.find(p); std::map<triplet, int>::const_iterator match = h.find(p); if (match != h.end()) { he.tlist[i] = match->second; he.itlist[i] = match->first; } else { h[p] = idx; he.tlist[i] = idx; he.itlist[i] = p; ++idx; } } meshContainer->numHwVertices = he.idmax = idx; if (mode == MESH_EXPORT_FULL_TOPOLOGY) { vertexCount.get(vcarray); vertexList.get(vlarray); normalCount.get(ncarray); normalList.get(nlarray); drnStatus = drn_writer_add_chunk(cache, vcarray, sizeof(int) * vertexCount.length()); meshContainer->vertexCountPerFace = drn_writer_get_last_chunk_id(cache); drnStatus = drn_writer_add_chunk(cache, vlarray, sizeof(int) * vertexList.length()); meshContainer->vertexListPerFace = drn_writer_get_last_chunk_id(cache); drnStatus = drn_writer_add_chunk(cache, ncarray, sizeof(int) * normalCount.length()); meshContainer->normalCountPerFace = drn_writer_get_last_chunk_id(cache); drnStatus = drn_writer_add_chunk(cache, nlarray, sizeof(int) * normalList.length()); meshContainer->normalListPerFace = drn_writer_get_last_chunk_id(cache); drnStatus = drn_writer_add_chunk(cache, & (he.tlist[0]), sizeof(int) * he.tlist.size()); meshContainer->triangleList = drn_writer_get_last_chunk_id(cache); delete[] vcarray; delete[] vlarray; delete[] ncarray; delete[] nlarray; } else { meshContainer->numUVSets = 0; drnStatus = drn_writer_add_chunk(cache, & (he.tlist[0]), sizeof(int) * he.tlist.size()); meshContainer->triangleList = drn_writer_get_last_chunk_id(cache); meshContainer->defaultUVSet = 0; } DRNT_DBG_LVL2(std::cout << "trianglelist" << triangleList << std::endl;);
// Propagate objectGroups from inMesh to subdivided outMesh // Note: Currently only supporting facet groups (for per-facet shading) MStatus createSmoothMesh_objectGroups( MFnMesh const & inMeshFn, MFnMeshData const & inMeshDat, MFnMeshData &newMeshDat, int level, int numSubfaces ) { MStatus status; MIntArray newCompElems; std::vector<unsigned int> offsets; // mapping of offsets for subdivided faces for(unsigned int gi=0; gi<inMeshDat.objectGroupCount(); gi++) { unsigned int compId = inMeshDat.objectGroup(gi, &status); MCHECKERR(status, "cannot get objectGroup() comp ID."); MFn::Type compType = inMeshDat.objectGroupType(compId, &status); MCHECKERR(status, "cannot get objectGroupType()."); // Only supporting kMeshPolygonComponent ObjectGroups at this time // Skip the other types if (compType == MFn::kMeshPolygonComponent) { // get elements from inMesh objectGroupComponent MIntArray compElems; MFnSingleIndexedComponent compFn( inMeshDat.objectGroupComponent(compId), &status ); MCHECKERR(status, "cannot get MFnSingleIndexedComponent for inMeshDat.objectGroupComponent()."); compFn.getElements(compElems); if (compElems.length()==0) { continue; } // over-allocation to maximum possible length newCompElems.setLength( numSubfaces ); if (offsets.empty()) { // lazy population of the subface offsets table int nfaces = inMeshFn.numPolygons(); offsets.resize(nfaces); for (int i=0, count=0; i<nfaces; ++i) { int nverts = inMeshFn.polygonVertexCount(i), nsubfaces = computeNumSubfaces(nverts, level); offsets[i] = count; count+=nsubfaces; } } unsigned int idx = 0; // convert/populate newCompElems from compElems of inMesh // (with new face indices) to outMesh for (unsigned int i=0; i < compElems.length(); i++) { int nverts = inMeshFn.polygonVertexCount(compElems[i]), nsubfaces = computeNumSubfaces(nverts, level); unsigned int subFaceOffset = offsets[compElems[i]]; for (int j=0; j<nsubfaces; ++j) { newCompElems[idx++] = subFaceOffset++; } } // resize to actual length newCompElems.setLength( idx ); // create comp createComp(newMeshDat, compType, compId, newCompElems); } } return MS::kSuccess; }
//-------------------------------------------------------------------------------------- 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]); } } } }
MStatus genRod( const MPoint &p0, const MPoint &p1, const double radius, const unsigned int nSegs, int &nPolys, MPointArray &verts, MIntArray &polyCounts, MIntArray &polyConnects ) { verts.clear(); polyCounts.clear(); polyConnects.clear(); unsigned int nCirclePts = nSegs; unsigned int nVerts = 2 * nCirclePts; // Calculate the local axiis of the rod MVector vec( p1 - p0 ); MVector up( 0.0, 1.0, 0.0 ); MVector xAxis, yAxis, zAxis; yAxis = vec.normal(); if( up.isParallel( yAxis, 0.1 ) ) up = MVector( 1.0, 0.0, 0.0 ); xAxis = yAxis ^ up; zAxis = (xAxis ^ yAxis).normal(); xAxis = (yAxis ^ zAxis ).normal(); // Calculate the vertex positions verts.setLength( nVerts ); double angleIncr = 2.0 * M_PI / nSegs; double angle; MPoint p; double x, z; unsigned int i; for( i=0, angle=0; i < nCirclePts; i++, angle += angleIncr ) { // Calculate position in circle x = radius * cos( angle ); z = radius * sin( angle ); p = p0 + x * xAxis + z * zAxis; verts[ i ] = p; p += vec; verts[ i + nCirclePts ] = p; } nPolys = nSegs; // Generate polycounts polyCounts.setLength( nPolys ); for( i=0; i < polyCounts.length(); i++ ) polyCounts[i] = 4; // Generate polyconnects polyConnects.setLength( nPolys * 4 ); polyConnects.clear(); for( i=0; i < nSegs; i++ ) { polyConnects.append( linearIndex( 0, i, 2, nCirclePts ) ); polyConnects.append( linearIndex( 0, i+1, 2, nCirclePts ) ); polyConnects.append( linearIndex( 1, i+1, 2, nCirclePts ) ); polyConnects.append( linearIndex( 1, i, 2, nCirclePts ) ); } return MS::kSuccess; }
// // Change the UVS for the given selection on this mesh object. // /////////////////////////////////////////////////////////////////////////////// MStatus flipUVCmd::getTweakedUVs( const MObject & meshObj, // Object MIntArray & uvList, // UVs to move MFloatArray & uPos, // Moved UVs MFloatArray & vPos ) // Moved UVs { MStatus status; unsigned int i; MFloatArray uArray; MFloatArray vArray; MFnMesh mesh( meshObj ); // Read all UVs from the poly object status = mesh.getUVs(uArray, vArray); CHECK_MSTATUS_AND_RETURN_IT(status); unsigned int nbUvShells = 1; MIntArray uvShellIds; if ((!flipGlobal) || extendToShell) { // First, extract the UV shells. status = mesh.getUvShellsIds(uvShellIds, nbUvShells); CHECK_MSTATUS_AND_RETURN_IT(status); } if (extendToShell) { // Find all shells that have at least a selected UV. bool *selected = new bool[nbUvShells]; for (i = 0 ; i<nbUvShells ; i++) selected[i] = false; for (i = 0 ; i<uvList.length() ; i++) { int indx = uvList[i]; selected[uvShellIds[indx]] = true; } // Now recompute a new list of UVs to modify. unsigned int numUvs = mesh.numUVs(); unsigned int numSelUvs = 0; // Preallocate a buffer, large enough to hold all Ids. This // prevents multiple reallocation from happening when growing // the array. uvList.setLength(numUvs); for (i = 0 ; i<numUvs ; i++) { if (selected[uvShellIds[i]]) uvList[numSelUvs++] = i; } // clamp the array to the proper size. uvList.setLength(numSelUvs); delete [] selected; } // For global flips, just pretend there is only one shell if (flipGlobal) nbUvShells = 1; float *minMax = new float[nbUvShells*4]; for (i = 0 ; i<nbUvShells ; i++) { minMax[4*i+0] = 1e30F; // Min U minMax[4*i+1] = 1e30F; // Min V minMax[4*i+2] = -1e30F; // Max U minMax[4*i+3] = -1e30F; // Max V } // Get the bounding box of the UVs, for each shell if flipGlobal // is true, or for the whole selection if false. for (i = 0 ; i<uvList.length() ; i++) { int indx = uvList[i]; int shellId = 0; if (!flipGlobal) shellId = uvShellIds[indx]; if (uArray[indx] < minMax[4*shellId+0]) minMax[4*shellId+0] = uArray[indx]; if (vArray[indx] < minMax[4*shellId+1]) minMax[4*shellId+1] = vArray[indx]; if (uArray[indx] > minMax[4*shellId+2]) minMax[4*shellId+2] = uArray[indx]; if (vArray[indx] > minMax[4*shellId+3]) minMax[4*shellId+3] = vArray[indx]; } // Adjust the size of the output arrays uPos.setLength(uvList.length()); vPos.setLength(uvList.length()); for (i = 0 ; i<uvList.length() ; i++) { int shellId = 0; int indx = uvList[i]; if (!flipGlobal) shellId = uvShellIds[indx]; // Flip U or V along the bounding box center. if (horizontal) { uPos[i] = minMax[4*shellId+0] + minMax[4*shellId+2] - uArray[indx]; vPos[i] = vArray[indx]; } else { uPos[i] = uArray[indx]; vPos[i] = minMax[4*shellId+1] + minMax[4*shellId+3] - vArray[indx]; } } delete [] minMax; return MS::kSuccess; }
//------------------------------------------------------------------------------------------- void vertexFty::doIt() //------------------------------------------------------------------------------------------- { meshCreator& creator = *ftyCreator; MIntArray& vtxList = *selVtxIDs; BPT_Helpers helper; //MERKE:Diese prozedur arbeitet nur mit dem MeshCreator, benutzt also kein MFnMesh etc. //zuersteinmal ein Ba aufbauen mit den gewählten vertizen BPT_BA selCheckList(vtxList,true,false,creator.getLastVtxID()); //ArbeitsArray für die folgende Prozedur // BPT_BA selList = selCheckList; //wird als lookup verwendet, der nicht verändert wird //Die einfachste Lösung: Ba aufbauen mit allen Faces, die schon bearbeitet wurden - bedeutet aber auch, dass für jeden SelVtx die //verbundenen Faces geholt werden müssen - momentan ist die Sache ziemlich billig (CPU ZEIT) //man müsste zuerst die verbundenen Faces zu allen Vertizen holen, und dese Dann abarbeiten MIntArray allConnectedFaces; UINT r = null; UINT l,i,x; //für iterationen // UINT cv; // == currentVtx MIntArray faceVtx; //vertizen des jeweiligen faces MIntArray connectedFaces; //hält die mit dem Vtx verbundenen Faces MIntArray match; //Array fr übereinstimmende Vtx //jetzt durch die SelVtx parsen und eine Facezurodnung herstellen l = vtxList.length(); //alle verbundenen Faces holen for(i = null; i < l; i++) { creator.getConnectedFaces(vtxList[i],connectedFaces); allConnectedFaces.setLength(allConnectedFaces.length() + connectedFaces.length()); for(x = null; x < connectedFaces.length(); x++) { allConnectedFaces[r++] = connectedFaces[x]; } } helper.memoryPrune(allConnectedFaces); l = allConnectedFaces.length(); for(i = null; i < l; i++) { creator.getFaceVtxIDs(allConnectedFaces[i],faceVtx); selCheckList.findMatching(faceVtx, match); if(match.length() > 1) splitFace(faceVtx,match,allConnectedFaces[i]); } /* for(i = 0; i < l; i++) { cv = vtxList[i]; //wenn der gegenwärtige Vtx noch nicht bearbeitet wurde if( ! selCheckList[cv]) //hier lieber operator [] nehmen, da isFlagSet noch nen unnötigen rangecheck macht { continue; } //ansonsten weitermachen und: //die verbundenen Faces holen creator.getConnectedFaces(cv,connectedFaces); //jetzt in jedem verbundenen Face checken, ob von den entsprechenden faceVertices //gewählte vertices vorhanden sind //zuvor aber den gegenwärtigen cv entfernen selCheckList.setBitFalse(cv); for(x = 0; x < connectedFaces.length(); x++) { creator.getFaceVtxIDs(connectedFaces[x],faceVtx); //wenn mehr als nur der cv auf dem face gewählt sind, dann connectProzedur starten selList.findMatching(faceVtx, match); //if(match.length() > 1) if(match.length() > 1) //nur testweise {//es handelt sich um ein gültiges face, da mindestens 2 vertizen im Face gewählt waren ->splitten INVIS(helper.printArray(faceVtx," = zu bearbeitendes Face");); splitFace(faceVtx, match, connectedFaces[x]); //zuguterletzt noch die matches aus selCheckList entfernen, damit diese nicht nochmal bearbeitet werden selCheckList.remove(match); } } } */ }
MStatus DDConvexHullUtils::generateMayaHull(MObject &output, const MPointArray &vertices, const DDConvexHullUtils::hullOpts &hullOptions) { // Allocate and push the vert list into the new array Mem Cleanup req. uint numInputVerts = vertices.length(); double *inputVerts = new double[numInputVerts*3]; for (uint i=0; i < numInputVerts; i++) { uint offset = i*3; inputVerts[offset] = vertices[i].x; inputVerts[offset+1] = vertices[i].y; inputVerts[offset+2] = vertices[i].z; } // Setup the flags uint hullFlags = QF_DEFAULT; if (hullOptions.forceTriangles) { hullFlags |= QF_TRIANGLES; } if (hullOptions.useSkinWidth) { hullFlags |= QF_SKIN_WIDTH; } if (hullOptions.reverseTriangleOrder) { hullFlags |= QF_REVERSE_ORDER; } // Create the description HullDesc hullDescription; hullDescription.mFlags = hullFlags; hullDescription.mMaxVertices = hullOptions.maxOutputVertices; hullDescription.mSkinWidth = hullOptions.skinWidth; hullDescription.mNormalEpsilon = hullOptions.normalEpsilon; hullDescription.mVertexStride = sizeof(double)*3; hullDescription.mVcount = numInputVerts; hullDescription.mVertices = inputVerts; // Create the hull HullLibrary hullComputer; HullResult hullResult; HullError err = hullComputer.CreateConvexHull(hullDescription, hullResult); MStatus hullStat = MStatus::kSuccess; if (err == QE_OK) { // Grab the verts MPointArray outPoints; for (uint i=0; i < hullResult.mNumOutputVertices; i++) { uint offset = i*3; MPoint curPoint(hullResult.mOutputVertices[offset], hullResult.mOutputVertices[offset+1], hullResult.mOutputVertices[offset+2]); outPoints.append(curPoint); } // Check if the results are in polygons, or triangles. Depending on // which for the result is in, the way the face indices are setup // is different. MIntArray polyCounts; MIntArray vertexConnects; if (hullResult.mPolygons) { const uint *idx = hullResult.mIndices; for (uint i=0; i < hullResult.mNumFaces; i++) { uint pCount = *idx++; polyCounts.append(pCount); for (uint j=0; j < pCount; j++) { uint val = idx[0]; vertexConnects.append(val); idx++; } } } else { polyCounts.setLength(hullResult.mNumFaces); for (uint i=0; i < hullResult.mNumFaces; i++) { polyCounts[i] = 3; uint *idx = &hullResult.mIndices[i*3]; vertexConnects.append(idx[0]); vertexConnects.append(idx[1]); vertexConnects.append(idx[2]); } } // Setup the outmesh MFnMesh outMeshFn(output); outMeshFn.create(hullResult.mNumOutputVertices, hullResult.mNumFaces, outPoints, polyCounts, vertexConnects, output, &hullStat); } else { hullStat = MStatus::kFailure; } // Mem Cleanup hullComputer.ReleaseResult(hullResult); delete[] inputVerts; return hullStat; }
MStatus PtexUVNode::compute( const MPlug &plug, MDataBlock &data ) { MStatus stat; bool hasNoEffect = false; MDataHandle inMeshHnd = data.inputValue( inMesh ); MDataHandle outMeshHnd = data.outputValue( outMesh ); MDataHandle stateHnd = data.inputValue( state ); int state = stateHnd.asInt(); if( state == 1 ) // No Effect/Pass through hasNoEffect = true; if( !hasNoEffect && plug == outMesh ) { MObject inMeshData = inMeshHnd.asMesh(); if( !hasNoEffect ) { MFnMeshData meshDataFn; MObject newMeshData = meshDataFn.create(); MFnMesh inMeshFn( inMeshData ); inMeshFn.copy( inMeshData, newMeshData ); MFnMesh meshFn( newMeshData ); MPointArray pts; meshFn.getPoints( pts ); MStringArray uvSetNames; meshFn.getUVSetNames( uvSetNames ); unsigned int defaultUvSetCount = (unsigned int)uvSetNames.length(); int num_faces = meshFn.numPolygons(); MIntArray uvCounts; uvCounts.setLength( num_faces ); for ( int i_f = 0; i_f < num_faces; i_f++ ) { int deg = meshFn.polygonVertexCount( i_f ); uvCounts[ i_f ] = deg; if ( deg != 4 ) { return MS::kFailure; } } MIntArray uvIds; uvIds.setLength( 4 * num_faces ); if ( defaultUvSetCount == 1 ) { int currentUVCount = meshFn.numUVs( uvSetNames[0] ); MFloatArray us, vs; us.setLength( 4 * num_faces ); vs.setLength( 4 * num_faces ); for ( int i_f = 0; i_f < num_faces; i_f++ ) { float f = (float)i_f; uvIds[ 4 * i_f + 0 ] = 4 * i_f + 0; uvIds[ 4 * i_f + 1 ] = 4 * i_f + 1; uvIds[ 4 * i_f + 2 ] = 4 * i_f + 2; uvIds[ 4 * i_f + 3 ] = 4 * i_f + 3; us[ 4 * i_f + 0 ] = (float)i_f; vs[ 4 * i_f + 0 ] = 0.0f; us[ 4 * i_f + 1 ] = (float)i_f + 1.0f; vs[ 4 * i_f + 1 ] = 0.0f; us[ 4 * i_f + 2 ] = (float)i_f + 1.0f; vs[ 4 * i_f + 2 ] = 1.0f; us[ 4 * i_f + 3 ] = (float)i_f; vs[ 4 * i_f + 3 ] = 1.0f; } stat = meshFn.setUVs( us, vs, &uvSetNames[0] ); stat = meshFn.assignUVs( uvCounts, uvIds, &uvSetNames[0] ); } meshFn.updateSurface(); meshFn.syncObject(); outMeshHnd.set( newMeshData ); } } else return MS::kUnknownParameter; if( hasNoEffect ) outMeshHnd.set( inMeshHnd.asMesh() ); data.setClean( plug ); return stat; }
bool tm_polyExtract::extractFaces_Func( MSelectionList &selectionList, MStringArray &node_names) { MStatus status; MObject meshObj; status = selectionList.getDependNode( 0, meshObj); if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func: Can't find object !");return false;} MFnMesh meshFn( meshObj, &status); if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func: Non mesh object founded !");return false;} MDagPath meshDagPath_first, meshDagPath; selectionList.getDagPath( 0, meshDagPath_first); MObject multiFaceComponent; MIntArray inputFacesArray; inputFacesArray.clear(); inputFacesArray.setSizeIncrement( 4096); MFnComponentListData compListFn; compListFn.create(); for (MItSelectionList faceComponentIter(selectionList, MFn::kMeshPolygonComponent); !faceComponentIter.isDone(); faceComponentIter.next()) { faceComponentIter.getDagPath(meshDagPath, multiFaceComponent); if(!(meshDagPath_first == meshDagPath)) { MGlobal::displayError("tm_polyExtract::extractFaces_Func: Different meshes faces founded !"); return false; } if (!multiFaceComponent.isNull()) { for (MItMeshPolygon faceIter(meshDagPath, multiFaceComponent); !faceIter.isDone(); faceIter.next()) { int faceIndex = faceIter.index(); #ifdef _DEBUG infoMStr += faceIndex; infoMStr += " "; #endif inputFacesArray.append( faceIndex); compListFn.add( multiFaceComponent ); } } } if( inputFacesArray.length() == 0) { MGlobal::displayError("tm_polyExtract::extractFaces_Func: No faces founded !"); return false; } #ifdef _DEBUG MGlobal::displayInfo( infoMStr); #endif meshFn.setObject( meshDagPath_first); meshObj = meshFn.object(); // MDagModifier dagModifier; MFnDagNode meshDagNodeFn; MFnDependencyNode depNodeFn; meshDagNodeFn.setObject( meshDagPath_first); MString meshName = meshDagNodeFn.name(); MObject outMesh_attrObject = meshDagNodeFn.attribute( "outMesh"); // ----------------------------------- duplicate shape MObject duplicated_meshObjectA; MObject duplicated_meshObjectB; MObject inMesh_attrObjectA; MObject inMesh_attrObjectB; /* MStringArray commandResult; MSelectionList selList; MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1); selList.add( commandResult[0]); selList.getDependNode( 0, duplicated_meshObjectA); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_tA"); duplicated_meshObjectA = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_sA"); inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh"); meshDagNodeFn.setObject( meshDagPath_first); selList.clear(); MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1); selList.add( commandResult[0]); selList.getDependNode( 0, duplicated_meshObjectB); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_tB"); duplicated_meshObjectB = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_sB"); inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh"); */ duplicated_meshObjectA = meshDagNodeFn.duplicate(); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_tA"); duplicated_meshObjectA = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectA); meshDagNodeFn.setName( meshName + "_sA"); inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh"); meshDagNodeFn.setObject( meshDagPath_first); duplicated_meshObjectB = meshDagNodeFn.duplicate(); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_tB"); duplicated_meshObjectB = meshDagNodeFn.child(0); meshDagNodeFn.setObject( duplicated_meshObjectB); meshDagNodeFn.setName( meshName + "_sB"); inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh"); // ----------------------------------- create node deleteComponent MDGModifier dgModifier; MObject deleteComponent_nodeObjectA = dgModifier.createNode( MString("deleteComponent")); depNodeFn.setObject( deleteComponent_nodeObjectA ); MObject deleteComponent_attrObjectA( depNodeFn.attribute( "deleteComponents" )); MObject inputGeometry_attrObjectA( depNodeFn.attribute( "inputGeometry" )); MObject outputGeometry_attrObjectA( depNodeFn.attribute( "outputGeometry" )); dgModifier.doIt(); depNodeFn.setName( "dfA_" + meshName); node_names.append( depNodeFn.name()); MObject deleteComponent_nodeObjectB = dgModifier.createNode( MString("deleteComponent")); depNodeFn.setObject( deleteComponent_nodeObjectB ); MObject deleteComponent_attrObjectB( depNodeFn.attribute( "deleteComponents" )); MObject inputGeometry_attrObjectB( depNodeFn.attribute( "inputGeometry" )); MObject outputGeometry_attrObjectB( depNodeFn.attribute( "outputGeometry" )); dgModifier.doIt(); depNodeFn.setName( "dfB_" + meshName); node_names.append( depNodeFn.name()); // ----------------------------------- set attribute deleteComponent.deleteComponents MObject componentList_object = compListFn.object(); MPlug deleteComponents_plugA( deleteComponent_nodeObjectA, deleteComponent_attrObjectA ); status = deleteComponents_plugA.setValue( componentList_object ); MIntArray invertedFaces; int numPolygons = meshFn.numPolygons(); invertedFaces.setLength( numPolygons - inputFacesArray.length()); int selFace = 0; int invFace = 0; for( int f = 0; f < numPolygons; f++) { if( f == inputFacesArray[selFace]) selFace++; else invertedFaces[invFace++] = f; } MFnSingleIndexedComponent singleIndexedComponentFn( meshObj); singleIndexedComponentFn.create( MFn::kMeshPolygonComponent); singleIndexedComponentFn.addElements( invertedFaces); compListFn.clear(); compListFn.create(); componentList_object = singleIndexedComponentFn.object(); compListFn.add( componentList_object); componentList_object = compListFn.object(); MPlug deleteComponents_plugB( deleteComponent_nodeObjectB, deleteComponent_attrObjectB ); status = deleteComponents_plugB.setValue( componentList_object ); // ------------------------------------- connecting plugs /**/ dgModifier.connect( meshObj, outMesh_attrObject, deleteComponent_nodeObjectA, inputGeometry_attrObjectA ); dgModifier.connect( deleteComponent_nodeObjectA, outputGeometry_attrObjectA, duplicated_meshObjectA, inMesh_attrObjectA ); dgModifier.connect( meshObj, outMesh_attrObject, deleteComponent_nodeObjectB, inputGeometry_attrObjectB ); dgModifier.connect( deleteComponent_nodeObjectB, outputGeometry_attrObjectB, duplicated_meshObjectB, inMesh_attrObjectB ); dgModifier.doIt(); // ---------------------------------- assigning shading group /**/ meshDagNodeFn.setObject( meshDagPath_first); MObject instObjGroups_attrObject = meshDagNodeFn.attribute( "instObjGroups"); MPlug instObjGroups_plug( meshObj, instObjGroups_attrObject); instObjGroups_plug = instObjGroups_plug.elementByPhysicalIndex(0); MPlugArray instObjGroups_plug_connectionsArray; instObjGroups_plug.connectedTo( instObjGroups_plug_connectionsArray, false, true); if( instObjGroups_plug_connectionsArray.length() > 0) { MPlug dagSetMembers_plug = instObjGroups_plug_connectionsArray[0]; MObject shadingSetNode_object = dagSetMembers_plug.node(); MFnSet setFn( shadingSetNode_object); setFn.addMember( duplicated_meshObjectA); setFn.addMember( duplicated_meshObjectB); //depNodeFn.setObject(shadingSetNode_object); //MGlobal::displayInfo( depNodeFn.name()); } // ------------------------------------------------------------ return true; }
void createUVset(TCCData &tccData, int sdRes, MFloatArray &uArray, MFloatArray &vArray, MFloatArray &sc_uArray, MFloatArray &sc_vArray, MIntArray &uvIdx, float lineThickness) { MFloatArray u4, v4, u5T0, v5T0, u5T1, v5T1, u5T2, v5T2, u5T3, v5T3, u5T4, v5T4; MIntArray id4, id5T0, id5T1, id5T2, id5T3, id5T4; double hds4_uvs[] = { 0,1, 1,1, 1,0, 0,0 }, hds4_itv[] = {1,1,1,1}; create_subdivided_face(sdRes, 4, hds4_uvs, hds4_itv, -1, u4, v4, id4); double hds5T0_uvs[] = { 0,.5, 0,1, 1,1, 1,0, 0,0 }, hds5T0_itv[] = {.5,.5,1,1,1}; create_subdivided_face(sdRes, 5, hds5T0_uvs, hds5T0_itv, 0, u5T0, v5T0, id5T0); double hds5T1_uvs[] = { 0,0, 0,.5, 0,1, 1,1, 1,0 }, hds5T1_itv[] = {1,.5,.5,1,1}; create_subdivided_face(sdRes, 5, hds5T1_uvs, hds5T1_itv, 1, u5T1, v5T1, id5T1); double hds5T2_uvs[] = { 1,0, 0,0, 0,.5, 0,1, 1,1 }, hds5T2_itv[] = {1,1,.5,.5,1}; create_subdivided_face(sdRes, 5, hds5T2_uvs, hds5T2_itv, 2, u5T2, v5T2, id5T2); double hds5T3_uvs[] = { 1,1, 1,0, 0,0, 0,.5, 0,1 }, hds5T3_itv[] = {1,1,1,.5,.5}; create_subdivided_face(sdRes, 5, hds5T3_uvs, hds5T3_itv, 3, u5T3, v5T3, id5T3); double hds5T4_uvs[] = { 0,1, 1,1, 1,0, 0,0, 0,.5 }, hds5T4_itv[] = {.5,1,1,1,.5}; create_subdivided_face(sdRes, 5, hds5T4_uvs, hds5T4_itv, 4, u5T4, v5T4, id5T4); int nV4 = u4.length(), nHE4 = id4.length(); int nV5 = u5T0.length(), nHE5 = id5T0.length(); int nF = tccData.nFV.length(); int nHE = 0, nV = 0; for (int kF = 0; kF<nF; kF++) { switch (tccData.nFV[kF]) { case 4: nV+=nV4; nHE+=nHE4; break; case 5: nV+=nV5; nHE+=nHE5; break; } } uArray.setLength(nV); sc_uArray.setLength(nV); vArray.setLength(nV); sc_vArray.setLength(nV); uvIdx.setLength(nHE); int kHE = 0, sd_kV = 0, sd_kHE = 0; for (int kF = 0; kF<nF; kF++) { int faceConfig = tccData.nFV[kF]; if (faceConfig==5) { for (int kT=0; kT<5; kT++) { if (tccData.T[kHE+kT]) break; faceConfig++; } } // uScale and vScale are chosen to not use T-edges, but match the U/V directions of the patch (convention: first edge gets vScale) switch (faceConfig) { case 4: copy_patch_uvs(sd_kV, sd_kHE, u4, v4, id4, uArray, vArray, tccData.itv[kHE], tccData.itv[kHE+1], sc_uArray, sc_vArray, uvIdx, lineThickness); break; case 5: copy_patch_uvs(sd_kV, sd_kHE, u5T0, v5T0, id5T0, uArray, vArray, tccData.itv[kHE+3], tccData.itv[kHE+4], sc_uArray, sc_vArray, uvIdx, lineThickness); break; case 6: copy_patch_uvs(sd_kV, sd_kHE, u5T1, v5T1, id5T1, uArray, vArray, tccData.itv[kHE+4], tccData.itv[kHE], sc_uArray, sc_vArray, uvIdx, lineThickness); break; case 7: copy_patch_uvs(sd_kV, sd_kHE, u5T2, v5T2, id5T2, uArray, vArray, tccData.itv[kHE], tccData.itv[kHE+1], sc_uArray, sc_vArray, uvIdx, lineThickness); break; case 8: copy_patch_uvs(sd_kV, sd_kHE, u5T3, v5T3, id5T3, uArray, vArray, tccData.itv[kHE+1], tccData.itv[kHE+2], sc_uArray, sc_vArray, uvIdx, lineThickness); break; case 9: copy_patch_uvs(sd_kV, sd_kHE, u5T4, v5T4, id5T4, uArray, vArray, tccData.itv[kHE+2], tccData.itv[kHE+3], sc_uArray, sc_vArray, uvIdx, lineThickness); break; } kHE += tccData.nFV[kF]; } }
// -------------------------------------------------------- void GeometryPolygonExporter::retrieveVertexIndices ( MIntArray &vertexIndices, MItMeshPolygon &meshPolygonsIter, uint &numPolygons, uint &numVertices ) { // Get the number of vertices in the current mesh's polygon int polygonVertexCount = meshPolygonsIter.polygonVertexCount(); if ( triangulated && polygonVertexCount > 3 ) { int numTriangles; meshPolygonsIter.numTriangles ( numTriangles ); if ( numTriangles > 0 ) { numVertices = 3; MPointArray vertexPositions; MIntArray meshVertexIndices; meshPolygonsIter.getTriangles ( vertexPositions, meshVertexIndices ); vertexIndices.setLength ( meshVertexIndices.length() ); numPolygons = meshVertexIndices.length() / numVertices; // Map the vertex indices to iterator vertex indices so that we can // get information from the iterator about normals and such. uint meshVertexIndexCount = meshVertexIndices.length(); for ( uint mvi = 0; mvi < meshVertexIndexCount; ++mvi ) { int meshVertexIndex = meshVertexIndices[mvi]; int polygonVertexCount = meshPolygonsIter.polygonVertexCount(); int iteratorVertexIndex = 0; for ( int pv = 0; pv < polygonVertexCount; ++pv ) { if ( ( int ) meshPolygonsIter.vertexIndex ( pv ) == meshVertexIndex ) { iteratorVertexIndex = pv; } } vertexIndices[mvi] = iteratorVertexIndex; } } else numPolygons = 0; } else if ( polygonVertexCount >= 3 ) { numPolygons = 1; vertexIndices.setLength ( polygonVertexCount ); for ( int pv = 0; pv < polygonVertexCount; ++pv ) { vertexIndices[pv] = pv; } #ifdef VALIDATE_DATA // Skip over any duplicate vertices in this face. // Very rarely, a cunning user manages to corrupt // a face entry on the mesh and somehow configure // a face to include the same vertex multiple times. // This will cause the read-back of this data to // reject the face, and can crash other COLLADA // consumers, so better to lose the data here for ( uint n = 0; n < vertexIndices.length() - 1; ++n ) { for ( uint m = n + 1; m < vertexIndices.length(); ) { if ( vertexIndices[n] == vertexIndices[m] ) { vertexIndices.remove ( m ); } else ++m; } } // Get the number of vertices of the current polygon. numVertices = vertexIndices->length(); #else // Get the number of vertices of the current polygon. numVertices = polygonVertexCount; #endif } }
MStatus updateTCCData::compute_remap(TCCData &tccData, MIntArray &vR, MIntArray &pO, MIntArray &cS) { pair<multimap<int, int>::iterator,multimap<int, int>::iterator> fRange; multimap<int, int> dst_V2F; // maps smallest face vertex index to all its faces MIntArray &src_nFV(tccData.nFV), &dst_nFV(tccData.o_nFV); MIntArray &src_F(tccData.F), &dst_F(tccData.o_F); // get source and destination F and nFV arrays size_t src_nHE = src_F.length(), src_nF = src_nFV.length(); size_t dst_nHE = dst_F.length(), dst_nF = dst_nFV.length(); pO.setLength(src_nF); cS.setLength(src_nF); MIntArray dst_F2H(dst_nF, 0); MIntArray dst_cS(dst_nF, 0); // build lookup map size_t kHE = 0; for (size_t kF=0; kF<dst_nF; kF++) { dst_F2H[kF] = kHE; size_t cnFV = dst_nFV[kF]; size_t minVI = dst_nHE; // big enough... size_t ccS = 0; for (size_t kFV=0; kFV<cnFV; kFV++) { if (dst_F[kHE]<minVI) { minVI = dst_F[kHE]; ccS = kFV; } kHE++; } dst_V2F.insert(pair<int,int>(minVI, kF)); dst_cS[kF] = ccS; } size_t src_F2H = 0; // look up new faces in old mesh for (size_t kF=0; kF<src_nF; kF++) { size_t cnFV = src_nFV[kF]; // find minimum remapped vtx index, remap vertices size_t minVI = src_nHE; // start with smth big enough... size_t src_ccS = 0; bool newFace = false; for (size_t kFV=0; kFV<cnFV; kFV++) { int vRI = vR[src_F[src_F2H+kFV]]; if (vRI == NO_DST_VTXID) { newFace = true; break; } if (vRI < minVI) { minVI = vRI; src_ccS = kFV; } } // no new vertices? ok, then let's see if we can find this face in dst if (!newFace) { bool faceMismatch = true; fRange = dst_V2F.equal_range(minVI); for (multimap<int, int>::iterator it=fRange.first; it!=fRange.second; ++it) { int dst_rF = (*it).second; // remapped face candidate if (dst_nFV[dst_rF] != cnFV) continue; // face vertex count mismatch -> not the right face faceMismatch = false; size_t ccS = dst_cS[dst_rF] + cnFV - src_ccS; // additional cnFV makes ccS always positive. for (size_t kFV=0; kFV<cnFV; kFV++) { // index in dst polygon, starting with the same vertex offset (relative to smallest index) as src polygon size_t o_kHE = dst_F2H[dst_rF] + ((kFV + ccS) % cnFV); int src_vI = vR[ src_F[ src_F2H + kFV ] ]; int dst_vI = dst_F[ o_kHE ]; if ( src_vI != dst_vI ) { faceMismatch = true; break; } } if (!faceMismatch) { pO[kF] = dst_rF; cS[kF] = ccS; break; } } if (faceMismatch) newFace = true; } // if new face, add it to delta_F and delta_nFV if (newFace) { pO[kF] = NO_DST_VTXID; } src_F2H += cnFV; } return MS::kSuccess; }
MStatus genBall( const MPoint ¢re, const double radius, const unsigned int nSegs, int &nPolys, MPointArray &verts, MIntArray &polyCounts, MIntArray &polyConnects ) { verts.clear(); polyCounts.clear(); polyConnects.clear(); int nAzimuthSegs = nSegs * 2; int nZenithSegs = nSegs; int nAzimuthPts = nAzimuthSegs; // Last point corresponds to the first int nZenithPts = nZenithSegs + 1; // Last point is at other pole double azimIncr = 2.0 * M_PI / nAzimuthSegs; double zenIncr = M_PI / nZenithSegs; MPoint p; double azimuth, zenith; double sinZenith; int azi, zeni; zenith = 0.0; for( zeni=0; zeni < nZenithPts; zeni++, zenith += zenIncr ) { azimuth = 0.0; for( azi=0; azi < nAzimuthPts; azi++, azimuth += azimIncr ) { sinZenith = sin(zenith); p.x = radius * sinZenith * cos(azimuth); p.y = radius * cos(zenith); p.z = radius * sinZenith * sin(azimuth); verts.append( p ); } } // Calculate the number of polygons nPolys = nAzimuthSegs * nZenithSegs; // Each face has four points polyCounts.setLength( nPolys ); int i; for( i=0; i < nPolys; i++ ) polyCounts[i] = 4; // Generate the faces for( zeni=0; zeni < nZenithSegs; zeni++ ) { for( azi=0; azi < nAzimuthSegs; azi++ ) { //MGlobal::displayInfo( MString( "\n" ) + azi + "," + zeni ); polyConnects.append( linearIndex( zeni, azi, nZenithPts, nAzimuthPts ) ); polyConnects.append( linearIndex( zeni, azi+1, nZenithPts, nAzimuthPts ) ); polyConnects.append( linearIndex( zeni+1, azi+1, nZenithPts, nAzimuthPts ) ); polyConnects.append( linearIndex( zeni+1, azi, nZenithPts, nAzimuthPts ) ); } } return MS::kSuccess; }
void VertexPolyColourCommand::PrepareMesh(VertexColourJob& job) { MDGModifier* modifier = NULL; // If the mesh doesn't have any vertex colours yet, create some default ones #if (MAYA_API_VERSION > 650) bool hasVertexColours = true; if (0 == job.meshData->mesh->numColorSets()) { hasVertexColours = false; } else { // Check the color set isn't the VCP_MasterComp used by the layers system if (job.meshData->mesh->numColorSets() == 1 && job.meshData->hasLayers) { hasVertexColours = false; } } if (!hasVertexColours) { if (m_isUndoable) modifier = new MDGModifier; // Create a colour set MString colorSetName("colorSet1"); job.meshData->mesh->createColorSet(colorSetName, modifier); job.meshData->mesh->setCurrentColorSetName(colorSetName, modifier); // Create default vertex colours MIntArray vertList; MColorArray colors; unsigned int numVerts = (unsigned int)job.meshData->mesh->numVertices(); vertList.setLength(numVerts); colors.setLength(numVerts); unsigned int i = 0; for (i = 0; i < numVerts; i++) vertList[i] = i; for (i = 0; i < numVerts; i++) colors[i].set(MColor::kRGB, 0.37f, 0.37f, 0.37f, 1.0f); // default rgb is default 0.37 // Fill vertex colours job.meshData->mesh->setVertexColors(colors, vertList, modifier); // If the mesh has layer data, set the active layer if (job.meshData->hasLayers) { MString name("colorSet1"); MFnDagNode attribNode(job.meshData->mesh->parent(0)); MObject activeLayerObj = attribNode.attribute(MString("VCP_Layer_Active")); if (!activeLayerObj.isNull()) { MPlug activeLayerPlug(attribNode.object(), activeLayerObj); activeLayerPlug.setValue(name); } MString command = "VCP_Layer_CreateDefaultLayerAttribs " + attribNode.fullPathName() + " colorSet1"; MGlobal::executeCommand(command); MGlobal::executeCommand("VCP_Layers_UpdateUI();"); /* attribNode.addAttribute(attr); MObject layerBlendAmountObj = attribNode.attribute(MString("VCP_Layer_") + name + "_BlendAmount"); if (!layerBlendAmountObj.isNull()) { MPlug layerBlendAmountPlug(attribNode.object(), layerBlendAmountObj); layerBlendAmountPlug.setValue(100.0f); } MObject layerBlendModeObj = attribNode.attribute(MString("VCP_Layer_") + name + "_BlendMode"); if (!layerBlendModeObj.isNull()) { MPlug layerBlendModePlug(attribNode.object(), layerBlendModeObj); layerBlendModePlug.setValue("Replace"); } MObject layerVisibleObj = attribNode.attribute(MString("VCP_Layer_") + name + "_Visible"); if (!layerVisibleObj.isNull()) { MPlug layerVisiblePlug(attribNode.object(), layerVisibleObj); layerVisiblePlug.setValue(true); }*/ job.meshData->DeleteLayersData(); GatherLayersData(); } } #endif if (modifier != NULL) { m_undos.push_back(modifier); } }
bool tm_polygon_selectloop::calculate( MIntArray &edgesArray, const int &selIndex, const int &mode, const double &angle_deg, const int &maxCount) { if(!objectIsSet) { MGlobal::displayError("tm_polygon_selectloop::calculate - Object is not set."); return false; } double angle = angle_deg*M_PI/180; MStatus stat; pMesh = new MFnMesh( meshObject, &stat); if (!stat) return false; int meshEdgesCount = pMesh->numEdges( &stat); if (!stat) return false; int *pVisitedEdges = new int[meshEdgesCount]; for( int i = 0; i < meshEdgesCount; i++) pVisitedEdges[i] = 0; pVtxIt = new MItMeshVertex( meshObject, &stat); if (!stat) return false; pEdgeIt = new MItMeshEdge( meshObject, &stat); if (!stat) return false; pFaceIt = new MItMeshPolygon( meshObject, &stat); if (!stat) return false; int edgeVtx[2]; int edge, vtx; stat = pMesh->getEdgeVertices( selIndex, edgeVtx); if (!stat) return false; std::list <int> edgesList; edgesList.push_front( selIndex); int count = 1; edge = selIndex; pVisitedEdges[selIndex] = 1; vtx = edgeVtx[0]; while( findNextEdge( edge, vtx, mode, angle)) { if (pVisitedEdges[edge]) break; if ((++count) > maxCount) break; edgesList.push_front( edge); pVisitedEdges[edge] = 1; } edge = selIndex; vtx = edgeVtx[1]; while( findNextEdge( edge, vtx, mode, angle)) { if (pVisitedEdges[edge]) break; if ((++count) > maxCount) break; edgesList.push_back( edge); pVisitedEdges[edge] = 1; } int len = (int)edgesList.size(); edgesArray.setLength( len); for( int i = 0; i < len; i++) { edgesArray[i] = *edgesList.begin(); edgesList.pop_front(); } if( pMesh != NULL) delete pMesh; if( pVtxIt != NULL) delete pVtxIt; if( pEdgeIt != NULL) delete pEdgeIt; if( pFaceIt != NULL) delete pFaceIt; if( pVisitedEdges != NULL) delete [] pVisitedEdges; return true; }