// Copyright NVIDIA Corporation 2006 -- Ignacio Castano #pragma once #ifndef NV_MESH_ATLAS_H #define NV_MESH_ATLAS_H #include "nvcore/Array.h" #include "nvcore/Ptr.h" #include "nvmath/Vector.h" #include "nvmesh/nvmesh.h" #include "nvmesh/halfedge/Mesh.h" namespace nv { namespace HalfEdge { class Mesh; } class Chart; class MeshCharts; class VertexMap; struct SegmentationSettings { SegmentationSettings(); float maxChartArea; float maxBoundaryLength; float proxyFitMetricWeight; float roundnessMetricWeight; float straightnessMetricWeight; float normalSeamMetricWeight; float textureSeamMetricWeight; }; /// An atlas is a set of charts. class Atlas { public: Atlas(); ~Atlas(); uint meshCount() const { return m_meshChartsArray.count(); } const MeshCharts * meshAt(uint i) const { return m_meshChartsArray[i]; } MeshCharts * meshAt(uint i) { return m_meshChartsArray[i]; } uint chartCount() const; const Chart * chartAt(uint i) const; Chart * chartAt(uint i); // Add mesh charts and takes ownership. void addMeshCharts(MeshCharts * meshCharts); void extractCharts(const HalfEdge::Mesh * mesh); void computeCharts(const HalfEdge::Mesh * mesh, const SegmentationSettings & settings, const Array & unchartedMaterialArray); // Compute a trivial seamless texture similar to ZBrush. //bool computeSeamlessTextureAtlas(bool groupFaces = true, bool scaleTiles = false, uint w = 1024, uint h = 1024); void parameterizeCharts(); // Pack charts in the smallest possible rectangle. float packCharts(int quality, float texelArea, bool blockAlign, bool conservative); private: Array m_meshChartsArray; }; // Set of charts corresponding to a single mesh. class MeshCharts { public: MeshCharts(const HalfEdge::Mesh * mesh); ~MeshCharts(); uint chartCount() const { return m_chartArray.count(); } uint vertexCount () const { return m_totalVertexCount; } const Chart * chartAt(uint i) const { return m_chartArray[i]; } Chart * chartAt(uint i) { return m_chartArray[i]; } void computeVertexMap(const Array & unchartedMaterialArray); // Extract the charts of the input mesh. void extractCharts(); // Compute charts using a simple segmentation algorithm. void computeCharts(const SegmentationSettings & settings, const Array & unchartedMaterialArray); void parameterizeCharts(); uint faceChartAt(uint i) const { return m_faceChart[i]; } uint faceIndexWithinChartAt(uint i) const { return m_faceIndex[i]; } uint vertexCountBeforeChartAt(uint i) const { return m_chartVertexCountPrefixSum[i]; } private: const HalfEdge::Mesh * m_mesh; Array m_chartArray; Array m_chartVertexCountPrefixSum; uint m_totalVertexCount; Array m_faceChart; // the chart of every face of the input mesh. Array m_faceIndex; // the index within the chart for every face of the input mesh. }; /// A chart is a connected set of faces with a certain topology (usually a disk). class Chart { public: Chart(); void build(const HalfEdge::Mesh * originalMesh, const Array & faceArray); void buildVertexMap(const HalfEdge::Mesh * originalMesh, const Array & unchartedMaterialArray); bool closeHoles(); bool isDisk() const { return m_isDisk; } bool isVertexMapped() const { return m_isVertexMapped; } uint vertexCount() const { return m_chartMesh->vertexCount(); } uint colocalVertexCount() const { return m_unifiedMesh->vertexCount(); } uint faceCount() const { return m_faceArray.count(); } uint faceAt(uint i) const { return m_faceArray[i]; } const HalfEdge::Mesh * chartMesh() const { return m_chartMesh.ptr(); } HalfEdge::Mesh * chartMesh() { return m_chartMesh.ptr(); } const HalfEdge::Mesh * unifiedMesh() const { return m_unifiedMesh.ptr(); } HalfEdge::Mesh * unifiedMesh() { return m_unifiedMesh.ptr(); } //uint vertexIndex(uint i) const { return m_vertexIndexArray[i]; } uint mapChartVertexToOriginalVertex(uint i) const { return m_chartToOriginalMap[i]; } uint mapChartVertexToUnifiedVertex(uint i) const { return m_chartToUnifiedMap[i]; } const Array & faceArray() const { return m_faceArray; } void transferParameterization(); float computeSurfaceArea() const; float computeParametricArea() const; Vector2 computeParametricBounds() const; float scale = 1.0f; uint vertexMapWidth; uint vertexMapHeight; private: bool closeLoop(uint start, const Array & loop); // Chart mesh. AutoPtr m_chartMesh; AutoPtr m_unifiedMesh; bool m_isDisk; bool m_isVertexMapped; // List of faces of the original mesh that belong to this chart. Array m_faceArray; // Map vertices of the chart mesh to vertices of the original mesh. Array m_chartToOriginalMap; Array m_chartToUnifiedMap; }; } // nv namespace #endif // NV_MESH_ATLAS_H