diff options
author | Sebastian Parborg <darkdefende@gmail.com> | 2019-08-26 19:34:11 +0300 |
---|---|---|
committer | Sebastian Parborg <darkdefende@gmail.com> | 2019-09-13 11:36:05 +0300 |
commit | 57e55906f04a48a951fbbcfd7c197eef35ad4387 (patch) | |
tree | a4246ffdd501027a37d7329dca05de4d9ed19b15 /extern/quadriflow/src/parametrizer.hpp | |
parent | 1c44d08a69eb3e66c7f942d748f549d6b8ca138f (diff) |
Add QuadriFlow remesher
Diffstat (limited to 'extern/quadriflow/src/parametrizer.hpp')
-rw-r--r-- | extern/quadriflow/src/parametrizer.hpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/extern/quadriflow/src/parametrizer.hpp b/extern/quadriflow/src/parametrizer.hpp new file mode 100644 index 00000000000..1f4a02be6c2 --- /dev/null +++ b/extern/quadriflow/src/parametrizer.hpp @@ -0,0 +1,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 |