Mesh 3: Fix demo tetrahedral filtering with a tetrahedral mesh having many subdomains (#7734)

## Summary of Changes

When a triangulation 3 has many subdomains (more than 24), some will not
be shown.

Changes done : 
 - [x] Lowered maximum number of subdomains allowed in filtering
 - [x] Made filtering work with up to 128 subdomains
 - [x] Made this limit more easy to change

Possible amelioration :
- [ ] Make filtering work with any number of subdomains (using a texture
buffer)

## Release Management

* Affected package(s): Mesh_3
* Issue(s) solved (if any): 
* Feature/Small Feature (if any):
* License and copyright ownership:
This commit is contained in:
Sebastien Loriot 2023-10-25 23:32:21 -07:00 committed by GitHub
commit b2df589e68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 16 deletions

View File

@ -11,6 +11,7 @@
#include <CGAL/double.h>
#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<int>(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<int>::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)

View File

@ -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<QColor> colors;
QVector<QColor> colors_subdomains;
boost::dynamic_bitset<> visible_subdomain;
std::bitset<24> bs[4] = {16777215, 16777215, 16777215, 16777215};
std::array<std::bitset<32>, 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<GLuint, number_of_bitset> 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<GLuint, number_of_bitset> 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()

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}