mirror of https://github.com/CGAL/cgal
Merge pull request #3516 from maxGimeno/Demo-fixes-GF
Polyhedron Demo: Fixes.
This commit is contained in:
commit
6c6244d9b8
|
|
@ -1649,7 +1649,7 @@ bool remove_degenerate_faces( TriangleMesh& tmesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TriangleMesh>
|
template<class TriangleMesh>
|
||||||
std::size_t remove_degenerate_faces(TriangleMesh& tmesh)
|
bool remove_degenerate_faces(TriangleMesh& tmesh)
|
||||||
{
|
{
|
||||||
return remove_degenerate_faces(tmesh,
|
return remove_degenerate_faces(tmesh,
|
||||||
CGAL::Polygon_mesh_processing::parameters::all_default());
|
CGAL::Polygon_mesh_processing::parameters::all_default());
|
||||||
|
|
|
||||||
|
|
@ -402,45 +402,70 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren
|
||||||
}
|
}
|
||||||
|
|
||||||
//Recursive function that do a pass over a menu and its sub-menus(etc.) and hide them when they are empty
|
//Recursive function that do a pass over a menu and its sub-menus(etc.) and hide them when they are empty
|
||||||
void filterMenuOperations(QMenu* menu, bool showFullMenu)
|
void filterMenuOperations(QMenu* menu, QString filter, bool keep_from_here)
|
||||||
{
|
{
|
||||||
Q_FOREACH(QAction* action, menu->actions()) {
|
QList<QAction*> buffer;
|
||||||
if(QMenu* menu = action->menu())
|
Q_FOREACH(QAction* action, menu->actions())
|
||||||
{
|
buffer.append(action);
|
||||||
filterMenuOperations(menu, showFullMenu);
|
while(!buffer.isEmpty()){
|
||||||
action->setVisible(showFullMenu && !(menu->isEmpty()));
|
|
||||||
|
Q_FOREACH(QAction* action, buffer) {
|
||||||
|
if(QMenu* submenu = action->menu())
|
||||||
|
{
|
||||||
|
bool keep = true;
|
||||||
|
if(!keep_from_here){
|
||||||
|
keep = submenu->menuAction()->text().contains(filter, Qt::CaseInsensitive);
|
||||||
|
if(!keep)
|
||||||
|
{
|
||||||
|
Q_FOREACH(QAction* subaction, submenu->actions())
|
||||||
|
{
|
||||||
|
submenu->removeAction(subaction);
|
||||||
|
buffer.append(subaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menu->addAction(submenu->menuAction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterMenuOperations(submenu, filter, keep);
|
||||||
|
action->setVisible(!(submenu->isEmpty()));
|
||||||
|
}
|
||||||
|
else if(action->text().contains(filter, Qt::CaseInsensitive)){
|
||||||
|
menu->addAction(action);
|
||||||
|
}
|
||||||
|
buffer.removeAll(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::filterOperations()
|
void MainWindow::filterOperations()
|
||||||
{
|
{
|
||||||
static QVector<QAction*> to_remove;
|
//return actions to their true menu
|
||||||
Q_FOREACH(QAction* action, to_remove)
|
Q_FOREACH(QMenu* menu, action_menu_map.values())
|
||||||
ui->menuOperations->removeAction(action);
|
{
|
||||||
QString filter=operationSearchBar.text();
|
Q_FOREACH(QAction* action, menu->actions())
|
||||||
if(!filter.isEmpty())
|
{
|
||||||
Q_FOREACH(const PluginNamePair& p, plugins) {
|
if(action != searchAction)
|
||||||
Q_FOREACH(QAction* action, p.first->actions()) {
|
menu->removeAction(action);
|
||||||
action->setVisible( p.first->applicable(action)
|
|
||||||
&& action->text().contains(filter, Qt::CaseInsensitive));
|
|
||||||
if(action->menu() != ui->menuOperations){
|
|
||||||
ui->menuOperations->addAction(action);
|
|
||||||
to_remove.push_back(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
Q_FOREACH(const PluginNamePair& p, plugins) {
|
|
||||||
Q_FOREACH(QAction* action, p.first->actions()) {
|
|
||||||
action->setVisible( p.first->applicable(action)
|
|
||||||
&& action->text().contains(filter, Qt::CaseInsensitive));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// do a pass over all menus in Operations and their sub-menus(etc.) and hide them when they are empty
|
|
||||||
}
|
}
|
||||||
filterMenuOperations(ui->menuOperations, filter.isEmpty());
|
Q_FOREACH(QAction* action, action_menu_map.keys())
|
||||||
|
{
|
||||||
|
action_menu_map[action]->addAction(action);
|
||||||
|
}
|
||||||
|
QString filter=operationSearchBar.text();
|
||||||
|
Q_FOREACH(const PluginNamePair& p, plugins) {
|
||||||
|
Q_FOREACH(QAction* action, p.first->actions()) {
|
||||||
|
action->setVisible( p.first->applicable(action)
|
||||||
|
&& (action->text().contains(filter, Qt::CaseInsensitive)
|
||||||
|
|| action->property("subMenuName")
|
||||||
|
.toString().contains(filter, Qt::CaseInsensitive)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// do a pass over all menus in Operations and their sub-menus(etc.) and hide them when they are empty
|
||||||
|
filterMenuOperations(ui->menuOperations, filter, false);
|
||||||
|
operationSearchBar.setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <CGAL/Three/exceptions.h>
|
#include <CGAL/Three/exceptions.h>
|
||||||
|
|
@ -549,12 +574,14 @@ void MainWindow::setMenus(QString name, QString parentName, QAction* a )
|
||||||
menu_map[parentName] = new QMenu(parentName, this);
|
menu_map[parentName] = new QMenu(parentName, this);
|
||||||
// add the submenu in the menu
|
// add the submenu in the menu
|
||||||
menu_map[parentName]->addMenu(menu_map[menuName]);
|
menu_map[parentName]->addMenu(menu_map[menuName]);
|
||||||
|
action_menu_map[menu_map[menuName]->menuAction()] = menu_map[parentName];
|
||||||
|
|
||||||
// only add the action in the last submenu
|
// only add the action in the last submenu
|
||||||
if(slash_index==-1)
|
if(slash_index==-1)
|
||||||
{
|
{
|
||||||
ui->menuOperations->removeAction(a);
|
ui->menuOperations->removeAction(a);
|
||||||
menu_map[menuName]->addAction(a);
|
menu_map[menuName]->addAction(a);
|
||||||
|
action_menu_map[a] = menu_map[menuName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -765,6 +792,7 @@ bool MainWindow::initPlugin(QObject* obj)
|
||||||
// If action does not belong to the menus, add it to "Operations" menu
|
// If action does not belong to the menus, add it to "Operations" menu
|
||||||
if(!childs.contains(action)) {
|
if(!childs.contains(action)) {
|
||||||
ui->menuOperations->addAction(action);
|
ui->menuOperations->addAction(action);
|
||||||
|
action_menu_map[action] = ui->menuOperations;
|
||||||
}
|
}
|
||||||
// Show and enable menu item
|
// Show and enable menu item
|
||||||
addAction(action);
|
addAction(action);
|
||||||
|
|
@ -968,6 +996,8 @@ void MainWindow::reloadItem() {
|
||||||
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
|
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
|
||||||
{
|
{
|
||||||
item = scene->item(id);
|
item = scene->item(id);
|
||||||
|
if(!item)//secure items like selection items that get deleted when their "parent" item is reloaded.
|
||||||
|
continue;
|
||||||
QString filename = item->property("source filename").toString();
|
QString filename = item->property("source filename").toString();
|
||||||
QString loader_name = item->property("loader_name").toString();
|
QString loader_name = item->property("loader_name").toString();
|
||||||
if(filename.isEmpty() || loader_name.isEmpty()) {
|
if(filename.isEmpty() || loader_name.isEmpty()) {
|
||||||
|
|
@ -986,9 +1016,9 @@ void MainWindow::reloadItem() {
|
||||||
new_item->setRenderingMode(item->renderingMode());
|
new_item->setRenderingMode(item->renderingMode());
|
||||||
new_item->setVisible(item->visible());
|
new_item->setVisible(item->visible());
|
||||||
Scene_item_with_properties *property_item = dynamic_cast<Scene_item_with_properties*>(new_item);
|
Scene_item_with_properties *property_item = dynamic_cast<Scene_item_with_properties*>(new_item);
|
||||||
|
scene->replaceItem(scene->item_id(item), new_item, true);
|
||||||
if(property_item)
|
if(property_item)
|
||||||
property_item->copyProperties(item);
|
property_item->copyProperties(item);
|
||||||
scene->replaceItem(scene->item_id(item), new_item, true);
|
|
||||||
new_item->invalidateOpenGLBuffers();
|
new_item->invalidateOpenGLBuffers();
|
||||||
item->deleteLater();
|
item->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
@ -1169,16 +1199,19 @@ bool MainWindow::open(QString filename, QString loader_name) {
|
||||||
CGAL::Three::Scene_item* MainWindow::loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface* loader) {
|
CGAL::Three::Scene_item* MainWindow::loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface* loader) {
|
||||||
CGAL::Three::Scene_item* item = NULL;
|
CGAL::Three::Scene_item* item = NULL;
|
||||||
if(!fileinfo.isFile() || !fileinfo.isReadable()) {
|
if(!fileinfo.isFile() || !fileinfo.isReadable()) {
|
||||||
throw std::invalid_argument(QString("File %1 is not a readable file.")
|
QMessageBox::warning(this, tr("Error"),
|
||||||
.arg(fileinfo.absoluteFilePath()).toStdString());
|
QString("File %1 is not a readable file.")
|
||||||
|
.arg(fileinfo.absoluteFilePath()));
|
||||||
}
|
}
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
item = loader->load(fileinfo);
|
item = loader->load(fileinfo);
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
if(!item) {
|
if(!item) {
|
||||||
throw std::logic_error(QString("Could not load item from file %1 using plugin %2")
|
QMessageBox::warning(this, tr("Error"),
|
||||||
.arg(fileinfo.absoluteFilePath()).arg(loader->name()).toStdString());
|
QString("Could not load item from file %1 using plugin %2")
|
||||||
|
.arg(fileinfo.absoluteFilePath()).arg(loader->name()));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setProperty("source filename", fileinfo.absoluteFilePath());
|
item->setProperty("source filename", fileinfo.absoluteFilePath());
|
||||||
|
|
@ -1201,11 +1234,13 @@ void MainWindow::selectSceneItem(int i)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
QItemSelection s =
|
QItemSelection s =
|
||||||
proxyModel->mapSelectionFromSource(scene->createSelection(i));
|
proxyModel->mapSelectionFromSource(scene->createSelection(i));
|
||||||
|
QModelIndex mi = proxyModel->mapFromSource(scene->getModelIndexFromId(i).first());
|
||||||
|
sceneView->setCurrentIndex(mi);
|
||||||
sceneView->selectionModel()->select(s,
|
sceneView->selectionModel()->select(s,
|
||||||
QItemSelectionModel::ClearAndSelect);
|
QItemSelectionModel::ClearAndSelect);
|
||||||
sceneView->scrollTo(s.indexes().first());
|
sceneView->scrollTo(s.indexes().first());
|
||||||
|
sceneView->setCurrentIndex(sceneView->selectionModel()->selectedIndexes().first());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1220,6 +1255,8 @@ void MainWindow::selectSceneItems(QList<int> is)
|
||||||
QItemSelection s =
|
QItemSelection s =
|
||||||
proxyModel->mapSelectionFromSource(scene->createSelection(is));
|
proxyModel->mapSelectionFromSource(scene->createSelection(is));
|
||||||
|
|
||||||
|
QModelIndex i = proxyModel->mapFromSource(scene->getModelIndexFromId(is.first()).first());
|
||||||
|
sceneView->setCurrentIndex(i);
|
||||||
sceneView->selectionModel()->select(s,
|
sceneView->selectionModel()->select(s,
|
||||||
QItemSelectionModel::ClearAndSelect);
|
QItemSelectionModel::ClearAndSelect);
|
||||||
sceneView->scrollTo(s.indexes().first());
|
sceneView->scrollTo(s.indexes().first());
|
||||||
|
|
@ -1403,6 +1440,15 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
|
||||||
QMap<QString, QAction*> menu_actions;
|
QMap<QString, QAction*> menu_actions;
|
||||||
QVector<QMenu*> slider_menus;
|
QVector<QMenu*> slider_menus;
|
||||||
bool has_stats = false;
|
bool has_stats = false;
|
||||||
|
bool has_reload = false;
|
||||||
|
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
|
||||||
|
{
|
||||||
|
if(!scene->item(id)->property("source filename").toString().isEmpty())
|
||||||
|
{
|
||||||
|
has_reload = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
Q_FOREACH(QAction* action, scene->item(main_index)->contextMenu()->actions())
|
Q_FOREACH(QAction* action, scene->item(main_index)->contextMenu()->actions())
|
||||||
{
|
{
|
||||||
if(action->property("is_groupable").toBool())
|
if(action->property("is_groupable").toBool())
|
||||||
|
|
@ -1565,10 +1611,13 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
|
||||||
connect(actionStatistics, SIGNAL(triggered()),
|
connect(actionStatistics, SIGNAL(triggered()),
|
||||||
this, SLOT(statisticsOnItem()));
|
this, SLOT(statisticsOnItem()));
|
||||||
}
|
}
|
||||||
|
if(has_reload)
|
||||||
|
{
|
||||||
QAction* reload = menu.addAction(tr("&Reload Item from File"));
|
QAction* reload = menu.addAction(tr("&Reload Item from File"));
|
||||||
reload->setProperty("is_groupable", true);
|
reload->setProperty("is_groupable", true);
|
||||||
connect(reload, SIGNAL(triggered()),
|
connect(reload, SIGNAL(triggered()),
|
||||||
this, SLOT(reloadItem()));
|
this, SLOT(reloadItem()));
|
||||||
|
}
|
||||||
QAction* saveas = menu.addAction(tr("&Save as..."));
|
QAction* saveas = menu.addAction(tr("&Save as..."));
|
||||||
connect(saveas, SIGNAL(triggered()),
|
connect(saveas, SIGNAL(triggered()),
|
||||||
this, SLOT(on_actionSaveAs_triggered()));
|
this, SLOT(on_actionSaveAs_triggered()));
|
||||||
|
|
@ -2196,6 +2245,8 @@ void MainWindow::on_actionLookAt_triggered()
|
||||||
if( i == QDialog::Accepted &&
|
if( i == QDialog::Accepted &&
|
||||||
dialog.has_correct_coordinates() )
|
dialog.has_correct_coordinates() )
|
||||||
{
|
{
|
||||||
|
if(viewer->camera()->frame()->isSpinning())
|
||||||
|
viewer->camera()->frame()->stopSpinning();
|
||||||
viewerShow((float)dialog.get_x()+viewer->offset().x,
|
viewerShow((float)dialog.get_x()+viewer->offset().x,
|
||||||
(float)dialog.get_y()+viewer->offset().y,
|
(float)dialog.get_y()+viewer->offset().y,
|
||||||
(float)dialog.get_z()+viewer->offset().z);
|
(float)dialog.get_z()+viewer->offset().z);
|
||||||
|
|
|
||||||
|
|
@ -453,6 +453,9 @@ private:
|
||||||
QMap<QString, QPair<QStringList, QString> >plugin_metadata_map;
|
QMap<QString, QPair<QStringList, QString> >plugin_metadata_map;
|
||||||
QMap<QString, bool> ignored_map;
|
QMap<QString, bool> ignored_map;
|
||||||
const QStringList& accepted_keywords;
|
const QStringList& accepted_keywords;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMap<QAction*, QMenu*> action_menu_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ifndef MAINWINDOW_H
|
#endif // ifndef MAINWINDOW_H
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFinite() const { return true; }
|
bool isFinite() const { return false; }
|
||||||
bool isEmpty() const { return is_tree_empty; }
|
bool isEmpty() const { return is_tree_empty; }
|
||||||
//computed in constructor
|
//computed in constructor
|
||||||
void compute_bbox() const {}
|
void compute_bbox() const {}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <CGAL/boost/graph/helpers.h>
|
#include <CGAL/boost/graph/helpers.h>
|
||||||
|
|
||||||
#include "Kernel_type.h"
|
#include "Kernel_type.h"
|
||||||
|
#include <CGAL/Three/Three.h>
|
||||||
typedef Kernel::Plane_3 Plane;
|
typedef Kernel::Plane_3 Plane;
|
||||||
typedef Kernel::Iso_cuboid_3 Iso_cuboid;
|
typedef Kernel::Iso_cuboid_3 Iso_cuboid;
|
||||||
typedef Kernel::Triangle_3 Triangle;
|
typedef Kernel::Triangle_3 Triangle;
|
||||||
|
|
@ -99,148 +100,150 @@ void Polyhedron_demo_pca_plugin::on_actionFitPlane_triggered()
|
||||||
Scene_surface_mesh_item* sm_item =
|
Scene_surface_mesh_item* sm_item =
|
||||||
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
||||||
|
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
Three::CursorScopeGuard scope(Qt::WaitCursor);
|
||||||
|
if(sm_item){
|
||||||
std::list<Triangle> triangles;
|
std::list<Triangle> triangles;
|
||||||
|
|
||||||
SMesh* pMesh = sm_item->polyhedron();
|
SMesh* pMesh = sm_item->polyhedron();
|
||||||
::triangles(*pMesh,std::back_inserter(triangles));
|
::triangles(*pMesh,std::back_inserter(triangles));
|
||||||
|
|
||||||
if(! triangles.empty()){
|
if(! triangles.empty()){
|
||||||
QString item_name = sm_item->name();
|
QString item_name = sm_item->name();
|
||||||
// fit plane to triangles
|
// fit plane to triangles
|
||||||
Plane plane;
|
Plane plane;
|
||||||
std::cout << "Fit plane...";
|
std::cout << "Fit plane...";
|
||||||
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),plane,CGAL::Dimension_tag<2>());
|
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),plane,CGAL::Dimension_tag<2>());
|
||||||
std::cout << "ok" << std::endl;
|
std::cout << "ok" << std::endl;
|
||||||
|
|
||||||
// compute centroid
|
// compute centroid
|
||||||
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
||||||
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
||||||
new_item->setPosition(center_of_mass.x(),
|
new_item->setPosition(center_of_mass.x(),
|
||||||
center_of_mass.y(),
|
center_of_mass.y(),
|
||||||
center_of_mass.z());
|
center_of_mass.z());
|
||||||
const Vector& normal = plane.orthogonal_vector();
|
const Vector& normal = plane.orthogonal_vector();
|
||||||
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
||||||
new_item->setName(tr("%1 (plane fit)").arg(item_name));
|
new_item->setName(tr("%1 (plane fit)").arg(item_name));
|
||||||
new_item->setColor(Qt::magenta);
|
new_item->setColor(Qt::magenta);
|
||||||
new_item->setRenderingMode(sm_item->renderingMode());
|
new_item->setRenderingMode(sm_item->renderingMode());
|
||||||
scene->addItem(new_item);
|
scene->addItem(new_item);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
Scene_points_with_normal_item* item =
|
||||||
Scene_points_with_normal_item* item =
|
qobject_cast<Scene_points_with_normal_item*>(scene->item(index));
|
||||||
qobject_cast<Scene_points_with_normal_item*>(scene->item(index));
|
|
||||||
|
if (item)
|
||||||
if (item)
|
{
|
||||||
{
|
Point_set* points = item->point_set();
|
||||||
Point_set* points = item->point_set();
|
|
||||||
|
// fit plane to triangles
|
||||||
// fit plane to triangles
|
Plane plane;
|
||||||
Plane plane;
|
Point center_of_mass;
|
||||||
Point center_of_mass;
|
std::cout << "Fit plane...";
|
||||||
std::cout << "Fit plane...";
|
CGAL::linear_least_squares_fitting_3
|
||||||
CGAL::linear_least_squares_fitting_3
|
(points->points().begin(),points->points().end(),plane, center_of_mass,
|
||||||
(points->points().begin(),points->points().end(),plane, center_of_mass,
|
CGAL::Dimension_tag<0>());
|
||||||
CGAL::Dimension_tag<0>());
|
std::cout << "ok" << std::endl;
|
||||||
std::cout << "ok" << std::endl;
|
|
||||||
|
// compute centroid
|
||||||
// compute centroid
|
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
||||||
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
new_item->setPosition(center_of_mass.x(),
|
||||||
new_item->setPosition(center_of_mass.x(),
|
center_of_mass.y(),
|
||||||
center_of_mass.y(),
|
center_of_mass.z());
|
||||||
center_of_mass.z());
|
const Vector& normal = plane.orthogonal_vector();
|
||||||
const Vector& normal = plane.orthogonal_vector();
|
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
||||||
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
new_item->setName(tr("%1 (plane fit)").arg(item->name()));
|
||||||
new_item->setName(tr("%1 (plane fit)").arg(item->name()));
|
new_item->setColor(Qt::magenta);
|
||||||
new_item->setColor(Qt::magenta);
|
new_item->setRenderingMode(item->renderingMode());
|
||||||
new_item->setRenderingMode(item->renderingMode());
|
scene->addItem(new_item);
|
||||||
scene->addItem(new_item);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
QApplication::restoreOverrideCursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Polyhedron_demo_pca_plugin::on_actionFitLine_triggered()
|
void Polyhedron_demo_pca_plugin::on_actionFitLine_triggered()
|
||||||
{
|
{
|
||||||
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
|
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
|
||||||
|
|
||||||
|
Three::CursorScopeGuard sg(Qt::WaitCursor);
|
||||||
|
|
||||||
Scene_surface_mesh_item* sm_item =
|
Scene_surface_mesh_item* sm_item =
|
||||||
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
||||||
|
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
||||||
|
|
||||||
CGAL::Bbox_3 bb;
|
|
||||||
|
|
||||||
std::list<Triangle> triangles;
|
if(sm_item)
|
||||||
SMesh* pMesh = sm_item->polyhedron();
|
{
|
||||||
bb = ::triangles(*pMesh,std::back_inserter(triangles));
|
CGAL::Bbox_3 bb;
|
||||||
|
|
||||||
if(! triangles.empty()){
|
SMesh* pMesh = sm_item->polyhedron();
|
||||||
QString item_name = sm_item->name();
|
std::list<Triangle> triangles;
|
||||||
// fit line to triangles
|
|
||||||
Line line;
|
bb = ::triangles(*pMesh,std::back_inserter(triangles));
|
||||||
std::cout << "Fit line...";
|
|
||||||
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),line,CGAL::Dimension_tag<2>());
|
if(! triangles.empty()){
|
||||||
std::cout << "ok" << std::endl;
|
QString item_name = sm_item->name();
|
||||||
|
// fit line to triangles
|
||||||
// compute centroid
|
Line line;
|
||||||
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
std::cout << "Fit line...";
|
||||||
|
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),line,CGAL::Dimension_tag<2>());
|
||||||
// compute bounding box diagonal
|
std::cout << "ok" << std::endl;
|
||||||
Iso_cuboid bbox(bb);
|
|
||||||
|
// compute centroid
|
||||||
// compute scale for rendering using diagonal of bbox
|
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
||||||
Point cmin = (bbox.min)();
|
|
||||||
Point cmax = (bbox.max)();
|
// compute bounding box diagonal
|
||||||
FT diag = std::sqrt(CGAL::squared_distance(cmin,cmax));
|
Iso_cuboid bbox(bb);
|
||||||
|
|
||||||
// construct a 3D bar
|
// compute scale for rendering using diagonal of bbox
|
||||||
Vector u = line.to_vector();
|
Point cmin = (bbox.min)();
|
||||||
u = u / std::sqrt(u*u);
|
Point cmax = (bbox.max)();
|
||||||
|
FT diag = std::sqrt(CGAL::squared_distance(cmin,cmax));
|
||||||
Point a = center_of_mass + u * diag;
|
|
||||||
Point b = center_of_mass - u * diag;
|
// construct a 3D bar
|
||||||
|
Vector u = line.to_vector();
|
||||||
Plane plane_a = line.perpendicular_plane(a);
|
u = u / std::sqrt(u*u);
|
||||||
|
|
||||||
Vector u1 = plane_a.base1();
|
Point a = center_of_mass + u * diag;
|
||||||
u1 = u1 / std::sqrt(u1*u1);
|
Point b = center_of_mass - u * diag;
|
||||||
u1 = u1 * 0.01 * diag;
|
|
||||||
Vector u2 = plane_a.base2();
|
Plane plane_a = line.perpendicular_plane(a);
|
||||||
u2 = u2 / std::sqrt(u2*u2);
|
|
||||||
u2 = u2 * 0.01 * diag;
|
Vector u1 = plane_a.base1();
|
||||||
|
u1 = u1 / std::sqrt(u1*u1);
|
||||||
Point points[8];
|
u1 = u1 * 0.01 * diag;
|
||||||
|
Vector u2 = plane_a.base2();
|
||||||
points[0] = a + u1;
|
u2 = u2 / std::sqrt(u2*u2);
|
||||||
points[1] = a + u2;
|
u2 = u2 * 0.01 * diag;
|
||||||
points[2] = a - u1;
|
|
||||||
points[3] = a - u2;
|
Point points[8];
|
||||||
|
|
||||||
points[4] = b + u1;
|
points[0] = a + u1;
|
||||||
points[5] = b + u2;
|
points[1] = a + u2;
|
||||||
points[6] = b - u1;
|
points[2] = a - u1;
|
||||||
points[7] = b - u2;
|
points[3] = a - u2;
|
||||||
|
|
||||||
// add best fit line as new polyhedron bar
|
points[4] = b + u1;
|
||||||
SMesh* pFit = new SMesh;
|
points[5] = b + u2;
|
||||||
CGAL::make_hexahedron(points[0],
|
points[6] = b - u1;
|
||||||
points[1],
|
points[7] = b - u2;
|
||||||
points[2],
|
|
||||||
points[3],
|
// add best fit line as new polyhedron bar
|
||||||
points[4],
|
SMesh* pFit = new SMesh;
|
||||||
points[5],
|
CGAL::make_hexahedron(
|
||||||
points[6],
|
points[0],
|
||||||
points[7],
|
points[3],
|
||||||
*pFit);
|
points[2],
|
||||||
Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item(pFit);
|
points[1],
|
||||||
new_item->setName(tr("%1 (line fit)").arg(item_name));
|
points[5],
|
||||||
new_item->setColor(Qt::magenta);
|
points[4],
|
||||||
new_item->setRenderingMode( sm_item->renderingMode());
|
points[7],
|
||||||
scene->addItem(new_item);
|
points[6],
|
||||||
|
*pFit);
|
||||||
|
Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item(pFit);
|
||||||
|
new_item->setName(tr("%1 (line fit)").arg(item_name));
|
||||||
|
new_item->setColor(Qt::magenta);
|
||||||
|
new_item->setRenderingMode( sm_item->renderingMode());
|
||||||
|
scene->addItem(new_item);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -297,15 +300,16 @@ void Polyhedron_demo_pca_plugin::on_actionFitLine_triggered()
|
||||||
points[7] = b - u2;
|
points[7] = b - u2;
|
||||||
|
|
||||||
SMesh* pFit = new SMesh;
|
SMesh* pFit = new SMesh;
|
||||||
CGAL::make_hexahedron(points[0],
|
CGAL::make_hexahedron(
|
||||||
points[1],
|
points[0],
|
||||||
points[2],
|
points[3],
|
||||||
points[3],
|
points[2],
|
||||||
points[4],
|
points[1],
|
||||||
points[5],
|
points[5],
|
||||||
points[6],
|
points[4],
|
||||||
points[7],
|
points[7],
|
||||||
*pFit);
|
points[6],
|
||||||
|
*pFit);
|
||||||
Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item(pFit);
|
Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item(pFit);
|
||||||
new_item->setName(tr("%1 (line fit)").arg(item->name()));
|
new_item->setName(tr("%1 (line fit)").arg(item->name()));
|
||||||
new_item->setColor(Qt::magenta);
|
new_item->setColor(Qt::magenta);
|
||||||
|
|
@ -313,8 +317,6 @@ void Polyhedron_demo_pca_plugin::on_actionFitLine_triggered()
|
||||||
scene->addItem(new_item);
|
scene->addItem(new_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Pca_plugin.moc"
|
#include "Pca_plugin.moc"
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,8 @@ private:
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
try{
|
try{
|
||||||
PMP::corefine(*item1->face_graph(), *item2->face_graph(), params::throw_on_self_intersection(true));
|
PMP::corefine(*item1->face_graph(), *item2->face_graph(), params::throw_on_self_intersection(true));
|
||||||
|
item1->resetColors();
|
||||||
|
item2->resetColors();
|
||||||
item1->invalidateOpenGLBuffers();
|
item1->invalidateOpenGLBuffers();
|
||||||
item2->invalidateOpenGLBuffers();
|
item2->invalidateOpenGLBuffers();
|
||||||
scene->itemChanged(item2);
|
scene->itemChanged(item2);
|
||||||
|
|
|
||||||
|
|
@ -302,7 +302,11 @@ private:
|
||||||
Messages_interface* messages;
|
Messages_interface* messages;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
~Engrave_text_plugin()
|
||||||
|
{
|
||||||
|
delete graphics_scene;
|
||||||
|
delete navigation;
|
||||||
|
}
|
||||||
void init(QMainWindow*,
|
void init(QMainWindow*,
|
||||||
CGAL::Three::Scene_interface*,
|
CGAL::Three::Scene_interface*,
|
||||||
Messages_interface* m) Q_DECL_OVERRIDE{
|
Messages_interface* m) Q_DECL_OVERRIDE{
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,7 @@ private Q_SLOTS:
|
||||||
Kernel::Vector_3(dir.x(), dir.y(), dir.z()));
|
Kernel::Vector_3(dir.x(), dir.y(), dir.z()));
|
||||||
scene->erase(scene->item_id(oliver_queen));
|
scene->erase(scene->item_id(oliver_queen));
|
||||||
oliver_queen = NULL;
|
oliver_queen = NULL;
|
||||||
|
target->resetColors();
|
||||||
target->invalidateOpenGLBuffers();
|
target->invalidateOpenGLBuffers();
|
||||||
target->itemChanged();
|
target->itemChanged();
|
||||||
target = NULL;
|
target = NULL;
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ public Q_SLOTS:
|
||||||
CGAL::Polygon_mesh_processing::fair(*selection_item->polyhedron(),
|
CGAL::Polygon_mesh_processing::fair(*selection_item->polyhedron(),
|
||||||
selection_item->selected_vertices,
|
selection_item->selected_vertices,
|
||||||
CGAL::Polygon_mesh_processing::parameters::fairing_continuity(continuity));
|
CGAL::Polygon_mesh_processing::parameters::fairing_continuity(continuity));
|
||||||
|
selection_item->polyhedron_item()->resetColors();
|
||||||
selection_item->changed_with_poly_item();
|
selection_item->changed_with_poly_item();
|
||||||
selection_item->invalidateOpenGLBuffers();
|
selection_item->invalidateOpenGLBuffers();
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
|
|
@ -128,6 +129,7 @@ public Q_SLOTS:
|
||||||
for(std::vector<boost::graph_traits<FaceGraph>::face_descriptor>::iterator it = new_facets.begin(); it != new_facets.end(); ++it) {
|
for(std::vector<boost::graph_traits<FaceGraph>::face_descriptor>::iterator it = new_facets.begin(); it != new_facets.end(); ++it) {
|
||||||
selection_item->selected_facets.insert(*it);
|
selection_item->selected_facets.insert(*it);
|
||||||
}
|
}
|
||||||
|
selection_item->polyhedron_item()->resetColors();
|
||||||
selection_item->changed_with_poly_item();
|
selection_item->changed_with_poly_item();
|
||||||
selection_item->invalidateOpenGLBuffers();
|
selection_item->invalidateOpenGLBuffers();
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
|
|
|
||||||
|
|
@ -366,6 +366,7 @@ protected:
|
||||||
|
|
||||||
void change_poly_item_by_blocking(Scene_face_graph_item* poly_item, Scene_hole_visualizer* collection) {
|
void change_poly_item_by_blocking(Scene_face_graph_item* poly_item, Scene_hole_visualizer* collection) {
|
||||||
if(collection) collection->block_poly_item_changed = true;
|
if(collection) collection->block_poly_item_changed = true;
|
||||||
|
poly_item->resetColors();
|
||||||
poly_item->invalidateOpenGLBuffers();
|
poly_item->invalidateOpenGLBuffers();
|
||||||
poly_item->redraw();
|
poly_item->redraw();
|
||||||
if(collection) collection->block_poly_item_changed = false;
|
if(collection) collection->block_poly_item_changed = false;
|
||||||
|
|
@ -860,7 +861,7 @@ void Polyhedron_demo_hole_filling_plugin::on_Fill_from_selection_button() {
|
||||||
last_active_item = edge_selection->polyhedron_item();
|
last_active_item = edge_selection->polyhedron_item();
|
||||||
accept_reject_toggle(true);
|
accept_reject_toggle(true);
|
||||||
}
|
}
|
||||||
|
edge_selection->polyhedron_item()->resetColors();
|
||||||
edge_selection->polyhedron_item()->invalidateOpenGLBuffers();
|
edge_selection->polyhedron_item()->invalidateOpenGLBuffers();
|
||||||
edge_selection->polyhedron_item()->itemChanged();
|
edge_selection->polyhedron_item()->itemChanged();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,11 @@ class Polyhedron_demo_mean_curvature_flow_skeleton_plugin :
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
~Polyhedron_demo_mean_curvature_flow_skeleton_plugin()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) {
|
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) {
|
||||||
|
|
||||||
this->mw = mainWindow;
|
this->mw = mainWindow;
|
||||||
|
|
|
||||||
|
|
@ -148,9 +148,10 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionRemoveDegenerateFaces_tr
|
||||||
qobject_cast<Item*>(scene->item(index));
|
qobject_cast<Item*>(scene->item(index));
|
||||||
if (poly_item)
|
if (poly_item)
|
||||||
{
|
{
|
||||||
std::size_t nbv =
|
std::size_t nbv = num_faces(*poly_item->polyhedron());
|
||||||
CGAL::Polygon_mesh_processing::remove_degenerate_faces(
|
CGAL::Polygon_mesh_processing::remove_degenerate_faces(
|
||||||
*poly_item->polyhedron());
|
*poly_item->polyhedron());
|
||||||
|
nbv -= num_faces(*poly_item->polyhedron());
|
||||||
CGAL::Three::Three::information(tr(" %1 degenerate faces have been removed.")
|
CGAL::Three::Three::information(tr(" %1 degenerate faces have been removed.")
|
||||||
.arg(nbv));
|
.arg(nbv));
|
||||||
poly_item->invalidateOpenGLBuffers();
|
poly_item->invalidateOpenGLBuffers();
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,8 @@ public Q_SLOTS:
|
||||||
// slots are called by signals of polyhedron_item
|
// slots are called by signals of polyhedron_item
|
||||||
void vertex_has_been_selected(void* void_ptr)
|
void vertex_has_been_selected(void* void_ptr)
|
||||||
{
|
{
|
||||||
|
if((*CGAL::QGLViewer::QGLViewerPool().begin())->property("performing_selection").toBool())
|
||||||
|
return;
|
||||||
is_active=true;
|
is_active=true;
|
||||||
if(active_handle_type == Active_handle::VERTEX || active_handle_type == Active_handle::PATH)
|
if(active_handle_type == Active_handle::VERTEX || active_handle_type == Active_handle::PATH)
|
||||||
{
|
{
|
||||||
|
|
@ -145,6 +147,8 @@ public Q_SLOTS:
|
||||||
}
|
}
|
||||||
void facet_has_been_selected(void* void_ptr)
|
void facet_has_been_selected(void* void_ptr)
|
||||||
{
|
{
|
||||||
|
if((*CGAL::QGLViewer::QGLViewerPool().begin())->property("performing_selection").toBool())
|
||||||
|
return;
|
||||||
is_active=true;
|
is_active=true;
|
||||||
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)
|
||||||
|
|
@ -157,6 +161,8 @@ public Q_SLOTS:
|
||||||
}
|
}
|
||||||
void edge_has_been_selected(void* void_ptr)
|
void edge_has_been_selected(void* void_ptr)
|
||||||
{
|
{
|
||||||
|
if((*CGAL::QGLViewer::QGLViewerPool().begin())->property("performing_selection").toBool())
|
||||||
|
return;
|
||||||
is_active=true;
|
is_active=true;
|
||||||
if(active_handle_type == Active_handle::EDGE)
|
if(active_handle_type == Active_handle::EDGE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,11 @@ public:
|
||||||
dock_widget->setWindowTitle(tr(
|
dock_widget->setWindowTitle(tr(
|
||||||
"Surface Mesh Selection"
|
"Surface Mesh Selection"
|
||||||
));
|
));
|
||||||
|
connect(dock_widget, &QDockWidget::visibilityChanged,
|
||||||
|
this, [this](bool b){
|
||||||
|
if(!b)
|
||||||
|
this->set_operation_mode(-1);
|
||||||
|
});
|
||||||
|
|
||||||
addDockWidget(dock_widget);
|
addDockWidget(dock_widget);
|
||||||
|
|
||||||
|
|
@ -771,7 +776,8 @@ public Q_SLOTS:
|
||||||
bool is_valid = true;
|
bool is_valid = true;
|
||||||
BOOST_FOREACH(boost::graph_traits<Face_graph>::face_descriptor fd, faces(*selection_item->polyhedron()))
|
BOOST_FOREACH(boost::graph_traits<Face_graph>::face_descriptor fd, faces(*selection_item->polyhedron()))
|
||||||
{
|
{
|
||||||
if (CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(fd, *selection_item->polyhedron()))
|
if (is_triangle(halfedge(fd, *selection_item->polyhedron()), *selection_item->polyhedron())
|
||||||
|
&& CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(fd, *selection_item->polyhedron()))
|
||||||
{
|
{
|
||||||
is_valid = false;
|
is_valid = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -551,7 +551,7 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Split edges</string>
|
<string>Split edge</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,8 @@ public Q_SLOTS:
|
||||||
}
|
}
|
||||||
if(!CGAL::Polygon_mesh_processing::triangulate_faces(*pMesh))
|
if(!CGAL::Polygon_mesh_processing::triangulate_faces(*pMesh))
|
||||||
CGAL::Three::Three::warning(tr("Some facets could not be triangulated."));
|
CGAL::Three::Three::warning(tr("Some facets could not be triangulated."));
|
||||||
|
|
||||||
|
sm_item->resetColors();
|
||||||
sm_item->invalidateOpenGLBuffers();
|
sm_item->invalidateOpenGLBuffers();
|
||||||
scene->itemChanged(sm_item);
|
scene->itemChanged(sm_item);
|
||||||
} // end of the loop on the selected items
|
} // end of the loop on the selected items
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,10 @@ public:
|
||||||
return _actions;
|
return _actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Polyhedron_demo_parameterization_plugin()
|
||||||
|
{
|
||||||
|
delete navigation;
|
||||||
|
}
|
||||||
void init(QMainWindow* mainWindow,
|
void init(QMainWindow* mainWindow,
|
||||||
Scene_interface* scene_interface,
|
Scene_interface* scene_interface,
|
||||||
Messages_interface* msg)
|
Messages_interface* msg)
|
||||||
|
|
@ -825,6 +829,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
|
||||||
if (i == QDialog::Rejected)
|
if (i == QDialog::Rejected)
|
||||||
{
|
{
|
||||||
std::cout << "Aborting parameterization" << std::endl;
|
std::cout << "Aborting parameterization" << std::endl;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -837,6 +842,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
|
||||||
std::cerr << "Error: incompatible orbifold type and number of cones" << std::endl;
|
std::cerr << "Error: incompatible orbifold type and number of cones" << std::endl;
|
||||||
std::cerr << "Types I, II & III require 3 selected vertices" << std::endl;
|
std::cerr << "Types I, II & III require 3 selected vertices" << std::endl;
|
||||||
std::cerr << "Type IV requires 4 selected vertices" << std::endl;
|
std::cerr << "Type IV requires 4 selected vertices" << std::endl;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -848,6 +854,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
|
||||||
if(!SMP::locate_unordered_cones(sMesh, unordered_cones.begin(), unordered_cones.end(), cmap))
|
if(!SMP::locate_unordered_cones(sMesh, unordered_cones.begin(), unordered_cones.end(), cmap))
|
||||||
{
|
{
|
||||||
std::cerr << "Error: invalid cone or seam selection" << std::endl;
|
std::cerr << "Error: invalid cone or seam selection" << std::endl;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -882,6 +889,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
|
||||||
std::cout << "success (in " << time.elapsed() << " ms)" << std::endl;
|
std::cout << "success (in " << time.elapsed() << " ms)" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "failure: " << SMP::get_error_message(status) << std::endl;
|
std::cerr << "failure: " << SMP::get_error_message(status) << std::endl;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>278</width>
|
<width>278</width>
|
||||||
<height>432</height>
|
<height>499</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
|
@ -118,6 +118,9 @@
|
||||||
<property name="prefix">
|
<property name="prefix">
|
||||||
<string>Transparency Pass Number: </string>
|
<string>Transparency Pass Number: </string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<number>4</number>
|
<number>4</number>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -311,7 +314,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Tick plugins you don't want to load at start up</string>
|
<string>Tick plugins you want to load at start up</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
|
|
@ -181,9 +181,9 @@ Scene::erase(Scene::Item_id index)
|
||||||
item->deleteLater();
|
item->deleteLater();
|
||||||
selected_item = -1;
|
selected_item = -1;
|
||||||
//re-creates the Scene_view
|
//re-creates the Scene_view
|
||||||
Q_FOREACH(Scene_item* item, m_entries)
|
Q_FOREACH(Item_id id, children)
|
||||||
{
|
{
|
||||||
organize_items(item, invisibleRootItem(), 0);
|
organize_items(this->item(id), invisibleRootItem(), 0);
|
||||||
}
|
}
|
||||||
QStandardItemModel::beginResetModel();
|
QStandardItemModel::beginResetModel();
|
||||||
Q_EMIT updated();
|
Q_EMIT updated();
|
||||||
|
|
@ -233,9 +233,9 @@ Scene::erase(QList<int> indices)
|
||||||
continue;
|
continue;
|
||||||
if(item->parentGroup())
|
if(item->parentGroup())
|
||||||
item->parentGroup()->removeChild(item);
|
item->parentGroup()->removeChild(item);
|
||||||
children.removeAll(removed_item);
|
children.removeAll(removed_item);
|
||||||
indexErased(removed_item);
|
indexErased(removed_item);
|
||||||
m_entries.removeAll(item);
|
m_entries.removeAll(item);
|
||||||
|
|
||||||
Q_EMIT itemAboutToBeDestroyed(item);
|
Q_EMIT itemAboutToBeDestroyed(item);
|
||||||
item->aboutToBeDestroyed();
|
item->aboutToBeDestroyed();
|
||||||
|
|
@ -244,9 +244,9 @@ Scene::erase(QList<int> indices)
|
||||||
clear();
|
clear();
|
||||||
index_map.clear();
|
index_map.clear();
|
||||||
selected_item = -1;
|
selected_item = -1;
|
||||||
Q_FOREACH(Scene_item* item, m_entries)
|
Q_FOREACH(Item_id id, children)
|
||||||
{
|
{
|
||||||
organize_items(item, invisibleRootItem(), 0);
|
organize_items(item(id), invisibleRootItem(), 0);
|
||||||
}
|
}
|
||||||
QStandardItemModel::beginResetModel();
|
QStandardItemModel::beginResetModel();
|
||||||
Q_EMIT updated();
|
Q_EMIT updated();
|
||||||
|
|
@ -276,12 +276,13 @@ void Scene::remove_item_from_groups(Scene_item* item)
|
||||||
}
|
}
|
||||||
Scene::~Scene()
|
Scene::~Scene()
|
||||||
{
|
{
|
||||||
Q_FOREACH(CGAL::Three::Scene_item* item_ptr, m_entries)
|
vao->destroy();
|
||||||
{
|
delete vao;
|
||||||
item_ptr->deleteLater();
|
Q_FOREACH(CGAL::Three::Scene_item* item_ptr, m_entries)
|
||||||
}
|
{
|
||||||
m_entries.clear();
|
item_ptr->deleteLater();
|
||||||
|
}
|
||||||
|
m_entries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Three::Scene_item*
|
CGAL::Three::Scene_item*
|
||||||
|
|
@ -683,6 +684,34 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
|
||||||
transparent_items.push_back(id);
|
transparent_items.push_back(id);
|
||||||
}
|
}
|
||||||
renderScene(children, viewer, picked_item_IDs, with_names, -1, false, NULL);
|
renderScene(children, viewer, picked_item_IDs, with_names, -1, false, NULL);
|
||||||
|
if(with_names)
|
||||||
|
{
|
||||||
|
//here we get the selected point, before erasing the depth buffer. We store it
|
||||||
|
//in a dynamic property as a QList<double>. If there is some alpha, the
|
||||||
|
//depth buffer is altered, and the picking will return true even when it is
|
||||||
|
// performed in the background, when it should return false. To avoid that,
|
||||||
|
// we distinguish the case were there is no alpha, to let the viewer
|
||||||
|
//perform it, and the case where the pixel is not found. In the first case,
|
||||||
|
//we erase the property, in the latter we return an empty list.
|
||||||
|
//According ot that, in the viewer, either we perform the picking, either we do nothing.
|
||||||
|
if(has_alpha()) {
|
||||||
|
bool found = false;
|
||||||
|
CGAL::qglviewer::Vec point = viewer->camera()->pointUnderPixel(picked_pixel, found) - viewer->offset();
|
||||||
|
if(found){
|
||||||
|
QList<QVariant> picked_point;
|
||||||
|
picked_point <<point.x
|
||||||
|
<<point.y
|
||||||
|
<<point.z;
|
||||||
|
viewer->setProperty("picked_point", picked_point);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
viewer->setProperty("picked_point", QList<QVariant>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
viewer->setProperty("picked_point", {});
|
||||||
|
}
|
||||||
|
}
|
||||||
if(!with_names && has_alpha())
|
if(!with_names && has_alpha())
|
||||||
{
|
{
|
||||||
std::vector<QOpenGLFramebufferObject*> fbos;
|
std::vector<QOpenGLFramebufferObject*> fbos;
|
||||||
|
|
@ -1188,8 +1217,9 @@ void Scene::moveRowUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!to_select.isEmpty())
|
if(!to_select.isEmpty()){
|
||||||
selectionChanged(to_select);
|
selectionChanged(to_select);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void Scene::moveRowDown()
|
void Scene::moveRowDown()
|
||||||
{
|
{
|
||||||
|
|
@ -1544,7 +1574,6 @@ void Scene::redraw_model()
|
||||||
index_map.clear();
|
index_map.clear();
|
||||||
//fills the model
|
//fills the model
|
||||||
Q_FOREACH(Item_id id, children)
|
Q_FOREACH(Item_id id, children)
|
||||||
|
|
||||||
{
|
{
|
||||||
organize_items(m_entries[id], invisibleRootItem(), 0);
|
organize_items(m_entries[id], invisibleRootItem(), 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1304,7 +1304,7 @@ QMenu* Scene_c3t3_item::contextMenu()
|
||||||
QMenu *container = new QMenu(tr("Alpha value"));
|
QMenu *container = new QMenu(tr("Alpha value"));
|
||||||
container->menuAction()->setProperty("is_groupable", true);
|
container->menuAction()->setProperty("is_groupable", true);
|
||||||
QWidgetAction *sliderAction = new QWidgetAction(0);
|
QWidgetAction *sliderAction = new QWidgetAction(0);
|
||||||
sliderAction->setDefaultWidget(d->alphaSlider);
|
sliderAction->setDefaultWidget(alphaSlider());
|
||||||
connect(d->alphaSlider, &QSlider::valueChanged,
|
connect(d->alphaSlider, &QSlider::valueChanged,
|
||||||
[this]()
|
[this]()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,8 @@ public:
|
||||||
if(has_normals)
|
if(has_normals)
|
||||||
{
|
{
|
||||||
const Kernel::Vector_3& n = point_set->normal(*it);
|
const Kernel::Vector_3& n = point_set->normal(*it);
|
||||||
Point_set_3<Kernel>::Point q = p + length * n;
|
Kernel::FT normalizer = 1.0/CGAL::sqrt(n.squared_length());
|
||||||
|
Point_set_3<Kernel>::Point q = p + length * n * normalizer;
|
||||||
positions_lines[i * size_p + 3] = q.x() + offset.x;
|
positions_lines[i * size_p + 3] = q.x() + offset.x;
|
||||||
positions_lines[i * size_p + 4] = q.y() + offset.y;
|
positions_lines[i * size_p + 4] = q.y() + offset.y;
|
||||||
positions_lines[i * size_p + 5] = q.z() + offset.z;
|
positions_lines[i * size_p + 5] = q.z() + offset.z;
|
||||||
|
|
@ -432,7 +433,7 @@ void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const
|
||||||
// we can't afford computing real average spacing just for display, 0.5% of bbox will do
|
// we can't afford computing real average spacing just for display, 0.5% of bbox will do
|
||||||
average_spacing = 0.005 * item->diagonalBbox();
|
average_spacing = 0.005 * item->diagonalBbox();
|
||||||
normal_length = (std::min)(average_spacing, std::sqrt(region_of_interest.squared_radius() / 1000.));
|
normal_length = (std::min)(average_spacing, std::sqrt(region_of_interest.squared_radius() / 1000.));
|
||||||
length_factor = 5.0/100*normal_Slider->value();
|
length_factor = 10.0/100*normal_Slider->value();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -70,18 +70,12 @@ Scene_polyhedron_item_decorator::select(double orig_x,
|
||||||
double dir_y,
|
double dir_y,
|
||||||
double dir_z)
|
double dir_z)
|
||||||
{
|
{
|
||||||
Scene_item::select(orig_x,
|
|
||||||
orig_y,
|
|
||||||
orig_z,
|
|
||||||
dir_x,
|
|
||||||
dir_y,
|
|
||||||
dir_z);
|
|
||||||
poly_item->select(orig_x,
|
poly_item->select(orig_x,
|
||||||
orig_y,
|
orig_y,
|
||||||
orig_z,
|
orig_z,
|
||||||
dir_x,
|
dir_x,
|
||||||
dir_y,
|
dir_y,
|
||||||
dir_z);
|
dir_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_face_graph_item* Scene_polyhedron_item_decorator::polyhedron_item() const {
|
Scene_face_graph_item* Scene_polyhedron_item_decorator::polyhedron_item() const {
|
||||||
|
|
|
||||||
|
|
@ -1112,6 +1112,7 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set<fg_vertex_d
|
||||||
set_active_handle_type(static_cast<Active_handle::Type>(1));
|
set_active_handle_type(static_cast<Active_handle::Type>(1));
|
||||||
d->tempInstructions("Face split.",
|
d->tempInstructions("Face split.",
|
||||||
"Select a facet (1/3).");
|
"Select a facet (1/3).");
|
||||||
|
polyhedron_item()->resetColors();
|
||||||
polyhedron_item()->invalidateOpenGLBuffers();
|
polyhedron_item()->invalidateOpenGLBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1337,6 +1338,7 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::set<fg_edge_de
|
||||||
temp_selected_edges.clear();
|
temp_selected_edges.clear();
|
||||||
temp_selected_vertices.clear();
|
temp_selected_vertices.clear();
|
||||||
compute_normal_maps();
|
compute_normal_maps();
|
||||||
|
polyhedron_item()->resetColors();
|
||||||
invalidateOpenGLBuffers();
|
invalidateOpenGLBuffers();
|
||||||
polyhedron_item()->invalidateOpenGLBuffers();
|
polyhedron_item()->invalidateOpenGLBuffers();
|
||||||
d->tempInstructions("Face and vertex added.",
|
d->tempInstructions("Face and vertex added.",
|
||||||
|
|
@ -1387,6 +1389,7 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::set<fg_edge_de
|
||||||
temp_selected_vertices.clear();
|
temp_selected_vertices.clear();
|
||||||
temp_selected_edges.clear();
|
temp_selected_edges.clear();
|
||||||
compute_normal_maps();
|
compute_normal_maps();
|
||||||
|
polyhedron_item()->resetColors();
|
||||||
invalidateOpenGLBuffers();
|
invalidateOpenGLBuffers();
|
||||||
polyhedron_item()->invalidateOpenGLBuffers();
|
polyhedron_item()->invalidateOpenGLBuffers();
|
||||||
d->tempInstructions("Face added.",
|
d->tempInstructions("Face added.",
|
||||||
|
|
@ -1485,6 +1488,7 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set<fg_face_des
|
||||||
invalidateOpenGLBuffers();
|
invalidateOpenGLBuffers();
|
||||||
//reset selection mode
|
//reset selection mode
|
||||||
set_active_handle_type(static_cast<Active_handle::Type>(0));
|
set_active_handle_type(static_cast<Active_handle::Type>(0));
|
||||||
|
poly_item->resetColors();
|
||||||
poly_item->invalidateOpenGLBuffers();
|
poly_item->invalidateOpenGLBuffers();
|
||||||
d->tempInstructions("Vertex splitted.", "Select the vertex you want splitted. (1/3)");
|
d->tempInstructions("Vertex splitted.", "Select the vertex you want splitted. (1/3)");
|
||||||
}
|
}
|
||||||
|
|
@ -1540,6 +1544,7 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set<fg_face_des
|
||||||
if(total !=0)
|
if(total !=0)
|
||||||
put(vpm, target(hhandle,*polyhedron()), Point_3(x/(double)total, y/(double)total, z/(double)total));
|
put(vpm, target(hhandle,*polyhedron()), Point_3(x/(double)total, y/(double)total, z/(double)total));
|
||||||
compute_normal_maps();
|
compute_normal_maps();
|
||||||
|
polyhedron_item()->resetColors();
|
||||||
poly_item->invalidateOpenGLBuffers();
|
poly_item->invalidateOpenGLBuffers();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -895,11 +895,10 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
if(normal == CGAL::NULL_VECTOR)
|
if(normal == CGAL::NULL_VECTOR)
|
||||||
{
|
{
|
||||||
boost::graph_traits<SMesh>::halfedge_descriptor start = prev(halfedge(fd, *smesh_), *smesh_);
|
boost::graph_traits<SMesh>::halfedge_descriptor start = prev(halfedge(fd, *smesh_), *smesh_);
|
||||||
boost::graph_traits<SMesh>::halfedge_descriptor next_;
|
boost::graph_traits<SMesh>::halfedge_descriptor hd = halfedge(fd, *smesh_);
|
||||||
|
boost::graph_traits<SMesh>::halfedge_descriptor next_=next(hd, *smesh_);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
boost::graph_traits<SMesh>::halfedge_descriptor hd = halfedge(fd, *smesh_);
|
|
||||||
next_ =next(hd, *smesh_);
|
|
||||||
const Point_3& pa = smesh_->point(target(hd, *smesh_));
|
const Point_3& pa = smesh_->point(target(hd, *smesh_));
|
||||||
const Point_3& pb = smesh_->point(target(next_, *smesh_));
|
const Point_3& pb = smesh_->point(target(next_, *smesh_));
|
||||||
const Point_3& pc = smesh_->point(target(prev(hd, *smesh_), *smesh_));
|
const Point_3& pc = smesh_->point(target(prev(hd, *smesh_), *smesh_));
|
||||||
|
|
@ -908,6 +907,7 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
normal = CGAL::cross_product(pb-pa, pc -pa);
|
normal = CGAL::cross_product(pb-pa, pc -pa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
next_ =next(next_, *smesh_);
|
||||||
}while(next_ != start);
|
}while(next_ != start);
|
||||||
|
|
||||||
if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return
|
if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return
|
||||||
|
|
|
||||||
|
|
@ -331,7 +331,14 @@ Viewer::~Viewer()
|
||||||
.arg(d->specular.z()));
|
.arg(d->specular.z()));
|
||||||
viewer_settings.setValue("spec_power",
|
viewer_settings.setValue("spec_power",
|
||||||
d->spec_power);
|
d->spec_power);
|
||||||
|
if(d->_recentFunctions)
|
||||||
|
delete d->_recentFunctions;
|
||||||
|
if(d->painter)
|
||||||
|
delete d->painter;
|
||||||
|
if(d->textRenderer)
|
||||||
|
d->textRenderer->deleteLater();
|
||||||
delete d;
|
delete d;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::setScene(CGAL::Three::Scene_draw_interface* scene)
|
void Viewer::setScene(CGAL::Three::Scene_draw_interface* scene)
|
||||||
|
|
@ -708,12 +715,27 @@ void Viewer::drawWithNames()
|
||||||
void Viewer::postSelection(const QPoint& pixel)
|
void Viewer::postSelection(const QPoint& pixel)
|
||||||
{
|
{
|
||||||
Q_EMIT selected(this->selectedName());
|
Q_EMIT selected(this->selectedName());
|
||||||
bool found = false;
|
CGAL::qglviewer::Vec point;
|
||||||
CGAL::qglviewer::Vec point = camera()->pointUnderPixel(pixel, found) - offset();
|
bool found = true;
|
||||||
|
if(property("picked_point").isValid()) {
|
||||||
|
if(!property("picked_point").toList().isEmpty())
|
||||||
|
{
|
||||||
|
QList<QVariant> picked_point = property("picked_point").toList();
|
||||||
|
point = CGAL::qglviewer::Vec (picked_point[0].toDouble(),
|
||||||
|
picked_point[1].toDouble(),
|
||||||
|
picked_point[2].toDouble());
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
point = camera()->pointUnderPixel(pixel, found) - offset();
|
||||||
|
}
|
||||||
if(found) {
|
if(found) {
|
||||||
Q_EMIT selectedPoint(point.x,
|
Q_EMIT selectedPoint(point.x,
|
||||||
point.y,
|
point.y,
|
||||||
point.z);
|
point.z);
|
||||||
CGAL::qglviewer::Vec dir;
|
CGAL::qglviewer::Vec dir;
|
||||||
CGAL::qglviewer::Vec orig;
|
CGAL::qglviewer::Vec orig;
|
||||||
if(d->projection_is_ortho)
|
if(d->projection_is_ortho)
|
||||||
|
|
@ -725,8 +747,10 @@ void Viewer::postSelection(const QPoint& pixel)
|
||||||
orig = camera()->position() - offset();
|
orig = camera()->position() - offset();
|
||||||
dir = point - orig;
|
dir = point - orig;
|
||||||
}
|
}
|
||||||
|
this->setProperty("performing_selection", true);
|
||||||
Q_EMIT selectionRay(orig.x, orig.y, orig.z,
|
Q_EMIT selectionRay(orig.x, orig.y, orig.z,
|
||||||
dir.x, dir.y, dir.z);
|
dir.x, dir.y, dir.z);
|
||||||
|
this->setProperty("performing_selection", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool CGAL::Three::Viewer_interface::readFrame(QString s, CGAL::qglviewer::Frame& frame)
|
bool CGAL::Three::Viewer_interface::readFrame(QString s, CGAL::qglviewer::Frame& frame)
|
||||||
|
|
@ -990,6 +1014,7 @@ void Viewer::drawVisualHints()
|
||||||
|
|
||||||
if (d->_displayMessage)
|
if (d->_displayMessage)
|
||||||
d->textRenderer->removeText(message_text);
|
d->textRenderer->removeText(message_text);
|
||||||
|
delete message_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLShaderProgram* Viewer::declare_program(int name,
|
QOpenGLShaderProgram* Viewer::declare_program(int name,
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <CGAL/Three/Scene_interface.h>
|
#include <CGAL/Three/Scene_interface.h>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
#ifdef three_EXPORTS
|
#ifdef three_EXPORTS
|
||||||
# define THREE_EXPORT Q_DECL_EXPORT
|
# define THREE_EXPORT Q_DECL_EXPORT
|
||||||
|
|
@ -96,6 +97,18 @@ protected:
|
||||||
static int default_normal_length;
|
static int default_normal_length;
|
||||||
static int default_lines_width;
|
static int default_lines_width;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct CursorScopeGuard
|
||||||
|
{
|
||||||
|
CursorScopeGuard(QCursor cursor)
|
||||||
|
{
|
||||||
|
QApplication::setOverrideCursor(cursor);
|
||||||
|
}
|
||||||
|
~CursorScopeGuard()
|
||||||
|
{
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue