// // Copyright 2016 Pixar // // Licensed under the Apache License, Version 2.0 (the "Apache License") // with the following modification; you may not use this file except in // compliance with the Apache License and the following modification to it: // Section 6. Trademarks. is deleted and replaced with: // // 6. Trademarks. This License does not grant permission to use the trade // names, trademarks, service marks, or product names of the Licensor // and its affiliates, except as required to comply with Section 4(c) of // the License and to reproduce the content of the NOTICE file. // // You may obtain a copy of the Apache License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the Apache License with the above modification is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the Apache License for the specific // language governing permissions and limitations under the Apache License. // #ifndef PXR_IMAGING_HD_VERTEX_ADJACENCY_H #define PXR_IMAGING_HD_VERTEX_ADJACENCY_H #include "pxr/pxr.h" #include "pxr/imaging/hd/api.h" #include "pxr/imaging/hd/version.h" #include "pxr/imaging/hd/bufferArrayRange.h" #include "pxr/imaging/hd/bufferSource.h" #include "pxr/imaging/hd/computation.h" #include "pxr/base/vt/array.h" #include PXR_NAMESPACE_OPEN_SCOPE using Hd_VertexAdjacencySharedPtr = std::shared_ptr; using Hd_AdjacencyBuilderComputationSharedPtr = std::shared_ptr; using Hd_AdjacencyBuilderComputationPtr = std::weak_ptr; class HdMeshTopology; /// \class Hd_VertexAdjacency /// /// Hd_VertexAdjacency encapsulates mesh adjacency information, /// which is used for smooth normal computation. /// /// The Adjacency table (built by the AdjacencyBuilder computation) /// provides the index of the previous and next vertex for each face /// that uses that vertex. /// /// The table is split into two parts. The first part of the table /// provides a offset to the prev/next data for the vertex as well as the /// number of faces that use the vertex. The second part of the table /// provides the actual prev/next indices. /// /// For example, The following prim has 4 vertices and 2 faces and uses /// a CCW winding order: /// /// 3.---.2 /// | /| /// | / | /// |/ | /// 0.---.1 /// /// Picking one vertex, 0, it is used by 2 faces, so it contains 2 previous/ /// next pairs: (2, 1) and (3, 2) /// /// The full adjacency table for this prim would be: /// /// 0 1 | 2 3 | 4 5 | 6 7 || 8 9 10 11 | 12 13 | 14 15 16 17 | 18 19 /// 8 2 | 12 1 | 14 2 | 18 1 || 2 1 3 2 | 0 2 | 1 0 0 3 | 2 0 /// Offset / Count pairs || Prev / Next Pairs /// per vertex || Per Vertex, Per Face. /// class Hd_VertexAdjacency final { public: HD_API Hd_VertexAdjacency(); HD_API ~Hd_VertexAdjacency(); /// Updates the internal adjacency table using the supplied topology. /// Important! The adjacency table needs to be computed before smooth /// normals. HD_API bool BuildAdjacencyTable(HdMeshTopology const *topology); /// Returns a shared adjacency builder computation which will call /// BuildAdjacencyTable. The shared computation is useful if multiple /// meshes share a topology and adjacency table, and only want to build the /// adjacency table once. HD_API HdBufferSourceSharedPtr GetSharedAdjacencyBuilderComputation( HdMeshTopology const *topology); /// Sets the buffer range used for adjacency table storage. void SetAdjacencyRange(HdBufferArrayRangeSharedPtr const &range) { _adjacencyRange = range; } /// Returns the buffer range used for adjacency table storage. HdBufferArrayRangeSharedPtr const &GetAdjacencyRange() const { return _adjacencyRange; } /// Returns the number of points in the adjacency table. int GetNumPoints() const { return _numPoints; } /// Returns the adjacency table. VtIntArray const &GetAdjacencyTable() const { return _adjacencyTable; } private: int _numPoints; VtIntArray _adjacencyTable; // adjacency buffer range HdBufferArrayRangeSharedPtr _adjacencyRange; // weak ptr of adjacency builder used for dependent computations Hd_AdjacencyBuilderComputationPtr _sharedAdjacencyBuilder; }; /// \class Hd_AdjacencyBuilderComputation /// /// A null buffer source to compute the adjacency table. /// Since this is a null buffer source, it won't actually produce buffer /// output; but other computations can depend on this to ensure /// BuildAdjacencyTable is called. /// class Hd_AdjacencyBuilderComputation : public HdNullBufferSource { public: HD_API Hd_AdjacencyBuilderComputation(Hd_VertexAdjacency *adjacency, HdMeshTopology const *topology); HD_API virtual bool Resolve() override; protected: HD_API virtual bool _CheckValid() const override; private: Hd_VertexAdjacency *_adjacency; HdMeshTopology const *_topology; }; /// \class Hd_AdjacencyBufferSource /// /// A buffer source that puts an already computed adjacency table into /// a resource registry buffer. This computation should be dependent on an /// Hd_AdjacencyBuilderComputation. /// class Hd_AdjacencyBufferSource : public HdComputedBufferSource { public: HD_API Hd_AdjacencyBufferSource( Hd_VertexAdjacency const *adjacency, HdBufferSourceSharedPtr const &adjacencyBuilder); // overrides HD_API virtual void GetBufferSpecs(HdBufferSpecVector *specs) const override; HD_API virtual bool Resolve() override; protected: HD_API virtual bool _CheckValid() const override; private: Hd_VertexAdjacency const *_adjacency; HdBufferSourceSharedPtr const _adjacencyBuilder; }; PXR_NAMESPACE_CLOSE_SCOPE #endif // PXR_IMAGING_HD_VERTEX_ADJACENCY_H