(new_item);
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
- add_group_number(child);
- new_item->has_group++;
+ update_group_number(child,n+1);
+ new_item->has_group = n;
}
void Scene_group_item::setColor(QColor c)
{
diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp
index 166603041d9..7297fdc493c 100644
--- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp
+++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp
@@ -736,13 +736,15 @@ Scene_polyhedron_item::toolTip() const
QObject::tr("Polyhedron %1 (mode: %5, color: %6)
"
"Number of vertices: %2
"
"Number of edges: %3
"
- "Number of facets: %4")
+ "Number of facets: %4
"
+ "has_group = %7")
.arg(this->name())
.arg(poly->size_of_vertices())
.arg(poly->size_of_halfedges()/2)
.arg(poly->size_of_facets())
.arg(this->renderingModeName())
- .arg(this->color().name());
+ .arg(this->color().name())
+ .arg(this->has_group);
str += QString("
Number of isolated vertices : %1
").arg(getNbIsolatedvertices());
return str;
}
diff --git a/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp b/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp
new file mode 100644
index 00000000000..96c1747abb0
--- /dev/null
+++ b/Polyhedron/demo/Polyhedron/Scene_spheres_item.cpp
@@ -0,0 +1,205 @@
+#include "Scene_spheres_item.h"
+
+void Scene_spheres_item::computeElements() const
+{
+ colors.clear();
+ edges_colors.clear();
+ centers.clear();
+ radius.clear();
+ Q_FOREACH(sphere_pair sp, spheres)
+ {
+ colors.push_back((float)sp.second.red()/255);
+ colors.push_back((float)sp.second.green()/255);
+ colors.push_back((float)sp.second.blue()/255);
+
+ edges_colors.push_back((float)sp.second.red()/255);
+ edges_colors.push_back((float)sp.second.green()/255);
+ edges_colors.push_back((float)sp.second.blue()/255);
+
+ centers.push_back(sp.first->center().x());
+ centers.push_back(sp.first->center().y());
+ centers.push_back(sp.first->center().z());
+
+ radius.push_back(sp.first->squared_radius());
+ }
+}
+
+void Scene_spheres_item::initializeBuffers(CGAL::Three::Viewer_interface *viewer) const
+{
+ if(has_plane)
+ {
+ program = getShaderProgram(PROGRAM_CUTPLANE_SPHERES, viewer);
+ attrib_buffers(viewer, PROGRAM_CUTPLANE_SPHERES);
+ }
+ else
+ {
+ program = getShaderProgram(PROGRAM_SPHERES, viewer);
+ attrib_buffers(viewer, PROGRAM_SPHERES);
+ }
+
+ program->bind();
+ vaos[Facets]->bind();
+ buffers[Vertices].bind();
+ buffers[Vertices].allocate(vertices.data(),
+ static_cast(vertices.size()*sizeof(float)));
+ program->enableAttributeArray("vertex");
+ program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
+ buffers[Vertices].release();
+
+ buffers[Normals].bind();
+ buffers[Normals].allocate(normals.data(),
+ static_cast(normals.size()*sizeof(float)));
+ program->enableAttributeArray("normals");
+ program->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
+ buffers[Normals].release();
+
+ buffers[Color].bind();
+ buffers[Color].allocate(colors.data(),
+ static_cast(colors.size()*sizeof(float)));
+ program->enableAttributeArray("colors");
+ program->setAttributeBuffer("colors", GL_FLOAT, 0, 3);
+ buffers[Color].release();
+
+ buffers[Radius].bind();
+ buffers[Radius].allocate(radius.data(),
+ static_cast(radius.size()*sizeof(float)));
+ program->enableAttributeArray("radius");
+ program->setAttributeBuffer("radius", GL_FLOAT, 0, 1);
+ buffers[Radius].release();
+
+ buffers[Center].bind();
+ buffers[Center].allocate(centers.data(),
+ static_cast(centers.size()*sizeof(float)));
+ program->enableAttributeArray("center");
+ program->setAttributeBuffer("center", GL_FLOAT, 0, 3);
+ buffers[Center].release();
+
+ viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
+ viewer->glVertexAttribDivisor(program->attributeLocation("radius"), 1);
+ viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1);
+ vaos[Facets]->release();
+
+
+ vaos[Edges]->bind();
+ buffers[Edge_vertices].bind();
+ buffers[Edge_vertices].allocate(edges.data(),
+ static_cast(edges.size()*sizeof(float)));
+ program->enableAttributeArray("vertex");
+ program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
+ buffers[Edge_vertices].release();
+
+ buffers[Normals].bind();
+ program->enableAttributeArray("normals");
+ program->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
+ buffers[Normals].release();
+
+ buffers[Edge_color].bind();
+ buffers[Edge_color].allocate(edges_colors.data(),
+ static_cast(edges_colors.size()*sizeof(float)));
+ program->enableAttributeArray("colors");
+ program->setAttributeBuffer("colors", GL_FLOAT, 0, 3);
+ buffers[Edge_color].release();
+
+ buffers[Radius].bind();
+ program->enableAttributeArray("radius");
+ program->setAttributeBuffer("radius", GL_FLOAT, 0, 1);
+ buffers[Radius].release();
+
+ buffers[Center].bind();
+ program->enableAttributeArray("center");
+ program->setAttributeBuffer("center", GL_FLOAT, 0, 3);
+ buffers[Center].release();
+
+ viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
+ viewer->glVertexAttribDivisor(program->attributeLocation("radius"), 1);
+ viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1);
+ vaos[Edges]->release();
+
+ program->release();
+
+ nb_centers = centers.size();
+ centers.clear();
+ centers.swap(centers);
+ colors.clear();
+ colors.swap(colors);
+ radius.clear();
+ radius.swap(radius);
+ edges_colors.clear();
+ edges_colors.swap(edges_colors);
+
+ are_buffers_filled = true;
+}
+
+void Scene_spheres_item::draw(Viewer_interface *viewer) const
+{
+ if (!are_buffers_filled)
+ {
+ computeElements();
+ initializeBuffers(viewer);
+ }
+ vaos[Facets]->bind();
+ if(has_plane)
+ {
+ program = getShaderProgram(PROGRAM_CUTPLANE_SPHERES, viewer);
+ attrib_buffers(viewer, PROGRAM_CUTPLANE_SPHERES);
+ program->bind();
+ QVector4D cp(plane.a(),plane.b(),plane.c(),plane.d());
+ program->setUniformValue("cutplane", cp);
+
+ }
+ else
+ {
+ program = getShaderProgram(PROGRAM_SPHERES, viewer);
+ attrib_buffers(viewer, PROGRAM_SPHERES);
+ program->bind();
+ }
+ viewer->glDrawArraysInstanced(GL_TRIANGLES, 0,
+ static_cast(vertices.size()/3),
+ static_cast(nb_centers));
+
+ program->release();
+ vaos[Facets]->release();
+}
+void Scene_spheres_item::draw_edges(Viewer_interface *viewer) const
+{
+ if (!are_buffers_filled)
+ {
+ computeElements();
+ initializeBuffers(viewer);
+ }
+ vaos[Edges]->bind();
+ if(has_plane)
+ {
+ program = getShaderProgram(PROGRAM_CUTPLANE_SPHERES, viewer);
+ attrib_buffers(viewer, PROGRAM_CUTPLANE_SPHERES);
+ program->bind();
+ QVector4D cp(plane.a(),plane.b(),plane.c(),plane.d());
+ program->setUniformValue("cutplane", cp);
+ }
+ else
+ {
+ program = getShaderProgram(PROGRAM_SPHERES, viewer);
+ attrib_buffers(viewer, PROGRAM_SPHERES);
+ program->bind();
+ }
+ viewer->glDrawArraysInstanced(GL_LINES, 0,
+ static_cast(vertices.size()/3),
+ static_cast(nb_centers));
+ program->release();
+ vaos[Edges]->release();
+}
+void Scene_spheres_item::add_sphere(CGAL::Sphere_3 *sphere, CGAL::Color color)
+{
+ sphere_pair pair_(sphere, color);
+ spheres.append(pair_);
+}
+
+void Scene_spheres_item::remove_sphere(CGAL::Sphere_3 *sphere)
+{
+ Q_FOREACH(sphere_pair pair_, spheres)
+ if(pair_.first == sphere)
+ {
+ spheres.removeAll(pair_);
+ break;
+ }
+}
diff --git a/Polyhedron/demo/Polyhedron/Scene_spheres_item.h b/Polyhedron/demo/Polyhedron/Scene_spheres_item.h
new file mode 100644
index 00000000000..e4a2efb88f4
--- /dev/null
+++ b/Polyhedron/demo/Polyhedron/Scene_spheres_item.h
@@ -0,0 +1,96 @@
+#ifndef SCENE_SPHERES_ITEM_H
+#define SCENE_SPHERES_ITEM_H
+#include "Scene_basic_objects_config.h"
+#include "create_sphere.h"
+#include "CGAL/Three/Scene_group_item.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+class SCENE_BASIC_OBJECTS_EXPORT Scene_spheres_item
+ : public CGAL::Three::Scene_item
+{
+ Q_OBJECT
+public:
+ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+ typedef std::pair*, CGAL::Color> sphere_pair ;
+
+ Scene_spheres_item(Scene_group_item* parent, bool planed = false)
+ :CGAL::Three::Scene_item(NbOfVbos,NbOfVaos)
+ ,precision(36)
+ ,has_plane(planed)
+
+ {
+ setParent(parent);
+ create_flat_and_wire_sphere(1.0f,vertices,normals, edges);
+ }
+
+ ~Scene_spheres_item() {
+ Q_FOREACH(sphere_pair sphere, spheres)
+ delete sphere.first;
+ }
+
+ bool isFinite() const { return false; }
+ bool isEmpty() const { return false; }
+ Scene_item* clone() const {return 0;}
+ QString toolTip() const {return QString();}
+ bool supportsRenderingMode(RenderingMode m) const {
+ return (m == Gouraud || m == Wireframe);
+ }
+ void compute_bbox() const { _bbox = Bbox(); }
+ void add_sphere(CGAL::Sphere_3* sphere, CGAL::Color = CGAL::Color(120,120,120));
+ void remove_sphere(CGAL::Sphere_3* sphere);
+ void setPrecision(int prec) { precision = prec; }
+
+ void draw(CGAL::Three::Viewer_interface* viewer) const;
+ void draw_edges(CGAL::Three::Viewer_interface* viewer) const;
+ void invalidateOpenGLBuffers(){are_buffers_filled = false;}
+ void computeElements() const;
+ void setPlane(Kernel::Plane_3 p_plane) { plane = p_plane; }
+
+private:
+ enum Vbos
+ {
+ Vertices = 0,
+ Edge_vertices,
+ Normals,
+ Center,
+ Radius,
+ Color,
+ Edge_color,
+ NbOfVbos
+ };
+ enum Vaos
+ {
+ Facets = 0,
+ Edges,
+ NbOfVaos
+ };
+
+
+ int precision;
+ mutable CGAL::Plane_3 plane;
+ bool has_plane;
+
+ QList spheres;
+ mutable std::vector vertices;
+ mutable std::vector normals;
+ mutable std::vector edges;
+ mutable std::vector colors;
+ mutable std::vector edges_colors;
+ mutable std::vector centers;
+ mutable std::vector radius;
+ mutable QOpenGLShaderProgram *program;
+ mutable int nb_centers;
+ void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const;
+
+};
+
+#endif // SCENE_SPHERES_ITEM_H
diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp
index 2e4c47ce637..96b92cfb79e 100644
--- a/Polyhedron/demo/Polyhedron/Viewer.cpp
+++ b/Polyhedron/demo/Polyhedron/Viewer.cpp
@@ -458,96 +458,47 @@ void Viewer::attrib_buffers(int program_name) const {
QVector4D specular(0.0f, 0.0f, 0.0f, 1.0f);
QOpenGLShaderProgram* program = getShaderProgram(program_name);
program->bind();
+ program->setUniformValue("mvp_matrix", mvp_mat);
switch(program_name)
{
- case PROGRAM_NO_SELECTION:
- program->setUniformValue("mvp_matrix", mvp_mat);
-
- program->setUniformValue("f_matrix",f_mat);
- break;
case PROGRAM_WITH_LIGHT:
- program->setUniformValue("mvp_matrix", mvp_mat);
- program->setUniformValue("mv_matrix", mv_mat);
- program->setUniformValue("light_pos", position);
- program->setUniformValue("light_diff",diffuse);
- program->setUniformValue("light_spec", specular);
- program->setUniformValue("light_amb", ambient);
- program->setUniformValue("spec_power", 51.8f);
- program->setUniformValue("is_two_side", is_both_sides);
- break;
case PROGRAM_C3T3:
- program->setUniformValue("mvp_matrix", mvp_mat);
- program->setUniformValue("mv_matrix", mv_mat);
- program->setUniformValue("light_pos", position);
- program->setUniformValue("light_diff",diffuse);
- program->setUniformValue("light_spec", specular);
- program->setUniformValue("light_amb", ambient);
- program->setUniformValue("spec_power", 51.8f);
- program->setUniformValue("is_two_side", is_both_sides);
- break;
- case PROGRAM_C3T3_EDGES:
- program->setUniformValue("mvp_matrix", mvp_mat);
- break;
- case PROGRAM_WITHOUT_LIGHT:
- program->setUniformValue("mvp_matrix", mvp_mat);
- program->setUniformValue("mv_matrix", mv_mat);
-
- program->setUniformValue("light_pos", position);
- program->setUniformValue("light_diff", diffuse);
- program->setUniformValue("light_spec", specular);
- program->setUniformValue("light_amb", ambient);
- program->setUniformValue("spec_power", 51.8f);
- program->setUniformValue("is_two_side", is_both_sides);
- program->setAttributeValue("normals", 0.0,0.0,0.0);
- program->setUniformValue("f_matrix",f_mat);
-
-
- break;
- case PROGRAM_WITH_TEXTURE:
-
- program->setUniformValue("mvp_matrix", mvp_mat);
- program->setUniformValue("mv_matrix", mv_mat);
- program->setUniformValue("light_pos", position);
- program->setUniformValue("light_diff",diffuse);
- program->setUniformValue("light_spec", specular);
- program->setUniformValue("light_amb", ambient);
- program->setUniformValue("spec_power", 51.8f);
- program->setUniformValue("s_texture",0);
- program->setUniformValue("f_matrix",f_mat);
-
- break;
case PROGRAM_PLANE_TWO_FACES:
- program->setUniformValue("mvp_matrix", mvp_mat);
- program->setUniformValue("mv_matrix", mv_mat);
- program->setUniformValue("light_pos", position);
- program->setUniformValue("light_diff",diffuse);
- program->setUniformValue("light_spec", specular);
- program->setUniformValue("light_amb", ambient);
- program->setUniformValue("spec_power", 51.8f);
- program->setUniformValue("is_two_side", is_both_sides);
- break;
-
- case PROGRAM_WITH_TEXTURED_EDGES:
-
- program->setUniformValue("mvp_matrix", mvp_mat);
- program->setUniformValue("s_texture",0);
-
- break;
case PROGRAM_INSTANCED:
-
- program->setUniformValue("mvp_matrix", mvp_mat);
- program->setUniformValue("mv_matrix", mv_mat);
-
+ case PROGRAM_WITH_TEXTURE:
+ case PROGRAM_CUTPLANE_SPHERES:
+ case PROGRAM_SPHERES:
program->setUniformValue("light_pos", position);
program->setUniformValue("light_diff",diffuse);
program->setUniformValue("light_spec", specular);
program->setUniformValue("light_amb", ambient);
program->setUniformValue("spec_power", 51.8f);
program->setUniformValue("is_two_side", is_both_sides);
-
break;
- case PROGRAM_INSTANCED_WIRE:
- program->setUniformValue("mvp_matrix", mvp_mat);
+ }
+ switch(program_name)
+ {
+ case PROGRAM_WITH_LIGHT:
+ case PROGRAM_C3T3:
+ case PROGRAM_PLANE_TWO_FACES:
+ case PROGRAM_INSTANCED:
+ case PROGRAM_CUTPLANE_SPHERES:
+ case PROGRAM_SPHERES:
+ program->setUniformValue("mv_matrix", mv_mat);
+ break;
+ case PROGRAM_WITHOUT_LIGHT:
+ program->setUniformValue("f_matrix",f_mat);
+ break;
+ case PROGRAM_WITH_TEXTURE:
+ program->setUniformValue("mv_matrix", mv_mat);
+ program->setUniformValue("s_texture",0);
+ program->setUniformValue("f_matrix",f_mat);
+ break;
+ case PROGRAM_WITH_TEXTURED_EDGES:
+ program->setUniformValue("s_texture",0);
+ break;
+ case PROGRAM_NO_SELECTION:
+ program->setUniformValue("f_matrix",f_mat);
break;
}
program->release();
@@ -1110,6 +1061,51 @@ QOpenGLShaderProgram* Viewer::getShaderProgram(int name) const
}
break;
+ case PROGRAM_CUTPLANE_SPHERES:
+ if( d->shader_programs[PROGRAM_CUTPLANE_SPHERES])
+ {
+ return d->shader_programs[PROGRAM_CUTPLANE_SPHERES];
+ }
+ else
+ {
+ QOpenGLShaderProgram *program = new QOpenGLShaderProgram(viewer);
+ if(!program->addShaderFromSourceFile(QOpenGLShader::Vertex,":/cgal/Polyhedron_3/resources/shader_c3t3_spheres.v"))
+ {
+ std::cerr<<"adding vertex shader FAILED"<addShaderFromSourceFile(QOpenGLShader::Fragment,":/cgal/Polyhedron_3/resources/shader_c3t3.f" ))
+ {
+ std::cerr<<"adding fragment shader FAILED"<bindAttributeLocation("colors", 1);
+ program->link();
+ d->shader_programs[PROGRAM_CUTPLANE_SPHERES] = program;
+ return program;
+ }
+ case PROGRAM_SPHERES:
+ if( d->shader_programs[PROGRAM_SPHERES])
+ {
+ return d->shader_programs[PROGRAM_SPHERES];
+ }
+ else
+ {
+ QOpenGLShaderProgram *program = new QOpenGLShaderProgram(viewer);
+ if(!program->addShaderFromSourceFile(QOpenGLShader::Vertex,":/cgal/Polyhedron_3/resources/shader_spheres.v" ))
+ {
+ std::cerr<<"adding vertex shader FAILED"<addShaderFromSourceFile(QOpenGLShader::Fragment,":/cgal/Polyhedron_3/resources/shader_with_light.f" ))
+ {
+ std::cerr<<"adding fragment shader FAILED"<bindAttributeLocation("colors", 1);
+ program->link();
+ d->shader_programs[PROGRAM_SPHERES] = program;
+ return program;
+
+ }
+ break;
+
default:
std::cerr<<"ERROR : Program not found."<(item);
- if(group)
- Q_FOREACH(Scene_item* child, group->getChildren())
- removeChild(child);
- item->has_group=0;
+ update_group_number(item,0);
children.removeOne(item);
}
//!Moves a child up in the list.
@@ -139,7 +134,8 @@ private:
//!Contains a reference to all the children of this group.
QList children;
//!Updates the property has_group for each group and sub-groups containing new_item.
- void add_group_number(Scene_item*new_item);
+ void update_group_number(Scene_item*new_item, int n);
+
bool expanded;
}; //end of class Scene_group_item
diff --git a/Three/include/CGAL/Three/Scene_item.h b/Three/include/CGAL/Three/Scene_item.h
index 18a3c214e57..f8e69ff0693 100644
--- a/Three/include/CGAL/Three/Scene_item.h
+++ b/Three/include/CGAL/Three/Scene_item.h
@@ -72,6 +72,8 @@ public:
PROGRAM_INSTANCED_WIRE, /** Used to display instanced rendered wired spheres. Not affected by light.*/
PROGRAM_C3T3, /** Used to render a c3t3_item. It discards any fragment on a side of a plane, meaning that nothing is displayed on this side of the plane. Affected by light.*/
PROGRAM_C3T3_EDGES, /** Used to render the edges of a c3t3_item. It discards any fragment on a side of a plane, meaning that nothing is displayed on this side of the plane. Not affected by light.*/
+ PROGRAM_CUTPLANE_SPHERES, /** Used to render the spheres of an item with a cut plane.*/
+ PROGRAM_SPHERES, /** Used to render one or several spheres.*/
NB_OF_PROGRAMS /** Holds the number of different programs in this enum.*/
};
typedef CGAL::Three::Scene_interface::Bbox Bbox;
diff --git a/Three/include/CGAL/Three/Viewer_interface.h b/Three/include/CGAL/Three/Viewer_interface.h
index 4263fcb3586..eefe0a1f505 100644
--- a/Three/include/CGAL/Three/Viewer_interface.h
+++ b/Three/include/CGAL/Three/Viewer_interface.h
@@ -61,6 +61,8 @@ public:
PROGRAM_INSTANCED_WIRE, /** Used to display instanced rendered wired spheres. Not affected by light.*/
PROGRAM_C3T3, /** Used to render a c3t3_item. It discards any fragment on a side of a plane, meaning that nothing is displayed on this side of the plane. Affected by light.*/
PROGRAM_C3T3_EDGES, /** Used to render the edges of a c3t3_item. It discards any fragment on a side of a plane, meaning that nothing is displayed on this side of the plane. Not affected by light.*/
+ PROGRAM_CUTPLANE_SPHERES, /** Used to render the spheres of an item with a cut plane.*/
+ PROGRAM_SPHERES, /** Used to render one or several spheres.*/
NB_OF_PROGRAMS /** Holds the number of different programs in this enum.*/
};