예제 #1
0
    void computeWithDerivative(tbb::blocked_range<int> const &r) const {
        float wP[20], wDs[20], wDt[20];
        BufferAdapter<const float> srcT(_src + _srcDesc.offset,
                                        _srcDesc.length,
                                        _srcDesc.stride);
        BufferAdapter<float> dstT(_dst + _dstDesc.offset
                                       + r.begin() * _dstDesc.stride,
                                  _dstDesc.length,
                                  _dstDesc.stride);
        BufferAdapter<float> dstDuT(_dstDu + _dstDuDesc.offset
                                       + r.begin() * _dstDuDesc.stride,
                                  _dstDuDesc.length,
                                  _dstDuDesc.stride);
        BufferAdapter<float> dstDvT(_dstDv + _dstDvDesc.offset
                                       + r.begin() * _dstDvDesc.stride,
                                  _dstDvDesc.length,
                                  _dstDvDesc.stride);

        for (int i = r.begin(); i < r.end(); ++i) {
            PatchCoord const &coord = _patchCoords[i];
            PatchArray const &array = _patchArrayBuffer[coord.handle.arrayIndex];

            int patchType = array.GetPatchType();
            Far::PatchParam const & param =
                _patchParamBuffer[coord.handle.patchIndex];

            int numControlVertices = 0;
            if (patchType == Far::PatchDescriptor::REGULAR) {
                Far::internal::GetBSplineWeights(param,
                                                 coord.s, coord.t, wP, wDs, wDt);
                numControlVertices = 16;
            } else if (patchType == Far::PatchDescriptor::GREGORY_BASIS) {
                Far::internal::GetGregoryWeights(param,
                                                 coord.s, coord.t, wP, wDs, wDt);
                numControlVertices = 20;
            } else if (patchType == Far::PatchDescriptor::QUADS) {
                Far::internal::GetBilinearWeights(param,
                                                  coord.s, coord.t, wP, wDs, wDt);
                numControlVertices = 4;
            } else {
                assert(0);
            }

            const int *cvs =
                &_patchIndexBuffer[array.indexBase + coord.handle.vertIndex];

            dstT.Clear();
            dstDuT.Clear();
            dstDvT.Clear();
            for (int j = 0; j < numControlVertices; ++j) {
                dstT.AddWithWeight(srcT[cvs[j]], wP[j]);
                dstDuT.AddWithWeight(srcT[cvs[j]], wDs[j]);
                dstDvT.AddWithWeight(srcT[cvs[j]], wDt[j]);
            }
            ++dstT;
            ++dstDuT;
            ++dstDvT;
        }
    }
예제 #2
0
/* static */
bool
OmpEvaluator::EvalPatches(
    const float *src, BufferDescriptor const &srcDesc,
    float *dst,       BufferDescriptor const &dstDesc,
    int numPatchCoords,
    const PatchCoord *patchCoords,
    const PatchArray *patchArrays,
    const int *patchIndexBuffer,
    const PatchParam *patchParamBuffer){

    src += srcDesc.offset;
    if (dst) dst += dstDesc.offset;
    else return false;
    BufferAdapter<const float> srcT(src, srcDesc.length, srcDesc.stride);

#pragma omp parallel for
    for (int i = 0; i < numPatchCoords; ++i) {
        BufferAdapter<float> dstT(dst + dstDesc.stride*i, dstDesc.length, dstDesc.stride);

        float wP[20], wDs[20], wDt[20];
        PatchCoord const &coord = patchCoords[i];
        PatchArray const &array = patchArrays[coord.handle.arrayIndex];

        int patchType = array.GetPatchType();
        // XXX: patchIndex is absolute. not sure it's consistent.
        //      (should be offsetted by array.primitiveIdBase?)
        //    patchParamBuffer[array.primitiveIdBase + coord.handle.patchIndex]
        Far::PatchParam::BitField patchBits = *(Far::PatchParam::BitField*)
            &patchParamBuffer[coord.handle.patchIndex].patchBits;

        int numControlVertices = 0;
        if (patchType == Far::PatchDescriptor::REGULAR) {
            Far::internal::GetBSplineWeights(patchBits,
                                             coord.s, coord.t, wP, wDs, wDt);
            numControlVertices = 16;
        } else if (patchType == Far::PatchDescriptor::GREGORY_BASIS) {
            Far::internal::GetGregoryWeights(patchBits,
                                             coord.s, coord.t, wP, wDs, wDt);
            numControlVertices = 20;
        } else if (patchType == Far::PatchDescriptor::QUADS) {
            Far::internal::GetBilinearWeights(patchBits,
                                              coord.s, coord.t, wP, wDs, wDt);
            numControlVertices = 4;
        } else {
            continue;
        }
        const int *cvs =
            &patchIndexBuffer[array.indexBase + coord.handle.vertIndex];

        dstT.Clear();
        for (int j = 0; j < numControlVertices; ++j) {
            dstT.AddWithWeight(srcT[cvs[j]], wP[j]);
        }
    }
    return true;
}
예제 #3
0
/* static */
bool
OmpEvaluator::EvalPatches(
    const float *src, BufferDescriptor const &srcDesc,
    float *dst,       BufferDescriptor const &dstDesc,
    float *du,        BufferDescriptor const &duDesc,
    float *dv,        BufferDescriptor const &dvDesc,
    int numPatchCoords,
    PatchCoord const *patchCoords,
    PatchArray const *patchArrays,
    const int *patchIndexBuffer,
    PatchParam const *patchParamBuffer) {

    src += srcDesc.offset;
    if (dst) dst += dstDesc.offset;
    if (du)  du += duDesc.offset;
    if (dv)  dv += dvDesc.offset;

    BufferAdapter<const float> srcT(src, srcDesc.length, srcDesc.stride);

#pragma omp parallel for
    for (int i = 0; i < numPatchCoords; ++i) {
        float wP[20], wDs[20], wDt[20];
        BufferAdapter<float> dstT(dst + dstDesc.stride*i, dstDesc.length, dstDesc.stride);
        BufferAdapter<float> duT(du   + duDesc.stride*i, duDesc.length, duDesc.stride);
        BufferAdapter<float> dvT(dv   + dvDesc.stride*i, dvDesc.length, dvDesc.stride);

        PatchCoord const &coord = patchCoords[i];
        PatchArray const &array = patchArrays[coord.handle.arrayIndex];

        int patchType = array.GetPatchType();
        Far::PatchParam::BitField patchBits = *(Far::PatchParam::BitField*)
            &patchParamBuffer[coord.handle.patchIndex].patchBits;

        int numControlVertices = 0;
        if (patchType == Far::PatchDescriptor::REGULAR) {
            Far::internal::GetBSplineWeights(patchBits,
                                             coord.s, coord.t, wP, wDs, wDt);
            numControlVertices = 16;
        } else if (patchType == Far::PatchDescriptor::GREGORY_BASIS) {
            Far::internal::GetGregoryWeights(patchBits,
                                             coord.s, coord.t, wP, wDs, wDt);
            numControlVertices = 20;
        } else if (patchType == Far::PatchDescriptor::QUADS) {
            Far::internal::GetBilinearWeights(patchBits,
                                              coord.s, coord.t, wP, wDs, wDt);
            numControlVertices = 4;
        } else {
            continue;
        }
        const int *cvs =
            &patchIndexBuffer[array.indexBase + coord.handle.vertIndex];

        dstT.Clear();
        duT.Clear();
        dvT.Clear();
        for (int j = 0; j < numControlVertices; ++j) {
            dstT.AddWithWeight(srcT[cvs[j]], wP[j]);
            duT.AddWithWeight(srcT[cvs[j]], wDs[j]);
            dvT.AddWithWeight(srcT[cvs[j]], wDt[j]);
        }
        ++dstT;
        ++duT;
        ++dvT;
    }
    return true;
}