Example #1
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
HdBufferSourceSharedPtr
HdSt_MeshTopology::GetTriangulateFaceVaryingComputation(
    HdBufferSourceSharedPtr const &source, SdfPath const &id)
{
    return HdBufferSourceSharedPtr(
        new HdSt_TriangulateFaceVaryingComputation(this, source, id));
}
Example #5
0
HdBufferSourceSharedPtr
Hd_VertexAdjacency::GetAdjacencyBuilderForGPUComputation()
{
    // If the cpu adjacency table has requested to be computed (and not yet
    // solved), make a dependency to its builder.
    HdBufferSourceSharedPtr gpuAdjacecnyBuilder =
        HdBufferSourceSharedPtr(new Hd_AdjacencyBuilderForGPUComputation(
                                    this, _adjacencyBuilder.lock()));

    return gpuAdjacecnyBuilder;
}
Example #6
0
HdBufferSourceSharedPtr
Hd_VertexAdjacency::GetSmoothNormalsComputation(
    HdBufferSourceSharedPtr const &points,
    TfToken const &dstName, bool packed)
{
    // if the vertex adjacency is scheduled to be built (and not yet resolved),
    // make a dependency to its builder.
    return HdBufferSourceSharedPtr(
        new Hd_SmoothNormalsComputation(
            this, points, dstName, _adjacencyBuilder.lock(), packed));
}
Example #7
0
HdBufferSourceSharedPtr
HdSt_MeshTopology::GetPointsIndexBuilderComputation()
{
    // this is simple enough to return the result right away.
    int numPoints = GetNumPoints();
    VtIntArray indices(numPoints);
    for (int i = 0; i < numPoints; ++i) indices[i] = i;

    return HdBufferSourceSharedPtr(
        new HdVtBufferSource(HdTokens->indices, VtValue(indices)));
}
Example #8
0
HdBufferSourceSharedPtr
HdSt_MeshTopology::GetQuadrangulateComputation(
    HdBufferSourceSharedPtr const &source, SdfPath const &id)
{
    // check if the quad table is already computed as all-quads.
    if (_quadInfo && _quadInfo->IsAllQuads()) {
        // no need of quadrangulation.
        return HdBufferSourceSharedPtr();
    }

    // Make a dependency to quad info, in case if the topology
    // is chaging and the quad info hasn't been populated.
    //
    // It can be null for the second or later primvar animation.
    // Don't call GetQuadInfoBuilderComputation instead. It may result
    // unregisterd computation.
    HdBufferSourceSharedPtr quadInfo = _quadInfoBuilder.lock();

    return HdBufferSourceSharedPtr(
        new HdSt_QuadrangulateComputation(this, source, quadInfo, id));
}
Example #9
0
HdBufferSourceSharedPtr
HdSt_MeshTopology::GetOsdTopologyComputation(SdfPath const &id)
{
    if (HdBufferSourceSharedPtr builder = _osdTopologyBuilder.lock()) {
        return builder;
    }

    // this has to be the first instance.
    if (!TF_VERIFY(!_subdivision)) return HdBufferSourceSharedPtr();

    // create HdSt_Subdivision
    _subdivision = HdSt_Osd3Factory::CreateSubdivision();

    if (!TF_VERIFY(_subdivision)) return HdBufferSourceSharedPtr();

    bool adaptive = RefinesToBSplinePatches();

    // create a topology computation for HdSt_Subdivision
    HdBufferSourceSharedPtr builder =
        _subdivision->CreateTopologyComputation(this, adaptive,
                                                _refineLevel, id);
    _osdTopologyBuilder = builder; // retain weak ptr
    return builder;
}
Example #10
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
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;
}
Example #12
0
HdBufferSourceSharedPtr
HdSt_MeshTopology::GetTriangleIndexBuilderComputation(SdfPath const &id)
{
    return HdBufferSourceSharedPtr(
        new HdSt_TriangleIndexBuilderComputation(this, id));
}
Example #13
0
void
HdxSelectionTask::_Sync(HdTaskContext* ctx)
{
    HD_TRACE_FUNCTION();

    SdfPath const& id = GetId();
    HdSceneDelegate* delegate = GetDelegate();
    HdRenderIndex& index = delegate->GetRenderIndex();
    HdChangeTracker& changeTracker = index.GetChangeTracker();
    HdDirtyBits bits = changeTracker.GetTaskDirtyBits(id);
    HdResourceRegistrySharedPtr const& resourceRegistry = 
        index.GetResourceRegistry();

    bool paramsChanged = bits & HdChangeTracker::DirtyParams;
    if (paramsChanged) {
        _GetSceneDelegateValue(HdTokens->params, &_params);
    }

    HdxSelectionTrackerSharedPtr sel;
    if (_GetTaskContextData(ctx, HdxTokens->selectionState, &sel)) {
        sel->Sync(&index);
    }

    if (sel && (paramsChanged || sel->GetVersion() != _lastVersion)) {

        _lastVersion = sel->GetVersion();
        VtIntArray offsets;
        VtIntArray values;
        
        _hasSelection = sel->GetSelectionOffsetBuffer(&index, &offsets);
        if (!_selOffsetBar) {

            HdBufferSpecVector offsetSpecs;
            offsetSpecs.emplace_back(HdxTokens->hdxSelectionBuffer,
                                     HdTupleType { HdTypeInt32, 1 });
            _selOffsetBar = resourceRegistry->AllocateSingleBufferArrayRange(
                                                /*role*/HdxTokens->selection,
                                                offsetSpecs);
        }

        if (!_selUniformBar) {
            HdBufferSpecVector uniformSpecs;
            uniformSpecs.emplace_back(HdxTokens->selColor,
                                      HdTupleType { HdTypeFloatVec4, 1 });
            uniformSpecs.emplace_back(HdxTokens->selLocateColor,
                                      HdTupleType { HdTypeFloatVec4, 1 });
            uniformSpecs.emplace_back(HdxTokens->selMaskColor,
                                      HdTupleType { HdTypeFloatVec4, 1 });
            _selUniformBar = resourceRegistry->AllocateUniformBufferArrayRange(
                                                /*role*/HdxTokens->selection,
                                                uniformSpecs);
        }

        //
        // Uniforms
        //
        HdBufferSourceSharedPtrVector uniformSources;
        uniformSources.push_back(HdBufferSourceSharedPtr(
                new HdVtBufferSource(HdxTokens->selColor,
                                     VtValue(_params.selectionColor))));
        uniformSources.push_back(HdBufferSourceSharedPtr(
                new HdVtBufferSource(HdxTokens->selLocateColor,
                                     VtValue(_params.locateColor))));
        uniformSources.push_back(HdBufferSourceSharedPtr(
                new HdVtBufferSource(HdxTokens->selMaskColor,
                                     VtValue(_params.maskColor))));
        resourceRegistry->AddSources(_selUniformBar, uniformSources);

        //
        // Offsets
        //
        HdBufferSourceSharedPtr offsetSource(
                new HdVtBufferSource(HdxTokens->hdxSelectionBuffer,
                                     VtValue(offsets)));
        resourceRegistry->AddSource(_selOffsetBar, offsetSource);
    }

    if (_params.enableSelection && _hasSelection) {
        (*ctx)[HdxTokens->selectionOffsets] = _selOffsetBar;
        (*ctx)[HdxTokens->selectionUniforms] = _selUniformBar;
    } else {
        (*ctx)[HdxTokens->selectionOffsets] = VtValue();
        (*ctx)[HdxTokens->selectionUniforms] = VtValue();
    }
}
Example #14
0
HdBufferSourceSharedPtr
HdSt_MeshTopology::GetQuadIndexBuilderComputation(SdfPath const &id)
{
    return HdBufferSourceSharedPtr(
        new HdSt_QuadIndexBuilderComputation(this, _quadInfoBuilder.lock(), id));
}
Example #15
0
HdBufferSourceSharedPtr
_TriangulateFaceVarying(HdBufferSourceSharedPtr const &source,
                        VtIntArray const &faceVertexCounts,
                        VtIntArray const &holeFaces,
                        bool flip,
                        SdfPath const &id)
{
    T const *srcPtr = reinterpret_cast<T const *>(source->GetData());
    int numElements = source->GetNumElements();

    // CPU face-varying triangulation
    bool invalidTopology = false;
    int numFVarValues = 0;
    int holeIndex = 0;
    int numHoleFaces = holeFaces.size();
    for (int i = 0; i < faceVertexCounts.size(); ++i) {
        int nv = faceVertexCounts[i] - 2;
        if (nv < 1) {
            // skip degenerated face
            invalidTopology = true;
        } else if (holeIndex < numHoleFaces and holeFaces[holeIndex] == i) {
            // skip hole face
            ++holeIndex;
        } else {
            numFVarValues += 3 * nv;
        }
    }
    if (invalidTopology) {
        TF_WARN("degenerated face found [%s]", id.GetText());
        invalidTopology = false;
    }

    VtArray<T> results(numFVarValues);
    // reset holeIndex
    holeIndex = 0;

    int dstIndex = 0;
    for (int i = 0, v = 0; i < faceVertexCounts.size(); ++i) {
        int nVerts = faceVertexCounts[i];

        if (nVerts < 3) {
            // Skip degenerate faces.
        } else if (holeIndex < numHoleFaces and holeFaces[holeIndex] == i) {
            // Skip hole faces.
            ++holeIndex;
        } else {
            // triangulate.
            // apply same triangulation as index does
            for (int j=0; j < nVerts-2; ++j) {
                if (not _FanTriangulate(&results[dstIndex],
                                        srcPtr, v, j, numElements, flip)) {
                    invalidTopology = true;
                }
                dstIndex += 3;
            }
        }
        v += nVerts;
    }
    if (invalidTopology) {
        TF_WARN("numVerts and verts are incosistent [%s]", id.GetText());
    }

    return HdBufferSourceSharedPtr(new HdVtBufferSource(
                                       source->GetName(), VtValue(results)));
}
Example #16
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;
}
void
HdStExtComputation::Sync(HdSceneDelegate *sceneDelegate,
                         HdRenderParam   *renderParam,
                         HdDirtyBits     *dirtyBits)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();
    TF_DEBUG(HD_EXT_COMPUTATION_UPDATED).Msg(
        "HdStExtComputation::Sync %s\n", GetId().GetText());

    HdExtComputation::_Sync(sceneDelegate, renderParam, dirtyBits);

    // We only commit GPU resources when directly executing a GPU computation
    // or when aggregating inputs for a downstream computation.
    if (GetGpuKernelSource().empty() && !IsInputAggregation()) {
        return;
    }

    HdRenderIndex &renderIndex = sceneDelegate->GetRenderIndex();
    HdStResourceRegistrySharedPtr const & resourceRegistry =
        boost::dynamic_pointer_cast<HdStResourceRegistry>(
                              renderIndex.GetResourceRegistry());

    HdBufferSourceVector inputs;
    for (TfToken const & inputName: GetSceneInputNames()) {
        VtValue inputValue = sceneDelegate->GetExtComputationInput(
                                                GetId(), inputName);
        size_t arraySize =
            inputValue.IsArrayValued() ? inputValue.GetArraySize() : 1;
        HdBufferSourceSharedPtr inputSource = HdBufferSourceSharedPtr(
                    new HdVtBufferSource(inputName, inputValue, arraySize));
        if (inputSource->IsValid()) {
            inputs.push_back(inputSource);
        } else {
            TF_WARN("Unsupported type %s for source %s in extComputation %s.",
                    inputValue.GetType().GetTypeName().c_str(),
                    inputName.GetText(), GetId().GetText());
        }
    }

    _inputRange.reset();
    if (!inputs.empty()) {
        if (_IsEnabledSharedExtComputationData() && IsInputAggregation()) {
            uint64_t inputId = _ComputeSharedComputationInputId(0, inputs);

            HdInstance<uint64_t, HdBufferArrayRangeSharedPtr> barInstance;
            std::unique_lock<std::mutex> regLog =
                resourceRegistry->RegisterExtComputationDataRange(inputId,
                                                                  &barInstance);

            if (barInstance.IsFirstInstance()) {
                // Allocate the first buffer range for this input key
                _inputRange = _AllocateComputationDataRange(inputs,
                                                            resourceRegistry);
                barInstance.SetValue(_inputRange);

                TF_DEBUG(HD_SHARED_EXT_COMPUTATION_DATA).Msg(
                    "Allocated shared ExtComputation buffer range: %s: %p\n",
                    GetId().GetText(), (void *)_inputRange.get());
            } else {
                // Share the existing buffer range for this input key
                _inputRange = barInstance.GetValue();

                TF_DEBUG(HD_SHARED_EXT_COMPUTATION_DATA).Msg(
                    "Reused shared ExtComputation buffer range: %s: %p\n",
                    GetId().GetText(), (void *)_inputRange.get());
            }

        } else {
            // We're not sharing, so go ahead and allocate new buffer range.
            _inputRange = _AllocateComputationDataRange(inputs,
                                                        resourceRegistry);
        }

        // Make sure that we also release any stale input range data
        renderIndex.GetChangeTracker().SetGarbageCollectionNeeded();
    }
}