Optimize remesh
Introduce isotropic remesh before QuadriFlow This will unify the edge length of all the faces before the mesh got subdived in QuadriFlowmaster
parent
3ebc2cca6b
commit
7f517386f0
|
@ -6,7 +6,31 @@
|
||||||
#ifdef WITH_CUDA
|
#ifdef WITH_CUDA
|
||||||
#include <cuda_runtime.h>
|
#include <cuda_runtime.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/remesh.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/border.h>
|
||||||
|
#include <boost/function_output_iterator.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
#include "remesher.h"
|
#include "remesher.h"
|
||||||
|
#include "booleanmesh.h"
|
||||||
|
|
||||||
|
typedef boost::graph_traits<CgalMesh>::halfedge_descriptor halfedge_descriptor;
|
||||||
|
typedef boost::graph_traits<CgalMesh>::edge_descriptor edge_descriptor;
|
||||||
|
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||||
|
|
||||||
|
struct halfedge2edge
|
||||||
|
{
|
||||||
|
halfedge2edge(const CgalMesh& m, std::vector<edge_descriptor>& edges)
|
||||||
|
: m_mesh(m), m_edges(edges)
|
||||||
|
{}
|
||||||
|
void operator()(const halfedge_descriptor& h) const
|
||||||
|
{
|
||||||
|
m_edges.push_back(edge(h, m_mesh));
|
||||||
|
}
|
||||||
|
const CgalMesh& m_mesh;
|
||||||
|
std::vector<edge_descriptor>& m_edges;
|
||||||
|
};
|
||||||
|
|
||||||
using namespace qflow;
|
using namespace qflow;
|
||||||
|
|
||||||
|
@ -36,6 +60,31 @@ const std::vector<std::pair<QUuid, QUuid>> &Remesher::getRemeshedVertexSources()
|
||||||
return m_remeshedVertexSources;
|
return m_remeshedVertexSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Remesher::isotropicRemesh(float targetEdgeLength, unsigned int iterationNum)
|
||||||
|
{
|
||||||
|
CgalMesh *mesh = buildCgalMesh<CgalKernel>(m_vertices, m_triangles);
|
||||||
|
if (nullptr == mesh)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<edge_descriptor> border;
|
||||||
|
PMP::border_halfedges(faces(*mesh),
|
||||||
|
*mesh,
|
||||||
|
boost::make_function_output_iterator(halfedge2edge(*mesh, border)));
|
||||||
|
PMP::split_long_edges(border, targetEdgeLength, *mesh);
|
||||||
|
|
||||||
|
PMP::isotropic_remeshing(faces(*mesh),
|
||||||
|
targetEdgeLength,
|
||||||
|
*mesh,
|
||||||
|
PMP::parameters::number_of_iterations(iterationNum)
|
||||||
|
.protect_constraints(true));
|
||||||
|
|
||||||
|
m_vertices.clear();
|
||||||
|
m_triangles.clear();
|
||||||
|
fetchFromCgalMesh<CgalKernel>(mesh, m_vertices, m_triangles);
|
||||||
|
|
||||||
|
delete mesh;
|
||||||
|
}
|
||||||
|
|
||||||
void Remesher::remesh()
|
void Remesher::remesh()
|
||||||
{
|
{
|
||||||
Parametrizer field;
|
Parametrizer field;
|
||||||
|
@ -44,6 +93,8 @@ void Remesher::remesh()
|
||||||
cudaFree(0);
|
cudaFree(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
isotropicRemesh();
|
||||||
|
|
||||||
field.V.resize(3, m_vertices.size());
|
field.V.resize(3, m_vertices.size());
|
||||||
field.F.resize(3, m_triangles.size());
|
field.F.resize(3, m_triangles.size());
|
||||||
for (decltype(m_vertices.size()) i = 0; i < m_vertices.size(); i++) {
|
for (decltype(m_vertices.size()) i = 0; i < m_vertices.size(); i++) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ private:
|
||||||
std::vector<std::pair<QVector3D, float>> m_nodes;
|
std::vector<std::pair<QVector3D, float>> m_nodes;
|
||||||
std::vector<std::pair<QUuid, QUuid>> m_sourceIds;
|
std::vector<std::pair<QUuid, QUuid>> m_sourceIds;
|
||||||
void resolveSources();
|
void resolveSources();
|
||||||
|
void isotropicRemesh(float targetEdgeLength=0.021, unsigned int iterationNum=3);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue