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; }
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; }
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; }
bool Hd_SceneExtCompInputSource::Resolve() { if (!_TryLock()) return false; _SetResolved(); return true; }
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; }
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; }
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; }
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; }
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; }
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; }
virtual bool Resolve() { if (not _TryLock()) return false; _SetResolved(); return true; }