From d6dd5da27c0480059a4f80e2fcb5f4f06f39c2e9 Mon Sep 17 00:00:00 2001 From: zzzzrrr Date: Sun, 25 Apr 2010 12:40:54 -0400 Subject: [PATCH] memory cleanup --- poly2tri/common/shapes.h | 19 +++++------ poly2tri/sweep/advancing_front.cc | 9 ++--- poly2tri/sweep/advancing_front.h | 4 +-- poly2tri/sweep/sweep.cc | 50 ++++++++++++++-------------- poly2tri/sweep/sweep.h | 5 +-- poly2tri/sweep/sweep_context.cc | 53 +++++++++++++++++++----------- poly2tri/sweep/sweep_context.h | 10 +++--- testbed/main.cc | 51 ++++++++++++++-------------- waf | Bin wscript | 28 ++++++++-------- 10 files changed, 120 insertions(+), 109 deletions(-) mode change 100644 => 100755 waf diff --git a/poly2tri/common/shapes.h b/poly2tri/common/shapes.h index 47d2037..92ad27d 100644 --- a/poly2tri/common/shapes.h +++ b/poly2tri/common/shapes.h @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -40,7 +40,6 @@ namespace p2t { -struct Node; struct Edge; struct Point { @@ -50,7 +49,7 @@ struct Point { /// Default constructor does nothing (for performance). Point() { - x = 0.0; + x = 0.0; y = 0.0; } @@ -63,43 +62,43 @@ struct Point { /// Set this point to all zeros. void set_zero() { - x = 0.0f; + x = 0.0f; y = 0.0f; } /// Set this point to some specified coordinates. void set(double x_, double y_) { - x = x_; + x = x_; y = y_; } /// Negate this point. Point operator -() const { - Point v; - v.set(-x, -y); + Point v; + v.set(-x, -y); return v; } /// Add a point to this point. void operator +=(const Point& v) { - x += v.x; + x += v.x; y += v.y; } /// Subtract a point from this point. void operator -=(const Point& v) { - x -= v.x; + x -= v.x; y -= v.y; } /// Multiply this point by a scalar. void operator *=(double a) { - x *= a; + x *= a; y *= a; } diff --git a/poly2tri/sweep/advancing_front.cc b/poly2tri/sweep/advancing_front.cc index 446caf7..6504245 100644 --- a/poly2tri/sweep/advancing_front.cc +++ b/poly2tri/sweep/advancing_front.cc @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -42,7 +42,7 @@ AdvancingFront::AdvancingFront(Node& head, Node& tail) Node* AdvancingFront::LocateNode(const double& x) { Node* node = search_node_; - + if (x < node->value) { while ((node = node->prev) != NULL) { if (x >= node->value) { @@ -72,7 +72,7 @@ Node* AdvancingFront::LocatePoint(const Point* point) const double px = point->x; Node* node = FindSearchNode(px); const double nx = node->point->x; - + if (px == nx) { if (point != node->point) { // We might have two nodes with same x value for a short time @@ -102,9 +102,6 @@ Node* AdvancingFront::LocatePoint(const Point* point) AdvancingFront::~AdvancingFront() { - delete head_; - delete search_node_; - delete tail_; } } diff --git a/poly2tri/sweep/advancing_front.h b/poly2tri/sweep/advancing_front.h index 4354905..abd2b5a 100644 --- a/poly2tri/sweep/advancing_front.h +++ b/poly2tri/sweep/advancing_front.h @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -28,7 +28,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #ifndef ADVANCED_FRONT_H #define ADVANCED_FRONT_H diff --git a/poly2tri/sweep/sweep.cc b/poly2tri/sweep/sweep.cc index 4cea046..a276e72 100644 --- a/poly2tri/sweep/sweep.cc +++ b/poly2tri/sweep/sweep.cc @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -88,7 +88,6 @@ Node& Sweep::PointEvent(SweepContext& tcx, Point& point) // x value than node due to how we fetch nodes from the front if (point.x <= node.point->x + EPSILON) { Fill(tcx, node); - delete &node; } //tcx.AddNode(new_node); @@ -172,12 +171,12 @@ Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node) Node* new_node = new Node(point); nodes_.push_back(new_node); - + new_node->next = node.next; new_node->prev = &node; node.next->prev = new_node; - node.next = new_node; - + node.next = new_node; + if (!Legalize(tcx, *triangle)) { tcx.MapTriangleToNodes(*triangle); } @@ -203,13 +202,13 @@ void Sweep::Fill(SweepContext& tcx, Node& node) // Update the advancing front node.prev->next = node.next; - node.next->prev = node.prev; + node.next->prev = node.prev; // If it was legalized the triangle has already been mapped if (!Legalize(tcx, *triangle)) { tcx.MapTriangleToNodes(*triangle); } - + } /** @@ -220,7 +219,8 @@ void Sweep::Fill(SweepContext& tcx, Node& node) * @param n */ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n) -{ +{ + // Fill right holes Node* node = n.next; @@ -228,9 +228,7 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n) double angle = HoleAngle(*node); if (angle > M_PI_2 || angle < -M_PI_2) break; Fill(tcx, *node); - Node *temp = node; node = node->next; - delete temp; } // Fill left holes @@ -240,9 +238,7 @@ void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n) double angle = HoleAngle(*node); if (angle > M_PI_2 || angle < -M_PI_2) break; Fill(tcx, *node); - Node *temp = node; node = node->prev; - delete temp; } // Fill right basins @@ -528,23 +524,19 @@ void Sweep::FillBasinReq(SweepContext& tcx, Node* node) return; } - Fill(tcx, *node); - Node *temp = node; - + Fill(tcx, *node); + if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) { - delete node; return; } else if (node->prev == tcx.basin.left_node) { Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point); if (o == CW) { - delete node; return; } node = node->next; } else if (node->next == tcx.basin.right_node) { Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point); if (o == CCW) { - delete node; return; } node = node->prev; @@ -557,7 +549,6 @@ void Sweep::FillBasinReq(SweepContext& tcx, Node* node) } } - delete temp; FillBasinReq(tcx, node); } @@ -628,8 +619,8 @@ void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) // Next is convex } } - } - + } + } void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) @@ -708,9 +699,9 @@ void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node) } else{ // Next is convex } - } - } - + } + } + } void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p) @@ -765,7 +756,7 @@ Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangl // t is not crossing edge after flip int edge_index = t.EdgeIndex(&p, &op); - + t.delaunay_edge[edge_index] = true; Legalize(tcx, t); t.ClearDelunayEdges(); @@ -814,6 +805,15 @@ void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& Point& newP = NextFlipPoint(ep, eq, ot, op); FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP); } +} + +Sweep::~Sweep() { + + // Clean up memory + for(int i = 0; i < nodes_.size(); i++) { + delete nodes_[i]; + } + } } diff --git a/poly2tri/sweep/sweep.h b/poly2tri/sweep/sweep.h index 5cc9e06..5cb8ef4 100644 --- a/poly2tri/sweep/sweep.h +++ b/poly2tri/sweep/sweep.h @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -35,7 +35,7 @@ * * "FlipScan" Constrained Edge Algorithm invented by Thomas Åhlén, thahlen@gmail.com */ - + #ifndef SWEEP_H #define SWEEP_H @@ -53,6 +53,7 @@ class Sweep { public: void Triangulate(SweepContext& tcx); +~Sweep(); private: diff --git a/poly2tri/sweep/sweep_context.cc b/poly2tri/sweep/sweep_context.cc index 184ebb0..13fb6e9 100644 --- a/poly2tri/sweep/sweep_context.cc +++ b/poly2tri/sweep/sweep_context.cc @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -91,7 +91,7 @@ void SweepContext::InitTriangulation() // Sort points along y-axis std::sort(points_.begin(), points_.end(), cmp); - + } void SweepContext::InitEdges(std::vector polyline) @@ -121,28 +121,23 @@ Node& SweepContext::LocateNode(Point& point) void SweepContext::CreateAdvancingFront(std::vector nodes) { - Node *head, *middle, *tail; + // Initial triangle Triangle* triangle = new Triangle(*points_[0], *tail_, *head_); map_.push_back(triangle); - head = new Node(*triangle->GetPoint(1), *triangle); - middle = new Node(*triangle->GetPoint(0), *triangle); - tail = new Node(*triangle->GetPoint(2)); - front_ = new AdvancingFront(*head, *tail); - - // Memory management :) - nodes.push_back(head); - nodes.push_back(middle); - nodes.push_back(tail); - + af_head_ = new Node(*triangle->GetPoint(1), *triangle); + af_middle_ = new Node(*triangle->GetPoint(0), *triangle); + af_tail_ = new Node(*triangle->GetPoint(2)); + front_ = new AdvancingFront(*af_head_, *af_tail_); + // TODO: More intuitive if head is middles next and not previous? // so swap head and tail - head->next = middle; - middle->next = tail; - middle->prev = head; - tail->prev = middle; + af_head_->next = af_middle_; + af_middle_->next = af_tail_; + af_middle_->prev = af_head_; + af_tail_->prev = af_middle_; } void SweepContext::RemoveNode(Node* node) @@ -180,9 +175,27 @@ void SweepContext::MeshClean(Triangle& triangle) SweepContext::~SweepContext() { - delete head_; - delete tail_; - delete front_; + + // Clean up memory + + delete head_; + delete tail_; + delete front_; + delete af_head_; + delete af_middle_; + delete af_tail_; + + typedef std::list type_list; + + for(type_list::iterator iter = map_.begin(); iter != map_.end(); ++iter) { + Triangle* ptr = *iter; + delete ptr; + } + + for(int i = 0; i < edge_list.size(); i++) { + delete edge_list[i]; + } + } } diff --git a/poly2tri/sweep/sweep_context.h b/poly2tri/sweep/sweep_context.h index fcc7a3d..da9b92a 100644 --- a/poly2tri/sweep/sweep_context.h +++ b/poly2tri/sweep/sweep_context.h @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -28,7 +28,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #ifndef SWEEP_CONTEXT_H #define SWEEP_CONTEXT_H @@ -91,7 +91,8 @@ AdvancingFront* front(); void MeshClean(Triangle& triangle); std::vector GetTriangles(); -std::list GetMap(); +std::list GetMap(); + std::vector edge_list; struct Basin { @@ -133,7 +134,6 @@ friend class Sweep; std::vector triangles_; std::list map_; - std::vector points_; // Advancing front @@ -143,7 +143,7 @@ Point* head_; // tail point used with advancing front Point* tail_; -//EdgeEvent edgeEvent = new EdgeEvent(); +Node *af_head_, *af_middle_, *af_tail_; void InitTriangulation(); void InitEdges(std::vector polyline); diff --git a/testbed/main.cc b/testbed/main.cc index 3c3f458..9083c8c 100644 --- a/testbed/main.cc +++ b/testbed/main.cc @@ -1,4 +1,4 @@ -/* +/* * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors * http://code.google.com/p/poly2tri/ * @@ -79,18 +79,18 @@ bool random_distribution = false; int main(int argc, char* argv[]) { - + int num_points = 0; double max, min; double zoom; - + if (argc != 5) { cout << "-== USAGE ==-" << endl; cout << "Load Data File: p2t filename center_x center_y zoom" << endl; cout << " Random Points: p2t random num_points width zoom" << endl; return 1; } - + if(string(argv[1]) == "random") { num_points = atoi(argv[2]); random_distribution = true; @@ -103,10 +103,10 @@ int main(int argc, char* argv[]) zoom = atof(argv[4]); cx = atof(argv[2]); cy = atof(argv[3]); - } - + } + vector polyline; - + if(random_distribution) { // Create a simple bounding box polyline.push_back(new Point(min,min)); @@ -115,7 +115,7 @@ int main(int argc, char* argv[]) polyline.push_back(new Point(max,min)); } else { // Load pointset from file - + // Parse and tokenize data file string line; ifstream myfile(argv[1]); @@ -142,25 +142,25 @@ int main(int argc, char* argv[]) cout << "Number of constrained edges = " << polyline.size() << endl; polylines.push_back(polyline); - + Init(); - /* + /* * Perform triangulation! - */ - + */ + double init_time = glfwGetTime(); - + /* * STEP 1: Create CDT and add primary polyline * NOTE: polyline must be a simple polygon. The polyline's points * constitute constrained edges. No repeat points!!! - */ + */ CDT* cdt = new CDT(polyline); - + /* * STEP 2: Add holes or Steiner points if necessary - */ + */ string s(argv[1]); if(s.find("dude.dat", 0) != string::npos) { // Add head hole @@ -182,12 +182,12 @@ int main(int argc, char* argv[]) cdt->AddPoint(new Point(x, y)); } } - + /* * STEP 3: Triangulate! */ cdt->Triangulate(); - + double dt = glfwGetTime() - init_time; triangles = cdt->GetTriangles(); @@ -196,9 +196,10 @@ int main(int argc, char* argv[]) cout << "Number of points = " << num_points << endl; cout << "Number of triangles = " << triangles.size() << endl; cout << "Elapsed time (ms) = " << dt*1000.0 << endl; - - MainLoop(zoom); + MainLoop(zoom); + + delete cdt; ShutDown(0); return 0; } @@ -216,7 +217,7 @@ void Init() glfwSetWindowTitle("Poly2Tri - C++"); glfwSwapInterval(1); - + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0.0, 0.0, 0.0, 0.0); @@ -310,10 +311,10 @@ void Draw(const double zoom) glVertex2f(c.x, c.y); glEnd(); } - + // green glColor3f(0, 1, 0); - + for(int i = 0; i < polylines.size(); i++) { vector poly = polylines[i]; glBegin(GL_LINE_LOOP); @@ -376,7 +377,7 @@ vector CreateHeadHole() { head_hole.push_back(new Point(320, 423)); head_hole.push_back(new Point(329, 413)); head_hole.push_back(new Point(332, 423)); - + return head_hole; } @@ -389,7 +390,7 @@ vector CreateChestHole() { chest_hole.push_back(new Point(329.8148,510.41534)); chest_hole.push_back(new Point(339.91632,480.11077)); chest_hole.push_back(new Point(334.86556,478.09046)); - + return chest_hole; } diff --git a/waf b/waf old mode 100644 new mode 100755 diff --git a/wscript b/wscript index a951574..a267658 100644 --- a/wscript +++ b/wscript @@ -5,42 +5,42 @@ srcdir = '.' blddir = 'build' p2t_source_files = ['poly2tri/common/shapes.cc', - 'poly2tri/sweep/cdt.cc', + 'poly2tri/sweep/cdt.cc', 'poly2tri/sweep/advancing_front.cc', 'poly2tri/sweep/sweep_context.cc', 'poly2tri/sweep/sweep.cc'] - + testbed_source_files = ['testbed/main.cc'] - + #Platform specific libs if sys.platform == 'win32': # MS Windows sys_libs = ['glfw', 'opengl32'] -elif sys.platform == 'darwin': +elif sys.platform == 'darwin': # Apple OSX sys_libs = ['glfw', 'OpenGL'] else: # GNU/Linux, BSD, etc sys_libs = ['glfw', 'GL'] - + def init(): print(' init called') - + def set_options(opt): print(' set_options') opt.tool_options('g++') - + def configure(conf): print(' calling the configuration') conf.check_tool('g++') - #conf.env.CXXFLAGS = ['-O0', '-pg', '-g'] - #conf.env.CXXFLAGS = ['-O0', '-g'] - conf.env.CXXFLAGS = ['-O3', '-ffast-math'] - + #conf.env.CXXFLAGS = ['-O0', '-pg', '-g'] + conf.env.CXXFLAGS = ['-O0', '-g'] + #conf.env.CXXFLAGS = ['-O3', '-ffast-math'] + def build(bld): print(' building') - + ''' # A static library # The extension (.a) is added automatically @@ -49,7 +49,7 @@ def build(bld): source = p2t_source_files, name = 'poly2tri', target = 'poly2tri') - + # 1. A simple program bld.new_task_gen( features = 'cxx cprogram', @@ -64,6 +64,6 @@ def build(bld): source = testbed_source_files + p2t_source_files, target = 'p2t', libs = sys_libs) - + def shutdown(): print(' shutdown called')