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>
|
||||
std::size_t remove_degenerate_faces(TriangleMesh& tmesh)
|
||||
bool remove_degenerate_faces(TriangleMesh& tmesh)
|
||||
{
|
||||
return remove_degenerate_faces(tmesh,
|
||||
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
|
||||
void filterMenuOperations(QMenu* menu, bool showFullMenu)
|
||||
void filterMenuOperations(QMenu* menu, QString filter, bool keep_from_here)
|
||||
{
|
||||
Q_FOREACH(QAction* action, menu->actions()) {
|
||||
if(QMenu* menu = action->menu())
|
||||
{
|
||||
filterMenuOperations(menu, showFullMenu);
|
||||
action->setVisible(showFullMenu && !(menu->isEmpty()));
|
||||
QList<QAction*> buffer;
|
||||
Q_FOREACH(QAction* action, menu->actions())
|
||||
buffer.append(action);
|
||||
while(!buffer.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()
|
||||
{
|
||||
static QVector<QAction*> to_remove;
|
||||
Q_FOREACH(QAction* action, to_remove)
|
||||
ui->menuOperations->removeAction(action);
|
||||
QString filter=operationSearchBar.text();
|
||||
if(!filter.isEmpty())
|
||||
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));
|
||||
if(action->menu() != ui->menuOperations){
|
||||
ui->menuOperations->addAction(action);
|
||||
to_remove.push_back(action);
|
||||
}
|
||||
}
|
||||
//return actions to their true menu
|
||||
Q_FOREACH(QMenu* menu, action_menu_map.values())
|
||||
{
|
||||
Q_FOREACH(QAction* action, menu->actions())
|
||||
{
|
||||
if(action != searchAction)
|
||||
menu->removeAction(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>
|
||||
|
|
@ -549,12 +574,14 @@ void MainWindow::setMenus(QString name, QString parentName, QAction* a )
|
|||
menu_map[parentName] = new QMenu(parentName, this);
|
||||
// add the submenu in the menu
|
||||
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
|
||||
if(slash_index==-1)
|
||||
{
|
||||
ui->menuOperations->removeAction(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(!childs.contains(action)) {
|
||||
ui->menuOperations->addAction(action);
|
||||
action_menu_map[action] = ui->menuOperations;
|
||||
}
|
||||
// Show and enable menu item
|
||||
addAction(action);
|
||||
|
|
@ -968,6 +996,8 @@ void MainWindow::reloadItem() {
|
|||
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
|
||||
{
|
||||
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 loader_name = item->property("loader_name").toString();
|
||||
if(filename.isEmpty() || loader_name.isEmpty()) {
|
||||
|
|
@ -986,9 +1016,9 @@ void MainWindow::reloadItem() {
|
|||
new_item->setRenderingMode(item->renderingMode());
|
||||
new_item->setVisible(item->visible());
|
||||
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)
|
||||
property_item->copyProperties(item);
|
||||
scene->replaceItem(scene->item_id(item), new_item, true);
|
||||
new_item->invalidateOpenGLBuffers();
|
||||
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* item = NULL;
|
||||
if(!fileinfo.isFile() || !fileinfo.isReadable()) {
|
||||
throw std::invalid_argument(QString("File %1 is not a readable file.")
|
||||
.arg(fileinfo.absoluteFilePath()).toStdString());
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
QString("File %1 is not a readable file.")
|
||||
.arg(fileinfo.absoluteFilePath()));
|
||||
}
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
item = loader->load(fileinfo);
|
||||
QApplication::restoreOverrideCursor();
|
||||
if(!item) {
|
||||
throw std::logic_error(QString("Could not load item from file %1 using plugin %2")
|
||||
.arg(fileinfo.absoluteFilePath()).arg(loader->name()).toStdString());
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
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());
|
||||
|
|
@ -1201,11 +1234,13 @@ void MainWindow::selectSceneItem(int i)
|
|||
}
|
||||
else {
|
||||
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,
|
||||
QItemSelectionModel::ClearAndSelect);
|
||||
sceneView->scrollTo(s.indexes().first());
|
||||
sceneView->setCurrentIndex(sceneView->selectionModel()->selectedIndexes().first());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1220,6 +1255,8 @@ void MainWindow::selectSceneItems(QList<int> is)
|
|||
QItemSelection s =
|
||||
proxyModel->mapSelectionFromSource(scene->createSelection(is));
|
||||
|
||||
QModelIndex i = proxyModel->mapFromSource(scene->getModelIndexFromId(is.first()).first());
|
||||
sceneView->setCurrentIndex(i);
|
||||
sceneView->selectionModel()->select(s,
|
||||
QItemSelectionModel::ClearAndSelect);
|
||||
sceneView->scrollTo(s.indexes().first());
|
||||
|
|
@ -1403,6 +1440,15 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
|
|||
QMap<QString, QAction*> menu_actions;
|
||||
QVector<QMenu*> slider_menus;
|
||||
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())
|
||||
{
|
||||
if(action->property("is_groupable").toBool())
|
||||
|
|
@ -1565,10 +1611,13 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
|
|||
connect(actionStatistics, SIGNAL(triggered()),
|
||||
this, SLOT(statisticsOnItem()));
|
||||
}
|
||||
if(has_reload)
|
||||
{
|
||||
QAction* reload = menu.addAction(tr("&Reload Item from File"));
|
||||
reload->setProperty("is_groupable", true);
|
||||
connect(reload, SIGNAL(triggered()),
|
||||
this, SLOT(reloadItem()));
|
||||
}
|
||||
QAction* saveas = menu.addAction(tr("&Save as..."));
|
||||
connect(saveas, SIGNAL(triggered()),
|
||||
this, SLOT(on_actionSaveAs_triggered()));
|
||||
|
|
@ -2196,6 +2245,8 @@ void MainWindow::on_actionLookAt_triggered()
|
|||
if( i == QDialog::Accepted &&
|
||||
dialog.has_correct_coordinates() )
|
||||
{
|
||||
if(viewer->camera()->frame()->isSpinning())
|
||||
viewer->camera()->frame()->stopSpinning();
|
||||
viewerShow((float)dialog.get_x()+viewer->offset().x,
|
||||
(float)dialog.get_y()+viewer->offset().y,
|
||||
(float)dialog.get_z()+viewer->offset().z);
|
||||
|
|
|
|||
|
|
@ -453,6 +453,9 @@ private:
|
|||
QMap<QString, QPair<QStringList, QString> >plugin_metadata_map;
|
||||
QMap<QString, bool> ignored_map;
|
||||
const QStringList& accepted_keywords;
|
||||
|
||||
private:
|
||||
QMap<QAction*, QMenu*> action_menu_map;
|
||||
};
|
||||
|
||||
#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; }
|
||||
//computed in constructor
|
||||
void compute_bbox() const {}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <CGAL/boost/graph/helpers.h>
|
||||
|
||||
#include "Kernel_type.h"
|
||||
#include <CGAL/Three/Three.h>
|
||||
typedef Kernel::Plane_3 Plane;
|
||||
typedef Kernel::Iso_cuboid_3 Iso_cuboid;
|
||||
typedef Kernel::Triangle_3 Triangle;
|
||||
|
|
@ -99,148 +100,150 @@ void Polyhedron_demo_pca_plugin::on_actionFitPlane_triggered()
|
|||
Scene_surface_mesh_item* sm_item =
|
||||
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
std::list<Triangle> triangles;
|
||||
|
||||
SMesh* pMesh = sm_item->polyhedron();
|
||||
::triangles(*pMesh,std::back_inserter(triangles));
|
||||
|
||||
if(! triangles.empty()){
|
||||
QString item_name = sm_item->name();
|
||||
// fit plane to triangles
|
||||
Plane plane;
|
||||
std::cout << "Fit plane...";
|
||||
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),plane,CGAL::Dimension_tag<2>());
|
||||
std::cout << "ok" << std::endl;
|
||||
|
||||
// compute centroid
|
||||
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
||||
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
||||
new_item->setPosition(center_of_mass.x(),
|
||||
center_of_mass.y(),
|
||||
center_of_mass.z());
|
||||
const Vector& normal = plane.orthogonal_vector();
|
||||
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
||||
new_item->setName(tr("%1 (plane fit)").arg(item_name));
|
||||
new_item->setColor(Qt::magenta);
|
||||
new_item->setRenderingMode(sm_item->renderingMode());
|
||||
scene->addItem(new_item);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Scene_points_with_normal_item* item =
|
||||
qobject_cast<Scene_points_with_normal_item*>(scene->item(index));
|
||||
|
||||
if (item)
|
||||
{
|
||||
Point_set* points = item->point_set();
|
||||
|
||||
// fit plane to triangles
|
||||
Plane plane;
|
||||
Point center_of_mass;
|
||||
std::cout << "Fit plane...";
|
||||
CGAL::linear_least_squares_fitting_3
|
||||
(points->points().begin(),points->points().end(),plane, center_of_mass,
|
||||
CGAL::Dimension_tag<0>());
|
||||
std::cout << "ok" << std::endl;
|
||||
|
||||
// compute centroid
|
||||
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
||||
new_item->setPosition(center_of_mass.x(),
|
||||
center_of_mass.y(),
|
||||
center_of_mass.z());
|
||||
const Vector& normal = plane.orthogonal_vector();
|
||||
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
||||
new_item->setName(tr("%1 (plane fit)").arg(item->name()));
|
||||
new_item->setColor(Qt::magenta);
|
||||
new_item->setRenderingMode(item->renderingMode());
|
||||
scene->addItem(new_item);
|
||||
|
||||
}
|
||||
Three::CursorScopeGuard scope(Qt::WaitCursor);
|
||||
if(sm_item){
|
||||
std::list<Triangle> triangles;
|
||||
|
||||
SMesh* pMesh = sm_item->polyhedron();
|
||||
::triangles(*pMesh,std::back_inserter(triangles));
|
||||
|
||||
if(! triangles.empty()){
|
||||
QString item_name = sm_item->name();
|
||||
// fit plane to triangles
|
||||
Plane plane;
|
||||
std::cout << "Fit plane...";
|
||||
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),plane,CGAL::Dimension_tag<2>());
|
||||
std::cout << "ok" << std::endl;
|
||||
|
||||
// compute centroid
|
||||
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
||||
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
||||
new_item->setPosition(center_of_mass.x(),
|
||||
center_of_mass.y(),
|
||||
center_of_mass.z());
|
||||
const Vector& normal = plane.orthogonal_vector();
|
||||
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
||||
new_item->setName(tr("%1 (plane fit)").arg(item_name));
|
||||
new_item->setColor(Qt::magenta);
|
||||
new_item->setRenderingMode(sm_item->renderingMode());
|
||||
scene->addItem(new_item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Scene_points_with_normal_item* item =
|
||||
qobject_cast<Scene_points_with_normal_item*>(scene->item(index));
|
||||
|
||||
if (item)
|
||||
{
|
||||
Point_set* points = item->point_set();
|
||||
|
||||
// fit plane to triangles
|
||||
Plane plane;
|
||||
Point center_of_mass;
|
||||
std::cout << "Fit plane...";
|
||||
CGAL::linear_least_squares_fitting_3
|
||||
(points->points().begin(),points->points().end(),plane, center_of_mass,
|
||||
CGAL::Dimension_tag<0>());
|
||||
std::cout << "ok" << std::endl;
|
||||
|
||||
// compute centroid
|
||||
Scene_plane_item* new_item = new Scene_plane_item(this->scene);
|
||||
new_item->setPosition(center_of_mass.x(),
|
||||
center_of_mass.y(),
|
||||
center_of_mass.z());
|
||||
const Vector& normal = plane.orthogonal_vector();
|
||||
new_item->setNormal(normal.x(), normal.y(), normal.z());
|
||||
new_item->setName(tr("%1 (plane fit)").arg(item->name()));
|
||||
new_item->setColor(Qt::magenta);
|
||||
new_item->setRenderingMode(item->renderingMode());
|
||||
scene->addItem(new_item);
|
||||
}
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void Polyhedron_demo_pca_plugin::on_actionFitLine_triggered()
|
||||
{
|
||||
const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
|
||||
|
||||
Three::CursorScopeGuard sg(Qt::WaitCursor);
|
||||
|
||||
Scene_surface_mesh_item* sm_item =
|
||||
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
CGAL::Bbox_3 bb;
|
||||
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
|
||||
|
||||
std::list<Triangle> triangles;
|
||||
SMesh* pMesh = sm_item->polyhedron();
|
||||
bb = ::triangles(*pMesh,std::back_inserter(triangles));
|
||||
|
||||
if(! triangles.empty()){
|
||||
QString item_name = sm_item->name();
|
||||
// fit line to triangles
|
||||
Line line;
|
||||
std::cout << "Fit line...";
|
||||
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),line,CGAL::Dimension_tag<2>());
|
||||
std::cout << "ok" << std::endl;
|
||||
|
||||
// compute centroid
|
||||
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
||||
|
||||
// compute bounding box diagonal
|
||||
Iso_cuboid bbox(bb);
|
||||
|
||||
// compute scale for rendering using diagonal of bbox
|
||||
Point cmin = (bbox.min)();
|
||||
Point cmax = (bbox.max)();
|
||||
FT diag = std::sqrt(CGAL::squared_distance(cmin,cmax));
|
||||
|
||||
// construct a 3D bar
|
||||
Vector u = line.to_vector();
|
||||
u = u / std::sqrt(u*u);
|
||||
|
||||
Point a = center_of_mass + u * diag;
|
||||
Point b = center_of_mass - u * diag;
|
||||
|
||||
Plane plane_a = line.perpendicular_plane(a);
|
||||
|
||||
Vector u1 = plane_a.base1();
|
||||
u1 = u1 / std::sqrt(u1*u1);
|
||||
u1 = u1 * 0.01 * diag;
|
||||
Vector u2 = plane_a.base2();
|
||||
u2 = u2 / std::sqrt(u2*u2);
|
||||
u2 = u2 * 0.01 * diag;
|
||||
|
||||
Point points[8];
|
||||
|
||||
points[0] = a + u1;
|
||||
points[1] = a + u2;
|
||||
points[2] = a - u1;
|
||||
points[3] = a - u2;
|
||||
|
||||
points[4] = b + u1;
|
||||
points[5] = b + u2;
|
||||
points[6] = b - u1;
|
||||
points[7] = b - u2;
|
||||
|
||||
// add best fit line as new polyhedron bar
|
||||
SMesh* pFit = new SMesh;
|
||||
CGAL::make_hexahedron(points[0],
|
||||
points[1],
|
||||
points[2],
|
||||
points[3],
|
||||
points[4],
|
||||
points[5],
|
||||
points[6],
|
||||
points[7],
|
||||
*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);
|
||||
if(sm_item)
|
||||
{
|
||||
CGAL::Bbox_3 bb;
|
||||
|
||||
SMesh* pMesh = sm_item->polyhedron();
|
||||
std::list<Triangle> triangles;
|
||||
|
||||
bb = ::triangles(*pMesh,std::back_inserter(triangles));
|
||||
|
||||
if(! triangles.empty()){
|
||||
QString item_name = sm_item->name();
|
||||
// fit line to triangles
|
||||
Line line;
|
||||
std::cout << "Fit line...";
|
||||
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),line,CGAL::Dimension_tag<2>());
|
||||
std::cout << "ok" << std::endl;
|
||||
|
||||
// compute centroid
|
||||
Point center_of_mass = CGAL::centroid(triangles.begin(),triangles.end());
|
||||
|
||||
// compute bounding box diagonal
|
||||
Iso_cuboid bbox(bb);
|
||||
|
||||
// compute scale for rendering using diagonal of bbox
|
||||
Point cmin = (bbox.min)();
|
||||
Point cmax = (bbox.max)();
|
||||
FT diag = std::sqrt(CGAL::squared_distance(cmin,cmax));
|
||||
|
||||
// construct a 3D bar
|
||||
Vector u = line.to_vector();
|
||||
u = u / std::sqrt(u*u);
|
||||
|
||||
Point a = center_of_mass + u * diag;
|
||||
Point b = center_of_mass - u * diag;
|
||||
|
||||
Plane plane_a = line.perpendicular_plane(a);
|
||||
|
||||
Vector u1 = plane_a.base1();
|
||||
u1 = u1 / std::sqrt(u1*u1);
|
||||
u1 = u1 * 0.01 * diag;
|
||||
Vector u2 = plane_a.base2();
|
||||
u2 = u2 / std::sqrt(u2*u2);
|
||||
u2 = u2 * 0.01 * diag;
|
||||
|
||||
Point points[8];
|
||||
|
||||
points[0] = a + u1;
|
||||
points[1] = a + u2;
|
||||
points[2] = a - u1;
|
||||
points[3] = a - u2;
|
||||
|
||||
points[4] = b + u1;
|
||||
points[5] = b + u2;
|
||||
points[6] = b - u1;
|
||||
points[7] = b - u2;
|
||||
|
||||
// add best fit line as new polyhedron bar
|
||||
SMesh* pFit = new SMesh;
|
||||
CGAL::make_hexahedron(
|
||||
points[0],
|
||||
points[3],
|
||||
points[2],
|
||||
points[1],
|
||||
points[5],
|
||||
points[4],
|
||||
points[7],
|
||||
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
|
||||
{
|
||||
|
|
@ -297,15 +300,16 @@ void Polyhedron_demo_pca_plugin::on_actionFitLine_triggered()
|
|||
points[7] = b - u2;
|
||||
|
||||
SMesh* pFit = new SMesh;
|
||||
CGAL::make_hexahedron(points[0],
|
||||
points[1],
|
||||
points[2],
|
||||
points[3],
|
||||
points[4],
|
||||
points[5],
|
||||
points[6],
|
||||
points[7],
|
||||
*pFit);
|
||||
CGAL::make_hexahedron(
|
||||
points[0],
|
||||
points[3],
|
||||
points[2],
|
||||
points[1],
|
||||
points[5],
|
||||
points[4],
|
||||
points[7],
|
||||
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);
|
||||
|
|
@ -313,8 +317,6 @@ void Polyhedron_demo_pca_plugin::on_actionFitLine_triggered()
|
|||
scene->addItem(new_item);
|
||||
}
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
#include "Pca_plugin.moc"
|
||||
|
|
|
|||
|
|
@ -152,6 +152,8 @@ private:
|
|||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
try{
|
||||
PMP::corefine(*item1->face_graph(), *item2->face_graph(), params::throw_on_self_intersection(true));
|
||||
item1->resetColors();
|
||||
item2->resetColors();
|
||||
item1->invalidateOpenGLBuffers();
|
||||
item2->invalidateOpenGLBuffers();
|
||||
scene->itemChanged(item2);
|
||||
|
|
|
|||
|
|
@ -302,7 +302,11 @@ private:
|
|||
Messages_interface* messages;
|
||||
|
||||
public :
|
||||
|
||||
~Engrave_text_plugin()
|
||||
{
|
||||
delete graphics_scene;
|
||||
delete navigation;
|
||||
}
|
||||
void init(QMainWindow*,
|
||||
CGAL::Three::Scene_interface*,
|
||||
Messages_interface* m) Q_DECL_OVERRIDE{
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@ private Q_SLOTS:
|
|||
Kernel::Vector_3(dir.x(), dir.y(), dir.z()));
|
||||
scene->erase(scene->item_id(oliver_queen));
|
||||
oliver_queen = NULL;
|
||||
target->resetColors();
|
||||
target->invalidateOpenGLBuffers();
|
||||
target->itemChanged();
|
||||
target = NULL;
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ public Q_SLOTS:
|
|||
CGAL::Polygon_mesh_processing::fair(*selection_item->polyhedron(),
|
||||
selection_item->selected_vertices,
|
||||
CGAL::Polygon_mesh_processing::parameters::fairing_continuity(continuity));
|
||||
selection_item->polyhedron_item()->resetColors();
|
||||
selection_item->changed_with_poly_item();
|
||||
selection_item->invalidateOpenGLBuffers();
|
||||
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) {
|
||||
selection_item->selected_facets.insert(*it);
|
||||
}
|
||||
selection_item->polyhedron_item()->resetColors();
|
||||
selection_item->changed_with_poly_item();
|
||||
selection_item->invalidateOpenGLBuffers();
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
|
|
|||
|
|
@ -366,6 +366,7 @@ protected:
|
|||
|
||||
void change_poly_item_by_blocking(Scene_face_graph_item* poly_item, Scene_hole_visualizer* collection) {
|
||||
if(collection) collection->block_poly_item_changed = true;
|
||||
poly_item->resetColors();
|
||||
poly_item->invalidateOpenGLBuffers();
|
||||
poly_item->redraw();
|
||||
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();
|
||||
accept_reject_toggle(true);
|
||||
}
|
||||
|
||||
edge_selection->polyhedron_item()->resetColors();
|
||||
edge_selection->polyhedron_item()->invalidateOpenGLBuffers();
|
||||
edge_selection->polyhedron_item()->itemChanged();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,11 @@ class Polyhedron_demo_mean_curvature_flow_skeleton_plugin :
|
|||
|
||||
public:
|
||||
|
||||
~Polyhedron_demo_mean_curvature_flow_skeleton_plugin()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) {
|
||||
|
||||
this->mw = mainWindow;
|
||||
|
|
|
|||
|
|
@ -148,9 +148,10 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionRemoveDegenerateFaces_tr
|
|||
qobject_cast<Item*>(scene->item(index));
|
||||
if (poly_item)
|
||||
{
|
||||
std::size_t nbv =
|
||||
std::size_t nbv = num_faces(*poly_item->polyhedron());
|
||||
CGAL::Polygon_mesh_processing::remove_degenerate_faces(
|
||||
*poly_item->polyhedron());
|
||||
nbv -= num_faces(*poly_item->polyhedron());
|
||||
CGAL::Three::Three::information(tr(" %1 degenerate faces have been removed.")
|
||||
.arg(nbv));
|
||||
poly_item->invalidateOpenGLBuffers();
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ public Q_SLOTS:
|
|||
// slots are called by signals of polyhedron_item
|
||||
void vertex_has_been_selected(void* void_ptr)
|
||||
{
|
||||
if((*CGAL::QGLViewer::QGLViewerPool().begin())->property("performing_selection").toBool())
|
||||
return;
|
||||
is_active=true;
|
||||
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)
|
||||
{
|
||||
if((*CGAL::QGLViewer::QGLViewerPool().begin())->property("performing_selection").toBool())
|
||||
return;
|
||||
is_active=true;
|
||||
if (active_handle_type == Active_handle::FACET
|
||||
|| active_handle_type == Active_handle::CONNECTED_COMPONENT)
|
||||
|
|
@ -157,6 +161,8 @@ public Q_SLOTS:
|
|||
}
|
||||
void edge_has_been_selected(void* void_ptr)
|
||||
{
|
||||
if((*CGAL::QGLViewer::QGLViewerPool().begin())->property("performing_selection").toBool())
|
||||
return;
|
||||
is_active=true;
|
||||
if(active_handle_type == Active_handle::EDGE)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ public:
|
|||
dock_widget->setWindowTitle(tr(
|
||||
"Surface Mesh Selection"
|
||||
));
|
||||
connect(dock_widget, &QDockWidget::visibilityChanged,
|
||||
this, [this](bool b){
|
||||
if(!b)
|
||||
this->set_operation_mode(-1);
|
||||
});
|
||||
|
||||
addDockWidget(dock_widget);
|
||||
|
||||
|
|
@ -771,7 +776,8 @@ public Q_SLOTS:
|
|||
bool is_valid = true;
|
||||
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;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -551,7 +551,7 @@
|
|||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Split edges</string>
|
||||
<string>Split edge</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ public Q_SLOTS:
|
|||
}
|
||||
if(!CGAL::Polygon_mesh_processing::triangulate_faces(*pMesh))
|
||||
CGAL::Three::Three::warning(tr("Some facets could not be triangulated."));
|
||||
|
||||
|
||||
sm_item->resetColors();
|
||||
sm_item->invalidateOpenGLBuffers();
|
||||
scene->itemChanged(sm_item);
|
||||
} // end of the loop on the selected items
|
||||
|
|
|
|||
|
|
@ -317,6 +317,10 @@ public:
|
|||
return _actions;
|
||||
}
|
||||
|
||||
~Polyhedron_demo_parameterization_plugin()
|
||||
{
|
||||
delete navigation;
|
||||
}
|
||||
void init(QMainWindow* mainWindow,
|
||||
Scene_interface* scene_interface,
|
||||
Messages_interface* msg)
|
||||
|
|
@ -825,6 +829,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
|
|||
if (i == QDialog::Rejected)
|
||||
{
|
||||
std::cout << "Aborting parameterization" << std::endl;
|
||||
QApplication::restoreOverrideCursor();
|
||||
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 << "Types I, II & III require 3 selected vertices" << std::endl;
|
||||
std::cerr << "Type IV requires 4 selected vertices" << std::endl;
|
||||
QApplication::restoreOverrideCursor();
|
||||
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))
|
||||
{
|
||||
std::cerr << "Error: invalid cone or seam selection" << std::endl;
|
||||
QApplication::restoreOverrideCursor();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -882,6 +889,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
|
|||
std::cout << "success (in " << time.elapsed() << " ms)" << std::endl;
|
||||
} else {
|
||||
std::cerr << "failure: " << SMP::get_error_message(status) << std::endl;
|
||||
QApplication::restoreOverrideCursor();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>278</width>
|
||||
<height>432</height>
|
||||
<height>499</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
|
|
@ -118,6 +118,9 @@
|
|||
<property name="prefix">
|
||||
<string>Transparency Pass Number: </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>4</number>
|
||||
</property>
|
||||
|
|
@ -311,7 +314,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -181,9 +181,9 @@ Scene::erase(Scene::Item_id index)
|
|||
item->deleteLater();
|
||||
selected_item = -1;
|
||||
//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();
|
||||
Q_EMIT updated();
|
||||
|
|
@ -233,9 +233,9 @@ Scene::erase(QList<int> indices)
|
|||
continue;
|
||||
if(item->parentGroup())
|
||||
item->parentGroup()->removeChild(item);
|
||||
children.removeAll(removed_item);
|
||||
indexErased(removed_item);
|
||||
m_entries.removeAll(item);
|
||||
children.removeAll(removed_item);
|
||||
indexErased(removed_item);
|
||||
m_entries.removeAll(item);
|
||||
|
||||
Q_EMIT itemAboutToBeDestroyed(item);
|
||||
item->aboutToBeDestroyed();
|
||||
|
|
@ -244,9 +244,9 @@ Scene::erase(QList<int> indices)
|
|||
clear();
|
||||
index_map.clear();
|
||||
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();
|
||||
Q_EMIT updated();
|
||||
|
|
@ -276,12 +276,13 @@ void Scene::remove_item_from_groups(Scene_item* item)
|
|||
}
|
||||
Scene::~Scene()
|
||||
{
|
||||
Q_FOREACH(CGAL::Three::Scene_item* item_ptr, m_entries)
|
||||
{
|
||||
item_ptr->deleteLater();
|
||||
}
|
||||
m_entries.clear();
|
||||
|
||||
vao->destroy();
|
||||
delete vao;
|
||||
Q_FOREACH(CGAL::Three::Scene_item* item_ptr, m_entries)
|
||||
{
|
||||
item_ptr->deleteLater();
|
||||
}
|
||||
m_entries.clear();
|
||||
}
|
||||
|
||||
CGAL::Three::Scene_item*
|
||||
|
|
@ -683,6 +684,34 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
|
|||
transparent_items.push_back(id);
|
||||
}
|
||||
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())
|
||||
{
|
||||
std::vector<QOpenGLFramebufferObject*> fbos;
|
||||
|
|
@ -1188,8 +1217,9 @@ void Scene::moveRowUp()
|
|||
}
|
||||
}
|
||||
}
|
||||
if(!to_select.isEmpty())
|
||||
if(!to_select.isEmpty()){
|
||||
selectionChanged(to_select);
|
||||
}
|
||||
}
|
||||
void Scene::moveRowDown()
|
||||
{
|
||||
|
|
@ -1544,7 +1574,6 @@ void Scene::redraw_model()
|
|||
index_map.clear();
|
||||
//fills the model
|
||||
Q_FOREACH(Item_id id, children)
|
||||
|
||||
{
|
||||
organize_items(m_entries[id], invisibleRootItem(), 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1304,7 +1304,7 @@ QMenu* Scene_c3t3_item::contextMenu()
|
|||
QMenu *container = new QMenu(tr("Alpha value"));
|
||||
container->menuAction()->setProperty("is_groupable", true);
|
||||
QWidgetAction *sliderAction = new QWidgetAction(0);
|
||||
sliderAction->setDefaultWidget(d->alphaSlider);
|
||||
sliderAction->setDefaultWidget(alphaSlider());
|
||||
connect(d->alphaSlider, &QSlider::valueChanged,
|
||||
[this]()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -185,7 +185,8 @@ public:
|
|||
if(has_normals)
|
||||
{
|
||||
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 + 4] = q.y() + offset.y;
|
||||
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
|
||||
average_spacing = 0.005 * item->diagonalBbox();
|
||||
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -70,18 +70,12 @@ Scene_polyhedron_item_decorator::select(double orig_x,
|
|||
double dir_y,
|
||||
double dir_z)
|
||||
{
|
||||
Scene_item::select(orig_x,
|
||||
orig_y,
|
||||
orig_z,
|
||||
dir_x,
|
||||
dir_y,
|
||||
dir_z);
|
||||
poly_item->select(orig_x,
|
||||
orig_y,
|
||||
orig_z,
|
||||
dir_x,
|
||||
dir_y,
|
||||
dir_z);
|
||||
orig_y,
|
||||
orig_z,
|
||||
dir_x,
|
||||
dir_y,
|
||||
dir_z);
|
||||
}
|
||||
|
||||
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));
|
||||
d->tempInstructions("Face split.",
|
||||
"Select a facet (1/3).");
|
||||
polyhedron_item()->resetColors();
|
||||
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_vertices.clear();
|
||||
compute_normal_maps();
|
||||
polyhedron_item()->resetColors();
|
||||
invalidateOpenGLBuffers();
|
||||
polyhedron_item()->invalidateOpenGLBuffers();
|
||||
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_edges.clear();
|
||||
compute_normal_maps();
|
||||
polyhedron_item()->resetColors();
|
||||
invalidateOpenGLBuffers();
|
||||
polyhedron_item()->invalidateOpenGLBuffers();
|
||||
d->tempInstructions("Face added.",
|
||||
|
|
@ -1485,6 +1488,7 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set<fg_face_des
|
|||
invalidateOpenGLBuffers();
|
||||
//reset selection mode
|
||||
set_active_handle_type(static_cast<Active_handle::Type>(0));
|
||||
poly_item->resetColors();
|
||||
poly_item->invalidateOpenGLBuffers();
|
||||
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)
|
||||
put(vpm, target(hhandle,*polyhedron()), Point_3(x/(double)total, y/(double)total, z/(double)total));
|
||||
compute_normal_maps();
|
||||
polyhedron_item()->resetColors();
|
||||
poly_item->invalidateOpenGLBuffers();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -895,11 +895,10 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
|||
if(normal == CGAL::NULL_VECTOR)
|
||||
{
|
||||
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
|
||||
{
|
||||
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& pb = smesh_->point(target(next_, *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);
|
||||
break;
|
||||
}
|
||||
next_ =next(next_, *smesh_);
|
||||
}while(next_ != start);
|
||||
|
||||
if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return
|
||||
|
|
|
|||
|
|
@ -331,7 +331,14 @@ Viewer::~Viewer()
|
|||
.arg(d->specular.z()));
|
||||
viewer_settings.setValue("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;
|
||||
|
||||
}
|
||||
|
||||
void Viewer::setScene(CGAL::Three::Scene_draw_interface* scene)
|
||||
|
|
@ -708,12 +715,27 @@ void Viewer::drawWithNames()
|
|||
void Viewer::postSelection(const QPoint& pixel)
|
||||
{
|
||||
Q_EMIT selected(this->selectedName());
|
||||
bool found = false;
|
||||
CGAL::qglviewer::Vec point = camera()->pointUnderPixel(pixel, found) - offset();
|
||||
CGAL::qglviewer::Vec point;
|
||||
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) {
|
||||
Q_EMIT selectedPoint(point.x,
|
||||
point.y,
|
||||
point.z);
|
||||
point.y,
|
||||
point.z);
|
||||
CGAL::qglviewer::Vec dir;
|
||||
CGAL::qglviewer::Vec orig;
|
||||
if(d->projection_is_ortho)
|
||||
|
|
@ -725,8 +747,10 @@ void Viewer::postSelection(const QPoint& pixel)
|
|||
orig = camera()->position() - offset();
|
||||
dir = point - orig;
|
||||
}
|
||||
this->setProperty("performing_selection", true);
|
||||
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)
|
||||
|
|
@ -990,6 +1014,7 @@ void Viewer::drawVisualHints()
|
|||
|
||||
if (d->_displayMessage)
|
||||
d->textRenderer->removeText(message_text);
|
||||
delete message_text;
|
||||
}
|
||||
|
||||
QOpenGLShaderProgram* Viewer::declare_program(int name,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <QDockWidget>
|
||||
#include <CGAL/Three/Scene_interface.h>
|
||||
#include <QMainWindow>
|
||||
#include <QApplication>
|
||||
|
||||
#ifdef three_EXPORTS
|
||||
# define THREE_EXPORT Q_DECL_EXPORT
|
||||
|
|
@ -96,6 +97,18 @@ protected:
|
|||
static int default_normal_length;
|
||||
static int default_lines_width;
|
||||
|
||||
public:
|
||||
struct CursorScopeGuard
|
||||
{
|
||||
CursorScopeGuard(QCursor cursor)
|
||||
{
|
||||
QApplication::setOverrideCursor(cursor);
|
||||
}
|
||||
~CursorScopeGuard()
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue