mirror of https://github.com/CGAL/cgal
Merge pull request #3970 from maxGimeno/Demo-LCC_plugin-GF
3D Demo: Lcc IO plugin
This commit is contained in:
commit
4719bac98e
|
|
@ -5,65 +5,82 @@
|
|||
#include <CGAL/Three/Three.h>
|
||||
#include <CGAL/Buffer_for_vao.h>
|
||||
|
||||
#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;
|
||||
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;
|
||||
|
||||
struct Facet{
|
||||
Facet():normal(Scene_lcc_item::LCC::Vector(0,0,0)){}
|
||||
Dart_const_handle f_handle;
|
||||
std::vector<Point> 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<float> faces;
|
||||
std::vector<float> lines;
|
||||
std::vector<float> vertices;
|
||||
std::vector<float> colors;
|
||||
|
||||
std::vector<Facet> facets;
|
||||
std::size_t nb_volumes;
|
||||
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)
|
||||
bool compute_face(Dart_const_handle dh, Facet& f)
|
||||
{
|
||||
f.f_handle = dh;
|
||||
const CGAL::qglviewer::Vec offset = static_cast<CGAL::Three::Viewer_interface*>(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<min) min=cur;
|
||||
cur=lcc.next(cur);
|
||||
}
|
||||
while(cur!=dh);
|
||||
|
||||
cur=dh;
|
||||
std::vector<Point> 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);
|
||||
|
|
@ -71,43 +88,43 @@ struct lcc_priv{
|
|||
faces.push_back(pt->z() + offset.z);
|
||||
}
|
||||
}
|
||||
else if (CGAL::Buffer_for_vao<float, std::size_t>::is_facet_convex(pts_in_face,normal))
|
||||
else if (CGAL::Buffer_for_vao<float, std::size_t>::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<pts_in_face.size()-1; ++i)
|
||||
for(std::size_t i=1; i<f.size()-1; ++i)
|
||||
{
|
||||
Point& p0 = pts_in_face[0];
|
||||
Point& p1 = pts_in_face[i];
|
||||
Point& p2 = pts_in_face[i+1];
|
||||
Point& p0 = f.points[0];
|
||||
Point& p1 = f.points[i];
|
||||
Point& p2 = f.points[i+1];
|
||||
|
||||
// (1) add points
|
||||
faces.push_back(p0.x() + offset.x);
|
||||
|
|
@ -145,16 +162,16 @@ struct lcc_priv{
|
|||
typedef CGAL::Exact_predicates_tag Itag;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits, TDS, Itag> 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; i<pts_in_face.size(); ++i)
|
||||
for (unsigned int i=0; i<f.size(); ++i)
|
||||
{
|
||||
typename CDT::Vertex_handle vh = cdt.insert(pts_in_face[i]);
|
||||
typename CDT::Vertex_handle vh = cdt.insert(f.points[i]);
|
||||
if(first==NULL)
|
||||
{ first=vh; }
|
||||
vh->info().v=normal;
|
||||
vh->info().v=f.normal;
|
||||
|
||||
if(previous!=NULL && previous!=vh)
|
||||
{ cdt.insert_constraint(previous, vh); }
|
||||
|
|
@ -238,9 +255,8 @@ struct lcc_priv{
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Scene_lcc_item::Scene_lcc_item(const LCC& lcc)
|
||||
|
|
@ -249,6 +265,7 @@ 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));
|
||||
|
|
@ -309,9 +326,9 @@ void Scene_lcc_item::draw(CGAL::Three::Viewer_interface* viewer) const
|
|||
computeElements();
|
||||
initializeBuffers(viewer);
|
||||
}
|
||||
|
||||
if(d->is_mono_color)
|
||||
getTriangleContainer(0)->setColor(this->color());
|
||||
getTriangleContainer(0)->draw(viewer, true);
|
||||
getTriangleContainer(0)->draw(viewer, d->is_mono_color);
|
||||
}
|
||||
|
||||
void Scene_lcc_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const
|
||||
|
|
@ -378,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 )
|
||||
{
|
||||
|
|
@ -397,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();
|
||||
|
|
@ -436,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 )
|
||||
{
|
||||
|
|
@ -457,6 +479,13 @@ void Scene_lcc_item::computeElements() const
|
|||
getTriangleContainer(0)->allocate(
|
||||
Tri::Flat_vertices, d->faces.data(),
|
||||
static_cast<int>(d->faces.size()*sizeof(float)));
|
||||
if(!d->is_mono_color)
|
||||
{
|
||||
getTriangleContainer(0)->allocate(Tri::FColors, d->colors.data(),
|
||||
static_cast<int>(d->colors.size()*sizeof(float)));
|
||||
}
|
||||
else
|
||||
getTriangleContainer(0)->allocate(Tri::FColors, 0, 0);
|
||||
|
||||
getEdgeContainer(0)->allocate(
|
||||
Ec::Vertices, d->lines.data(),
|
||||
|
|
@ -501,3 +530,86 @@ bool Scene_lcc_item::isEmpty() const
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Scene_lcc_item::randomFaceColors()
|
||||
{
|
||||
d->is_mono_color = false;
|
||||
d->colors.resize(d->nb_faces);
|
||||
for(std::size_t 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()
|
||||
{
|
||||
d->is_mono_color = false;
|
||||
d->colors.resize(d->nb_faces);
|
||||
std::vector<QColor> colors(d->nb_volumes);
|
||||
for(std::size_t i = 0; i<d->nb_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.";
|
||||
|
||||
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->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<QAction*>("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);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <CGAL/Three/Scene_item_rendering_helper.h>
|
||||
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#ifdef scene_lcc_item_EXPORTS
|
||||
# define SCENE_LCC_ITEM_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
|
|
@ -41,9 +43,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();
|
||||
void randomVolumeColors();
|
||||
void resetColors();
|
||||
private:
|
||||
friend struct lcc_priv;
|
||||
lcc_priv* d;
|
||||
|
|
|
|||
Loading…
Reference in New Issue