示例#1
0
文件: triangulate.cpp 项目: JT-a/USD
bool
HdSt_TriangulateFaceVaryingComputation::Resolve()
{
    if (!TF_VERIFY(_source)) return false;
    if (!_source->IsResolved()) return false;

    if (!_TryLock()) return false;

    HD_TRACE_FUNCTION();
    HD_PERF_COUNTER_INCR(HdPerfTokens->triangulateFaceVarying);

    VtValue result;
    HdMeshUtil meshUtil(_topology, _id);
    if(meshUtil.ComputeTriangulatedFaceVaryingPrimvar(
            _source->GetData(),
            _source->GetNumElements(),
            _source->GetGLElementDataType(),
            &result)) {
        _SetResult(HdBufferSourceSharedPtr(
                    new HdVtBufferSource(
                        _source->GetName(),
                        result)));
    } else {
        _SetResult(_source);
    }

    _SetResolved();
    return true;
}
示例#2
0
bool
Hd_TriangulateFaceVaryingComputation::Resolve()
{
    if (not TF_VERIFY(_source)) return false;
    if (not _source->IsResolved()) return false;

    if (not _TryLock()) return false;

    HD_TRACE_FUNCTION();
    HD_PERF_COUNTER_INCR(HdPerfTokens->triangulateFaceVarying);

    VtIntArray const &faceVertexCounts = _topology->GetFaceVertexCounts();
    VtIntArray const &holeFaces = _topology->GetHoleIndices();
    bool flip = (_topology->GetOrientation() != HdTokens->rightHanded);
    HdBufferSourceSharedPtr result;

    switch (_source->GetGLElementDataType()) {
    case GL_FLOAT:
        result = _TriangulateFaceVarying<float>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    case GL_FLOAT_VEC2:
        result = _TriangulateFaceVarying<GfVec2f>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    case GL_FLOAT_VEC3:
        result = _TriangulateFaceVarying<GfVec3f>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    case GL_FLOAT_VEC4:
        result = _TriangulateFaceVarying<GfVec4f>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    case GL_DOUBLE:
        result = _TriangulateFaceVarying<double>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    case GL_DOUBLE_VEC2:
        result = _TriangulateFaceVarying<GfVec2d>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    case GL_DOUBLE_VEC3:
        result = _TriangulateFaceVarying<GfVec3d>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    case GL_DOUBLE_VEC4:
        result = _TriangulateFaceVarying<GfVec4d>(
            _source, faceVertexCounts, holeFaces, flip, _id);
        break;
    default:
        TF_CODING_ERROR("Unsupported primvar type for triangulation [%s]",
                        _id.GetText());
        result = _source;
        break;
    }

    _SetResult(result);
    _SetResolved();
    return true;
}
示例#3
0
文件: triangulate.cpp 项目: JT-a/USD
bool
HdSt_TriangleIndexBuilderComputation::Resolve()
{
    if (!_TryLock()) return false;

    HD_TRACE_FUNCTION();

    VtVec3iArray trianglesFaceVertexIndices;
    VtIntArray primitiveParam;
    HdMeshUtil meshUtil(_topology, _id);
    meshUtil.ComputeTriangleIndices(
            &trianglesFaceVertexIndices,
            &primitiveParam);

    _SetResult(HdBufferSourceSharedPtr(
                   new HdVtBufferSource(
                       HdTokens->indices,
                       VtValue(trianglesFaceVertexIndices))));

    _primitiveParam.reset(new HdVtBufferSource(
                              HdTokens->primitiveParam,
                              VtValue(primitiveParam)));

    _SetResolved();
    return true;
}
示例#4
0
bool
Hd_SceneExtCompInputSource::Resolve()
{
    if (!_TryLock()) return false;

    _SetResolved();
    return true;
}
示例#5
0
bool
Hd_SmoothNormalsComputation::Resolve()
{
    // dependency check first
    if (_adjacencyBuilder) {
        if (not _adjacencyBuilder->IsResolved()) return false;
    }
    if (_points) {
        if (not _points->IsResolved()) return false;
    }
    if (not _TryLock()) return false;

    HD_TRACE_FUNCTION();
    HD_MALLOC_TAG_FUNCTION();

    if (not TF_VERIFY(_adjacency)) return true;

    int numPoints = _points->GetNumElements();

    HdBufferSourceSharedPtr normals;
    switch (_points->GetGLElementDataType()) {
    case GL_FLOAT_VEC3:
        normals = HdBufferSourceSharedPtr(
            new HdVtBufferSource(
                _dstName, VtValue(
                    _adjacency->ComputeSmoothNormals(
                        numPoints,
                        static_cast<const GfVec3f*>(_points->GetData())))));
        break;
    case GL_DOUBLE_VEC3:
        normals = HdBufferSourceSharedPtr(
            new HdVtBufferSource(
                _dstName, VtValue(
                    _adjacency->ComputeSmoothNormals(
                        numPoints,
                        static_cast<const GfVec3d*>(_points->GetData())))));
        break;
    default:
        TF_CODING_ERROR("Unsupported points type for computing smooth normals");
        break;
    }

    _SetResult(normals);

    // call base class to mark as resolved.
    _SetResolved();
    return true;
}
示例#6
0
bool
Hd_CompExtCompInputSource::Resolve()
{
    bool sourceValid = _source->IsValid();
    if (sourceValid) {
        if (!_source->IsResolved()) {
            return false;
        }
    }

    if (!_TryLock()) return false;

    if (!sourceValid || _source->HasResolveError()) {
        _SetResolveError();
        return true;
    }

    _SetResolved();
    return true;
}
示例#7
0
bool
Hd_AdjacencyBuilderForGPUComputation::Resolve()
{
    if (!_adjacencyBuilder->IsResolved()) return false;
    if (!_TryLock()) return false;

    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    // prepare buffer source to be transferred.
    std::vector<int> const &adjacency = _adjacency->GetAdjacencyTable();

    // create buffer source
    VtIntArray array(adjacency.size());
    for (size_t i = 0; i < adjacency.size(); ++i) {
        array[i] = adjacency[i];
    }
    _SetResult(HdBufferSourceSharedPtr(new HdVtBufferSource(HdTokens->adjacency,
                                                            VtValue(array))));
    _SetResolved();
    return true;
}
bool
HdExtCompPrimvarBufferSource::Resolve()
{
    bool sourceValid = _source->IsValid();
    if (sourceValid) {
        if (!_source->IsResolved()) {
            return false;
        }
    }

    if (!_TryLock()) return false;

    if (!sourceValid || _source->HasResolveError()) {
        _SetResolveError();
        return true;
    }

    HdVtBufferSource output(_primvarName,
                            _source->GetOutputByIndex(_sourceOutputIdx));

    // Validate output type and count matches what is expected.
    if (output.GetTupleType() != _tupleType) {
        TF_WARN("Output type mismatch on %s. ", _primvarName.GetText());
        _SetResolveError();
        return true;
    }
    if (output.GetNumElements() != _source->GetNumElements()) {
        TF_WARN("Output elements mismatch on %s. ", _primvarName.GetText());
        _SetResolveError();
        return true;
    }

    _rawDataPtr = output.GetData();

    _SetResolved();
    return true;
}
示例#9
0
bool
Hd_TriangleIndexBuilderComputation::Resolve()
{
    if (not _TryLock()) return false;

    HD_TRACE_FUNCTION();

    // generate triangle index buffer

    int const * numVertsPtr = _topology->GetFaceVertexCounts().cdata();
    int const * vertsPtr = _topology->GetFaceVertexIndices().cdata();
    int const * holeFacesPtr = _topology->GetHoleIndices().cdata();
    int numFaces = _topology->GetFaceVertexCounts().size();
    int numVertIndices = _topology->GetFaceVertexIndices().size();
    int numTris = 0;
    int numHoleFaces = _topology->GetHoleIndices().size();
    bool invalidTopology = false;
    int holeIndex = 0;
    for (int i=0; i<numFaces; ++i) {
        int nv = numVertsPtr[i]-2;
        if (nv < 1) {
            // skip degenerated face
            invalidTopology = true;
        } else if (holeIndex < numHoleFaces and holeFacesPtr[holeIndex] == i) {
            // skip hole face
            ++holeIndex;
        } else {
            numTris += nv;
        }
    }
    if (invalidTopology) {
        TF_WARN("degenerated face found [%s]", _id.GetText());
        invalidTopology = false;
    }

    VtVec3iArray trianglesFaceVertexIndices(numTris);
    VtIntArray primitiveParam(numTris);
    bool flip = (_topology->GetOrientation() != HdTokens->rightHanded);

    // reset holeIndex
    holeIndex = 0;

    for (int i=0,tv=0,v=0; i<numFaces; ++i) {
        int nv = numVertsPtr[i];
        if (nv < 3) {
            // Skip degenerate faces.
        } else if (holeIndex < numHoleFaces and holeFacesPtr[holeIndex] == i) {
            // Skip hole faces.
            ++holeIndex;
        } else {
            // edgeFlag is used for inner-line removal of non-triangle
            // faces on wireframe shading.
            //
            //          0__                0  0   0__
            //        _/|\ \_            _/.  ..   . \_
            //      _/  | \  \_   ->   _/  .  . .   .  \_
            //     /  A |C \ B \_     /  A .  .C .   . B \_
            //    1-----2---3----4   1-----2  1---2   1----2
            //
            //  Type   EdgeFlag    Draw
            //    -       0        show all edges
            //    A       1        hide [2-0]
            //    B       2        hide [0-1]
            //    C       3        hide [0-1] and [2-0]
            //
            int edgeFlag = 0;
            for (int j=0; j < nv-2; ++j) {
                if (nv > 3) {
                    if (j == 0) edgeFlag = flip ? 2 : 1;
                    else if (j == nv-3) edgeFlag = flip ? 1 : 2;
                    else edgeFlag = 3;
                }

                if (not _FanTriangulate(
                        trianglesFaceVertexIndices[tv],
                        vertsPtr, v, j, numVertIndices, flip)) {
                    invalidTopology = true;
                }

                // note that ptex indexing isn't available along with
                // triangulation.
                int coarseFaceParam =
                    HdMeshTopology::EncodeCoarseFaceParam(i, edgeFlag);
                primitiveParam[tv] = coarseFaceParam;
                ++tv;
            }
        }
        // When the face is degenerate and nv > 0, we need to increment the v
        // pointer to walk past the degenerate verts.
        v += nv;
    }
    if (invalidTopology) {
        TF_WARN("numVerts and verts are incosistent [%s]",
                _id.GetText());
    }

    _SetResult(HdBufferSourceSharedPtr(
                   new HdVtBufferSource(
                       HdTokens->indices,
                       VtValue(trianglesFaceVertexIndices))));

    _primitiveParam.reset(new HdVtBufferSource(
                              HdTokens->primitiveParam,
                              VtValue(primitiveParam)));

    _SetResolved();
    return true;
}
示例#10
0
bool
Hd_AdjacencyBuilderComputation::Resolve()
{
    if (!_TryLock()) return false;

    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    // compute adjacency

    int const * numVertsPtr = _topology->GetFaceVertexCounts().cdata();
    int const * vertsPtr = _topology->GetFaceVertexIndices().cdata();
    int numFaces = _topology->GetFaceVertexCounts().size();
    // compute numPoints from topology indices
    int numPoints = HdMeshTopology::ComputeNumPoints(
        _topology->GetFaceVertexIndices());
    bool flip = (_topology->GetOrientation() != HdTokens->rightHanded);

    // Store the number of points
    _adjacency->_numPoints = numPoints;


    // Track the number of entries needed the adjacency table.
    // We start by needing 2 per point (offset and valence).
    size_t numEntries = numPoints * 2;


    // Compute the size of each entry, so we can work out the offsets.
    std::vector<int> vertexValence(numPoints);


    int vertIndex = 0;
    for (int i=0; i<numFaces; ++i) {
        int nv = numVertsPtr[i];
        for (int j=0; j<nv; ++j) {
            int index = vertsPtr[vertIndex++];
            if (index < 0 || index >= numPoints) {
                TF_CODING_ERROR("vertex index out of range "
                                "index: %d numPoints: %d", index, numPoints);
                return false;
            }
            ++vertexValence[index];
        }

        // Increase the number of entries needed by 2 (prev & next index).
        // for every vertex in the face.
        numEntries += 2 * nv;
    }


    // Each entry is a count followed by pairs of adjacent vertex indices.
    // We use a uniform entry size for all vertices, this allows faster
    // lookups at the cost of some additional memory.
    std::vector<int> &adjTable = _adjacency->_adjacencyTable;
    HD_PERF_COUNTER_SUBTRACT(HdPerfTokens->adjacencyBufSize,
                                                 adjTable.size() * sizeof(int));


    adjTable.clear();
    adjTable.resize(numEntries, 0);
    HD_PERF_COUNTER_ADD(HdPerfTokens->adjacencyBufSize,
                                                      numEntries * sizeof(int));

    // Fill out first part of buffer with offsets.  Even though we
    // know counts, don't fill them out now, so we know how many indices
    // we've written so far.
    int currentOffset = numPoints * 2;
    for (int pointNum = 0; pointNum < numPoints; ++pointNum) {
        adjTable[pointNum * 2] = currentOffset;
        currentOffset += 2*vertexValence[pointNum];
    }

    vertIndex = 0;
    for (int i=0; i<numFaces; ++i) {
        int nv = numVertsPtr[i];
        for (int j=0; j<nv; ++j) {
            int prev = vertsPtr[vertIndex+(j+nv-1)%nv];
            int curr = vertsPtr[vertIndex+j];
            int next = vertsPtr[vertIndex+(j+1)%nv];
            if (flip) std::swap(prev, next);

            int entryOffset = adjTable[curr * 2 + 0];
            int &entryCount = adjTable[curr * 2 + 1];

            int pairOffset = entryOffset + entryCount * 2;
            ++entryCount;

            adjTable[pairOffset + 0] = prev;
            adjTable[pairOffset + 1] = next;
        }
        vertIndex += nv;
    }

    // call base class to mark as resolved.
    _SetResolved();
    return true;
}
示例#11
0
bool
Hd_SmoothNormalsComputation::Resolve()
{
    // dependency check first
    if (_adjacencyBuilder) {
        if (!_adjacencyBuilder->IsResolved()) return false;
    }
    if (!_points->IsResolved()) return false;
    if (!_TryLock()) return false;

    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    if (!TF_VERIFY(_adjacency)) return true;

    size_t numPoints = _points->GetNumElements();

    HdBufferSourceSharedPtr normals;

    switch (_points->GetTupleType().type) {
    case HdTypeFloatVec3:
        if (_packed) {
            normals = HdBufferSourceSharedPtr(
                new HdVtBufferSource(
                    _dstName, VtValue(
                        Hd_SmoothNormals::ComputeSmoothNormalsPacked(
                            _adjacency,
                            numPoints,
                            static_cast<const GfVec3f*>(_points->GetData())))));
        } else {
            normals = HdBufferSourceSharedPtr(
                new HdVtBufferSource(
                    _dstName, VtValue(
                        Hd_SmoothNormals::ComputeSmoothNormals(
                            _adjacency,
                            numPoints,
                            static_cast<const GfVec3f*>(_points->GetData())))));
        }
        break;
    case HdTypeDoubleVec3:
        if (_packed) {
            normals = HdBufferSourceSharedPtr(
                new HdVtBufferSource(
                    _dstName, VtValue(
                        Hd_SmoothNormals::ComputeSmoothNormalsPacked(
                            _adjacency,
                            numPoints,
                            static_cast<const GfVec3d*>(_points->GetData())))));
        } else {
            normals = HdBufferSourceSharedPtr(
                new HdVtBufferSource(
                    _dstName, VtValue(
                        Hd_SmoothNormals::ComputeSmoothNormals(
                            _adjacency,
                            numPoints,
                            static_cast<const GfVec3d*>(_points->GetData())))));
        }
        break;
    default:
        TF_CODING_ERROR("Unsupported points type for computing smooth normals");
        break;
    }

    _SetResult(normals);

    // call base class to mark as resolved.
    _SetResolved();
    return true;
}
示例#12
0
 virtual bool Resolve() {
     if (not _TryLock()) return false;
     _SetResolved();
     return true;
 }