mirror of https://github.com/CGAL/cgal
398 lines
16 KiB
C++
398 lines
16 KiB
C++
#include "Polyhedron_demo_plugin_helper.h"
|
|
#include "Scene_polyhedron_item.h"
|
|
#include "Scene_edit_polyhedron_item.h"
|
|
|
|
#include <QAction>
|
|
#include <QMainWindow>
|
|
#include <QFileDialog>
|
|
|
|
#include <QGLViewer/qglviewer.h>
|
|
|
|
#include "ui_Deform_mesh.h"
|
|
|
|
class Polyhedron_demo_edit_polyhedron_plugin :
|
|
public QObject,
|
|
public Polyhedron_demo_plugin_helper
|
|
{
|
|
Q_OBJECT
|
|
Q_INTERFACES(Polyhedron_demo_plugin_interface)
|
|
|
|
public:
|
|
Polyhedron_demo_edit_polyhedron_plugin()
|
|
: Polyhedron_demo_plugin_helper(), dock_widget(NULL)
|
|
{ }
|
|
~Polyhedron_demo_edit_polyhedron_plugin()
|
|
{ }
|
|
|
|
void init(QMainWindow* mainWindow, Scene_interface* scene_interface);
|
|
QList<QAction*> actions() const;
|
|
bool applicable() const;
|
|
|
|
public slots:
|
|
void on_actionDeformation_triggered();
|
|
/////// Dock window signal handlers //////
|
|
// what they do is simply transmiting required 'action' to selected scene_edit_polyhedron_item object
|
|
void on_AddCtrlVertPushButton_clicked();
|
|
void on_PrevCtrlVertPushButton_clicked();
|
|
void on_NextCtrlVertPushButton_clicked();
|
|
void on_SelectAllVerticesPushButton_clicked();
|
|
void on_DeleteCtrlVertPushButton_clicked();
|
|
void on_ApplyAndClosePushButton_clicked();
|
|
void on_ClearROIPushButton_clicked();
|
|
void on_ShowROICheckBox_stateChanged(int state);
|
|
void on_ShowAsSphereCheckBox_stateChanged(int state);
|
|
void on_ActivatePivotingCheckBox_stateChanged(int state);
|
|
void on_OverwritePushButton_clicked();
|
|
void on_SaveROIPushButton_clicked();
|
|
void on_ReadROIPushButton_clicked();
|
|
void dock_widget_visibility_changed(bool visible);
|
|
void on_Select_isolated_components_button_clicked();
|
|
void on_Get_minimum_button_clicked();
|
|
|
|
void on_BrushSpinBoxCtrlVert_changed(int);
|
|
void on_BrushSpinBoxRoi_changed(int);
|
|
void on_ROIRadioButton_toggled(bool);
|
|
void new_item_created(int item_id);
|
|
|
|
private:
|
|
typedef Scene_interface::Item_id Item_id;
|
|
|
|
Scene_edit_polyhedron_item* convert_to_edit_polyhedron(Item_id, Scene_polyhedron_item*);
|
|
Scene_polyhedron_item* convert_to_plain_polyhedron(Item_id, Scene_edit_polyhedron_item*);
|
|
|
|
Ui::DeformMesh ui_widget;
|
|
QDockWidget* dock_widget;
|
|
|
|
QAction* actionDeformation;
|
|
}; // end Polyhedron_demo_edit_polyhedron_plugin
|
|
|
|
QList<QAction*> Polyhedron_demo_edit_polyhedron_plugin::actions() const {
|
|
return QList<QAction*>() << actionDeformation;
|
|
}
|
|
bool Polyhedron_demo_edit_polyhedron_plugin::applicable() const {
|
|
Q_FOREACH(Scene_interface::Item_id i, scene->selectionIndices())
|
|
{
|
|
if(qobject_cast<Scene_polyhedron_item*>(scene->item(i))
|
|
|| qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i)))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::init(QMainWindow* mainWindow, Scene_interface* scene_interface)
|
|
{
|
|
mw = mainWindow;
|
|
scene = scene_interface;
|
|
|
|
actionDeformation = new QAction("Surface Mesh Deformation", mw);
|
|
|
|
actionDeformation->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
|
|
connect(actionDeformation, SIGNAL(triggered()), this, SLOT(on_actionDeformation_triggered()));
|
|
|
|
// Connect Scene::newItem so that, if dock_widget is visible, convert
|
|
// automatically polyhedron items to "edit polyhedron" items.
|
|
QObject* scene = dynamic_cast<QObject*>(scene_interface);
|
|
if(scene) {
|
|
connect(scene, SIGNAL(newItem(int)), this, SLOT(new_item_created(int)));
|
|
} else {
|
|
std::cerr << "ERROR " << __FILE__ << ":" << __LINE__ << " :"
|
|
<< " cannot convert scene_interface to scene!\n";
|
|
}
|
|
|
|
////////////////// Construct widget /////////////////////////////
|
|
// First time, construct docking window
|
|
dock_widget = new QDockWidget("Mesh Deformation", mw);
|
|
dock_widget->setVisible(false); // do not show at the beginning
|
|
|
|
ui_widget.setupUi(dock_widget);
|
|
mw->addDockWidget(Qt::LeftDockWidgetArea, dock_widget);
|
|
|
|
connect(ui_widget.AddCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_AddCtrlVertPushButton_clicked()));
|
|
connect(ui_widget.PrevCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_PrevCtrlVertPushButton_clicked()));
|
|
connect(ui_widget.NextCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_NextCtrlVertPushButton_clicked()));
|
|
connect(ui_widget.SelectAllVerticesPushButton, SIGNAL(clicked()), this, SLOT(on_SelectAllVerticesPushButton_clicked()));
|
|
connect(ui_widget.DeleteCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_DeleteCtrlVertPushButton_clicked()));
|
|
connect(ui_widget.ApplyAndClosePushButton, SIGNAL(clicked()), this, SLOT(on_ApplyAndClosePushButton_clicked()));
|
|
connect(ui_widget.ClearROIPushButton, SIGNAL(clicked()), this, SLOT(on_ClearROIPushButton_clicked()));
|
|
connect(ui_widget.ShowROICheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ShowROICheckBox_stateChanged(int)));
|
|
connect(ui_widget.ShowAsSphereCheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ShowAsSphereCheckBox_stateChanged(int)));
|
|
connect(ui_widget.ActivatePivotingCheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ActivatePivotingCheckBox_stateChanged(int)));
|
|
connect(ui_widget.OverwritePushButton, SIGNAL(clicked()), this, SLOT(on_OverwritePushButton_clicked()));
|
|
connect(ui_widget.Select_isolated_components_button, SIGNAL(clicked()), this, SLOT(on_Select_isolated_components_button_clicked()));
|
|
connect(ui_widget.Get_minimum_button, SIGNAL(clicked()), this, SLOT(on_Get_minimum_button_clicked()));
|
|
|
|
connect(ui_widget.SaveROIPushButton, SIGNAL(clicked()), this, SLOT(on_SaveROIPushButton_clicked()));
|
|
connect(ui_widget.ReadROIPushButton, SIGNAL(clicked()), this, SLOT(on_ReadROIPushButton_clicked()));
|
|
connect(dock_widget, SIGNAL(visibilityChanged(bool)), this, SLOT(dock_widget_visibility_changed(bool)) );
|
|
|
|
connect(ui_widget.BrushSpinBoxRoi, SIGNAL(valueChanged(int)), this, SLOT(on_BrushSpinBoxRoi_changed(int)));
|
|
connect(ui_widget.BrushSpinBoxCtrlVert, SIGNAL(valueChanged(int)), this, SLOT(on_BrushSpinBoxCtrlVert_changed(int)));
|
|
connect(ui_widget.ROIRadioButton, SIGNAL(toggled(bool)), this, SLOT(on_ROIRadioButton_toggled(bool)));
|
|
///////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_actionDeformation_triggered()
|
|
{
|
|
// dock widget should be constructed in init()
|
|
if(dock_widget->isVisible()) { dock_widget->hide(); }
|
|
else { dock_widget->show(); }
|
|
}
|
|
|
|
/////// Dock window signal handlers //////
|
|
// what they do is simply transmitting required 'action' to selected scene_edit_polyhedron_item object
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_AddCtrlVertPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
edit_item->create_ctrl_vertices_group();
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_PrevCtrlVertPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
edit_item->prev_ctrl_vertices_group();
|
|
scene->itemChanged(edit_item); // for repaint
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_NextCtrlVertPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
edit_item->next_ctrl_vertices_group();
|
|
scene->itemChanged(edit_item); // for repaint
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_SelectAllVerticesPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
edit_item->set_all_vertices_as_roi();
|
|
scene->itemChanged(edit_item); // for repaint
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_DeleteCtrlVertPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
edit_item->delete_ctrl_vertices_group();
|
|
scene->itemChanged(edit_item); // for repaint
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_ClearROIPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
edit_item->clear_roi();
|
|
scene->itemChanged(edit_item); // for repaint
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_ApplyAndClosePushButton_clicked()
|
|
{
|
|
dock_widget->setVisible(false);
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_ShowROICheckBox_stateChanged(int /*state*/)
|
|
{
|
|
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i)
|
|
{
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
|
|
if(!edit_item) { continue; }
|
|
|
|
scene->itemChanged(edit_item); // just for redraw
|
|
}
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_ShowAsSphereCheckBox_stateChanged(int /*state*/)
|
|
{
|
|
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i)
|
|
{
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
|
|
if(!edit_item) { continue; }
|
|
|
|
scene->itemChanged(edit_item); // just for redraw
|
|
}
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_ActivatePivotingCheckBox_stateChanged(int state)
|
|
{
|
|
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i)
|
|
{
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
|
|
if(!edit_item) { continue; }
|
|
|
|
if(state == Qt::Checked) {
|
|
edit_item->pivoting_begin();
|
|
}
|
|
else {
|
|
edit_item->pivoting_end();
|
|
}
|
|
scene->itemChanged(edit_item);
|
|
}
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_OverwritePushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
edit_item->overwrite_deform_object();
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_Select_isolated_components_button_clicked() {
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
boost::optional<std::size_t> minimum =
|
|
edit_item->select_isolated_components(ui_widget.Threshold_size_spin_box->value());
|
|
if(minimum) {
|
|
ui_widget.Threshold_size_spin_box->setValue(*minimum);
|
|
}
|
|
}
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_Get_minimum_button_clicked() {
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return; // the selected item is not of the right type
|
|
|
|
boost::optional<std::size_t> minimum = edit_item->get_minimum_isolated_component();
|
|
if(minimum) {
|
|
ui_widget.Threshold_size_spin_box->setValue(*minimum);
|
|
}
|
|
}
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_SaveROIPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return;
|
|
|
|
QString fileName = QFileDialog::getSaveFileName(mw, "Save",
|
|
"roi.txt", "Text (*.txt)");
|
|
if(fileName.isNull()) { return; }
|
|
|
|
edit_item->save_roi(fileName.toLocal8Bit().data());
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_ReadROIPushButton_clicked()
|
|
{
|
|
int item_id = scene->mainSelectionIndex();
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(item_id));
|
|
if(!edit_item) return;
|
|
|
|
QString fileName = QFileDialog::getOpenFileName(mw, "Read",
|
|
"roi.txt", "Text (*.txt)");
|
|
if(fileName.isNull()) { return; }
|
|
|
|
edit_item->read_roi(fileName.toLocal8Bit().data());
|
|
scene->itemChanged(edit_item);
|
|
}
|
|
void Polyhedron_demo_edit_polyhedron_plugin::dock_widget_visibility_changed(bool visible)
|
|
{
|
|
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries();
|
|
i < end; ++i)
|
|
{
|
|
Scene_polyhedron_item* poly_item = qobject_cast<Scene_polyhedron_item*>(scene->item(i));
|
|
if (poly_item)
|
|
{ poly_item->update_halfedge_indices(); }
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
|
|
|
|
if(visible && poly_item) {
|
|
convert_to_edit_polyhedron(i, poly_item);
|
|
} else if(!visible && edit_item) {
|
|
convert_to_plain_polyhedron(i, edit_item);
|
|
}
|
|
}
|
|
|
|
//QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin();
|
|
//if(visible)
|
|
//{
|
|
// viewer->camera()->setType(qglviewer::Camera::ORTHOGRAPHIC);
|
|
//}else
|
|
//{
|
|
// viewer->camera()->setType(qglviewer::Camera::PERSPECTIVE);
|
|
//}
|
|
}
|
|
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_ROIRadioButton_toggled(bool value) {
|
|
int k_ring = value ? ui_widget.BrushSpinBoxRoi->value() :
|
|
ui_widget.BrushSpinBoxCtrlVert->value();
|
|
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i)
|
|
{
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
|
|
if(!edit_item) { continue; }
|
|
|
|
edit_item->set_k_ring(k_ring);
|
|
}
|
|
}
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_BrushSpinBoxCtrlVert_changed(int value) {
|
|
if(ui_widget.ROIRadioButton->isChecked()) { return; }
|
|
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i)
|
|
{
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
|
|
if(!edit_item) { continue; }
|
|
|
|
edit_item->set_k_ring(value);
|
|
}
|
|
}
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::on_BrushSpinBoxRoi_changed(int value) {
|
|
if(!ui_widget.ROIRadioButton->isChecked()) { return; }
|
|
for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i)
|
|
{
|
|
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
|
|
if(!edit_item) { continue; }
|
|
|
|
edit_item->set_k_ring(value);
|
|
}
|
|
}
|
|
|
|
void Polyhedron_demo_edit_polyhedron_plugin::new_item_created(int item_id)
|
|
{
|
|
if(dock_widget->isVisible()) {
|
|
Scene_polyhedron_item* poly_item =
|
|
qobject_cast<Scene_polyhedron_item*>(scene->item(item_id));
|
|
if(poly_item) {
|
|
convert_to_edit_polyhedron(item_id, poly_item);
|
|
}
|
|
}
|
|
}
|
|
|
|
Scene_edit_polyhedron_item*
|
|
Polyhedron_demo_edit_polyhedron_plugin::convert_to_edit_polyhedron(Item_id i,
|
|
Scene_polyhedron_item* poly_item)
|
|
{
|
|
QString poly_item_name = poly_item->name();
|
|
Scene_edit_polyhedron_item* edit_poly = new Scene_edit_polyhedron_item(poly_item, &ui_widget, mw);
|
|
edit_poly->setColor(poly_item->color());
|
|
edit_poly->setName(QString("%1 (edit)").arg(poly_item->name()));
|
|
edit_poly->setRenderingMode(Gouraud);
|
|
poly_item->setName(poly_item_name); // Because it is changed when the
|
|
// name of edit_poly is changed.
|
|
int k_ring = ui_widget.ROIRadioButton->isChecked() ? ui_widget.BrushSpinBoxRoi->value() :
|
|
ui_widget.BrushSpinBoxCtrlVert->value();
|
|
edit_poly->set_k_ring(k_ring);
|
|
scene->replaceItem(i, edit_poly);
|
|
return edit_poly;
|
|
}
|
|
|
|
Scene_polyhedron_item*
|
|
Polyhedron_demo_edit_polyhedron_plugin::convert_to_plain_polyhedron(Item_id i,
|
|
Scene_edit_polyhedron_item* edit_item)
|
|
{
|
|
Scene_polyhedron_item* poly_item = edit_item->to_polyhedron_item();
|
|
scene->replaceItem(i, poly_item);
|
|
delete edit_item;
|
|
return poly_item;
|
|
}
|
|
|
|
|
|
|
|
Q_EXPORT_PLUGIN2(Polyhedron_demo_edit_polyhedron_plugin, Polyhedron_demo_edit_polyhedron_plugin)
|
|
|
|
#include "Polyhedron_demo_edit_polyhedron_plugin.moc"
|