Done Polygon_soup_item

This commit is contained in:
Maxime Gimeno 2018-09-20 16:59:27 +02:00
parent 665c25886a
commit 99fbc5587f
3 changed files with 186 additions and 206 deletions

View File

@ -4,6 +4,9 @@
#include "Scene_polygon_soup_item.h" #include "Scene_polygon_soup_item.h"
#include "Scene_surface_mesh_item.h" #include "Scene_surface_mesh_item.h"
#include <CGAL/Three/Viewer_interface.h> #include <CGAL/Three/Viewer_interface.h>
#include <CGAL/Three/Triangle_container.h>
#include <CGAL/Three/Edge_container.h>
#include <CGAL/Three/Point_container.h>
#include <QObject> #include <QObject>
#include <QApplication> #include <QApplication>
@ -28,6 +31,11 @@
#include <CGAL/array.h> #include <CGAL/array.h>
#include <map> #include <map>
using namespace CGAL::Three;
typedef Viewer_interface Vi;
typedef Triangle_container Tc;
typedef Edge_container Ec;
typedef Point_container Pc;
struct Scene_polygon_soup_item_priv{ struct Scene_polygon_soup_item_priv{
typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; typedef Polygon_soup::Polygons::const_iterator Polygons_iterator;
@ -50,28 +58,20 @@ struct Scene_polygon_soup_item_priv{
soup = NULL; soup = NULL;
} }
} }
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
void compute_normals_and_vertices(void) const; void compute_normals_and_vertices(void) const;
void triangulate_polygon(Polygons_iterator, int ) const; void triangulate_polygon(Polygons_iterator, int ) const;
mutable QOpenGLShaderProgram *program; mutable QOpenGLShaderProgram *program;
enum VAOs { enum Face_names {
Flat_Facets=0, Flat_facets=0,
Smooth_Facets, Smooth_facets,
Edges,
NM_Edges,
NbOfVaos
}; };
enum VBOs { enum Edge_names {
Facets_vertices = 0, Edges = 0,
Facets_normals, NM_edges
Edges_vertices,
NM_Edges_vertices,
F_Colors,
V_Colors,
NbOfVbos
}; };
Polygon_soup* soup; Polygon_soup* soup;
bool oriented; bool oriented;
mutable std::vector<float> positions_poly; mutable std::vector<float> positions_poly;
@ -87,114 +87,8 @@ struct Scene_polygon_soup_item_priv{
}; };
typedef Scene_polygon_soup_item_priv Priv;
void
Scene_polygon_soup_item_priv::initializeBuffers(CGAL::Three::Viewer_interface* viewer) const
{
//vao containing the data for the facets
{
program = item->getShaderProgram(Scene_polygon_soup_item::PROGRAM_WITH_LIGHT, viewer);
program->bind();
item->vaos[Flat_Facets]->bind();
item->buffers[Facets_vertices].bind();
item->buffers[Facets_vertices].allocate(positions_poly.data(),
static_cast<int>(positions_poly.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,4);
item->buffers[Facets_vertices].release();
item->buffers[Facets_normals].bind();
item->buffers[Facets_normals].allocate(normals.data(),
static_cast<int>(normals.size()*sizeof(float)));
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals",GL_FLOAT,0,3);
item->buffers[Facets_normals].release();
if(!f_colors.empty())
{
item->buffers[F_Colors].bind();
item->buffers[F_Colors].allocate(f_colors.data(),
static_cast<int>(f_colors.size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors",GL_FLOAT,0,3);
item->buffers[F_Colors].release();
}
item->vaos[Flat_Facets]->release();
item->vaos[Smooth_Facets]->bind();
item->buffers[Facets_vertices].bind();
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,4);
item->buffers[Facets_vertices].release();
item->buffers[Facets_normals].release();
item->buffers[Facets_normals].bind();
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals",GL_FLOAT,0,3);
item->buffers[Facets_normals].release();
if(!v_colors.empty())
{
item->buffers[V_Colors].bind();
item->buffers[V_Colors].allocate(v_colors.data(),
static_cast<int>(v_colors.size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors",GL_FLOAT,0,3);
item->buffers[V_Colors].release();
}
item->vaos[Smooth_Facets]->release();
program->release();
nb_polys = positions_poly.size();
positions_poly.resize(0);
std::vector<float>(positions_poly).swap(positions_poly);
normals.resize(0);
std::vector<float>(normals).swap(normals);
v_colors.resize(0);
std::vector<float>(v_colors).swap(v_colors);
}
//vao containing the data for the edges
{
program = item->getShaderProgram(Scene_polygon_soup_item::PROGRAM_WITHOUT_LIGHT, viewer);
program->bind();
item->vaos[Edges]->bind();
item->buffers[Edges_vertices].bind();
item->buffers[Edges_vertices].allocate(positions_lines.data(),
static_cast<int>(positions_lines.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,4);
item->buffers[Edges_vertices].release();
program->release();
item->vaos[Edges]->release();
nb_lines = positions_lines.size();
positions_lines.resize(0);
std::vector<float>(positions_lines).swap(positions_lines);
}
//vao containing the data for the non manifold edges
{
program = item->getShaderProgram(Scene_polygon_soup_item::PROGRAM_WITHOUT_LIGHT, viewer);
program->bind();
item->vaos[NM_Edges]->bind();
item->buffers[NM_Edges_vertices].bind();
item->buffers[NM_Edges_vertices].allocate(positions_nm_lines.data(),
static_cast<int>(positions_nm_lines.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,4);
item->buffers[NM_Edges_vertices].release();
item->vaos[NM_Edges]->release();
nb_nm_edges = positions_nm_lines.size();
positions_nm_lines.resize(0);
std::vector<float> (positions_nm_lines).swap(positions_nm_lines);
}
item->are_buffers_filled = true;
}
typedef EPICK Traits; typedef EPICK Traits;
typedef Polygon_soup::Polygon_3 Facet; typedef Polygon_soup::Polygon_3 Facet;
@ -270,18 +164,15 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol
positions_poly.push_back(ffit->vertex(0)->point().x()); positions_poly.push_back(ffit->vertex(0)->point().x());
positions_poly.push_back(ffit->vertex(0)->point().y()); positions_poly.push_back(ffit->vertex(0)->point().y());
positions_poly.push_back(ffit->vertex(0)->point().z()); positions_poly.push_back(ffit->vertex(0)->point().z());
positions_poly.push_back(1.0);
positions_poly.push_back(ffit->vertex(1)->point().x()); positions_poly.push_back(ffit->vertex(1)->point().x());
positions_poly.push_back(ffit->vertex(1)->point().y()); positions_poly.push_back(ffit->vertex(1)->point().y());
positions_poly.push_back(ffit->vertex(1)->point().z()); positions_poly.push_back(ffit->vertex(1)->point().z());
positions_poly.push_back(1.0);
positions_poly.push_back(ffit->vertex(2)->point().x()); positions_poly.push_back(ffit->vertex(2)->point().x());
positions_poly.push_back(ffit->vertex(2)->point().y()); positions_poly.push_back(ffit->vertex(2)->point().y());
positions_poly.push_back(ffit->vertex(2)->point().z()); positions_poly.push_back(ffit->vertex(2)->point().z());
positions_poly.push_back(1.0);
const Point_3& pa = soup->points[pit->at(0)]; const Point_3& pa = soup->points[pit->at(0)];
@ -317,7 +208,6 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol
void void
Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{ Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{
QApplication::setOverrideCursor(Qt::WaitCursor);
//get the vertices and normals //get the vertices and normals
const CGAL::qglviewer::Vec offset = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset(); const CGAL::qglviewer::Vec offset = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
@ -365,7 +255,6 @@ Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{
positions_poly.push_back(p.x()+offset.x); positions_poly.push_back(p.x()+offset.x);
positions_poly.push_back(p.y()+offset.y); positions_poly.push_back(p.y()+offset.y);
positions_poly.push_back(p.z()+offset.z); positions_poly.push_back(p.z()+offset.z);
positions_poly.push_back(1.0);
if(!soup->fcolors.empty()) if(!soup->fcolors.empty())
{ {
const CGAL::Color color = soup->fcolors[nb]; const CGAL::Color color = soup->fcolors[nb];
@ -394,12 +283,10 @@ Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{
positions_lines.push_back(pa.x()+offset.x); positions_lines.push_back(pa.x()+offset.x);
positions_lines.push_back(pa.y()+offset.y); positions_lines.push_back(pa.y()+offset.y);
positions_lines.push_back(pa.z()+offset.z); positions_lines.push_back(pa.z()+offset.z);
positions_lines.push_back(1.0);
positions_lines.push_back(pb.x()+offset.x); positions_lines.push_back(pb.x()+offset.x);
positions_lines.push_back(pb.y()+offset.y); positions_lines.push_back(pb.y()+offset.y);
positions_lines.push_back(pb.z()+offset.z); positions_lines.push_back(pb.z()+offset.z);
positions_lines.push_back(1.0);
} }
} }
@ -413,21 +300,27 @@ Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{
positions_nm_lines.push_back(a.x()+offset.x); positions_nm_lines.push_back(a.x()+offset.x);
positions_nm_lines.push_back(a.y()+offset.y); positions_nm_lines.push_back(a.y()+offset.y);
positions_nm_lines.push_back(a.z()+offset.z); positions_nm_lines.push_back(a.z()+offset.z);
positions_nm_lines.push_back(1.0);
positions_nm_lines.push_back(b.x()+offset.x); positions_nm_lines.push_back(b.x()+offset.x);
positions_nm_lines.push_back(b.y()+offset.y); positions_nm_lines.push_back(b.y()+offset.y);
positions_nm_lines.push_back(b.z()+offset.z); positions_nm_lines.push_back(b.z()+offset.z);
positions_nm_lines.push_back(1.0);
} }
QApplication::restoreOverrideCursor();
} }
Scene_polygon_soup_item::Scene_polygon_soup_item() Scene_polygon_soup_item::Scene_polygon_soup_item()
: Scene_item(Scene_polygon_soup_item_priv::NbOfVbos,Scene_polygon_soup_item_priv::NbOfVaos)
{ {
d = new Scene_polygon_soup_item_priv(this); d = new Scene_polygon_soup_item_priv(this);
for(int i = 1; i>=0; --i)
{
setTriangleContainer(i,
new Tc(Vi::PROGRAM_WITH_LIGHT, false));
setEdgeContainer(i,
new Ec(Vi::PROGRAM_NO_SELECTION, false));
}
setPointContainer(0,
new Pc(Vi::PROGRAM_NO_SELECTION, false));
} }
Scene_polygon_soup_item::~Scene_polygon_soup_item() Scene_polygon_soup_item::~Scene_polygon_soup_item()
@ -652,93 +545,81 @@ Scene_polygon_soup_item::toolTip() const
void void
Scene_polygon_soup_item::draw(CGAL::Three::Viewer_interface* viewer) const { Scene_polygon_soup_item::draw(CGAL::Three::Viewer_interface* viewer) const {
if(!are_buffers_filled)
{
d->compute_normals_and_vertices();
d->initializeBuffers(viewer);
}
if(d->soup == 0) return; if(d->soup == 0) return;
attribBuffers(viewer,PROGRAM_WITH_LIGHT); if(!isInit())
d->program = getShaderProgram(PROGRAM_WITH_LIGHT); initGL();
d->program->bind(); if ( getBuffersFilled() &&
! getBuffersInit(viewer))
{
initializeBuffers(viewer);
setBuffersInit(viewer, true);
}
if(!getBuffersFilled())
{
computeElements();
initializeBuffers(viewer);
}
if(renderingMode() == Flat || renderingMode() == FlatPlusEdges) if(renderingMode() == Flat || renderingMode() == FlatPlusEdges)
{ {
vaos[Scene_polygon_soup_item_priv::Flat_Facets]->bind();
if(d->soup->fcolors.empty()) if(d->soup->fcolors.empty())
{ getTriangleContainer(Priv::Flat_facets)->setColor(this->color());
d->program->setAttributeValue("colors", this->color()); getTriangleContainer(Priv::Flat_facets)->draw(viewer, d->soup->fcolors.empty());
}
} }
else if(renderingMode() == Gouraud) else if(renderingMode() == Gouraud)
{ {
vaos[Scene_polygon_soup_item_priv::Smooth_Facets]->bind();
if(d->soup->vcolors.empty()) if(d->soup->vcolors.empty())
d->program->setAttributeValue("colors", this->color()); getTriangleContainer(Priv::Smooth_facets)->setColor(this->color());
getTriangleContainer(Priv::Smooth_facets)->draw(viewer, d->soup->vcolors.empty());
} }
//draw the polygons
// the third argument is the number of vec4 that will be entered
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(d->nb_polys/4));
// Clean-up
d->program->release();
vaos[Scene_polygon_soup_item_priv::Smooth_Facets]->release();
vaos[Scene_polygon_soup_item_priv::Flat_Facets]->release();
} }
void void
Scene_polygon_soup_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const { Scene_polygon_soup_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const {
if(!are_buffers_filled)
{
d->compute_normals_and_vertices();
d->initializeBuffers(viewer);
}
if(d->soup == 0) return; if(d->soup == 0) return;
vaos[Scene_polygon_soup_item_priv::Edges]->bind(); if(!isInit())
attribBuffers(viewer,PROGRAM_WITHOUT_LIGHT); initGL();
d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); if ( getBuffersFilled() &&
d->program->bind(); ! getBuffersInit(viewer))
QColor color = this->color(); {
d->program->setAttributeValue("colors", color); initializeBuffers(viewer);
//draw the points setBuffersInit(viewer, true);
viewer->glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(d->nb_lines/4)); }
// Clean-up if(!getBuffersFilled())
d->program->release(); {
vaos[Scene_polygon_soup_item_priv::Edges]->release(); computeElements();
initializeBuffers(viewer);
}
getPointContainer(0)->setColor(this->color());
getPointContainer(0)->draw(viewer, true);
} }
void void
Scene_polygon_soup_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { Scene_polygon_soup_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const {
if(!are_buffers_filled)
{
d->compute_normals_and_vertices();
d->initializeBuffers(viewer);
}
if(d->soup == 0) return; if(d->soup == 0) return;
vaos[Scene_polygon_soup_item_priv::Edges]->bind(); if(!isInit())
attribBuffers(viewer,PROGRAM_WITHOUT_LIGHT); initGL();
d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); if ( getBuffersFilled() &&
d->program->bind(); ! getBuffersInit(viewer))
d->program->setAttributeValue("colors", QColor(Qt::black)); {
//draw the edges initializeBuffers(viewer);
viewer->glDrawArrays(GL_LINES, 0,static_cast<GLsizei>( d->nb_lines/4)); setBuffersInit(viewer, true);
// Clean-up }
d->program->release(); if(!getBuffersFilled())
vaos[Scene_polygon_soup_item_priv::Edges]->release(); {
computeElements();
initializeBuffers(viewer);
}
getEdgeContainer(Priv::Edges)->setColor(QColor(Qt::black));
getEdgeContainer(Priv::Edges)->draw(viewer, true);
if(displayNonManifoldEdges()) if(displayNonManifoldEdges())
{ {
vaos[Scene_polygon_soup_item_priv::NM_Edges]->bind(); getEdgeContainer(Priv::NM_edges)->setColor(QColor(Qt::red));
attribBuffers(viewer,PROGRAM_WITHOUT_LIGHT); //draw the edges
d->program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); getEdgeContainer(Priv::NM_edges)->draw(viewer, true);
d->program->bind();
QColor c = QColor(Qt::red);
d->program->setAttributeValue("colors", c);
//draw the edges
viewer->glDrawArrays(GL_LINES, 0,static_cast<GLsizei>( d->nb_nm_edges/4));
// Clean-up
d->program->release();
vaos[Scene_polygon_soup_item_priv::NM_Edges]->release();
} }
} }
bool bool
@ -749,8 +630,14 @@ Scene_polygon_soup_item::isEmpty() const {
void void
Scene_polygon_soup_item::invalidateOpenGLBuffers() Scene_polygon_soup_item::invalidateOpenGLBuffers()
{ {
are_buffers_filled = false;
compute_bbox(); compute_bbox();
for(int i=0; i<2; ++i)
{
getTriangleContainer(i)->reset_vbos(ALL);
getEdgeContainer(i)->reset_vbos(ALL);
}
getPointContainer(0)->reset_vbos(ALL);
setBuffersFilled(false);
} }
void Scene_polygon_soup_item::compute_bbox() const { void Scene_polygon_soup_item::compute_bbox() const {
@ -764,8 +651,8 @@ void Scene_polygon_soup_item::compute_bbox() const {
++it) { ++it) {
bbox = bbox + it->bbox(); bbox = bbox + it->bbox();
} }
_bbox = Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), setBbox(Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(),
bbox.xmax(),bbox.ymax(),bbox.zmax()); bbox.xmax(),bbox.ymax(),bbox.zmax()));
} }
void void
@ -866,3 +753,96 @@ Scene_polygon_soup_item::non_manifold_edges() const
{ {
return d->soup->non_manifold_edges; return d->soup->non_manifold_edges;
} }
void Scene_polygon_soup_item::initializeBuffers(Viewer_interface *v) const
{
getTriangleContainer(Priv::Flat_facets)->initializeBuffers(v);
getTriangleContainer(Priv::Flat_facets)->setFlatDataSize(d->nb_polys);
getTriangleContainer(Priv::Smooth_facets)->initializeBuffers(v);
getTriangleContainer(Priv::Smooth_facets)->setFlatDataSize(d->nb_polys);
getEdgeContainer(Priv::Edges)->initializeBuffers(v);
getEdgeContainer(Priv::Edges)->setFlatDataSize(d->nb_lines);
getEdgeContainer(Priv::NM_edges)->initializeBuffers(v);
getEdgeContainer(Priv::NM_edges)->setFlatDataSize(d->nb_nm_edges);
getPointContainer(0)->initializeBuffers(v);
getPointContainer(0)->setFlatDataSize(d->nb_lines);
d->normals.resize(0);
d->positions_poly.resize(0);
d->normals.shrink_to_fit();
d->positions_poly.shrink_to_fit();
d->v_colors.resize(0);
d->v_colors.shrink_to_fit();
d->positions_lines.resize(0);
d->positions_lines.shrink_to_fit();
d->positions_nm_lines.resize(0);
d->positions_nm_lines.shrink_to_fit();
}
void Scene_polygon_soup_item::computeElements() const
{
QApplication::setOverrideCursor(Qt::WaitCursor);
d->compute_normals_and_vertices();
getTriangleContainer(Priv::Flat_facets)->allocate(
Tc::Flat_vertices,
d->positions_poly.data(),
static_cast<int>(d->positions_poly.size()*sizeof(float)));
getTriangleContainer(Priv::Flat_facets)->allocate(
Tc::Flat_normals,
d->normals.data(),
static_cast<int>(d->normals.size()*sizeof(float)));
if(!d->f_colors.empty())
{
getTriangleContainer(Priv::Flat_facets)->allocate(
Tc::FColors,
d->f_colors.data(),
static_cast<int>(d->f_colors.size()*sizeof(float)));
}
getTriangleContainer(Priv::Smooth_facets)->allocate(
Tc::Flat_vertices,
d->positions_poly.data(),
static_cast<int>(d->positions_poly.size()*sizeof(float)));
getTriangleContainer(Priv::Smooth_facets)->allocate(
Tc::Flat_normals,
d->normals.data(),
static_cast<int>(d->normals.size()*sizeof(float)));
if(!d->v_colors.empty())
{
getTriangleContainer(Priv::Smooth_facets)->allocate(
Tc::VColors,
d->v_colors.data(),
static_cast<int>(d->v_colors.size()*sizeof(float)));
}
d->nb_polys = d->positions_poly.size();
getEdgeContainer(Priv::Edges)->allocate(
Ec::Vertices,
d->positions_lines.data(),
static_cast<int>(d->positions_lines.size()*sizeof(float)));
getPointContainer(0)->allocate(
Pc::Vertices,
d->positions_lines.data(),
static_cast<int>(d->positions_lines.size()*sizeof(float)));
getEdgeContainer(Priv::NM_edges)->allocate(
Ec::Vertices,
d->positions_nm_lines.data(),
static_cast<int>(d->positions_nm_lines.size()*sizeof(float)));
d->nb_nm_edges = d->positions_nm_lines.size();
d->nb_lines = d->positions_lines.size();
setBuffersFilled(true);
QApplication::restoreOverrideCursor();
}

View File

@ -1,7 +1,7 @@
#ifndef SCENE_POLYGON_SOUP_ITEM_H #ifndef SCENE_POLYGON_SOUP_ITEM_H
#define SCENE_POLYGON_SOUP_ITEM_H #define SCENE_POLYGON_SOUP_ITEM_H
#include "Scene_polygon_soup_item_config.h" #include "Scene_polygon_soup_item_config.h"
#include <CGAL/Three/Scene_item.h> #include <CGAL/Three/Scene_item_rendering_helper.h>
#include "SMesh_type.h" #include "SMesh_type.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@ -99,7 +99,7 @@ struct Polygon_soup
class Scene_surface_mesh_item; class Scene_surface_mesh_item;
class SCENE_POLYGON_SOUP_ITEM_EXPORT Scene_polygon_soup_item class SCENE_POLYGON_SOUP_ITEM_EXPORT Scene_polygon_soup_item
: public CGAL::Three::Scene_item : public CGAL::Three::Scene_item_rendering_helper
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -151,8 +151,8 @@ public:
const Points& points() const; const Points& points() const;
const Polygons& polygons() const; const Polygons& polygons() const;
const Edges& non_manifold_edges() const; const Edges& non_manifold_edges() const;
void newViewer(CGAL::Three::Viewer_interface*)Q_DECL_OVERRIDE{} void initializeBuffers(CGAL::Three::Viewer_interface *) const Q_DECL_OVERRIDE;
void removeViewer(CGAL::Three::Viewer_interface*)Q_DECL_OVERRIDE{} void computeElements() const Q_DECL_OVERRIDE;
public Q_SLOTS: public Q_SLOTS:
void shuffle_orientations(); void shuffle_orientations();
bool orient(); bool orient();

View File

@ -756,7 +756,7 @@ void Scene_surface_mesh_item::drawEdges(CGAL::Three::Viewer_interface *viewer) c
setBuffersInit(viewer, true); setBuffersInit(viewer, true);
} }
getEdgeContainer(0)->setSelected(is_selected); getEdgeContainer(0)->setSelected(is_selected);
getEdgeContainer(0)->setColor(color().lighter(50)); getEdgeContainer(0)->setColor(QColor(Qt::black));
getEdgeContainer(0)->draw( viewer, true); getEdgeContainer(0)->draw( viewer, true);
if(d->has_feature_edges) if(d->has_feature_edges)
{ {