Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Lab/demo/Lab/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,10 @@ if(CGAL_Qt6_FOUND AND Qt6_FOUND)
if(TARGET Qt6::WebSockets)
target_compile_definitions(cgal_lab PRIVATE -DCGAL_USE_WEBSOCKETS)
target_compile_definitions(demo_framework PRIVATE -DCGAL_USE_WEBSOCKETS)
target_link_libraries(cgal_lab PRIVATE Qt6::WebSockets)
target_link_libraries(
cgal_lab PRIVATE demo_framework point_dialog Qt6::Widgets
PUBLIC CGAL::CGAL Qt6::Gui Qt6::OpenGLWidgets Qt6::Qml
)
endif()
cgal_add_compilation_test(cgal_lab)

Expand Down
99 changes: 74 additions & 25 deletions Lab/demo/Lab/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
#include "File_loader_dialog.h"
#include "Viewer.h"



#include <CGAL/Qt/manipulatedCameraFrame.h>
#include <CGAL/Qt/manipulatedFrame.h>

Expand Down Expand Up @@ -957,16 +959,38 @@ void MainWindow::reloadItem() {

Scene_item* item = nullptr;

for(Scene::Item_id id : scene->selectionIndices())
{
for(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.
if(!item)
continue;

QString filename = item->property("source filename").toString();
QString loader_name = item->property("loader_name").toString();

// ---> 1. CACHE DEPENDENCIES BEFORE THEY SELF-DESTRUCT <---
typedef QPair<QString, QString> DepInfo;
QList<DepInfo> saved_deps;

for(int i = 0; i < scene->numberOfEntries(); ++i) {
Scene_item* potential_dep = scene->item(i);
if(!potential_dep)
continue;

QVariant parent_name_var = potential_dep->property("parent_mesh_name");
if(parent_name_var.isValid() && parent_name_var.toString() == item->name()) {
QString d_file = potential_dep->property("source filename").toString();
QString d_loader = potential_dep->property("loader_name").toString();

if(!d_file.isEmpty() && !d_loader.isEmpty()) {
saved_deps.append(qMakePair(d_file, d_loader));
}
}
}

if(filename.isEmpty() || loader_name.isEmpty()) {
this->warning(QString("Cannot reload item %1: "
"the item has no \"source filename\" or no \"loader_name\" attached\n").arg(item->name()));
"the item has no \"source filename\" or no \"loader_name\" attached\n")
.arg(item->name()));
continue;
}

Expand All @@ -976,40 +1000,65 @@ void MainWindow::reloadItem() {
QList<Scene_item*> new_items = loadItem(fileinfo, fileloader, ok, false);
if(!ok)
return;

QVariant varian = item->property("load_mates");
if(!varian.isValid()) //typically when a soup is oriented, the soup_item is deleted and thus the varain points to an unexisting item.
{
Scene_item* item_to_highlight = nullptr; // Track the new mesh to give it focus

// BRANCH A: Standard Reload
if(!varian.isValid()) {
Scene_item* new_item = new_items.front();
new_item->setName(item->name());
new_item->setColor(item->color());
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_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);
new_item->invalidateOpenGLBuffers();

item_to_highlight = new_item;
item->deleteLater();
return;
}
QSequentialIterable iterable = varian.value<QSequentialIterable>();
// BRANCH B: Load Mates Reload
else {
QSequentialIterable iterable = varian.value<QSequentialIterable>();
int mate_id = 0;
for(const QVariant& v : iterable) {
Scene_item* mate = v.value<Scene_item*>();
Scene_item* new_item = new_items[mate_id];
new_item->setName(mate->name());
new_item->setColor(mate->color());
new_item->setRenderingMode(mate->renderingMode());
new_item->setVisible(mate->visible());
Scene_item_with_properties* property_item = dynamic_cast<Scene_item_with_properties*>(new_item);
scene->replaceItem(scene->item_id(mate), new_item, true);
if(property_item)
property_item->copyProperties(mate);
new_item->invalidateOpenGLBuffers();
mate->deleteLater();

item_to_highlight = new_item;
}
}

// Can use foreach:
int mate_id = 0;
for(const QVariant &v: iterable)
{
Scene_item* mate = v.value<Scene_item*>();
Scene_item* new_item = new_items[mate_id];
new_item->setName(mate->name());
new_item->setColor(mate->color());
new_item->setRenderingMode(mate->renderingMode());
new_item->setVisible(mate->visible());
Scene_item_with_properties *property_item = dynamic_cast<Scene_item_with_properties*>(new_item);
scene->replaceItem(scene->item_id(mate), new_item, true);
if(property_item)
property_item->copyProperties(mate);
new_item->invalidateOpenGLBuffers();
mate->deleteLater();
// ---> 2. RESTORE DEPENDENCIES (Runs unconditionally now!) <---
if(item_to_highlight) {
// Force the UI to highlight the newly loaded mesh
scene->setSelectedItem(scene->item_id(item_to_highlight));
QCoreApplication::processEvents();

// Command the plugin to reload the cached text files
for(const DepInfo& info : saved_deps) {
CGAL::Three::CGAL_Lab_io_plugin_interface* dep_fileloader = findLoader(info.second);
QFileInfo dep_fileinfo(info.first);
bool dep_ok;
loadItem(dep_fileinfo, dep_fileloader, dep_ok, true);
}
}

if(!varian.isValid()) {
return;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions Lab/demo/Lab/Plugins/PMP/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
include(CGALlab_macros)



if(TARGET CGAL::Eigen3_support)
cgal_lab_plugin(jet_fitting_plugin Jet_fitting_plugin)
target_link_libraries(
Expand Down
2 changes: 2 additions & 0 deletions Lab/demo/Lab/Plugins/PMP/Degenerated_faces_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ void Degenerated_faces_plugin::on_actionDegenFaces_triggered()
selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(poly_item->name()));
poly_item->setRenderingMode(Wireframe);
scene->addItem(selection_item);
poly_item->addDependency(selection_item);
scene->itemChanged(poly_item);
scene->itemChanged(selection_item);
found = true;
Expand Down Expand Up @@ -204,6 +205,7 @@ void Degenerated_faces_plugin::on_actionDegenEdges_triggered()
selection_item->setName(tr("%1 (selection) (null length edges)").arg(poly_item->name()));
poly_item->setRenderingMode(Wireframe);
scene->addItem(selection_item);
poly_item->addDependency(selection_item);
scene->itemChanged(poly_item);
scene->itemChanged(selection_item);
found = true;
Expand Down
50 changes: 32 additions & 18 deletions Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,34 @@ class CGAL_Lab_selection_plugin :
return false;
}

QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override {
if(fileinfo.suffix().toLower() != "txt")
{
ok = false;
return QList<Scene_item*>();
}
// There will be no actual loading at this step.
Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item();
if(!item->load(fileinfo.filePath().toStdString())) {
delete item;
ok = false;
return QList<Scene_item*>();
}
item->setName(fileinfo.completeBaseName());
ok = true;
if(add_to_scene)
CGAL::Three::Three::scene()->addItem(item);
return QList<Scene_item*>()<<item;
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene = true) override {
if(fileinfo.suffix().toLower() != "txt") {
ok = false;
return QList<Scene_item*>();
}

// 1. Create the item. (CGAL automatically attaches this to whatever is highlighted in the UI!)
Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item();

// 2. Load the points. Since we didn't mess with the mesh pointer, it maps perfectly.
if(!item->load(fileinfo.filePath().toStdString())) {
delete item;
ok = false;
return QList<Scene_item*>();
}

item->setName(fileinfo.completeBaseName());

// 3. TAG IT: Just quietly tag it so MainWindow can find it during a reload.
Scene_item* target_item = CGAL::Three::Three::scene()->item(CGAL::Three::Three::scene()->mainSelectionIndex());
if(target_item) {
item->setProperty("parent_mesh_name", target_item->name());
}

ok = true;
if(add_to_scene)
CGAL::Three::Three::scene()->addItem(item);
return QList<Scene_item*>() << item;
}

bool canSave(const CGAL::Three::Scene_item* scene_item) override {
Expand Down Expand Up @@ -1199,6 +1209,10 @@ public Q_SLOTS:
}

selection_item_map.insert(std::make_pair(poly_item, selection_item));

poly_item->addDependency(selection_item);


connect(this, SIGNAL(save_handleType()),selection_item, SLOT(save_handleType()));
connect(selection_item, SIGNAL(updateInstructions(QString)), this, SLOT(setInstructions(QString)));
connect(selection_item, SIGNAL(printMessage(QString)), this, SLOT(printMessage(QString)));
Expand Down
Loading