mirror of https://github.com/CGAL/cgal
Merge pull request #1044 from maxGimeno/Euler_operations-rebase-GF
Polyhedron demo : Euler operations in selection_plugin
This commit is contained in:
commit
ef13f66767
|
|
@ -75,7 +75,7 @@ public:
|
||||||
messages = m;
|
messages = m;
|
||||||
actionSelection = new QAction(tr("Selection"), mw);
|
actionSelection = new QAction(tr("Selection"), mw);
|
||||||
connect(actionSelection, SIGNAL(triggered()), this, SLOT(selection_action()));
|
connect(actionSelection, SIGNAL(triggered()), this, SLOT(selection_action()));
|
||||||
|
last_mode = 0;
|
||||||
dock_widget = new QDockWidget("Selection", mw);
|
dock_widget = new QDockWidget("Selection", mw);
|
||||||
dock_widget->setVisible(false);
|
dock_widget->setVisible(false);
|
||||||
|
|
||||||
|
|
@ -93,13 +93,11 @@ public:
|
||||||
this, SLOT(on_Selection_type_combo_box_changed(int)));
|
this, SLOT(on_Selection_type_combo_box_changed(int)));
|
||||||
connect(ui_widget.Insertion_radio_button, SIGNAL(toggled(bool)), this, SLOT(on_Insertion_radio_button_toggled(bool)));
|
connect(ui_widget.Insertion_radio_button, SIGNAL(toggled(bool)), this, SLOT(on_Insertion_radio_button_toggled(bool)));
|
||||||
connect(ui_widget.Brush_size_spin_box, SIGNAL(valueChanged(int)), this, SLOT(on_Brush_size_spin_box_changed(int)));
|
connect(ui_widget.Brush_size_spin_box, SIGNAL(valueChanged(int)), this, SLOT(on_Brush_size_spin_box_changed(int)));
|
||||||
connect(ui_widget.Create_point_set_item_button, SIGNAL(clicked()), this, SLOT(on_Create_point_set_item_button_clicked()));
|
connect(ui_widget.validateButton, SIGNAL(clicked()), this, SLOT(on_validateButton_clicked()));
|
||||||
connect(ui_widget.Create_polyline_item_button, SIGNAL(clicked()), this, SLOT(on_Create_polyline_item_button_clicked()));
|
|
||||||
connect(ui_widget.Erase_selected_facets_button, SIGNAL(clicked()), this, SLOT(on_Erase_selected_facets_button_clicked()));
|
|
||||||
connect(ui_widget.Keep_connected_components_button, SIGNAL(clicked()), this, SLOT(on_Keep_connected_components_button_clicked()));
|
|
||||||
connect(ui_widget.Expand_reduce_button, SIGNAL(clicked()), this, SLOT(on_Expand_reduce_button_clicked()));
|
connect(ui_widget.Expand_reduce_button, SIGNAL(clicked()), this, SLOT(on_Expand_reduce_button_clicked()));
|
||||||
connect(ui_widget.Create_polyhedron_item_button, SIGNAL(clicked()), this, SLOT(on_Create_polyhedron_item_button_clicked()));
|
|
||||||
connect(ui_widget.Select_sharp_edges_button, SIGNAL(clicked()), this, SLOT(on_Select_sharp_edges_button_clicked()));
|
connect(ui_widget.Select_sharp_edges_button, SIGNAL(clicked()), this, SLOT(on_Select_sharp_edges_button_clicked()));
|
||||||
|
connect(ui_widget.modeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_ModeBox_changed(int)));
|
||||||
|
connect(ui_widget.editionBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_editionBox_changed(int)));
|
||||||
|
|
||||||
QObject* scene = dynamic_cast<QObject*>(scene_interface);
|
QObject* scene = dynamic_cast<QObject*>(scene_interface);
|
||||||
if(scene) {
|
if(scene) {
|
||||||
|
|
@ -111,7 +109,14 @@ public:
|
||||||
{
|
{
|
||||||
dock_widget->hide();
|
dock_widget->hide();
|
||||||
}
|
}
|
||||||
|
Q_SIGNALS:
|
||||||
|
void save_handleType();
|
||||||
|
void set_operation_mode(int);
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
void setInstructions(QString s)
|
||||||
|
{
|
||||||
|
ui_widget.instructionsLabel->setText(s);
|
||||||
|
}
|
||||||
void selection_action() {
|
void selection_action() {
|
||||||
dock_widget->show();
|
dock_widget->show();
|
||||||
dock_widget->raise();
|
dock_widget->raise();
|
||||||
|
|
@ -119,12 +124,17 @@ public Q_SLOTS:
|
||||||
Scene_polyhedron_item* poly_item = getSelectedItem<Scene_polyhedron_item>();
|
Scene_polyhedron_item* poly_item = getSelectedItem<Scene_polyhedron_item>();
|
||||||
if(!poly_item || selection_item_map.find(poly_item) != selection_item_map.end()) { return; }
|
if(!poly_item || selection_item_map.find(poly_item) != selection_item_map.end()) { return; }
|
||||||
Scene_polyhedron_selection_item* new_item = new Scene_polyhedron_selection_item(poly_item, mw);
|
Scene_polyhedron_selection_item* new_item = new Scene_polyhedron_selection_item(poly_item, mw);
|
||||||
|
connect(this, SIGNAL(save_handleType()),new_item, SLOT(save_handleType()));
|
||||||
|
connect(new_item, SIGNAL(updateInstructions(QString)), this, SLOT(setInstructions(QString)));
|
||||||
|
connect(this, SIGNAL(set_operation_mode(int)),new_item, SLOT(set_operation_mode(int)));
|
||||||
int item_id = scene->addItem(new_item);
|
int item_id = scene->addItem(new_item);
|
||||||
QObject* scene_ptr = dynamic_cast<QObject*>(scene);
|
QObject* scene_ptr = dynamic_cast<QObject*>(scene);
|
||||||
if (scene_ptr)
|
if (scene_ptr)
|
||||||
connect(new_item,SIGNAL(simplicesSelected(CGAL::Three::Scene_item*)), scene_ptr, SLOT(setSelectedItem(CGAL::Three::Scene_item*)));
|
connect(new_item,SIGNAL(simplicesSelected(CGAL::Three::Scene_item*)), scene_ptr, SLOT(setSelectedItem(CGAL::Three::Scene_item*)));
|
||||||
scene->setSelectedItem(item_id);
|
scene->setSelectedItem(item_id);
|
||||||
|
on_ModeBox_changed(ui_widget.modeBox->currentIndex());
|
||||||
}
|
}
|
||||||
|
on_Selection_type_combo_box_changed(ui_widget.Selection_type_combo_box->currentIndex());
|
||||||
}
|
}
|
||||||
// Select all
|
// Select all
|
||||||
void on_Select_all_button_clicked() {
|
void on_Select_all_button_clicked() {
|
||||||
|
|
@ -199,11 +209,19 @@ public Q_SLOTS:
|
||||||
// all other arrangements (putting inside selection_item_map), setting names etc,
|
// all other arrangements (putting inside selection_item_map), setting names etc,
|
||||||
// other params (e.g. k_ring) will be set inside new_item_created
|
// other params (e.g. k_ring) will be set inside new_item_created
|
||||||
Scene_polyhedron_selection_item* new_item = new Scene_polyhedron_selection_item(poly_item, mw);
|
Scene_polyhedron_selection_item* new_item = new Scene_polyhedron_selection_item(poly_item, mw);
|
||||||
|
//To specify what action should be performed on shift+left-click
|
||||||
|
connect(this, SIGNAL(save_handleType()),new_item, SLOT(save_handleType()));
|
||||||
|
connect(new_item, SIGNAL(updateInstructions(QString)), this, SLOT(setInstructions(QString)));
|
||||||
|
connect(this, SIGNAL(set_operation_mode(int)),new_item, SLOT(set_operation_mode(int)));
|
||||||
int item_id = scene->addItem(new_item);
|
int item_id = scene->addItem(new_item);
|
||||||
QObject* scene_ptr = dynamic_cast<QObject*>(scene);
|
QObject* scene_ptr = dynamic_cast<QObject*>(scene);
|
||||||
if (scene_ptr)
|
if (scene_ptr)
|
||||||
connect(new_item,SIGNAL(simplicesSelected(CGAL::Three::Scene_item*)), scene_ptr, SLOT(setSelectedItem(CGAL::Three::Scene_item*)));
|
connect(new_item,SIGNAL(simplicesSelected(CGAL::Three::Scene_item*)), scene_ptr, SLOT(setSelectedItem(CGAL::Three::Scene_item*)));
|
||||||
scene->setSelectedItem(item_id);
|
scene->setSelectedItem(item_id);
|
||||||
|
ui_widget.modeBox->setCurrentIndex(last_mode);
|
||||||
|
on_ModeBox_changed(ui_widget.modeBox->currentIndex());
|
||||||
|
on_Selection_type_combo_box_changed(ui_widget.Selection_type_combo_box->currentIndex());
|
||||||
|
|
||||||
}
|
}
|
||||||
void on_Selection_type_combo_box_changed(int index) {
|
void on_Selection_type_combo_box_changed(int index) {
|
||||||
typedef Scene_polyhedron_selection_item::Active_handle Active_handle;
|
typedef Scene_polyhedron_selection_item::Active_handle Active_handle;
|
||||||
|
|
@ -222,119 +240,178 @@ public Q_SLOTS:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_Create_point_set_item_button_clicked() {
|
|
||||||
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
|
||||||
if(!selection_item) {
|
|
||||||
print_message("Error: there is no selected polyhedron selection item!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(selection_item->selected_vertices.empty()) {
|
|
||||||
print_message("Error: there is no selected vertex in polyhedron selection item!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Scene_points_with_normal_item* point_item = new Scene_points_with_normal_item();
|
|
||||||
point_item->setName(QString("%1-points").arg(selection_item->name()));
|
|
||||||
for(Scene_polyhedron_selection_item::Selection_set_vertex::iterator begin = selection_item->selected_vertices.begin();
|
|
||||||
begin != selection_item->selected_vertices.end(); ++begin) {
|
|
||||||
point_item->point_set()->push_back((*begin)->point());
|
|
||||||
}
|
|
||||||
scene->setSelectedItem( scene->addItem(point_item) );
|
|
||||||
scene->itemChanged(point_item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_Create_polyline_item_button_clicked(){
|
void on_validateButton_clicked() {
|
||||||
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
switch(ui_widget.operationsBox->currentIndex())
|
||||||
if(!selection_item) {
|
|
||||||
print_message("Error: there is no selected polyhedron selection item!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(selection_item->selected_edges.empty()) {
|
|
||||||
print_message("Error: there is no selected edge in polyhedron selection item!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Scene_polylines_item* polyline_item = new Scene_polylines_item();
|
|
||||||
polyline_item->setName(QString("%1-edges").arg(selection_item->name()));
|
|
||||||
|
|
||||||
typedef boost::adjacency_list < boost::listS,
|
|
||||||
boost::vecS,
|
|
||||||
boost::undirectedS,
|
|
||||||
Kernel::Point_3 > Edge_graph;
|
|
||||||
typedef Polyhedron::Vertex_handle Vertex_handle;
|
|
||||||
Edge_graph edge_graph;
|
|
||||||
std::map<Vertex_handle, Edge_graph::vertex_descriptor> p2vd;
|
|
||||||
std::map<Vertex_handle, Edge_graph::vertex_descriptor>::iterator it_find;
|
|
||||||
bool insert_OK;
|
|
||||||
|
|
||||||
for(Scene_polyhedron_selection_item::Selection_set_edge::iterator begin = selection_item->selected_edges.begin();
|
|
||||||
begin != selection_item->selected_edges.end(); ++begin)
|
|
||||||
{
|
{
|
||||||
Vertex_handle source = begin->halfedge()->opposite()->vertex();
|
//Create Point Set Item from Selected Vertices
|
||||||
boost::tie(it_find, insert_OK)
|
case 0:
|
||||||
= p2vd.insert(std::make_pair(source, Edge_graph::vertex_descriptor()));
|
{
|
||||||
if (insert_OK)
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
{
|
if(!selection_item) {
|
||||||
it_find->second = add_vertex(edge_graph);
|
print_message("Error: there is no selected polyhedron selection item!");
|
||||||
edge_graph[it_find->second] = source->point();
|
return;
|
||||||
}
|
}
|
||||||
Edge_graph::vertex_descriptor src=it_find->second;
|
if(selection_item->selected_vertices.empty()) {
|
||||||
|
print_message("Error: there is no selected vertex in polyhedron selection item!");
|
||||||
Vertex_handle target = begin->halfedge()->vertex();
|
return;
|
||||||
boost::tie(it_find, insert_OK)
|
}
|
||||||
= p2vd.insert(std::make_pair(target, Edge_graph::vertex_descriptor()));
|
Scene_points_with_normal_item* point_item = new Scene_points_with_normal_item();
|
||||||
if (insert_OK)
|
point_item->setName(QString("%1-points").arg(selection_item->name()));
|
||||||
{
|
for(Scene_polyhedron_selection_item::Selection_set_vertex::iterator begin = selection_item->selected_vertices.begin();
|
||||||
it_find->second = add_vertex(edge_graph);
|
begin != selection_item->selected_vertices.end(); ++begin) {
|
||||||
edge_graph[it_find->second] = target->point();
|
point_item->point_set()->push_back((*begin)->point());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Edge_graph::vertex_descriptor tgt=it_find->second;
|
|
||||||
boost::add_edge(src, tgt, edge_graph);
|
|
||||||
}
|
}
|
||||||
|
//Create Polyline Item from Selected Edges
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
|
if(!selection_item) {
|
||||||
|
print_message("Error: there is no selected polyhedron selection item!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(selection_item->selected_edges.empty()) {
|
||||||
|
print_message("Error: there is no selected edge in polyhedron selection item!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Scene_polylines_item* polyline_item = new Scene_polylines_item();
|
||||||
|
polyline_item->setName(QString("%1-edges").arg(selection_item->name()));
|
||||||
|
|
||||||
Polyline_visitor<Edge_graph> polyline_visitor(polyline_item, edge_graph);
|
typedef boost::adjacency_list < boost::listS,
|
||||||
CGAL::split_graph_into_polylines( edge_graph,
|
boost::vecS,
|
||||||
polyline_visitor,
|
boost::undirectedS,
|
||||||
Is_terminal() );
|
Kernel::Point_3 > Edge_graph;
|
||||||
scene->setSelectedItem( scene->addItem(polyline_item) );
|
typedef Polyhedron::Vertex_handle Vertex_handle;
|
||||||
scene->itemChanged(polyline_item);
|
Edge_graph edge_graph;
|
||||||
|
std::map<Vertex_handle, Edge_graph::vertex_descriptor> p2vd;
|
||||||
|
std::map<Vertex_handle, Edge_graph::vertex_descriptor>::iterator it_find;
|
||||||
|
bool insert_OK;
|
||||||
|
|
||||||
|
for(Scene_polyhedron_selection_item::Selection_set_edge::iterator begin = selection_item->selected_edges.begin();
|
||||||
|
begin != selection_item->selected_edges.end(); ++begin)
|
||||||
|
{
|
||||||
|
Vertex_handle source = begin->halfedge()->opposite()->vertex();
|
||||||
|
boost::tie(it_find, insert_OK)
|
||||||
|
= p2vd.insert(std::make_pair(source, Edge_graph::vertex_descriptor()));
|
||||||
|
if (insert_OK)
|
||||||
|
{
|
||||||
|
it_find->second = add_vertex(edge_graph);
|
||||||
|
edge_graph[it_find->second] = source->point();
|
||||||
|
}
|
||||||
|
Edge_graph::vertex_descriptor src=it_find->second;
|
||||||
|
|
||||||
|
Vertex_handle target = begin->halfedge()->vertex();
|
||||||
|
boost::tie(it_find, insert_OK)
|
||||||
|
= p2vd.insert(std::make_pair(target, Edge_graph::vertex_descriptor()));
|
||||||
|
if (insert_OK)
|
||||||
|
{
|
||||||
|
it_find->second = add_vertex(edge_graph);
|
||||||
|
edge_graph[it_find->second] = target->point();
|
||||||
|
}
|
||||||
|
Edge_graph::vertex_descriptor tgt=it_find->second;
|
||||||
|
boost::add_edge(src, tgt, edge_graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Polyline_visitor<Edge_graph> polyline_visitor(polyline_item, edge_graph);
|
||||||
|
CGAL::split_graph_into_polylines( edge_graph,
|
||||||
|
polyline_visitor,
|
||||||
|
Is_terminal() );
|
||||||
|
scene->setSelectedItem( scene->addItem(polyline_item) );
|
||||||
|
scene->itemChanged(polyline_item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Create Polyhedron Item from Selected Facets
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
|
if(!selection_item) {
|
||||||
|
print_message("Error: there is no selected polyhedron selection item!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene_polyhedron_item* poly_item = new Scene_polyhedron_item();
|
||||||
|
if(selection_item->export_selected_facets_as_polyhedron(poly_item->polyhedron())) {
|
||||||
|
poly_item->setName(QString("%1-facets").arg(selection_item->name()));
|
||||||
|
poly_item->invalidateOpenGLBuffers(); // for init()
|
||||||
|
scene->setSelectedItem( scene->addItem(poly_item) );
|
||||||
|
scene->itemChanged(poly_item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete poly_item;
|
||||||
|
print_message("Error: polyhedron item is not created!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Erase Selected Facets from Polyhedron Item
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
|
if(!selection_item) {
|
||||||
|
print_message("Error: there is no selected polyhedron selection item!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selection_item->erase_selected_facets();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Keep connected components of Selected Facets
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
|
if (!selection_item) {
|
||||||
|
print_message("Error: there is no selected polyhedron selection item!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selection_item->keep_connected_components();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_Erase_selected_facets_button_clicked() {
|
void on_ModeBox_changed(int index)
|
||||||
|
{
|
||||||
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
if(!selection_item) {
|
selection_item->on_Ctrlz_pressed();
|
||||||
print_message("Error: there is no selected polyhedron selection item!");
|
last_mode = index;
|
||||||
return;
|
switch(index)
|
||||||
|
{
|
||||||
|
//Selection mode
|
||||||
|
case 0:
|
||||||
|
ui_widget.selection_groupBox->setVisible(true);
|
||||||
|
ui_widget.edition_groupBox->setVisible(false);
|
||||||
|
Q_EMIT set_operation_mode(-1);
|
||||||
|
on_Selection_type_combo_box_changed(ui_widget.Selection_type_combo_box->currentIndex());
|
||||||
|
break;
|
||||||
|
//Edition mode
|
||||||
|
case 1:
|
||||||
|
ui_widget.selection_groupBox->setVisible(false);
|
||||||
|
ui_widget.edition_groupBox->setVisible(true);
|
||||||
|
Q_EMIT save_handleType();
|
||||||
|
Q_EMIT set_operation_mode(ui_widget.editionBox->currentIndex());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
selection_item->erase_selected_facets();
|
|
||||||
}
|
}
|
||||||
void on_Keep_connected_components_button_clicked() {
|
|
||||||
|
void on_editionBox_changed(int mode )
|
||||||
|
{
|
||||||
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
if (!selection_item) {
|
selection_item->on_Ctrlz_pressed();
|
||||||
print_message("Error: there is no selected polyhedron selection item!");
|
if(ui_widget.modeBox->currentIndex() == 0)
|
||||||
return;
|
{
|
||||||
|
Q_EMIT set_operation_mode(-1);
|
||||||
}
|
}
|
||||||
selection_item->keep_connected_components();
|
else
|
||||||
}
|
{
|
||||||
void on_Create_polyhedron_item_button_clicked() {
|
Q_EMIT set_operation_mode(mode);
|
||||||
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
|
||||||
if(!selection_item) {
|
|
||||||
print_message("Error: there is no selected polyhedron selection item!");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_polyhedron_item* poly_item = new Scene_polyhedron_item();
|
|
||||||
if(selection_item->export_selected_facets_as_polyhedron(poly_item->polyhedron())) {
|
|
||||||
poly_item->setName(QString("%1-facets").arg(selection_item->name()));
|
|
||||||
poly_item->invalidateOpenGLBuffers(); // for init()
|
|
||||||
scene->setSelectedItem( scene->addItem(poly_item) );
|
|
||||||
scene->itemChanged(poly_item);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete poly_item;
|
|
||||||
print_message("Error: polyhedron item is not created!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_Select_sharp_edges_button_clicked() {
|
void on_Select_sharp_edges_button_clicked() {
|
||||||
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
Scene_polyhedron_selection_item* selection_item = getSelectedItem<Scene_polyhedron_selection_item>();
|
||||||
if (!selection_item) {
|
if (!selection_item) {
|
||||||
|
|
@ -431,6 +508,7 @@ private:
|
||||||
Ui::Selection ui_widget;
|
Ui::Selection ui_widget;
|
||||||
typedef std::multimap<Scene_polyhedron_item*, Scene_polyhedron_selection_item*> Selection_item_map;
|
typedef std::multimap<Scene_polyhedron_item*, Scene_polyhedron_selection_item*> Selection_item_map;
|
||||||
Selection_item_map selection_item_map;
|
Selection_item_map selection_item_map;
|
||||||
|
int last_mode;
|
||||||
}; // end Polyhedron_demo_selection_plugin
|
}; // end Polyhedron_demo_selection_plugin
|
||||||
|
|
||||||
//Q_EXPORT_PLUGIN2(Polyhedron_demo_selection_plugin, Polyhedron_demo_selection_plugin)
|
//Q_EXPORT_PLUGIN2(Polyhedron_demo_selection_plugin, Polyhedron_demo_selection_plugin)
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>455</width>
|
<width>479</width>
|
||||||
<height>528</height>
|
<height>606</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|
@ -16,136 +16,379 @@
|
||||||
<widget class="QWidget" name="dockWidgetContents">
|
<widget class="QWidget" name="dockWidgetContents">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="modeBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Selection Mode</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Edition Mode</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="selection_groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Selection by Type</string>
|
<string>Selection Operations</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="text">
|
<property name="title">
|
||||||
<string>Selection Type :</string>
|
<string>Selection by Type</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Selection Type :</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="Selection_type_combo_box">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Vertex</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Facet</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Edge</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Selected components (facet)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="Insertion_radio_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insertion</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="Removal_radio_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Removal</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Brush &size:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>Brush_size_spin_box</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="Brush_size_spin_box"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="Select_all_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string extracomment="Select all simplices of Selection Type"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select &All</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="Inverse_selection_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string extracomment="Invert selection for Selection Type"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Invert Selection</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="Clear_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string extracomment="Clear selection for Selection Type"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>&Clear</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="verticalSpacer_3">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>20</width>
|
||||||
<height>20</height>
|
<height>40</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="Selection_type_combo_box">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
<string>Vertex</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Facet</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Edge</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Selected components (facet)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="Insertion_radio_button">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Insertion</string>
|
<string>Isolated &Component Size:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="buddy">
|
||||||
<bool>true</bool>
|
<cstring>Threshold_size_spin_box</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="Removal_radio_button">
|
<widget class="QSpinBox" name="Threshold_size_spin_box">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999999999</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="Get_minimum_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Removal</string>
|
<string>&Get Minimum</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
<widget class="QPushButton" name="Select_isolated_components_button">
|
||||||
<item>
|
<property name="text">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
<string>Select &Isolated Components Below Threshold</string>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QLabel" name="label">
|
</widget>
|
||||||
<property name="text">
|
|
||||||
<string>Brush &size:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>Brush_size_spin_box</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="Brush_size_spin_box"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<spacer name="verticalSpacer_1">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="Select_all_button">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="toolTip">
|
|
||||||
<string extracomment="Select all simplices of Selection Type"/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Select &All</string>
|
<string>Sharp edges angle:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="Inverse_selection_button">
|
<widget class="QSpinBox" name="Sharp_angle_spinbox">
|
||||||
<property name="toolTip">
|
<property name="sizePolicy">
|
||||||
<string extracomment="Invert selection for Selection Type"/>
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="maximum">
|
||||||
<string>Invert Selection</string>
|
<number>180</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>60</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="Clear_button">
|
<widget class="QPushButton" name="Select_sharp_edges_button">
|
||||||
<property name="toolTip">
|
|
||||||
<string extracomment="Clear selection for Selection Type"/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Clear</string>
|
<string>Select</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Expand or reduce selection:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="Expand_reduce_spin_box">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-50</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="Expand_reduce_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_13" stretch="1,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="operationsBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create Point Set Item from Selected Vertices</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create Polyline Item from Selected Edges</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create Polyhedron Item from Selected Facets</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Erase Selected Facets from Polyhedron Item</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Keep Connected Components of Selected Facets</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="validateButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Validate</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -156,216 +399,6 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Isolated &Component Size:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>Threshold_size_spin_box</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="Threshold_size_spin_box">
|
|
||||||
<property name="maximum">
|
|
||||||
<number>999999999</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Get_minimum_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Get Minimum</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Select_isolated_components_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Select &Isolated Components Below Threshold</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sharp edges angle:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="Sharp_angle_spinbox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>180</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>60</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Select_sharp_edges_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Select</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_1">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Expand or reduce selection:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="Expand_reduce_spin_box">
|
|
||||||
<property name="minimum">
|
|
||||||
<number>-50</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>50</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Expand_reduce_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Apply</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_5">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Create_point_set_item_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Create Point Set Item from Selected Vertices</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Create_polyline_item_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Create Polyline Item from Selected Edges</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Create_polyhedron_item_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Create Polyhedron Item from Selected Facets</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Erase_selected_facets_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Erase Selected Facets from Polyhedron Item</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="Keep_connected_components_button">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string extracomment="from selected facets"/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Keep connected components of Selected Facets</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -393,6 +426,94 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="edition_groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Editions Operations</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9" stretch="0,1,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="editionBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Join vertex</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Split vertex</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Split edges</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Join face</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Split face</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Collapse edge</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Flip edge</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add center vertex</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove center vertex</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add vertex and face to border (Advanced)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add face to border (Advanced)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="instructionsLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Instructions
|
||||||
|
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ctrl+Z to cancel the temporary selection.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ typedef boost::graph_traits<Polyhedron>::face_descriptor face_descriptor;
|
||||||
typedef boost::graph_traits<Polyhedron>::halfedge_descriptor halfedge_descriptor;
|
typedef boost::graph_traits<Polyhedron>::halfedge_descriptor halfedge_descriptor;
|
||||||
typedef boost::graph_traits<Polyhedron>::edge_descriptor edge_descriptor;
|
typedef boost::graph_traits<Polyhedron>::edge_descriptor edge_descriptor;
|
||||||
class Scene_spheres_item;
|
class Scene_spheres_item;
|
||||||
|
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||||
struct Array_based_vertex_point_map
|
struct Array_based_vertex_point_map
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ typedef CGAL::Triangulation_face_base_with_info_2<Face_info,
|
||||||
P_traits> Fb1;
|
P_traits> Fb1;
|
||||||
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
||||||
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||||||
typedef CGAL::No_intersection_tag Itag;
|
typedef CGAL::Exact_predicates_tag Itag;
|
||||||
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits,
|
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits,
|
||||||
TDS,
|
TDS,
|
||||||
Itag> CDTbase;
|
Itag> CDTbase;
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ typedef CGAL::Triangulation_face_base_with_info_2<Face_info,
|
||||||
P_traits> Fb1;
|
P_traits> Fb1;
|
||||||
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
||||||
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||||||
typedef CGAL::No_intersection_tag Itag;
|
typedef CGAL::Exact_predicates_tag Itag;
|
||||||
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits,
|
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits,
|
||||||
TDS,
|
TDS,
|
||||||
Itag> CDTbase;
|
Itag> CDTbase;
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
#include <CGAL/AABB_tree.h>
|
#include <CGAL/AABB_tree.h>
|
||||||
#include <CGAL/AABB_traits.h>
|
#include <CGAL/AABB_traits.h>
|
||||||
#include <CGAL/AABB_face_graph_triangle_primitive.h>
|
|
||||||
|
|
||||||
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
||||||
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
||||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||||
|
|
@ -39,33 +37,190 @@
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||||
|
//Used to triangulate the AABB_Tree
|
||||||
|
class Primitive
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// types
|
||||||
|
typedef Polyhedron::Facet_iterator Id; // Id type
|
||||||
|
typedef Kernel::Point_3 Point; // point type
|
||||||
|
typedef Kernel::Triangle_3 Datum; // datum type
|
||||||
|
|
||||||
|
private:
|
||||||
|
// member data
|
||||||
|
Id m_it; // iterator
|
||||||
|
Datum m_datum; // 3D triangle
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
public:
|
||||||
|
Primitive() {}
|
||||||
|
Primitive(Datum triangle, Id it)
|
||||||
|
: m_it(it), m_datum(triangle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Id& id() { return m_it; }
|
||||||
|
const Id& id() const { return m_it; }
|
||||||
|
Datum& datum() { return m_datum; }
|
||||||
|
const Datum& datum() const { return m_datum; }
|
||||||
|
|
||||||
|
/// Returns a point on the primitive
|
||||||
|
Point reference_point() const { return m_datum.vertex(0); }
|
||||||
|
};
|
||||||
|
|
||||||
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
|
|
||||||
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_traits;
|
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_traits;
|
||||||
typedef CGAL::AABB_tree<AABB_traits> Input_facets_AABB_tree;
|
typedef CGAL::AABB_tree<AABB_traits> Input_facets_AABB_tree;
|
||||||
const char* aabb_property_name = "Scene_polyhedron_item aabb tree";
|
const char* aabb_property_name = "Scene_polyhedron_item aabb tree";
|
||||||
|
|
||||||
Input_facets_AABB_tree* get_aabb_tree(Scene_polyhedron_item* item)
|
typedef Polyhedron::Traits Traits;
|
||||||
|
typedef Polyhedron::Facet Facet;
|
||||||
|
typedef CGAL::Triangulation_2_projection_traits_3<Traits> P_traits;
|
||||||
|
typedef Polyhedron::Halfedge_handle Halfedge_handle;
|
||||||
|
struct Face_info {
|
||||||
|
Polyhedron::Halfedge_handle e[3];
|
||||||
|
bool is_external;
|
||||||
|
};
|
||||||
|
typedef CGAL::Triangulation_vertex_base_with_info_2<Halfedge_handle,
|
||||||
|
P_traits> Vb;
|
||||||
|
typedef CGAL::Triangulation_face_base_with_info_2<Face_info,
|
||||||
|
P_traits> Fb1;
|
||||||
|
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
||||||
|
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||||||
|
typedef CGAL::Exact_predicates_tag Itag;
|
||||||
|
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits,
|
||||||
|
TDS,
|
||||||
|
Itag> CDTbase;
|
||||||
|
typedef CGAL::Constrained_triangulation_plus_2<CDTbase> CDT;
|
||||||
|
|
||||||
|
//Make sure all the facets are triangles
|
||||||
|
typedef Polyhedron::Traits Kernel;
|
||||||
|
typedef Kernel::Point_3 Point;
|
||||||
|
typedef Kernel::Vector_3 Vector;
|
||||||
|
typedef Polyhedron::Halfedge_around_facet_circulator HF_circulator;
|
||||||
|
typedef boost::graph_traits<Polyhedron>::face_descriptor face_descriptor;
|
||||||
|
QList<Kernel::Triangle_3> triangulate_primitive(Polyhedron::Facet_iterator fit,
|
||||||
|
Traits::Vector_3 normal)
|
||||||
{
|
{
|
||||||
QVariant aabb_tree_property = item->property(aabb_property_name);
|
//The output list
|
||||||
if(aabb_tree_property.isValid()) {
|
QList<Kernel::Triangle_3> res;
|
||||||
void* ptr = aabb_tree_property.value<void*>();
|
//check if normal contains NaN values
|
||||||
return static_cast<Input_facets_AABB_tree*>(ptr);
|
if (normal.x() != normal.x() || normal.y() != normal.y() || normal.z() != normal.z())
|
||||||
|
{
|
||||||
|
qDebug()<<"Warning in triangulation of the selection item: normal contains NaN values and is not valid.";
|
||||||
|
return QList<Kernel::Triangle_3>();
|
||||||
|
}
|
||||||
|
P_traits cdt_traits(normal);
|
||||||
|
CDT cdt(cdt_traits);
|
||||||
|
|
||||||
|
Facet::Halfedge_around_facet_circulator
|
||||||
|
he_circ = fit->facet_begin(),
|
||||||
|
he_circ_end(he_circ);
|
||||||
|
|
||||||
|
// Iterates on the vector of facet handles
|
||||||
|
typedef boost::graph_traits<Polyhedron>::vertex_descriptor vertex_descriptor;
|
||||||
|
boost::container::flat_map<CDT::Vertex_handle, vertex_descriptor> v2v;
|
||||||
|
CDT::Vertex_handle previous, first;
|
||||||
|
do {
|
||||||
|
CDT::Vertex_handle vh = cdt.insert(he_circ->vertex()->point());
|
||||||
|
v2v.insert(std::make_pair(vh, he_circ->vertex()));
|
||||||
|
if(first == 0) {
|
||||||
|
first = vh;
|
||||||
}
|
}
|
||||||
else {
|
vh->info() = he_circ;
|
||||||
Polyhedron* poly = item->polyhedron();
|
if(previous != 0 && previous != vh) {
|
||||||
if(poly) {
|
cdt.insert_constraint(previous, vh);
|
||||||
Input_facets_AABB_tree* tree =
|
}
|
||||||
new Input_facets_AABB_tree(faces(*poly).first,
|
previous = vh;
|
||||||
faces(*poly).second,
|
} while( ++he_circ != he_circ_end );
|
||||||
*poly);
|
cdt.insert_constraint(previous, first);
|
||||||
item->setProperty(aabb_property_name,
|
// sets mark is_external
|
||||||
QVariant::fromValue<void*>(tree));
|
for(CDT::All_faces_iterator
|
||||||
return tree;
|
fit2 = cdt.all_faces_begin(),
|
||||||
|
end = cdt.all_faces_end();
|
||||||
|
fit2 != end; ++fit2)
|
||||||
|
{
|
||||||
|
fit2->info().is_external = false;
|
||||||
|
}
|
||||||
|
//check if the facet is external or internal
|
||||||
|
std::queue<CDT::Face_handle> face_queue;
|
||||||
|
face_queue.push(cdt.infinite_vertex()->face());
|
||||||
|
while(! face_queue.empty() ) {
|
||||||
|
CDT::Face_handle fh = face_queue.front();
|
||||||
|
face_queue.pop();
|
||||||
|
if(fh->info().is_external) continue;
|
||||||
|
fh->info().is_external = true;
|
||||||
|
for(int i = 0; i <3; ++i) {
|
||||||
|
if(!cdt.is_constrained(std::make_pair(fh, i)))
|
||||||
|
{
|
||||||
|
face_queue.push(fh->neighbor(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//iterates on the internal faces to add the vertices to the positions
|
||||||
|
//and the normals to the appropriate vectors
|
||||||
|
for(CDT::Finite_faces_iterator
|
||||||
|
ffit = cdt.finite_faces_begin(),
|
||||||
|
end = cdt.finite_faces_end();
|
||||||
|
ffit != end; ++ffit)
|
||||||
|
{
|
||||||
|
if(ffit->info().is_external)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
res << Kernel::Triangle_3(ffit->vertex(0)->point(),
|
||||||
|
ffit->vertex(1)->point(),
|
||||||
|
ffit->vertex(2)->point());
|
||||||
|
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void* Scene_polyhedron_item::get_aabb_tree()
|
||||||
|
{
|
||||||
|
QVariant aabb_tree_property = this->property(aabb_property_name);
|
||||||
|
if(aabb_tree_property.isValid()) {
|
||||||
|
void* ptr = aabb_tree_property.value<void*>();
|
||||||
|
return static_cast<Input_facets_AABB_tree*>(ptr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Polyhedron* poly = this->polyhedron();
|
||||||
|
if(poly) {
|
||||||
|
|
||||||
|
Input_facets_AABB_tree* tree =
|
||||||
|
new Input_facets_AABB_tree();
|
||||||
|
typedef Polyhedron::Traits Kernel;
|
||||||
|
int index =0;
|
||||||
|
Q_FOREACH( Polyhedron::Facet_iterator f, faces(*poly))
|
||||||
|
{
|
||||||
|
if(!f->is_triangle())
|
||||||
|
{
|
||||||
|
Traits::Vector_3 normal = f->plane().orthogonal_vector(); //initialized in compute_normals_and_vertices
|
||||||
|
index +=3;
|
||||||
|
Q_FOREACH(Kernel::Triangle_3 triangle, triangulate_primitive(f,normal))
|
||||||
|
{
|
||||||
|
Primitive primitive(triangle, f);
|
||||||
|
tree->insert(primitive);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else return 0;
|
else
|
||||||
|
{
|
||||||
|
Kernel::Triangle_3 triangle(
|
||||||
|
f->halfedge()->vertex()->point(),
|
||||||
|
f->halfedge()->next()->vertex()->point(),
|
||||||
|
f->halfedge()->next()->next()->vertex()->point()
|
||||||
|
);
|
||||||
|
Primitive primitive(triangle, f);
|
||||||
|
tree->insert(primitive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->setProperty(aabb_property_name,
|
||||||
|
QVariant::fromValue<void*>(tree));
|
||||||
|
return tree;
|
||||||
}
|
}
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_aabb_tree(Scene_polyhedron_item* item)
|
void delete_aabb_tree(Scene_polyhedron_item* item)
|
||||||
|
|
@ -91,38 +246,15 @@ void push_back_xyz(const TypeWithXYZ& t,
|
||||||
vector.push_back(t.z());
|
vector.push_back(t.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef Polyhedron::Traits Traits;
|
|
||||||
typedef Polyhedron::Facet Facet;
|
|
||||||
typedef CGAL::Triangulation_2_projection_traits_3<Traits> P_traits;
|
|
||||||
typedef Polyhedron::Halfedge_handle Halfedge_handle;
|
|
||||||
struct Face_info {
|
|
||||||
Polyhedron::Halfedge_handle e[3];
|
|
||||||
bool is_external;
|
|
||||||
};
|
|
||||||
typedef CGAL::Triangulation_vertex_base_with_info_2<Halfedge_handle,
|
|
||||||
P_traits> Vb;
|
|
||||||
typedef CGAL::Triangulation_face_base_with_info_2<Face_info,
|
|
||||||
P_traits> Fb1;
|
|
||||||
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
|
||||||
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
|
||||||
typedef CGAL::No_intersection_tag Itag;
|
|
||||||
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits,
|
|
||||||
TDS,
|
|
||||||
Itag> CDTbase;
|
|
||||||
typedef CGAL::Constrained_triangulation_plus_2<CDTbase> CDT;
|
|
||||||
|
|
||||||
//Make sure all the facets are triangles
|
//Make sure all the facets are triangles
|
||||||
|
template<typename VertexNormalPmap>
|
||||||
template<typename FaceNormalPmap, typename VertexNormalPmap>
|
|
||||||
void
|
void
|
||||||
Scene_polyhedron_item::triangulate_facet(Facet_iterator fit,
|
Scene_polyhedron_item::triangulate_facet(Facet_iterator fit,
|
||||||
const FaceNormalPmap& fnmap,
|
const Traits::Vector_3& normal,
|
||||||
const VertexNormalPmap& vnmap,
|
const VertexNormalPmap& vnmap,
|
||||||
const bool colors_only) const
|
const bool colors_only) const
|
||||||
{
|
{
|
||||||
//Computes the normal of the facet
|
|
||||||
Traits::Vector_3 normal = get(fnmap, fit);
|
|
||||||
|
|
||||||
//check if normal contains NaN values
|
//check if normal contains NaN values
|
||||||
if (normal.x() != normal.x() || normal.y() != normal.y() || normal.z() != normal.z())
|
if (normal.x() != normal.x() || normal.y() != normal.y() || normal.z() != normal.z())
|
||||||
{
|
{
|
||||||
|
|
@ -408,11 +540,11 @@ Scene_polyhedron_item::compute_normals_and_vertices(const bool colors_only) cons
|
||||||
{
|
{
|
||||||
if (f == boost::graph_traits<Polyhedron>::null_face())
|
if (f == boost::graph_traits<Polyhedron>::null_face())
|
||||||
continue;
|
continue;
|
||||||
|
Vector nf = get(nf_pmap, f);
|
||||||
|
f->plane() = Kernel::Plane_3(f->halfedge()->vertex()->point(), nf);
|
||||||
if(is_triangle(f->halfedge(),*poly))
|
if(is_triangle(f->halfedge(),*poly))
|
||||||
{
|
{
|
||||||
const int this_patch_id = f->patch_id();
|
const int this_patch_id = f->patch_id();
|
||||||
Vector n = get(nf_pmap, f);
|
|
||||||
HF_circulator he = f->facet_begin();
|
HF_circulator he = f->facet_begin();
|
||||||
HF_circulator end = he;
|
HF_circulator end = he;
|
||||||
CGAL_For_all(he,end)
|
CGAL_For_all(he,end)
|
||||||
|
|
@ -427,7 +559,7 @@ Scene_polyhedron_item::compute_normals_and_vertices(const bool colors_only) cons
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If Flat shading:1 normal per polygon added once per vertex
|
// If Flat shading:1 normal per polygon added once per vertex
|
||||||
push_back_xyz(n, normals_flat);
|
push_back_xyz(nf, normals_flat);
|
||||||
|
|
||||||
//// If Gouraud shading: 1 normal per vertex
|
//// If Gouraud shading: 1 normal per vertex
|
||||||
Vector nv = get(nv_pmap, he->vertex());
|
Vector nv = get(nv_pmap, he->vertex());
|
||||||
|
|
@ -454,8 +586,6 @@ Scene_polyhedron_item::compute_normals_and_vertices(const bool colors_only) cons
|
||||||
if (colors_only)
|
if (colors_only)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Vector nf = get(nf_pmap, f);
|
|
||||||
|
|
||||||
//1st half-quad
|
//1st half-quad
|
||||||
Point p0 = f->halfedge()->vertex()->point();
|
Point p0 = f->halfedge()->vertex()->point();
|
||||||
Point p1 = f->halfedge()->next()->vertex()->point();
|
Point p1 = f->halfedge()->next()->vertex()->point();
|
||||||
|
|
@ -512,7 +642,7 @@ Scene_polyhedron_item::compute_normals_and_vertices(const bool colors_only) cons
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
triangulate_facet(f, nf_pmap, nv_pmap, colors_only);
|
triangulate_facet(f, nf, nv_pmap, colors_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -576,6 +706,7 @@ Scene_polyhedron_item::Scene_polyhedron_item()
|
||||||
nb_lines = 0;
|
nb_lines = 0;
|
||||||
nb_f_lines = 0;
|
nb_f_lines = 0;
|
||||||
invalidate_stats();
|
invalidate_stats();
|
||||||
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p)
|
Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p)
|
||||||
|
|
@ -1011,107 +1142,94 @@ Scene_polyhedron_item::select(double orig_x,
|
||||||
double dir_y,
|
double dir_y,
|
||||||
double dir_z)
|
double dir_z)
|
||||||
{
|
{
|
||||||
if(facet_picking_m) {
|
void* vertex_to_emit = 0;
|
||||||
typedef Input_facets_AABB_tree Tree;
|
if(facet_picking_m) {
|
||||||
typedef Tree::Object_and_primitive_id Object_and_primitive_id;
|
typedef Input_facets_AABB_tree Tree;
|
||||||
|
|
||||||
Tree* aabb_tree = get_aabb_tree(this);
|
|
||||||
if(aabb_tree) {
|
|
||||||
const Kernel::Point_3 ray_origin(orig_x, orig_y, orig_z);
|
|
||||||
const Kernel::Vector_3 ray_dir(dir_x, dir_y, dir_z);
|
|
||||||
const Kernel::Ray_3 ray(ray_origin, ray_dir);
|
|
||||||
typedef std::list<Object_and_primitive_id> Intersections;
|
|
||||||
Intersections intersections;
|
|
||||||
aabb_tree->all_intersections(ray, std::back_inserter(intersections));
|
|
||||||
Intersections::iterator closest = intersections.begin();
|
|
||||||
if(closest != intersections.end()) {
|
|
||||||
const Kernel::Point_3* closest_point =
|
|
||||||
CGAL::object_cast<Kernel::Point_3>(&closest->first);
|
|
||||||
for(Intersections::iterator
|
|
||||||
it = boost::next(intersections.begin()),
|
|
||||||
end = intersections.end();
|
|
||||||
it != end; ++it)
|
|
||||||
{
|
|
||||||
if(! closest_point) {
|
|
||||||
closest = it;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const Kernel::Point_3* it_point =
|
|
||||||
CGAL::object_cast<Kernel::Point_3>(&it->first);
|
|
||||||
if(it_point &&
|
|
||||||
(ray_dir * (*it_point - *closest_point)) < 0)
|
|
||||||
{
|
|
||||||
closest = it;
|
|
||||||
closest_point = it_point;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(closest_point) {
|
|
||||||
Polyhedron::Facet_handle selected_fh = closest->second;
|
|
||||||
|
|
||||||
// The computation of the nearest vertex may be costly. Only
|
Tree* aabb_tree = static_cast<Input_facets_AABB_tree*>(get_aabb_tree());
|
||||||
// do it if some objects are connected to the signal
|
if(aabb_tree) {
|
||||||
// 'selected_vertex'.
|
const Kernel::Point_3 ray_origin(orig_x, orig_y, orig_z);
|
||||||
if(QObject::receivers(SIGNAL(selected_vertex(void*))) > 0)
|
const Kernel::Vector_3 ray_dir(dir_x, dir_y, dir_z);
|
||||||
{
|
const Kernel::Ray_3 ray(ray_origin, ray_dir);
|
||||||
Polyhedron::Halfedge_around_facet_circulator
|
const boost::optional< Tree::Intersection_and_primitive_id<Kernel::Ray_3>::Type >
|
||||||
he_it = selected_fh->facet_begin(),
|
variant = aabb_tree->first_intersection(ray);
|
||||||
around_end = he_it;
|
if(variant)
|
||||||
|
{
|
||||||
|
const Kernel::Point_3* closest_point = boost::get<Kernel::Point_3>( &variant->first );
|
||||||
|
if(closest_point) {
|
||||||
|
Polyhedron::Facet_handle selected_fh = variant->second;
|
||||||
|
// The computation of the nearest vertex may be costly. Only
|
||||||
|
// do it if some objects are connected to the signal
|
||||||
|
// 'selected_vertex'.
|
||||||
|
if(QObject::receivers(SIGNAL(selected_vertex(void*))) > 0)
|
||||||
|
{
|
||||||
|
Polyhedron::Halfedge_around_facet_circulator
|
||||||
|
he_it = selected_fh->facet_begin(),
|
||||||
|
around_end = he_it;
|
||||||
|
|
||||||
Polyhedron::Vertex_handle v = he_it->vertex(), nearest_v = v;
|
Polyhedron::Vertex_handle v = he_it->vertex(), nearest_v = v;
|
||||||
|
|
||||||
Kernel::FT sq_dist = CGAL::squared_distance(*closest_point,
|
Kernel::FT sq_dist = CGAL::squared_distance(*closest_point,
|
||||||
v->point());
|
v->point());
|
||||||
while(++he_it != around_end) {
|
while(++he_it != around_end) {
|
||||||
v = he_it->vertex();
|
v = he_it->vertex();
|
||||||
Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point,
|
Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point,
|
||||||
v->point());
|
v->point());
|
||||||
if(new_sq_dist < sq_dist) {
|
if(new_sq_dist < sq_dist) {
|
||||||
sq_dist = new_sq_dist;
|
sq_dist = new_sq_dist;
|
||||||
nearest_v = v;
|
nearest_v = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//bottleneck
|
vertex_to_emit = (void*)(&*nearest_v);
|
||||||
Q_EMIT selected_vertex((void*)(&*nearest_v));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(QObject::receivers(SIGNAL(selected_edge(void*))) > 0
|
if(QObject::receivers(SIGNAL(selected_edge(void*))) > 0
|
||||||
|| QObject::receivers(SIGNAL(selected_halfedge(void*))) > 0)
|
|| QObject::receivers(SIGNAL(selected_halfedge(void*))) > 0)
|
||||||
{
|
{
|
||||||
Polyhedron::Halfedge_around_facet_circulator
|
Polyhedron::Halfedge_around_facet_circulator
|
||||||
he_it = selected_fh->facet_begin(),
|
he_it = selected_fh->facet_begin(),
|
||||||
around_end = he_it;
|
around_end = he_it;
|
||||||
|
|
||||||
Polyhedron::Halfedge_handle nearest_h = he_it;
|
Polyhedron::Halfedge_handle nearest_h = he_it;
|
||||||
Kernel::FT sq_dist = CGAL::squared_distance(*closest_point,
|
Kernel::FT sq_dist = CGAL::squared_distance(*closest_point,
|
||||||
Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point()));
|
Kernel::Segment_3(he_it->vertex()->point(),
|
||||||
|
he_it->opposite()->
|
||||||
|
vertex()->
|
||||||
|
point()));
|
||||||
|
|
||||||
while(++he_it != around_end) {
|
while(++he_it != around_end)
|
||||||
Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point,
|
{
|
||||||
Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point()));
|
Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point,
|
||||||
if(new_sq_dist < sq_dist) {
|
Kernel::Segment_3(he_it->vertex()->point(),
|
||||||
sq_dist = new_sq_dist;
|
he_it->opposite()->
|
||||||
nearest_h = he_it;
|
vertex()->
|
||||||
}
|
point()));
|
||||||
}
|
if(new_sq_dist < sq_dist) {
|
||||||
|
sq_dist = new_sq_dist;
|
||||||
|
nearest_h = he_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Q_EMIT selected_halfedge((void*)(&*nearest_h));
|
Q_EMIT selected_halfedge((void*)(&*nearest_h));
|
||||||
Q_EMIT selected_edge((void*)(std::min)(&*nearest_h, &*nearest_h->opposite()));
|
Q_EMIT selected_edge((void*)(std::min)(&*nearest_h, &*nearest_h->opposite()));
|
||||||
}
|
}
|
||||||
|
Q_EMIT selected_vertex(vertex_to_emit);
|
||||||
Q_EMIT selected_facet((void*)(&*selected_fh));
|
Q_EMIT selected_facet((void*)(&*selected_fh));
|
||||||
if(erase_next_picked_facet_m) {
|
|
||||||
polyhedron()->erase_facet(selected_fh->halfedge());
|
if(erase_next_picked_facet_m) {
|
||||||
polyhedron()->normalize_border();
|
polyhedron()->erase_facet(selected_fh->halfedge());
|
||||||
//set_erase_next_picked_facet(false);
|
polyhedron()->normalize_border();
|
||||||
invalidateOpenGLBuffers();
|
//set_erase_next_picked_facet(false);
|
||||||
|
invalidateOpenGLBuffers();
|
||||||
Q_EMIT itemChanged();
|
Q_EMIT itemChanged();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Base::select(orig_x, orig_y, orig_z, dir_x, dir_y, dir_z);
|
}
|
||||||
|
Base::select(orig_x, orig_y, orig_z, dir_x, dir_y, dir_z);
|
||||||
|
Q_EMIT selection_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene_polyhedron_item::update_vertex_indices()
|
void Scene_polyhedron_item::update_vertex_indices()
|
||||||
|
|
|
||||||
|
|
@ -109,13 +109,13 @@ public Q_SLOTS:
|
||||||
double dir_x,
|
double dir_x,
|
||||||
double dir_y,
|
double dir_y,
|
||||||
double dir_z);
|
double dir_z);
|
||||||
|
|
||||||
void update_vertex_indices();
|
void update_vertex_indices();
|
||||||
void update_facet_indices();
|
void update_facet_indices();
|
||||||
void update_halfedge_indices();
|
void update_halfedge_indices();
|
||||||
void invalidate_aabb_tree();
|
void invalidate_aabb_tree();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
void selection_done();
|
||||||
void selected_vertex(void*);
|
void selected_vertex(void*);
|
||||||
void selected_facet(void*);
|
void selected_facet(void*);
|
||||||
void selected_edge(void*);
|
void selected_edge(void*);
|
||||||
|
|
@ -149,7 +149,7 @@ private:
|
||||||
Edges,
|
Edges,
|
||||||
Feature_edges,
|
Feature_edges,
|
||||||
Gouraud_Facets,
|
Gouraud_Facets,
|
||||||
NbOfVaos = Gouraud_Facets+1
|
NbOfVaos
|
||||||
};
|
};
|
||||||
enum VBOs {
|
enum VBOs {
|
||||||
Facets_vertices = 0,
|
Facets_vertices = 0,
|
||||||
|
|
@ -159,7 +159,7 @@ private:
|
||||||
Feature_edges_vertices,
|
Feature_edges_vertices,
|
||||||
Edges_color,
|
Edges_color,
|
||||||
Facets_normals_gouraud,
|
Facets_normals_gouraud,
|
||||||
NbOfVbos = Facets_normals_gouraud+1
|
NbOfVbos
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable std::vector<float> positions_lines;
|
mutable std::vector<float> positions_lines;
|
||||||
|
|
@ -180,10 +180,11 @@ private:
|
||||||
using CGAL::Three::Scene_item::initializeBuffers;
|
using CGAL::Three::Scene_item::initializeBuffers;
|
||||||
void initializeBuffers(CGAL::Three::Viewer_interface *viewer = 0) const;
|
void initializeBuffers(CGAL::Three::Viewer_interface *viewer = 0) const;
|
||||||
void compute_normals_and_vertices(const bool colors_only = false) const;
|
void compute_normals_and_vertices(const bool colors_only = false) const;
|
||||||
template<typename FaceNormalPmap, typename VertexNormalPmap>
|
template<typename VertexNormalPmap>
|
||||||
void triangulate_facet(Facet_iterator,
|
void triangulate_facet(Facet_iterator,
|
||||||
const FaceNormalPmap&, const VertexNormalPmap&,
|
const Polyhedron::Traits::Vector_3&, const VertexNormalPmap&,
|
||||||
const bool colors_only) const;
|
const bool colors_only) const;
|
||||||
|
void* get_aabb_tree();
|
||||||
double volume, area;
|
double volume, area;
|
||||||
|
|
||||||
int m_min_patch_id; // the min value of the patch ids initialized in init()
|
int m_min_patch_id; // the min value of the patch ids initialized in init()
|
||||||
|
|
|
||||||
|
|
@ -43,21 +43,24 @@ public:
|
||||||
|
|
||||||
Scene_polyhedron_item_k_ring_selection
|
Scene_polyhedron_item_k_ring_selection
|
||||||
(Scene_polyhedron_item* poly_item, QMainWindow* mw, Active_handle::Type aht, int k_ring)
|
(Scene_polyhedron_item* poly_item, QMainWindow* mw, Active_handle::Type aht, int k_ring)
|
||||||
:is_active(false)
|
:is_active(false), is_edit_mode(false)
|
||||||
{
|
{
|
||||||
init(poly_item, mw, aht, k_ring);
|
init(poly_item, mw, aht, k_ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(Scene_polyhedron_item* poly_item, QMainWindow* /*mw*/, Active_handle::Type aht, int k_ring) {
|
void setEditMode(bool b) { is_edit_mode = b; }
|
||||||
|
|
||||||
|
void init(Scene_polyhedron_item* poly_item, QMainWindow* mw, Active_handle::Type aht, int k_ring) {
|
||||||
this->poly_item = poly_item;
|
this->poly_item = poly_item;
|
||||||
this->active_handle_type = aht;
|
this->active_handle_type = aht;
|
||||||
this->k_ring = k_ring;
|
this->k_ring = k_ring;
|
||||||
|
mainwindow = mw;
|
||||||
poly_item->enable_facets_picking(true);
|
poly_item->enable_facets_picking(true);
|
||||||
poly_item->set_color_vector_read_only(true);
|
poly_item->set_color_vector_read_only(true);
|
||||||
|
|
||||||
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
||||||
viewer->installEventFilter(this);
|
viewer->installEventFilter(this);
|
||||||
|
mw->installEventFilter(this);
|
||||||
#if QGLVIEWER_VERSION >= 0x020501
|
#if QGLVIEWER_VERSION >= 0x020501
|
||||||
viewer->setMouseBindingDescription(Qt::Key_D, Qt::ShiftModifier, Qt::LeftButton, "(When in selection plugin) Removes the clicked primitive from the selection. ");
|
viewer->setMouseBindingDescription(Qt::Key_D, Qt::ShiftModifier, Qt::LeftButton, "(When in selection plugin) Removes the clicked primitive from the selection. ");
|
||||||
#else
|
#else
|
||||||
|
|
@ -73,8 +76,9 @@ public Q_SLOTS:
|
||||||
void vertex_has_been_selected(void* void_ptr)
|
void vertex_has_been_selected(void* void_ptr)
|
||||||
{
|
{
|
||||||
is_active=true;
|
is_active=true;
|
||||||
if(active_handle_type != Active_handle::VERTEX) { return; }
|
if(active_handle_type == Active_handle::VERTEX)
|
||||||
process_selection( static_cast<Polyhedron::Vertex*>(void_ptr)->halfedge()->vertex() );
|
process_selection( static_cast<Polyhedron::Vertex*>(void_ptr)->halfedge()->vertex() );
|
||||||
|
updateIsTreated();
|
||||||
}
|
}
|
||||||
void facet_has_been_selected(void* void_ptr)
|
void facet_has_been_selected(void* void_ptr)
|
||||||
{
|
{
|
||||||
|
|
@ -82,23 +86,37 @@ public Q_SLOTS:
|
||||||
if (active_handle_type == Active_handle::FACET
|
if (active_handle_type == Active_handle::FACET
|
||||||
|| active_handle_type == Active_handle::CONNECTED_COMPONENT)
|
|| active_handle_type == Active_handle::CONNECTED_COMPONENT)
|
||||||
process_selection(static_cast<Polyhedron::Facet*>(void_ptr)->halfedge()->facet());
|
process_selection(static_cast<Polyhedron::Facet*>(void_ptr)->halfedge()->facet());
|
||||||
|
updateIsTreated();
|
||||||
}
|
}
|
||||||
void edge_has_been_selected(void* void_ptr)
|
void edge_has_been_selected(void* void_ptr)
|
||||||
{
|
{
|
||||||
is_active=true;
|
is_active=true;
|
||||||
if(active_handle_type != Active_handle::EDGE) { return; }
|
if(active_handle_type == Active_handle::EDGE)
|
||||||
process_selection( edge(static_cast<Polyhedron::Halfedge*>(void_ptr)->opposite()->opposite(), *poly_item->polyhedron()) );
|
process_selection( edge(static_cast<Polyhedron::Halfedge*>(void_ptr)->opposite()->opposite(), *poly_item->polyhedron()) );
|
||||||
|
updateIsTreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void selected(const std::set<Polyhedron::Vertex_handle>&);
|
void selected(const std::set<Polyhedron::Vertex_handle>&);
|
||||||
void selected(const std::set<Polyhedron::Facet_handle>&);
|
void selected(const std::set<Polyhedron::Facet_handle>&);
|
||||||
void selected(const std::set<edge_descriptor>&);
|
void selected(const std::set<edge_descriptor>&);
|
||||||
void toogle_insert(const bool);
|
void toogle_insert(const bool);
|
||||||
void endSelection();
|
void endSelection();
|
||||||
|
void resetIsTreated();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void updateIsTreated()
|
||||||
|
{
|
||||||
|
static ushort i = 0;
|
||||||
|
i++;
|
||||||
|
if(i==3)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
Q_EMIT resetIsTreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
template<class HandleType>
|
template<class HandleType>
|
||||||
void process_selection(HandleType clicked) {
|
void process_selection(HandleType clicked) {
|
||||||
const std::set<HandleType>& selection = extract_k_ring(clicked, k_ring);
|
const std::set<HandleType>& selection = extract_k_ring(clicked, k_ring);
|
||||||
|
|
@ -169,9 +187,10 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool eventFilter(QObject* /*target*/, QEvent *event)
|
bool eventFilter(QObject* target, QEvent *event)
|
||||||
{
|
{
|
||||||
// This filter is both filtering events from 'viewer' and 'main window'
|
// This filter is both filtering events from 'viewer' and 'main window'
|
||||||
|
|
||||||
// key events
|
// key events
|
||||||
if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
|
if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
|
|
@ -193,6 +212,12 @@ protected:
|
||||||
}
|
}
|
||||||
// mouse events
|
// mouse events
|
||||||
if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
|
if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
|
||||||
|
if(!state.shift_pressing && target == mainwindow)
|
||||||
|
{
|
||||||
|
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
||||||
|
viewer->setFocus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
QMouseEvent* mouse_event = static_cast<QMouseEvent*>(event);
|
QMouseEvent* mouse_event = static_cast<QMouseEvent*>(event);
|
||||||
if(mouse_event->button() == Qt::LeftButton) {
|
if(mouse_event->button() == Qt::LeftButton) {
|
||||||
state.left_button_pressing = event->type() == QEvent::MouseButtonPress;
|
state.left_button_pressing = event->type() == QEvent::MouseButtonPress;
|
||||||
|
|
@ -205,16 +230,22 @@ protected:
|
||||||
}
|
}
|
||||||
//to avoid the contextual menu to mess up the states.
|
//to avoid the contextual menu to mess up the states.
|
||||||
else if(mouse_event->button() == Qt::RightButton) {
|
else if(mouse_event->button() == Qt::RightButton) {
|
||||||
state.left_button_pressing = false;
|
state.left_button_pressing = false;
|
||||||
state.shift_pressing = false;
|
state.shift_pressing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// use mouse move event for paint-like selection
|
|
||||||
if( (event->type() == QEvent::MouseMove
|
// if not in edit mode, use mouse move event for paint-like selection
|
||||||
|| (event->type() == QEvent::MouseButtonPress
|
if( (!is_edit_mode && event->type() == QEvent::MouseMove && state.shift_pressing && state.left_button_pressing)
|
||||||
&& static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton))
|
||
|
||||||
&& (state.shift_pressing && state.left_button_pressing) )
|
(event->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton && state.shift_pressing ))
|
||||||
{
|
{
|
||||||
|
if(target == mainwindow)
|
||||||
|
{
|
||||||
|
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
||||||
|
viewer->setFocus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// paint with mouse move event
|
// paint with mouse move event
|
||||||
QMouseEvent* mouse_event = static_cast<QMouseEvent*>(event);
|
QMouseEvent* mouse_event = static_cast<QMouseEvent*>(event);
|
||||||
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
||||||
|
|
@ -231,6 +262,9 @@ protected:
|
||||||
}//end MouseMove
|
}//end MouseMove
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_edit_mode;
|
||||||
|
QMainWindow *mainwindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <CGAL/boost/graph/selection.h>
|
#include <CGAL/boost/graph/selection.h>
|
||||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||||
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
|
|
||||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||||
|
|
||||||
|
|
@ -184,13 +185,15 @@ public:
|
||||||
Scene_polyhedron_selection_item()
|
Scene_polyhedron_selection_item()
|
||||||
: Scene_polyhedron_item_decorator(NULL, false)
|
: Scene_polyhedron_item_decorator(NULL, false)
|
||||||
{
|
{
|
||||||
for(int i=0; i<3; i++)
|
original_sel_mode = static_cast<Active_handle::Type>(0);
|
||||||
|
this ->operation_mode = -1;
|
||||||
|
for(int i=0; i<6; i++)
|
||||||
{
|
{
|
||||||
addVaos(i);
|
addVaos(i);
|
||||||
vaos[i]->create();
|
vaos[i]->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<7; i++)
|
for(int i=0; i<10; i++)
|
||||||
{
|
{
|
||||||
buffers[i].create();
|
buffers[i].create();
|
||||||
}
|
}
|
||||||
|
|
@ -198,28 +201,36 @@ public:
|
||||||
nb_points = 0;
|
nb_points = 0;
|
||||||
nb_lines = 0;
|
nb_lines = 0;
|
||||||
this->setColor(facet_color);
|
this->setColor(facet_color);
|
||||||
|
first_selected = false;
|
||||||
|
is_treated = false;
|
||||||
|
poly_need_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_polyhedron_selection_item(Scene_polyhedron_item* poly_item, QMainWindow* mw)
|
Scene_polyhedron_selection_item(Scene_polyhedron_item* poly_item, QMainWindow* mw)
|
||||||
: Scene_polyhedron_item_decorator(NULL, false)
|
: Scene_polyhedron_item_decorator(NULL, false)
|
||||||
{
|
{
|
||||||
|
original_sel_mode = static_cast<Active_handle::Type>(0);
|
||||||
|
this ->operation_mode = -1;
|
||||||
nb_facets = 0;
|
nb_facets = 0;
|
||||||
nb_points = 0;
|
nb_points = 0;
|
||||||
nb_lines = 0;
|
nb_lines = 0;
|
||||||
|
|
||||||
for(int i=0; i<3; i++)
|
for(int i=0; i<6; i++)
|
||||||
{
|
{
|
||||||
addVaos(i);
|
addVaos(i);
|
||||||
vaos[i]->create();
|
vaos[i]->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<7; i++)
|
for(int i=0; i<8; i++)
|
||||||
{
|
{
|
||||||
buffers[i].create();
|
buffers[i].create();
|
||||||
}
|
}
|
||||||
init(poly_item, mw);
|
init(poly_item, mw);
|
||||||
this->setColor(facet_color);
|
this->setColor(facet_color);
|
||||||
invalidateOpenGLBuffers();
|
invalidateOpenGLBuffers();
|
||||||
|
first_selected = false;
|
||||||
|
is_treated = false;
|
||||||
|
poly_need_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Scene_polyhedron_selection_item()
|
~Scene_polyhedron_selection_item()
|
||||||
|
|
@ -237,9 +248,12 @@ protected:
|
||||||
SLOT(selected(const std::set<Polyhedron::Facet_handle>&)));
|
SLOT(selected(const std::set<Polyhedron::Facet_handle>&)));
|
||||||
connect(&k_ring_selector, SIGNAL(selected(const std::set<edge_descriptor>&)), this,
|
connect(&k_ring_selector, SIGNAL(selected(const std::set<edge_descriptor>&)), this,
|
||||||
SLOT(selected(const std::set<edge_descriptor>&)));
|
SLOT(selected(const std::set<edge_descriptor>&)));
|
||||||
|
connect(poly_item, SIGNAL(selection_done()), this, SLOT(update_poly()));
|
||||||
|
|
||||||
connect(&k_ring_selector, SIGNAL(endSelection()), this,SLOT(endSelection()));
|
connect(&k_ring_selector, SIGNAL(endSelection()), this,SLOT(endSelection()));
|
||||||
connect(&k_ring_selector, SIGNAL(toogle_insert(bool)), this,SLOT(toggle_insert(bool)));
|
connect(&k_ring_selector, SIGNAL(toogle_insert(bool)), this,SLOT(toggle_insert(bool)));
|
||||||
k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1);
|
k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1);
|
||||||
|
connect(&k_ring_selector, SIGNAL(resetIsTreated()), this, SLOT(resetIsTreated()));
|
||||||
|
|
||||||
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
||||||
viewer->installEventFilter(this);
|
viewer->installEventFilter(this);
|
||||||
|
|
@ -787,14 +801,32 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
void updateInstructions(QString);
|
||||||
void simplicesSelected(CGAL::Three::Scene_item*);
|
void simplicesSelected(CGAL::Three::Scene_item*);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
void update_poly()
|
||||||
|
{
|
||||||
|
if(poly_need_update)
|
||||||
|
poly_item->invalidateOpenGLBuffers();
|
||||||
|
}
|
||||||
|
void on_Ctrlz_pressed();
|
||||||
|
void emitTempInstruct();
|
||||||
|
void resetIsTreated() { is_treated = false;}
|
||||||
|
void save_handleType()
|
||||||
|
{
|
||||||
|
original_sel_mode = get_active_handle_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_operation_mode(int mode);
|
||||||
|
|
||||||
void invalidateOpenGLBuffers() {
|
void invalidateOpenGLBuffers() {
|
||||||
|
|
||||||
// do not use decorator function, which calls changed on poly_item which cause deletion of AABB
|
// do not use decorator function, which calls changed on poly_item which cause deletion of AABB
|
||||||
// poly_item->invalidateOpenGLBuffers();
|
// poly_item->invalidateOpenGLBuffers();
|
||||||
are_buffers_filled = false;
|
are_buffers_filled = false;
|
||||||
|
are_temp_buffers_filled = false;
|
||||||
|
poly = polyhedron();
|
||||||
compute_bbox();
|
compute_bbox();
|
||||||
}
|
}
|
||||||
// slots are called by signals of polyhedron_k_ring_selector
|
// slots are called by signals of polyhedron_k_ring_selector
|
||||||
|
|
@ -820,6 +852,14 @@ public Q_SLOTS:
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject* /*target*/, QEvent * gen_event)
|
bool eventFilter(QObject* /*target*/, QEvent * gen_event)
|
||||||
{
|
{
|
||||||
|
if(gen_event->type() == QEvent::KeyPress
|
||||||
|
&& static_cast<QKeyEvent*>(gen_event)->key()==Qt::Key_Z)
|
||||||
|
{
|
||||||
|
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(gen_event);
|
||||||
|
if(keyEvent->modifiers().testFlag(Qt::ControlModifier))
|
||||||
|
on_Ctrlz_pressed();
|
||||||
|
}
|
||||||
|
|
||||||
if(!visible() || !k_ring_selector.state.shift_pressing) { return false; }
|
if(!visible() || !k_ring_selector.state.shift_pressing) { return false; }
|
||||||
if(gen_event->type() == QEvent::Wheel)
|
if(gen_event->type() == QEvent::Wheel)
|
||||||
{
|
{
|
||||||
|
|
@ -849,24 +889,23 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename HandleRange>
|
|
||||||
bool treat_selection(const HandleRange& selection)
|
|
||||||
{
|
|
||||||
typedef typename HandleRange::value_type HandleType;
|
|
||||||
Selection_traits<HandleType, Scene_polyhedron_selection_item> tr(this);
|
|
||||||
|
|
||||||
bool any_change = false;
|
//Generic class
|
||||||
if(is_insert) {
|
template<typename HandleRange>
|
||||||
BOOST_FOREACH(HandleType h, selection)
|
bool treat_selection(const HandleRange&)
|
||||||
any_change |= tr.container().insert(h).second;
|
{
|
||||||
}
|
qDebug()<<"ERROR : unknown HandleRange";
|
||||||
else{
|
return false;
|
||||||
BOOST_FOREACH(HandleType h, selection)
|
}
|
||||||
any_change |= (tr.container().erase(h)!=0);
|
template<typename HandleRange>
|
||||||
}
|
bool treat_classic_selection(const HandleRange& selection);
|
||||||
if(any_change) { invalidateOpenGLBuffers(); Q_EMIT itemChanged(); }
|
|
||||||
return any_change;
|
//Specialization for set<Vertex_handle>
|
||||||
}
|
bool treat_selection(const std::set<Polyhedron::Vertex_handle>& selection);
|
||||||
|
bool treat_selection(const std::set<edge_descriptor>& selection);
|
||||||
|
bool treat_selection(const std::set<Polyhedron::Facet_handle>& selection);
|
||||||
|
bool treat_selection(const std::vector<Polyhedron::Facet_handle>& selection);
|
||||||
|
|
||||||
|
|
||||||
Facet_handle face(Facet_handle fh)
|
Facet_handle face(Facet_handle fh)
|
||||||
{ return fh; }
|
{ return fh; }
|
||||||
|
|
@ -904,6 +943,7 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Is_selected_property_map<edge_descriptor>
|
Is_selected_property_map<edge_descriptor>
|
||||||
selected_edges_pmap(std::vector<bool>& mark)
|
selected_edges_pmap(std::vector<bool>& mark)
|
||||||
|
|
@ -943,11 +983,27 @@ public:
|
||||||
Selection_set_vertex selected_vertices;
|
Selection_set_vertex selected_vertices;
|
||||||
Selection_set_facet selected_facets;
|
Selection_set_facet selected_facets;
|
||||||
Selection_set_edge selected_edges; // stores one halfedge for each pair (halfedge with minimum address)
|
Selection_set_edge selected_edges; // stores one halfedge for each pair (halfedge with minimum address)
|
||||||
|
|
||||||
|
Selection_set_vertex temp_selected_vertices;
|
||||||
|
Selection_set_facet temp_selected_facets;
|
||||||
|
Selection_set_edge temp_selected_edges; // stores one halfedge for each pair (halfedge with minimum address)
|
||||||
//
|
//
|
||||||
QColor vertex_color, facet_color, edge_color;
|
QColor vertex_color, facet_color, edge_color;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool poly_need_update;
|
||||||
|
mutable bool are_temp_buffers_filled;
|
||||||
|
//Specifies Selection/edition mode
|
||||||
|
bool first_selected;
|
||||||
|
int operation_mode;
|
||||||
|
QString m_temp_instructs;
|
||||||
|
bool is_treated;
|
||||||
|
Vertex_handle to_split_vh;
|
||||||
|
Facet_handle to_split_fh;
|
||||||
|
edge_descriptor to_join_ed;
|
||||||
|
Active_handle::Type original_sel_mode;
|
||||||
|
//Only needed for the triangulation
|
||||||
|
Polyhedron* poly;
|
||||||
mutable std::vector<float> positions_facets;
|
mutable std::vector<float> positions_facets;
|
||||||
mutable std::vector<float> normals;
|
mutable std::vector<float> normals;
|
||||||
mutable std::vector<float> positions_lines;
|
mutable std::vector<float> positions_lines;
|
||||||
|
|
@ -955,11 +1011,29 @@ private:
|
||||||
mutable std::size_t nb_facets;
|
mutable std::size_t nb_facets;
|
||||||
mutable std::size_t nb_points;
|
mutable std::size_t nb_points;
|
||||||
mutable std::size_t nb_lines;
|
mutable std::size_t nb_lines;
|
||||||
|
|
||||||
|
mutable std::vector<float> positions_temp_facets;
|
||||||
|
mutable std::vector<float> temp_normals;
|
||||||
|
mutable std::vector<float> positions_temp_lines;
|
||||||
|
mutable std::vector<float> positions_temp_points;
|
||||||
|
mutable std::size_t nb_temp_facets;
|
||||||
|
mutable std::size_t nb_temp_points;
|
||||||
|
mutable std::size_t nb_temp_lines;
|
||||||
|
|
||||||
mutable QOpenGLShaderProgram *program;
|
mutable QOpenGLShaderProgram *program;
|
||||||
|
|
||||||
using CGAL::Three::Scene_item::initializeBuffers;
|
using CGAL::Three::Scene_item::initializeBuffers;
|
||||||
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
|
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
|
||||||
|
void initialize_temp_buffers(CGAL::Three::Viewer_interface *viewer) const;
|
||||||
void computeElements() const;
|
void computeElements() const;
|
||||||
|
void compute_any_elements(std::vector<float> &p_facets, std::vector<float> &p_lines, std::vector<float> &p_points, std::vector<float> &p_normals,
|
||||||
|
const Selection_set_vertex& p_sel_vertex, const Selection_set_facet &p_sel_facet, const Selection_set_edge &p_sel_edges) const;
|
||||||
|
void compute_temp_elements() const;
|
||||||
|
|
||||||
|
template<typename FaceNormalPmap>
|
||||||
|
void triangulate_facet(Facet_handle, const FaceNormalPmap&,
|
||||||
|
std::vector<float> &p_facets,std::vector<float> &p_normals) const;
|
||||||
|
void tempInstructions(QString s1, QString s2);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue