Merge pull request #1028 from maxGimeno/Polyhedron_demo-Spheres_item-GF

Polyhedron demo : Create new items for the spheres and the intersection of the c3t3_item
This commit is contained in:
Sébastien Loriot 2016-05-04 14:41:07 +02:00
commit 5ea6cc63b6
25 changed files with 1199 additions and 998 deletions

View File

@ -208,6 +208,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
add_library(scene_basic_objects SHARED
Scene_plane_item.cpp
Scene_spheres_item.cpp
)
target_link_libraries(scene_basic_objects
demo_framework
@ -227,7 +228,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
add_item(scene_c2t3_item Scene_c2t3_item.cpp)
add_item(scene_c3t3_item Scene_c3t3_item.cpp)
target_link_libraries(scene_c3t3_item scene_polyhedron_item scene_polygon_soup_item ${TBB_LIBRARIES})
target_link_libraries(scene_c3t3_item scene_polyhedron_item scene_polygon_soup_item scene_basic_objects ${TBB_LIBRARIES})
add_item(scene_polyhedron_item Scene_polyhedron_item.cpp)
add_item(scene_polyhedron_transform_item Plugins/PCA/Scene_polyhedron_transform_item.cpp )
@ -241,6 +242,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
target_link_libraries(scene_combinatorial_map_item scene_polyhedron_item)
add_item(scene_polylines_item Scene_polylines_item.cpp)
target_link_libraries(scene_polylines_item scene_basic_objects)
add_item(scene_polyhedron_item_decorator Scene_polyhedron_item_decorator.cpp )
target_link_libraries(scene_polyhedron_item_decorator scene_polyhedron_item)
@ -260,7 +262,8 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
add_item(scene_textured_polyhedron_item Scene_textured_polyhedron_item.cpp texture.cpp)
add_item(scene_edit_polyhedron_item Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp
${editionUI_FILES})
target_link_libraries(scene_edit_polyhedron_item scene_polyhedron_item scene_polyhedron_item_k_ring_selection)
target_link_libraries(scene_edit_polyhedron_item scene_polyhedron_item scene_polyhedron_item_k_ring_selection
scene_basic_objects)
endif()
add_item(scene_implicit_function_item Scene_implicit_function_item.cpp Color_ramp.cpp )
@ -272,8 +275,9 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
target_link_libraries(scene_nef_polyhedron_item scene_polyhedron_item)
add_item(scene_points_with_normal_item Scene_points_with_normal_item.cpp)
target_link_libraries( scene_points_with_normal_item gl_splat)
target_link_libraries( demo_framework gl_splat)
@ -342,6 +346,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
scene_points_with_normal_item
scene_implicit_function_item
scene_polylines_item
scene_basic_objects
NAMESPACE Polyhedron_
APPEND FILE polyhedron_demo_targets.cmake)

View File

@ -1711,7 +1711,7 @@ void MainWindow::restoreCollapseState()
void MainWindow::make_new_group()
{
Scene_group_item * group = new Scene_group_item("New group");
scene->add_group(group);
scene->addItem(group);
}
void MainWindow::on_upButton_pressed()

View File

@ -2,6 +2,7 @@
#include "Scene_c3t3_item.h"
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/IO/File_avizo.h>
#include <iostream>
#include <fstream>
@ -9,18 +10,31 @@
class Polyhedron_demo_c3t3_binary_io_plugin :
public QObject,
public CGAL::Three::Polyhedron_demo_io_plugin_interface
public CGAL::Three::Polyhedron_demo_io_plugin_interface,
public CGAL::Three::Polyhedron_demo_plugin_interface
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface)
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public:
void init(QMainWindow*, CGAL::Three::Scene_interface* sc )
{
this->scene = sc;
}
QString name() const { return "C3t3_io_plugin"; }
QString nameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma)"; }
QString saveNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma);;avizo (*.am)"; }
QString loadNameFilters() const { return "binary files (*.cgal)" ; }
QList<QAction*> actions() const
{
return QList<QAction*>();
}
bool applicable(QAction*) const
{
return false;
}
bool canLoad() const;
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
@ -30,6 +44,7 @@ public:
private:
bool try_load_other_binary_format(std::istream& in, C3t3& c3t3);
bool try_load_a_cdt_3(std::istream& in, C3t3& c3t3);
CGAL::Three::Scene_interface* scene;
};
@ -55,6 +70,7 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
Scene_c3t3_item* item = new Scene_c3t3_item();
item->setName(fileinfo.baseName());
item->setScene(scene);
if(item->load_binary(in)) {

View File

@ -451,7 +451,7 @@ treat_result(Scene_item& source_item,
const Scene_interface::Item_id index = scene->mainSelectionIndex();
scene->itemChanged(index);
scene->setSelectedItem(-1);
Scene_interface::Item_id new_item_id = scene->addItem(&result_item);
scene->setSelectedItem(new_item_id);
}

View File

@ -52,7 +52,7 @@ Meshing_thread* cgal_code_mesh_3(const Polyhedron* pMesh,
std::cerr << "done (" << timer.time() << " ms)" << std::endl;
Scene_c3t3_item* p_new_item = new Scene_c3t3_item;
p_new_item->set_scene(scene);
p_new_item->setScene(scene);
Mesh_parameters param;
param.facet_angle = facet_angle;
@ -93,7 +93,7 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction,
new Function_mesh_domain(Function_wrapper(*pfunction), domain_bbox, 1e-7);
Scene_c3t3_item* p_new_item = new Scene_c3t3_item;
p_new_item->set_scene(scene);
p_new_item->setScene(scene);
Mesh_parameters param;
param.protect_features = false;
@ -143,7 +143,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage,
CGAL::Timer timer;
timer.start();
Scene_c3t3_item* p_new_item = new Scene_c3t3_item;
p_new_item->set_scene(scene);
p_new_item->setScene(scene);
Mesh_parameters param;
param.protect_features = protect_features;

View File

@ -512,6 +512,7 @@ void Polyhedron_demo_mean_curvature_flow_skeleton_plugin::on_actionConvert_to_me
CGAL::internal::IsTerminalDefault() );
skeleton_item->setName(QString("Medial skeleton curve of %1").arg(item->name()));
scene->setSelectedItem(-1);
scene->addItem(skeleton_item);
skeleton_item->invalidateOpenGLBuffers();

View File

@ -225,17 +225,19 @@ void Polyhedron_demo_edit_polyhedron_plugin::on_ShowROICheckBox_stateChanged(int
{
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
if(!edit_item) { continue; }
scene->itemChanged(edit_item); // just for redraw
}
}
void Polyhedron_demo_edit_polyhedron_plugin::on_ShowAsSphereCheckBox_stateChanged(int /*state*/)
void Polyhedron_demo_edit_polyhedron_plugin::on_ShowAsSphereCheckBox_stateChanged(int state)
{
for(CGAL::Three::Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i)
{
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
if(!edit_item) { continue; }
if(state == 0)
edit_item->ShowAsSphere(false);
else
edit_item->ShowAsSphere(true);
scene->itemChanged(edit_item); // just for redraw
}
}
@ -334,8 +336,10 @@ void Polyhedron_demo_edit_polyhedron_plugin::dock_widget_visibility_changed(bool
Scene_edit_polyhedron_item* edit_item = qobject_cast<Scene_edit_polyhedron_item*>(scene->item(i));
if(visible && poly_item) {
ui_widget.ShowAsSphereCheckBox->setChecked(false);
convert_to_edit_polyhedron(i, poly_item);
} else if(!visible && edit_item) {
edit_item->ShowAsSphere(false);
convert_to_plain_polyhedron(i, edit_item);
}
}
@ -401,7 +405,9 @@ Polyhedron_demo_edit_polyhedron_plugin::convert_to_edit_polyhedron(Item_id i,
int k_ring = ui_widget.ROIRadioButton->isChecked() ? ui_widget.BrushSpinBoxRoi->value() :
ui_widget.BrushSpinBoxCtrlVert->value();
edit_poly->set_k_ring(k_ring);
scene->setSelectedItem(-1);
scene->replaceItem(i, edit_poly);
scene->setSelectedItem(i);
return edit_poly;
}

View File

@ -1,8 +1,8 @@
//#define CGAL_PMP_REMESHING_VERBOSE
#include "opengl_tools.h"
#include "create_sphere.h"
#include "Scene_edit_polyhedron_item.h"
#include "Scene_spheres_item.h"
#include <CGAL/Three/Viewer_interface.h>
#include <boost/foreach.hpp>
#include <algorithm>
@ -14,7 +14,7 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item
(Scene_polyhedron_item* poly_item,
Ui::DeformMesh* ui_widget,
QMainWindow* mw)
: Scene_item(NumberOfBuffers,NumberOfVaos),
: Scene_group_item("unnamed",NumberOfBuffers,NumberOfVaos),
ui_widget(ui_widget),
poly_item(poly_item),
is_rot_free(true),
@ -22,10 +22,10 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item
k_ring_selector(poly_item, mw, Scene_polyhedron_item_k_ring_selection::Active_handle::VERTEX, true)
{
nb_ROI = 0;
nb_sphere = 0;
nb_control = 0;
nb_axis = 0;
nb_bbox = 0;
spheres = NULL;
mw->installEventFilter(this);
// bind vertex picking
connect(&k_ring_selector, SIGNAL(selected(const std::set<Polyhedron::Vertex_handle>&)), this,
@ -98,8 +98,6 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item
connect(ui_widget->remeshingEdgeLengthInput_checkBox, SIGNAL(toggled(bool)),
ui_widget->remeshing_edge_length_spinbox, SLOT(setEnabled(bool)));
//the spheres :
create_Sphere(length_of_axis/15.0);
invalidateOpenGLBuffers();
}
@ -150,8 +148,11 @@ void Scene_edit_polyhedron_item::initialize_buffers(CGAL::Three::Viewer_interfac
program->setAttributeBuffer("vertex",GL_DOUBLE,0,3);
buffers[Roi_vertices].release();
vaos[Roi_points]->release();
program->release();
nb_ROI = ROI_points.size();
ROI_points.clear();
ROI_points.swap(ROI_points);
}
//vao for the edges
{
@ -165,46 +166,10 @@ void Scene_edit_polyhedron_item::initialize_buffers(CGAL::Three::Viewer_interfac
vaos[Edges]->release();
program->release();
}
//vao for the ROI spheres
{
program = getShaderProgram(PROGRAM_INSTANCED, viewer);
program->bind();
vaos[ROI_spheres]->bind();
buffers[Sphere_vertices].bind();
buffers[Sphere_vertices].allocate(pos_sphere.data(),
static_cast<int>(pos_sphere.size()*sizeof(double)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_DOUBLE,0,3);
buffers[Sphere_vertices].release();
buffers[Sphere_normals].bind();
buffers[Sphere_normals].allocate(normals_sphere.data(),
static_cast<int>(normals_sphere.size()*sizeof(double)));
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals",GL_DOUBLE,0,3);
buffers[Sphere_normals].release();
buffers[Roi_vertices].bind();
program->enableAttributeArray("center");
program->setAttributeBuffer("center",GL_DOUBLE,0,3);
buffers[Roi_vertices].release();
if(viewer->extension_is_found)
{
viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1);
}
vaos[ROI_spheres]->release();
ROI_color.resize(0);
std::vector<double>(ROI_color).swap(ROI_color);
nb_ROI = ROI_points.size();
ROI_points.resize(0);
std::vector<double>(ROI_points).swap(ROI_points);
}
//vao for the BBOX
{
bbox_program.bind();
vaos[4]->bind();
vaos[BBox]->bind();
buffers[Bbox_vertices].bind();
buffers[Bbox_vertices].allocate(pos_bbox.data(),
static_cast<int>(pos_bbox.size()*sizeof(double)));
@ -212,7 +177,7 @@ void Scene_edit_polyhedron_item::initialize_buffers(CGAL::Three::Viewer_interfac
bbox_program.setAttributeBuffer("vertex",GL_DOUBLE,0,3);
buffers[Bbox_vertices].release();
vaos[4]->release();
vaos[BBox]->release();
nb_bbox = pos_bbox.size();
pos_bbox.resize(0);
std::vector<double>(pos_bbox).swap(pos_bbox);
@ -234,41 +199,9 @@ void Scene_edit_polyhedron_item::initialize_buffers(CGAL::Three::Viewer_interfac
vaos[Control_points]->release();
program->release();
}
//vao for the control spheres
{
program = getShaderProgram(PROGRAM_INSTANCED, viewer);
program->bind();
vaos[Control_spheres]->bind();
buffers[Sphere_vertices].bind();
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_DOUBLE,0,3);
buffers[Sphere_normals].bind();
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals",GL_DOUBLE,0,3);
buffers[Sphere_normals].release();
buffers[Control_vertices].bind();
program->enableAttributeArray("center");
program->setAttributeBuffer("center",GL_DOUBLE,0,3);
buffers[Control_vertices].release();
if(viewer->extension_is_found)
{
viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
}
vaos[Control_spheres]->release();
nb_sphere = pos_sphere.size();
//pos_sphere.resize(0);
//std::vector<double>(pos_sphere).swap(pos_sphere);
// normals_sphere.resize(0);
// std::vector<double>(normals_sphere).swap(normals_sphere);
control_color.resize(0);
std::vector<double>(control_color).swap(control_color);
nb_control = control_points.size();
control_points.resize(0);
std::vector<double>(control_points).swap(control_points);
control_points.clear();
control_points.swap(control_points);
}
//vao for the axis
{
@ -370,11 +303,19 @@ void Scene_edit_polyhedron_item::compute_normals_and_vertices(void)
BOOST_FOREACH(vertex_descriptor vd, deform_mesh->roi_vertices())
{
if(!deform_mesh->is_control_vertex(vd))
{//gl_draw_point( vd->point() );
{
ROI_points.push_back(vd->point().x());
ROI_points.push_back(vd->point().y());
ROI_points.push_back(vd->point().z());
if(spheres)
{
CGAL::Color c(0,255,0);
Kernel::Sphere_3 *sphere = new Kernel::Sphere_3(vd->point(), length_of_axis/15.0);
spheres->add_sphere(sphere, c);
}
}
}
ROI_color.assign(ROI_points.size(),0);
for(std::size_t i=0; i<ROI_color.size()/3; i++)
@ -403,6 +344,13 @@ void Scene_edit_polyhedron_item::compute_normals_and_vertices(void)
control_color.push_back(r);
control_color.push_back(0);
control_color.push_back(b);
if(spheres)
{
CGAL::Color c(255,0,0);
Kernel::Sphere_3 *sphere = new Kernel::Sphere_3((*hb)->point(), length_of_axis/15.0);
spheres->add_sphere(sphere, c);
}
}
}
@ -700,10 +648,8 @@ void Scene_edit_polyhedron_item::draw_frame_plane(QGLViewer* ) const
void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer) const {
CGAL::GL::Color color;
CGAL::GL::Point_size point_size; point_size.set_point_size(5);
color.set_rgb_color(0, 1.f, 0);
if(ui_widget->ShowROICheckBox->isChecked()) {
if(!ui_widget->ShowAsSphereCheckBox->isChecked() || !viewer->extension_is_found) {
@ -718,17 +664,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View
vaos[Roi_points]->release();
}
else{
vaos[ROI_spheres]->bind();
program = getShaderProgram(PROGRAM_INSTANCED);
attrib_buffers(viewer,PROGRAM_INSTANCED);
program->bind();
program->setAttributeValue("colors", QColor(0,255,0));
viewer->glDrawArraysInstanced(GL_TRIANGLES, 0,
static_cast<GLsizei>(nb_sphere/3),
static_cast<GLsizei>(nb_ROI/3));
program->release();
vaos[ROI_spheres]->release();
Scene_group_item::draw(viewer);
}
}
@ -742,18 +678,6 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View
program->release();
vaos[Control_points]->release();
}
else{
vaos[Control_spheres]->bind();
program = getShaderProgram(PROGRAM_INSTANCED);
attrib_buffers(viewer,PROGRAM_INSTANCED);
program->bind();
program->setAttributeValue("colors", QColor(255,0,0));
viewer->glDrawArraysInstanced(GL_TRIANGLES, 0,
static_cast<GLsizei>(nb_sphere/3),
static_cast<GLsizei>(nb_control/3));
program->release();
vaos[Control_spheres]->release();
}
QGLViewer* viewerB = *QGLViewer::QGLViewerPool().begin();
for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data)
@ -804,7 +728,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View
viewer->camera()->getModelViewProjectionMatrix(temp_mat);
for(int i=0; i<16; i++)
mvp_mat.data()[i] = (float)temp_mat[i];
vaos[4]->bind();
vaos[BBox]->bind();
bbox_program.bind();
bbox_program.setUniformValue("rotations", f_mat);
bbox_program.setUniformValue("translation", vec);
@ -813,7 +737,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::View
program->setAttributeValue("colors", QColor(255,0,0));
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(nb_bbox/3));
bbox_program.release();
vaos[4]->release();
vaos[BBox]->release();
}
}
}
@ -858,10 +782,14 @@ void Scene_edit_polyhedron_item::compute_bbox(const CGAL::Three::Scene_interface
void Scene_edit_polyhedron_item::invalidateOpenGLBuffers()
{
if(spheres)
spheres->clear_spheres();
compute_normals_and_vertices();
update_normals();
compute_bbox();
are_buffers_filled = false;
if(spheres)
spheres->invalidateOpenGLBuffers();
}
Scene_polyhedron_item* Scene_edit_polyhedron_item::to_polyhedron_item() {
@ -959,10 +887,6 @@ bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e)
return false;
}
void Scene_edit_polyhedron_item::create_Sphere(double R)
{
create_flat_sphere(R, pos_sphere, normals_sphere);
}
//#include "Scene_edit_polyhedron_item.moc"
void Scene_edit_polyhedron_item::update_frame_plane()
@ -972,3 +896,25 @@ void Scene_edit_polyhedron_item::update_frame_plane()
hgb_data->refresh();
}
}
void Scene_edit_polyhedron_item::ShowAsSphere(bool b)
{
if(b && !spheres)
{
spheres = new Scene_spheres_item(this, false);
spheres->setName("ROI & Control spheres");
spheres->setRenderingMode(Gouraud);
connect(spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres()));
scene->setSelectedItem(scene->item_id(this));
scene->addItem(spheres);
scene->changeGroup(spheres, this);
lockChild(spheres);
invalidateOpenGLBuffers();
}
else if(!b && spheres!=0)
{
unlockChild(spheres);
removeChild(spheres);
scene->erase(scene->item_id(spheres));
}
}

View File

@ -3,6 +3,10 @@
//#define CGAL_PROFILE
#include "Scene_edit_polyhedron_item_config.h"
#include "Scene_polyhedron_item.h"
#include <CGAL/Three/Scene_group_item.h>
#include "Scene_polyhedron_item_k_ring_selection.h"
#include "Travel_isolated_components.h"
@ -35,7 +39,7 @@ typedef boost::graph_traits<Polyhedron>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Polyhedron>::face_descriptor face_descriptor;
typedef boost::graph_traits<Polyhedron>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Polyhedron>::edge_descriptor edge_descriptor;
class Scene_spheres_item;
struct Array_based_vertex_point_map
{
public:
@ -191,7 +195,7 @@ struct Mouse_keyboard_state_deformation
// This class represents a polyhedron in the OpenGL scene
class SCENE_EDIT_POLYHEDRON_ITEM_EXPORT Scene_edit_polyhedron_item
: public CGAL::Three::Scene_item {
: public CGAL::Three::Scene_group_item {
Q_OBJECT
public:
/// Create an Scene_edit_polyhedron_item from a Scene_polyhedron_item.
@ -236,6 +240,7 @@ public:
bool isFinite() const { return true; }
bool isEmpty() const;
void compute_bbox() const;
Bbox bbox() const{return Scene_item::bbox();}
int get_k_ring() { return k_ring_selector.k_ring; }
void set_k_ring(int v) { k_ring_selector.k_ring = v; }
@ -244,12 +249,17 @@ public:
// take keyboard events from main-window, which is more stable
bool eventFilter(QObject *target, QEvent *event);
void update_frame_plane();
void ShowAsSphere(bool b);
protected:
void timerEvent(QTimerEvent *event);
public Q_SLOTS:
void reset_spheres()
{
spheres = NULL;
}
void invalidateOpenGLBuffers();
void selected(const std::set<Polyhedron::Vertex_handle>& m)
{
@ -259,7 +269,7 @@ public Q_SLOTS:
vertex_descriptor vh = *it;
bool changed = false;
if(ui_widget->ROIRadioButton->isChecked()) {
if(ui_widget->InsertRadioButton->isChecked()) { changed = insert_roi_vertex(vh); }
if(ui_widget->InsertRadioButton->isChecked()) { changed = insert_roi_vertex(vh);}
else { changed = erase_roi_vertex(vh); }
}
else {
@ -298,16 +308,14 @@ private:
mutable std::vector<GLdouble> normals;
mutable std::vector<GLdouble> pos_bbox;
mutable std::vector<GLdouble> pos_axis;
mutable std::vector<GLdouble> pos_sphere;
mutable std::vector<GLdouble> normals_sphere;
mutable std::vector<GLdouble> pos_frame_plane;
mutable QOpenGLShaderProgram *program;
mutable QOpenGLShaderProgram bbox_program;
mutable std::size_t nb_ROI;
mutable std::size_t nb_sphere;
mutable std::size_t nb_control;
mutable std::size_t nb_axis;
mutable std::size_t nb_bbox;
mutable Scene_spheres_item* spheres;
enum Buffer
{
@ -315,8 +323,6 @@ private:
Facet_normals,
Roi_vertices,
Control_vertices,
Sphere_vertices,
Sphere_normals,
Bbox_vertices,
Axis_vertices,
Axis_colors,
@ -328,10 +334,8 @@ private:
Facets=0,
Roi_points,
Edges,
ROI_spheres,
BBox,
Control_points,
Control_spheres,
Axis,
Frame_plane,
NumberOfVaos
@ -341,7 +345,6 @@ private:
void initialize_buffers(CGAL::Three::Viewer_interface *viewer) const;
void compute_normals_and_vertices(void);
void compute_bbox(const CGAL::Three::Scene_interface::Bbox&);
void create_Sphere(double);
void reset_drawing_data();
Deform_mesh* deform_mesh;

View File

@ -39,5 +39,6 @@
<file>resources/shader_c3t3.v</file>
<file>resources/shader_c3t3.f</file>
<file>resources/shader_plane_two_faces.f</file>
<file>resources/shader_spheres.v</file>
</qresource>
</RCC>

View File

@ -50,10 +50,6 @@ Scene::Scene(QObject* parent)
Scene::Item_id
Scene::addItem(CGAL::Three::Scene_item* item)
{
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item);
if(group)
m_group_entries.prepend(group);
Bbox bbox_before = bbox();
m_entries.push_back(item);
connect(item, SIGNAL(itemChanged()),
@ -80,6 +76,10 @@ Scene::addItem(CGAL::Three::Scene_item* item)
Q_EMIT updated();
Item_id id = m_entries.size() - 1;
Q_EMIT newItem(id);
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item);
if(group)
add_group(group);
//if group selected, add item to it
if(mainSelectionIndex() >=0)
{
@ -91,7 +91,7 @@ Scene::addItem(CGAL::Three::Scene_item* item)
if(selected_group)
{
selected_group->addChild(item);
group_added();
redraw_model();
}
}
}
@ -118,32 +118,38 @@ Scene::replaceItem(Scene::Item_id index, CGAL::Three::Scene_item* item, bool emi
Q_EMIT updated_bbox();
}
Q_EMIT updated();
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(m_entries[index]);
if(group)
{
add_group(group);
}
itemChanged(index);
Q_EMIT restoreCollapsedState();
group_added();
redraw_model();
return item;
}
Scene::Item_id
Scene::erase(Scene::Item_id index)
{
CGAL::Three::Scene_item* item = m_entries[index];
if(item->parentGroup()
&& item->parentGroup()->isChildLocked(item))
return -1;
clear();
index_map.clear();
if(index < 0 || index >= m_entries.size())
return -1;
CGAL::Three::Scene_item* item = m_entries[index];
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item);
if(group)
{
m_group_entries.removeAll(group);
}
Q_FOREACH(CGAL::Three::Scene_group_item* group, m_group_entries)
{
if(group->getChildren().contains(item))
group->removeChild(item);
}
if(item->parentGroup())
item->parentGroup()->removeChild(item);
Q_EMIT itemAboutToBeDestroyed(item);
item->deleteLater();
m_entries.removeAll(item);
@ -175,6 +181,10 @@ Scene::erase(QList<int> indices)
max_index = (std::max)(max_index, index);
CGAL::Three::Scene_item* item = m_entries[index];
if(item->parentGroup()
&& item->parentGroup()->isChildLocked(item))
if(!indices.contains(item_id(item->parentGroup())))
continue;
if(!to_be_removed.contains(item))
to_be_removed.push_back(item);
}
@ -186,9 +196,8 @@ Scene::erase(QList<int> indices)
{
m_group_entries.removeAll(group);
}
Q_FOREACH(CGAL::Three::Scene_group_item* group_item, m_group_entries)
if(group_item->getChildren().contains(item))
group_item->removeChild(item);
if(item->parentGroup())
item->parentGroup()->removeChild(item);
Q_EMIT itemAboutToBeDestroyed(item);
item->deleteLater();
m_entries.removeAll(item);
@ -231,7 +240,7 @@ Scene::~Scene()
{
Q_FOREACH(CGAL::Three::Scene_item* item_ptr, m_entries)
{
delete item_ptr;
item_ptr->deleteLater();
}
m_entries.clear();
@ -355,7 +364,6 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
viewer->glEnable(GL_LIGHTING);
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item || selected_items_list.contains(index))
@ -409,7 +417,6 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
|| item.renderingMode() == Wireframe)
{
viewer->glDisable(GL_LIGHTING);
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item || selected_items_list.contains(index))
@ -431,7 +438,6 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
else{
if( item.renderingMode() == PointsPlusNormals ){
viewer->glDisable(GL_LIGHTING);
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
viewer->glPointSize(2.f);
viewer->glLineWidth(1.0f);
if(index == selected_item || selected_items_list.contains(index))
@ -480,7 +486,6 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
(!with_names && item.renderingMode() == PointsPlusNormals))
{
viewer->glDisable(GL_LIGHTING);
viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
viewer->glPointSize(2.0f);
viewer->glLineWidth(1.0f);
@ -561,7 +566,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer)
{
Q_EMIT(itemPicked(index_map.key(mainSelectionIndex())));
}
Q_EMIT drawFinished();
}
// workaround for Qt-4.2 (see above)
@ -744,59 +749,57 @@ bool Scene::dropMimeData(const QMimeData * /*data*/,
//get IDs of all children of selected groups
Q_FOREACH(int i, selected_items_list)
{
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item(i));
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
groups_children << item_id(child);
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(item(i));
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
groups_children << item_id(child);
}
// Insure that children of selected groups will not be added twice
Q_FOREACH(int i, selected_items_list)
{
if(!groups_children.contains(i))
items << item(i);
if(!groups_children.contains(i))
{
items << item(i);
}
}
//Gets the group at the drop position
CGAL::Three::Scene_group_item* group =
qobject_cast<CGAL::Three::Scene_group_item*>(this->item(index_map[parent]));
qobject_cast<CGAL::Three::Scene_group_item*>(this->item(index_map[parent]));
bool one_contained = false;
if(group)
{
Q_FOREACH(int id, selected_items_list)
Q_FOREACH(int id, selected_items_list)
if(group->getChildren().contains(item(id)))
{
one_contained = true;
break;
one_contained = true;
break;
}
}
//if the drop item is not a group_item or if it already contains the item, then the drop action must be ignored
if(!group ||one_contained)
{
//unless the drop zone is empty, which means the item should be removed from all groups.
if(!parent.isValid())
//unless the drop zone is empty, which means the item should be removed from all groups.
if(!parent.isValid())
{
Q_FOREACH(Scene_item* item, items)
{
Q_FOREACH(Scene_item* item, items)
while(item->has_group!=0)
{
Q_FOREACH(CGAL::Three::Scene_group_item* group_item, m_group_entries)
if(group_item->getChildren().contains(item))
{
group_item->removeChild(item);
break;
}
}
group_added();
return true;
if(item->parentGroup())
{
item->parentGroup()->removeChild(item);
}
}
return false;
redraw_model();
return true;
}
return false;
}
Q_FOREACH(Scene_item* item, items)
changeGroup(item, group);
Q_FOREACH(Scene_item* item, items)
changeGroup(item, group);
//group->addChild(item(mainSelectionIndex()));
group_added();
redraw_model();
return true;
}
void Scene::moveRowUp()
@ -820,7 +823,7 @@ void Scene::moveRowUp()
int newId = index_map.value(index(baseId.row()-1, baseId.column(),baseId.parent())) ;
m_entries.move(mainSelectionIndex(), newId);
}
group_added();
redraw_model();
setSelectedItem(m_entries.indexOf(selected_item));
}
}
@ -845,7 +848,7 @@ void Scene::moveRowDown()
int newId = index_map.value(index(baseId.row()+1, baseId.column(),baseId.parent())) ;
m_entries.move(mainSelectionIndex(), newId);
}
group_added();
redraw_model();
setSelectedItem(m_entries.indexOf(selected_item));
}
}
@ -1102,7 +1105,7 @@ QList<Scene_item*> Scene::item_entries() const
{
return m_entries;
}
void Scene::group_added()
void Scene::redraw_model()
{
//makes the hierarchy in the tree
//clears the model
@ -1118,18 +1121,15 @@ void Scene::group_added()
void Scene::changeGroup(Scene_item *item, CGAL::Three::Scene_group_item *target_group)
{
//remove item from the containing group if any
if(item->has_group!=0)
Q_FOREACH(CGAL::Three::Scene_group_item* group, m_group_entries)
{
if(group->getChildren().contains(item))
if(item->parentGroup())
{
remove_item_from_groups(item);
break;
if(item->parentGroup()->isChildLocked(item))
return;
item->parentGroup()->removeChild(item);
}
}
//add the item to the target group
target_group->addChild(item);
item->moveToGroup(target_group);
//add the item to the target group
target_group->addChild(item);
item->moveToGroup(target_group);
}
float Scene::get_bbox_length() const
@ -1250,17 +1250,17 @@ void Scene::add_group(Scene_group_item* group)
Q_FOREACH(int id, indices)
changeGroup(item(id),group);
changeGroup(group, existing_group);
addItem(group);
group_added();
redraw_model();
}
//else wer create a new group
//else we create a new group
else
{
Q_FOREACH(int id, indices)
changeGroup(item(id),group);
addItem(group);
group_added();
redraw_model();
}
connect(this, SIGNAL(drawFinished()), group, SLOT(resetDraw()));
group->setScene(this);
}
namespace scene { namespace details {

View File

@ -178,9 +178,8 @@ public Q_SLOTS:
//!Removes item from all the groups of the scene.
void remove_item_from_groups(CGAL::Three::Scene_item* item);
void add_group(Scene_group_item* group);
//!Re-organizes the sceneView.
void group_added();
void redraw_model();
//! Sets the selected item to the target index.
void setSelectedItemIndex(int i)
{
@ -245,11 +244,12 @@ Q_SIGNALS:
void selectionRay(double, double, double, double, double, double);
void selectionChanged(int i);
void restoreCollapsedState();
void drawFinished();
private Q_SLOTS:
//! Casts a selection ray and calls the item function select.
void setSelectionRay(double, double, double, double, double, double);
void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();}
void add_group(Scene_group_item* group);
private:
/*! Calls the drawing functions of each visible item according
* to its current renderingMode. If with_names is true, uses

View File

@ -1,5 +1,5 @@
#include "config.h"
#include "create_sphere.h"
#include "Scene_spheres_item.h"
#include "Scene_c3t3_item.h"
#include <QVector>
@ -31,6 +31,192 @@ typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
typedef Tree::Point_and_primitive_id Point_and_primitive_id;
// The special Scene_item only for triangles
class Scene_intersection_item : public CGAL::Three::Scene_item
{
Q_OBJECT
public :
Scene_intersection_item(Scene_c3t3_item* parent)
:CGAL::Three::Scene_item(NumberOfBuffers,NumberOfVaos)
{
setParent(parent);
}
void init_vectors(
std::vector<float> *p_vertices,
std::vector<float> *p_normals,
std::vector<float> *p_edges,
std::vector<float> *p_colors)
{
vertices = p_vertices;
normals = p_normals;
edges = p_edges;
colors = p_colors;
}
void setColor(QColor c)
{
qobject_cast<Scene_c3t3_item*>(this->parent())->setColor(c);
Scene_item::setColor(c);
}
// Indicates if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const {
return (m != Gouraud && m != PointsPlusNormals && m != Splatting && m != Points);
}
void initialize_buffers(CGAL::Three::Viewer_interface *viewer)
{
//vao containing the data for the facets
{
program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer);
program->bind();
vaos[Facets]->bind();
buffers[Vertices].bind();
buffers[Vertices].allocate(vertices->data(),
static_cast<int>(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<int>(normals->size()*sizeof(float)));
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
buffers[Normals].release();
buffers[Colors].bind();
buffers[Colors].allocate(colors->data(),
static_cast<int>(colors->size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors", GL_FLOAT, 0, 3);
buffers[Colors].release();
vaos[Facets]->release();
program->release();
}
//vao containing the data for the lines
{
program = getShaderProgram(PROGRAM_NO_SELECTION, viewer);
program->bind();
vaos[Lines]->bind();
buffers[Edges].bind();
buffers[Edges].allocate(edges->data(),
static_cast<int>(edges->size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
buffers[Edges].release();
vaos[Lines]->release();
program->release();
}
}
//Displays the item
void draw(CGAL::Three::Viewer_interface* viewer) const
{
vaos[Facets]->bind();
program = getShaderProgram(PROGRAM_WITH_LIGHT);
attrib_buffers(viewer, PROGRAM_WITH_LIGHT);
program->bind();
// positions_poly is also used for the faces in the cut plane
// and changes when the cut plane is moved
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertices->size() / 3));
program->release();
vaos[Facets]->release();
}
void draw_edges(CGAL::Three::Viewer_interface* viewer) const
{
vaos[Lines]->bind();
program = getShaderProgram(PROGRAM_NO_SELECTION);
attrib_buffers(viewer, PROGRAM_NO_SELECTION);
program->bind();
program->setAttributeValue("colors", QColor(Qt::black));
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(edges->size() / 3));
program->release();
vaos[Lines]->release();
}
void addTriangle(Kernel::Point_3 pa, Kernel::Point_3 pb, Kernel::Point_3 pc, CGAL::Color color)
{
Kernel::Vector_3 n = cross_product(pb - pa, pc - pa);
n = n / CGAL::sqrt(n*n);
for (int i = 0; i<3; i++)
{
normals->push_back(n.x());
normals->push_back(n.y());
normals->push_back(n.z());
}
vertices->push_back(pa.x());
vertices->push_back(pa.y());
vertices->push_back(pa.z());
vertices->push_back(pb.x());
vertices->push_back(pb.y());
vertices->push_back(pb.z());
vertices->push_back(pc.x());
vertices->push_back(pc.y());
vertices->push_back(pc.z());
edges->push_back(pa.x());
edges->push_back(pa.y());
edges->push_back(pa.z());
edges->push_back(pb.x());
edges->push_back(pb.y());
edges->push_back(pb.z());
edges->push_back(pb.x());
edges->push_back(pb.y());
edges->push_back(pb.z());
edges->push_back(pc.x());
edges->push_back(pc.y());
edges->push_back(pc.z());
edges->push_back(pc.x());
edges->push_back(pc.y());
edges->push_back(pc.z());
edges->push_back(pa.x());
edges->push_back(pa.y());
edges->push_back(pa.z());
for(int i=0; i<3; i++)
{
colors->push_back((float)color.red()/255);
colors->push_back((float)color.green()/255);
colors->push_back((float)color.blue()/255);
}
}
Scene_item* clone() const {return 0;}
QString toolTip() const {return QString();}
private:
enum Buffer
{
Vertices =0,
Normals,
Colors,
Edges,
NumberOfBuffers
};
enum Vao
{
Facets=0,
Lines,
NumberOfVaos
};
//contains the data
mutable std::vector<float> *vertices;
mutable std::vector<float> *normals;
mutable std::vector<float> *edges;
mutable std::vector<float> *colors;
mutable QOpenGLShaderProgram *program;
}; //end of class Scene_triangle_item
struct Scene_c3t3_item_priv {
Scene_c3t3_item_priv(Scene_c3t3_item* item)
@ -95,29 +281,11 @@ struct Set_show_tetrahedra {
Set_show_tetrahedra(Scene_c3t3_item_priv* priv) : priv(priv) {}
void operator()(bool b) {
priv->show_tetrahedra = b;
priv->item->changed();
priv->item->itemChanged();
priv->item->show_intersection(b);
}
};
void Scene_c3t3_item::compile_shaders()
{
program_sphere = new QOpenGLShaderProgram(this);
if(!program_sphere->addShaderFromSourceFile(QOpenGLShader::Vertex,":/cgal/Polyhedron_3/resources/shader_c3t3_spheres.v"))
{
std::cerr<<"adding vertex shader FAILED"<<std::endl;
}
if(!program_sphere->addShaderFromSourceFile(QOpenGLShader::Fragment,":/cgal/Polyhedron_3/resources/shader_c3t3.f" ))
{
std::cerr<<"adding fragment shader FAILED"<<std::endl;
}
if(!program_sphere->link())
{
//std::cerr<<"linking Program FAILED"<<std::endl;
qDebug() << program_sphere->log();
}
}
double complex_diag(const Scene_item* item) {
const Scene_item::Bbox& bbox = item->bbox();
const double& xdelta = bbox.xmax-bbox.xmin;
@ -130,10 +298,9 @@ double complex_diag(const Scene_item* item) {
}
Scene_c3t3_item::Scene_c3t3_item()
: Scene_item(NumberOfBuffers, NumberOfVaos)
: Scene_group_item("unnamed", NumberOfBuffers, NumberOfVaos)
, d(new Scene_c3t3_item_priv(this))
, frame(new ManipulatedFrame())
, last_known_scene(NULL)
, data_item_(NULL)
, histogram_()
, indices_()
@ -146,21 +313,22 @@ Scene_c3t3_item::Scene_c3t3_item()
s_normals.resize(0);
ws_vertex.resize(0);
need_changed = false;
spheres = NULL;
intersection = NULL;
compute_bbox();
startTimer(0);
connect(frame, SIGNAL(modified()), this, SLOT(changed()));
c3t3_changed();
setRenderingMode(FlatPlusEdges);
compile_shaders();
spheres_are_shown = false;
create_flat_and_wire_sphere(1.0f,s_vertex,s_normals, ws_vertex);
}
Scene_c3t3_item::Scene_c3t3_item(const C3t3& c3t3)
: Scene_item(NumberOfBuffers, NumberOfVaos)
: Scene_group_item("unnamed", NumberOfBuffers, NumberOfVaos)
, d(new Scene_c3t3_item_priv(c3t3, this))
, frame(new ManipulatedFrame())
, last_known_scene(NULL)
, data_item_(NULL)
, histogram_()
, indices_()
@ -172,12 +340,14 @@ Scene_c3t3_item::Scene_c3t3_item(const C3t3& c3t3)
s_normals.resize(0);
ws_vertex.resize(0);
need_changed = false;
spheres = NULL;
intersection = NULL;
compute_bbox();
startTimer(0);
connect(frame, SIGNAL(modified()), this, SLOT(changed()));
reset_cut_plane();
c3t3_changed();
setRenderingMode(FlatPlusEdges);
compile_shaders();
spheres_are_shown = false;
create_flat_and_wire_sphere(1.0f,s_vertex,s_normals, ws_vertex);
}
@ -518,8 +688,8 @@ void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const {
}
vaos[Grid]->bind();
program = getShaderProgram(PROGRAM_WITHOUT_LIGHT);
attrib_buffers(viewer, PROGRAM_WITHOUT_LIGHT);
program = getShaderProgram(PROGRAM_NO_SELECTION);
attrib_buffers(viewer, PROGRAM_NO_SELECTION);
program->bind();
program->setAttributeValue("colors", QColor(Qt::black));
QMatrix4x4 f_mat;
@ -543,68 +713,24 @@ void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const {
vaos[Facets]->release();
if(d->show_tetrahedra && !frame->isManipulated()) {
if (!are_intersection_buffers_filled)
if(d->show_tetrahedra){
if(!frame->isManipulated() && !are_intersection_buffers_filled)
{
if(!intersection->visible())
intersection->setVisible(true);
ncthis->compute_intersections();
ncthis->initialize_intersection_buffers(viewer);
intersection->initialize_buffers(viewer);
are_intersection_buffers_filled = true;
}
vaos[iFacets]->bind();
program = getShaderProgram(PROGRAM_WITH_LIGHT);
attrib_buffers(viewer, PROGRAM_WITH_LIGHT);
program->bind();
// positions_poly is also used for the faces in the cut plane
// and changes when the cut plane is moved
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(positions_poly.size() / 3));
program->release();
vaos[iFacets]->release();
else if(frame->isManipulated() && intersection->visible())
intersection->setVisible(false);
}
if(spheres_are_shown)
{
vaos[Spheres]->bind();
program_sphere->bind();
//ModelViewMatrix used for the transformation of the camera.
QMatrix4x4 mvp_mat;
// ModelView Matrix used for the lighting system
QMatrix4x4 mv_mat;
GLdouble d_mat[16];
GLint is_both_sides = 0;
viewer->camera()->getModelViewProjectionMatrix(d_mat);
//Convert the GLdoubles matrices in GLfloats
for (int i=0; i<16; ++i){
mvp_mat.data()[i] = GLfloat(d_mat[i]);
}
viewer->camera()->getModelViewMatrix(d_mat);
for (int i=0; i<16; ++i)
mv_mat.data()[i] = GLfloat(d_mat[i]);
QVector4D position(0.0f,0.0f,1.0f, 1.0f );
QVector4D ambient(0.4f, 0.4f, 0.4f, 0.4f);
// Diffuse
QVector4D diffuse(1.0f, 1.0f, 1.0f, 1.0f);
// Specular
QVector4D specular(0.0f, 0.0f, 0.0f, 1.0f);
viewer->glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides);
QVector4D cp(this->plane().a(),this->plane().b(),this->plane().c(),this->plane().d());
program_sphere->setUniformValue("cutplane", cp);
program_sphere->setUniformValue("mvp_matrix", mvp_mat);
program_sphere->setUniformValue("mv_matrix", mv_mat);
program_sphere->setUniformValue("light_pos", position);
program_sphere->setUniformValue("light_diff",diffuse);
program_sphere->setUniformValue("light_spec", specular);
program_sphere->setUniformValue("light_amb", ambient);
program_sphere->setUniformValue("spec_power", 51.8f);
program_sphere->setUniformValue("is_two_side", is_both_sides);
viewer->glDrawArraysInstanced(GL_TRIANGLES, 0,
static_cast<GLsizei>(s_vertex.size()/3),
static_cast<GLsizei>(s_radius.size()));
program_sphere->release();
vaos[Spheres]->release();
spheres->setPlane(this->plane());
}
Scene_group_item::draw(viewer);
}
void Scene_c3t3_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const {
@ -624,8 +750,8 @@ void Scene_c3t3_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const {
if(renderingMode() == Wireframe)
{
vaos[Grid]->bind();
program = getShaderProgram(PROGRAM_WITHOUT_LIGHT);
attrib_buffers(viewer, PROGRAM_WITHOUT_LIGHT);
program = getShaderProgram(PROGRAM_NO_SELECTION);
attrib_buffers(viewer, PROGRAM_NO_SELECTION);
program->bind();
program->setAttributeValue("colors", QColor(Qt::black));
QMatrix4x4 f_mat;
@ -647,64 +773,25 @@ void Scene_c3t3_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const {
program->release();
vaos[Edges]->release();
if(d->show_tetrahedra && !frame->isManipulated()) {
if (!are_intersection_buffers_filled)
if(d->show_tetrahedra){
if(!frame->isManipulated() && !are_intersection_buffers_filled)
{
if(!intersection->visible())
intersection->setVisible(true);
ncthis->compute_intersections();
ncthis->initialize_intersection_buffers(viewer);
intersection->initialize_buffers(viewer);
are_intersection_buffers_filled = true;
}
vaos[iEdges]->bind();
program = getShaderProgram(PROGRAM_NO_SELECTION);
attrib_buffers(viewer, PROGRAM_NO_SELECTION);
program->bind();
program->setAttributeValue("colors", QColor(Qt::black));
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(positions_lines.size() / 3));
program->release();
vaos[iEdges]->release();
else if(frame->isManipulated() && intersection->visible())
intersection->setVisible(false);
}
if(spheres_are_shown)
{
vaos[Wired_spheres]->bind();
program_sphere->bind();
//ModelViewMatrix used for the transformation of the camera.
QMatrix4x4 mvp_mat;
// ModelView Matrix used for the lighting system
QMatrix4x4 mv_mat;
GLdouble d_mat[16];
GLint is_both_sides = 0;
viewer->camera()->getModelViewProjectionMatrix(d_mat);
//Convert the GLdoubles matrices in GLfloats
for (int i=0; i<16; ++i){
mvp_mat.data()[i] = GLfloat(d_mat[i]);
}
viewer->camera()->getModelViewMatrix(d_mat);
for (int i=0; i<16; ++i)
mv_mat.data()[i] = GLfloat(d_mat[i]);
QVector4D position(0.0f,0.0f,1.0f, 1.0f );
QVector4D ambient(0.4f, 0.4f, 0.4f, 0.4f);
// Diffuse
QVector4D diffuse(1.0f, 1.0f, 1.0f, 1.0f);
// Specular
QVector4D specular(0.0f, 0.0f, 0.0f, 1.0f);
viewer->glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides);
program_sphere->setUniformValue("mvp_matrix", mvp_mat);
program_sphere->setUniformValue("mv_matrix", mv_mat);
program_sphere->setUniformValue("light_pos", position);
program_sphere->setUniformValue("light_diff",diffuse);
program_sphere->setUniformValue("light_spec", specular);
program_sphere->setUniformValue("light_amb", ambient);
program_sphere->setUniformValue("spec_power", 51.8f);
program_sphere->setUniformValue("is_two_side", is_both_sides);
viewer->glDrawArraysInstanced(GL_TRIANGLES, 0,
static_cast<GLsizei>(ws_vertex.size()/3),
static_cast<GLsizei>(s_radius.size()));
program_sphere->release();
vaos[Wired_spheres]->release();
spheres->setPlane(this->plane());
}
Scene_group_item::draw_edges(viewer);
}
void Scene_c3t3_item::draw_points(CGAL::Three::Viewer_interface * viewer) const
@ -727,8 +814,8 @@ void Scene_c3t3_item::draw_points(CGAL::Three::Viewer_interface * viewer) const
program->release();
vaos[Grid]->bind();
program = getShaderProgram(PROGRAM_WITHOUT_LIGHT);
attrib_buffers(viewer, PROGRAM_WITHOUT_LIGHT);
program = getShaderProgram(PROGRAM_NO_SELECTION);
attrib_buffers(viewer, PROGRAM_NO_SELECTION);
program->bind();
program->setAttributeValue("colors", this->color());
QMatrix4x4 f_mat;
@ -738,11 +825,18 @@ void Scene_c3t3_item::draw_points(CGAL::Three::Viewer_interface * viewer) const
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(positions_grid.size() / 3));
program->release();
vaos[Grid]->release();
if(spheres_are_shown)
{
spheres->setPlane(this->plane());
}
Scene_group_item::draw_edges(viewer);
}
void Scene_c3t3_item::draw_triangle(const Kernel::Point_3& pa,
const Kernel::Point_3& pb,
const Kernel::Point_3& pc, bool /* is_cut */) const {
const Kernel::Point_3& pc) const
{
#undef darker
Kernel::Vector_3 n = cross_product(pb - pa, pc - pa);
@ -834,11 +928,11 @@ void Scene_c3t3_item::export_facets_in_complex()
}
soup_item->setName(QString("%1_%2").arg(this->name()).arg("facets"));
last_known_scene->addItem(soup_item);
scene->addItem(soup_item);
}
else{
item->setName(QString("%1_%2").arg(this->name()).arg("facets"));
last_known_scene->addItem(item);
scene->addItem(item);
}
}
@ -878,60 +972,6 @@ QMenu* Scene_c3t3_item::contextMenu()
return menu;
}
void Scene_c3t3_item::initialize_intersection_buffers(CGAL::Three::Viewer_interface *viewer)
{
//vao containing the data for the facets
{
program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer);
program->bind();
vaos[iFacets]->bind();
buffers[iFacet_vertices].bind();
buffers[iFacet_vertices].allocate(positions_poly.data(),
static_cast<int>(positions_poly.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
buffers[iFacet_vertices].release();
buffers[iFacet_normals].bind();
buffers[iFacet_normals].allocate(normals.data(),
static_cast<int>(normals.size()*sizeof(float)));
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
buffers[iFacet_normals].release();
buffers[iFacet_colors].bind();
buffers[iFacet_colors].allocate(f_colors.data(),
static_cast<int>(f_colors.size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors", GL_FLOAT, 0, 3);
buffers[iFacet_colors].release();
vaos[iFacets]->release();
program->release();
}
//vao containing the data for the lines
{
program = getShaderProgram(PROGRAM_NO_SELECTION, viewer);
program->bind();
vaos[iEdges]->bind();
buffers[iEdges_vertices].bind();
buffers[iEdges_vertices].allocate(positions_lines.data(),
static_cast<int>(positions_lines.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
buffers[iEdges_vertices].release();
vaos[iEdges]->release();
program->release();
}
are_intersection_buffers_filled = true;
}
void Scene_c3t3_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer)
{
//vao containing the data for the facets
@ -997,7 +1037,7 @@ void Scene_c3t3_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer)
//vao containing the data for the grid
{
program = getShaderProgram(PROGRAM_WITHOUT_LIGHT, viewer);
program = getShaderProgram(PROGRAM_NO_SELECTION, viewer);
program->bind();
vaos[Grid]->bind();
@ -1011,121 +1051,27 @@ void Scene_c3t3_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer)
program->release();
}
//vao containing the data for the spheres
{
program_sphere->bind();
vaos[Spheres]->bind();
buffers[Sphere_vertices].bind();
buffers[Sphere_vertices].allocate(s_vertex.data(),
static_cast<int>(s_vertex.size()*sizeof(float)));
program_sphere->enableAttributeArray("vertex");
program_sphere->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
buffers[Sphere_vertices].release();
buffers[Sphere_normals].bind();
buffers[Sphere_normals].allocate(s_normals.data(),
static_cast<int>(s_normals.size()*sizeof(float)));
program_sphere->enableAttributeArray("normals");
program_sphere->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
buffers[Sphere_normals].release();
buffers[Sphere_colors].bind();
buffers[Sphere_colors].allocate(s_colors.data(),
static_cast<int>(s_colors.size()*sizeof(float)));
program_sphere->enableAttributeArray("colors");
program_sphere->setAttributeBuffer("colors", GL_FLOAT, 0, 3);
buffers[Sphere_colors].release();
buffers[Sphere_radius].bind();
buffers[Sphere_radius].allocate(s_radius.data(),
static_cast<int>(s_radius.size()*sizeof(float)));
program_sphere->enableAttributeArray("radius");
program_sphere->setAttributeBuffer("radius", GL_FLOAT, 0, 1);
buffers[Sphere_radius].release();
buffers[Sphere_center].bind();
buffers[Sphere_center].allocate(s_center.data(),
static_cast<int>(s_center.size()*sizeof(float)));
program_sphere->enableAttributeArray("center");
program_sphere->setAttributeBuffer("center", GL_FLOAT, 0, 3);
buffers[Sphere_center].release();
viewer->glVertexAttribDivisor(program_sphere->attributeLocation("center"), 1);
viewer->glVertexAttribDivisor(program_sphere->attributeLocation("radius"), 1);
viewer->glVertexAttribDivisor(program_sphere->attributeLocation("colors"), 1);
vaos[Spheres]->release();
}
//vao containing the data for the wired spheres
{
program_sphere->bind();
vaos[Wired_spheres]->bind();
buffers[Wired_spheres_vertices].bind();
buffers[Wired_spheres_vertices].allocate(s_vertex.data(),
static_cast<int>(s_vertex.size()*sizeof(float)));
program_sphere->enableAttributeArray("vertex");
program_sphere->setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
buffers[Wired_spheres_vertices].release();
buffers[Sphere_normals].bind();
program_sphere->enableAttributeArray("normals");
program_sphere->setAttributeBuffer("normals", GL_FLOAT, 0, 3);
buffers[Sphere_normals].release();
buffers[Sphere_colors].bind();
program_sphere->enableAttributeArray("colors");
program_sphere->setAttributeBuffer("colors", GL_FLOAT, 0, 3);
buffers[Sphere_colors].release();
buffers[Sphere_radius].bind();
program_sphere->enableAttributeArray("radius");
program_sphere->setAttributeBuffer("radius", GL_FLOAT, 0, 1);
buffers[Sphere_radius].release();
buffers[Sphere_center].bind();
program_sphere->enableAttributeArray("center");
program_sphere->setAttributeBuffer("center", GL_FLOAT, 0, 3);
buffers[Sphere_center].release();
viewer->glVertexAttribDivisor(program_sphere->attributeLocation("center"), 1);
viewer->glVertexAttribDivisor(program_sphere->attributeLocation("radius"), 1);
viewer->glVertexAttribDivisor(program_sphere->attributeLocation("colors"), 1);
vaos[Wired_spheres]->release();
program_sphere->release();
}
program_sphere->release();
program->release();
are_buffers_filled = true;
}
void Scene_c3t3_item_priv::compute_intersection(const Primitive& facet)
{
{
const Kernel::Point_3& pa = facet.id().first->vertex(0)->point();
const Kernel::Point_3& pb = facet.id().first->vertex(1)->point();
const Kernel::Point_3& pc = facet.id().first->vertex(2)->point();
const Kernel::Point_3& pd = facet.id().first->vertex(3)->point();
QColor color = this->colors[facet.id().first->subdomain_index()].darker(150);
QColor c = this->colors[facet.id().first->subdomain_index()].darker(150);
for(int i=0; i < 12;i++){
item->f_colors.push_back(color.redF());
item->f_colors.push_back(color.greenF());
item->f_colors.push_back(color.blueF());
}
item->draw_triangle(pb, pa, pc, true);
item->draw_triangle(pa, pb, pd, true);
item->draw_triangle(pa, pd, pc, true);
item->draw_triangle(pb, pc, pd, true);
CGAL::Color color(c.red(), c.green(), c.blue());
item->draw_triangle_edges(pb, pa, pc);
item->draw_triangle_edges(pa, pb, pd);
item->draw_triangle_edges(pa, pd, pc);
item->draw_triangle_edges(pb, pc, pd);
item->intersection->addTriangle(pb, pa, pc, color);
item->intersection->addTriangle(pa, pb, pd, color);
item->intersection->addTriangle(pa, pd, pc, color);
item->intersection->addTriangle(pb, pc, pd, color);
{
Tr::Cell_handle nh = facet.id().first->neighbor(facet.id().second);
@ -1135,20 +1081,10 @@ void Scene_c3t3_item_priv::compute_intersection(const Primitive& facet)
const Kernel::Point_3& pc = nh->vertex(2)->point();
const Kernel::Point_3& pd = nh->vertex(3)->point();
for(int i=0; i < 12;i++){
item->f_colors.push_back(color.redF());
item->f_colors.push_back(color.greenF());
item->f_colors.push_back(color.blueF());
}
item->draw_triangle(pb, pa, pc, true);
item->draw_triangle(pa, pb, pd, true);
item->draw_triangle(pa, pd, pc, true);
item->draw_triangle(pb, pc, pd, true);
item->draw_triangle_edges(pb, pa, pc);
item->draw_triangle_edges(pa, pb, pd);
item->draw_triangle_edges(pa, pd, pc);
item->draw_triangle_edges(pb, pc, pd);
item->intersection->addTriangle(pb, pa, pc, color);
item->intersection->addTriangle(pa, pb, pd, color);
item->intersection->addTriangle(pa, pd, pc, color);
item->intersection->addTriangle(pb, pc, pd, color);
}
}
@ -1180,6 +1116,44 @@ void Scene_c3t3_item::compute_intersections()
boost::make_function_output_iterator(Compute_intersection(*this->d)));
}
void Scene_c3t3_item::compute_spheres()
{
if(!spheres)
return;
for(Tr::Finite_vertices_iterator
vit = d->c3t3.triangulation().finite_vertices_begin(),
end = d->c3t3.triangulation().finite_vertices_end();
vit != end; ++vit)
{
if(vit->point().weight()==0) continue;
typedef Tr::Vertex_handle Vertex_handle;
std::vector<Vertex_handle> incident_vertices;
d->c3t3.triangulation().incident_vertices(vit, std::back_inserter(incident_vertices));
bool red = vit->is_special();
for(std::vector<Vertex_handle>::const_iterator
vvit = incident_vertices.begin(), end = incident_vertices.end();
vvit != end; ++vvit)
{
if(Kernel::Sphere_3(vit->point().point(),
vit->point().weight()).bounded_side((*vvit)->point().point())
== CGAL::ON_BOUNDED_SIDE)
red = true;
}
QColor c;
if(red)
c = QColor(Qt::red);
else
c = spheres->color().darker(250);
Kernel::Point_3 center(vit->point().point().x(),
vit->point().point().y(),
vit->point().point().z());
float radius = CGAL::sqrt(vit->point().weight());
Kernel::Sphere_3* sphere = new Kernel::Sphere_3(center, radius);
spheres->add_sphere(sphere, CGAL::Color(c.red(), c.green(), c.blue()));
}
spheres->invalidateOpenGLBuffers();
}
void Scene_c3t3_item::compute_elements()
{
@ -1242,57 +1216,15 @@ void Scene_c3t3_item::compute_elements()
f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF());
f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF());
f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF());
if ((index % 2 == 1) == c3t3().is_in_complex(cell)) draw_triangle(pb, pa, pc, false);
else draw_triangle(pa, pb, pc, false);
if ((index % 2 == 1) == c3t3().is_in_complex(cell)) draw_triangle(pb, pa, pc);
else draw_triangle(pa, pb, pc);
draw_triangle_edges(pa, pb, pc);
}
}
//The Spheres
{
for(Tr::Finite_vertices_iterator
vit = d->c3t3.triangulation().finite_vertices_begin(),
end = d->c3t3.triangulation().finite_vertices_end();
vit != end; ++vit)
{
if(vit->point().weight()==0) continue;
typedef Tr::Vertex_handle Vertex_handle;
std::vector<Vertex_handle> incident_vertices;
d->c3t3.triangulation().incident_vertices(vit, std::back_inserter(incident_vertices));
bool red = vit->is_special();
for(std::vector<Vertex_handle>::const_iterator
vvit = incident_vertices.begin(), end = incident_vertices.end();
vvit != end; ++vvit)
{
if(Kernel::Sphere_3(vit->point().point(),
vit->point().weight()).bounded_side((*vvit)->point().point())
== CGAL::ON_BOUNDED_SIDE)
red = true;
}
if(red){
s_colors.push_back(1.0);
s_colors.push_back(0.0);
s_colors.push_back(0.0);
}
else{
QColor c = this->color().darker(250);
s_colors.push_back(c.redF());
s_colors.push_back(c.greenF());
s_colors.push_back(c.blueF());
}
s_center.push_back(vit->point().point().x());
s_center.push_back(vit->point().point().y());
s_center.push_back(vit->point().point().z());
s_radius.push_back(CGAL::sqrt(vit->point().weight()));
}
}
}
bool Scene_c3t3_item::load_binary(std::istream& is)
{
if(!CGAL::Mesh_3::load_binary_file(is, c3t3())) return false;
@ -1329,3 +1261,51 @@ Scene_c3t3_item::setColor(QColor c)
// function and the intersection is not drawn before the next draw call
are_intersection_buffers_filled = false;
}
void Scene_c3t3_item::show_spheres(bool b)
{
spheres_are_shown = b;
if(b && !spheres)
{
spheres = new Scene_spheres_item(this, true);
spheres->setName("Protecting spheres");
spheres->setRenderingMode(Gouraud);
connect(spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres()));
scene->addItem(spheres);
scene->changeGroup(spheres, this);
lockChild(spheres);
compute_spheres();
}
else if (!b && spheres!=NULL)
{
unlockChild(spheres);
scene->erase(scene->item_id(spheres));
}
Q_EMIT redraw();
}
void Scene_c3t3_item::show_intersection(bool b)
{
if(b && !intersection)
{
intersection = new Scene_intersection_item(this);
intersection->init_vectors(&positions_poly,
&normals,
&positions_lines,
&f_colors);
intersection->setName("Intersection tetrahedra");
intersection->setRenderingMode(renderingMode());
connect(intersection, SIGNAL(destroyed()), this, SLOT(reset_intersection_item()));
scene->addItem(intersection);
scene->changeGroup(intersection, this);
lockChild(intersection);
are_intersection_buffers_filled = false;
}
else if (!b && intersection!=NULL)
{
unlockChild(intersection);
scene->erase(scene->item_id(intersection));
}
Q_EMIT redraw();
}
#include "Scene_c3t3_item.moc"

View File

@ -19,17 +19,17 @@
#include <QOpenGLShaderProgram>
#include <CGAL/Three/Viewer_interface.h>
#include <CGAL/Three/Scene_item.h>
#include <CGAL/Three/Scene_group_item.h>
#include <Scene_polyhedron_item.h>
#include <Scene_polygon_soup_item.h>
#include <CGAL/IO/File_binary_mesh_3.h>
struct Scene_c3t3_item_priv;
class Scene_spheres_item;
class Scene_intersection_item;
using namespace CGAL::Three;
class SCENE_C3T3_ITEM_EXPORT Scene_c3t3_item
: public Scene_item
: public Scene_group_item
{
Q_OBJECT
public:
@ -86,8 +86,12 @@ public:
&& c3t3().number_of_cells_in_complex() == 0 );
}
void compute_bbox() const;
void compute_bbox() const;
Scene_item::Bbox bbox() const
{
return Scene_item::bbox();
}
Scene_c3t3_item* clone() const {
return 0;
}
@ -102,7 +106,7 @@ public:
// Indicate if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const {
return (m != Gouraud && m != PointsPlusNormals && m != Splatting);
return (m != Gouraud && m != PointsPlusNormals && m != Splatting && m != Points);
}
void draw(CGAL::Three::Viewer_interface* viewer) const;
@ -114,7 +118,7 @@ private:
void reset_cut_plane();
void draw_triangle(const Kernel::Point_3& pa,
const Kernel::Point_3& pb,
const Kernel::Point_3& pc, bool /* is_cut */) const;
const Kernel::Point_3& pc) const;
void draw_triangle_edges(const Kernel::Point_3& pa,
const Kernel::Point_3& pb,
@ -129,12 +133,17 @@ private:
void data_item_destroyed();
void show_spheres(bool b)
void reset_spheres()
{
spheres_are_shown = b;
Q_EMIT redraw();
spheres = NULL;
}
void reset_intersection_item()
{
intersection = NULL;
}
void show_spheres(bool b);
void show_intersection(bool b);
virtual QPixmap graphicalToolTip() const;
void update_histogram();
@ -151,8 +160,6 @@ private:
public:
QMenu* contextMenu();
void set_scene(CGAL::Three::Scene_interface* scene){ last_known_scene = scene; }
protected:
friend struct Scene_c3t3_item_priv;
@ -170,12 +177,6 @@ private:
Facet_colors,
Edges_vertices,
Grid_vertices,
Sphere_vertices,
Sphere_normals,
Sphere_colors,
Sphere_radius,
Sphere_center,
Wired_spheres_vertices,
iEdges_vertices,
iFacet_vertices,
iFacet_normals,
@ -187,15 +188,14 @@ private:
Facets=0,
Edges,
Grid,
Spheres,
Wired_spheres,
iEdges,
iFacets,
NumberOfVaos
};
qglviewer::ManipulatedFrame* frame;
CGAL::Three::Scene_interface* last_known_scene;
Scene_spheres_item *spheres;
Scene_intersection_item *intersection;
bool spheres_are_shown;
const Scene_item* data_item_;
QPixmap histogram_;
@ -226,14 +226,13 @@ private:
mutable std::vector<float> s_radius;
mutable std::vector<float> s_center;
mutable QOpenGLShaderProgram *program;
mutable QOpenGLShaderProgram *program_sphere;
using Scene_item::initialize_buffers;
void initialize_buffers(CGAL::Three::Viewer_interface *viewer);
void initialize_intersection_buffers(CGAL::Three::Viewer_interface *viewer);
void compute_spheres();
void compute_elements();
void compute_intersections();
void compile_shaders();
};
#endif // SCENE_C3T3_ITEM_H

View File

@ -3,11 +3,13 @@
#include <QDebug>
using namespace CGAL::Three;
Scene_group_item::Scene_group_item(QString name)
: Scene_item(0,0)
Scene_group_item::Scene_group_item(QString name, int nb_vbos, int nb_vaos )
: Scene_item(nb_vbos, nb_vaos)
, scene(NULL)
{
this->name_ = name;
expanded = true;
already_drawn = false;
}
bool Scene_group_item::isFinite() const
@ -53,20 +55,20 @@ void Scene_group_item::addChild(Scene_item* new_item)
if(!children.contains(new_item))
{
children.append(new_item);
add_group_number(new_item);
update_group_number(new_item, has_group+1);
}
}
void Scene_group_item::add_group_number(Scene_item * new_item)
void Scene_group_item::update_group_number(Scene_item * new_item, int n)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(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)
{
@ -82,7 +84,8 @@ void Scene_group_item::setRenderingMode(RenderingMode m)
Scene_item::setRenderingMode(m);
Q_FOREACH(Scene_item* child, children)
{
child->setRenderingMode(m);
if(child->supportsRenderingMode(m))
child->setRenderingMode(m);
}
}
@ -118,7 +121,7 @@ void Scene_group_item::moveUp(int i)
}
void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const {
if(viewer->inDrawWithNames()) return;
if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) {
if(!child->visible()) continue;
switch(child->renderingMode()) {
@ -128,12 +131,26 @@ void Scene_group_item::draw(CGAL::Three::Viewer_interface* viewer) const {
child->draw(viewer); break;
default: break;
}
switch(child->renderingMode()) {
case FlatPlusEdges:
case Wireframe:
case PointsPlusNormals:
child->draw_edges(viewer); break;
default: break;
}
switch(child->renderingMode()) {
case Points:
case PointsPlusNormals:
child->draw_points(viewer); break;
default: break;
}
}
already_drawn = true;
}
void Scene_group_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const
{
if(viewer->inDrawWithNames()) return;
if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) {
if(!child->visible()) continue;
switch(child->renderingMode()) {
@ -143,12 +160,26 @@ void Scene_group_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const
child->draw_edges(viewer); break;
default: break;
}
switch(child->renderingMode()) {
case Flat:
case FlatPlusEdges:
case Gouraud:
child->draw(viewer); break;
default: break;
}
switch(child->renderingMode()) {
case Points:
case PointsPlusNormals:
child->draw_points(viewer); break;
default: break;
}
}
already_drawn = true;
}
void Scene_group_item::draw_points(CGAL::Three::Viewer_interface* viewer) const
{
if(viewer->inDrawWithNames()) return;
if(viewer->inDrawWithNames() || already_drawn ) return;
Q_FOREACH(Scene_item* child, children) {
if(!child->visible()) continue;
switch(child->renderingMode()) {
@ -157,7 +188,22 @@ void Scene_group_item::draw_points(CGAL::Three::Viewer_interface* viewer) const
child->draw_points(viewer); break;
default: break;
}
switch(child->renderingMode()) {
case Flat:
case FlatPlusEdges:
case Gouraud:
child->draw(viewer); break;
default: break;
}
switch(child->renderingMode()) {
case FlatPlusEdges:
case Wireframe:
case PointsPlusNormals:
child->draw_edges(viewer); break;
default: break;
}
}
already_drawn = true;
}
void Scene_group_item::draw_splats(CGAL::Three::Viewer_interface* viewer) const
@ -168,3 +214,23 @@ void Scene_group_item::draw_splats(CGAL::Three::Viewer_interface* viewer) const
child->draw_splats(viewer);
}
}
void Scene_group_item::lockChild(Scene_item *child)
{
if(!children.contains(child))
return;
child->setProperty("lock", true);
}
void Scene_group_item::unlockChild(Scene_item *child)
{
if(!children.contains(child))
return;
child->setProperty("lock", false);
}
bool Scene_group_item::isChildLocked(Scene_item *child)
{
if(!children.contains(child)
|| (!child->property("lock").toBool()) )
return false;
return true;
}

View File

@ -986,8 +986,8 @@ Scene_polyhedron_item::setColor(QColor c)
// reset patch ids
if (colors_.size()>2 || plugin_has_set_color_vector_m)
{
colors_.clear();
is_monochrome = true;
colors_.clear();
is_monochrome = true;
}
Scene_item::setColor(c);
}

View File

@ -1,11 +1,10 @@
#include "Scene_polylines_item.h"
#include "create_sphere.h"
#include "Scene_spheres_item.h"
#include <CGAL/bounding_box.h>
#include <CGAL/gl.h>
#include <QMenu>
#include <QAction>
#include <QInputDialog>
class Scene_polylines_item_private {
@ -18,18 +17,10 @@ public:
spheres_drawn_radius(0)
{}
void draw_sphere(const K::Point_3&, double) const;
void draw_spheres(const Scene_polylines_item*) const;
bool draw_extremities;
double spheres_drawn_radius;
};
void
Scene_polylines_item::create_Sphere(float R) const
{
create_flat_and_wire_sphere(R, positions_spheres, normals_spheres, positions_wire_spheres);
}
void
Scene_polylines_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer = 0) const
@ -49,143 +40,17 @@ Scene_polylines_item::initialize_buffers(CGAL::Three::Viewer_interface *viewer =
buffers[Edges_Vertices].release();
vaos[Edges]->release();
program->release();
nb_lines = positions_lines.size();
positions_lines.clear();
positions_lines.swap(positions_lines);
}
//vao for the spheres
{
if(viewer->extension_is_found)
{
program = getShaderProgram(PROGRAM_INSTANCED, viewer);
program->bind();
vaos[Spheres]->bind();
buffers[Spheres_Vertices].bind();
buffers[Spheres_Vertices].allocate(positions_spheres.data(),
static_cast<int>(positions_spheres.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
buffers[Spheres_Vertices].release();
buffers[Spheres_Normals].bind();
buffers[Spheres_Normals].allocate(normals_spheres.data(),
static_cast<int>(normals_spheres.size()*sizeof(float)));
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals",GL_FLOAT,0,3);
buffers[Spheres_Normals].release();
buffers[Spheres_Colors].bind();
buffers[Spheres_Colors].allocate(color_spheres.data(),
static_cast<int>(color_spheres.size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors",GL_FLOAT,0,3);
buffers[Spheres_Colors].release();
buffers[Spheres_Center].bind();
buffers[Spheres_Center].allocate(positions_center.data(),
static_cast<int>(positions_center.size()*sizeof(float)));
program->enableAttributeArray("center");
program->setAttributeBuffer("center",GL_FLOAT,0,3);
buffers[Spheres_Center].release();
viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1);
}
else
{
program = getShaderProgram(PROGRAM_NO_SELECTION, viewer);
program->bind();
vaos[Spheres]->bind();
buffers[Spheres_Vertices].bind();
buffers[Spheres_Vertices].allocate(positions_center.data(),
static_cast<int>(positions_center.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
buffers[Spheres_Vertices].release();
buffers[Spheres_Normals].bind();
buffers[Spheres_Normals].allocate(color_spheres.data(),
static_cast<int>(color_spheres.size()*sizeof(float)));
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors",GL_FLOAT,0,3);
buffers[Spheres_Normals].release();
}
vaos[Spheres]->release();
program->release();
}
//vao for the wired spheres
{
if(viewer->extension_is_found)
{
program = getShaderProgram(PROGRAM_INSTANCED_WIRE, viewer);
program->bind();
vaos[Wired_Spheres]->bind();
buffers[Wired_Spheres_Vertices].bind();
buffers[Wired_Spheres_Vertices].allocate(positions_wire_spheres.data(),
static_cast<int>(positions_wire_spheres.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
buffers[Wired_Spheres_Vertices].release();
buffers[Spheres_Colors].bind();
program->enableAttributeArray("colors");
program->setAttributeBuffer("colors",GL_FLOAT,0,3);
buffers[Spheres_Colors].release();
buffers[Spheres_Normals].bind();
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals",GL_FLOAT,0,3);
buffers[Spheres_Normals].release();
buffers[Spheres_Center].bind();
program->enableAttributeArray("center");
program->setAttributeBuffer("center",GL_FLOAT,0,3);
buffers[Spheres_Center].release();
viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1);
viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1);
vaos[Wired_Spheres]->release();
program->release();
nb_lines = positions_lines.size();
positions_lines.resize(0);
std::vector<float>(positions_lines).swap(positions_lines);
nb_spheres = positions_spheres.size();
positions_spheres.resize(0);
std::vector<float>(positions_spheres).swap(positions_spheres);
normals_spheres.resize(0);
std::vector<float>(normals_spheres).swap(normals_spheres);
color_spheres.resize(0);
std::vector<float>(color_spheres).swap(color_spheres);
nb_centers = positions_center.size();
positions_center.resize(0);
std::vector<float>(positions_center).swap(positions_center);
nb_wire = positions_wire_spheres.size();
positions_wire_spheres.resize(0);
std::vector<float>(positions_wire_spheres).swap(positions_wire_spheres);
}
}
are_buffers_filled = true;
}
void
Scene_polylines_item::compute_elements() const
{
positions_spheres.resize(0);
positions_wire_spheres.resize(0);
positions_lines.resize(0);
color_spheres.resize(0);
normals_spheres.resize(0);
positions_center.resize(0);
nbSpheres = 0;
//Fills the VBO with the lines
for(std::list<std::vector<Point_3> >::const_iterator it = polylines.begin();
it != polylines.end();
@ -205,132 +70,115 @@ Scene_polylines_item::compute_elements() const
positions_lines.push_back(b.y());
positions_lines.push_back(b.z());
positions_lines.push_back(1.0);
}
}
//Fills the VBO with the spheres
if(d->draw_extremities)
{
// FIRST, count the number of incident cycles and polylines
// for all extremities.
typedef std::map<Point_3, int> Point_to_int_map;
typedef Point_to_int_map::iterator iterator;
Point_to_int_map corner_polyline_nb;
{ // scope to fill corner_polyline_nb'
Point_to_int_map corner_cycles_nb;
for(std::list<std::vector<Point_3> >::const_iterator
it = this->polylines.begin(),
end = this->polylines.end();
it != end; ++it)
{
const K::Point_3& a = *it->begin();
const K::Point_3& b = *it->rbegin();
if(a == b) {
if ( it->size()>1 )
++corner_cycles_nb[a];
else
++corner_polyline_nb[a];
}
else {
++corner_polyline_nb[a];
++corner_polyline_nb[b];
}
}
// THEN, ignore points that are incident to one cycle only.
for(iterator
c_it = corner_cycles_nb.begin(),
end = corner_cycles_nb.end();
c_it != end; ++c_it)
{
const Point_3& a = c_it->first;
iterator p_it = corner_polyline_nb.find(a);
// If the point 'a'=c_it->first has only incident cycles...
if(p_it == corner_polyline_nb.end()) {
// ...then count it as a corner only if it has two incident cycles
// or more.
if(c_it->second > 1) {
corner_polyline_nb[a] = c_it->second;
}
} else {
// else add the number of cycles.
p_it->second += c_it->second;
}
}
}
// At this point, 'corner_polyline_nb' gives the multiplicity of all
// corners.
//Finds the centers of the spheres and their color
for(iterator
p_it = corner_polyline_nb.begin(),
end = corner_polyline_nb.end();
p_it != end; ++p_it)
{
nbSpheres++;
const K::Point_3& centre = p_it->first;
positions_center.push_back(centre.x());
positions_center.push_back(centre.y());
positions_center.push_back(centre.z());
float colors[3];
switch(p_it->second) {
case 1:
colors[0] = 0.0; // black
colors[1] = 0.0;
colors[2] = 0.0;
break;
case 2:
colors[0] = 0.0; // green
colors[1] = 0.8f;
colors[2] = 0.0;
break;
case 3:
colors[0] = 0.0; // blue
colors[1] = 0.0;
colors[2] = 0.8f;
break;
case 4:
colors[0] = 0.8f; //red
colors[1] = 0.0;
colors[2] = 0.0;
break;
default:
colors[0] = 0.8f; //fuschia
colors[1] = 0.0;
colors[2] = 0.8f;
}
color_spheres.push_back(colors[0]);
color_spheres.push_back(colors[1]);
color_spheres.push_back(colors[2]);
color_wire_spheres.push_back(colors[0]);
color_wire_spheres.push_back(colors[1]);
color_wire_spheres.push_back(colors[2]);
color_wire_spheres.push_back(colors[0]);
color_wire_spheres.push_back(colors[1]);
color_wire_spheres.push_back(colors[2]);
}
create_Sphere(d->spheres_drawn_radius);
}
}
void
Scene_polylines_item::compute_spheres()
{
// FIRST, count the number of incident cycles and polylines
// for all extremities.
typedef std::map<Point_3, int> Point_to_int_map;
typedef Point_to_int_map::iterator iterator;
Point_to_int_map corner_polyline_nb;
{ // scope to fill corner_polyline_nb'
Point_to_int_map corner_cycles_nb;
for(std::list<std::vector<Point_3> >::const_iterator
it = this->polylines.begin(),
end = this->polylines.end();
it != end; ++it)
{
const K::Point_3& a = *it->begin();
const K::Point_3& b = *it->rbegin();
if(a == b) {
if ( it->size()>1 )
++corner_cycles_nb[a];
else
++corner_polyline_nb[a];
}
else {
++corner_polyline_nb[a];
++corner_polyline_nb[b];
}
}
// THEN, ignore points that are incident to one cycle only.
for(iterator
c_it = corner_cycles_nb.begin(),
end = corner_cycles_nb.end();
c_it != end; ++c_it)
{
const Point_3& a = c_it->first;
iterator p_it = corner_polyline_nb.find(a);
// If the point 'a'=c_it->first has only incident cycles...
if(p_it == corner_polyline_nb.end()) {
// ...then count it as a corner only if it has two incident cycles
// or more.
if(c_it->second > 1) {
corner_polyline_nb[a] = c_it->second;
}
} else {
// else add the number of cycles.
p_it->second += c_it->second;
}
}
}
// At this point, 'corner_polyline_nb' gives the multiplicity of all
// corners.
//Finds the centers of the spheres and their color
for(iterator
p_it = corner_polyline_nb.begin(),
end = corner_polyline_nb.end();
p_it != end; ++p_it)
{
const K::Point_3& center = p_it->first;
int colors[3];
switch(p_it->second) {
case 1:
colors[0] = 0; // black
colors[1] = 0;
colors[2] = 0;
break;
case 2:
colors[0] = 0; // green
colors[1] = 200;
colors[2] = 0;
break;
case 3:
colors[0] = 0; // blue
colors[1] = 0;
colors[2] = 200;
break;
case 4:
colors[0] = 200; //red
colors[1] = 0;
colors[2] = 0;
break;
default:
colors[0] = 200; //fuschia
colors[1] = 0;
colors[2] = 200;
}
CGAL::Color c(colors[0], colors[1], colors[2]);
K::Sphere_3 *sphere = new K::Sphere_3(center, d->spheres_drawn_radius);
spheres->add_sphere(sphere, c);
}
}
Scene_polylines_item::Scene_polylines_item()
:CGAL::Three::Scene_item(NbOfVbos,NbOfVaos)
:CGAL::Three::Scene_group_item("unnamed",NbOfVbos,NbOfVaos)
,d(new Scene_polylines_item_private())
,nbSpheres(0)
{
setRenderingMode(FlatPlusEdges);
nb_spheres = 0;
nb_wire = 0;
nb_centers = 0;
nb_lines = 0;
spheres = NULL;
invalidateOpenGLBuffers();
}
@ -430,30 +278,7 @@ Scene_polylines_item::draw(CGAL::Three::Viewer_interface* viewer) const {
}
if(d->draw_extremities)
{
if(viewer->extension_is_found)
{
vaos[Spheres]->bind();
QOpenGLShaderProgram* program = getShaderProgram(PROGRAM_INSTANCED);
attrib_buffers(viewer, PROGRAM_INSTANCED);
program->bind();
viewer->glDrawArraysInstanced(GL_TRIANGLES, 0,
static_cast<GLsizei>(nb_spheres/3), nbSpheres);
program->release();
vaos[Spheres]->release();
}
else
{
vaos[Spheres]->bind();
QOpenGLShaderProgram* program = getShaderProgram(PROGRAM_NO_SELECTION);
attrib_buffers(viewer, PROGRAM_NO_SELECTION);
glPointSize(8.0f);
glEnable(GL_POINT_SMOOTH);
program->bind();
viewer->glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(nb_centers/3));
glDisable(GL_POINT_SMOOTH);
program->release();
vaos[Spheres]->release();
}
Scene_group_item::draw(viewer);
}
}
@ -476,17 +301,7 @@ Scene_polylines_item::draw_edges(CGAL::Three::Viewer_interface* viewer) const {
vaos[Edges]->release();
if(d->draw_extremities)
{
if(viewer->extension_is_found)
{
vaos[Wired_Spheres]->bind();
attrib_buffers(viewer, PROGRAM_INSTANCED_WIRE);
program = getShaderProgram(PROGRAM_INSTANCED_WIRE);
program->bind();
viewer->glDrawArraysInstanced(GL_LINES, 0,
static_cast<GLsizei>(nb_wire/3), nbSpheres);
program->release();
vaos[Wired_Spheres]->release();
}
Scene_group_item::draw_edges(viewer);
}
}
@ -509,6 +324,10 @@ Scene_polylines_item::draw_points(CGAL::Three::Viewer_interface* viewer) const {
// Clean-up
vaos[Edges]->release();
program->release();
if(d->draw_extremities)
{
Scene_group_item::draw_points(viewer);
}
}
QMenu* Scene_polylines_item::contextMenu()
@ -575,7 +394,23 @@ void Scene_polylines_item::change_corner_radii(double r) {
if(r >= 0) {
d->spheres_drawn_radius = r;
d->draw_extremities = (r > 0);
this->invalidateOpenGLBuffers();
if(r>0 && !spheres)
{
spheres = new Scene_spheres_item(this, false);
spheres->setName("Corner spheres");
spheres->setRenderingMode(Gouraud);
connect(spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres()));
scene->addItem(spheres);
scene->changeGroup(spheres, this);
lockChild(spheres);
compute_spheres();
spheres->invalidateOpenGLBuffers();
}
else if (r<=0 && spheres!=NULL)
{
unlockChild(spheres);
scene->erase(scene->item_id(spheres));
}
Q_EMIT itemChanged();
}
}

View File

@ -3,7 +3,7 @@
#include "Scene_polylines_item_config.h"
#include <CGAL/Three/Viewer_interface.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Three/Scene_item.h>
#include <CGAL/Three/Scene_group_item.h>
#include <QString>
#include <QMenu>
@ -12,8 +12,9 @@
#include <vector>
class Scene_polylines_item_private;
class Scene_spheres_item;
class SCENE_POLYLINES_ITEM_EXPORT Scene_polylines_item : public CGAL::Three::Scene_item
class SCENE_POLYLINES_ITEM_EXPORT Scene_polylines_item : public CGAL::Three::Scene_group_item
{
Q_OBJECT
public:
@ -76,6 +77,10 @@ public Q_SLOTS:
void change_corner_radii(double);
void change_corner_radii();
void split_at_sharp_angles();
void reset_spheres()
{
spheres = NULL;
}
void merge(Scene_polylines_item*);
@ -94,39 +99,24 @@ private:
enum VAOs {
Edges=0,
Spheres,
Wired_Spheres,
NbOfVaos = Wired_Spheres+1
NbOfVaos
};
enum VBOs {
Edges_Vertices = 0,
Spheres_Vertices,
Spheres_Normals,
Spheres_Colors,
Spheres_Center,
Wired_Spheres_Vertices,
NbOfVbos = Wired_Spheres_Vertices+1
NbOfVbos
};
mutable Scene_spheres_item *spheres;
mutable std::vector<float> positions_lines;
mutable std::vector<float> positions_spheres;
mutable std::vector<float> positions_wire_spheres;
mutable std::vector<float> positions_center;
mutable std::vector<float> normals_spheres;
mutable std::vector<float> color_spheres;
mutable std::vector<float> color_wire_spheres;
mutable std::size_t nb_spheres;
mutable std::size_t nb_wire;
mutable std::size_t nb_centers;
mutable std::size_t nb_lines;
mutable GLuint nbSpheres;
typedef std::map<Point_3, int> Point_to_int_map;
typedef Point_to_int_map::iterator iterator;
void create_Sphere(float) const;
using CGAL::Three::Scene_item::initialize_buffers;
void initialize_buffers(CGAL::Three::Viewer_interface *viewer) const;
using CGAL::Three::Scene_item::compute_elements;
void compute_elements() const;
void compute_spheres();

View File

@ -0,0 +1,211 @@
#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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<GLsizei>(vertices.size()/3),
static_cast<GLsizei>(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<GLsizei>(edges.size()/3),
static_cast<GLsizei>(nb_centers));
program->release();
vaos[Edges]->release();
}
void Scene_spheres_item::add_sphere(CGAL::Sphere_3<Kernel> *sphere, CGAL::Color color)
{
Sphere_pair pair_(sphere, color);
spheres.append(pair_);
}
void Scene_spheres_item::remove_sphere(CGAL::Sphere_3<Kernel> *sphere)
{
Q_FOREACH(Sphere_pair pair_, spheres)
if(pair_.first == sphere)
{
spheres.removeAll(pair_);
break;
}
}
void Scene_spheres_item::clear_spheres()
{
spheres.clear();
}

View File

@ -0,0 +1,98 @@
#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 <CGAL/Three/Scene_item.h>
#include <CGAL/Three/Scene_interface.h>
#include <CGAL/Three/Viewer_interface.h>
#include <CGAL/Sphere_3.h>
#include <CGAL/Plane_3.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <QOpenGLShaderProgram>
#include <QList>
#include <vector>
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::Sphere_3<Kernel>*, 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<Kernel>* sphere, CGAL::Color = CGAL::Color(120,120,120));
void remove_sphere(CGAL::Sphere_3<Kernel>* sphere);
void clear_spheres();
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<Kernel> plane;
bool has_plane;
QList<Sphere_pair> spheres;
mutable std::vector<float> vertices;
mutable std::vector<float> normals;
mutable std::vector<float> edges;
mutable std::vector<float> colors;
mutable std::vector<float> edges_colors;
mutable std::vector<float> centers;
mutable std::vector<float> radius;
mutable QOpenGLShaderProgram *program;
mutable int nb_centers;
void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const;
};
#endif // SCENE_SPHERES_ITEM_H

View File

@ -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"<<std::endl;
}
if(!program->addShaderFromSourceFile(QOpenGLShader::Fragment,":/cgal/Polyhedron_3/resources/shader_c3t3.f" ))
{
std::cerr<<"adding fragment shader FAILED"<<std::endl;
}
program->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"<<std::endl;
}
if(!program->addShaderFromSourceFile(QOpenGLShader::Fragment,":/cgal/Polyhedron_3/resources/shader_with_light.f" ))
{
std::cerr<<"adding fragment shader FAILED"<<std::endl;
}
program->bindAttributeLocation("colors", 1);
program->link();
d->shader_programs[PROGRAM_SPHERES] = program;
return program;
}
break;
default:
std::cerr<<"ERROR : Program not found."<<std::endl;
return 0;

View File

@ -0,0 +1,21 @@
#version 120
attribute highp vec4 vertex;
attribute highp vec3 normals;
attribute highp vec3 colors;
attribute highp vec3 center;
attribute highp float radius;
uniform highp mat4 mvp_matrix;
uniform highp mat4 mv_matrix;
varying highp vec4 fP;
varying highp vec3 fN;
varying highp vec4 color;
void main(void)
{
color = vec4(colors, 1.0);
fP = mv_matrix * vertex;
fN = mat3(mv_matrix)* normals;
gl_Position = mvp_matrix *
vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0) ;
}

View File

@ -23,6 +23,7 @@
#define SCENE_GROUP_ITEM_H
#include <CGAL/Three/Scene_item.h>
#include <CGAL/Three/Scene_interface.h>
using namespace CGAL::Three;
#include <QtCore/qglobal.h>
@ -40,12 +41,30 @@ class DEMO_FRAMEWORK_EXPORT Scene_group_item : public Scene_item
{
Q_OBJECT
public :
Scene_group_item(QString name = QString("New group"));
Scene_group_item(QString name = QString("New group"), int nb_vbos = 0, int nb_vaos = 0);
~Scene_group_item() {}
//!Sets the scene;
void setScene(Scene_interface* s) { scene = s; }
//!Returns false to avoid disturbing the BBox of the scene.
bool isFinite() const;
//!Returns true to avoid disturbing the BBox of the scene.
bool isEmpty() const ;
/*!
* \brief Locks a child
* A locked child cannot be moved out of the group nor can it be deleted.
*/
void lockChild(CGAL::Three::Scene_item*);
/*!
* \brief Unlocks a child
* @see lockChild()
*/
void unlockChild(CGAL::Three::Scene_item*);
/*!
* \brief Tells if a child is locked.
* \return true if the child is locked.
* @see lockChild()
*/
bool isChildLocked(CGAL::Three::Scene_item*);
//!Returns if the group_item is currently expanded or collapsed in the view.
//! True means expanded, false means collapsed.
//! @see setExpanded.
@ -122,12 +141,9 @@ public :
//!@see getChildren @see addChild
void removeChild( Scene_item* item)
{
Scene_group_item* group =
qobject_cast<Scene_group_item*>(item);
if(group)
Q_FOREACH(Scene_item* child, group->getChildren())
removeChild(child);
item->has_group=0;
if(isChildLocked(item))
return;
update_group_number(item,0);
children.removeOne(item);
}
//!Moves a child up in the list.
@ -135,12 +151,19 @@ public :
//!Moves a child down in the list.
void moveDown(int);
public Q_SLOTS:
void resetDraw() { already_drawn = false;}
private:
//!Updates the property has_group for each group and sub-groups containing new_item.
void update_group_number(Scene_item*new_item, int n);
bool expanded;
mutable bool already_drawn;
protected:
Scene_interface *scene;
//!Contains a reference to all the children of this group.
QList<Scene_item*> children;
//!Updates the property has_group for each group and sub-groups containing new_item.
void add_group_number(Scene_item*new_item);
bool expanded;
}; //end of class Scene_group_item

View File

@ -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;

View File

@ -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.*/
};