diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index 35b3bb4e9fe..08a63e2bf8d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -281,8 +281,15 @@ struct Scene_c3t3_item_priv { } ~Scene_c3t3_item_priv() { - delete frame; - delete tet_Slider; + c3t3.clear(); + tree.clear(); + if(frame) + { + static_cast(QGLViewer::QGLViewerPool().first())->setManipulatedFrame(0); + delete frame; + frame = NULL; + delete tet_Slider; + } } void init_default_values() { @@ -520,7 +527,11 @@ Scene_c3t3_item::Scene_c3t3_item(const C3t3& c3t3) Scene_c3t3_item::~Scene_c3t3_item() { - delete d; + if(d) + { + delete d; + d = NULL; + } } @@ -562,12 +573,16 @@ Scene_c3t3_item::c3t3() void Scene_c3t3_item::changed() { + if(!d) + return; d->need_changed = true; QTimer::singleShot(0,this, SLOT(updateCutPlane())); } void Scene_c3t3_item::updateCutPlane() { // just handle deformation - paint like selection is handled in eventFilter() + if(!d) + return; if(d->need_changed) { d->are_intersection_buffers_filled = false; d->need_changed = false; @@ -1704,7 +1719,10 @@ void Scene_c3t3_item::reset_spheres() d->spheres = NULL; } CGAL::Three::Scene_item::ManipulatedFrame* Scene_c3t3_item::manipulatedFrame() { - return d->frame; + if(d) + return d->frame; + else + return NULL; } void Scene_c3t3_item::setPosition(float x, float y, float z) { @@ -1988,6 +2006,30 @@ void Scene_c3t3_item::invalidateOpenGLBuffers() } void Scene_c3t3_item::resetCutPlane() { + if(!d) + return; d->reset_cut_plane(); } + +void Scene_c3t3_item::itemAboutToBeDestroyed(Scene_item *item) +{ + Scene_item::itemAboutToBeDestroyed(item); + + if(d && item == this) + { + d->c3t3.clear(); + d->tree.clear(); + if(d->frame) + { + static_cast(QGLViewer::QGLViewerPool().first())->setManipulatedFrame(0); + delete d->frame; + d->frame = NULL; + delete d->tet_Slider; + } + delete d; + d=0; + } + +} + #include "Scene_c3t3_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h index 4af3ebe6af4..a5fbb23568a 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h @@ -149,6 +149,8 @@ public: QColor get_histogram_color(const double v) const; + void itemAboutToBeDestroyed(Scene_item *) Q_DECL_OVERRIDE; + protected: friend struct Scene_c3t3_item_priv; Scene_c3t3_item_priv* d; diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index bc841281536..e924d47bdfe 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -84,8 +84,11 @@ struct Scene_points_with_normal_item_priv } ~Scene_points_with_normal_item_priv() { - Q_ASSERT(m_points != NULL); - delete m_points; m_points = NULL; + if(m_points) + { + delete m_points; + m_points = NULL; + } delete normal_Slider; delete point_Slider; } @@ -870,3 +873,13 @@ int Scene_points_with_normal_item::getPointSliderValue() { return d->point_Slider->value(); } + +void Scene_points_with_normal_item::itemAboutToBeDestroyed(Scene_item *item) +{ + Scene_item::itemAboutToBeDestroyed(item); + if(d && d->m_points && item == this) + { + delete d->m_points; + d->m_points = NULL; + } +} diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h index ad75b4cafd1..41c938492ef 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h @@ -89,6 +89,7 @@ public Q_SLOTS: void pointSliderPressed(); //Set the status of the slider as `released` void pointSliderReleased(); + void itemAboutToBeDestroyed(Scene_item *) Q_DECL_OVERRIDE; // Data protected: diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 20609352900..cc912635d9a 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -44,7 +44,11 @@ struct Scene_polygon_soup_item_priv{ } ~Scene_polygon_soup_item_priv() { - delete soup; + if(soup) + { + delete soup; + soup = NULL; + } } void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const; void compute_normals_and_vertices(void) const; @@ -846,3 +850,16 @@ const Scene_polygon_soup_item::Points& Scene_polygon_soup_item::points() const { bool Scene_polygon_soup_item::isDataColored() { return d->soup->fcolors.size()>0 || d->soup->vcolors.size()>0;} std::vector Scene_polygon_soup_item::getVColors() const{return d->soup->vcolors;} std::vector Scene_polygon_soup_item::getFColors() const{return d->soup->fcolors;} + +void Scene_polygon_soup_item::itemAboutToBeDestroyed(Scene_item *item) +{ + Scene_item::itemAboutToBeDestroyed(item); + if(d && item == this) + { + if(d->soup) + { + delete d->soup; + d->soup=NULL; + } + } +} diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index d3f561b6054..767deb6f3ab 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -151,6 +151,7 @@ public Q_SLOTS: void setDisplayNonManifoldEdges(const bool); bool displayNonManifoldEdges() const; + void itemAboutToBeDestroyed(Scene_item *item) Q_DECL_OVERRIDE; protected: friend struct Scene_polygon_soup_item_priv; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 9a33edaa508..b439e4bf04f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -94,6 +94,11 @@ struct Scene_polyhedron_item_priv{ { init_default_values(); } + ~Scene_polyhedron_item_priv() + { + delete poly; + delete targeted_id; + } void init_default_values() { show_only_feature_edges_m = false; @@ -123,11 +128,6 @@ struct Scene_polyhedron_item_priv{ const bool colors_only) const; void init(); void invalidate_stats(); - void destroy() - { - delete poly; - delete targeted_id; - } void* get_aabb_tree(); QList triangulate_primitive(Polyhedron::Facet_iterator fit, Traits::Vector_3 normal); @@ -811,14 +811,21 @@ Scene_polyhedron_item::~Scene_polyhedron_item() CGAL::Three::Viewer_interface* v = qobject_cast(viewer); //Clears the targeted Id - v->textRenderer->removeText(d->targeted_id); + if(d) + v->textRenderer->removeText(d->targeted_id); //Remove textitems - v->textRenderer->removeTextList(textItems); - delete textItems; + if(textItems) + { + v->textRenderer->removeTextList(textItems); + delete textItems; + textItems=NULL; + } + } + if(d) + { + delete d; + d=NULL; } - - d->destroy(); - delete d; } #include "Color_map.h" @@ -1819,6 +1826,7 @@ bool Scene_polyhedron_item::intersect_face(double orig_x, return false; } + bool Scene_polyhedron_item::supportsRenderingMode(RenderingMode m) const { return ( @@ -1835,3 +1843,13 @@ void Scene_polyhedron_item::set_flat_disabled(bool b) invalidateOpenGLBuffers(); itemChanged(); } + +void Scene_polyhedron_item::itemAboutToBeDestroyed(Scene_item *item) +{ + Scene_item::itemAboutToBeDestroyed(item); + if(d && item == this) + { + delete d; + d=NULL; + } +} diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index 53d6073d7a3..8d911488dbd 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -54,9 +54,9 @@ public: MEAN_ANGLE }; - bool has_stats()const {return true;} - QString computeStats(int type); - CGAL::Three::Scene_item::Header_data header() const; + bool has_stats()const Q_DECL_OVERRIDE{return true;} + QString computeStats(int type)Q_DECL_OVERRIDE; + CGAL::Three::Scene_item::Header_data header() const Q_DECL_OVERRIDE; TextListItem* textItems; Scene_polyhedron_item(); // Scene_polyhedron_item(const Scene_polyhedron_item&); @@ -64,7 +64,7 @@ public: Scene_polyhedron_item(Polyhedron* const p); ~Scene_polyhedron_item(); - Scene_polyhedron_item* clone() const; + Scene_polyhedron_item* clone() const Q_DECL_OVERRIDE; // IO bool load(std::istream& in); @@ -73,28 +73,28 @@ public: bool save_obj(std::ostream& out) const; // Function for displaying meta-data of the item - virtual QString toolTip() const; + virtual QString toolTip() const Q_DECL_OVERRIDE; // Function to override the context menu - QMenu* contextMenu(); + QMenu* contextMenu() Q_DECL_OVERRIDE; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const; + virtual bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE; // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void draw() const {} - virtual void draw(CGAL::Three::Viewer_interface*) const; - virtual void drawEdges() const {} - virtual void drawEdges(CGAL::Three::Viewer_interface* viewer) const; - virtual void drawPoints(CGAL::Three::Viewer_interface*) const; + virtual void draw(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE; + virtual void drawEdges() const Q_DECL_OVERRIDE{} + virtual void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; + virtual void drawPoints(CGAL::Three::Viewer_interface*) const Q_DECL_OVERRIDE; // Get wrapped polyhedron Polyhedron* polyhedron(); const Polyhedron* polyhedron() const; // Get dimensions - bool isFinite() const { return true; } - bool isEmpty() const; - void compute_bbox() const; + bool isFinite() const Q_DECL_OVERRIDE { return true; } + bool isEmpty() const Q_DECL_OVERRIDE; + void compute_bbox() const Q_DECL_OVERRIDE; std::vector& color_vector(); void set_color_vector_read_only(bool on_off); bool is_color_vector_read_only(); @@ -109,9 +109,9 @@ public: //! @returns `true` if the item has multiple colors at the same time. bool isItemMulticolor(); - void printPrimitiveId(QPoint point, CGAL::Three::Viewer_interface*viewer); - void printPrimitiveIds(CGAL::Three::Viewer_interface*viewer) const; - bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface*); + void printPrimitiveId(QPoint point, CGAL::Three::Viewer_interface*viewer) Q_DECL_OVERRIDE; + void printPrimitiveIds(CGAL::Three::Viewer_interface*viewer) const Q_DECL_OVERRIDE; + bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface*) Q_DECL_OVERRIDE; //! @returns `true` if `f` is the first facet intersected by a raytracing bool intersect_face(double orig_x, @@ -123,9 +123,9 @@ public: Polyhedron::Facet_handle f); public Q_SLOTS: - virtual void invalidateOpenGLBuffers(); - virtual void selection_changed(bool); - virtual void setColor(QColor c); + virtual void invalidateOpenGLBuffers() Q_DECL_OVERRIDE; + virtual void selection_changed(bool) Q_DECL_OVERRIDE; + virtual void setColor(QColor c) Q_DECL_OVERRIDE; virtual void show_feature_edges(bool); void show_only_feature_edges(bool); void enable_facets_picking(bool); @@ -137,11 +137,12 @@ public Q_SLOTS: double orig_z, double dir_x, double dir_y, - double dir_z); + double dir_z) Q_DECL_OVERRIDE; void update_vertex_indices(); void update_facet_indices(); void update_halfedge_indices(); void invalidate_aabb_tree(); + void itemAboutToBeDestroyed(Scene_item *) Q_DECL_OVERRIDE; Q_SIGNALS: void selection_done(); diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 2574d2f2614..6bb2f8b3340 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -42,7 +42,11 @@ struct Scene_surface_mesh_item_priv{ ~Scene_surface_mesh_item_priv() { - delete smesh_; + if(smesh_) + { + delete smesh_; + smesh_ = NULL; + } } void initializeBuffers(CGAL::Three::Viewer_interface *) const; @@ -649,3 +653,12 @@ void Scene_surface_mesh_item::compute_bbox()const } +void Scene_surface_mesh_item::itemAboutToBeDestroyed(Scene_item *item) +{ + Scene_item::itemAboutToBeDestroyed(item); + if(d && d->smesh_ && item == this) + { + delete d->smesh_; + d->smesh_ = NULL; + } +} diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h index f40924c446e..e128b59e608 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h @@ -54,6 +54,7 @@ public: void compute_bbox()const; void standard_constructor(SMesh *sm); public Q_SLOTS: + void itemAboutToBeDestroyed(Scene_item *) Q_DECL_OVERRIDE; virtual void selection_changed(bool); protected: friend struct Scene_surface_mesh_item_priv; diff --git a/Three/include/CGAL/Three/Scene_item.h b/Three/include/CGAL/Three/Scene_item.h index 58cf022df38..bb99db64d71 100644 --- a/Three/include/CGAL/Three/Scene_item.h +++ b/Three/include/CGAL/Three/Scene_item.h @@ -321,6 +321,9 @@ public Q_SLOTS: } //!Emits an aboutToBeDestroyed() signal. + //!Override this function to delete what needs to be deleted on destruction. + //!This might be needed as items are not always deleted right away by Qt and this behaviour may cause a simily + //!memory leak, for example when multiple items are created at the same time. virtual void itemAboutToBeDestroyed(Scene_item*); //!Selects a point through raycasting. @@ -331,6 +334,8 @@ public Q_SLOTS: double dir_y, double dir_z); + + Q_SIGNALS: //! Is emitted to notify a change in the item's data. void itemChanged();