static MStatus convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner, std::vector<Vertex> const & refinedVerts, bool hasUVs, std::vector<FVarVertexUV> const & refinedUVs, bool hasColors, std::vector<FVarVertexColor> const & refinedColors, MFnMesh & inMeshFn, MObject newMeshDataObj) { MStatus status; typedef OpenSubdiv::Far::ConstIndexArray IndexArray; int maxlevel = refiner.GetMaxLevel(); OpenSubdiv::Far::TopologyLevel const & refLastLevel = refiner.GetLevel(maxlevel); int nfaces = refLastLevel.GetNumFaces(); // Init Maya Data // Face Counts MIntArray faceCounts(nfaces); for (int face=0; face < nfaces; ++face) { faceCounts[face] = 4; } // Face Connects MIntArray faceConnects(nfaces*4); for (int face=0, idx=0; face < nfaces; ++face) { IndexArray fverts = refLastLevel.GetFaceVertices(face); for (int vert=0; vert < fverts.size(); ++vert) { faceConnects[idx++] = fverts[vert]; } } // Points int nverts = refLastLevel.GetNumVertices(); int firstOfLastVert = refiner.GetNumVerticesTotal() - nverts - refiner.GetLevel(0).GetNumVertices(); MFloatPointArray points(nverts); for (int vIt = 0; vIt < nverts; ++vIt) { Vertex const & v = refinedVerts[firstOfLastVert + vIt]; points.set(vIt, v.position[0], v.position[1], v.position[2]); } // Create New Mesh from MFnMesh MFnMesh newMeshFn; MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(), points, faceCounts, faceConnects, newMeshDataObj, &status); MCHECKERR(status, "Cannot create new mesh"); // Get face-varying set names and other info from the inMesh MStringArray uvSetNames; MStringArray colorSetNames; std::vector<int> colorSetChannels; std::vector<MFnMesh::MColorRepresentation> colorSetReps; int totalColorSetChannels = 0; status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels); // Add new UVs back to the mesh if needed if (hasUVs) { MIntArray fvarConnects(faceConnects.length()); int count = 0; for (int f = 0; f < refLastLevel.GetNumFaces(); ++f) { IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELUV); for (int index = 0 ; index < faceIndices.size() ; ++index) { fvarConnects[count++] = faceIndices[index]; } } int nuvs = refLastLevel.GetNumFVarValues(CHANNELUV); int firstOfLastUvs = refiner.GetNumFVarValuesTotal(CHANNELUV) - nuvs - refiner.GetLevel(0).GetNumFVarValues(CHANNELUV); MFloatArray uCoord(nuvs), vCoord(nuvs); for (int uvIt = 0; uvIt < nuvs; ++uvIt) { FVarVertexUV const & uv = refinedUVs[firstOfLastUvs + uvIt]; uCoord[uvIt] = uv.u; vCoord[uvIt] = uv.v; } // Currently, the plugin only supports one UV set int uvSetIndex = 0; if (uvSetIndex > 0) { status = newMeshFn.createUVSetDataMesh( uvSetNames[uvSetIndex] ); MCHECKERR(status, "Cannot create UVSet"); } static MString defaultUVName("map1"); MString const * uvname = uvSetIndex==0 ? &defaultUVName : &uvSetNames[uvSetIndex]; status = newMeshFn.setUVs(uCoord, vCoord, uvname); MCHECKERR(status, "Cannot set UVs for set : "+*uvname); status = newMeshFn.assignUVs(faceCounts, fvarConnects, uvname); MCHECKERR(status, "Cannot assign UVs"); } // Add new colors back to the mesh if needed if (hasColors) { int count = 0; MIntArray fvarConnects2(faceConnects.length()); for (int f = 0 ; f < refLastLevel.GetNumFaces(); ++f) { IndexArray faceIndices = refLastLevel.GetFaceFVarValues(f, CHANNELCOLOR); for (int index = 0 ; index < faceIndices.size() ; ++index) { fvarConnects2[count++] = faceIndices[index]; } } int ncols = refLastLevel.GetNumFVarValues(CHANNELCOLOR); int firstOfLastCols = refiner.GetNumFVarValuesTotal(CHANNELCOLOR) - ncols - refiner.GetLevel(0).GetNumFVarValues(CHANNELCOLOR); MColorArray colorArray(ncols); for (int colIt = 0; colIt < ncols; ++colIt) { FVarVertexColor const & c = refinedColors[firstOfLastCols + colIt]; colorArray.set(colIt, c.r, c.g, c.b, c.a); } // Currently, the plugin only supports one color sets int colorSetIndex = 0; // Assign color buffer and map the ids for each face-vertex // API Limitation: Cannot set MColorRepresentation here status = newMeshFn.createColorSetDataMesh( colorSetNames[colorSetIndex]); MCHECKERR(status, "Cannot create ColorSet"); bool isColorClamped = inMeshFn.isColorClamped( colorSetNames[colorSetIndex], &status); MCHECKERR(status, "Can not get Color Clamped "); status = newMeshFn.setIsColorClamped( colorSetNames[colorSetIndex], isColorClamped); MCHECKERR(status, "Can not set Color Clamped : " + isColorClamped); status = newMeshFn.setColors( colorArray, &colorSetNames[colorSetIndex], colorSetReps[colorSetIndex]); MCHECKERR(status, "Can not set Colors"); status = newMeshFn.assignColors( fvarConnects2, &colorSetNames[colorSetIndex]); MCHECKERR(status, "Can not assign Colors"); } return MS::kSuccess; }
int main(int argc, char *argv[]) { QApplication a(argc, argv); QPalette p; p.setColor(QPalette::Background, QColor("#97CBFF")); a.setPalette(p); //a.setAutoFillBackground(true); QLabel *window = new QLabel(); window->setWindowTitle(TEXT_WINDOW_TITLE); QLabel *horCoordinate = new QLabel(); QPixmap hCoord(PATH_HCOORD_IMG); horCoordinate->setPixmap(hCoord); horCoordinate->setMinimumSize(SIZE_COORDINATE_L, SIZE_COORDINATE_W); QLabel *verCoordinate = new QLabel(); QPixmap vCoord(PATH_VCOORD_IMG); verCoordinate->setPixmap(vCoord); verCoordinate->setMinimumSize(SIZE_COORDINATE_W, SIZE_COORDINATE_L); Chessboard *chessboard = new Chessboard(); QPixmap img(PATH_CHESSBORAD_IMG); chessboard->setPixmap(img.scaled(SIZE_CHESSBOARD, SIZE_CHESSBOARD)); chessboard->setMinimumSize(SIZE_CHESSBOARD, SIZE_CHESSBOARD); QTextCodec *TradChineseCodec = QTextCodec::codecForName("Big5-ETen"); QLabel *chessboardReadme = new QLabel(TradChineseCodec->toUnicode( "<center> <b>黑方</b> 滑鼠左鍵 |<b> 白方</b> 滑鼠右鍵 |<b> 清空</b> 滑鼠中鍵 </center>")); chessboardReadme->setAlignment(Qt::AlignHCenter); QLabel *funcReadme = new QLabel(TradChineseCodec->toUnicode(" <br> <br> <br> <br> <br><br> <br> <br> <br>")); QPushButton *clearBoard = new QPushButton(TradChineseCodec->toUnicode("清空棋盤")); QObject::connect(clearBoard, SIGNAL(clicked()), chessboard, SLOT(cleanChessboard())); QPushButton *readBoardData = new QPushButton(TradChineseCodec->toUnicode("讀取已存棋盤")); QObject::connect(readBoardData, SIGNAL(clicked()), chessboard, SLOT(readFromTxt())); QGridLayout *buttonLayout = new QGridLayout(); buttonLayout->addWidget(readBoardData, 0, 0); buttonLayout->addWidget(clearBoard, 0, 1); QGridLayout *wholeChessboard = new QGridLayout; wholeChessboard->addWidget(horCoordinate, 0, 1); wholeChessboard->addWidget(verCoordinate, 1, 0); wholeChessboard->addWidget(chessboard, 1, 1); wholeChessboard->addWidget(chessboardReadme, 2, 0, 1, 2); wholeChessboard->addLayout(buttonLayout, 3, 0, 1, 2); wholeChessboard->addWidget(funcReadme, 4, 0, 1, 2); wholeChessboard->setMargin(20); FuncSet1 *findThreat = new FuncSet1(); findThreat->setMinimumSize(SIZE_FUNC_W, SIZE_FUNC_H2); findThreat->setBrd(&(chessboard->boardData)); FuncSet2 *threatSpaceSearch = new FuncSet2(); threatSpaceSearch->setMinimumSize(SIZE_FUNC_W, SIZE_FUNC_H1); threatSpaceSearch->setBrd(&(chessboard->boardData)); FuncSet3 *availableMove = new FuncSet3(); availableMove->setMinimumSize(SIZE_FUNC_W, SIZE_FUNC_H2); availableMove->setBrd(&(chessboard->boardData)); FuncSet4 *proofNumberSearch = new FuncSet4(); proofNumberSearch->setMinimumSize(SIZE_FUNC_W, SIZE_FUNC_H1); proofNumberSearch->setBrd(&(chessboard->boardData)); QGridLayout *wholeApp = new QGridLayout(); wholeApp->addLayout(wholeChessboard, 0, 0, 3, 1); wholeApp->addWidget(availableMove, 0, 1); wholeApp->addWidget(findThreat, 1, 1); wholeApp->addWidget(threatSpaceSearch, 2, 1); wholeApp->addWidget(proofNumberSearch, 0, 2, 3, 1); wholeApp->setSpacing(15); QObject::connect(chessboard, SIGNAL(changeFuncsTurn(int)), availableMove, SLOT(changeTurn(int))); QObject::connect(chessboard, SIGNAL(changeFuncsTurn(int)), findThreat, SLOT(changeTurn(int))); QObject::connect(chessboard, SIGNAL(changeFuncsTurn(int)), threatSpaceSearch, SLOT(changeTurn(int))); QObject::connect(chessboard, SIGNAL(changeFuncsTurn(int)), proofNumberSearch, SLOT(changeTurn(int))); //wholeChessboard->addWidget(test, 4, 0, 1, 2); /*Paper *ya = new Paper(); wholeApp->addWidget(ya, 2,2); BoardData orig; orig.printBoard(ya); orig.set(0,0,BLACK); orig.set(0,1,WHITE); orig.printBoard(ya); BoardData *tmp = new BoardData(&orig); tmp->set(1,1,BLACK); tmp->printBoard(ya); orig.printBoard(ya);*/ window->setLayout(wholeApp); // 把其他method也寫進去 // 以上先以"測試階段"的感覺去寫 // last step: 整理code 還有output // threatspaceSearch 23 window->show(); return a.exec(); }
MStatus convertOsdFarToMayaMeshData( FMesh const * farMesh, OpenSubdiv::OsdCpuVertexBuffer * vertexBuffer, int subdivisionLevel, MFnMesh const & inMeshFn, MObject newMeshDataObj ) { MStatus returnStatus; // Get sizing data from OSD const OpenSubdiv::FarPatchTables *farPatchTables = farMesh->GetPatchTables(); int numPolygons = farPatchTables->GetNumFaces(); // use the highest level stored in the patch tables const unsigned int *polygonConnects_orig = farPatchTables->GetFaceVertices(); // use the highest level stored in the patch tables const OpenSubdiv::FarSubdivisionTables<OpenSubdiv::OsdVertex> *farSubdivTables = farMesh->GetSubdivisionTables(); unsigned int numVertices = farSubdivTables->GetNumVertices(subdivisionLevel); unsigned int vertexOffset = farSubdivTables->GetFirstVertexOffset(subdivisionLevel); // Init Maya Data MFloatPointArray points(numVertices); MIntArray faceCounts(numPolygons); // number of edges for each polygon. Assume quads (4-edges per face) MIntArray faceConnects(numPolygons*4); // array of vertex ids for all edges. assuming quads // -- Face Counts for (int i=0; i < numPolygons; ++i) { faceCounts[i] = 4; } // -- Face Connects for (unsigned int i=0; i < faceConnects.length(); i++) { faceConnects[i] = polygonConnects_orig[i] - vertexOffset; // adjust vertex indices so that v0 is at index 0 } // -- Points // Number of floats in each vertex. (positions, normals, etc) int numFloatsPerVertex = vertexBuffer->GetNumElements(); assert(numFloatsPerVertex == 3); // assuming only xyz stored for each vertex const float *vertexData = vertexBuffer->BindCpuBuffer(); float *ptrVertexData; for (unsigned int i=0; i < numVertices; i++) { // make sure to offset to the first osd vertex for that subd level unsigned int osdRawVertexIndex = i + vertexOffset; // Lookup the data in the vertexData ptrVertexData = (float *) vertexData + ((osdRawVertexIndex) * numFloatsPerVertex); points.set(i, ptrVertexData[0], ptrVertexData[1], ptrVertexData[2]); } // Create New Mesh from MFnMesh MFnMesh newMeshFn; MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(), points, faceCounts, faceConnects, newMeshDataObj, &returnStatus); MCHECKERR(returnStatus, "Cannot create new mesh"); // Attach UVs (if present) // ASSUMPTION: Only tracking UVs as FVar data. Will need to change this // ASSUMPTION: OSD has a unique UV for each face-vertex int fvarTotalWidth = farMesh->GetTotalFVarWidth(); if (fvarTotalWidth > 0) { // Get face-varying set names and other info from the inMesh MStringArray uvSetNames; MStringArray colorSetNames; std::vector<int> colorSetChannels; std::vector<MFnMesh::MColorRepresentation> colorSetReps; int totalColorSetChannels = 0; returnStatus = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames, colorSetChannels, colorSetReps, totalColorSetChannels); int numUVSets = uvSetNames.length(); int expectedFvarTotalWidth = numUVSets*2 + totalColorSetChannels; assert(fvarTotalWidth == expectedFvarTotalWidth); const OpenSubdiv::FarPatchTables::FVarDataTable &fvarDataTable = farPatchTables->GetFVarDataTable(); assert(fvarDataTable.size() == expectedFvarTotalWidth*faceConnects.length()); // Create an array of indices to map each face-vert to the UV and ColorSet Data MIntArray fvarConnects(faceConnects.length()); for (unsigned int i=0; i < faceConnects.length(); i++) { fvarConnects[i] = i; } MFloatArray uCoord(faceConnects.length()); MFloatArray vCoord(faceConnects.length()); for (int uvSetIndex=0; uvSetIndex < numUVSets; uvSetIndex++) { for(unsigned int vertid=0; vertid < faceConnects.length(); vertid++) { int fvarItem = vertid*fvarTotalWidth + uvSetIndex*2; // stride per vertex is the fvarTotalWidth uCoord[vertid] = fvarDataTable[fvarItem]; vCoord[vertid] = fvarDataTable[fvarItem+1]; } // Assign UV buffer and map the uvids for each face-vertex if (uvSetIndex != 0) { // assume uvset index 0 is the default UVset, so do not create returnStatus = newMeshFn.createUVSetDataMesh( uvSetNames[uvSetIndex] ); } MCHECKERR(returnStatus, "Cannot create UVSet"); newMeshFn.setUVs(uCoord,vCoord, &uvSetNames[uvSetIndex]); newMeshFn.assignUVs(faceCounts, fvarConnects, &uvSetNames[uvSetIndex]); } MColorArray colorArray(faceConnects.length()); int colorSetRelativeStartIndex = numUVSets*2; for (unsigned int colorSetIndex=0; colorSetIndex < colorSetNames.length(); colorSetIndex++) { for(unsigned int vertid=0; vertid < faceConnects.length(); vertid++) { int fvarItem = vertid*fvarTotalWidth + colorSetRelativeStartIndex; if (colorSetChannels[colorSetIndex] == 1) { colorArray[vertid].r = fvarDataTable[fvarItem]; colorArray[vertid].g = fvarDataTable[fvarItem]; colorArray[vertid].b = fvarDataTable[fvarItem]; colorArray[vertid].a = 1.0f; } else if (colorSetChannels[colorSetIndex] == 3) { colorArray[vertid].r = fvarDataTable[fvarItem]; colorArray[vertid].g = fvarDataTable[fvarItem+1]; colorArray[vertid].b = fvarDataTable[fvarItem+2]; colorArray[vertid].a = 1.0f; } else { colorArray[vertid].r = fvarDataTable[fvarItem]; colorArray[vertid].g = fvarDataTable[fvarItem+1]; colorArray[vertid].b = fvarDataTable[fvarItem+2]; colorArray[vertid].a = fvarDataTable[fvarItem+3]; } } // Assign UV buffer and map the uvids for each face-vertex // API Limitation: Cannot set MColorRepresentation here returnStatus = newMeshFn.createColorSetDataMesh(colorSetNames[colorSetIndex]); MCHECKERR(returnStatus, "Cannot create ColorSet"); bool isColorClamped = inMeshFn.isColorClamped(colorSetNames[colorSetIndex], &returnStatus); newMeshFn.setIsColorClamped(colorSetNames[colorSetIndex], isColorClamped); newMeshFn.setColors(colorArray, &colorSetNames[colorSetIndex], colorSetReps[colorSetIndex]); newMeshFn.assignColors(fvarConnects, &colorSetNames[colorSetIndex]); // Increment colorSet start location in fvar buffer colorSetRelativeStartIndex += colorSetChannels[colorSetIndex]; } } return MS::kSuccess; }
SICALLBACK aaOcean_Evaluate( ICENodeContext& in_ctxt ) { aaOcean *pOcean = (aaOcean *)(CValue::siPtrType)in_ctxt.GetUserData(); CIndexSet indexSet(in_ctxt, ID_IN_PointID ); CDataArrayLong PointID(in_ctxt, ID_IN_PointID ); CDataArrayBool bEnable(in_ctxt, ID_IN_ENABLE); CDataArrayFloat uCoord(in_ctxt, ID_IN_U); CDataArrayFloat vCoord(in_ctxt, ID_IN_V); CDataArrayBool enableFoam( in_ctxt, ID_IN_ENABLEFOAM); CDataArrayMatrix4f transform(in_ctxt, ID_IN_TRANSFORM); const int count = PointID.GetCount(); float worldSpaceVec[3] = {0.0f, 0.0f, 0.0f}; float localSpaceVec[3] = {0.0f, 0.0f, 0.0f}; int transformArraySize = 0; bool transformSingleton = TRUE; if(transform.GetCount() > 1) transformSingleton = FALSE; ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( ); switch( out_portID ) { case ID_OUT_OCEAN: { CDataArrayVector3f outData( in_ctxt ); if(bEnable[0]) { #pragma omp parallel for private(worldSpaceVec, localSpaceVec) for(int i = 0; i<count; ++i) { // get ocean displacement vector worldSpaceVec[1] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eHEIGHTFIELD); if(pOcean->isChoppy()) { worldSpaceVec[0] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eCHOPX); worldSpaceVec[2] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eCHOPZ); } // multiply displacement vector by input transform matrix if(!transformSingleton) transformArraySize = i; multiplyMatrix(&worldSpaceVec[0], &localSpaceVec[0], transform, transformArraySize); outData[i].PutX(localSpaceVec[0]); outData[i].PutY(localSpaceVec[1]); outData[i].PutZ(localSpaceVec[2]); outData[i].PutX(worldSpaceVec[0]); outData[i].PutY(worldSpaceVec[1]); outData[i].PutZ(worldSpaceVec[2]); } } else { #pragma omp parallel for for(int i = 0; i<count; ++i) { outData[i].PutX(0.f); outData[i].PutY(0.f); outData[i].PutZ(0.f); } } } break; case ID_OUT_FOAM: { if(pOcean->isChoppy() && bEnable[0] && enableFoam[0]) { CDataArrayFloat outData( in_ctxt ); // output raw (unscaled) foam in ICE deformer #pragma omp parallel for for(int i = 0; i<count; ++i) outData[i] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eFOAM); } } break; case ID_OUT_EIGEN_MINUS: { CDataArrayVector3f outData( in_ctxt ); if(pOcean->isChoppy() && bEnable[0] && enableFoam[0]) { #pragma omp parallel for private(worldSpaceVec, localSpaceVec) for(int i = 0; i<count; ++i) { worldSpaceVec[0] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eEIGENMINUSX); worldSpaceVec[2] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eEIGENMINUSZ); multiplyMatrix(&worldSpaceVec[0], &localSpaceVec[0], transform, transformArraySize); outData[i].PutX(localSpaceVec[0]); outData[i].PutY(0.0f); outData[i].PutZ(localSpaceVec[2]); } } else { #pragma omp parallel for for(int i = 0; i<count; ++i){ outData[i].PutX(0);outData[i].PutY(0);outData[i].PutZ(0);} } } break; case ID_OUT_EIGEN_PLUS: { CDataArrayVector3f outData( in_ctxt ); if(pOcean->isChoppy() && bEnable[0] && enableFoam[0]) { #pragma omp parallel for private(worldSpaceVec, localSpaceVec) for(int i = 0; i<count; ++i) { worldSpaceVec[0] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eEIGENPLUSX); worldSpaceVec[2] = pOcean->getOceanData(uCoord[i], vCoord[i], aaOcean::eEIGENPLUSZ); multiplyMatrix(&worldSpaceVec[0], &localSpaceVec[0], transform, transformArraySize); outData[i].PutX(localSpaceVec[0]); outData[i].PutY(0.0f); outData[i].PutZ(localSpaceVec[2]); } } else { #pragma omp parallel for for(int i = 0; i<count; ++i){ outData[i].PutX(0); outData[i].PutY(0); outData[i].PutZ(0);} } } break; } return CStatus::OK; }