Merge pull request #5621 from sloriot/Demo-polylines_in_offset_meshing

Add support for protecting features in offset meshing
This commit is contained in:
Sebastien Loriot 2021-04-21 15:31:36 +02:00 committed by GitHub
commit 4f3c2b7ee4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 204 additions and 115 deletions

View File

@ -36,7 +36,8 @@ if(NOT CGAL_DISABLE_GMP)
polyhedron_demo_plugin(offset_meshing_plugin Offset_meshing_plugin
${remeshingUI_FILES})
target_link_libraries(offset_meshing_plugin PUBLIC scene_surface_mesh_item
scene_polygon_soup_item)
scene_polygon_soup_item
scene_polylines_item)
if(TARGET CGAL::Eigen3_support)
target_link_libraries(offset_meshing_plugin PUBLIC CGAL::Eigen3_support)
endif()

View File

@ -12,6 +12,7 @@
#include <QThread>
#include "Scene_surface_mesh_item.h"
#include "Scene_polygon_soup_item.h"
#include "Scene_polylines_item.h"
#include <QInputDialog>
#include <QStringList>
#include <QMessageBox>
@ -30,6 +31,7 @@
#include <CGAL/Timer.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/Labeled_mesh_domain_3.h>
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Three/Three.h>
@ -250,15 +252,18 @@ public:
// declare the CGAL function
template<class Mesh>
SMesh* cgal_off_meshing(QWidget*,
Mesh* tm_ptr,
const double offset_value,
const double angle,
const double sizing,
const double approx,
int tag)
Mesh* tm_ptr,
Scene_polylines_item* polylines_item,
const double offset_value,
const double angle,
const double sizing,
const double approx,
const double edge_size,
int tag)
{
typedef EPICK GT;
typedef CGAL::Labeled_mesh_domain_3<GT, int, int> Mesh_domain;
typedef CGAL::Labeled_mesh_domain_3<GT, int, int> Mesh_domain_base;
typedef CGAL::Mesh_domain_with_polyline_features_3<Mesh_domain_base> Mesh_domain;
typedef C3t3::Triangulation Tr;
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
typedef GT::Sphere_3 Sphere_3;
@ -292,7 +297,20 @@ SMesh* cgal_off_meshing(QWidget*,
Mesh_criteria criteria(p::facet_angle = angle,
p::facet_size = sizing,
p::facet_distance = approx,
p::facet_topology = topology);
p::facet_topology = topology,
p::edge_size = edge_size);
if (polylines_item!=nullptr)
{
typedef std::vector<Mesh_domain::Surface_patch_index> Surface_patch_ids;
std::vector<Mesh_domain::Surface_patch_index> surface_patch_ids;
domain.add_features_and_incidences(polylines_item->polylines.begin(),
polylines_item->polylines.end(),
CGAL::Identity_property_map<Scene_polylines_item::Polyline>(),
CGAL::Constant_property_map<Scene_polylines_item::Polyline, Surface_patch_ids>(
surface_patch_ids));
}
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
p::no_perturb(),
@ -330,40 +348,48 @@ struct Mesher_thread:public QThread{
private:
SMesh* sMesh;
Scene_polygon_soup_item* soup_item;
Scene_polylines_item* polylines_item;
const double offset_value;
const double angle;
const double sizing;
const double approx;
const double edge_size;
int tag_index;
public:
Mesher_thread( SMesh* tm_ptr,
Scene_polygon_soup_item* soup_item,
Scene_polylines_item* polylines_item,
const double offset_value,
const double angle,
const double sizing,
const double approx,
const double edge_size,
int tag)
:sMesh(tm_ptr), soup_item(soup_item),
:sMesh(tm_ptr), soup_item(soup_item), polylines_item(polylines_item),
offset_value(offset_value), angle(angle),
sizing(sizing), approx(approx), tag_index(tag){
sizing(sizing), approx(approx), edge_size(edge_size), tag_index(tag){
}
void run() override {
SMesh* new_mesh= nullptr;
if(soup_item)
new_mesh = cgal_off_meshing(CGAL::Three::Three::mainWindow(),
soup_item,
polylines_item,
offset_value,
angle,
sizing,
approx,
edge_size,
tag_index);
else
new_mesh = cgal_off_meshing(CGAL::Three::Three::mainWindow(),
sMesh,
polylines_item,
offset_value,
angle,
sizing,
approx,
edge_size,
tag_index);
Q_EMIT resultReady(new_mesh);
}
@ -399,12 +425,20 @@ public:
}
}
bool applicable(QAction* a) const {
Scene_item* item = scene->item(scene->mainSelectionIndex());
bool applicable(QAction*) const {
if ( scene->selectionIndices().size() != 1 &&
scene->selectionIndices().size() != 2 )
{
return false;
}
return
qobject_cast<Scene_surface_mesh_item*>(item) ||
(a == actionOffsetMeshing && qobject_cast<Scene_polygon_soup_item*>(item));
Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices())
{
if ( qobject_cast<Scene_surface_mesh_item*>(scene->item(index)) ||
qobject_cast<Scene_polygon_soup_item*>(scene->item(index)) )
return true;
}
return false;
}
QList<QAction*> actions() const {
@ -456,12 +490,37 @@ void Polyhedron_demo_offset_meshing_plugin::inflate_mesh()
void Polyhedron_demo_offset_meshing_plugin::offset_meshing()
{
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_item* item = scene->item(index);
Scene_surface_mesh_item* sm_item =
qobject_cast<Scene_surface_mesh_item*>(item);
Scene_polygon_soup_item* soup_item =
qobject_cast<Scene_polygon_soup_item*>(item);
Scene_surface_mesh_item* sm_item = nullptr;
Scene_polygon_soup_item* soup_item = nullptr;
Scene_polylines_item* polylines_item = nullptr;
Scene_item* item = nullptr;
bool mesh_or_soup_item_found = false;
Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices())
{
if (!mesh_or_soup_item_found)
{
sm_item = qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
if (sm_item == nullptr)
{
soup_item = qobject_cast<Scene_polygon_soup_item*>(item);
if (soup_item != nullptr)
{
item=scene->item(index);
mesh_or_soup_item_found = true;
continue;
}
}
else
{
item=scene->item(index);
mesh_or_soup_item_found = true;
continue;
}
}
polylines_item = qobject_cast<Scene_polylines_item*>(scene->item(index));
}
SMesh* sMesh = NULL;
double diag = 0;
@ -507,6 +566,14 @@ void Polyhedron_demo_offset_meshing_plugin::offset_meshing()
diag); // max
ui.approx->setValue(diag * 0.005);
if (polylines_item!=nullptr)
{
ui.edge_sizing->setRange(diag * 10e-6, // min
diag); // max
ui.edge_sizing->setValue(diag * 0.05); // default value
}
else
ui.edge_sizing->setEnabled(false);
int i = dialog.exec();
if(i == QDialog::Rejected)
@ -515,6 +582,7 @@ void Polyhedron_demo_offset_meshing_plugin::offset_meshing()
const double angle = ui.angle->value();
const double approx = ui.approx->value();
const double sizing = ui.sizing->value();
const double edge_size=polylines_item!=nullptr?ui.edge_sizing->value():0;
const int tag_index = ui.tags->currentIndex();
if(tag_index < 0) return;
@ -532,22 +600,26 @@ void Polyhedron_demo_offset_meshing_plugin::offset_meshing()
if(soup_item)
worker = new Mesher_thread(nullptr,
soup_item,
polylines_item,
offset_value,
angle,
sizing,
approx,
edge_size,
tag_index);
else
worker = new Mesher_thread(sMesh,
nullptr,
polylines_item,
offset_value,
angle,
sizing,
approx,
edge_size,
tag_index);
connect(worker, &QThread::finished, worker, &QObject::deleteLater);
connect(worker, &Mesher_thread::resultReady, this,
[item, angle, sizing, approx, offset_value, index]
[item, angle, sizing, approx, offset_value/* , index */]
(SMesh *new_mesh){
QApplication::restoreOverrideCursor();
if(!new_mesh){
@ -563,7 +635,7 @@ void Polyhedron_demo_offset_meshing_plugin::offset_meshing()
new_item->setColor(Qt::magenta);
new_item->setWireframeMode();
CGAL::Three::Three::scene()->addItem(new_item);
CGAL::Three::Three::scene()->itemChanged(index);
// CGAL::Three::Three::scene()->itemChanged(index);
QApplication::restoreOverrideCursor();
});

View File

@ -6,102 +6,78 @@
<rect>
<x>0</x>
<y>0</y>
<width>344</width>
<height>169</height>
<width>376</width>
<height>216</height>
</rect>
</property>
<property name="windowTitle">
<string>Meshing criteria</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0">
<item row="1" column="1">
<widget class="DoubleEdit" name="sizing">
<property name="text">
<string>0.00</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="tags">
<item>
<property name="text">
<string>Non manifold</string>
</property>
</item>
<item>
<property name="text">
<string>Manifold</string>
</property>
</item>
<item>
<property name="text">
<string>Manifold with boundaries</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="angleLabel">
<property name="text">
<string>&amp;Angle:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="sizingLabel">
<property name="text">
<string>&amp;Size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="approxLabel">
<property name="text">
<string>Approximation &amp;error:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Topological criterion:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>tags</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="DoubleEdit" name="approx">
<property name="text">
<string>0.00</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="DoubleEdit" name="angle">
<property name="text">
<string>25.0</string>
</property>
</widget>
</item>
</layout>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2" colspan="2">
<widget class="DoubleEdit" name="angle">
<property name="text">
<string>25.0</string>
</property>
</widget>
</item>
<item>
<item row="1" column="2" colspan="2">
<widget class="DoubleEdit" name="sizing">
<property name="text">
<string>0.00</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="approxLabel">
<property name="text">
<string>Approximation &amp;error:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="DoubleEdit" name="approx">
<property name="text">
<string>0.00</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Topological criterion:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>tags</cstring>
</property>
</widget>
</item>
<item row="4" column="2" colspan="2">
<widget class="QComboBox" name="tags">
<item>
<property name="text">
<string>Non manifold</string>
</property>
</item>
<item>
<property name="text">
<string>Manifold</string>
</property>
</item>
<item>
<property name="text">
<string>Manifold with boundaries</string>
</property>
</item>
</widget>
</item>
<item row="5" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -114,7 +90,7 @@
</property>
</spacer>
</item>
<item>
<item row="6" column="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -124,6 +100,46 @@
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="DoubleEdit" name="edge_sizing">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>0.00</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="sizingLabel_2">
<property name="text">
<string>&amp;Edge size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="sizingLabel">
<property name="text">
<string>&amp;Size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="angleLabel">
<property name="text">
<string>&amp;Angle:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>