Welcome to mirror list, hosted at ThFree Co, Russian Federation.

parametrizer.hpp « src « quadriflow « extern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1f4a02be6c26e5547644072ce2e092a5548a8229 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#ifndef PARAMETRIZER_H_
#define PARAMETRIZER_H_
#include <atomic>
#include <condition_variable>
#ifdef WITH_TBB
#include <tbb/tbb.h>
#endif

#include <Eigen/Core>
#include <Eigen/Dense>
#include <list>
#include <map>
#include <set>
#include <unordered_set>
#include "adjacent-matrix.hpp"
#include "disajoint-tree.hpp"
#include "field-math.hpp"
#include "hierarchy.hpp"
#include "post-solver.hpp"
#include "serialize.hpp"

namespace qflow {

using namespace Eigen;

typedef std::pair<unsigned int, unsigned int> Edge;
typedef std::map<int, std::pair<int, int>> SingDictionary;

struct ExpandInfo {
    ExpandInfo() {}
    int current_v;
    int singularity;
    int step;
    int edge_id;
    int prev;
};

class Parametrizer {
   public:
    Parametrizer() {}
    // Mesh Initialization
    void Load(const char* filename);
    void NormalizeMesh();
    void ComputeMeshStatus();
    void ComputeSmoothNormal();
    void ComputeSharpEdges();
    void ComputeSharpO();
    void ComputeVertexArea();
    void Initialize(int faces);

    // Singularity and Mesh property
    void AnalyzeValence();
    void ComputeOrientationSingularities();
    void ComputePositionSingularities();

    // Integer Grid Map Pipeline
    void ComputeIndexMap(int with_scale = 0);
    void BuildEdgeInfo();
    void ComputeMaxFlow();
    void MarkInteger();
    void BuildIntegerConstraints();

    // Fix Flip
    void FixFlipHierarchy();
    void FixFlipSat();
    void FixHoles();
    void FixHoles(std::vector<int>& loop_vertices);
    void FixValence();
    double QuadEnergy(std::vector<int>& loop_vertices, std::vector<Vector4i>& res_quads,
                      int level);

    // Quadmesh and IO
    void AdvancedExtractQuad();
    void BuildTriangleManifold(DisajointTree& disajoint_tree, std::vector<int>& edge,
                               std::vector<int>& face, std::vector<DEdge>& edge_values,
                               std::vector<Vector3i>& F2E, std::vector<Vector2i>& E2F,
                               std::vector<Vector2i>& EdgeDiff, std::vector<Vector3i>& FQ);
    void OutputMesh(const char* obj_name);

    std::map<int, int> singularities;  // map faceid to valence (1 (valence=3) or 3(valence=5))
    std::map<int, Vector2i> pos_sing;
    MatrixXi pos_rank;   // pos_rank(i, j) i \in [0, 3) jth face ith vertex  rotate by its value so
                         // that all thress vertices are in the same orientation
    MatrixXi pos_index;  // pos_index(i x 2 + dim, j) i \in [0, 6) jth face ith vertex's
                         // (t_ij-t_ji)'s dim's dimenstion in the paper
    // input mesh
    MatrixXd V;
    MatrixXd N;
    MatrixXd Nf;
    MatrixXd FS;
    MatrixXd FQ;
    MatrixXi F;

    double normalize_scale;
    Vector3d normalize_offset;

    // data structures
    VectorXd rho;
    VectorXi V2E;
    VectorXi E2E;
    VectorXi boundary;
    VectorXi nonManifold;  // nonManifold vertices, in boolean
    AdjacentMatrix adj;
    Hierarchy hierarchy;

    // Mesh Status;
    double surface_area;
    double scale;
    double average_edge_length;
    double max_edge_length;
    VectorXd A;

    // just for test
    DisajointTree disajoint_tree;

    int compact_num_v;
    std::vector<std::vector<int>> Vset;
    std::vector<Vector3d> O_compact;
    std::vector<Vector3d> Q_compact;
    std::vector<Vector3d> N_compact;
    std::vector<Vector4i> F_compact;
    std::set<std::pair<int, int>> Quad_edges;
    std::vector<int> V2E_compact;
    std::vector<int> E2E_compact;
    VectorXi boundary_compact;
    VectorXi nonManifold_compact;

    std::vector<int> bad_vertices;
    std::vector<double> counter;
    std::vector<int>
        sharp_edges;  // sharp_edges[deid]: whether deid is a sharp edge that should be preserved
    std::vector<int> allow_changes;   // allow_changes[variable_id]: whether var can be changed
                                      // based on sharp edges
    std::vector<Vector2i> edge_diff;  // edge_diff[edgeIds[i](j)]:  t_ij+t_ji under
                                      // edge_values[edgeIds[i](j)].x's Q value
    std::vector<DEdge> edge_values;   // see above
    std::vector<Vector3i>
        face_edgeIds;  // face_edgeIds[i](j): ith face jth edge's "undirected edge ID"

    // face_edgeOrients[i](j): Rotate from edge_diff space
    //    (a) initially, to F(0, i)'s Q space
    //    (b) later on, to a global Q space where some edges are fixed
    std::vector<Vector3i> face_edgeOrients;

    // variable[i].first: indices of the two equations corresponding to variable i
    // variable[i].second: number of positive minus negative of variables' occurances
    std::vector<std::pair<Vector2i, int>> variables;

    struct QuadInfo {
        QuadInfo() : patchId(-1), coordinate(0x10000000, 0x10000000), singular(0), edge(0) {}
        int patchId;
        Vector2i coordinate;
        int singular;
        int edge;
    };
    std::vector<QuadInfo> quad_info;

    // scale
    void ComputeInverseAffine();
    void EstimateSlope();
    std::vector<MatrixXd> triangle_space;

    // flag
    int flag_preserve_sharp = 0;
    int flag_preserve_boundary = 0;
    int flag_adaptive_scale = 0;
    int flag_aggresive_sat = 0;
    int flag_minimum_cost_flow = 0;
};

extern void generate_adjacency_matrix_uniform(const MatrixXi& F, const VectorXi& V2E,
                                              const VectorXi& E2E, const VectorXi& nonManifold,
                                              AdjacentMatrix& adj);

} // namespace qflow

#endif