Beispiel #1
0
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();
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}