mirror of https://github.com/CGAL/cgal
Merge pull request #2514 from janetournois/Polyhedron_demo-fix_isotropic_remeshing_plugin-jtournois
Polyhedron demo - fix isotropic remeshing plugin
This commit is contained in:
commit
7caa6ea021
|
|
@ -189,6 +189,9 @@ namespace internal {
|
|||
patch_ids_map = CGAL::internal::add_property(Face_property_tag("PMP_patch_id"), pmesh);
|
||||
if (do_init)
|
||||
{
|
||||
#ifdef CGAL_PMP_REMESHING_VERBOSE
|
||||
std::cout << "Compute connected components property map." << std::endl;
|
||||
#endif
|
||||
nb_cc
|
||||
= PMP::connected_components(pmesh,
|
||||
patch_ids_map,
|
||||
|
|
@ -616,6 +619,10 @@ namespace internal {
|
|||
#ifdef CGAL_PMP_REMESHING_VERBOSE
|
||||
std::cout << "Collapse short edges (" << low << ", " << high << ")..."
|
||||
<< std::endl;
|
||||
#endif
|
||||
#ifdef CGAL_PMP_REMESHING_VERBOSE_PROGRESS
|
||||
std::cout << "Fill bimap...";
|
||||
std::cout.flush();
|
||||
#endif
|
||||
double sq_low = low*low;
|
||||
double sq_high = high*high;
|
||||
|
|
@ -627,6 +634,9 @@ namespace internal {
|
|||
if( (sqlen < sq_low) && is_collapse_allowed(e) )
|
||||
short_edges.insert(short_edge(halfedge(e, mesh_), sqlen));
|
||||
}
|
||||
#ifdef CGAL_PMP_REMESHING_VERBOSE_PROGRESS
|
||||
std::cout << "done." << std::endl;
|
||||
#endif
|
||||
|
||||
unsigned int nb_collapses = 0;
|
||||
while (!short_edges.empty())
|
||||
|
|
@ -686,6 +696,8 @@ namespace internal {
|
|||
|
||||
if (is_on_patch_border(va) && !is_on_patch_border(vb))
|
||||
continue;//we cannot swap again. It would lead to a face inversion
|
||||
else if (is_corner(va) && !is_corner(vb))
|
||||
continue;//idem
|
||||
}
|
||||
else
|
||||
continue;//both directions invert a face
|
||||
|
|
@ -1355,34 +1367,10 @@ private:
|
|||
//collect normals to faces around vs AND vt
|
||||
//vertices are at the same location, but connectivity is still be same,
|
||||
//with plenty of degenerate triangles (which are common to both stars)
|
||||
std::vector<Vector_3> normals_patch1;
|
||||
std::vector<Vector_3> normals_patch2;
|
||||
normals_patch1.reserve(8);
|
||||
normals_patch2.reserve(8);
|
||||
Patch_id patch1 = -1, patch2 = -1;
|
||||
BOOST_FOREACH(halfedge_descriptor hd,
|
||||
boost::range::join(halfedges_around_target(h, mesh_),
|
||||
halfedges_around_target(opposite(h, mesh_), mesh_)))
|
||||
{
|
||||
Vector_3 n = compute_normal(face(hd, mesh_));
|
||||
if (n == CGAL::NULL_VECTOR) //for degenerate faces
|
||||
continue;
|
||||
Patch_id pid = get_patch_id(face(hd, mesh_));
|
||||
|
||||
if (patch1 == Patch_id(-1))
|
||||
patch1 = pid; //not met yet
|
||||
else if (patch2 == Patch_id(-1) && patch1 != pid)
|
||||
patch2 = pid; //not met yet
|
||||
CGAL_assertion(pid == patch1 || pid == patch2);
|
||||
|
||||
if (pid == patch1) normals_patch1.push_back(n);
|
||||
else normals_patch2.push_back(n);
|
||||
}
|
||||
|
||||
//on each surface patch,
|
||||
//check all normals have same orientation
|
||||
bool res = check_orientation(normals_patch1)
|
||||
&& check_orientation(normals_patch2);
|
||||
bool res = check_normals(
|
||||
boost::range::join(
|
||||
halfedges_around_target(h, mesh_),
|
||||
halfedges_around_target(opposite(h, mesh_), mesh_)));
|
||||
|
||||
//restore position
|
||||
put(vpmap_, vs, ps);
|
||||
|
|
@ -1436,7 +1424,7 @@ private:
|
|||
if (GeomTraits().collinear_3_object()(p,q,r))
|
||||
return CGAL::NULL_VECTOR;
|
||||
else
|
||||
return PMP::compute_face_normal(f, mesh_);
|
||||
return PMP::compute_face_normal(f, mesh_, parameters::vertex_point_map(vpmap_));
|
||||
}
|
||||
|
||||
template <typename FaceRange>
|
||||
|
|
@ -1832,37 +1820,43 @@ private:
|
|||
//have all their 2 by 2 dot products > 0
|
||||
bool check_normals(const vertex_descriptor& v) const
|
||||
{
|
||||
if (is_corner(v))
|
||||
return true;//if we want to deal with this case,
|
||||
//we should use a multimap to store <Patch_id, Normal>
|
||||
return check_normals(halfedges_around_target(halfedge(v, mesh_), mesh_));
|
||||
}
|
||||
|
||||
std::vector<Vector_3> normals_patch1;
|
||||
std::vector<Vector_3> normals_patch2;
|
||||
normals_patch1.reserve(8);
|
||||
normals_patch2.reserve(8);
|
||||
Patch_id patch1 = -1, patch2 = -1;
|
||||
BOOST_FOREACH(halfedge_descriptor hd,
|
||||
halfedges_around_target(halfedge(v, mesh_), mesh_))
|
||||
template <typename HalfedgeRange>
|
||||
bool check_normals(const HalfedgeRange& hedges) const
|
||||
{
|
||||
typedef std::multimap<Patch_id, Vector_3> Normals_multimap;
|
||||
typedef typename Normals_multimap::iterator Normals_iterator;
|
||||
|
||||
Normals_multimap normals_per_patch;
|
||||
BOOST_FOREACH(halfedge_descriptor hd, hedges)
|
||||
{
|
||||
Vector_3 n = compute_normal(face(hd, mesh_));
|
||||
if (n == CGAL::NULL_VECTOR)
|
||||
if (n == CGAL::NULL_VECTOR) //for degenerate faces
|
||||
continue;
|
||||
Patch_id pid = get_patch_id(face(hd, mesh_));
|
||||
|
||||
if (patch1 == Patch_id(-1))
|
||||
patch1 = pid; //not met yet
|
||||
else if (patch2 == Patch_id(-1) && patch1 != pid)
|
||||
patch2 = pid; //not met yet
|
||||
CGAL_assertion(pid == patch1 || pid == patch2);
|
||||
|
||||
if (pid == patch1) normals_patch1.push_back(n);
|
||||
else normals_patch2.push_back(n);
|
||||
normals_per_patch.insert(std::make_pair(pid, n));
|
||||
}
|
||||
|
||||
//on each surface patch,
|
||||
//check all normals have same orientation
|
||||
return check_orientation(normals_patch1)
|
||||
&& check_orientation(normals_patch2);
|
||||
for (Normals_iterator it = normals_per_patch.begin();
|
||||
it != normals_per_patch.end();/*done inside loop*/)
|
||||
{
|
||||
std::vector<Vector_3> normals;
|
||||
std::pair<Normals_iterator, Normals_iterator> n_range
|
||||
= normals_per_patch.equal_range((*it).first);
|
||||
for (Normals_iterator iit = n_range.first; iit != n_range.second; ++iit)
|
||||
normals.push_back((*iit).second);
|
||||
|
||||
if (!check_orientation(normals))
|
||||
return false;
|
||||
|
||||
it = n_range.second;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool check_normals(const halfedge_descriptor& h) const
|
||||
|
|
@ -1917,7 +1911,6 @@ private:
|
|||
Patch_id_to_index_map patch_id_to_index_map;
|
||||
Triangle_list input_triangles_;
|
||||
Patch_id_list input_patch_ids_;
|
||||
Patch_id_to_index_map patch_id_to_index_map_;
|
||||
Halfedge_status_pmap halfedge_status_pmap_;
|
||||
bool protect_constraints_;
|
||||
FacePatchMap patch_ids_map_;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//#define CGAL_PMP_REMESHING_VERBOSE
|
||||
//#define CGAL_PMP_REMESHING_DEBUG
|
||||
//#define CGAL_PMP_REMESHING_VERY_VERBOSE
|
||||
//#define CGAL_PMP_REMESHING_VERBOSE_PROGRESS
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
|
|
@ -8,11 +9,15 @@
|
|||
|
||||
#ifdef USE_SURFACE_MESH
|
||||
#include "Scene_surface_mesh_item.h"
|
||||
#include <CGAL/Mesh_3/properties_Surface_mesh.h>
|
||||
#else
|
||||
#include "Scene_polyhedron_item.h"
|
||||
#include "Polyhedron_type.h"
|
||||
#include <CGAL/Mesh_3/properties_Polyhedron_3.h>
|
||||
#endif
|
||||
|
||||
#include <CGAL/Mesh_3/properties.h>
|
||||
|
||||
#include "Scene_polyhedron_selection_item.h"
|
||||
|
||||
#include <CGAL/iterator.h>
|
||||
|
|
@ -341,11 +346,25 @@ public Q_SLOTS:
|
|||
typedef boost::graph_traits<FaceGraph>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||
|
||||
const FaceGraph& pmesh = (poly_item != NULL)
|
||||
FaceGraph& pmesh = (poly_item != NULL)
|
||||
? *poly_item->polyhedron()
|
||||
: *selection_item->polyhedron();
|
||||
|
||||
reset_face_ids(pmesh);
|
||||
|
||||
Patch_id_pmap fpmap = get(CGAL::face_patch_id_t<int>(), pmesh);
|
||||
bool fpmap_valid = false;
|
||||
{
|
||||
BOOST_FOREACH(face_descriptor f, faces(pmesh))
|
||||
{
|
||||
if (get(fpmap, f) != 1)
|
||||
{
|
||||
fpmap_valid = true;
|
||||
break;/*1 is the default value for both Surface_mesh and Polyhedron*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selection_item)
|
||||
{
|
||||
if (edges_only)
|
||||
|
|
@ -378,11 +397,8 @@ public Q_SLOTS:
|
|||
else
|
||||
std::cout << "No selected or boundary edges to be split" << std::endl;
|
||||
}
|
||||
else
|
||||
else //not edges_only
|
||||
{
|
||||
if (selection_item->selected_facets.empty() &&
|
||||
(!selection_item->selected_edges.empty() || !selection_item->selected_vertices.empty()))
|
||||
{
|
||||
if(protect &&
|
||||
!CGAL::Polygon_mesh_processing::internal::constraints_are_short_enough(
|
||||
*selection_item->polyhedron(),
|
||||
|
|
@ -399,36 +415,59 @@ public Q_SLOTS:
|
|||
return;
|
||||
}
|
||||
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(
|
||||
faces(*selection_item->polyhedron())
|
||||
, target_length
|
||||
, *selection_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.edge_is_constrained_map(selection_item->constrained_edges_pmap())
|
||||
.relax_constraints(smooth_features)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.vertex_is_constrained_map(selection_item->constrained_vertices_pmap())
|
||||
|
||||
.face_patch_map(get(CGAL::face_patch_id_t<int>(), *selection_item->polyhedron())));
|
||||
}
|
||||
else
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(
|
||||
selection_item->selected_facets
|
||||
, target_length
|
||||
, *selection_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.edge_is_constrained_map(selection_item->constrained_edges_pmap())
|
||||
.relax_constraints(smooth_features)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.vertex_is_constrained_map(selection_item->constrained_vertices_pmap())
|
||||
.face_patch_map(get(CGAL::face_patch_id_t<int>(), *selection_item->polyhedron())));
|
||||
if (selection_item->selected_facets.empty() && !selection_item->isEmpty())
|
||||
{
|
||||
if (fpmap_valid)
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(faces(*selection_item->polyhedron())
|
||||
, target_length
|
||||
, *selection_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.edge_is_constrained_map(selection_item->constrained_edges_pmap())
|
||||
.relax_constraints(smooth_features)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.vertex_is_constrained_map(selection_item->constrained_vertices_pmap())
|
||||
.face_patch_map(fpmap));
|
||||
else
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(faces(*selection_item->polyhedron())
|
||||
, target_length
|
||||
, *selection_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.edge_is_constrained_map(selection_item->constrained_edges_pmap())
|
||||
.relax_constraints(smooth_features)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.vertex_is_constrained_map(selection_item->constrained_vertices_pmap()));
|
||||
}
|
||||
else //selected_facets not empty
|
||||
{
|
||||
if (fpmap_valid)
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(selection_item->selected_facets
|
||||
, target_length
|
||||
, *selection_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.edge_is_constrained_map(selection_item->constrained_edges_pmap())
|
||||
.relax_constraints(smooth_features)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.vertex_is_constrained_map(selection_item->constrained_vertices_pmap())
|
||||
.face_patch_map(fpmap));
|
||||
else
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(selection_item->selected_facets
|
||||
, target_length
|
||||
, *selection_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.edge_is_constrained_map(selection_item->constrained_edges_pmap())
|
||||
.relax_constraints(smooth_features)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.vertex_is_constrained_map(selection_item->constrained_vertices_pmap()));
|
||||
}
|
||||
}
|
||||
#ifdef USE_SURFACE_MESH
|
||||
selection_item->polyhedron_item()->setColor(
|
||||
selection_item->polyhedron_item()->color());
|
||||
selection_item->polyhedron_item()->setItemIsMulticolor(false);
|
||||
selection_item->polyhedron_item()->setItemIsMulticolor(fpmap_valid);
|
||||
selection_item->polyhedron_item()->polyhedron()->collect_garbage();
|
||||
#else
|
||||
if(!selection_item->polyhedron_item()->isItemMulticolor())
|
||||
|
|
@ -475,16 +514,28 @@ public Q_SLOTS:
|
|||
}
|
||||
Scene_polyhedron_selection_item::Is_constrained_map<Edge_set> ecm(&edges_to_protect);
|
||||
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(
|
||||
faces(*poly_item->polyhedron())
|
||||
, target_length
|
||||
, *poly_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.face_patch_map(get(CGAL::face_patch_id_t<int>(), *poly_item->polyhedron()))
|
||||
.edge_is_constrained_map(ecm)
|
||||
.relax_constraints(smooth_features));
|
||||
if (fpmap_valid)
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(
|
||||
faces(*poly_item->polyhedron())
|
||||
, target_length
|
||||
, *poly_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.edge_is_constrained_map(ecm)
|
||||
.relax_constraints(smooth_features)
|
||||
.face_patch_map(fpmap));
|
||||
else
|
||||
CGAL::Polygon_mesh_processing::isotropic_remeshing(
|
||||
faces(*poly_item->polyhedron())
|
||||
, target_length
|
||||
, *poly_item->polyhedron()
|
||||
, CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
|
||||
.protect_constraints(protect)
|
||||
.number_of_relaxation_steps(nb_smooth)
|
||||
.edge_is_constrained_map(ecm)
|
||||
.relax_constraints(smooth_features));
|
||||
|
||||
}
|
||||
//destroys the patch_id_map for the Surface_mesh_item to avoid assertions.
|
||||
#ifdef USE_SURFACE_MESH
|
||||
|
|
|
|||
Loading…
Reference in New Issue