Merge pull request #5108 from janetournois/PMP-remesh_after_detect_sharp_features-jtournois

Demo isotropic_remeshing_plugin - keep selection valid
This commit is contained in:
Laurent Rineau 2020-11-04 20:46:02 +01:00
commit daee7209b5
3 changed files with 112 additions and 57 deletions

View File

@ -351,7 +351,6 @@ public Q_SLOTS:
? *poly_item->polyhedron()
: *selection_item->polyhedron();
Patch_id_pmap fpmap = get(CGAL::face_patch_id_t<int>(), pmesh);
bool fpmap_valid = false;
{
@ -461,40 +460,6 @@ public Q_SLOTS:
}
}
SMesh mesh_ = *selection_item->polyhedron();
std::vector<bool> are_edges_removed;
are_edges_removed.resize(mesh_.number_of_edges()+mesh_.number_of_removed_edges());
std::vector<bool> are_edges_constrained;
are_edges_constrained.resize(are_edges_removed.size());
for(std::size_t i=0; i< are_edges_removed.size(); ++i)
{
are_edges_removed[i] = mesh_.is_removed(SMesh::Edge_index(static_cast<int>(i)));
if(!are_edges_removed[i])
are_edges_constrained[i] = get(selection_item->constrained_edges_pmap(), SMesh::Edge_index(static_cast<int>(i)));
}
int i0, i1,
nE(mesh_.number_of_edges()+mesh_.number_of_removed_edges());
//get constrained values in order.
if (nE > 0)
{
i0=0; i1=nE-1;
while (1)
{
// find first removed and last un-removed
while (!are_edges_removed[i0] && i0 < i1) ++i0;
while ( are_edges_removed[i1] && i0 < i1) --i1;
if (i0 >= i1) break;
// swap
std::swap(are_edges_constrained[i0], are_edges_constrained[i1]);
std::swap(are_edges_removed[i0], are_edges_removed[i1]);
}
// remember new size
nE = are_edges_removed[i0] ? i0 : i0+1;
}
selection_item->polyhedron_item()->setColor(
selection_item->polyhedron_item()->color());
if(fpmap_valid)
@ -506,19 +471,11 @@ public Q_SLOTS:
{
selection_item->polyhedron_item()->setItemIsMulticolor(false);
}
selection_item->polyhedron_item()->polyhedron()->collect_garbage();
//fix constrained_edges_map
for(int i=0; i< nE; ++i)
{
Scene_polyhedron_selection_item::Is_constrained_map<Scene_polyhedron_selection_item::Selection_set_edge>
pmap = selection_item->constrained_edges_pmap();
put(pmap, SMesh::Edge_index(i), are_edges_constrained[i]);
}
selection_item->poly_item_changed();
selection_item->clear<face_descriptor>();
selection_item->changed_with_poly_item();
selection_item->setKeepSelectionValid(Scene_polyhedron_selection_item::Edge);
selection_item->polyhedron_item()->invalidateOpenGLBuffers();
Q_EMIT selection_item->polyhedron_item()->itemChanged();
selection_item->invalidateOpenGLBuffers();
selection_item->setKeepSelectionValid(Scene_polyhedron_selection_item::None);
}
else if (poly_item)
{

View File

@ -95,6 +95,7 @@ struct Scene_polyhedron_selection_item_priv{
{
filtered_graph = nullptr;
item->setProperty("classname", QString("surface_mesh"));
keep_selection_valid = Scene_polyhedron_selection_item::None;
}
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
@ -201,6 +202,7 @@ struct Scene_polyhedron_selection_item_priv{
std::size_t num_faces;
std::size_t num_vertices;
std::size_t num_edges;
Scene_polyhedron_selection_item::SelectionTypes keep_selection_valid;
};
typedef Scene_polyhedron_selection_item_priv Priv;
@ -2138,6 +2140,13 @@ void Scene_polyhedron_selection_item::selected_HL(const std::set<fg_edge_descrip
Q_EMIT itemChanged();
}
void Scene_polyhedron_selection_item::reset_numbers()
{
d->num_faces = num_faces(*poly_item->polyhedron());
d->num_vertices = num_vertices(*poly_item->polyhedron());
d->num_edges = num_edges(*poly_item->polyhedron());
}
void Scene_polyhedron_selection_item::init(Scene_face_graph_item* poly_item, QMainWindow* mw)
{
this->poly_item = poly_item;
@ -2172,22 +2181,26 @@ void Scene_polyhedron_selection_item::init(Scene_face_graph_item* poly_item, QMa
connect(&k_ring_selector,SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*)), this, SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*)));
k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1);
connect(&k_ring_selector, SIGNAL(resetIsTreated()), this, SLOT(resetIsTreated()));
connect(poly_item, &Scene_surface_mesh_item::itemChanged, this, [this](){
std::size_t new_num_faces = num_faces(*this->poly_item->face_graph());
std::size_t new_num_vertices = num_vertices(*this->poly_item->face_graph());
std::size_t new_num_edges = num_edges(*this->poly_item->face_graph());
if(new_num_faces != d->num_faces)
if(new_num_faces != d->num_faces
&& !d->keep_selection_valid.testFlag(Facet))
{
selected_facets.clear();
d->num_faces = new_num_faces ;
}
if(new_num_vertices!= d->num_vertices)
if(new_num_vertices!= d->num_vertices
&& !d->keep_selection_valid.testFlag(Vertex))
{
selected_vertices.clear();
d->num_vertices = new_num_vertices ;
}
if(new_num_edges!= d->num_edges)
if(new_num_edges!= d->num_edges
&& !d->keep_selection_valid.testFlag(Edge))
{
selected_edges.clear();
d->num_edges = new_num_edges ;
@ -2622,3 +2635,30 @@ void Scene_polyhedron_selection_item::updateDisplayedIds(QEvent* e)
}
}
}
void Scene_polyhedron_selection_item::poly_item_changed()
{
if(d->keep_selection_valid != None)
{
Update_indices_visitor visitor(selected_vertices,
selected_edges,
selected_facets,
*polyhedron());
polyhedron()->collect_garbage(visitor);
}
else
{
if(!d->keep_selection_valid.testFlag(Vertex))
remove_erased_handles<fg_vertex_descriptor>();
if(!d->keep_selection_valid.testFlag(Edge))
remove_erased_handles<fg_edge_descriptor>();
if(!d->keep_selection_valid.testFlag(Facet))
remove_erased_handles<fg_face_descriptor>();
}
compute_normal_maps();
}
void Scene_polyhedron_selection_item::setKeepSelectionValid(SelectionTypes type)
{
d->keep_selection_valid = type;
}

View File

@ -206,6 +206,13 @@ public:
typedef Scene_facegraph_item_k_ring_selection::Active_handle Active_handle;
enum SelectionType{
Vertex=0x1,
Edge=0x2,
Facet=0x4,
None=0x8
};
Q_DECLARE_FLAGS(SelectionTypes, SelectionType)
void common_constructor();
Scene_polyhedron_selection_item() ;
Scene_polyhedron_selection_item(Scene_face_graph_item* poly_item, QMainWindow* mw);
@ -228,6 +235,7 @@ public:
}
void initializeBuffers(CGAL::Three::Viewer_interface *) const;
void computeElements() const;
void setKeepSelectionValid(SelectionTypes type);
protected:
void init(Scene_face_graph_item* poly_item, QMainWindow* mw);
@ -276,6 +284,8 @@ public:
return selected_vertices.empty() && selected_edges.empty() && selected_facets.empty();
}
void reset_numbers();
void compute_bbox() const
{
// Workaround a bug in g++-4.8.3:
@ -837,12 +847,7 @@ public Q_SLOTS:
void selected_HL(const std::set<fg_vertex_descriptor>& m);
void selected_HL(const std::set<fg_face_descriptor>& m);
void selected_HL(const std::set<fg_edge_descriptor>& m);
void poly_item_changed() {
remove_erased_handles<fg_vertex_descriptor>();
remove_erased_handles<fg_edge_descriptor>();
remove_erased_handles<fg_face_descriptor>();
compute_normal_maps();
}
void poly_item_changed();
void endSelection(){
Q_EMIT simplicesSelected(this);
}
@ -1025,6 +1030,59 @@ protected :
friend struct Scene_polyhedron_selection_item_priv;
Scene_polyhedron_selection_item_priv *d;
struct Update_indices_visitor
{
Selection_set_vertex& m_vertices;
Selection_set_edge& m_edges;
Selection_set_facet& m_facets;
FaceGraph& m_mesh;
Update_indices_visitor(Selection_set_vertex& vertices,
Selection_set_edge& edges,
Selection_set_facet& facets,
FaceGraph& mesh)
: m_vertices(vertices), m_edges(edges), m_facets(facets), m_mesh(mesh)
{}
template<typename V2V, typename E2E, typename F2F>
void operator()(const V2V& v2v, const E2E& e2e, const F2F& f2f)
{
//in *2* maps,
//left is old simplex, right is new simplex
Selection_set_vertex new_vertices;
Selection_set_edge new_edges;
Selection_set_facet new_facets;
for(vertex_descriptor v : m_vertices)
{
if(v2v[v] != boost::graph_traits<SMesh>::null_vertex()
&& int(v2v[v]) < static_cast<int>(m_mesh.number_of_vertices()))
new_vertices.insert(v2v[v]);
}
m_vertices.clear();
m_vertices.insert(new_vertices.begin(), new_vertices.end());
for (fg_edge_descriptor e : m_edges)
{
halfedge_descriptor h = halfedge(e, m_mesh);
if(e2e[h] != boost::graph_traits<SMesh>::null_halfedge()
&& int(e2e[h]) < static_cast<int>(m_mesh.number_of_halfedges()))
new_edges.insert(edge(e2e[h], m_mesh));
}
m_edges.clear();
m_edges.insert(new_edges.begin(), new_edges.end());
for (face_descriptor f : m_facets)
if(f2f[f] != boost::graph_traits<SMesh>::null_face()
&& int(f2f[f]) < static_cast<int>(m_mesh.number_of_faces()))
new_facets.insert(f2f[f]);
m_facets.clear();
m_facets.insert(new_facets.begin(), new_facets.end());
}
};
public:
//statistics
enum STATS {