cgal/Polyhedron/demo/Polyhedron/Polyhedron_demo_nef_plugin.cpp

311 lines
9.7 KiB
C++

#include "Scene_polyhedron_item.h"
#include "Scene_nef_polyhedron_item.h"
#include "Polyhedron_demo_plugin_interface.h"
#include "Polyhedron_demo_plugin_helper.h"
#include <QString>
#include <QAction>
#include <QMenu>
#include <QMainWindow>
#include <QApplication>
#include <QTime>
#include <QMessageBox>
class Polyhedron_demo_nef_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public:
QStringList actionsNames() const {
return QStringList() << "actionToNef"
<< "actionToPoly"
<< "actionUnion"
<< "actionIntersection"
<< "actionDifference"
<< "actionConvexDecomposition"
<< "actionMinkowskiSum";
}
void init(QMainWindow* mainWindow,
Scene_interface* scene_interface)
{
mw = mainWindow;
scene = scene_interface;
actions_map["actionConvexDecomposition"] = getActionFromMainWindow(mw, "actionConvexDecomposition");
actions_map["actionConvexDecomposition"]->setProperty("subMenuName", "Object creation");
actions_map["actionToNef"] = getActionFromMainWindow(mw, "actionToNef");
actions_map["actionToPoly"] = getActionFromMainWindow(mw, "actionToPoly");
actions_map["actionUnion"] = getActionFromMainWindow(mw, "actionUnion");
actions_map["actionIntersection"] = getActionFromMainWindow(mw, "actionIntersection");
actions_map["actionDifference"] = getActionFromMainWindow(mw, "actionDifference");
actions_map["actionMinkowskiSum"] = getActionFromMainWindow(mw, "actionMinkowskiSum");
autoConnectActions();
}
bool applicable(QAction*) const {
const int indexA = scene->selectionAindex();
const int indexB = scene->selectionBindex();
return qobject_cast<Scene_polyhedron_item*>(scene->item(scene->mainSelectionIndex()))
|| qobject_cast<Scene_nef_polyhedron_item*>(scene->item(scene->mainSelectionIndex()))
|| qobject_cast<Scene_polyhedron_item*>(scene->item(indexA))
|| qobject_cast<Scene_polyhedron_item*>(scene->item(indexB))
|| qobject_cast<Scene_nef_polyhedron_item*>(scene->item(indexA))
|| qobject_cast<Scene_nef_polyhedron_item*>(scene->item(indexB))
;
}
// QList<QAction*> actions() const {
// QMenu* menu = new QMenu(tr("Boolean operations"), mw);
// QAction* action_to_nef = new QAction(tr("Convert to nef polyhedron"), mw);
// connect(action_to_nef, SIGNAL(triggered()),
// this, SLOT(convert_to_nef_polyhedron()));
// QAction* action_to_poly = new QAction(tr("Convert nef polyhedron to polyhedron"), mw);
// connect(action_to_poly, SIGNAL(triggered()),
// this, SLOT(convert_to_polyhedron()));
// menu->addAction(action_to_nef);
// menu->addAction(action_to_poly);
// return QList<QAction*>() << menu->menuAction();
// }
private:
enum Boolean_operation { BOOLEAN_UNION,
BOOLEAN_INTERSECTION,
BOOLEAN_DIFFERENCE,
MINKOWSKI_SUM
};
void boolean_operation(const Boolean_operation operation);
public Q_SLOTS:
void on_actionToNef_triggered();
void on_actionToPoly_triggered();
void on_actionUnion_triggered();
void on_actionIntersection_triggered();
void on_actionDifference_triggered();
void on_actionMinkowskiSum_triggered();
void on_actionConvexDecomposition_triggered();
}; // end class Polyhedron_demo_nef_plugin
void
Polyhedron_demo_nef_plugin::on_actionToNef_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_polyhedron_item* item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(item)
{
QApplication::setOverrideCursor(Qt::WaitCursor);
QTime time;
time.start();
std::cerr << "Convert polyhedron to nef polyhedron...";
Scene_nef_polyhedron_item* new_nef_item =
Scene_nef_polyhedron_item::from_polyhedron(item);
new_nef_item->setName(tr("%1 (to nef)").arg(item->name()));
new_nef_item->setRenderingMode(item->renderingMode());
item->setVisible(false);
scene->itemChanged(index);
scene->addItem(new_nef_item);
std::cerr << "ok (" << time.elapsed() << " ms)" << std::endl;
QApplication::restoreOverrideCursor();
}
}
void
Polyhedron_demo_nef_plugin::on_actionConvexDecomposition_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_polyhedron_item* pitem =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
Scene_nef_polyhedron_item* item =
(pitem)? Scene_nef_polyhedron_item::from_polyhedron(pitem)
: qobject_cast<Scene_nef_polyhedron_item*>(scene->item(index));
if(item) {
QTime time;
time.start();
std::cerr << "Convex decomposition...";
QApplication::setOverrideCursor(Qt::WaitCursor);
std::list<Scene_polyhedron_item*> convex_parts;
item->convex_decomposition(convex_parts);
int i = 0;
for(std::list<Scene_polyhedron_item*>::iterator it = convex_parts.begin();
it != convex_parts.end();
++it){
(*it)->setName(tr("part %1 of %2").arg(i++).arg(item->name()));
(*it)->setRenderingMode(item->renderingMode());
scene->addItem(*it);
}
if(pitem){
delete item;
pitem->setVisible(false);
} else {
item->setVisible(false);
}
std::cerr << "ok (" << time.elapsed() << " ms)" << std::endl;
QApplication::restoreOverrideCursor();
} else {
std::cerr << "Only a Polyhedron or a Nef Polyhedron can be decomposed in convex parts" << std::endl;
}
}
void
Polyhedron_demo_nef_plugin::on_actionToPoly_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_nef_polyhedron_item* item =
qobject_cast<Scene_nef_polyhedron_item*>(scene->item(index));
if(item)
{
QTime time;
time.start();
std::cerr << "Convert nef polyhedron to polyhedron...";
if(!item->is_simple())
{
QMessageBox::warning(mw,
tr("Cannot convert"),
tr("The nef polyhedron \"%1\" is not simple, "
"and thus cannot be converted!")
.arg(item->name()));
return;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
Scene_polyhedron_item* new_item = item->convert_to_polyhedron();
new_item->setName(tr("%1 (from nef)").arg(item->name()));
new_item->setRenderingMode(item->renderingMode());
item->setVisible(false);
scene->itemChanged(index);
scene->addItem(new_item);
std::cerr << "ok (" << time.elapsed() << " ms)" << std::endl;
QApplication::restoreOverrideCursor();
}
}
void Polyhedron_demo_nef_plugin::on_actionUnion_triggered()
{
boolean_operation(BOOLEAN_UNION);
}
void Polyhedron_demo_nef_plugin::on_actionIntersection_triggered()
{
boolean_operation(BOOLEAN_INTERSECTION);
}
void Polyhedron_demo_nef_plugin::on_actionDifference_triggered()
{
boolean_operation(BOOLEAN_DIFFERENCE);
}
void
Polyhedron_demo_nef_plugin::on_actionMinkowskiSum_triggered()
{
boolean_operation(MINKOWSKI_SUM);
}
void Polyhedron_demo_nef_plugin::boolean_operation(const Boolean_operation operation)
{
const int indexA = scene->selectionAindex();
const int indexB = scene->selectionBindex();
if(indexA < 0 || indexB < 0) return;
if(indexA == indexB) return;
if(qobject_cast<Scene_polyhedron_item*>(scene->item(indexA)) ||
qobject_cast<Scene_polyhedron_item*>(scene->item(indexB))) {
QMenu* menu = mw->findChild<QMenu*>("menu_Boolean_operations");
if(!menu) qWarning("Do not find object named \"menu_Boolean_operations\"!");
QMessageBox::warning(mw,
tr("Boolean operation cannot be applied on normal polyhedron"),
tr("You need to call the operation \"%1\" in the menu \"%2\".")
.arg(actions_map["actionToNef"]->text())
.arg(menu ? menu->title() : "Boolean operations"));
}
Scene_nef_polyhedron_item* itemA =
qobject_cast<Scene_nef_polyhedron_item*>(scene->item(indexA));
Scene_nef_polyhedron_item* itemB =
qobject_cast<Scene_nef_polyhedron_item*>(scene->item(indexB));
if(!itemA || !itemB)
return;
QApplication::setOverrideCursor(Qt::WaitCursor);
// copy itemA
Scene_nef_polyhedron_item* new_item = 0;
if(operation != MINKOWSKI_SUM) {
new_item = new Scene_nef_polyhedron_item(*itemA->nef_polyhedron());
};
// perform Boolean operation
std::cout << "Boolean operation...";
QTime time;
time.start();
switch(operation)
{
case BOOLEAN_UNION:
(*new_item) += (*itemB);
break;
case BOOLEAN_INTERSECTION:
(*new_item) *= (*itemB);
break;
case BOOLEAN_DIFFERENCE:
(*new_item) -= (*itemB);
break;
case MINKOWSKI_SUM:
new_item = Scene_nef_polyhedron_item::sum(*itemA,
*itemB);
}
std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;
QString name;
switch(operation)
{
case BOOLEAN_UNION:
name = tr("%1 union %2");
break;
case BOOLEAN_INTERSECTION:
name = tr("%1 intersection %2");
break;
case BOOLEAN_DIFFERENCE:
name = tr("%1 minus %2");
break;
case MINKOWSKI_SUM:
name = tr("Minkowski sum of %1 and %2");
}
new_item->setName(name.arg(itemA->name(), itemB->name()));
new_item->setColor(Qt::green);
new_item->setRenderingMode(FlatPlusEdges);
itemA->setRenderingMode(Wireframe);
itemB->setRenderingMode(Wireframe);
scene->addItem(new_item);
scene->itemChanged(indexA);
scene->itemChanged(indexB);
QApplication::restoreOverrideCursor();
}
#include "Polyhedron_demo_nef_plugin.moc"