From e67a747a5c97cbf3adc26e85d461c98591f3ae9a Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 3 Jul 2020 15:46:13 +0200 Subject: [PATCH] WIP t3_item --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 1 + .../demo/Polyhedron/Plugins/IO/CMakeLists.txt | 3 +- .../Plugins/IO/triangulation_3_io_plugin.cpp | 55 +- .../demo/Polyhedron/Scene_c3t3_item.cpp | 2 +- Polyhedron/demo/Polyhedron/Scene_c3t3_item.h | 2 - .../Polyhedron/Scene_triangulation_3_item.cpp | 727 ++++++++++++++++++ .../Polyhedron/Scene_triangulation_3_item.h | 84 ++ Polyhedron/demo/Polyhedron/T3_type.h | 7 + 8 files changed, 862 insertions(+), 19 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp create mode 100644 Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h create mode 100644 Polyhedron/demo/Polyhedron/T3_type.h diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index d3e8ff9837b..5f04e286517 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -334,6 +334,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND) scene_points_with_normal_item) add_item(scene_lcc_item Scene_lcc_item.cpp) + add_item(scene_triangulation_3_item Scene_triangulation_3_item.cpp) foreach(lib demo_framework scene_basic_objects scene_color_ramp scene_polygon_soup_item scene_nef_polyhedron_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index dc89b5a8f5d..c841c39794d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -51,8 +51,7 @@ set_package_properties( PURPOSE "Can be used for I/O (DICOM, VTU, VTP.") polyhedron_demo_plugin(triangulation_3_io_plugin triangulation_3_io_plugin KEYWORDS IO) -#todo -#target_link_libraries(triangulation_3_io_plugin PUBLIC scene_triangulation_3_item) +target_link_libraries(triangulation_3_io_plugin PUBLIC scene_triangulation_3_item) if(VTK_FOUND) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/triangulation_3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/triangulation_3_io_plugin.cpp index dc677fe5df7..71008c5c8aa 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/triangulation_3_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/triangulation_3_io_plugin.cpp @@ -1,8 +1,9 @@ #include #include - +#include "T3_type.h" #include #include +#include "Scene_triangulation_3_item.h" class Triangulation_3_io_plugin : public QObject, @@ -27,20 +28,47 @@ public: //todo: same QString saveNameFilters() const override{ - return ""; + return ".tr_tst"; } //todo bool canLoad(QFileInfo) const override{ return true; } QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override{ + // Open file - std::ifstream ifs(fileinfo.filePath().toUtf8()); - if(!ifs) { - std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; - ok = false; - return QList(); + //std::ifstream ifs(fileinfo.filePath().toUtf8()); + //if(!ifs) { + // std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; + // ok = false; + // Scene_triangulation_3_item* new_item = new Scene_triangulation_3_item(); + // return QList(); + //} + + //temp { + T3* tr = new Tr(); + CGAL::Random rng; + typedef T3::Point Point; + typedef T3::Cell_handle Cell_handle; + + while (tr->number_of_vertices() < 20) + tr->insert(Point(rng.get_double(-1., 1.), rng.get_double(-1., 1.), rng.get_double(-1., 1.))); + + const typename T3::Geom_traits::Plane_3 + plane(Point_3(0, 0, 0), Point_3(0, 1, 0), Point_3(0, 0, 1)); + + for (Cell_handle c : tr->finite_cell_handles()) + { + if (plane.has_on_positive_side( + CGAL::centroid(Point_3(c->vertex(0)->point()), Point_3(c->vertex(1)->point()), + Point_3(c->vertex(2)->point()),Point_3( c->vertex(3)->point())))) + c->set_subdomain_index(1); + else + c->set_subdomain_index(2); } + CGAL_assertion(tr->is_valid(true)); + //} + QString ext = fileinfo.suffix(); bool res = true; @@ -55,14 +83,13 @@ public: ok = false; return QList(); } - //Scene_lcc_item* new_item = new Scene_lcc_item(lcc); + Scene_triangulation_3_item* new_item = new Scene_triangulation_3_item(tr); //new_item->setName(fileinfo.fileName()); - //new_item->invalidateOpenGLBuffers(); - //if(add_to_scene) - // CGAL::Three::Three::scene()->addItem(new_item); - //ok = true; - //return QList()<invalidateOpenGLBuffers(); + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(new_item); + ok = true; + return QList()<(-plane.d()) }; } -// The special Scene_item only for triangles + class Scene_intersection_item : public CGAL::Three::Scene_item_rendering_helper { Q_OBJECT diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h index c34951335b6..6d0f224440c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h @@ -24,8 +24,6 @@ #include 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_group_item, public Scene_item_with_properties diff --git a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp new file mode 100644 index 00000000000..f5ce9300506 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp @@ -0,0 +1,727 @@ +#include "config.h" +#include "Scene_triangulation_3_item.h" +#include +#include +#include +#include + + +using namespace CGAL::Three; +typedef Triangle_container Tc; +typedef Edge_container Ec; +typedef Point_container Pc; +typedef Viewer_interface Vi; + +QVector4D cgal_plane_to_vector4d(EPICK::Plane_3 plane) { + return { + static_cast(-plane.a()), + static_cast(-plane.b()), + static_cast(-plane.c()), + static_cast(-plane.d()) }; +} + +class Scene_intersection_item : public CGAL::Three::Scene_item_rendering_helper +{ + Q_OBJECT +public : + Scene_intersection_item(Scene_triangulation_3_item* parent) + :is_fast(false) + { + setParent(parent); + alphaSlider = NULL; + m_alpha = 1.0f; + setTriangleContainer(0, new Tc(Vi::PROGRAM_C3T3, false)); + setEdgeContainer(0, new Ec(Vi::PROGRAM_NO_SELECTION, false)); + } + bool isFinite() const Q_DECL_OVERRIDE{ return false; } + ~Scene_intersection_item() + { + if(alphaSlider) + delete alphaSlider; + } + void compute_bbox() const Q_DECL_OVERRIDE{} + + void gl_initialization(Vi* viewer) + { + if(!isInit(viewer)) + initGL(viewer); + computeElements(); + initializeBuffers(viewer); + } + void init_vectors( + std::vector *p_vertices, + std::vector *p_normals, + std::vector *p_edges, + std::vector *p_colors, + std::vector *p_bary) + { + vertices = p_vertices; + normals = p_normals; + edges = p_edges; + colors = p_colors; + barycenters = p_bary; + } + void setColor(QColor c) Q_DECL_OVERRIDE + { + qobject_cast(this->parent())->setColor(c); + Scene_item::setColor(c); + } + // Indicates if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE{ + return (m != Gouraud && m != PointsPlusNormals && m != Points && m != ShadedPoints); + } + void computeElements() const Q_DECL_OVERRIDE + { + getTriangleContainer(0)->reset_vbos(ALL); + getEdgeContainer(0)->reset_vbos(ALL); + + getTriangleContainer(0)->allocate(Tc::Flat_vertices, + vertices->data(), static_cast(vertices->size()*sizeof(float))); + getTriangleContainer(0)->allocate(Tc::Flat_normals, normals->data(), + static_cast(normals->size()*sizeof(float))); + getTriangleContainer(0)->allocate(Tc::FColors, colors->data(), + static_cast(colors->size()*sizeof(float))); + getTriangleContainer(0)->allocate(Tc::Facet_centers, barycenters->data(), + static_cast(barycenters->size()*sizeof(float))); + getEdgeContainer(0)->allocate(Ec::Vertices, edges->data(), + static_cast(edges->size()*sizeof(float))); + setBuffersFilled(true); + } + void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const Q_DECL_OVERRIDE + { + //vao containing the data for the facets + { + getTriangleContainer(0)->initializeBuffers(viewer); + getTriangleContainer(0)->setFlatDataSize(vertices->size()); + } + //vao containing the data for the lines + { + getEdgeContainer(0)->initializeBuffers(viewer); + getEdgeContainer(0)->setFlatDataSize(edges->size()); + } + } + + //Displays the item + void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE + { + if(is_fast) + return; + + if(!alphaSlider) + { + alphaSlider = new QSlider(::Qt::Horizontal); + alphaSlider->setMinimum(0); + alphaSlider->setMaximum(255); + alphaSlider->setValue(255); + } + viewer->makeCurrent(); + const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); + QVector4D cp = cgal_plane_to_vector4d(plane); + getTriangleContainer(0)->setPlane(-cp); + getTriangleContainer(0)->setShrinkFactor(1.0); + // positions_poly is also used for the faces in the cut plane + // and changes when the cut plane is moved + getTriangleContainer(0)->setAlpha(alpha()); + getTriangleContainer(0)->draw(viewer, false); + } + void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE + { + if(is_fast) + return; + const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); + QVector4D cp = cgal_plane_to_vector4d(plane); + getEdgeContainer(0)->setPlane(cp); + getEdgeContainer(0)->setColor(QColor(Qt::black)); + getEdgeContainer(0)->draw(viewer, true); + + } + + void setFast(bool b) + { + is_fast = b; + } + + void addTriangle(const Tr::Bare_point& pa, const Tr::Bare_point& pb, + const Tr::Bare_point& pc, const CGAL::Color color) + { + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); + n = n / CGAL::sqrt(n*n); + + auto push_normal = [this](auto n) { + normals->push_back(static_cast(n.x())); + normals->push_back(static_cast(n.y())); + normals->push_back(static_cast(n.z())); + }; + + auto push_vertex = [this, &offset](const auto& p) { + this->vertices->push_back(static_cast(p.x()+offset.x)); + this->vertices->push_back(static_cast(p.y()+offset.y)); + this->vertices->push_back(static_cast(p.z()+offset.z)); + }; + + auto push_edge = [this, &offset](const auto& pa, const auto& pb) { + this->edges->push_back(static_cast(pa.x()+offset.x)); + this->edges->push_back(static_cast(pa.y()+offset.y)); + this->edges->push_back(static_cast(pa.z()+offset.z)); + this->edges->push_back(static_cast(pb.x()+offset.x)); + this->edges->push_back(static_cast(pb.y()+offset.y)); + this->edges->push_back(static_cast(pb.z()+offset.z)); + }; + + for (int i = 0; i<3; i++) + { + push_normal(n); + } + push_vertex(pa); + push_vertex(pb); + push_vertex(pc); + + push_edge(pa, pb); + push_edge(pb, pc); + push_edge(pc, pa); + + 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); + + barycenters->push_back(static_cast((pa[0]+pb[0]+pc[0])/3.0 + offset.x)); + barycenters->push_back(static_cast((pa[1]+pb[1]+pc[1])/3.0 + offset.y)); + barycenters->push_back(static_cast((pa[2]+pb[2]+pc[2])/3.0 + offset.z)); + } + } + + Scene_item* clone() const Q_DECL_OVERRIDE{return 0;} + QString toolTip() const Q_DECL_OVERRIDE{return QString();} + QMenu* contextMenu() Q_DECL_OVERRIDE + { + QMenu* menu = Scene_item::contextMenu(); + + const char* prop_name = "Menu modified by Scene_surface_mesh_item."; + bool menuChanged = menu->property(prop_name).toBool(); + + if(!menuChanged) { + menu->addSeparator(); + QMenu *container = new QMenu(tr("Alpha value")); + container->menuAction()->setProperty("is_groupable", true); + QWidgetAction *sliderAction = new QWidgetAction(0); + sliderAction->setDefaultWidget(alphaSlider); + connect(alphaSlider, &QSlider::valueChanged, + [this](){ + setAlpha(alphaSlider->value()); + redraw(); + }); + + container->addAction(sliderAction); + menu->addMenu(container); + setProperty("menu_changed", true); + menu->setProperty(prop_name, true); + } + return menu; + } + float alpha() const Q_DECL_OVERRIDE + { + return m_alpha ; + } + + void setAlpha(int a) Q_DECL_OVERRIDE + { + m_alpha = a / 255.0f; + redraw(); + } +private: + + //contains the data + mutable std::vector *vertices; + mutable std::vector *normals; + mutable std::vector *edges; + mutable std::vector *colors; + mutable std::vector *barycenters; + mutable bool is_fast; + mutable QSlider* alphaSlider; + mutable float m_alpha ; +}; //end of class Scene_triangle_item + +struct Scene_triangulation_3_item_priv{ + mutable std::size_t positions_poly_size; + mutable std::size_t positions_lines_size; + + mutable std::vector positions_lines; + mutable std::vector positions_poly; + mutable std::vector normals; + mutable std::vector f_colors; + QVector colors; + QVector colors_subdomains; + typedef std::set Indices; + Indices surface_patch_indices_; + bool need_changed; + Indices subdomain_indices_; + QSlider* alphaSlider; + Scene_triangulation_3_item* item; + bool show_tetrahedra; + CGAL::qglviewer::ManipulatedFrame* frame; + mutable std::map are_intersection_buffers_filled; + bool areInterBufFilled(CGAL::Three::Viewer_interface* viewer) + { + if(are_intersection_buffers_filled.find(viewer) != are_intersection_buffers_filled.end()) + return are_intersection_buffers_filled[viewer]; + return false; + } + + + void initialize_intersection_buffers(CGAL::Three::Viewer_interface *viewer); + void computeIntersections(CGAL::Three::Viewer_interface* viewer); + + void draw_triangle(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const; + void draw_triangle_edges(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const; + + void push_normal(std::vector& normals, const EPICK::Vector_3& n) const + { + normals.push_back(static_cast(n.x())); + normals.push_back(static_cast(n.y())); + normals.push_back(static_cast(n.z())); + } + void push_point(std::vector& points, const EPICK::Point_3& p, + const CGAL::qglviewer::Vec& offset) const + { + points.push_back(static_cast(p.x()+offset.x)); + points.push_back(static_cast(p.y()+offset.y)); + points.push_back(static_cast(p.z()+offset.z)); + } + void push_edge(std::vector& edges, + const EPICK::Point_3& pa, + const EPICK::Point_3& pb, + const CGAL::qglviewer::Vec& offset) const + { + push_point(edges, pa, offset); + push_point(edges, pb, offset); + } + void compute_color_map(const QColor& c) + { + typedef Indices::size_type size_type; + + const size_type nb_domains = subdomain_indices_.size(); + + double i = 0; + for (Indices::iterator it = subdomain_indices_.begin(), + end = subdomain_indices_.end(); it != end; ++it, i += 1.) + { + double hue = c.hueF() + 1. / double(nb_domains) * i; + if (hue > 1) { hue -= 1.; } + colors_subdomains[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); + } + const size_type nb_patch_indices = surface_patch_indices_.size(); + i = 0; + for (Indices::iterator it = surface_patch_indices_.begin(), + end = surface_patch_indices_.end(); it != end; ++it, i += 1.) + { + double hue = c.hueF() + 1. / double(nb_patch_indices) * i; + if (hue > 1) { hue -= 1.; } + colors[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); + } + } + + //!Allows OpenGL 2.0 context to get access to glDrawArraysInstanced. + typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); + //!Allows OpenGL 2.0 context to get access to glVertexAttribDivisor. + typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + //!Allows OpenGL 2.0 context to get access to gkFrameBufferTexture2D. + PFNGLDRAWARRAYSINSTANCEDARBPROC glDrawArraysInstanced; + //!Allows OpenGL 2.0 context to get access to glVertexAttribDivisor. + PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor; + Scene_intersection_item *intersection; + T3* t3; + bool last_intersection; + +}; + +struct Set_show_tetrahedra { + Scene_triangulation_3_item_priv* priv; + Set_show_tetrahedra(Scene_triangulation_3_item_priv* priv) : priv(priv) {} + void operator()(bool b) { + priv->show_tetrahedra = b; + priv->item->show_intersection(b); + } +}; + +void Scene_triangulation_3_item_priv::draw_triangle(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const +{ + Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); + n = n / CGAL::sqrt(n*n); + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + + for (int i = 0; i<3; i++) + { + push_normal(normals, n); + } + push_point(positions_poly, pa, offset); + push_point(positions_poly, pb, offset); + push_point(positions_poly, pc, offset); + +} + +void Scene_triangulation_3_item_priv::draw_triangle_edges(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const +{ + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + push_edge(positions_lines, pa, pb, offset); + push_edge(positions_lines, pb, pc, offset); + push_edge(positions_lines, pc, pa, offset); +} + +Scene_triangulation_3_item::Scene_triangulation_3_item() +{ + d = new Scene_triangulation_3_item_priv(); + common_constructor(); +} +Scene_triangulation_3_item::Scene_triangulation_3_item(T3* t3) +{ + d = new Scene_triangulation_3_item_priv(); + d->t3 = t3; + common_constructor(); +} + +Scene_triangulation_3_item::~Scene_triangulation_3_item() +{ + delete d->t3; + delete d; +} + + +void Scene_triangulation_3_item::common_constructor() +{ + compute_bbox(); + connect(d->frame, SIGNAL(modified()), this, SLOT(frame_changed())); + changed(); + setRenderingMode(FlatPlusEdges); + + setTriangleContainer(0, new Tc(Vi::PROGRAM_WITH_LIGHT, false)); setEdgeContainer(0, new Ec(Vi::PROGRAM_NO_SELECTION, false)); + setPointContainer(0, new Pc(Vi::PROGRAM_NO_SELECTION, false)); + d->show_tetrahedra = true; + d->last_intersection = !d->show_tetrahedra; + for(auto v : CGAL::QGLViewer::QGLViewerPool()) + { + v->installEventFilter(this); + } +} + +void Scene_triangulation_3_item::invalidateOpenGLBuffers() +{ + setBuffersFilled(false); + getTriangleContainer(0)->reset_vbos(ALL); + getEdgeContainer(0)->reset_vbos(ALL); + getPointContainer(0)->reset_vbos(ALL); + + Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool()) + { + CGAL::Three::Viewer_interface* viewer = static_cast(v); + if(viewer == NULL) + continue; + setBuffersInit(viewer, false); + } + + compute_bbox(); +} + +void +Scene_triangulation_3_item::frame_changed() +{ + if(!d) + return; + d->need_changed = true; + QTimer::singleShot(0,this, SLOT(updateCutPlane())); +} + +void Scene_triangulation_3_item::changed() +{ + // Update colors + // Fill indices map and get max subdomain value + d->surface_patch_indices_.clear(); + d->subdomain_indices_.clear(); + + int max = 0; + for (Tr::Finite_cells_iterator cit = d->t3->finite_cells_begin(), + end = d->t3->finite_cells_end(); cit != end; ++cit) + { + max = (std::max)(max, cit->subdomain_index()); + d->subdomain_indices_.insert(cit->subdomain_index()); + } + const int max_subdomain_index = max; + for (Tr::Finite_facets_iterator fit = d->t3->finite_facets_begin(), + end = d->t3->finite_facets_end(); fit != end; ++fit) + { + max = (std::max)(max, fit->first->surface_patch_index(fit->second)); + d->surface_patch_indices_.insert(fit->first->surface_patch_index(fit->second)); + } + + d->colors.resize(max + 1); + d->colors_subdomains.resize(max_subdomain_index + 1); + d->compute_color_map(color_); + +} + +const T3& Scene_triangulation_3_item::triangulation() const +{ + return *d->t3; +} + +T3& Scene_triangulation_3_item::triangulation() +{ + return *d->t3; +} + + +void Scene_triangulation_3_item::compute_bbox() const +{ + if (isEmpty()) + _bbox = Bbox(); + else { + bool bbox_init = false; + CGAL::Bbox_3 result; + for (Tr::Finite_vertices_iterator + vit = d->t3->finite_vertices_begin(), + end = d->t3->finite_vertices_end(); + vit != end; ++vit) + { + if (bbox_init) + result = result + vit->point().bbox(); + else + { + result = vit->point().bbox(); + bbox_init = true; + } + } + _bbox = Bbox(result.xmin(), result.ymin(), result.zmin(), + result.xmax(), result.ymax(), result.zmax()); + } +} + +Scene_triangulation_3_item* Scene_triangulation_3_item::clone() const {} + +QString Scene_triangulation_3_item::toolTip() const { return QString(); } + +void Scene_triangulation_3_item::draw(CGAL::Three::Viewer_interface* viewer) const +{ + Scene_triangulation_3_item* ncthis = const_cast(this); + if(!visible()) + return; + + if(!isInit(viewer)) + initGL(viewer); + if ( getBuffersFilled() && + ! getBuffersInit(viewer)) + { + initializeBuffers(viewer); + setBuffersInit(viewer, true); + } + if(!getBuffersFilled()) + { + computeElements(); + initializeBuffers(viewer); + } + if(renderingMode() == Flat || + renderingMode() == FlatPlusEdges) + { + getTriangleContainer(0)->setAlpha(alpha()); + getTriangleContainer(0)->draw(viewer, false); + } + if(d->show_tetrahedra){ + ncthis->show_intersection(true); + if(!d->frame->isManipulated()) + d->intersection->setFast(false); + else + d->intersection->setFast(true); + + if(!d->frame->isManipulated() && !d->areInterBufFilled(viewer)) + { + //initGL + ncthis->d->computeIntersections(viewer); + d->are_intersection_buffers_filled[viewer] = true; + ncthis->show_intersection(true); + } + } +} + +void Scene_triangulation_3_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const +{ + if(!visible()) + return; + if(renderingMode() == Wireframe || + renderingMode() == FlatPlusEdges ) + { + if(renderingMode() == FlatPlusEdges) + { + GLint renderMode; + viewer->glGetIntegerv(GL_RENDER_MODE, &renderMode); + if(renderMode == GL_SELECT) return; + } + if(!isInit(viewer)) + initGL(viewer); + if ( getBuffersFilled() && + ! getBuffersInit(viewer)) + { + initializeBuffers(viewer); + setBuffersInit(viewer, true); + } + if(!getBuffersFilled()) + { + computeElements(); + initializeBuffers(viewer); + } + getEdgeContainer(0)->setColor(QColor(Qt::black)); + getEdgeContainer(0)->draw(viewer, true); + } +} + +void Scene_triangulation_3_item::drawPoints(CGAL::Three::Viewer_interface * viewer) const +{ + if(!visible()) + return; + if(renderingMode() == Points) + { + if(!isInit(viewer)) + initGL(viewer); + if ( getBuffersFilled() && + ! getBuffersInit(viewer)) + { + initializeBuffers(viewer); + setBuffersInit(viewer, true); + } + if(!getBuffersFilled()) + { + computeElements(); + initializeBuffers(viewer); + } + + getPointContainer(0)->setColor(this->color()); + getPointContainer(0)->draw(viewer, true); + } +} + + +void Scene_triangulation_3_item::initializeBuffers(Viewer_interface *viewer) const +{ + //vao containing the data for the facets + { + getTriangleContainer(0)->initializeBuffers(viewer); + getTriangleContainer(0)->setFlatDataSize( + d->positions_poly_size); + + d->positions_poly.clear(); + d->positions_poly.shrink_to_fit(); + d->normals.clear(); + d->normals.shrink_to_fit(); + d->f_colors.clear(); + d->f_colors.shrink_to_fit(); + } + + //vao containing the data for the lines + { + getEdgeContainer(0)->initializeBuffers(viewer); + getEdgeContainer(0)->setFlatDataSize( + d->positions_lines_size); + } + //vao containing the data for the points + { + getPointContainer(0)->initializeBuffers(viewer); + getPointContainer(0)->setFlatDataSize( + d->positions_lines_size); + + d->positions_lines.clear(); + d->positions_lines.shrink_to_fit(); + } +} + +void Scene_triangulation_3_item::computeElements() const { + + QApplication::setOverrideCursor(Qt::WaitCursor); + + if(!d->alphaSlider) + { + d->alphaSlider = new QSlider(::Qt::Horizontal); + d->alphaSlider->setMinimum(0); + d->alphaSlider->setMaximum(255); + d->alphaSlider->setValue(255); + } + + d->positions_poly.clear(); + d->normals.clear(); + d->positions_lines.clear(); + d->f_colors.clear(); + { + Geom_traits::Construct_point_3 wp2p + = d->t3->geom_traits().construct_point_3_object(); + + for (Tr::Facet_iterator + fit = d->t3->facets_begin(), + end = d->t3->facets_end(); + fit != end; ++fit) + { + const Tr::Cell_handle& cell = fit->first; + const int& index = fit->second; + const Tr::Bare_point& pa = wp2p(cell->vertex((index + 1) & 3)->point()); + const Tr::Bare_point& pb = wp2p(cell->vertex((index + 2) & 3)->point()); + const Tr::Bare_point& pc = wp2p(cell->vertex((index + 3) & 3)->point()); + + QColor color = d->colors[cell->surface_patch_index(index)]; + d->f_colors.push_back((float)color.redF());d->f_colors.push_back((float)color.greenF());d->f_colors.push_back((float)color.blueF()); + d->f_colors.push_back((float)color.redF());d->f_colors.push_back((float)color.greenF());d->f_colors.push_back((float)color.blueF()); + d->f_colors.push_back((float)color.redF());d->f_colors.push_back((float)color.greenF());d->f_colors.push_back((float)color.blueF()); + d->draw_triangle(pb, pa, pc); + d->draw_triangle_edges(pa, pb, pc); + } + } + + getTriangleContainer(0)->allocate( + Tc::Flat_vertices, d->positions_poly.data(), + static_cast(d->positions_poly.size()*sizeof(float))); + + getTriangleContainer(0)->allocate( + Tc::Flat_normals, + d->normals.data(), + static_cast(d->normals.size()*sizeof(float))); + + getTriangleContainer(0)->allocate( + Tc::FColors, + d->f_colors.data(), + static_cast(d->f_colors.size()*sizeof(float))); + + d->positions_poly_size = d->positions_poly.size(); + + getEdgeContainer(0)->allocate( + Ec::Vertices, + d->positions_lines.data(), + static_cast(d->positions_lines.size()*sizeof(float))); + d->positions_lines_size = d->positions_lines.size(); + + getPointContainer(0)->allocate( + Pc::Vertices, + d->positions_lines.data(), + static_cast(d->positions_lines.size()*sizeof(float))); + + setBuffersFilled(true); + QApplication::restoreOverrideCursor(); +} + +void Scene_triangulation_3_item::updateCutPlane() +{ // just handle deformation - paint like selection is handled in eventFilter() + if(!d) + return; + if(d->need_changed) { + for(auto v : CGAL::QGLViewer::QGLViewerPool()) + { + CGAL::Three::Viewer_interface* viewer = static_cast(v); + d->are_intersection_buffers_filled[viewer] = false; + } + d->need_changed = false; + } +} diff --git a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h new file mode 100644 index 00000000000..7851bcc94a4 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h @@ -0,0 +1,84 @@ +#ifndef SCENE_TRIANGULATION_3_ITEM_H +#define SCENE_TRIANGULATION_3_ITEM_H + +#include "T3_type.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#ifdef scene_triangulation_3_item_EXPORTS +# define mesh_3_demo_scene_triangulation_3_item_EXPORTS 1 +#endif + +#ifdef mesh_3_demo_scene_triangulation_3_item_EXPORTS +# define SCENE_TRIANGULATION_3_ITEM_EXPORT Q_DECL_EXPORT +#else +# define SCENE_TRIANGULATION_3_ITEM_EXPORT Q_DECL_IMPORT +#endif + +struct Scene_triangulation_3_item_priv; +using namespace CGAL::Three; +class SCENE_TRIANGULATION_3_ITEM_EXPORT Scene_triangulation_3_item + : public Scene_item_rendering_helper +{ + Q_OBJECT +public: + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; + + Scene_triangulation_3_item(); + Scene_triangulation_3_item(T3* t3); + ~Scene_triangulation_3_item(); + + void common_constructor(); + void invalidateOpenGLBuffers() Q_DECL_OVERRIDE; + void changed(); + const T3& triangulation() const; + T3& triangulation(); + bool isFinite() const Q_DECL_OVERRIDE { return true; } + bool isEmpty() const Q_DECL_OVERRIDE { + //todo + return false; + } + + void compute_bbox() const Q_DECL_OVERRIDE; + Scene_item::Bbox bbox() const Q_DECL_OVERRIDE + { + //todo + return Scene_item::bbox(); + } + void frame_changed(); + Scene_triangulation_3_item* clone() const Q_DECL_OVERRIDE; + + QString toolTip() const Q_DECL_OVERRIDE; + + // Indicate if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE{ + return (m != Gouraud && m != PointsPlusNormals && m != Points && m != ShadedPoints); + } + + void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; + void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; + void drawPoints(CGAL::Three::Viewer_interface * viewer) const Q_DECL_OVERRIDE; + +public Q_SLOTS: + void initializeBuffers(Viewer_interface *) const Q_DECL_OVERRIDE; + void computeElements() const Q_DECL_OVERRIDE; + void reset_intersection_item(); + void show_intersection(bool b); + +protected: + friend struct Scene_triangulation_3_item_priv; + Scene_triangulation_3_item_priv* d; +}; + +#endif // SCENE_TRIANGULATION_3_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/T3_type.h b/Polyhedron/demo/Polyhedron/T3_type.h new file mode 100644 index 00000000000..59daacdccd7 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/T3_type.h @@ -0,0 +1,7 @@ +#ifndef CGAL_DEMO_T3_TYPE_H +#define CGAL_DEMO_T3_TYPE_H +#include "C3t3_type.h" +#include + +typedef CGAL::Triangulation_3 T3; +#endif // CGAL_DEMO_T3_TYPE_H