Files
workinf_Blender_Wasm/blender-5.2.0/extern/quadriflow/src/parametrizer.hpp
2026-08-12 04:47:48 -04:00

179 lines
5.4 KiB
C++

#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
// Return false when the solver fails.
bool 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