bool
OsdUtilAdaptiveEvaluator::Refine(
    int numThreads, string * /* errorMessage */)
{
    const FarMesh<OsdVertex> *fmesh = _refiner->GetFarMesh();


    if (numThreads > 1) {
#ifdef OPENSUBDIV_HAS_OPENMP
        OsdOmpComputeController ompComputeController(numThreads);
        ompComputeController.Refine(_computeContext,
                                    fmesh->GetKernelBatches(),
                                    _vertexBuffer, _vvBuffer);
        return true;
#endif
    }


    OsdCpuComputeController cpuComputeController;
    cpuComputeController.Refine(_computeContext,
                                fmesh->GetKernelBatches(),
                                _vertexBuffer, _vvBuffer);

    return true;
}
Beispiel #2
0
//------------------------------------------------------------------------------
static void
createOsdMesh( const std::string &shape, int level, Scheme scheme=kCatmark ) {

    // Create HBR mesh
    OsdHbrMesh * hmesh = simpleHbr<OsdVertex>(shape.c_str(), scheme, g_orgPositions, true);

    g_positions.resize(g_orgPositions.size(),0.0f);

    int nfaces = hmesh->GetNumFaces(),
        nptexfaces = getNumPtexFaces(hmesh, nfaces);
    
    // Generate sample locations 
    int nsamples = createRandomSamples( nptexfaces, g_nsamples, g_coords );

    createCoarseMesh(hmesh, nfaces);

    // Create FAR mesh
    OsdFarMeshFactory factory( hmesh, level, /*adaptive*/ true);    
    
    delete g_fmesh;
    g_fmesh = factory.Create(/*fvar*/ true);
    
    int nverts = g_fmesh->GetNumVertices();
    

    
    // Create v-buffer & populate w/ positions
    delete g_vertexData;
    g_vertexData = OsdCpuVertexBuffer::Create(3, nverts);

    // Create primvar v-buffer & populate w/ colors or (u,v) data
    delete g_varyingData; g_varyingData = 0;
    if (g_drawMode==kVARYING) {
        g_varyingData = OsdCpuVertexBuffer::Create(3, nverts);
        g_varyingData->UpdateData( &g_varyingColors[0], 0, nverts);
    }
            
    // Create a Compute context, used to "pose" the vertices
    delete g_computeCtx;
    g_computeCtx = OsdCpuComputeContext::Create(g_fmesh->GetSubdivisionTables(), g_fmesh->GetVertexEditTables());
    
    g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData, g_varyingData );
    

    
    // Create eval context & data buffers
    delete g_evalCtx;
    g_evalCtx = OsdCpuEvalLimitContext::Create(g_fmesh->GetPatchTables(), /*requireFVarData*/ true);

    delete g_Q;
    g_Q = OsdCpuGLVertexBuffer::Create(6,nsamples);
    memset( g_Q->BindCpuBuffer(), 0, nsamples*6*sizeof(float));

    delete g_dQu;
    g_dQu = OsdCpuGLVertexBuffer::Create(6,nsamples);
    memset( g_dQu->BindCpuBuffer(), 0, nsamples*6*sizeof(float));

    delete g_dQv;
    g_dQv = OsdCpuGLVertexBuffer::Create(6,nsamples);
    memset( g_dQv->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
        
    updateGeom();

    // Bind g_Q as a GL_POINTS VBO
    glBindVertexArray(g_samplesVAO);
    
    glBindBuffer(GL_ARRAY_BUFFER, g_Q->BindVBO());

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (float*)12);

    glBindVertexArray(0);
}
Beispiel #3
0
//------------------------------------------------------------------------------
static void
updateGeom() {

    int nverts = (int)g_orgPositions.size() / 3;

    const float *p = &g_orgPositions[0];

    float r = sin(g_frame*0.001f) * g_moveScale;

    for (int i = 0; i < nverts; ++i) {
        //float move = 0.05f*cosf(p[0]*20+g_frame*0.01f);
        float ct = cos(p[2] * r);
        float st = sin(p[2] * r);
        g_positions[i*3+0] = p[0]*ct + p[1]*st;
        g_positions[i*3+1] = -p[0]*st + p[1]*ct;
        g_positions[i*3+2] = p[2];
        p+=3;
    }

    // Run Compute pass to pose the control vertices ---------------------------
    Stopwatch s;
    s.Start();
    
    g_vertexData->UpdateData( &g_positions[0], 0, nverts);
    
    g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData, g_varyingData );

    s.Stop();
    g_computeTime = float(s.GetElapsed() * 1000.0f);


    // Run Eval pass to get the samples locations ------------------------------

    s.Start();
    
    // Reset the output buffer

    g_nsamplesFound=0;

    // Bind/Unbind of the vertex buffers to the context needs to happen 
    // outside of the parallel loop
    g_evalCtx->GetVertexData().Bind( g_idesc, g_vertexData, g_odesc, g_Q, g_dQu, g_dQv );

    // The varying data ends-up interleaved in the same g_Q output buffer because
    // g_Q has a stride of 6 and g_vdesc sets the offset to 3, while g_odesc sets
    // the offset to 0
    switch (g_drawMode) {
        case kVARYING     : g_evalCtx->GetVaryingData().Bind( g_idesc, g_varyingData, g_vdesc, g_Q ); break;

        case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Bind( g_fvidesc, g_fvodesc, g_Q );

        case kUV :

        default : g_evalCtx->GetVaryingData().Unbind(); break;
    }

#define USE_OPENMP
#if defined(OPENSUBDIV_HAS_OPENMP) and defined(USE_OPENMP)
    #pragma omp parallel for
#endif
    for (int i=0; i<(int)g_coords.size(); ++i) {
    
        int n = g_evalCtrl.EvalLimitSample<OsdCpuVertexBuffer,OsdCpuGLVertexBuffer>( g_coords[i], g_evalCtx, i );

        if (n) {
            // point colors
            switch (g_drawMode) {
                case kUV : { float * color = g_Q->BindCpuBuffer() + i*g_Q->GetNumElements()  + 3;
                             color[0] = g_coords[i].u;
                             color[1] = 0.0f;
                             color[2] = g_coords[i].v; } break;

                case kVARYING : break;

                case kFACEVARYING : break;
                
                default : break;
           }
#if defined(OPENSUBDIV_HAS_OPENMP) and defined(USE_OPENMP)
            #pragma omp atomic
#endif
            g_nsamplesFound += n;
        } else {
            // "hide" unfound samples (hole tags...) as a black dot at the origin
            float * sample = g_Q->BindCpuBuffer() + i*g_Q->GetNumElements();
            memset(sample, 0, g_Q->GetNumElements() * sizeof(float));
        }
    }
    
    g_evalCtx->GetVertexData().Unbind();

    switch (g_drawMode) {
        case kVARYING     : g_evalCtx->GetVaryingData().Unbind(); break;

        case kFACEVARYING : g_evalCtx->GetFaceVaryingData().Unbind(); break;

        default : break;
    }
    
    g_Q->BindVBO();

    s.Stop();
    
    g_evalTime = float(s.GetElapsed() * 1000.0f);
}