godot/thirdparty/thekla_atlas/nvmesh/param/Atlas.h

184 lines
5.4 KiB
C++

// Copyright NVIDIA Corporation 2006 -- Ignacio Castano <icastano@nvidia.com>
#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<uint> & 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<MeshCharts *> 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<uint> & unchartedMaterialArray);
// Extract the charts of the input mesh.
void extractCharts();
// Compute charts using a simple segmentation algorithm.
void computeCharts(const SegmentationSettings & settings, const Array<uint> & 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<Chart *> m_chartArray;
Array<uint> m_chartVertexCountPrefixSum;
uint m_totalVertexCount;
Array<uint> m_faceChart; // the chart of every face of the input mesh.
Array<uint> 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<uint> & faceArray);
void buildVertexMap(const HalfEdge::Mesh * originalMesh, const Array<uint> & 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<uint> & 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<HalfEdge::Edge *> & loop);
// Chart mesh.
AutoPtr<HalfEdge::Mesh> m_chartMesh;
AutoPtr<HalfEdge::Mesh> m_unifiedMesh;
bool m_isDisk;
bool m_isVertexMapped;
// List of faces of the original mesh that belong to this chart.
Array<uint> m_faceArray;
// Map vertices of the chart mesh to vertices of the original mesh.
Array<uint> m_chartToOriginalMap;
Array<uint> m_chartToUnifiedMap;
};
} // nv namespace
#endif // NV_MESH_ATLAS_H