diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Tetrahedra_filtering_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Tetrahedra_filtering_plugin.cpp index ce75e3eafd3..0fb84c348ad 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Tetrahedra_filtering_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Tetrahedra_filtering_plugin.cpp @@ -11,6 +11,7 @@ #include #include "Scene_c3t3_item.h" +#include "Scene_triangulation_3_item.h" #include "Scene_tetrahedra_item.h" #include "Messages_interface.h" #include "CGAL_double_edit.h" @@ -58,6 +59,10 @@ public : addDockWidget(dock_widget); connect(dock_widget->resetButton, &QPushButton::clicked, [this](){ + if(!tet_item) + return; + tet_item->c3t3_item()->resetVisibleSubdomain(); + tet_item->c3t3_item()->computeIntersection(); filter(); }); } @@ -129,6 +134,7 @@ public Q_SLOTS: connect(dock_widget->minEdit, &DoubleEdit::editingFinished, tet_item, QOverload<>::of(&Scene_tetrahedra_item::setMinThreshold)); connect(dock_widget->maxEdit, &DoubleEdit::editingFinished, tet_item, QOverload<>::of(&Scene_tetrahedra_item::setMaxThreshold)); + onFilterIndexChanged(dock_widget->filterBox->currentIndex()); dock_widget->show(); } @@ -150,14 +156,25 @@ public Q_SLOTS: if(!tet_item) return; Scene_c3t3_item* c3t3_item = tet_item->c3t3_item(); - if(c3t3_item->subdomain_indices().size() > 96) + unsigned int max_number_of_item = 32*Scene_triangulation_3_item::number_of_bitset-1; + if(c3t3_item->subdomain_indices().size() >= max_number_of_item) { - QMessageBox::warning(nullptr, "Warning", tr("The filtering is only available for items with less than 96 subdomains, and this one has %1").arg(c3t3_item->subdomain_indices().size())); + QString message = tr("The filtering is only available for items with less than %1 subdomains, and this one has %2") + .arg(max_number_of_item) + .arg(c3t3_item->subdomain_indices().size()); + QMessageBox::warning(nullptr, "Warning", message); return; } int counter = 0; int limit = static_cast(std::ceil(CGAL::approximate_sqrt(EPICK::FT(c3t3_item->subdomain_indices().size())))); QGridLayout *layout = dock_widget->gridLayout; + //delete all items (see https://stackoverflow.com/questions/4272196/qt-remove-all-widgets-from-layout) + QLayoutItem* item; + while ((item = layout->takeAt(0))) + { + delete item->widget(); + delete item; + } for (std::set::iterator it = c3t3_item->subdomain_indices().begin(), end = c3t3_item->subdomain_indices().end(); it != end; ++it) { @@ -165,7 +182,7 @@ public Q_SLOTS: QPushButton* button = new QPushButton(tr("%1").arg(index)); buttons.push_back(button); button->setCheckable(true); - button->setChecked(true); + button->setChecked(c3t3_item->isVisibleSubdomain(index)); QColor color = c3t3_item->getSubdomainIndexColor(index); QString s("QPushButton { font-weight: bold; background: #" + QString::number(90,16) diff --git a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp index 7dc8c51f1ce..89b6838e996 100644 --- a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp @@ -353,6 +353,7 @@ struct Scene_triangulation_3_item_priv { is_aabb_tree_built = false; alphaSlider = NULL; is_filterable = true; + visible_bitset.fill(0xFFFFFFFF); } void computeIntersection(const Primitive& facet); void fill_aabb_tree() { @@ -492,7 +493,7 @@ struct Scene_triangulation_3_item_priv { QVector colors; QVector colors_subdomains; boost::dynamic_bitset<> visible_subdomain; - std::bitset<24> bs[4] = {16777215, 16777215, 16777215, 16777215}; + std::array, Scene_triangulation_3_item::number_of_bitset> visible_bitset; bool show_tetrahedra; bool is_aabb_tree_built; bool last_intersection; @@ -659,7 +660,7 @@ Scene_triangulation_3_item::triangulation_changed() } const int max_subdomain_index = max; d->visible_subdomain.resize(max_subdomain_index+1, true); - d->is_filterable &=( d->subdomain_ids.size() < 96); + d->is_filterable &=( d->subdomain_indices_.size() < 32*number_of_bitset-1); for (Tr::Finite_facets_iterator fit = triangulation().finite_facets_begin(), end = triangulation().finite_facets_end(); fit != end; ++fit) { @@ -972,8 +973,11 @@ void Scene_triangulation_3_item::draw(CGAL::Three::Viewer_interface* viewer) con program->bind(); if(d->is_filterable) { - QVector4D visible_bitset(d->bs[0].to_ulong(),d->bs[1].to_ulong(),d->bs[2].to_ulong(),d->bs[3].to_ulong()); - program->setUniformValue("is_visible_bitset", visible_bitset); + std::array visible_bitset_ulong; + std::transform(d->visible_bitset.cbegin(), d->visible_bitset.cend(), visible_bitset_ulong.begin(), + [](const std::bitset<32>& bitset) { return bitset.to_ulong(); } + ); + program->setUniformValueArray("is_visible_bitset", visible_bitset_ulong.data(), number_of_bitset); } program->setUniformValue("is_filterable", d->is_filterable); program->release(); @@ -1051,8 +1055,11 @@ void Scene_triangulation_3_item::drawEdges(CGAL::Three::Viewer_interface* viewer program->bind(); if(d->is_filterable) { - QVector4D visible_bitset(d->bs[0].to_ulong(),d->bs[1].to_ulong(),d->bs[2].to_ulong(),d->bs[3].to_ulong()); - program->setUniformValue("is_visible_bitset", visible_bitset); + std::array visible_bitset_ulong; + std::transform(d->visible_bitset.cbegin(), d->visible_bitset.cend(), visible_bitset_ulong.begin(), + [](const std::bitset<32>& bitset) { return bitset.to_ulong(); } + ); + program->setUniformValueArray("is_visible_bitset", visible_bitset_ulong.data(), number_of_bitset); } program->setUniformValue("is_filterable", d->is_filterable); program->release(); @@ -2043,6 +2050,12 @@ QColor Scene_triangulation_3_item::getSubdomainIndexColor(int i) const return d->colors_subdomains[i]; } +void Scene_triangulation_3_item::resetVisibleSubdomain() +{ + d->visible_subdomain.set(); + d->visible_bitset.fill(0xFFFFFFFF); +} + void Scene_triangulation_3_item::switchVisibleSubdomain(int id) { d->visible_subdomain[id] = !d->visible_subdomain[id]; @@ -2050,7 +2063,12 @@ void Scene_triangulation_3_item::switchVisibleSubdomain(int id) int i = compact_id/32; int j = compact_id%32; - d->bs[i][j] = d->visible_subdomain[id]; + d->visible_bitset[i][j] = d->visible_subdomain[id]; +} + +bool Scene_triangulation_3_item::isVisibleSubdomain(int id) const +{ + return d->visible_subdomain[id]; } void Scene_triangulation_3_item::computeIntersection() diff --git a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h index 8cd2b81bd12..6ca88cdca07 100644 --- a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h @@ -31,6 +31,7 @@ using namespace CGAL::Three; Q_OBJECT public: typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; + static const int number_of_bitset = 4; // also defined in "shader_c3t3.frag" and "shader_c3t3_edges.frag" Scene_triangulation_3_item(bool display_elements = true); Scene_triangulation_3_item(const T3 t3, bool display_elements = true); @@ -141,7 +142,9 @@ public: QColor get_histogram_color(const double v) const; + void resetVisibleSubdomain(); void switchVisibleSubdomain(int); + bool isVisibleSubdomain(int) const; void itemAboutToBeDestroyed(Scene_item *) Q_DECL_OVERRIDE; diff --git a/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag b/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag index 27b255c5e1c..f7b5c3d59ba 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag +++ b/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag @@ -1,4 +1,7 @@ #version 150 + +const int number_of_bitset = 4; + in vec4 color; in vec4 fP; in vec3 fN; @@ -19,8 +22,8 @@ uniform bool writing; uniform sampler2D sampler; uniform float alpha; uniform bool is_surface; -uniform vec4 is_visible_bitset; uniform bool is_filterable; +uniform int is_visible_bitset[number_of_bitset]; out vec4 out_color; float depth(float z) @@ -33,11 +36,13 @@ void main(void) { { uint domain1 = uint(subdomain_out.x); uint domain2 = uint(subdomain_out.y); - uint i1 = domain1/25u; - uint i2 = domain2/25u; + uint i1 = domain1/32u; + uint j1 = domain1%32u; + uint i2 = domain2/32u; + uint j2 = domain2%32u; uint visible1 = uint(is_visible_bitset[i1]); uint visible2 = uint(is_visible_bitset[i2]); - if((visible1>>(domain1%25u))%2u == 0u && (visible2>>(domain2%25u))%2u == 0u) + if(((visible1>>j1)&1u) == 0u && ((visible2>>j2)&1u) == 0u) { discard; } diff --git a/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag b/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag index c3fbb6bba00..a6d15c1a6a9 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag +++ b/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag @@ -1,9 +1,12 @@ #version 150 + +const int number_of_bitset = 4; + in vec4 color; flat in vec2 subdomain_out; uniform bool is_surface; -uniform vec4 is_visible_bitset; uniform bool is_filterable; +uniform int is_visible_bitset[number_of_bitset]; out vec4 out_color; void main(void) { @@ -12,10 +15,12 @@ void main(void) uint domain1 = uint(subdomain_out.x); uint domain2 = uint(subdomain_out.y); uint i1 = domain1/32u; + uint j1 = domain1%32u; uint i2 = domain2/32u; + uint j2 = domain2%32u; uint visible1 = uint(is_visible_bitset[i1]); uint visible2 = uint(is_visible_bitset[i2]); - if((visible1>>(domain1%32u))%2u == 0u && (visible2>>(domain2%32u))%2u == 0u) + if(((visible1>>j1)&1u) == 0u && ((visible2>>j2)&1u) == 0u) { discard; }