Merge pull request #3424 from maxGimeno/Demo-Some_fixes-GF

Polyhedron demo: some fixes
This commit is contained in:
Sebastien Loriot 2018-11-15 19:57:46 +01:00 committed by GitHub
commit 641efa944b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 602 additions and 135 deletions

View File

@ -426,8 +426,25 @@ public:
const Local_point& S=facet[id];
const Local_point& T=facet[(id+1==facet.size())?0:id+1];
Local_vector V1=Local_vector((T-S).x(), (T-S).y(), (T-S).z());
if(std::isnan(S.x()) ||
std::isnan(S.y()) ||
std::isnan(S.z()))
{
return false;
}
if(std::isnan(T.x()) ||
std::isnan(T.y()) ||
std::isnan(T.z()))
{
return false;
}
const Local_point& U=facet[(id+2==facet.size())?0:id+2];
if(std::isnan(U.x()) ||
std::isnan(U.y()) ||
std::isnan(U.z()))
{
return false;
}
Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z());
orientation = Local_kernel::Orientation_3()(V1, V2, normal);

View File

@ -12,14 +12,22 @@ compute_color_map(QColor base_color,
qreal hue = base_color.hueF();
const qreal step = ((qreal)1) / nb_of_colors;
qreal h = hue;
int s = base_color.saturation(),
v = base_color.value();
s = s<90 ? s+90 : s;
v = v<90 ? v+90 : v;
float sf=s/256.0f,
vf=v/256.0f;
qreal h = hue==-1 ? 0
:hue;
for(unsigned i = 0; i < nb_of_colors; ++i) {
if (h!=-1) h += step;
if ( h > 1 ) { h -= 1; }
//avoid S and V near 0 to avoid having all the same colors
*out++ = QColor::fromHsvF(h,
base_color.saturationF(),
base_color.valueF());
sf,
vf);
}
return out;
}

View File

@ -211,6 +211,8 @@ MainWindow::MainWindow(bool verbose, QWidget* parent)
connect(scene, SIGNAL(selectionChanged(int)),
this, SLOT(selectSceneItem(int)));
connect(scene, SIGNAL(selectionChanged(QList<int>)),
this, SLOT(selectSceneItems(QList<int>)));
connect(scene, SIGNAL(itemPicked(const QModelIndex &)),
this, SLOT(recenterSceneView(const QModelIndex &)));
@ -350,7 +352,7 @@ MainWindow::MainWindow(bool verbose, QWidget* parent)
readSettings(); // Among other things, the column widths are stored.
// Load plugins, and re-enable actions that need it.
operationSearchBar.setPlaceholderText("Research...");
operationSearchBar.setPlaceholderText("Filter...");
searchAction->setDefaultWidget(&operationSearchBar);
connect(&operationSearchBar, &QLineEdit::textChanged,
this, &MainWindow::filterOperations);
@ -397,29 +399,45 @@ MainWindow::MainWindow(bool verbose, QWidget* parent)
}
//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)
void filterMenuOperations(QMenu* menu, bool showFullMenu)
{
Q_FOREACH(QAction* action, menu->actions()) {
if(QMenu* menu = action->menu())
{
filterMenuOperations(menu);
action->setVisible(!(menu->isEmpty()));
}
Q_FOREACH(QAction* action, menu->actions()) {
if(QMenu* menu = action->menu())
{
filterMenuOperations(menu, showFullMenu);
action->setVisible(showFullMenu && !(menu->isEmpty()));
}
}
}
void MainWindow::filterOperations()
{
static QVector<QAction*> to_remove;
Q_FOREACH(QAction* action, to_remove)
ui->menuOperations->removeAction(action);
QString filter=operationSearchBar.text();
Q_FOREACH(const PluginNamePair& p, plugins) {
Q_FOREACH(QAction* action, p.first->actions()) {
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);
}
}
}
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
}
// do a pass over all menus in Operations and their sub-menus(etc.) and hide them when they are empty
filterMenuOperations(ui->menuOperations);
filterMenuOperations(ui->menuOperations, filter.isEmpty());
}
#include <CGAL/Three/exceptions.h>
@ -1159,6 +1177,24 @@ void MainWindow::selectSceneItem(int i)
sceneView->selectionModel()->select(s,
QItemSelectionModel::ClearAndSelect);
sceneView->scrollTo(s.indexes().first());
}
}
void MainWindow::selectSceneItems(QList<int> is)
{
if(is.first() < 0 || is.last() >= scene->numberOfEntries()) {
sceneView->selectionModel()->clearSelection();
updateInfo();
updateDisplayInfo();
}
else {
QItemSelection s =
proxyModel->mapSelectionFromSource(scene->createSelection(is));
sceneView->selectionModel()->select(s,
QItemSelectionModel::ClearAndSelect);
sceneView->scrollTo(s.indexes().first());
}
}
@ -1337,6 +1373,7 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
else if(scene->selectionIndices().size() > 1 )
{
QMap<QString, QAction*> menu_actions;
QVector<QMenu*> slider_menus;
bool has_stats = false;
Q_FOREACH(QAction* action, scene->item(main_index)->contextMenu()->actions())
{
@ -1347,6 +1384,14 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
{
menu_actions["alpha slider"] = action->menu()->actions().last();
}
else if(action->text() == QString("Points Size"))
{
menu_actions["points slider"] = action->menu()->actions().last();
}
else if(action->text() == QString("Normals Length"))
{
menu_actions["normals slider"] = action->menu()->actions().last();
}
}
}
@ -1364,7 +1409,9 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
QMenu menu;
Q_FOREACH(QString name, menu_actions.keys())
{
if(name == QString("alpha slider"))
if(name == QString("alpha slider")
|| name == QString("points slider")
|| name == QString("normals slider"))
continue;
if(name == QString("Alpha value"))
{
@ -1399,7 +1446,75 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
});
QMenu* new_menu = new QMenu("Alpha value", &menu);
new_menu->addAction(sliderAction);
menu.addMenu(new_menu);
slider_menus.push_back(new_menu);
}
else if(name == QString("Points Size"))
{
QWidgetAction* sliderAction = new QWidgetAction(&menu);
QSlider* slider = new QSlider(&menu);
slider->setMinimum(1);
slider->setMaximum(25);
slider->setValue(
qobject_cast<QSlider*>(
qobject_cast<QWidgetAction*>
(menu_actions["points slider"])->defaultWidget()
)->value());
slider->setOrientation(Qt::Horizontal);
sliderAction->setDefaultWidget(slider);
connect(slider, &QSlider::valueChanged, [this, slider]()
{
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
{
Scene_item* item = scene->item(id);
Q_FOREACH(QAction* action, item->contextMenu()->actions())
{
if(action->text() == "Points Size")
{
QWidgetAction* sliderAction = qobject_cast<QWidgetAction*>(action->menu()->actions().last());
QSlider* ac_slider = qobject_cast<QSlider*>(sliderAction->defaultWidget());
ac_slider->setValue(slider->value());
break;
}
}
}
});
QMenu* new_menu = new QMenu("Points Size", &menu);
new_menu->addAction(sliderAction);
slider_menus.push_back(new_menu);
}
else if(name == QString("Normals Length"))
{
QWidgetAction* sliderAction = new QWidgetAction(&menu);
QSlider* slider = new QSlider(&menu);
slider->setValue(
qobject_cast<QSlider*>(
qobject_cast<QWidgetAction*>
(menu_actions["normals slider"])->defaultWidget()
)->value());
slider->setOrientation(Qt::Horizontal);
sliderAction->setDefaultWidget(slider);
connect(slider, &QSlider::valueChanged, [this, slider]()
{
Q_FOREACH(Scene::Item_id id, scene->selectionIndices())
{
Scene_item* item = scene->item(id);
Q_FOREACH(QAction* action, item->contextMenu()->actions())
{
if(action->text() == "Normals Length")
{
QWidgetAction* sliderAction = qobject_cast<QWidgetAction*>(action->menu()->actions().last());
QSlider* ac_slider = qobject_cast<QSlider*>(sliderAction->defaultWidget());
ac_slider->setValue(slider->value());
break;
}
}
}
});
QMenu* new_menu = new QMenu("Normals Length", &menu);
new_menu->addAction(sliderAction);
slider_menus.push_back(new_menu);
}
else
{
@ -1407,6 +1522,13 @@ void MainWindow::showSceneContextMenu(const QPoint& p) {
connect(action, &QAction::triggered, this, &MainWindow::propagate_action);
}
}
if(!slider_menus.empty())
{
Q_FOREACH(QMenu* m, slider_menus){
menu.addMenu(m);
}
menu.insertSeparator(0);
}
if(has_stats)
{
QAction* actionStatistics =
@ -1443,14 +1565,15 @@ void MainWindow::updateInfo() {
if(item) {
QString item_text = item->toolTip();
QString item_filename = item->property("source filename").toString();
if(item->bbox()!=CGAL::Bbox_3())
CGAL::Bbox_3 bbox = item->bbox();
if(bbox !=CGAL::Bbox_3())
item_text += QString("<div>Bounding box: min (%1,%2,%3), max (%4,%5,%6)</div>")
.arg(item->bbox().xmin())
.arg(item->bbox().ymin())
.arg(item->bbox().zmin())
.arg(item->bbox().xmax())
.arg(item->bbox().ymax())
.arg(item->bbox().zmax());
.arg(bbox.xmin())
.arg(bbox.ymin())
.arg(bbox.zmin())
.arg(bbox.xmax())
.arg(bbox.ymax())
.arg(bbox.zmax());
if(!item_filename.isEmpty()) {
item_text += QString("<div>File:<i> %1</div>").arg(item_filename);
}
@ -1473,6 +1596,7 @@ void MainWindow::readSettings()
QSettings settings;
viewer->setAntiAliasing(settings.value("antialiasing", false).toBool());
viewer->setFastDrawing(settings.value("quick_camera_mode", true).toBool());
scene->enableVisibilityRecentering(settings.value("offset_update", true).toBool());
viewer->textRenderer()->setMax(settings.value("max_text_items", 10000).toInt());
viewer->setTotalPass(settings.value("transparency_pass_number", 4).toInt());
CGAL::Three::Three::s_defaultSMRM = CGAL::Three::Three::modeFromName(
@ -1483,6 +1607,9 @@ void MainWindow::readSettings()
QStringList blacklist=settings.value("plugin_blacklist",QStringList()).toStringList();
Q_FOREACH(QString name,blacklist){ plugin_blacklist.insert(name); }
def_save_dir = settings.value("default_saveas_dir", QDir::homePath()).toString();
this->default_point_size = settings.value("points_size").toInt();
this->default_normal_length = settings.value("normals_length").toInt();
this->default_lines_width = settings.value("lines_width").toInt();
}
void MainWindow::writeSettings()
@ -1710,7 +1837,7 @@ void MainWindow::on_actionSaveAs_triggered()
&sf);
if(filename.isEmpty())
continue;
return;
last_saved_dir = QFileInfo(filename).absoluteDir().path();
extensions.indexIn(sf.split(";;").first());
QString filter_ext, filename_ext;
@ -1845,6 +1972,22 @@ void MainWindow::on_actionPreferences_triggered()
QSettings settings;
prefdiag.setupUi(&dialog);
float lineWidth[2];
if(!viewer->isOpenGL_4_3())
viewer->glGetFloatv(GL_LINE_WIDTH_RANGE, lineWidth);
else
{
lineWidth[0] = 0;
lineWidth[1] = 10;
}
prefdiag.linesHorizontalSlider->setMinimum(lineWidth[0]);
prefdiag.linesHorizontalSlider->setMaximum(lineWidth[1]);
prefdiag.offset_updateCheckBox->setChecked(
settings.value("offset_update", true).toBool());
connect(prefdiag.offset_updateCheckBox, SIGNAL(toggled(bool)),
scene, SLOT(enableVisibilityRecentering(bool)));
prefdiag.antialiasingCheckBox->setChecked(settings.value("antialiasing", false).toBool());
connect(prefdiag.antialiasingCheckBox, SIGNAL(toggled(bool)),
viewer, SLOT(setAntiAliasing(bool)));
@ -1865,6 +2008,24 @@ void MainWindow::on_actionPreferences_triggered()
{
setTransparencyPasses(i);
});
prefdiag.pointsHorizontalSlider->setValue(this->default_point_size);
connect(prefdiag.pointsHorizontalSlider, &QSlider::valueChanged,
this, [this](int i)
{
this->default_point_size = i;
});
prefdiag.normalsHorizontalSlider->setValue(this->default_normal_length);
connect(prefdiag.normalsHorizontalSlider, &QSlider::valueChanged,
this, [this](int i)
{
this->default_normal_length = i;
});
prefdiag.linesHorizontalSlider->setValue(this->default_lines_width);
connect(prefdiag.linesHorizontalSlider, &QSlider::valueChanged,
this, [this](int i)
{
this->default_lines_width = i;
});
connect(prefdiag.background_colorPushButton, &QPushButton::clicked,
this, &MainWindow::setBackgroundColor);
@ -1906,10 +2067,10 @@ void MainWindow::on_actionPreferences_triggered()
QTreeWidgetItem *item = new QTreeWidgetItem(pluginItem);
item->setText(1, name);
if(plugin_blacklist.contains(name)){
item->setCheckState(0, Qt::Checked);
item->setCheckState(0, Qt::Unchecked);
}
else{
item->setCheckState(0, Qt::Unchecked);
item->setCheckState(0, Qt::Checked);
}
if(pluginsStatus_map[name] == QString("success"))
item->setBackground(1, successBrush);
@ -1933,13 +2094,15 @@ void MainWindow::on_actionPreferences_triggered()
for (std::size_t k=0; k<items.size(); ++k)
{
QTreeWidgetItem* item=items[k];
if (item->checkState(0)==Qt::Checked)
if (item->checkState(0)==Qt::Unchecked)
plugin_blacklist.insert(item->text(1));
}
//write settings
settings.setValue("antialiasing",
prefdiag.antialiasingCheckBox->isChecked());
settings.setValue("offset_update",
prefdiag.offset_updateCheckBox->isChecked());
settings.setValue("quick_camera_mode",
prefdiag.quick_cameraCheckBox->isChecked());
settings.setValue("transparency_pass_number",
@ -1951,7 +2114,9 @@ void MainWindow::on_actionPreferences_triggered()
CGAL::Three::Three::defaultSurfaceMeshRenderingMode()));
settings.setValue("default_ps_rm", CGAL::Three::Three::modeName(
CGAL::Three::Three::defaultPointSetRenderingMode()));
settings.setValue("points_size", this->default_point_size);
settings.setValue("normals_length", this->default_normal_length);
settings.setValue("lines_width", this->default_lines_width);
}
}
@ -2055,7 +2220,7 @@ void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m)
void MainWindow::on_actionRecenterScene_triggered()
{
updateViewerBBox();
viewer->camera()->interpolateToFitScene();
viewer->camera()->showEntireScene();
}
void MainWindow::on_actionLoadPlugin_triggered()

View File

@ -142,6 +142,11 @@ public Q_SLOTS:
* the index i in the Geometric Objects view.
*/
void selectSceneItem(int i);
/*!
* Clears the current selection and selects the scene_items with
* indices in is in the Geometric Objects view.
*/
void selectSceneItems(QList<int> i);
/*!
* Prints coordinates of a point and its distance to the last
* position printed by this function.

View File

@ -16,11 +16,16 @@ public:
QString nameFilters() const { return "Selection files(*.selection.txt)"; }
bool canLoad() const {
Scene_facegraph_item* sel_item = qobject_cast<Scene_facegraph_item*>(CGAL::Three::Three::scene()->item(
CGAL::Three::Three::scene()->mainSelectionIndex()));
if(sel_item)
return true;
return false;
Scene_item * item = CGAL::Three::Three::scene()->item(
CGAL::Three::Three::scene()->mainSelectionIndex());
Scene_facegraph_item* fg_item = qobject_cast<Scene_facegraph_item*>(item);
if(fg_item)
return true;
Scene_polyhedron_selection_item* sel_item =
qobject_cast<Scene_polyhedron_selection_item*>(item);
if (sel_item)
return true;
return false;
}
CGAL::Three::Scene_item* load(QFileInfo fileinfo) {
if(fileinfo.suffix().toLower() != "txt") return 0;

View File

@ -280,7 +280,7 @@ public:
QString nameFilters() const {
return "VTK PolyData files (*.vtk);; VTK XML PolyData (*.vtp);; VTK XML UnstructuredGrid (*.vtu)"; }
QString name() const { return "vtk_sm_plugin"; }
QString name() const { return "vtk_plugin"; }
bool canSave(const CGAL::Three::Scene_item* item)
{
return (qobject_cast<const Scene_facegraph_item*>(item)

View File

@ -133,6 +133,7 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
if ( NULL != sm_item )
{
const_cast<Scene_surface_mesh_item*>(sm_item)->setItemIsMulticolor(true);
const_cast<Scene_surface_mesh_item*>(sm_item)->computeItemColorVectorAutomatically(true);
// Build domain
const SMesh* smesh = sm_item->face_graph();
if ( NULL == smesh )

View File

@ -97,8 +97,11 @@ private:
QApplication::setOverrideCursor(Qt::WaitCursor);
item->face_graph()->collect_garbage();
item->color_vector().clear();
if(!item->hasPatchIds())
if(!item->hasPatchIds()){
item->setItemIsMulticolor(true);
item->computeItemColorVectorAutomatically(true);
}
typedef boost::property_map<FaceGraph,CGAL::face_patch_id_t<int> >::type PatchIDMap;
FaceGraph* fg =item->face_graph();
boost::property_map<FaceGraph, boost::vertex_index_t>::type

View File

@ -133,6 +133,7 @@ void Polyhedron_demo_detect_sharp_edges_plugin::detectSharpEdges(bool input_dial
.vertex_incident_patches_map(vip));
//update item
item->setItemIsMulticolor(true);
item->computeItemColorVectorAutomatically(true);
item->invalidateOpenGLBuffers();
// update scene

View File

@ -473,7 +473,16 @@ public Q_SLOTS:
}
selection_item->polyhedron_item()->setColor(
selection_item->polyhedron_item()->color());
selection_item->polyhedron_item()->setItemIsMulticolor(fpmap_valid);
if(fpmap_valid)
{
selection_item->polyhedron_item()->setItemIsMulticolor(true);
selection_item->polyhedron_item()->computeItemColorVectorAutomatically(true);
}
else
{
selection_item->polyhedron_item()->setItemIsMulticolor(false);
}
selection_item->polyhedron_item()->polyhedron()->collect_garbage();
//fix constrained_edges_map
for(int i=0; i< nE; ++i)

View File

@ -81,7 +81,6 @@ public Q_SLOTS:
private :
CGAL::Three::Scene_interface* scene;
std::vector<QColor> colors_;
}; // end Polyhedron_demo_polyhedron_stitching_plugin
void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionJoinPolyhedra_triggered()
@ -140,7 +139,6 @@ bool operator()(FaceGraph* mesh1, FaceGraph* mesh2)
void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionSplitPolyhedra_triggered()
{
Q_FOREACH(int index, scene->selectionIndices()) {
colors_.clear();
Scene_facegraph_item* item =
qobject_cast<Scene_facegraph_item*>(scene->item(index));
if(item)
@ -176,17 +174,17 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionSplitPolyhedra_tr
}
int cc=0;
compute_color_map(item->color(), item->isItemMulticolor() ? static_cast<unsigned int>(new_polyhedra.size()) : 1,
std::back_inserter(colors_));
Scene_group_item *group = new Scene_group_item("CC");
scene->addItem(group);
BOOST_FOREACH(FaceGraph* polyhedron_ptr, new_polyhedra)
{
Scene_facegraph_item* new_item=new Scene_facegraph_item(polyhedron_ptr);
new_item->setName(tr("%1 - CC %2").arg(item->name()).arg(cc));
new_item->setColor(colors_[item->isItemMulticolor()? cc : 0]);
if(item->isItemMulticolor() || item->hasPatchIds())
new_item->setColor(item->color_vector()[cc]);
else
new_item->setColor(item->color());
++cc;
scene->addItem(new_item);
scene->changeGroup(new_item, group);
@ -246,6 +244,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionColorConnectedCom
typedef boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
selection_item->polyhedron_item()->setItemIsMulticolor(true);
selection_item->polyhedron_item()->computeItemColorVectorAutomatically(true);
FaceGraph& pmesh = *(selection_item->polyhedron());
boost::property_map<FaceGraph, boost::face_index_t>::type fim

View File

@ -429,6 +429,7 @@ void Polyhedron_demo_mean_curvature_flow_skeleton_plugin::on_actionSegment()
}
item_segmentation->setItemIsMulticolor(true);
item_segmentation->computeItemColorVectorAutomatically(true);
item_segmentation->setProperty("NbPatchIds", nb_segment); //for join_and_split plugin
item_segmentation->invalidateOpenGLBuffers();
scene->addItem(item_segmentation);

View File

@ -855,23 +855,36 @@ public Q_SLOTS:
qobject_cast<Scene_polyhedron_selection_item*>(scene->item(item_id));
if(!selection_item) { return; }
Scene_face_graph_item* poly_item = getSelectedItem<Scene_face_graph_item>();
Scene_face_graph_item* poly_item = NULL;
if(selection_item->polyhedron_item() == NULL) { //coming from selection_io loader
bool found = false;
for(int i = 0; i<scene->numberOfEntries(); ++i){
poly_item = qobject_cast<Scene_face_graph_item*>(scene->item(i));
if(!poly_item)
continue;
if(!selection_item->actual_load(poly_item, mw)) {
continue;
}
found = true;
selection_item->invalidateOpenGLBuffers();
scene->itemChanged(selection_item);
break;
}
if(!found)
{
print_message("Error: loading selection item is not successful!");
scene->erase(item_id);
return;
}
} else {
poly_item = getSelectedItem<Scene_face_graph_item>();
}
if(!poly_item) {
CGAL_assertion(selection_item->polyhedron_item() == NULL); // which means it is coming from selection_io loader
print_message("Error: please select corresponding polyhedron item from Geometric Objects list.");
scene->erase(item_id);
return;
}
if(selection_item->polyhedron_item() == NULL) { //coming from selection_io loader
if(!selection_item->actual_load(poly_item, mw)) {
print_message("Error: loading selection item is not successful!");
scene->erase(item_id);
return;
}
selection_item->invalidateOpenGLBuffers();
scene->itemChanged(selection_item);
}
// now set default params both for selection items coming from selection_io, or on_Create_selection_item_button_clicked
Active_handle::Type aht = static_cast<Active_handle::Type>(ui_widget.Selection_type_combo_box->currentIndex());
bool is_insert = ui_widget.Insertion_radio_button->isChecked();

View File

@ -229,6 +229,7 @@ void Polyhedron_demo_mesh_plane_detection_plugin::colorize_segmentation(
std::vector<QColor>& color_vector)
{
item->setItemIsMulticolor(true);
item->computeItemColorVectorAutomatically(true);
SMesh* sm = item->face_graph();
color_vector.clear();
std::size_t max_segment = 0;

View File

@ -378,6 +378,7 @@ void Polyhedron_demo_mesh_segmentation_plugin::colorize_sdf(
put(pidmap, *facet_it, static_cast<int>(patch_id));
}
item->setItemIsMulticolor(true);
item->computeItemColorVectorAutomatically(false);
}
@ -407,6 +408,7 @@ void Polyhedron_demo_mesh_segmentation_plugin::colorize_segmentation(
color_vector.push_back(aColor);
}
item->setItemIsMulticolor(true);
item->computeItemColorVectorAutomatically(true);
item->setProperty("NbPatchIds", static_cast<int>(max_segment + 1)); //for join_and_split plugin
}

View File

@ -78,6 +78,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="offset_updateCheckBox">
<property name="text">
<string>Visibility Changes Recenter</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="max_itemsSpinBox">
<property name="sizePolicy">
@ -185,6 +192,75 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Default Sizes</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Points: </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="pointsHorizontalSlider">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>25</number>
</property>
<property name="value">
<number>2</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="normalsHorizontalSlider">
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSlider" name="linesHorizontalSlider">
<property name="value">
<number>2</number>
</property>
<property name="tracking">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Normals:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Lines:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="background_colorPushButton">
<property name="text">

View File

@ -1074,64 +1074,174 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
return true;
}
void Scene::moveRowUp()
{
int selected_id = selectionIndices().first();
Scene_item* selected_item = item(selected_id);
if(!selected_item)
return;
if(index_map.key(selected_id).row() > 0)
//todo : if a group is selected, don't treat it's children.
bool Scene::sort_lists(QVector<QList<int> >&sorted_lists, bool up)
{
QVector<int> group_found;
Q_FOREACH(int i, selectionIndices())
{
if(item(selected_id)->has_group >0)
Scene_item* item = this->item(i);
if(item->has_group == 0)
{
Scene_group_item* group = selected_item->parentGroup();
if(group)
{
int id = group->getChildren().indexOf(item_id(selected_item));
group->moveUp(id);
}
sorted_lists.first().push_back(i);
}
else
{
int group_id = item_id(item->parentGroup());
if(group_found.contains(group_id))
sorted_lists[group_id].push_back(i);
else
{
group_found.push_back(group_id);
if(sorted_lists.size() < group_id+1)
sorted_lists.resize(group_id+1);
sorted_lists[group_id].push_back(i);
}
}
}
//iterate the first list to find the groups that are selected and remove the corresponding
//sub lists.
//todo: do that for each group. (treat subgroups)
for(int i = 0; i< sorted_lists.first().size(); ++i)
{
Scene_group_item* group = qobject_cast<Scene_group_item*>(this->item(sorted_lists.first()[i]));
if(group && ! group->getChildren().isEmpty())
{
sorted_lists[sorted_lists.first()[i]].clear();
}
}
std::sort(sorted_lists.first().begin(), sorted_lists.first().end(),
[this](int a, int b) {
return children.indexOf(a) < children.indexOf(b);
});
if(!sorted_lists.first().isEmpty())
{
if(up && children.indexOf(sorted_lists.first().first()) == 0)
return false;
else if(!up && children.indexOf(sorted_lists.first().last()) == children.size() -1)
return false;
}
for(int i=1; i<sorted_lists.size(); ++i)
{
QList<int>& list = sorted_lists[i];
if(list.isEmpty())
continue;
Scene_group_item* group = qobject_cast<Scene_group_item*>(this->item(i));
if(!group)
continue;
std::sort(list.begin(), list.end(),
[group](int a, int b) {
return group->getChildren().indexOf(a) < group->getChildren().indexOf(b);
});
if(up && group->getChildren().indexOf(list.first()) == 0)
return false;
else if(!up && group->getChildren().indexOf(list.last()) == group->getChildren().size()-1)
return false;
}
return true;
}
void Scene::moveRowUp()
{
QVector<QList<int> >sorted_lists(1);
QList<int> to_select;
//sort lists according to the indices of each item in its container (scene or group)
//if moving one up would put it out of range, then we stop and do nothing.
if(!sort_lists(sorted_lists, true))
return;
for(int i=0; i<sorted_lists.first().size(); ++i)
{
Item_id selected_id = sorted_lists.first()[i];
Scene_item* selected_item = item(selected_id);
if(!selected_item)
return;
if(index_map.key(selected_id).row() > 0)
{
//if not in group
QModelIndex baseId = index_map.key(selected_id);
int newId = children.indexOf(
index_map.value(index(baseId.row()-1, baseId.column(),baseId.parent()))) ;
children.move(children.indexOf(selected_id), newId);
redraw_model();
to_select.append(m_entries.indexOf(selected_item));
}
redraw_model();
setSelectedItem(m_entries.indexOf(selected_item));
}
for(int i=1; i<sorted_lists.size(); ++i)
{
for(int j = 0; j< sorted_lists[i].size(); ++j)
{
Item_id selected_id = sorted_lists[i][j];
Scene_item* selected_item = item(selected_id);
if(!selected_item)
return;
if(index_map.key(selected_id).row() > 0)
{
Scene_group_item* group = selected_item->parentGroup();
if(group)
{
int id = group->getChildren().indexOf(item_id(selected_item));
group->moveUp(id);
redraw_model();
to_select.append(m_entries.indexOf(selected_item));
}
}
}
}
if(!to_select.isEmpty())
selectionChanged(to_select);
}
void Scene::moveRowDown()
{
int selected_id = selectionIndices().first();
Scene_item* selected_item = item(selected_id);
if(!selected_item)
QVector<QList<int> >sorted_lists(1);
QList<int> to_select;
//sort lists according to the indices of each item in its container (scene or group)
//if moving one up would put it out of range, then we stop and do nothing.
if(!sort_lists(sorted_lists, false))
return;
if(index_map.key(selected_id).row() < rowCount(index_map.key(selected_id).parent())-1)
for(int i=sorted_lists.first().size()-1; i>=0; --i)
{
if(item(selected_id)->has_group >0)
Item_id selected_id = sorted_lists.first()[i];
Scene_item* selected_item = item(selected_id);
if(!selected_item)
return;
if(index_map.key(selected_id).row() < rowCount(index_map.key(selected_id).parent())-1)
{
Scene_group_item* group = selected_item->parentGroup();
if(group)
//if not in group
QModelIndex baseId = index_map.key(selected_id);
int newId = children.indexOf(
index_map.value(index(baseId.row()+1, baseId.column(),baseId.parent()))) ;
children.move(children.indexOf(selected_id), newId);
redraw_model();
to_select.prepend(m_entries.indexOf(selected_item));
}
}
for(int i=1; i<sorted_lists.size(); ++i){
if(sorted_lists[i].isEmpty())
continue;
for(int j = sorted_lists[i].size()-1; j >=0; --j)
{
Item_id selected_id = sorted_lists[i][j];
Scene_item* selected_item = item(selected_id);
if(!selected_item)
return;
if(index_map.key(selected_id).row() < rowCount(index_map.key(selected_id).parent())-1)
{
int id = group->getChildren().indexOf(item_id(selected_item));
group->moveDown(id);
if(item(selected_id)->has_group >0)
{
Scene_group_item* group = selected_item->parentGroup();
if(group)
{
int id = group->getChildren().indexOf(item_id(selected_item));
group->moveDown(id);
}
}
redraw_model();
to_select.prepend(m_entries.indexOf(selected_item));
}
}
else
{
//if not in group
QModelIndex baseId = index_map.key(selected_id);
int newId = children.indexOf(
index_map.value(index(baseId.row()+1, baseId.column(),baseId.parent()))) ;
children.move(children.indexOf(selected_id), newId);
}
redraw_model();
setSelectedItem(m_entries.indexOf(selected_item));
}
selectionChanged(to_select);
}
Scene::Item_id Scene::mainSelectionIndex() const {
return (selectionIndices().size() == 1) ? selected_item : -1;
@ -1155,6 +1265,15 @@ QItemSelection Scene::createSelection(int i)
index_map.keys(i).at(4));
}
QItemSelection Scene::createSelection(QList<int> is)
{
QItemSelection sel;
Q_FOREACH(int i, is)
sel.select(index_map.keys(i).at(0),
index_map.keys(i).at(4));
return sel;
}
QItemSelection Scene::createSelectionAll()
{
//it is not possible to directly create a selection with items that have different parents, so
@ -1201,7 +1320,8 @@ void Scene::itemVisibilityChanged(CGAL::Three::Scene_item* item)
&& !item->isEmpty())
{
//does not recenter
Q_EMIT updated_bbox(false);
if(visibility_recentering_enabled)
Q_EMIT updated_bbox(false);
}
}
@ -1662,3 +1782,8 @@ void Scene::adjustIds(Item_id removed_id)
m_entries[i]->setId(i-1);//the signal is emitted before m_entries is amputed from the item, so new id is current id -1.
}
}
void Scene::enableVisibilityRecentering(bool b)
{
visibility_recentering_enabled = b;
}

View File

@ -12,6 +12,7 @@
#include <QString>
#include <QColor>
#include <QList>
#include <QVector>
#include <QMap>
#include <QItemDelegate>
#include <QPixmap>
@ -128,6 +129,8 @@ public:
// auxiliary public function for QMainWindow
//Selects the row at index i in the sceneView.
QItemSelection createSelection(int i);
//same fo lists
QItemSelection createSelection(QList<int> is);
//Selects all the rows in the sceneView.
QItemSelection createSelectionAll();
//Connects specific signals to a group when it is added and
@ -208,6 +211,7 @@ public Q_SLOTS:
void setItemA(int i);
//!Sets the item_B as the item at index i .
void setItemB(int i);
void enableVisibilityRecentering(bool);
Q_SIGNALS:
//generated automatically by moc
@ -228,6 +232,8 @@ Q_SIGNALS:
void selectionRay(double, double, double, double, double, double);
//! Used to update the selected item in the Geometric Objects view.
void selectionChanged(int i);
//! Used to update the selected items in the Geometric Objects view.
void selectionChanged(QList<int> is);
//! Used when you don't want to update the selectedItem in the Geometric Objects view.
void itemIndexSelected(int i);
//! Emit this to reset the collapsed state of all groups after the Geometric Objects view has been redrawn.
@ -280,7 +286,8 @@ private:
QOpenGLShaderProgram program;
QOpenGLVertexArrayObject* vao;
mutable QOpenGLBuffer vbo[2];
bool visibility_recentering_enabled;
bool sort_lists(QVector<QList<int> >&sorted_lists, bool up);
}; // end class Scene
class QAbstractProxyModel;

View File

@ -1881,6 +1881,8 @@ void Scene_c3t3_item::copyProperties(Scene_item *item)
show_cnc(c3t3_item->has_cnc());
show_grid(c3t3_item->has_grid());
int value = c3t3_item->alphaSlider()->value();
alphaSlider()->setValue(value);
}
bool Scene_c3t3_item::is_valid() const

View File

@ -47,10 +47,10 @@ struct Scene_points_with_normal_item_priv
nb_lines = 0;
is_point_slider_moving = false;
normal_Slider = new QSlider(Qt::Horizontal);
normal_Slider->setValue(20);
normal_Slider->setValue(CGAL::Three::Three::getDefaultNormalLength());
point_Slider = new QSlider(Qt::Horizontal);
point_Slider->setMinimum(1);
point_Slider->setValue(2);
point_Slider->setValue(CGAL::Three::Three::getDefaultPointSize());
point_Slider->setMaximum(25);
}
Scene_points_with_normal_item_priv(Scene_points_with_normal_item* parent)
@ -223,11 +223,6 @@ Scene_points_with_normal_item::Scene_points_with_normal_item(const Scene_points_
setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode());
is_selected = true;
}
if(d->m_points->number_of_points() < 30 )
d->point_Slider->setValue(5);
else
d->point_Slider->setValue(2);
invalidateOpenGLBuffers();
}
@ -241,10 +236,6 @@ Scene_points_with_normal_item::Scene_points_with_normal_item(const SMesh& input_
d = new Scene_points_with_normal_item_priv(input_mesh, this);
setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode());
is_selected = true;
if(d->m_points->number_of_points() < 30 )
d->point_Slider->setValue(5);
else
d->point_Slider->setValue(2);
invalidateOpenGLBuffers();
}
@ -622,10 +613,7 @@ bool Scene_points_with_normal_item::read_ply_point_set(std::istream& stream)
bool ok = stream &&
CGAL::read_ply_point_set (stream, *(d->m_points), &(d->m_comments)) &&
!isEmpty();
if(d->m_points->number_of_points() < 30 )
d->point_Slider->setValue(5);
else
d->point_Slider->setValue(2);
d->point_Slider->setValue(CGAL::Three::Three::getDefaultPointSize());
std::cerr << d->m_points->info();
if (!d->m_points->has_normal_map())
@ -673,10 +661,7 @@ bool Scene_points_with_normal_item::read_off_point_set(std::istream& stream)
bool ok = stream &&
CGAL::read_off_point_set(stream, *(d->m_points)) &&
!isEmpty();
if(d->m_points->number_of_points() < 30 )
d->point_Slider->setValue(5);
else
d->point_Slider->setValue(2);
d->point_Slider->setValue(CGAL::Three::Three::getDefaultPointSize());
invalidateOpenGLBuffers();
return ok;
}
@ -702,10 +687,7 @@ bool Scene_points_with_normal_item::read_xyz_point_set(std::istream& stream)
bool ok = stream &&
CGAL::read_xyz_point_set (stream, *(d->m_points)) &&
!isEmpty();
if(d->m_points->number_of_points() < 30 )
d->point_Slider->setValue(5);
else
d->point_Slider->setValue(2);
d->point_Slider->setValue(CGAL::Three::Three::getDefaultPointSize());
invalidateOpenGLBuffers();
return ok;
}
@ -931,7 +913,7 @@ QMenu* Scene_points_with_normal_item::contextMenu()
connect(d->normal_Slider, &QSlider::sliderReleased, this, &Scene_points_with_normal_item::itemChanged);
}
sliderAction->setDefaultWidget(d->normal_Slider);
container->menuAction()->setProperty("is_groupable", true);
container->addAction(sliderAction);
menu->addMenu(container);
}
@ -942,7 +924,7 @@ QMenu* Scene_points_with_normal_item::contextMenu()
connect(d->point_Slider, &QSlider::valueChanged, this, &Scene_points_with_normal_item::itemChanged);
sliderAction->setDefaultWidget(d->point_Slider);
container->menuAction()->setProperty("is_groupable", true);
container->addAction(sliderAction);
menu->addMenu(container);

View File

@ -793,6 +793,7 @@ public:
void setItemIsMulticolor(bool b) {
poly_item->setItemIsMulticolor(b);
poly_item->computeItemColorVectorAutomatically(b);
}
void selection_changed(bool b);

View File

@ -2,6 +2,7 @@
#include "Scene_spheres_item.h"
#include <CGAL/bounding_box.h>
#include <CGAL/Three/Three.h>
#include <QMenu>
#include <QSlider>
#include <QWidgetAction>
@ -18,9 +19,9 @@ struct Scene_polylines_item_private {
spheres_drawn_square_radius(0)
{
line_Slider = new QSlider(Qt::Horizontal);
line_Slider->setMaximum(2);
line_Slider->setValue(CGAL::Three::Three::getDefaultLinesWidth());
line_Slider->setMaximum(2000);
line_Slider->setMinimum(1);
line_Slider->setValue(2);
item = parent;
invalidate_stats();
}

View File

@ -287,9 +287,9 @@ void Scene_surface_mesh_item::standard_constructor(SMesh* sm)
d->textVItems = new TextListItem(this);
d->textEItems = new TextListItem(this);
d->textFItems = new TextListItem(this);
are_buffers_filled = false;
invalidate(ALL);
}
Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh* sm)
{
@ -674,10 +674,12 @@ void Scene_surface_mesh_item_priv::initialize_colors() const
max = (std::max)(max, fpatch_id_map[fd]);
min_patch_id = (std::min)(min_patch_id, fpatch_id_map[fd]);
}
colors_.clear();
compute_color_map(item->color(), (std::max)(1, max + 1 - min_patch_id),
std::back_inserter(colors_));
if(item->property("recompute_colors").toBool())
{
colors_.clear();
compute_color_map(item->color(), (std::max)(1, max + 1 - min_patch_id),
std::back_inserter(colors_));
}
}
void Scene_surface_mesh_item_priv::initializeBuffers(CGAL::Three::Viewer_interface* viewer)const
@ -1072,7 +1074,7 @@ void* Scene_surface_mesh_item_priv::get_aabb_tree()
BOOST_FOREACH( face_descriptor f, faces(*sm))
{
//if face is degenerate, skip it
if (CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(f, *sm))
if (CGAL::is_triangle(halfedge(f, *sm), *sm) && CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(f, *sm))
continue;
//if face not triangle, triangulate corresponding primitive before adding it to the tree
if(!CGAL::is_triangle(halfedge(f, *sm), *sm))
@ -2207,3 +2209,17 @@ void Scene_surface_mesh_item::computeElements()const
d->compute_elements(ALL);
setBuffersFilled(true);
}
void Scene_surface_mesh_item::copyProperties(Scene_item *item)
{
Scene_surface_mesh_item* sm_item = qobject_cast<Scene_surface_mesh_item*>(item);
if(!sm_item)
return;
int value = sm_item->alphaSlider()->value();
alphaSlider()->setValue(value);
}
void Scene_surface_mesh_item::computeItemColorVectorAutomatically(bool b)
{
this->setProperty("recompute_colors",b);
}

View File

@ -8,6 +8,7 @@
#include "Scene_surface_mesh_item_config.h"
#include <CGAL/Three/Scene_zoomable_item_interface.h>
#include <CGAL/Three/Scene_print_item_interface.h>
#include <CGAL/Three/Scene_item_with_properties.h>
#ifndef Q_MOC_RUN
#include "SMesh_type.h"
@ -32,6 +33,7 @@ class QSlider;
struct Scene_surface_mesh_item_priv;
class SCENE_SURFACE_MESH_ITEM_EXPORT Scene_surface_mesh_item
: public CGAL::Three::Scene_item_rendering_helper,
public CGAL::Three::Scene_item_with_properties,
public CGAL::Three::Scene_zoomable_item_interface,
public CGAL::Three::Scene_print_item_interface{
Q_INTERFACES(CGAL::Three::Scene_print_item_interface)
@ -62,10 +64,18 @@ public:
bool isEmpty() const Q_DECL_OVERRIDE;
Bbox bbox() const Q_DECL_OVERRIDE;
QString toolTip() const Q_DECL_OVERRIDE;
void copyProperties(Scene_item *) Q_DECL_OVERRIDE;
QMenu* contextMenu() Q_DECL_OVERRIDE;
void setItemIsMulticolor(bool);
//to be called before invalidate() to enable or disable the recomputation
//of the colors_ vector to scale on min_patch value.
// For example, the Mesh_segmentation_plugin computes the colors_
// vector itself, so it must set recompute_colors to false to avoid
// having it ovewritten
// in the code of this item.
void computeItemColorVectorAutomatically(bool);
bool isItemMulticolor();
bool hasPatchIds();
Vertex_selection_map vertex_selection_map();

View File

@ -11,6 +11,9 @@ QObject* Three::s_connectable_scene = NULL;
Three* Three::s_three = NULL;
RenderingMode Three::s_defaultSMRM;
RenderingMode Three::s_defaultPSRM;
int Three::default_point_size;
int Three::default_normal_length;
int Three::default_lines_width;
QMainWindow* Three::mainWindow()
{
@ -184,3 +187,17 @@ RenderingMode Three::modeFromName(QString name) {
return Points;
}
int Three::getDefaultPointSize()
{
return default_point_size;
}
int Three::getDefaultNormalLength()
{
return default_normal_length;
}
int Three::getDefaultLinesWidth()
{
return default_lines_width;
}

View File

@ -611,12 +611,6 @@ void Viewer::keyPressEvent(QKeyEvent* e)
update();
return;
}
else if(e->key() == Qt::Key_C) {
QVector4D box[6];
for(int i=0; i<6; ++i)
box[i] = QVector4D(1,0,0,0);
enableClippingBox(box);
}
}
else if(e->key() == Qt::Key_I && e->modifiers() & Qt::ControlModifier){
d->scene->printAllIds(this);

View File

@ -52,6 +52,9 @@ public:
static RenderingMode defaultPointSetRenderingMode();
static QString modeName(RenderingMode mode);
static RenderingMode modeFromName(QString name);
static int getDefaultPointSize();
static int getDefaultNormalLength();
static int getDefaultLinesWidth();
/*! \brief Adds a dock widget to the interface
*
* Adds a dock widget in the left section of the MainWindow. If the slot is already
@ -81,6 +84,9 @@ protected:
static Three* s_three;
static RenderingMode s_defaultSMRM;
static RenderingMode s_defaultPSRM;
static int default_point_size;
static int default_normal_length;
static int default_lines_width;
};
}