summaryrefslogtreecommitdiff
path: root/thirdparty/thekla_atlas/nvmesh/param/AtlasBuilder.h
blob: f25c724f7e00e3fe4200800b989b061c76740ab0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// This code is in the public domain -- castano@gmail.com

#pragma once
#ifndef NV_MESH_ATLASBUILDER_H
#define NV_MESH_ATLASBUILDER_H

#include "Atlas.h"

#include "nvmath/Vector.h"
#include "nvmath/Random.h"
#include "nvmesh/nvmesh.h"

#include "nvcore/Array.h"
#include "nvcore/BitArray.h"



namespace nv
{
    namespace HalfEdge { class Mesh; }

    struct ChartBuildData;

    struct AtlasBuilder
    {
        AtlasBuilder(const HalfEdge::Mesh * m);
        ~AtlasBuilder();

        void markUnchartedFaces(const Array<uint> & unchartedFaces);

        void computeShortestPaths();

        void placeSeeds(float threshold, uint maxSeedCount);
        void createRandomChart(float threshold);

        void addFaceToChart(ChartBuildData * chart, uint f, bool recomputeProxy=false);

        bool growCharts(float threshold, uint faceCount);
        bool growChart(ChartBuildData * chart, float threshold, uint faceCount);

        void resetCharts();

        void updateCandidates(ChartBuildData * chart, uint face);

        void updateProxies();
        void updateProxy(ChartBuildData * chart);

        bool relocateSeeds();
        bool relocateSeed(ChartBuildData * chart);

        void updatePriorities(ChartBuildData * chart);

        float evaluatePriority(ChartBuildData * chart, uint face);
        float evaluateProxyFitMetric(ChartBuildData * chart, uint face);
        float evaluateDistanceToBoundary(ChartBuildData * chart, uint face);
        float evaluateDistanceToSeed(ChartBuildData * chart, uint face);
        float evaluateRoundnessMetric(ChartBuildData * chart, uint face, float newBoundaryLength, float newChartArea);
        float evaluateStraightnessMetric(ChartBuildData * chart, uint face);

        float evaluateNormalSeamMetric(ChartBuildData * chart, uint f);
        float evaluateTextureSeamMetric(ChartBuildData * chart, uint f);
        float evaluateSeamMetric(ChartBuildData * chart, uint f);

        float evaluateChartArea(ChartBuildData * chart, uint f);
        float evaluateBoundaryLength(ChartBuildData * chart, uint f);
        Vector3 evaluateChartNormalSum(ChartBuildData * chart, uint f);
        Vector3 evaluateChartCentroidSum(ChartBuildData * chart, uint f);

        Vector3 computeChartCentroid(const ChartBuildData * chart);


        void fillHoles(float threshold);
        void mergeCharts();

        // @@ Cleanup.
        struct Candidate {
            uint face;
            ChartBuildData * chart;
            float metric;
        };

        const Candidate & getBestCandidate() const;
        void removeCandidate(uint f);
        void updateCandidate(ChartBuildData * chart, uint f, float metric);

        void mergeChart(ChartBuildData * owner, ChartBuildData * chart, float sharedBoundaryLength);


        uint chartCount() const { return chartArray.count(); }
        const Array<uint> & chartFaces(uint i) const;

        const HalfEdge::Mesh * mesh;
        uint facesLeft;
        Array<int> faceChartArray;
        Array<ChartBuildData *> chartArray;
        Array<float> shortestPaths;

        Array<float> edgeLengths;
        Array<float> faceAreas;

        Array<Candidate> candidateArray; //
        Array<uint> faceCandidateArray; // Map face index to candidate index.

        MTRand rand;

        SegmentationSettings settings;
    };

} // nv namespace

#endif // NV_MESH_ATLASBUILDER_H