mirror of https://github.com/CGAL/cgal
Merge pull request #4811 from maxGimeno/Demo-Fixes_and_features-maxGimeno
Polyhedron demo: fixes and features
This commit is contained in:
commit
aff306bb55
|
|
@ -371,6 +371,7 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren
|
|||
|
||||
// Setup the submenu of the View menu that can toggle the dockwidgets
|
||||
Q_FOREACH(QDockWidget* widget, findChildren<QDockWidget*>()) {
|
||||
widget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
|
||||
ui->menuDockWindows->addAction(widget->toggleViewAction());
|
||||
}
|
||||
ui->menuDockWindows->removeAction(ui->dummyAction);
|
||||
|
|
@ -1285,7 +1286,7 @@ QList<Scene_item*> MainWindow::loadItem(QFileInfo fileinfo,
|
|||
QCursor tmp_cursor(Qt::WaitCursor);
|
||||
CGAL::Three::Three::CursorScopeGuard guard(tmp_cursor);
|
||||
QList<Scene_item*> result = loader->load(fileinfo, ok, add_to_scene);
|
||||
if(result.empty() || !ok)
|
||||
if(!ok)
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
QMessageBox::warning(this, tr("Error"),
|
||||
|
|
@ -1579,6 +1580,8 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
|
|||
has_stats = true;
|
||||
}
|
||||
QMenu menu;
|
||||
menu.addAction(actionAddToGroup);
|
||||
menu.insertSeparator(0);
|
||||
Q_FOREACH(QString name, menu_actions.keys())
|
||||
{
|
||||
if(name == QString("alpha slider")
|
||||
|
|
@ -2579,6 +2582,10 @@ void MainWindow::makeNewGroup()
|
|||
{
|
||||
Scene_group_item * group = new Scene_group_item();
|
||||
scene->addItem(group);
|
||||
for(Scene::Item_id id : scene->selectionIndices())
|
||||
{
|
||||
scene->changeGroup(scene->item(id), group);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_upButton_pressed()
|
||||
|
|
@ -2956,6 +2963,7 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered()
|
|||
std::vector<QColor> colors;
|
||||
std::vector<int> rendering_modes;
|
||||
QStringList not_saved;
|
||||
Polyhedron_demo_io_plugin_interface* camera_plugin = nullptr;
|
||||
for(int i = 0; i < scene->numberOfEntries(); ++i)
|
||||
{
|
||||
Scene_item* item = scene->item(i);
|
||||
|
|
@ -2963,6 +2971,8 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered()
|
|||
QString ext;
|
||||
for(Polyhedron_demo_io_plugin_interface* iop : io_plugins)
|
||||
{
|
||||
if(iop->name() == "camera_positions_plugin")
|
||||
camera_plugin = iop;
|
||||
if(iop->isDefaultLoader(item))
|
||||
{
|
||||
QString sf = iop->saveNameFilters().split(";;").first();
|
||||
|
|
@ -2992,6 +3002,23 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered()
|
|||
colors.push_back(item->color());
|
||||
rendering_modes.push_back(item->renderingMode());
|
||||
}
|
||||
bool has_camera_positions = false;
|
||||
if(camera_plugin)
|
||||
{
|
||||
QString fullpath = make_fullpath("camera_tmp.camera.txt");
|
||||
QList<Scene_item*> dummy;
|
||||
if(camera_plugin->save(QFileInfo(fullpath), dummy))
|
||||
{
|
||||
QByteArray item = file_to_string(fullpath.toStdString().c_str());
|
||||
os << "var camera_positions= [\'";
|
||||
os<<qCompress(item, 9).toBase64().toStdString().c_str();
|
||||
os << "\']\n" ;
|
||||
//delete temp file
|
||||
QFile tmp_file(fullpath);
|
||||
tmp_file.remove();
|
||||
has_camera_positions =true;
|
||||
}
|
||||
}
|
||||
if(loaders.empty())
|
||||
return;
|
||||
//path
|
||||
|
|
@ -3054,6 +3081,12 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered()
|
|||
os << " it.setRenderingMode(rendering_modes[index]);\n";
|
||||
os << "});\n";
|
||||
os << "viewer.moveCameraToCoordinates(camera, 0.05);\n";
|
||||
if(has_camera_positions)
|
||||
{
|
||||
os<<" var path=\"cams.camera.txt\";\n";
|
||||
os<<" var fullpath = main_window.write_string_to_file(camera_positions, path);\n";
|
||||
os<<" main_window.open(fullpath,\'camera_positions_plugin\');\n";
|
||||
}
|
||||
os.close();
|
||||
if(!not_saved.empty())
|
||||
QMessageBox::warning(this,
|
||||
|
|
@ -3238,6 +3271,13 @@ void MainWindow::setupViewer(Viewer* viewer, SubViewer* subviewer)
|
|||
}
|
||||
viewer->setTotalPass(nb);
|
||||
});
|
||||
|
||||
action = subviewer->findChild<QAction*>("actionScaleScene");
|
||||
action->setCheckable(true);
|
||||
action->setChecked(false);
|
||||
connect(action, &QAction::triggered,
|
||||
viewer, &Viewer::scaleScene);
|
||||
|
||||
action= subviewer->findChild<QAction*>("actionBackFrontShading");
|
||||
connect(action, SIGNAL(toggled(bool)),
|
||||
viewer, SLOT(setBackFrontShading(bool)));
|
||||
|
|
@ -3450,6 +3490,10 @@ SubViewer::SubViewer(QWidget *parent, MainWindow* mw, Viewer* mainviewer)
|
|||
actionBackFrontShading->setChecked(false);
|
||||
viewMenu->addAction(actionBackFrontShading);
|
||||
|
||||
QAction* actionScaleScene = new QAction("&Scale the Scene...",this);
|
||||
actionScaleScene->setObjectName("actionScaleScene");
|
||||
viewMenu->addAction(actionScaleScene);
|
||||
|
||||
if(mainviewer)
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowIcon(QIcon(":/cgal/icons/resources/menu.png"));
|
||||
|
|
|
|||
|
|
@ -89,13 +89,9 @@ void Camera_positions_list::activatedRow(QModelIndex index)
|
|||
Three::activeViewer()->moveCameraToCoordinates(s);
|
||||
}
|
||||
|
||||
void Camera_positions_list::on_saveButton_pressed()
|
||||
{
|
||||
QString filename =
|
||||
QFileDialog::getSaveFileName(this,
|
||||
tr("Save camera coordinates to file"),
|
||||
QString(),
|
||||
tr("(*.camera.txt)"));
|
||||
bool Camera_positions_list::save(QString filename) {
|
||||
if(m_model->rowCount() <1)
|
||||
return false;
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QTextStream out(&file);
|
||||
|
|
@ -108,6 +104,17 @@ void Camera_positions_list::on_saveButton_pressed()
|
|||
<< "\n";
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Camera_positions_list::on_saveButton_pressed()
|
||||
{
|
||||
QString filename =
|
||||
QFileDialog::getSaveFileName(this,
|
||||
tr("Save camera coordinates to file"),
|
||||
QString(),
|
||||
tr("(*.camera.txt)"));
|
||||
save(filename);
|
||||
}
|
||||
|
||||
void Camera_positions_list::on_openButton_pressed()
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
void load(QString filename);
|
||||
bool save(QString filename);
|
||||
protected Q_SLOTS:
|
||||
void on_plusButton_pressed();
|
||||
void on_minusButton_pressed();
|
||||
|
|
@ -41,3 +42,4 @@ private:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,11 @@ public:
|
|||
return QList<Scene_item*>();
|
||||
}
|
||||
|
||||
bool canSave(const Scene_item*) override { return false; }
|
||||
bool save(QFileInfo,QList<CGAL::Three::Scene_item*>& ) override {return false; }
|
||||
bool canSave(const Scene_item*) override { return true; }
|
||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& ) override
|
||||
{
|
||||
return cpl->save(fileinfo.filePath());
|
||||
}
|
||||
private:
|
||||
Camera_positions_list* cpl;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ target_link_libraries(surface_intersection_plugin PUBLIC scene_surface_mesh_item
|
|||
|
||||
qt5_wrap_ui( repairUI_FILES RemoveNeedlesDialog.ui)
|
||||
polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin ${repairUI_FILES} KEYWORDS PMP)
|
||||
target_link_libraries(repair_polyhedron_plugin PUBLIC scene_surface_mesh_item)
|
||||
target_link_libraries(repair_polyhedron_plugin PUBLIC scene_points_with_normal_item scene_surface_mesh_item)
|
||||
|
||||
qt5_wrap_ui( isotropicRemeshingUI_FILES Isotropic_remeshing_dialog.ui)
|
||||
polyhedron_demo_plugin(isotropic_remeshing_plugin Isotropic_remeshing_plugin ${isotropicRemeshingUI_FILES} KEYWORDS PMP)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include "Scene_surface_mesh_item.h"
|
||||
#include "Scene_points_with_normal_item.h"
|
||||
#include <CGAL/Three/Scene_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
|
||||
|
|
@ -47,6 +48,7 @@ public:
|
|||
actionRemoveSelfIntersections = new QAction(tr("Remove Self-Intersections"), mw);
|
||||
actionStitchCloseBorderHalfedges = new QAction(tr("Stitch Close Border Halfedges"), mw);
|
||||
actionDuplicateNMVertices = new QAction(tr("Duplicate Non-Manifold Vertices"), mw);
|
||||
actionExtractNMVertices = new QAction(tr("Extract Non-Manifold Vertices"), mw);
|
||||
actionMergeDuplicatedVerticesOnBoundaryCycles = new QAction(tr("Merge Duplicated Vertices on Boundary Cycles"), mw);
|
||||
actionAutorefine = new QAction(tr("Autorefine Mesh"), mw);
|
||||
actionAutorefineAndRMSelfIntersections = new QAction(tr("Autorefine and Remove Self-Intersections"), mw);
|
||||
|
|
@ -57,6 +59,7 @@ public:
|
|||
actionRemoveSelfIntersections->setObjectName("actionRemoveSelfIntersections");
|
||||
actionStitchCloseBorderHalfedges->setObjectName("actionStitchCloseBorderHalfedges");
|
||||
actionDuplicateNMVertices->setObjectName("actionDuplicateNMVertices");
|
||||
actionExtractNMVertices->setObjectName("actionExtractNMVertices");
|
||||
actionMergeDuplicatedVerticesOnBoundaryCycles->setObjectName("actionMergeDuplicatedVerticesOnBoundaryCycles");
|
||||
actionAutorefine->setObjectName("actionAutorefine");
|
||||
actionAutorefineAndRMSelfIntersections->setObjectName("actionAutorefineAndRMSelfIntersections");
|
||||
|
|
@ -67,6 +70,7 @@ public:
|
|||
actionRemoveSelfIntersections->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental");
|
||||
actionRemoveIsolatedVertices->setProperty("subMenuName", "Polygon Mesh Processing/Repair");
|
||||
actionDuplicateNMVertices->setProperty("subMenuName", "Polygon Mesh Processing/Repair");
|
||||
actionExtractNMVertices->setProperty("subMenuName", "Polygon Mesh Processing/Repair");
|
||||
actionMergeDuplicatedVerticesOnBoundaryCycles->setProperty("subMenuName", "Polygon Mesh Processing/Repair");
|
||||
actionAutorefine->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental");
|
||||
actionAutorefineAndRMSelfIntersections->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental");
|
||||
|
|
@ -82,6 +86,7 @@ public:
|
|||
<< actionRemoveSelfIntersections
|
||||
<< actionStitchCloseBorderHalfedges
|
||||
<< actionDuplicateNMVertices
|
||||
<< actionExtractNMVertices
|
||||
<< actionMergeDuplicatedVerticesOnBoundaryCycles
|
||||
<< actionAutorefine
|
||||
<< actionAutorefineAndRMSelfIntersections
|
||||
|
|
@ -104,6 +109,8 @@ public:
|
|||
template <typename Item>
|
||||
void on_actionDuplicateNMVertices_triggered(Scene_interface::Item_id index);
|
||||
template <typename Item>
|
||||
void on_actionExtractNMVertices_triggered(Scene_interface::Item_id index);
|
||||
template <typename Item>
|
||||
void on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(Scene_interface::Item_id index);
|
||||
template <typename Item>
|
||||
void on_actionAutorefine_triggered(Scene_interface::Item_id index);
|
||||
|
|
@ -116,6 +123,7 @@ public Q_SLOTS:
|
|||
void on_actionRemoveSelfIntersections_triggered();
|
||||
void on_actionStitchCloseBorderHalfedges_triggered();
|
||||
void on_actionDuplicateNMVertices_triggered();
|
||||
void on_actionExtractNMVertices_triggered();
|
||||
void on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered();
|
||||
void on_actionAutorefine_triggered();
|
||||
void on_actionAutorefineAndRMSelfIntersections_triggered();
|
||||
|
|
@ -127,6 +135,7 @@ private:
|
|||
QAction* actionRemoveSelfIntersections;
|
||||
QAction* actionStitchCloseBorderHalfedges;
|
||||
QAction* actionDuplicateNMVertices;
|
||||
QAction* actionExtractNMVertices;
|
||||
QAction* actionMergeDuplicatedVerticesOnBoundaryCycles;
|
||||
QAction* actionAutorefine;
|
||||
QAction* actionAutorefineAndRMSelfIntersections;
|
||||
|
|
@ -347,6 +356,32 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionDuplicateNMVertices_trig
|
|||
}
|
||||
}
|
||||
|
||||
template <typename Item>
|
||||
void Polyhedron_demo_repair_polyhedron_plugin::on_actionExtractNMVertices_triggered(Scene_interface::Item_id index)
|
||||
{
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
typedef typename boost::graph_traits<typename Item::Face_graph>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
if (Item* poly_item = qobject_cast<Item*>(scene->item(index)))
|
||||
{
|
||||
std::vector<halfedge_descriptor> hds;
|
||||
PMP::non_manifold_vertices(*poly_item->face_graph(), std::back_inserter(hds));
|
||||
if(hds.empty())
|
||||
{
|
||||
CGAL::Three::Three::information(tr(" No NM vertex found."));
|
||||
return;
|
||||
}
|
||||
Scene_points_with_normal_item* pitem = new Scene_points_with_normal_item();
|
||||
pitem->setColor(Qt::red);
|
||||
pitem->setName(QString("%1 nm vertices").arg(poly_item->name()));
|
||||
for(const auto& h : hds)
|
||||
{
|
||||
pitem->point_set()->insert(poly_item->face_graph()->point(target(h, *poly_item->face_graph())));
|
||||
}
|
||||
scene->addItem (pitem);
|
||||
}
|
||||
}
|
||||
|
||||
void Polyhedron_demo_repair_polyhedron_plugin::on_actionDuplicateNMVertices_triggered()
|
||||
{
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
|
@ -355,6 +390,14 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionDuplicateNMVertices_trig
|
|||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void Polyhedron_demo_repair_polyhedron_plugin::on_actionExtractNMVertices_triggered()
|
||||
{
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
const Scene_interface::Item_id index = scene->mainSelectionIndex();
|
||||
on_actionExtractNMVertices_triggered<Scene_surface_mesh_item>(index);
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
template <typename Item>
|
||||
void Polyhedron_demo_repair_polyhedron_plugin::on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(Scene_interface::Item_id index)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ void CGAL::Three::Polyhedron_demo_plugin_helper::addDockWidget(QDockWidget* dock
|
|||
{
|
||||
mw->addDockWidget(::Qt::LeftDockWidgetArea, dock_widget);
|
||||
dock_widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
|
||||
|
||||
dock_widget->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
|
||||
QList<QDockWidget*> dockWidgets = mw->findChildren<QDockWidget*>();
|
||||
int counter = 0;
|
||||
Q_FOREACH(QDockWidget* dock, dockWidgets) {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ Scene::addItem(CGAL::Three::Scene_item* item)
|
|||
item->drawEdges(CGAL::Three::Three::mainViewer());
|
||||
item->drawPoints(CGAL::Three::Three::mainViewer());
|
||||
CGAL::Three::Three::mainViewer()->setDepthPeelingFbo(fbo);
|
||||
if(group)
|
||||
m_groups.append(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -110,6 +112,7 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
|
|||
QList<Scene_item*> group_children;
|
||||
if(group)
|
||||
{
|
||||
m_groups.removeAll(index);
|
||||
Q_FOREACH(Item_id id, group->getChildren())
|
||||
{
|
||||
CGAL::Three::Scene_item* child = group->getChild(id);
|
||||
|
|
@ -152,6 +155,7 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
|
|||
if(group)
|
||||
{
|
||||
addGroup(group);
|
||||
m_groups.append(index);
|
||||
}
|
||||
itemChanged(index);
|
||||
Q_EMIT restoreCollapsedState();
|
||||
|
|
@ -173,6 +177,7 @@ Scene::erase(Scene::Item_id index)
|
|||
setSelectedItemsList(QList<Scene_interface::Item_id>()<<item_id(item));
|
||||
return erase(selectionIndices());
|
||||
}
|
||||
m_groups.removeAll(index);
|
||||
if(item->parentGroup()
|
||||
&& item->parentGroup()->isChildLocked(item))
|
||||
return -1;
|
||||
|
|
@ -248,6 +253,7 @@ Scene::erase(QList<int> indices)
|
|||
item->parentGroup()->removeChild(item);
|
||||
children.removeAll(removed_item);
|
||||
indexErased(removed_item);
|
||||
m_groups.removeAll(removed_item);
|
||||
m_entries.removeAll(item);
|
||||
|
||||
Q_EMIT itemAboutToBeDestroyed(item);
|
||||
|
|
@ -1359,9 +1365,15 @@ QItemSelection Scene::createSelectionAll()
|
|||
//it is not possible to directly create a selection with items that have different parents, so
|
||||
//we do it iteratively.
|
||||
QItemSelection sel;
|
||||
for(int i=0; i< m_entries.size(); ++i)
|
||||
sel.select(index_map.keys(i).at(0),
|
||||
index_map.keys(i).at(4));
|
||||
sel.select(this->createIndex(0, 0),
|
||||
this->createIndex(m_entries.size(), LastColumn));
|
||||
for(const auto& gid : m_groups)
|
||||
{
|
||||
CGAL::Three::Scene_group_item* group =
|
||||
qobject_cast<CGAL::Three::Scene_group_item*>(item(gid));
|
||||
sel.select(index_map.keys(group->getChildren().first()).at(0),
|
||||
index_map.keys(group->getChildren().last()).at(4));
|
||||
}
|
||||
return sel;
|
||||
}
|
||||
|
||||
|
|
@ -1726,7 +1738,7 @@ void Scene::updatePrimitiveIds(CGAL::Three::Scene_item* it)
|
|||
}
|
||||
}
|
||||
}
|
||||
bool Scene::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer)
|
||||
bool Scene::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer, const QVector3D& scaler)
|
||||
{
|
||||
CGAL::Three::Scene_item *i = item(mainSelectionIndex());
|
||||
if(!i)
|
||||
|
|
@ -1734,7 +1746,7 @@ bool Scene::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_inte
|
|||
Scene_print_item_interface* spit= qobject_cast<Scene_print_item_interface*>(i);
|
||||
if(spit && i->visible())
|
||||
{
|
||||
bool res = spit->testDisplayId(x,y,z, viewer);
|
||||
bool res = spit->testDisplayId(x,y,z, viewer, scaler);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ public:
|
|||
int numberOfEntries() const Q_DECL_OVERRIDE;
|
||||
// returns the list of items.
|
||||
const QList<CGAL::Three::Scene_item*>& entries() const { return m_entries; }
|
||||
|
||||
Q_INVOKABLE CGAL::Three::Scene_item* item(int) const Q_DECL_OVERRIDE;
|
||||
int item_id(CGAL::Three::Scene_item*) const Q_DECL_OVERRIDE;
|
||||
|
||||
|
|
@ -94,7 +95,7 @@ public:
|
|||
void printAllIds() Q_DECL_OVERRIDE;
|
||||
//!Re-computes the primitiveIds for `item`
|
||||
void updatePrimitiveIds(Scene_item *item) Q_DECL_OVERRIDE;
|
||||
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer) Q_DECL_OVERRIDE;
|
||||
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer, const QVector3D& scaler) Q_DECL_OVERRIDE;
|
||||
Bbox bbox() const Q_DECL_OVERRIDE;
|
||||
void computeBbox();
|
||||
double len_diagonal() const Q_DECL_OVERRIDE
|
||||
|
|
@ -280,6 +281,7 @@ private:
|
|||
typedef QList<CGAL::Three::Scene_item*> Entries;
|
||||
//List containing all the scene_items.
|
||||
Entries m_entries;
|
||||
QList<Item_id> m_groups; //used to optimize createSelectionAll()
|
||||
QList<Item_id> children;
|
||||
// Index of the currently selected item.
|
||||
int selected_item;
|
||||
|
|
|
|||
|
|
@ -2254,9 +2254,9 @@ void Scene_polyhedron_selection_item::printAllIds()
|
|||
{
|
||||
d->item->polyhedron_item()->printAllIds();
|
||||
}
|
||||
bool Scene_polyhedron_selection_item::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer)const
|
||||
bool Scene_polyhedron_selection_item::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer, const QVector3D& scaler)const
|
||||
{
|
||||
return d->item->polyhedron_item()->testDisplayId(x, y, z, viewer);
|
||||
return d->item->polyhedron_item()->testDisplayId(x, y, z, viewer, scaler);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ public:
|
|||
bool printEdgeIds() const;
|
||||
bool printFaceIds() const;
|
||||
void printAllIds();
|
||||
bool testDisplayId(double, double, double, CGAL::Three::Viewer_interface*)const;
|
||||
bool testDisplayId(double, double, double, CGAL::Three::Viewer_interface*, const QVector3D&)const;
|
||||
bool shouldDisplayIds(CGAL::Three::Scene_item *current_item) const;
|
||||
QString defaultSaveName() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2130,7 +2130,7 @@ void Scene_surface_mesh_item::printAllIds()
|
|||
d->killIds();
|
||||
}
|
||||
|
||||
bool Scene_surface_mesh_item::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer)const
|
||||
bool Scene_surface_mesh_item::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer, const QVector3D& scaler)const
|
||||
{
|
||||
const CGAL::qglviewer::Vec offset = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
||||
EPICK::Point_3 src(x - offset.x,
|
||||
|
|
@ -2138,13 +2138,14 @@ bool Scene_surface_mesh_item::testDisplayId(double x, double y, double z, CGAL::
|
|||
z - offset.z);
|
||||
|
||||
CGAL::qglviewer::Camera* cam = viewer->camera();
|
||||
EPICK::Point_3 dest( cam->position().x - offset.x,
|
||||
cam->position().y - offset.y,
|
||||
cam->position().z - offset.z);
|
||||
EPICK::Point_3 dest( cam->position().x/scaler.x() - offset.x,
|
||||
cam->position().y/scaler.y() - offset.y,
|
||||
cam->position().z/scaler.z() - offset.z);
|
||||
EPICK::Vector_3 v(src,dest);
|
||||
EPICK::Vector_3 dir(cam->viewDirection().x,
|
||||
cam->viewDirection().y,
|
||||
cam->viewDirection().z);
|
||||
|
||||
if(-CGAL::scalar_product(v, dir) < cam->zNear()) //if src is behind the near plane, don't display.
|
||||
return false;
|
||||
v = 0.01*v;
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ public:
|
|||
bool printFaceIds()const Q_DECL_OVERRIDE;
|
||||
void printAllIds() Q_DECL_OVERRIDE;
|
||||
bool shouldDisplayIds(CGAL::Three::Scene_item *current_item) const Q_DECL_OVERRIDE;
|
||||
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface*)const Q_DECL_OVERRIDE;
|
||||
bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface*, const QVector3D &scaler)const Q_DECL_OVERRIDE;
|
||||
float alpha() const Q_DECL_OVERRIDE;
|
||||
void setAlpha(int alpha) Q_DECL_OVERRIDE;
|
||||
QSlider* alphaSlider();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include <CGAL/Three/Scene_item.h>
|
||||
#include <CGAL/Three/Scene_print_item_interface.h>
|
||||
#include "Scene_polyhedron_selection_item.h"
|
||||
void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer)
|
||||
void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer, const QVector3D& scaler)
|
||||
{
|
||||
QPainter *painter = viewer->getPainter();
|
||||
if (!painter->isActive())
|
||||
|
|
@ -23,10 +23,15 @@ void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer)
|
|||
if(viewer->testDisplayId(src.x, src.y, src.z))
|
||||
{
|
||||
if(item->is_3D())
|
||||
rect = QRect(int(camera->projectedCoordinatesOf(src).x-item->width()/2),
|
||||
int(camera->projectedCoordinatesOf(src).y-item->height()/2),
|
||||
{
|
||||
src.x *= scaler.x();
|
||||
src.y *= scaler.y();
|
||||
src.z *= scaler.z();
|
||||
rect = QRect(int(camera->projectedCoordinatesOf(src).x -item->width()/2),
|
||||
int(camera->projectedCoordinatesOf(src).y -item->height()/2),
|
||||
int(item->width()),
|
||||
int(item->height()));
|
||||
}
|
||||
else
|
||||
rect = QRect(int(src.x-item->width()/2),
|
||||
int(src.y-item->height()/2),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <QOpenGLDebugLogger>
|
||||
#include <QStyleFactory>
|
||||
#include <QAction>
|
||||
#include <QMultipleInputDialog.h>
|
||||
#include <QRegularExpressionMatch>
|
||||
#ifdef CGAL_USE_WEBSOCKETS
|
||||
#include <QtWebSockets/QWebSocket>
|
||||
|
|
@ -25,6 +26,7 @@
|
|||
#include <CGAL/Three/Three.h>
|
||||
|
||||
#include "ui_LightingDialog.h"
|
||||
#include "CGAL_double_edit.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <QMimeData>
|
||||
|
|
@ -46,8 +48,10 @@ public:
|
|||
bool clipping;
|
||||
bool projection_is_ortho;
|
||||
bool cam_sharing;
|
||||
bool scene_scaling;
|
||||
GLfloat gl_point_size;
|
||||
QVector4D clipbox[6];
|
||||
QVector3D scaler;
|
||||
QPainter *painter;
|
||||
|
||||
// L i g h t i n g
|
||||
|
|
@ -117,6 +121,7 @@ public:
|
|||
{
|
||||
return shader_programs;
|
||||
}
|
||||
|
||||
#ifdef CGAL_USE_WEBSOCKETS
|
||||
QWebSocket m_webSocket;
|
||||
#endif
|
||||
|
|
@ -292,6 +297,8 @@ void Viewer::doBindings()
|
|||
d->textRenderer = new TextRenderer();
|
||||
d->is_2d_selection_mode = false;
|
||||
d->is_connected = false;
|
||||
d->scene_scaling = false;
|
||||
d->scaler = QVector3D(1,1,1);
|
||||
|
||||
connect( d->textRenderer, SIGNAL(sendMessage(QString,int)),
|
||||
this, SLOT(printMessage(QString,int)) );
|
||||
|
|
@ -407,7 +414,7 @@ Viewer::~Viewer()
|
|||
.arg(d->back_color.redF())
|
||||
.arg(d->back_color.greenF())
|
||||
.arg(d->back_color.blueF()));
|
||||
|
||||
makeCurrent();
|
||||
d->vao.destroy();
|
||||
if(d->_recentFunctions)
|
||||
delete d->_recentFunctions;
|
||||
|
|
@ -831,9 +838,23 @@ void Viewer::postSelection(const QPoint& pixel)
|
|||
point = camera()->pointUnderPixel(pixel, found) - offset();
|
||||
}
|
||||
if(found) {
|
||||
Q_EMIT selectedPoint(point.x,
|
||||
point.y,
|
||||
point.z);
|
||||
QVector3D transformed_point(point.x,
|
||||
point.y,
|
||||
point.z);
|
||||
if(d->scene_scaling)
|
||||
{
|
||||
transformed_point = QVector3D(
|
||||
point.x+offset().x,
|
||||
point.y+offset().y,
|
||||
point.z+offset().z);
|
||||
transformed_point = transformed_point/d->scaler;
|
||||
transformed_point[0] -=offset().x ;
|
||||
transformed_point[1] -=offset().y ;
|
||||
transformed_point[2] -=offset().z ;
|
||||
}
|
||||
Q_EMIT selectedPoint(transformed_point.x(),
|
||||
transformed_point.y(),
|
||||
transformed_point.z());
|
||||
CGAL::qglviewer::Vec dir;
|
||||
CGAL::qglviewer::Vec orig;
|
||||
if(d->projection_is_ortho)
|
||||
|
|
@ -931,6 +952,10 @@ void Viewer::attribBuffers(int program_name) const {
|
|||
this->camera()->getModelViewProjectionMatrix(d_mat);
|
||||
for (int i=0; i<16; ++i)
|
||||
mvp_mat.data()[i] = GLfloat(d_mat[i]);
|
||||
if(d->scene_scaling){
|
||||
mvp_mat.scale(d->scaler);
|
||||
mv_mat.scale(d->scaler);
|
||||
}
|
||||
|
||||
QOpenGLShaderProgram* program = getShaderProgram(program_name);
|
||||
program->bind();
|
||||
|
|
@ -1130,7 +1155,7 @@ void Viewer::drawVisualHints()
|
|||
{
|
||||
d->textRenderer->addText(message_text);
|
||||
}
|
||||
d->textRenderer->draw(this);
|
||||
d->textRenderer->draw(this, d->scaler);
|
||||
|
||||
if (d->_displayMessage)
|
||||
d->textRenderer->removeText(message_text);
|
||||
|
|
@ -1458,7 +1483,7 @@ void Viewer::wheelEvent(QWheelEvent* e)
|
|||
|
||||
bool Viewer::testDisplayId(double x, double y, double z)
|
||||
{
|
||||
return d->scene->testDisplayId(x,y,z,this);
|
||||
return d->scene->testDisplayId(x,y,z,this, d->scaler);
|
||||
}
|
||||
|
||||
QPainter* Viewer::getPainter(){return d->painter;}
|
||||
|
|
@ -1552,26 +1577,26 @@ void Viewer_impl::showDistance(QPoint pixel)
|
|||
rendering_program_dist.setAttributeBuffer("vertex",GL_FLOAT,0,3);
|
||||
buffer.release();
|
||||
vao.release();
|
||||
|
||||
distance_is_displayed = true;
|
||||
double dist = std::sqrt((BPoint.x-APoint.x)*(BPoint.x-APoint.x) + (BPoint.y-APoint.y)*(BPoint.y-APoint.y) + (BPoint.z-APoint.z)*(BPoint.z-APoint.z));
|
||||
double dist = std::sqrt((BPoint.x-APoint.x)/scaler.x()*(BPoint.x-APoint.x)/scaler.x() + (BPoint.y-APoint.y)/scaler.y()*(BPoint.y-APoint.y)/scaler.y() + (BPoint.z-APoint.z)/scaler.z()*(BPoint.z-APoint.z)/scaler.z());
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
TextItem *ACoord = new TextItem(float(APoint.x),
|
||||
float(APoint.y),
|
||||
float(APoint.z),
|
||||
QString("A(%1,%2,%3)")
|
||||
.arg(APoint.x-viewer->offset().x, 0, 'g', 10)
|
||||
.arg(APoint.y-viewer->offset().y, 0, 'g', 10)
|
||||
.arg(APoint.z-viewer->offset().z, 0, 'g', 10), true, font, Qt::red, true);
|
||||
.arg(APoint.x/scaler.x()-viewer->offset().x, 0, 'g', 10)
|
||||
.arg(APoint.y/scaler.y()-viewer->offset().y, 0, 'g', 10)
|
||||
.arg(APoint.z/scaler.z()-viewer->offset().z, 0, 'g', 10), true, font, Qt::red, true);
|
||||
distance_text.append(ACoord);
|
||||
TextItem *BCoord = new TextItem(float(BPoint.x),
|
||||
float(BPoint.y),
|
||||
float(BPoint.z),
|
||||
QString("B(%1,%2,%3)")
|
||||
.arg(BPoint.x-viewer->offset().x, 0, 'g', 10)
|
||||
.arg(BPoint.y-viewer->offset().y, 0, 'g', 10)
|
||||
.arg(BPoint.z-viewer->offset().z, 0, 'g', 10), true, font, Qt::red, true);
|
||||
.arg(BPoint.x/scaler.x()-viewer->offset().x, 0, 'g', 10)
|
||||
.arg(BPoint.y/scaler.y()-viewer->offset().y, 0, 'g', 10)
|
||||
.arg(BPoint.z/scaler.z()-viewer->offset().z, 0, 'g', 10), true, font, Qt::red, true);
|
||||
|
||||
distance_text.append(BCoord);
|
||||
CGAL::qglviewer::Vec centerPoint = 0.5*(BPoint+APoint);
|
||||
TextItem *centerCoord = new TextItem(float(centerPoint.x),
|
||||
|
|
@ -1583,12 +1608,12 @@ void Viewer_impl::showDistance(QPoint pixel)
|
|||
Q_FOREACH(TextItem* ti, distance_text)
|
||||
textRenderer->addText(ti);
|
||||
Q_EMIT(viewer->sendMessage(QString("First point : A(%1,%2,%3), second point : B(%4,%5,%6), distance between them : %7")
|
||||
.arg(APoint.x-viewer->offset().x)
|
||||
.arg(APoint.y-viewer->offset().y)
|
||||
.arg(APoint.z-viewer->offset().z)
|
||||
.arg(BPoint.x-viewer->offset().x)
|
||||
.arg(BPoint.y-viewer->offset().y)
|
||||
.arg(BPoint.z-viewer->offset().z)
|
||||
.arg(APoint.x/scaler.x()-viewer->offset().x)
|
||||
.arg(APoint.y/scaler.y()-viewer->offset().y)
|
||||
.arg(APoint.z/scaler.z()-viewer->offset().z)
|
||||
.arg(BPoint.x/scaler.x()-viewer->offset().x)
|
||||
.arg(BPoint.y/scaler.y()-viewer->offset().y)
|
||||
.arg(BPoint.z/scaler.z()-viewer->offset().z)
|
||||
.arg(dist, 0, 'g', 10)));
|
||||
}
|
||||
|
||||
|
|
@ -1958,6 +1983,56 @@ bool Viewer::isClipping() const
|
|||
{
|
||||
return d->clipping;
|
||||
}
|
||||
|
||||
void Viewer::scaleScene()
|
||||
{
|
||||
CGAL::Bbox_3 bbox = CGAL::Three::Three::scene()->bbox();
|
||||
if(!d->scene_scaling)
|
||||
{
|
||||
QMultipleInputDialog dialog ("Scale Scene", CGAL::Three::Three::mainWindow());
|
||||
DoubleEdit* x_val = dialog.add<DoubleEdit> ("Scale along X");
|
||||
DoubleEdit* y_val = dialog.add<DoubleEdit> ("Scale along Y");
|
||||
DoubleEdit* z_val = dialog.add<DoubleEdit> ("Scale along Z");
|
||||
x_val->setMinimum(0);
|
||||
y_val->setMinimum(0);
|
||||
z_val->setMinimum(0);
|
||||
if(bbox != CGAL::Bbox_3(0,0,0,0,0,0))
|
||||
{
|
||||
QPushButton* norm_button = dialog.add<QPushButton> ("");
|
||||
norm_button->setText("Normalize");
|
||||
norm_button->setToolTip("Automatically fill values to display the scene in a unit cube.");
|
||||
|
||||
connect(norm_button, &QPushButton::clicked, this,
|
||||
[x_val, y_val, z_val, &bbox](){
|
||||
x_val->setValue(1.0/(bbox.xmax()-bbox.xmin()));
|
||||
y_val->setValue(1.0/(bbox.ymax()-bbox.ymin()));
|
||||
z_val->setValue(1.0/(bbox.zmax()-bbox.zmin()));
|
||||
});
|
||||
}
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
{
|
||||
parent()->findChild<QAction*>("actionScaleScene")->setChecked(false);
|
||||
return;
|
||||
}
|
||||
d->scaler.setX(x_val->text()==""?1.0:x_val->value());
|
||||
d->scaler.setY(y_val->text()==""?1.0:y_val->value());
|
||||
d->scaler.setZ(z_val->text()==""?1.0:z_val->value());
|
||||
|
||||
if(d->scaler.x() == 0.0 || d->scaler.y() == 0.0 || d->scaler.z()== 0.0)
|
||||
{
|
||||
parent()->findChild<QAction*>("actionScaleScene")->setChecked(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
d->scaler = QVector3D(1,1,1);
|
||||
|
||||
CGAL::qglviewer::Vec vmin(((float)bbox.xmin()+offset().x)*d->scaler.x(), ((float)bbox.ymin()+offset().y)*d->scaler.y(), ((float)bbox.zmin()+offset().z)*d->scaler.z()),
|
||||
vmax(((float)bbox.xmax()+offset().x)*d->scaler.x(), ((float)bbox.ymax()+offset().y)*d->scaler.y(), ((float)bbox.zmax()+offset().z)*d->scaler.z());
|
||||
camera()->setPivotPoint((vmin+vmax)*0.5);
|
||||
camera()->fitBoundingBox(vmin, vmax);
|
||||
d->scene_scaling = !d->scene_scaling;
|
||||
}
|
||||
#ifdef CGAL_USE_WEBSOCKETS
|
||||
void Viewer::setShareCam(bool b, QString session)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ public Q_SLOTS:
|
|||
void onSocketConnected();
|
||||
void onTextMessageSocketReceived(QString message);
|
||||
#endif
|
||||
|
||||
void scaleScene();
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *)Q_DECL_OVERRIDE;
|
||||
void paintGL()Q_DECL_OVERRIDE;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public:
|
|||
* \param z the Z coordinate of theTextItem's position.
|
||||
* \param viewer the viewer used to display the Scene.
|
||||
* \return true if the TextItem is visible. */
|
||||
virtual bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer) = 0;
|
||||
virtual bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer, const QVector3D& scaler) = 0;
|
||||
|
||||
///\brief displays all the vertices ids if there are less than max_textItems.
|
||||
virtual void printVertexIds() = 0;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public:
|
|||
//!
|
||||
//! \returns true if the Id should be displayed
|
||||
//! \returns false if the Id should not be displayed (if it is hidden for example)
|
||||
virtual bool testDisplayId(double, double, double, CGAL::Three::Viewer_interface*)const = 0;
|
||||
virtual bool testDisplayId(double, double, double, CGAL::Three::Viewer_interface*, const QVector3D& scaler)const = 0;
|
||||
|
||||
//! \brief Tests if this item should display its ids.
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ public:
|
|||
{
|
||||
}
|
||||
//!Draws all the `TextItem`s
|
||||
void draw(CGAL::Three::Viewer_interface* viewer);
|
||||
void draw(CGAL::Three::Viewer_interface* viewer, const QVector3D& scaler);
|
||||
//!\brief Adds a single TextItem to TextRenderer::local_textItems
|
||||
//!
|
||||
//! @see addText(float p_x, float p_y, float p_z, QString p_text, bool p_3D = true, QFont font = QFont(), QColor p_color = Qt::black)
|
||||
|
|
|
|||
Loading…
Reference in New Issue