From 4d310309503735a3a7fd0379bbf61eff5e37f6a8 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 22 May 2019 16:22:01 +0200 Subject: [PATCH 1/2] WIP randomColors for lcc --- Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp | 75 +++++++++++++++++-- Polyhedron/demo/Polyhedron/Scene_lcc_item.h | 7 +- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp b/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp index 24d62e25222..2d92e3d8e1e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp @@ -5,7 +5,10 @@ #include #include +#include "Color_map.h" #include "Scene_lcc_item.h" + +//todo : create a struct for facets containing useful infos for drawing and their volume, and fill it during computeElements(). using namespace CGAL::Three; typedef Triangle_container Tri; typedef Edge_container Ec; @@ -21,11 +24,13 @@ struct lcc_priv{ std::vector faces; std::vector lines; std::vector vertices; + std::vector colors; + bool is_mono_color; std::size_t nb_lines, nb_vertices, nb_faces; lcc_priv(const Scene_lcc_item::LCC& lcc) - :lcc(lcc){} + :lcc(lcc), is_mono_color(true){} void compute_face(Dart_const_handle dh) { @@ -240,7 +245,6 @@ struct lcc_priv{ } } - }; Scene_lcc_item::Scene_lcc_item(const LCC& lcc) @@ -309,9 +313,9 @@ void Scene_lcc_item::draw(CGAL::Three::Viewer_interface* viewer) const computeElements(); initializeBuffers(viewer); } - - getTriangleContainer(0)->setColor(this->color()); - getTriangleContainer(0)->draw(viewer, true); + if(d->is_mono_color) + getTriangleContainer(0)->setColor(this->color()); + getTriangleContainer(0)->draw(viewer, d->is_mono_color); } void Scene_lcc_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const @@ -383,7 +387,7 @@ void Scene_lcc_item::computeElements() const typename LCC::size_type markfaces = d->lcc.get_new_mark(); typename LCC::size_type markedges = d->lcc.get_new_mark(); typename LCC::size_type markvertices = d->lcc.get_new_mark(); - + for (typename LCC::Dart_range::const_iterator it=d->lcc.darts().begin(), itend=d->lcc.darts().end(); it!=itend; ++it ) { @@ -397,7 +401,7 @@ void Scene_lcc_item::computeElements() const d->lcc.mark(itv, markvolumes); // To be sure that all darts of the basic iterator will be marked if (!d->lcc.is_marked(itv, markfaces)) { - d->compute_face(itv); + d->compute_face(itv); for (typename LCC::template Dart_of_cell_basic_range<2>:: const_iterator itf=d->lcc.template darts_of_cell_basic<2>(itv, markfaces).begin(), itfend=d->lcc.template darts_of_cell_basic<2>(itv, markfaces).end(); @@ -457,7 +461,14 @@ void Scene_lcc_item::computeElements() const getTriangleContainer(0)->allocate( Tri::Flat_vertices, d->faces.data(), static_cast(d->faces.size()*sizeof(float))); - + if(!d->is_mono_color) + { + getTriangleContainer(0)->allocate(Tri::FColors, d->colors.data(), + static_cast(d->colors.size()*sizeof(float))); + } + else + getTriangleContainer(0)->allocate(Tri::FColors, 0, 0); + getEdgeContainer(0)->allocate( Ec::Vertices, d->lines.data(), static_cast(d->lines.size()*sizeof(float))); @@ -501,3 +512,51 @@ bool Scene_lcc_item::isEmpty() const { return false; } + +void Scene_lcc_item::randomFaceColors(bool b) +{ + d->is_mono_color = !b; + if(b) + { + d->colors.resize(d->nb_faces); + for(int i=0; i< d->colors.size()-3; i+=3) + { + QColor col = generate_random_color(); + d->colors[i] = col.redF(); + d->colors[i+1] = col.greenF(); + d->colors[i+2] = col.blueF(); + } + } + invalidateOpenGLBuffers(); + redraw(); +} + +void Scene_lcc_item::randomVolumeColors() +{ + qDebug()<<"coucou !"; +} + +QMenu* Scene_lcc_item::contextMenu() +{ + const char* prop_name = "Menu modified by Scene_lcc_item."; + + QMenu* menu = Scene_item::contextMenu(); + + // Use dynamic properties: + // https://doc.qt.io/qt-5/qobject.html#property + bool menuChanged = menu->property(prop_name).toBool(); + + if(!menuChanged) { + menu->addSeparator(); + QAction* action = menu->addAction(tr("Set Random Colors for faces.")); + action->setCheckable(true); + action->setObjectName("actionRandomFaceColors"); + connect(action, &QAction::triggered, + this, &Scene_lcc_item::randomFaceColors); + menu->setProperty(prop_name, true); + } + + QAction* action = menu->findChild("actionRandomFaceColors"); + if(action) action->setChecked(!d->is_mono_color); + return menu; +} diff --git a/Polyhedron/demo/Polyhedron/Scene_lcc_item.h b/Polyhedron/demo/Polyhedron/Scene_lcc_item.h index a8ac14feb6b..e177a1ab8e1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_lcc_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_lcc_item.h @@ -4,6 +4,8 @@ #include #include +#include + #ifdef scene_lcc_item_EXPORTS # define SCENE_LCC_ITEM_EXPORT Q_DECL_EXPORT #else @@ -40,10 +42,13 @@ public: void computeElements() const Q_DECL_OVERRIDE; void initializeBuffers(CGAL::Three::Viewer_interface *) const Q_DECL_OVERRIDE; + + QMenu* contextMenu() Q_DECL_OVERRIDE ; public Q_SLOTS: void invalidateOpenGLBuffers() Q_DECL_OVERRIDE; - + void randomFaceColors(bool b); + void randomVolumeColors(); private: friend struct lcc_priv; lcc_priv* d; From 6a3cce1429a122a5e9abde29120b848586cf8465 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 29 May 2019 15:46:12 +0200 Subject: [PATCH 2/2] Add colors per volume. --- Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp | 163 ++++++++++++------ Polyhedron/demo/Polyhedron/Scene_lcc_item.h | 3 +- 2 files changed, 110 insertions(+), 56 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp b/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp index 2d92e3d8e1e..d00de3279f3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_lcc_item.cpp @@ -15,16 +15,30 @@ typedef Edge_container Ec; typedef Point_container Pc; typedef Viewer_interface Vi; +typedef Scene_lcc_item::LCC::Dart_const_handle Dart_const_handle; typedef Scene_lcc_item::LCC::Dart_handle Dart_handle; -typedef Scene_lcc_item::LCC::Point Point; +typedef Scene_lcc_item::LCC::Point Point; + +struct Facet{ + Facet():normal(Scene_lcc_item::LCC::Vector(0,0,0)){} + Dart_const_handle f_handle; + std::vector points; + Scene_lcc_item::LCC::Vector normal; + std::size_t volume_id; + std::size_t size() { return points.size(); } +}; + struct lcc_priv{ - typedef Scene_lcc_item::LCC::Dart_const_handle Dart_const_handle; + Scene_lcc_item::LCC lcc; std::vector faces; std::vector lines; std::vector vertices; std::vector colors; + + std::vector facets; + std::size_t nb_volumes; bool is_mono_color; std::size_t nb_lines, nb_vertices, nb_faces; @@ -32,43 +46,41 @@ struct lcc_priv{ lcc_priv(const Scene_lcc_item::LCC& lcc) :lcc(lcc), is_mono_color(true){} - void compute_face(Dart_const_handle dh) + bool compute_face(Dart_const_handle dh, Facet& f) { + f.f_handle = dh; const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); // We fill only closed faces. Dart_const_handle cur=dh; Dart_const_handle min=dh; do { - if (!lcc.is_next_exist(cur)) return; // open face=>not filled + if (!lcc.is_next_exist(cur)) return false; // open face=>not filled if (cur pts_in_face; do { - pts_in_face.push_back(lcc.point(cur)); + f.points.push_back(lcc.point(cur)); cur=lcc.next(cur); } while(cur!=dh); - Scene_lcc_item::LCC::Vector normal(0,0,0); - - for (std::size_t i = 0; i < pts_in_face.size() ; ++ i){ - const Point& pa = pts_in_face[i]; - const Point& pb = pts_in_face[(i+1)%pts_in_face.size()]; - double x = normal.x() + (pa.y()-pb.y())*(pa.z()+pb.z()); - double y = normal.y() + (pa.z()-pb.z())*(pa.x()+pb.x()); - double z = normal.z() + (pa.x()-pb.x())*(pa.y()+pb.y()); - normal = Scene_lcc_item::LCC::Vector(x,y,z); + for (std::size_t i = 0; i < f.size() ; ++ i){ + const Point& pa = f.points[i]; + const Point& pb = f.points[(i+1)%f.size()]; + double x = f.normal.x() + (pa.y()-pb.y())*(pa.z()+pb.z()); + double y = f.normal.y() + (pa.z()-pb.z())*(pa.x()+pb.x()); + double z = f.normal.z() + (pa.x()-pb.x())*(pa.y()+pb.y()); + f.normal = Scene_lcc_item::LCC::Vector(x,y,z); } - if (pts_in_face.size()==3) + if (f.size()==3) { - for(auto pt = pts_in_face.begin(); - pt != pts_in_face.end(); + for(auto pt = f.points.begin(); + pt != f.points.end(); ++pt) { faces.push_back(pt->x() + offset.x); @@ -76,43 +88,43 @@ struct lcc_priv{ faces.push_back(pt->z() + offset.z); } } - else if (CGAL::Buffer_for_vao::is_facet_convex(pts_in_face,normal)) + else if (CGAL::Buffer_for_vao::is_facet_convex(f.points,f.normal)) { - if (pts_in_face.size()==4) + if (f.size()==4) { - Point p = pts_in_face[0]; + Point p = f.points[0]; faces.push_back(p.x() + offset.x); faces.push_back(p.y() + offset.y); faces.push_back(p.z() + offset.z); - p = pts_in_face[1]; + p = f.points[1]; faces.push_back(p.x() + offset.x); faces.push_back(p.y() + offset.y); faces.push_back(p.z() + offset.z); - p = pts_in_face[2]; + p = f.points[2]; faces.push_back(p.x() + offset.x); faces.push_back(p.y() + offset.y); faces.push_back(p.z() + offset.z); - p = pts_in_face[0]; + p = f.points[0]; faces.push_back(p.x() + offset.x); faces.push_back(p.y() + offset.y); faces.push_back(p.z() + offset.z); - p = pts_in_face[2]; + p = f.points[2]; faces.push_back(p.x() + offset.x); faces.push_back(p.y() + offset.y); faces.push_back(p.z() + offset.z); - p = pts_in_face[3]; + p = f.points[3]; faces.push_back(p.x() + offset.x); faces.push_back(p.y() + offset.y); faces.push_back(p.z() + offset.z); } else { - for(std::size_t i=1; i CDT; - P_traits cdt_traits(normal); + P_traits cdt_traits(f.normal); CDT cdt(cdt_traits); // (1) We insert all the edges as contraint in the CDT. typename CDT::Vertex_handle previous=NULL, first=NULL; - for (unsigned int i=0; iinfo().v=normal; + vh->info().v=f.normal; if(previous!=NULL && previous!=vh) { cdt.insert_constraint(previous, vh); } @@ -243,7 +255,7 @@ struct lcc_priv{ } } } - + return true; } }; @@ -253,11 +265,12 @@ Scene_lcc_item::Scene_lcc_item(const LCC& lcc) d->nb_faces = 0; d->nb_lines = 0; d->nb_vertices = 0; + d->nb_volumes = 0; setTriangleContainer(0, new Tri(Three::mainViewer()->isOpenGL_4_3() ? Vi::PROGRAM_FLAT : Vi::PROGRAM_OLD_FLAT, false)); - setEdgeContainer(0, + setEdgeContainer(0, new Ec(Three::mainViewer()->isOpenGL_4_3() ? Vi::PROGRAM_SOLID_WIREFRAME : Vi::PROGRAM_NO_SELECTION , false)); @@ -382,12 +395,13 @@ void Scene_lcc_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const void Scene_lcc_item::computeElements() const { CGAL::Three::Three::CursorScopeGuard guard{QCursor(Qt::WaitCursor)}; + d->facets.clear(); const CGAL::qglviewer::Vec offset = CGAL::Three::Three::mainViewer()->offset(); typename LCC::size_type markvolumes = d->lcc.get_new_mark(); typename LCC::size_type markfaces = d->lcc.get_new_mark(); typename LCC::size_type markedges = d->lcc.get_new_mark(); typename LCC::size_type markvertices = d->lcc.get_new_mark(); - + std::size_t volume_id = 0; for (typename LCC::Dart_range::const_iterator it=d->lcc.darts().begin(), itend=d->lcc.darts().end(); it!=itend; ++it ) { @@ -401,7 +415,10 @@ void Scene_lcc_item::computeElements() const d->lcc.mark(itv, markvolumes); // To be sure that all darts of the basic iterator will be marked if (!d->lcc.is_marked(itv, markfaces)) { - d->compute_face(itv); + Facet f; + if(d->compute_face(itv, f)) + d->facets.push_back(f); + d->facets.back().volume_id = volume_id; for (typename LCC::template Dart_of_cell_basic_range<2>:: const_iterator itf=d->lcc.template darts_of_cell_basic<2>(itv, markfaces).begin(), itfend=d->lcc.template darts_of_cell_basic<2>(itv, markfaces).end(); @@ -440,9 +457,10 @@ void Scene_lcc_item::computeElements() const } } } + ++volume_id; } } - + d->nb_volumes = volume_id; for (typename LCC::Dart_range::const_iterator it=d->lcc.darts().begin(), itend=d->lcc.darts().end(); it!=itend; ++it ) { @@ -513,29 +531,54 @@ bool Scene_lcc_item::isEmpty() const return false; } -void Scene_lcc_item::randomFaceColors(bool b) +void Scene_lcc_item::randomFaceColors() { - d->is_mono_color = !b; - if(b) + d->is_mono_color = false; + d->colors.resize(d->nb_faces); + for(std::size_t i=0; i< d->colors.size()-3; i+=3) { - d->colors.resize(d->nb_faces); - for(int i=0; i< d->colors.size()-3; i+=3) - { - QColor col = generate_random_color(); - d->colors[i] = col.redF(); - d->colors[i+1] = col.greenF(); - d->colors[i+2] = col.blueF(); - } + QColor col = generate_random_color(); + d->colors[i] = col.redF(); + d->colors[i+1] = col.greenF(); + d->colors[i+2] = col.blueF(); } + invalidateOpenGLBuffers(); redraw(); } void Scene_lcc_item::randomVolumeColors() { - qDebug()<<"coucou !"; + d->is_mono_color = false; + d->colors.resize(d->nb_faces); + std::vector colors(d->nb_volumes); + for(std::size_t i = 0; inb_volumes; ++i) + { + colors[i] = generate_random_color(); + } + std::size_t color_id = 0; + for(auto f : d->facets)//filled in the same order as GL faces + { + QColor col = colors[f.volume_id]; + //3 points per face. + for(std::size_t j = 0; j < 3; ++j) + { + d->colors[color_id+j*3] = col.redF(); + d->colors[color_id+j*3+1] = col.greenF(); + d->colors[color_id+j*3+2] = col.blueF(); + } + color_id += 9; + } + invalidateOpenGLBuffers(); + redraw(); } +void Scene_lcc_item::resetColors() +{ + d->is_mono_color = true; + invalidateOpenGLBuffers(); + redraw(); +} QMenu* Scene_lcc_item::contextMenu() { const char* prop_name = "Menu modified by Scene_lcc_item."; @@ -548,15 +591,25 @@ QMenu* Scene_lcc_item::contextMenu() if(!menuChanged) { menu->addSeparator(); - QAction* action = menu->addAction(tr("Set Random Colors for faces.")); - action->setCheckable(true); + QAction* action = menu->addAction(tr("Set Random Colors for Faces.")); action->setObjectName("actionRandomFaceColors"); connect(action, &QAction::triggered, this, &Scene_lcc_item::randomFaceColors); + action = menu->addAction(tr("Set Random Colors for Volumes.")); + action->setObjectName("actionRandomVolumeColors"); + connect(action, &QAction::triggered, + this, &Scene_lcc_item::randomVolumeColors); menu->setProperty(prop_name, true); } + QAction* action = menu->findChild("actionResetColors"); + if(!action) + { + action = menu->addAction(tr("Reset Colors.")); + action->setObjectName("actionResetColors"); + connect(action, &QAction::triggered, + this, &Scene_lcc_item::resetColors); + } + action->setVisible(!d->is_mono_color); - QAction* action = menu->findChild("actionRandomFaceColors"); - if(action) action->setChecked(!d->is_mono_color); return menu; } diff --git a/Polyhedron/demo/Polyhedron/Scene_lcc_item.h b/Polyhedron/demo/Polyhedron/Scene_lcc_item.h index e177a1ab8e1..94469f23731 100644 --- a/Polyhedron/demo/Polyhedron/Scene_lcc_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_lcc_item.h @@ -47,8 +47,9 @@ public: public Q_SLOTS: void invalidateOpenGLBuffers() Q_DECL_OVERRIDE; - void randomFaceColors(bool b); + void randomFaceColors(); void randomVolumeColors(); + void resetColors(); private: friend struct lcc_priv; lcc_priv* d;