From e47e97ce09a7a74856f4c413ca246adb94a22d43 Mon Sep 17 00:00:00 2001 From: Bryn Keller Date: Sun, 26 Nov 2017 22:21:12 -0500 Subject: [PATCH] removing smart pointers --- console.cpp | 42 ++++---- dcel/anchor.cpp | 8 +- dcel/anchor.h | 12 +-- dcel/arrangement.cpp | 142 ++++++++++++++----------- dcel/arrangement.h | 52 ++++----- dcel/arrangement_builder.cpp | 127 +++++++++++----------- dcel/arrangement_builder.h | 6 +- dcel/arrangement_message.cpp | 35 ++++--- dcel/dcel.cpp | 42 ++++---- dcel/dcel.h | 52 ++++----- math/persistence_updater.cpp | 180 ++++++++++++++++---------------- math/persistence_updater.h | 36 +++---- math/template_points_matrix.cpp | 20 ++-- math/template_points_matrix.h | 22 ++-- pointer_comparator.h | 8 ++ 15 files changed, 408 insertions(+), 376 deletions(-) diff --git a/console.cpp b/console.cpp index 9cb41169..06711cf8 100644 --- a/console.cpp +++ b/console.cpp @@ -327,27 +327,27 @@ int main(int argc, char* argv[]) //of the run. This message just announces the absolute path of the file. //The viewer should capture the file name from the stdout stream, and //then wait for the console program to finish before attempting to read the file. -// std::stringstream ss(std::ios_base::binary | std::ios_base::out | std::ios_base::in); -// { -// boost::archive::binary_oarchive archive(ss); -// archive << *arrangement_message; -// } -// std::clog << "Testing deserialization locally..." << std::endl; -// std::string original = ss.str(); -// ArrangementMessage test; -// { -// boost::archive::binary_iarchive inarch(ss); -// inarch >> test; -// std::clog << "Deserialized!"; -// } -// if (!(*arrangement_message == test)) { -// throw std::runtime_error("Original and deserialized don't match!"); -// } -// Arrangement reconstituted = arrangement_message->to_arrangement(); -// ArrangementMessage round_trip(reconstituted); -// if (!(round_trip == *arrangement_message)) { -// throw std::runtime_error("Original and reconstituted don't match!"); -// } + std::stringstream ss(std::ios_base::binary | std::ios_base::out | std::ios_base::in); + { + boost::archive::binary_oarchive archive(ss); + archive << *arrangement_message; + } + std::clog << "Testing deserialization locally..." << std::endl; + std::string original = ss.str(); + ArrangementMessage test; + { + boost::archive::binary_iarchive inarch(ss); + inarch >> test; + std::clog << "Deserialized!"; + } + if (!(*arrangement_message == test)) { + throw std::runtime_error("Original and deserialized don't match!"); + } + Arrangement reconstituted = arrangement_message->to_arrangement(); + ArrangementMessage round_trip(reconstituted); + if (!(round_trip == *arrangement_message)) { + throw std::runtime_error("Original and reconstituted don't match!"); + } if (binary) { std::cout << "ARRANGEMENT: " << params.outputFile << std::endl; } else if (verbosity > 0) { diff --git a/dcel/anchor.cpp b/dcel/anchor.cpp index 6007ea34..f3c0ddb1 100644 --- a/dcel/anchor.cpp +++ b/dcel/anchor.cpp @@ -22,7 +22,7 @@ along with this program. If not, see . #include "math/template_points_matrix.h" #include -Anchor::Anchor(std::shared_ptr e) +Anchor::Anchor(TemplatePointsMatrixEntry* e) : x_coord(e->x) , y_coord(e->y) , entry(e) @@ -77,12 +77,12 @@ unsigned Anchor::get_y() const return y_coord; } -void Anchor::set_line(std::shared_ptr e) +void Anchor::set_line(Halfedge* e) { dual_line = e; } -std::shared_ptr Anchor::get_line() const +Halfedge* Anchor::get_line() const { return dual_line; } @@ -107,7 +107,7 @@ void Anchor::toggle() above_line = !above_line; } -std::shared_ptr Anchor::get_entry() +TemplatePointsMatrixEntry* Anchor::get_entry() { return entry; } diff --git a/dcel/anchor.h b/dcel/anchor.h index 2025f90a..5b0f405d 100644 --- a/dcel/anchor.h +++ b/dcel/anchor.h @@ -35,7 +35,7 @@ struct TemplatePointsMatrixEntry; class Anchor { public: - Anchor(std::shared_ptr e); //default constructor + Anchor(TemplatePointsMatrixEntry* e); //default constructor Anchor(unsigned x, unsigned y); //constructor, requires only x- and y-coordinates Anchor(); //For serialization @@ -46,8 +46,8 @@ class Anchor { unsigned get_x() const; //get the discrete x-coordinate unsigned get_y() const; //get the discrete y-coordinate - void set_line(std::shared_ptr e); //set the pointer to the line corresponding to this Anchor in the arrangement - std::shared_ptr get_line() const; //get the pointer to the line corresponding to this Anchor in the arrangement + void set_line(Halfedge* e); //set the pointer to the line corresponding to this Anchor in the arrangement + Halfedge* get_line() const; //get the pointer to the line corresponding to this Anchor in the arrangement void set_position(unsigned p); //sets the relative position of the Anchor line at the sweep line, used for Bentley-Ottmann DCEL construction algorithm unsigned get_position() const; //gets the relative position of the Anchor line at the sweep line, used for Bentley-Ottmann DCEL construction algorithm @@ -55,7 +55,7 @@ class Anchor { bool is_above(); //returns true iff this Anchor is above the current slice line, used for the vineyard-update process of storing persistence data in cells of the arrangement void toggle(); //toggles above/below state of this Anchor; called whever the slice line crosses this Anchor in the vineyard-update process of storing persistence data - std::shared_ptr get_entry(); //accessor + TemplatePointsMatrixEntry* get_entry(); //accessor void set_weight(unsigned long w); //sets the estimate of the cost of updating the RU-decomposition when crossing this anchor unsigned long get_weight(); //returns estimate of the cost of updating the RU-decomposition when crossing this anchor @@ -67,9 +67,9 @@ class Anchor { unsigned x_coord; //discrete x-coordinate unsigned y_coord; //discrete y-coordinate - std::shared_ptr entry; //TemplatePointsMatrixEntry at the position of this anchor + TemplatePointsMatrixEntry* entry; //TemplatePointsMatrixEntry at the position of this anchor - std::shared_ptr dual_line; //pointer to left-most halfedge corresponding to this Anchor in the arrangement + Halfedge* dual_line; //pointer to left-most halfedge corresponding to this Anchor in the arrangement unsigned position; //relative position of Anchor line at sweep line, used for Bentley-Ottmann DCEL construction algorithm bool above_line; //true iff this Anchor is above the current slice line, used for the vineyard-update process of storing persistence data in cells of the arrangement unsigned long weight; //estimate of the cost of updating the RU-decomposition when crossing this anchor diff --git a/dcel/arrangement.cpp b/dcel/arrangement.cpp index 8425c446..dcd884fa 100644 --- a/dcel/arrangement.cpp +++ b/dcel/arrangement.cpp @@ -62,15 +62,15 @@ Arrangement::Arrangement(std::vector xe, , verbosity(verbosity) { //create vertices - vertices.push_back(std::make_shared(0, INFTY)); //index 0 - vertices.push_back(std::make_shared(INFTY, INFTY)); //index 1 - vertices.push_back(std::make_shared(INFTY, -INFTY)); //index 2 - vertices.push_back(std::make_shared(0, -INFTY)); //index 3 + vertices.push_back(new Vertex(0, INFTY)); //index 0 + vertices.push_back(new Vertex(INFTY, INFTY)); //index 1 + vertices.push_back(new Vertex(INFTY, -INFTY)); //index 2 + vertices.push_back(new Vertex(0, -INFTY)); //index 3 //create halfedges for (int i = 0; i < 4; i++) { - halfedges.push_back(std::make_shared(vertices[i], std::shared_ptr(nullptr))); //index 0, 2, 4, 6 (inside halfedges) - halfedges.push_back(std::make_shared(vertices[(i + 1) % 4], std::shared_ptr(nullptr))); //index 1, 3, 5, 7 (outside halfedges) + halfedges.push_back(new Halfedge(vertices[i], nullptr)); //index 0, 2, 4, 6 (inside halfedges) + halfedges.push_back(new Halfedge(vertices[(i + 1) % 4], nullptr)); //index 1, 3, 5, 7 (outside halfedges) halfedges[2 * i]->set_twin(halfedges[2 * i + 1]); halfedges[2 * i + 1]->set_twin(halfedges[2 * i]); } @@ -86,39 +86,53 @@ Arrangement::Arrangement(std::vector xe, } //create face - faces.push_back(std::make_shared(halfedges[0], faces.size())); + faces.push_back(new Face(halfedges[0], faces.size())); //set the remaining pointers on the halfedges for (int i = 0; i < 4; i++) { - std::shared_ptr inside = halfedges[2 * i]; + Halfedge* inside = halfedges[2 * i]; inside->set_next(halfedges[(2 * i + 2) % 8]); inside->set_prev(halfedges[(2 * i + 6) % 8]); inside->set_face(faces[0]); - std::shared_ptr outside = halfedges[2 * i + 1]; + Halfedge* outside = halfedges[2 * i + 1]; outside->set_next(halfedges[(2 * i + 7) % 8]); outside->set_prev(halfedges[(2 * i + 3) % 8]); } } //end constructor +Arrangement::~Arrangement() { + for(auto face : faces) { + delete face; + } + for(auto halfedge: halfedges) { + delete halfedge; + } + for(auto anchor: all_anchors) { + delete anchor; + } + for(auto vertex: vertices) { + delete vertex; + } +} //inserts a new vertex on the specified edge, with the specified coordinates, and updates all relevant pointers // i.e. new vertex is between initial and termainal points of the specified edge //returns pointer to a new halfedge, whose initial point is the new vertex, and that follows the specified edge around its face -std::shared_ptr Arrangement::insert_vertex(std::shared_ptr edge, double x, double y) +Halfedge* Arrangement::insert_vertex(Halfedge* edge, double x, double y) { //create new vertex - std::shared_ptr new_vertex = std::make_shared(x, y); - vertices.push_back(new_vertex); + vertices.push_back(new Vertex(x, y)); + auto new_vertex = vertices.back(); //get twin and Anchor of this edge - std::shared_ptr twin = edge->get_twin(); - std::shared_ptr anchor = edge->get_anchor(); + auto twin = edge->get_twin(); + auto anchor = edge->get_anchor(); //create new halfedges - std::shared_ptr up = std::make_shared(new_vertex, anchor); - halfedges.push_back(up); - std::shared_ptr dn = std::make_shared(new_vertex, anchor); - halfedges.push_back(dn); + halfedges.push_back(new Halfedge(new_vertex, anchor)); + auto up = halfedges.back(); + halfedges.push_back(new Halfedge(new_vertex, anchor)); + auto dn = halfedges.back(); //update pointers up->set_next(edge->get_next()); @@ -150,17 +164,18 @@ std::shared_ptr Arrangement::insert_vertex(std::shared_ptr e //creates the first pair of Halfedges in an Anchor line, anchored on the left edge of the strip at origin of specified edge // also creates a new face (the face below the new edge) // CAUTION: leaves nullptr: new_edge.next and new_twin.prev -std::shared_ptr Arrangement::create_edge_left(std::shared_ptr edge, std::shared_ptr anchor) +Halfedge* Arrangement::create_edge_left(Halfedge* edge, Anchor* anchor) { //create new halfedges - std::shared_ptr new_edge(new Halfedge(edge->get_origin(), anchor)); //points AWAY FROM left edge - halfedges.push_back(new_edge); - std::shared_ptr new_twin(new Halfedge(nullptr, anchor)); //points TOWARDS left edge - halfedges.push_back(new_twin); + ; //points AWAY FROM left edge + halfedges.push_back(new Halfedge(edge->get_origin(), anchor)); + auto new_edge = halfedges.back(); + halfedges.push_back(new Halfedge(nullptr, anchor)); //points TOWARDS left edge + auto new_twin = halfedges.back(); //create new face - std::shared_ptr new_face(new Face(new_edge, faces.size())); - faces.push_back(new_face); + faces.push_back(new Face(new_edge, faces.size())); + auto new_face = faces.back(); //update Halfedge pointers new_edge->set_prev(edge->get_prev()); @@ -187,7 +202,7 @@ std::shared_ptr Arrangement::create_edge_left(std::shared_ptr cell; + Face* cell; if (degrees == 90) //then line is vertical { cell = find_vertical_line(-1 * offset); //multiply by -1 to correct for orientation of offset @@ -196,7 +211,7 @@ BarcodeTemplate& Arrangement::get_barcode_template(double degrees, double offset } } else if (degrees == 0) { //then line is horizontal - std::shared_ptr anchor = find_least_upper_anchor(offset); + auto anchor = find_least_upper_anchor(offset); if (anchor != nullptr) cell = anchor->get_line()->get_face(); @@ -240,16 +255,16 @@ unsigned Arrangement::num_faces() //creates a new anchor in the vector all_anchors void Arrangement::add_anchor(Anchor anchor) { - all_anchors.insert(std::make_shared(anchor.get_entry())); + all_anchors.insert(new Anchor(anchor.get_entry())); } //finds the first anchor that intersects the left edge of the arrangement at a point not less than the specified y-coordinate // if no such anchor, returns nullptr -std::shared_ptr Arrangement::find_least_upper_anchor(double y_coord) +Anchor* Arrangement::find_least_upper_anchor(double y_coord) { //binary search to find greatest y-grade not greater than than y_coord unsigned best = 0; - if (y_grades.size() >= 1 && y_grades[0] <= y_coord) { + if ((!y_grades.empty()) && y_grades[0] <= y_coord) { //binary search the vector y_grades unsigned min = 0; unsigned max = y_grades.size() - 1; @@ -270,20 +285,20 @@ std::shared_ptr Arrangement::find_least_upper_anchor(double y_coord) //if we get here, then y_grades[best] is the greatest y-grade not greater than y_coord //now find Anchor whose line intersects the left edge of the arrangement lowest, but not below y_grade[best] unsigned int zero = 0; //disambiguate the following function call - std::shared_ptr test(new Anchor(zero, best)); - std::set, PointerComparator>::iterator it = all_anchors.lower_bound(test); + auto test = new Anchor(zero, best); + auto it = all_anchors.lower_bound(test); if (it == all_anchors.end()) //not found { return nullptr; } //else - return *it; + return (*it); } //end find_least_upper_anchor() //finds the (unbounded) cell associated to dual point of the vertical line with the given x-coordinate // i.e. finds the Halfedge whose Anchor x-coordinate is the largest such coordinate not larger than than x_coord; returns the Face corresponding to that Halfedge -std::shared_ptr Arrangement::find_vertical_line(double x_coord) +Face* Arrangement::find_vertical_line(double x_coord) { //is there an Anchor with x-coordinate not greater than x_coord? if (vertical_line_query_list.size() >= 1 @@ -295,7 +310,7 @@ std::shared_ptr Arrangement::find_vertical_line(double x_coord) while (max >= min) { unsigned mid = (max + min) / 2; - std::shared_ptr test = vertical_line_query_list[mid]->get_anchor(); + auto test = vertical_line_query_list[mid]->get_anchor(); if (x_grades[test->get_x()] <= x_coord) //found a lower bound, but search upper subarray for a better lower bound { @@ -313,7 +328,7 @@ std::shared_ptr Arrangement::find_vertical_line(double x_coord) } //end find_vertical_line() -void Arrangement::announce_next_point(std::shared_ptr finger, std::shared_ptr next_pt) +void Arrangement::announce_next_point(Halfedge* finger, Vertex* next_pt) { if (verbosity >= 10) { @@ -325,12 +340,13 @@ void Arrangement::announce_next_point(std::shared_ptr finger, std::sha } //find a 2-cell containing the specified point -std::shared_ptr Arrangement::find_point(double x_coord, double y_coord) +Face* Arrangement::find_point(double x_coord, double y_coord) { + std::cerr << "find_point " << x_coord << ", " << y_coord << std::endl; //start on the left edge of the arrangement, at the correct y-coordinate - std::shared_ptr start = find_least_upper_anchor(-1 * y_coord); + auto start = find_least_upper_anchor(-1 * y_coord); - std::shared_ptr finger = nullptr; //for use in finding the cell + Halfedge* finger = nullptr; //for use in finding the cell if (start == nullptr) //then starting point is in the top (unbounded) cell { @@ -345,7 +361,7 @@ std::shared_ptr Arrangement::find_point(double x_coord, double y_coord) } } - std::shared_ptr cell = nullptr; //will later point to the cell containing the specified point + Face* cell = nullptr; //will later point to the cell containing the specified point while (cell == nullptr) //while not found { @@ -354,7 +370,7 @@ std::shared_ptr Arrangement::find_point(double x_coord, double y_coord) } //find the edge of the current cell that crosses the horizontal line at y_coord - std::shared_ptr next_pt = finger->get_next()->get_origin(); + Vertex* next_pt = finger->get_next()->get_origin(); announce_next_point(finger, next_pt); @@ -376,7 +392,7 @@ std::shared_ptr Arrangement::find_point(double x_coord, double y_coord) } else //move to adjacent cell { //find degree of vertex - std::shared_ptr thumb = finger->get_next(); + auto thumb = finger->get_next(); int deg = 1; while (thumb != finger->get_twin()) { thumb = thumb->get_twin()->get_next(); @@ -396,7 +412,7 @@ std::shared_ptr Arrangement::find_point(double x_coord, double y_coord) cell = finger->get_face(); } else //then edge is not vertical { - std::shared_ptr temp = finger->get_anchor(); + Anchor* temp = finger->get_anchor(); double x_pos = (y_coord + y_grades[temp->get_y()]) / x_grades[temp->get_x()]; //NOTE: division by zero never occurs because we are searching along a horizontal line, and thus we never cross horizontal lines in the arrangement if (x_pos >= x_coord) //found the cell @@ -439,8 +455,8 @@ void Arrangement::print() debug() << " Halfedges"; for (unsigned i = 0; i < halfedges.size(); i++) { - std::shared_ptr e = halfedges[i]; - std::shared_ptr t = e->get_twin(); + auto e = halfedges[i]; + auto t = e->get_twin(); debug() << " halfedge " << i << ": " << *(e->get_origin()) << "--" << *(t->get_origin()) << "; "; if (e->get_anchor() == nullptr) debug() << "Anchor null; "; @@ -455,7 +471,7 @@ void Arrangement::print() } debug() << " Anchor set: "; - std::set>::iterator it; + std::set::iterator it; for (it = all_anchors.begin(); it != all_anchors.end(); ++it) { Anchor cur = **it; debug() << "(" << cur.get_x() << ", " << cur.get_y() << ") halfedge " << HID(cur.get_line()) << "; "; @@ -463,7 +479,7 @@ void Arrangement::print() } //end print() template -long index_of(std::vector const& vec, T const& t) +long index_of(std::vector const& vec, T const* t) { for (size_t i = 0; i < vec.size(); i++) { if (vec[i] == t) @@ -474,26 +490,26 @@ long index_of(std::vector const& vec, T const& t) //look up halfedge ID, used in print() for debugging // HID = halfedge ID -long Arrangement::HID(std::shared_ptr h) const +long Arrangement::HID(Halfedge* h) const { return index_of(halfedges, h); } //look up face ID, used in print() for debugging // FID = face ID -long Arrangement::FID(std::shared_ptr f) const +long Arrangement::FID(Face* f) const { return index_of(faces, f); } //look up vertex ID, used in print() for debugging // VID = vertex ID -long Arrangement::VID(std::shared_ptr v) const +long Arrangement::VID(Vertex* v) const { return index_of(vertices, v); } -long Arrangement::AID(std::shared_ptr a) const +long Arrangement::AID(Anchor* a) const { auto it = all_anchors.begin(); @@ -515,8 +531,8 @@ void Arrangement::test_consistency() bool face_problem = false; std::set edges_found_in_faces; - for (std::vector>::iterator it = faces.begin(); it != faces.end(); ++it) { - std::shared_ptr face = *it; + for (auto it = faces.begin(); it != faces.end(); ++it) { + auto face = (*it); if (verbosity >= 10) { //FID calls are expensive //TODO put an ID field in Face and others? @@ -526,7 +542,7 @@ void Arrangement::test_consistency() debug() << " PROBLEM: face" << FID(face) << "has null edge pointer."; face_problem = true; } else { - std::shared_ptr start = face->get_boundary(); + auto start = face->get_boundary(); edges_found_in_faces.insert(HID(start)); if (start->get_face() != face) { @@ -537,7 +553,7 @@ void Arrangement::test_consistency() if (start->get_next() == nullptr) debug() << " PROBLEM: starting halfedge" << HID(start) << "of face" << FID(face) << "has nullptr next pointer."; else { - std::shared_ptr cur = start->get_next(); + auto cur = start->get_next(); int i = 0; while (cur != start) { edges_found_in_faces.insert(HID(cur)); @@ -574,8 +590,8 @@ void Arrangement::test_consistency() if (halfedges.size() < 2) { debug() << "Only " << halfedges.size() << "halfedges present!"; } - std::shared_ptr start = halfedges[1]; - std::shared_ptr cur = start; + auto start = halfedges[1]; + auto cur = start; do { edges_found_in_faces.insert(HID(cur)); @@ -602,11 +618,11 @@ void Arrangement::test_consistency() bool curve_problem = false; std::set edges_found_in_curves; - for (std::set>::iterator it = all_anchors.begin(); it != all_anchors.end(); ++it) { - std::shared_ptr anchor = *it; + for (auto it = all_anchors.begin(); it != all_anchors.end(); ++it) { + auto anchor = *it; debug() << " Checking line for anchor (" << anchor->get_x() << "," << anchor->get_y() << ")"; - std::shared_ptr edge = anchor->get_line(); + Halfedge* edge = anchor->get_line(); do { edges_found_in_curves.insert(HID(edge)); edges_found_in_curves.insert(HID(edge->get_twin())); @@ -666,7 +682,7 @@ void Arrangement::test_consistency() //check anchor lines debug() << "Checking order of vertices along right edge of the strip:"; - std::shared_ptr redge = halfedges[3]; + auto redge = halfedges[3]; while (redge != halfedges[1]) { debug() << " y = " << redge->get_origin()->get_y() << "at vertex" << VID(redge->get_origin()); redge = redge->get_next(); @@ -677,7 +693,7 @@ void Arrangement::test_consistency() //Crossing constructor //precondition: Anchors a and b must be comparable -Arrangement::Crossing::Crossing(std::shared_ptr a, std::shared_ptr b, std::shared_ptr m) +Arrangement::Crossing::Crossing(Anchor* a, Anchor* b, Arrangement* m) : a(a) , b(b) , m(m) @@ -712,7 +728,7 @@ bool Arrangement::CrossingComparator::operator()(const Crossing& c1, const Cross throw std::runtime_error("Inverted crossing error"); } - std::shared_ptr m = c1.m; //makes it easier to reference arrays in the arrangement + Arrangement* m = c1.m; //makes it easier to reference arrays in the arrangement //now do the comparison //if the x-coordinates are nearly equal as double values, then compare exact values diff --git a/dcel/arrangement.h b/dcel/arrangement.h index fc21d79f..31859607 100644 --- a/dcel/arrangement.h +++ b/dcel/arrangement.h @@ -46,6 +46,7 @@ class Vertex; class ArrangementMessage; + class Arrangement { //TODO: refactor so Arrangement doesn't need friends. friend class PersistenceUpdater; @@ -60,6 +61,8 @@ class Arrangement { // requires references to vectors of all multi-grade values (both double and exact values) Arrangement(std::vector xe, std::vector ye, unsigned verbosity); + ~Arrangement(); + //returns barcode template associated with the specified line (point) BarcodeTemplate& get_barcode_template(double degrees, double offset); @@ -87,42 +90,42 @@ class Arrangement { friend std::ostream& operator<<(std::ostream&, const Arrangement&); friend std::istream& operator>>(std::istream&, Arrangement&); - std::shared_ptr insert_vertex(std::shared_ptr edge, double x, double y); //inserts a new vertex on the specified edge, with the specified coordinates, and updates all relevant pointers + Halfedge* insert_vertex(Halfedge* edge, double x, double y); //inserts a new vertex on the specified edge, with the specified coordinates, and updates all relevant pointers private: //data structures std::vector x_grades; //floating-point values for x-grades std::vector y_grades; //floating-point values for y-grades - std::vector> vertices; //all vertices in the arrangement - std::vector> halfedges; //all halfedges in the arrangement - std::vector> faces; //all faces in the arrangement + std::vector vertices; //all vertices in the arrangement + std::vector halfedges; //all halfedges in the arrangement + std::vector faces; //all faces in the arrangement unsigned verbosity; //set of Anchors that are represented in the arrangement, ordered by position of curve along left side of the arrangement, from bottom to top - std::set, PointerComparator> all_anchors; + std::set> all_anchors; - std::shared_ptr topleft; //pointer to Halfedge that points down from top left corner (0,infty) - std::shared_ptr topright; //pointer to Halfedge that points down from the top right corner (infty,infty) - std::shared_ptr bottomleft; //pointer to Halfedge that points up from bottom left corner (0,-infty) - std::shared_ptr bottomright; //pointer to Halfedge that points up from bottom right corner (infty,-infty) + Halfedge* topleft; //pointer to Halfedge that points down from top left corner (0,infty) + Halfedge* topright; //pointer to Halfedge that points down from the top right corner (infty,infty) + Halfedge* bottomleft; //pointer to Halfedge that points up from bottom left corner (0,-infty) + Halfedge* bottomright; //pointer to Halfedge that points up from bottom right corner (infty,-infty) //stores a pointer to the rightmost Halfedge of the "top" line of each unique slope, ordered from small slopes to big slopes (each Halfedge points to Anchor and Face for vertical-line queries) - std::vector> vertical_line_query_list; + std::vector vertical_line_query_list; ///// functions for creating the arrangement ///// //creates the first pair of Halfedges in an anchor line, anchored on the left edge of the strip - std::shared_ptr create_edge_left(std::shared_ptr edge, std::shared_ptr anchor); + Halfedge* create_edge_left(Halfedge* edge, Anchor* anchor); //computes and stores the edge weight for each anchor line void find_edge_weights(PersistenceUpdater& updater); //finds a pseudo-optimal path through all 2-cells of the arrangement - void find_path(std::vector>& pathvec); + void find_path(std::vector& pathvec); //builds the path recursively - void find_subpath(unsigned cur_node, std::vector>& adj, std::vector>& pathvec, bool return_path); + void find_subpath(unsigned cur_node, std::vector>& adj, std::vector& pathvec, bool return_path); //stores (a copy of) the given barcode template in faces[i]; used for re-building the arrangement from a RIVET data file void set_barcode_template(unsigned i, BarcodeTemplate& bt); @@ -130,33 +133,32 @@ class Arrangement { ///// functions for searching the arrangement ///// //finds the first anchor that intersects the left edge of the arrangement at a point not less than the specified y-coordinate; if no such anchor, returns NULL - std::shared_ptr find_least_upper_anchor(double y_coord); + Anchor* find_least_upper_anchor(double y_coord); //finds the (unbounded) cell associated to dual point of the vertical line with the given x-coordinate // i.e. finds the Halfedge whose anchor x-coordinate is the largest such coordinate not larger than than x_coord; returns the Face corresponding to that Halfedge - std::shared_ptr find_vertical_line(double x_coord); + Face* find_vertical_line(double x_coord); //finds a 2-cell containing the specified point - std::shared_ptr find_point(double x_coord, double y_coord); + Face* find_point(double x_coord, double y_coord); ///// functions for testing ///// long HID(Halfedge* h) const; //halfedge ID, for printing and debugging - long HID(std::shared_ptr h) const; //halfedge ID, for printing and debugging - long FID(std::shared_ptr f) const; //face ID, for printing and debugging - long AID(std::shared_ptr a) const; //anchor ID, for printing and debugging - long VID(std::shared_ptr v) const; //vertex ID, for printing and debugging + long FID(Face* f) const; //face ID, for printing and debugging + long AID(Anchor* a) const; //anchor ID, for printing and debugging + long VID(Vertex* v) const; //vertex ID, for printing and debugging - void announce_next_point(std::shared_ptr finder, std::shared_ptr next_pt); + void announce_next_point(Halfedge* finder, Vertex* next_pt); //struct to hold a future intersection event -- used when building the arrangement struct Crossing { - std::shared_ptr a; //pointer to one line - std::shared_ptr b; //pointer to the other line -- must ensure that line for anchor a is below line for anchor b just before the crossing point!!!!! + Anchor* a; //pointer to one line + Anchor* b; //pointer to the other line -- must ensure that line for anchor a is below line for anchor b just before the crossing point!!!!! double x; //x-coordinate of intersection point (floating-point) - std::shared_ptr m; //pointer to the arrangement, so the Crossing has access to the vectors x_grades, x_exact, y_grades, and y_exact + Arrangement* m; //pointer to the arrangement, so the Crossing has access to the vectors x_grades, x_exact, y_grades, and y_exact - Crossing(std::shared_ptr a, std::shared_ptr b, std::shared_ptr m); //precondition: Anchors a and b must be comparable + Crossing(Anchor* a, Anchor* b, Arrangement* m); //precondition: Anchors a and b must be comparable bool x_equal(const Crossing* other) const; //returns true iff this Crossing has (exactly) the same x-coordinate as other Crossing }; diff --git a/dcel/arrangement_builder.cpp b/dcel/arrangement_builder.cpp index 3fec41e4..bbe987d9 100644 --- a/dcel/arrangement_builder.cpp +++ b/dcel/arrangement_builder.cpp @@ -64,7 +64,7 @@ std::shared_ptr ArrangementBuilder::build_arrangement(MultiBetti& m //now that we have all the anchors, we can build the interior of the arrangement progress.progress(25); timer.restart(); - build_interior(arrangement); + build_interior(*arrangement); if (verbosity >= 2) { debug() << "Line arrangement constructed; this took " << timer.elapsed() << " milliseconds."; if (verbosity >= 4) { @@ -82,7 +82,7 @@ std::shared_ptr ArrangementBuilder::build_arrangement(MultiBetti& m //now that the arrangement is constructed, we can find a path -- NOTE: path starts with a (near-vertical) line to the right of all multigrades progress.progress(75); - std::vector> path; + std::vector path; timer.restart(); find_path(*arrangement, path); if (verbosity >= 2) { @@ -120,7 +120,7 @@ std::shared_ptr ArrangementBuilder::build_arrangement(std::vector= 2) { debug() << "Line arrangement constructed; this took " << timer.elapsed() << " milliseconds."; if (verbosity >= 4) { @@ -149,28 +149,28 @@ std::shared_ptr ArrangementBuilder::build_arrangement(std::vector arrangement) +void ArrangementBuilder::build_interior(Arrangement &arrangement) { if (verbosity >= 8) { debug() << "BUILDING ARRANGEMENT: Anchors sorted for left edge of strip: "; - for (std::set, Anchor_LeftComparator>::iterator it = arrangement->all_anchors.begin(); - it != arrangement->all_anchors.end(); ++it) + for (auto it = arrangement.all_anchors.begin(); + it != arrangement.all_anchors.end(); ++it) debug(true) << "(" << (*it)->get_x() << "," << (*it)->get_y() << ") "; } // DATA STRUCTURES //data structure for ordered list of lines - std::vector> lines; - lines.reserve(arrangement->all_anchors.size()); + std::vector lines; + lines.reserve(arrangement.all_anchors.size()); //data structure for queue of future intersections - std::priority_queue, - std::vector>, + std::priority_queue, PointerComparator> crossings; //data structure for all pairs of Anchors whose potential crossings have been considered - typedef std::pair, std::shared_ptr> Anchor_pair; + typedef std::pair Anchor_pair; std::set considered_pairs; // PART 1: INSERT VERTICES AND EDGES ALONG LEFT EDGE OF THE ARRANGEMENT @@ -179,11 +179,11 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement } //for each Anchor, create vertex and associated halfedges, anchored on the left edge of the strip - std::shared_ptr leftedge = arrangement->bottomleft; + auto leftedge = arrangement.bottomleft; unsigned prev_y = std::numeric_limits::max(); - for (std::set, Anchor_LeftComparator>::iterator it = arrangement->all_anchors.begin(); - it != arrangement->all_anchors.end(); ++it) { - std::shared_ptr cur_anchor = *it; + for (auto it = arrangement.all_anchors.begin(); + it != arrangement.all_anchors.end(); ++it) { + auto cur_anchor = *it; if (verbosity >= 10) { debug() << " Processing Anchor" @@ -192,13 +192,13 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement if (cur_anchor->get_y() != prev_y) //then create new vertex { - double dual_point_y_coord = -1 * arrangement->y_grades[cur_anchor->get_y()]; //point-line duality requires multiplying by -1 - leftedge = arrangement->insert_vertex(leftedge, 0, dual_point_y_coord); //set leftedge to edge that will follow the new edge + double dual_point_y_coord = -1 * arrangement.y_grades[cur_anchor->get_y()]; //point-line duality requires multiplying by -1 + leftedge = arrangement.insert_vertex(leftedge, 0, dual_point_y_coord); //set leftedge to edge that will follow the new edge prev_y = cur_anchor->get_y(); //remember the discrete y-index } //now insert new edge at origin vertex of leftedge - std::shared_ptr new_edge = arrangement->create_edge_left(leftedge, cur_anchor); + auto new_edge = arrangement.create_edge_left(leftedge, cur_anchor); //remember Halfedge corresponding to this Anchor lines.push_back(new_edge); @@ -212,10 +212,10 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement //for each pair of consecutive lines, if they intersect, store the intersection for (unsigned i = 0; i + 1 < lines.size(); i++) { - std::shared_ptr a = lines[i]->get_anchor(); - std::shared_ptr b = lines[i + 1]->get_anchor(); + auto a = lines[i]->get_anchor(); + auto b = lines[i + 1]->get_anchor(); if (a->comparable(*b)) //then the Anchors are (strongly) comparable, so we must store an intersection - crossings.push(std::make_shared(a, b, arrangement)); + crossings.push(new Arrangement::Crossing(a, b, &arrangement)); //remember that we have now considered this intersection considered_pairs.insert(Anchor_pair(a, b)); @@ -231,7 +231,7 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement int status_interval = 10000; //controls frequency of output //current position of sweep line - std::shared_ptr sweep = NULL; + Arrangement::Crossing *sweep = nullptr; while (!crossings.empty()) { //get the next intersection from the queue @@ -250,7 +250,7 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement } //find out if more than two curves intersect at this point - while (!crossings.empty() && sweep->x_equal(crossings.top().get()) && (cur->b == crossings.top()->a)) { + while (!crossings.empty() && sweep->x_equal(crossings.top()) && (cur->b == crossings.top()->a)) { cur = crossings.top(); crossings.pop(); @@ -262,7 +262,7 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement } //compute y-coordinate of intersection - double intersect_y = arrangement->x_grades[sweep->a->get_x()] * (sweep->x) - arrangement->y_grades[sweep->a->get_y()]; + double intersect_y = arrangement.x_grades[sweep->a->get_x()] * (sweep->x) - arrangement.y_grades[sweep->a->get_y()]; if (verbosity >= 10) { debug() << " found intersection between" @@ -270,23 +270,23 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement } //create new vertex - auto new_vertex = std::make_shared(sweep->x, intersect_y); - arrangement->vertices.push_back(new_vertex); + auto new_vertex = new Vertex(sweep->x, intersect_y); + arrangement.vertices.push_back(new_vertex); //anchor edges to vertex and create new face(s) and edges //TODO: check this!!! - std::shared_ptr prev_new_edge = NULL; //necessary to remember the previous new edge at each interation of the loop - std::shared_ptr first_incoming = lines[first_pos]; //necessary to remember the first incoming edge - std::shared_ptr prev_incoming = NULL; //necessary to remember the previous incoming edge at each iteration of the loop + Halfedge* prev_new_edge = NULL; //necessary to remember the previous new edge at each interation of the loop + Halfedge* first_incoming = lines[first_pos]; //necessary to remember the first incoming edge + Halfedge* prev_incoming = NULL; //necessary to remember the previous incoming edge at each iteration of the loop for (unsigned cur_pos = first_pos; cur_pos <= last_pos; cur_pos++) { //anchor edge to vertex - std::shared_ptr incoming = lines[cur_pos]; + auto incoming = lines[cur_pos]; incoming->get_twin()->set_origin(new_vertex); //create next pair of twin halfedges along the current curve (i.e. curves[incident_edges[i]] ) - std::shared_ptr new_edge(new Halfedge(new_vertex, incoming->get_anchor())); //points AWAY FROM new_vertex - arrangement->halfedges.push_back(new_edge); - std::shared_ptr new_twin(new Halfedge(NULL, incoming->get_anchor())); //points TOWARDS new_vertex - arrangement->halfedges.push_back(new_twin); + auto new_edge = new Halfedge(new_vertex, incoming->get_anchor()); //points AWAY FROM new_vertex + arrangement.halfedges.push_back(new_edge); + auto new_twin = new Halfedge(NULL, incoming->get_anchor()); //points TOWARDS new_vertex + arrangement.halfedges.push_back(new_twin); //update halfedge pointers new_edge->set_twin(new_twin); @@ -303,8 +303,8 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement incoming->set_next(prev_incoming->get_twin()); incoming->get_next()->set_prev(incoming); - std::shared_ptr new_face(new Face(new_twin, arrangement->faces.size())); - arrangement->faces.push_back(new_face); + auto new_face = new Face(new_twin, arrangement.faces.size()); + arrangement.faces.push_back(new_face); new_twin->set_face(new_face); prev_new_edge->set_face(new_face); @@ -335,7 +335,7 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement //update lines vector: flip portion of vector [first_pos, last_pos] for (unsigned i = 0; i < (last_pos - first_pos + 1) / 2; i++) { //swap curves[first_pos + i] and curves[last_pos - i] - std::shared_ptr temp = lines[first_pos + i]; + auto temp = lines[first_pos + i]; lines[first_pos + i] = lines[last_pos - i]; lines[last_pos - i] = temp; } @@ -343,29 +343,29 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement //find new intersections and add them to intersections queue if (first_pos > 0) //then consider lower intersection { - std::shared_ptr a = lines[first_pos - 1]->get_anchor(); - std::shared_ptr b = lines[first_pos]->get_anchor(); + auto a = lines[first_pos - 1]->get_anchor(); + auto b = lines[first_pos]->get_anchor(); if (considered_pairs.find(Anchor_pair(a, b)) == considered_pairs.end() && considered_pairs.find(Anchor_pair(b, a)) == considered_pairs.end()) //then this pair has not yet been considered { considered_pairs.insert(Anchor_pair(a, b)); if (a->comparable(*b)) //then the Anchors are (strongly) comparable, so we have found an intersection to store - crossings.push(std::make_shared(a, b, arrangement)); + crossings.push(new Arrangement::Crossing(a, b, &arrangement)); } } if (last_pos + 1 < lines.size()) //then consider upper intersection { - std::shared_ptr a = lines[last_pos]->get_anchor(); - std::shared_ptr b = lines[last_pos + 1]->get_anchor(); + auto a = lines[last_pos]->get_anchor(); + auto b = lines[last_pos + 1]->get_anchor(); if (considered_pairs.find(Anchor_pair(a, b)) == considered_pairs.end() && considered_pairs.find(Anchor_pair(b, a)) == considered_pairs.end()) //then this pair has not yet been considered { considered_pairs.insert(Anchor_pair(a, b)); if (a->comparable(*b)) //then the Anchors are (strongly) comparable, so we have found an intersection to store - crossings.push(std::make_shared(a, b, arrangement)); + crossings.push(new Arrangement::Crossing(a, b, &arrangement)); } } @@ -382,7 +382,7 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement debug() << "PART 3: RIGHT EDGE OF THE ARRANGEMENT"; } - std::shared_ptr rightedge = arrangement->bottomright; //need a reference halfedge along the right side of the strip + auto rightedge = arrangement.bottomright; //need a reference halfedge along the right side of the strip unsigned cur_x = 0; //keep track of discrete x-coordinate of last Anchor whose line was connected to right edge (x-coordinate of Anchor is slope of line) //connect each line to the right edge of the arrangement (at x = INFTY) @@ -390,28 +390,28 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement // lines that have the same slope m are "tied together" at the same vertex, with coordinates (INFTY, Y) // where Y = INFTY if m is positive, Y = -INFTY if m is negative, and Y = 0 if m is zero for (unsigned cur_pos = 0; cur_pos < lines.size(); cur_pos++) { - std::shared_ptr incoming = lines[cur_pos]; - std::shared_ptr cur_anchor = incoming->get_anchor(); + auto incoming = lines[cur_pos]; + auto cur_anchor = incoming->get_anchor(); if (cur_anchor->get_x() > cur_x || cur_pos == 0) //then create a new vertex for this line { cur_x = cur_anchor->get_x(); double Y = INFTY; //default, for lines with positive slope - if (arrangement->x_grades[cur_x] < 0) + if (arrangement.x_grades[cur_x] < 0) Y = -1 * Y; //for lines with negative slope - else if (arrangement->x_grades[cur_x] == 0) + else if (arrangement.x_grades[cur_x] == 0) Y = 0; //for horizontal lines - rightedge = arrangement->insert_vertex(rightedge, INFTY, Y); + rightedge = arrangement.insert_vertex(rightedge, INFTY, Y); } else //no new vertex required, but update previous entry for vertical-line queries - arrangement->vertical_line_query_list.pop_back(); + arrangement.vertical_line_query_list.pop_back(); //store Halfedge for vertical-line queries - arrangement->vertical_line_query_list.push_back(incoming->get_twin()); + arrangement.vertical_line_query_list.push_back(incoming->get_twin()); //connect current line to the most-recently-inserted vertex - std::shared_ptr cur_vertex = rightedge->get_origin(); + auto cur_vertex = rightedge->get_origin(); incoming->get_twin()->set_origin(cur_vertex); //update halfedge pointers @@ -431,8 +431,8 @@ void ArrangementBuilder::build_interior(std::shared_ptr arrangement //computes and stores the edge weight for each anchor line void ArrangementBuilder::find_edge_weights(Arrangement& arrangement, PersistenceUpdater& updater) { - std::vector> pathvec; - std::shared_ptr cur_edge = arrangement.topright; + std::vector pathvec; + auto cur_edge = arrangement.topright; //find a path across all anchor lines while (cur_edge->get_twin() != arrangement.bottomright) //then there is another vertex to consider on the right edge @@ -457,7 +457,7 @@ void ArrangementBuilder::find_edge_weights(Arrangement& arrangement, Persistence //finds a pseudo-optimal path through all 2-cells of the arrangement // path consists of a vector of Halfedges // at each step of the path, the Halfedge points to the Anchor being crossed and the 2-cell (Face) being entered -void ArrangementBuilder::find_path(Arrangement& arrangement, std::vector>& pathvec) +void ArrangementBuilder::find_path(Arrangement& arrangement, std::vector& pathvec) { // PART 1: BUILD THE DUAL GRAPH OF THE ARRANGEMENT @@ -475,11 +475,11 @@ void ArrangementBuilder::find_path(Arrangement& arrangement, std::vector boundary = (arrangement.faces[i])->get_boundary(); - std::shared_ptr current = boundary; + auto boundary = (arrangement.faces[i])->get_boundary(); + auto current = boundary; do { //find index of neighbor - std::shared_ptr neighbor = current->get_twin()->get_face(); + auto neighbor = current->get_twin()->get_face(); if (neighbor != NULL) { unsigned long j = neighbor->id(); @@ -530,7 +530,7 @@ void ArrangementBuilder::find_path(Arrangement& arrangement, std::vector initial_cell = arrangement.topleft->get_twin()->get_face(); + auto initial_cell = arrangement.topleft->get_twin()->get_face(); unsigned long start = initial_cell->id(); //store the children of each node (with initial_cell regarded as the root of the tree) @@ -560,11 +560,14 @@ void ArrangementBuilder::find_path(Arrangement& arrangement, std::vector>& children, std::vector>& pathvec) +void ArrangementBuilder::find_subpath(Arrangement& arrangement, + unsigned start_node, + std::vector>& children, + std::vector& pathvec) { std::stack nodes; // stack for nodes as we do DFS nodes.push(start_node); // push node onto the node stack - std::stack> backtrack; // stack for storing extra copy of std::shared_ptr* so we don't have to recalculate when popping + std::stack backtrack; // stack for storing extra copy of std::shared_ptr* so we don't have to recalculate when popping unsigned numDiscovered = 1, numNodes = children.size(); while (numDiscovered != numNodes) // while we have not traversed the whole tree @@ -577,7 +580,7 @@ void ArrangementBuilder::find_subpath(Arrangement& arrangement, unsigned start_n unsigned next_node = children[node].back(); children[node].pop_back(); - std::shared_ptr cur_edge = (arrangement.faces[node])->get_boundary(); + auto cur_edge = (arrangement.faces[node])->get_boundary(); while (cur_edge->get_twin()->get_face() != arrangement.faces[next_node]) { cur_edge = cur_edge->get_next(); diff --git a/dcel/arrangement_builder.h b/dcel/arrangement_builder.h index de85e5a0..8daa6671 100644 --- a/dcel/arrangement_builder.h +++ b/dcel/arrangement_builder.h @@ -49,12 +49,12 @@ class ArrangementBuilder { private: unsigned verbosity; - void build_interior(std::shared_ptr arrangement); + void build_interior(Arrangement &arrangement); //builds the interior of DCEL arrangement using a version of the Bentley-Ottmann algorithm //precondition: all achors have been stored via find_anchors() void find_edge_weights(Arrangement& arrangement, PersistenceUpdater& updater); - void find_path(Arrangement& arrangement, std::vector>& pathvec); - void find_subpath(Arrangement& arrangement, unsigned cur_node, std::vector>& adj, std::vector>& pathvec); + void find_path(Arrangement& arrangement, std::vector& pathvec); + void find_subpath(Arrangement& arrangement, unsigned cur_node, std::vector>& adj, std::vector& pathvec); }; #endif //RIVET_CONSOLE_MESH_BUILDER_H diff --git a/dcel/arrangement_message.cpp b/dcel/arrangement_message.cpp index d352f492..26a1b248 100644 --- a/dcel/arrangement_message.cpp +++ b/dcel/arrangement_message.cpp @@ -29,6 +29,9 @@ along with this program. If not, see . template struct Ptr_Compare { + bool operator()(const T* left, const T* right) const { + return &(*left) < &(*right); + } bool operator()(const std::shared_ptr left, const std::shared_ptr right) const { return &(*left) < &(*right); } @@ -45,10 +48,10 @@ ArrangementMessage::ArrangementMessage(Arrangement const& arrangement) , anchors() , faces() { - std::map, long, Ptr_Compare> face_map; - std::map, long, Ptr_Compare> halfedge_map; - std::map, long, Ptr_Compare> anchor_map; - std::map, long, Ptr_Compare> vertex_map; + std::map> face_map; + std::map> halfedge_map; + std::map> anchor_map; + std::map> vertex_map; //Build maps long id_counter = 0; for(auto face : arrangement.faces) { @@ -67,22 +70,22 @@ ArrangementMessage::ArrangementMessage(Arrangement const& arrangement) vertex_map.emplace(vertex, id_counter++); } - auto HID = [&halfedge_map](const std::shared_ptr &ptr) { + auto HID = [&halfedge_map](const Halfedge* ptr) { auto it = halfedge_map.find(ptr); return it == halfedge_map.end() ? -1 : it->second; }; - auto AID = [&anchor_map](const std::shared_ptr &ptr) { + auto AID = [&anchor_map](const Anchor* ptr) { auto it = anchor_map.find(ptr); return it == anchor_map.end() ? -1 : it->second; }; - auto VID = [&vertex_map](const std::shared_ptr &ptr) { + auto VID = [&vertex_map](const Vertex* ptr) { auto it = vertex_map.find(ptr); return it == vertex_map.end() ? -1 : it->second; }; - auto FID = [&face_map](const std::shared_ptr &ptr) { + auto FID = [&face_map](const Face* ptr) { return ptr == nullptr ? -1 : ptr->id(); }; @@ -405,17 +408,17 @@ Arrangement ArrangementMessage::to_arrangement() const Arrangement arrangement; //First create all the objects for (auto vertex : vertices) { - arrangement.vertices.push_back(std::make_shared<::Vertex>(vertex.x, vertex.y)); + arrangement.vertices.push_back(new ::Vertex(vertex.x, vertex.y)); } for (size_t i = 0; i < faces.size(); i++) { - arrangement.faces.push_back(std::make_shared<::Face>(nullptr, i)); + arrangement.faces.push_back(new ::Face(nullptr, i)); } for (size_t i = 0; i < half_edges.size(); i++) { - arrangement.halfedges.push_back(std::make_shared<::Halfedge>()); + arrangement.halfedges.push_back(new ::Halfedge()); } - std::vector> temp_anchors; //For indexing, since arrangement.all_anchors is a set + std::vector<::Anchor*> temp_anchors; //For indexing, since arrangement.all_anchors is a set for (auto anchor : anchors) { - std::shared_ptr<::Anchor> ptr = std::make_shared<::Anchor>(anchor.x_coord, anchor.y_coord); + auto ptr = new ::Anchor(anchor.x_coord, anchor.y_coord); assert(anchor.x_coord == ptr->get_x()); assert(anchor.y_coord == ptr->get_y()); temp_anchors.push_back(ptr); @@ -423,7 +426,7 @@ Arrangement ArrangementMessage::to_arrangement() const // std::cout << "building anchors" << std::endl; arrangement.all_anchors.clear(); - arrangement.all_anchors = std::set, PointerComparator<::Anchor, Anchor_LeftComparator>>(temp_anchors.begin(), temp_anchors.end()); + arrangement.all_anchors = std::set>(temp_anchors.begin(), temp_anchors.end()); assert(arrangement.all_anchors.size() == anchors.size()); @@ -487,9 +490,9 @@ Arrangement ArrangementMessage::to_arrangement() const ::Anchor& anchor = **it; ArrangementMessage::AnchorM ref = anchors[i]; if (ref.dual_line != HalfedgeId::invalid()) { - std::shared_ptr<::Halfedge> edge = arrangement.halfedges[static_cast(ref.dual_line)]; + auto edge = arrangement.halfedges[static_cast(ref.dual_line)]; //TODO: why, oh why, should this reset be necessary? - anchor.get_line().reset(); +// anchor.get_line().reset(); anchor.set_line(edge); } if (ref.above_line != anchor.is_above()) { diff --git a/dcel/dcel.cpp b/dcel/dcel.cpp index f90adb61..355d71be 100644 --- a/dcel/dcel.cpp +++ b/dcel/dcel.cpp @@ -41,12 +41,12 @@ Vertex::Vertex() { } -void Vertex::set_incident_edge(std::shared_ptr edge) +void Vertex::set_incident_edge(Halfedge* edge) { incident_edge = edge; } -std::shared_ptr Vertex::get_incident_edge() +Halfedge* Vertex::get_incident_edge() { return incident_edge; } @@ -75,7 +75,7 @@ bool Vertex::operator==(Vertex const& other) /*** implementation of class Halfedge ***/ -Halfedge::Halfedge(std::shared_ptr v, std::shared_ptr p) +Halfedge::Halfedge(Vertex* v, Anchor* p) : origin(v) , twin(nullptr) , next(nullptr) @@ -95,69 +95,69 @@ Halfedge::Halfedge() { } -void Halfedge::set_twin(std::shared_ptr e) +void Halfedge::set_twin(Halfedge* e) { twin = e; } -std::shared_ptr Halfedge::get_twin() const +Halfedge* Halfedge::get_twin() const { return twin; } -void Halfedge::set_next(std::shared_ptr e) +void Halfedge::set_next(Halfedge* e) { next = e; } -std::shared_ptr Halfedge::get_next() const +Halfedge* Halfedge::get_next() const { return next; } -void Halfedge::set_prev(std::shared_ptr e) +void Halfedge::set_prev(Halfedge* e) { prev = e; } -std::shared_ptr Halfedge::get_prev() const +Halfedge* Halfedge::get_prev() const { return prev; } -void Halfedge::set_origin(std::shared_ptr v) +void Halfedge::set_origin(Vertex* v) { origin = v; } -std::shared_ptr Halfedge::get_origin() const +Vertex* Halfedge::get_origin() const { return origin; } -void Halfedge::set_face(std::shared_ptr f) +void Halfedge::set_face(Face* f) { face = f; } -std::shared_ptr Halfedge::get_face() const +Face* Halfedge::get_face() const { return face; } -void Halfedge::set_anchor(std::shared_ptr anchor) +void Halfedge::set_anchor(Anchor* anchor) { this->anchor = anchor; } -std::shared_ptr Halfedge::get_anchor() const +Anchor* Halfedge::get_anchor() const { return anchor; } Debug& operator<<(Debug& qd, const Halfedge& e) { - std::shared_ptr t = e.twin; + Halfedge* t = e.twin; qd << *(e.origin) << "--" << *(t->origin) << "; "; if (e.anchor == nullptr) qd << "Anchor null; "; @@ -168,7 +168,7 @@ Debug& operator<<(Debug& qd, const Halfedge& e) /*** implementation of class Face ***/ -Face::Face(std::shared_ptr e, unsigned long id) +Face::Face(Halfedge* e, unsigned long id) : boundary(e) , visited(false) , identifier(id) @@ -186,12 +186,12 @@ Face::~Face() { } -void Face::set_boundary(std::shared_ptr e) +void Face::set_boundary(Halfedge* e) { boundary = e; } -std::shared_ptr Face::get_boundary() +Halfedge* Face::get_boundary() { return boundary; } @@ -218,8 +218,8 @@ void Face::mark_as_visited() Debug& operator<<(Debug& qd, const Face& f) { - std::shared_ptr start = f.boundary; - std::shared_ptr curr = start; + Halfedge* start = f.boundary; + Halfedge* curr = start; do { qd << *(curr->get_origin()) << "--"; curr = curr->get_next(); diff --git a/dcel/dcel.h b/dcel/dcel.h index 1bd11ec1..c083dde0 100644 --- a/dcel/dcel.h +++ b/dcel/dcel.h @@ -45,8 +45,8 @@ class Vertex { Vertex(double x_coord, double y_coord); //constructor, sets (x, y)-coordinates of the vertex Vertex(); //For serialization - void set_incident_edge(std::shared_ptr edge); //set the incident edge - std::shared_ptr get_incident_edge(); //get the incident edge + void set_incident_edge(Halfedge* edge); //set the incident edge + Halfedge* get_incident_edge(); //get the incident edge double get_x(); //get the x-coordinate double get_y(); //get the y-coordinate @@ -59,7 +59,7 @@ class Vertex { void serialize(Archive& ar, const unsigned int version); private: - std::shared_ptr incident_edge; //pointer to one edge incident to this vertex + Halfedge* incident_edge; //pointer to one edge incident to this vertex double x; //x-coordinate of this vertex double y; //y-coordinate of this vertex @@ -70,26 +70,26 @@ class Anchor; class Halfedge { public: - Halfedge(std::shared_ptr v, std::shared_ptr p); //constructor, requires origin vertex as well as Anchor corresponding to this halfedge (Anchor never changes) + Halfedge(Vertex* v, Anchor* p); //constructor, requires origin vertex as well as Anchor corresponding to this halfedge (Anchor never changes) Halfedge(); //constructor for a null Halfedge - void set_twin(std::shared_ptr e); //set the twin halfedge - std::shared_ptr get_twin() const; //get the twin halfedge + void set_twin(Halfedge* e); //set the twin halfedge + Halfedge* get_twin() const; //get the twin halfedge - void set_next(std::shared_ptr e); //set the next halfedge in the boundary of the face that this halfedge borders - std::shared_ptr get_next() const; //get the next halfedge + void set_next(Halfedge* e); //set the next halfedge in the boundary of the face that this halfedge borders + Halfedge* get_next() const; //get the next halfedge - void set_prev(std::shared_ptr e); //set the previous halfedge in the boundary of the face that this halfedge borders - std::shared_ptr get_prev() const; //get the previous halfedge + void set_prev(Halfedge* e); //set the previous halfedge in the boundary of the face that this halfedge borders + Halfedge* get_prev() const; //get the previous halfedge - void set_origin(std::shared_ptr v); //set the origin vertex - std::shared_ptr get_origin() const; //get the origin vertex + void set_origin(Vertex* v); //set the origin vertex + Vertex* get_origin() const; //get the origin vertex - void set_face(std::shared_ptr f); //set the face that this halfedge borders - std::shared_ptr get_face() const; //get the face that this halfedge borders + void set_face(Face* f); //set the face that this halfedge borders + Face* get_face() const; //get the face that this halfedge borders - void set_anchor(std::shared_ptr); //set the Anchor - std::shared_ptr get_anchor() const; //get the Anchor + void set_anchor(Anchor*); //set the Anchor + Anchor* get_anchor() const; //get the Anchor friend Debug& operator<<(Debug& qd, const Halfedge& e); //for printing the halfedge @@ -97,23 +97,23 @@ class Halfedge { void serialize(Archive& ar, const unsigned int version); private: - std::shared_ptr origin; //pointer to the vertex from which this halfedge originates - std::shared_ptr twin; //pointer to the halfedge that, together with this halfedge, make one edge - std::shared_ptr next; //pointer to the next halfedge around the boundary of the face to the right of this halfedge - std::shared_ptr prev; //pointer to the previous halfedge around the boundary of the face to the right of this halfedge - std::shared_ptr face; //pointer to the face to the right of this halfedge - std::shared_ptr anchor; //stores the coordinates of the anchor corresponding to this halfedge + Vertex* origin; //pointer to the vertex from which this halfedge originates + Halfedge* twin; //pointer to the halfedge that, together with this halfedge, make one edge + Halfedge* next; //pointer to the next halfedge around the boundary of the face to the right of this halfedge + Halfedge* prev; //pointer to the previous halfedge around the boundary of the face to the right of this halfedge + Face* face; //pointer to the face to the right of this halfedge + Anchor* anchor; //stores the coordinates of the anchor corresponding to this halfedge }; //end class Halfedge class Face { public: - Face(std::shared_ptr e, unsigned long id); //constructor: requires pointer to a boundary halfedge + Face(Halfedge* e, unsigned long id); //constructor: requires pointer to a boundary halfedge Face(); // For serialization ~Face(); //destructor: destroys barcode template - void set_boundary(std::shared_ptr e); //set the pointer to a halfedge on the boundary of this face - std::shared_ptr get_boundary(); //get the (pointer to the) boundary halfedge + void set_boundary(Halfedge* e); //set the pointer to a halfedge on the boundary of this face + Halfedge* get_boundary(); //get the (pointer to the) boundary halfedge BarcodeTemplate& get_barcode(); //returns a reference to the barcode template stored in this cell void set_barcode(const BarcodeTemplate& bt); //stores (a copy of) the specified barcode template in this cell @@ -129,7 +129,7 @@ class Face { unsigned long id() const; private: - std::shared_ptr boundary; //pointer to one halfedge in the boundary of this cell + Halfedge* boundary; //pointer to one halfedge in the boundary of this cell BarcodeTemplate dbc; //barcode template stored in this cell bool visited; //initially false, set to true after this cell has been visited in the vineyard-update process (so that we can distinguish a cell with an empty barcode from an unvisited cell) unsigned long identifier; // Arrangement-specific ID for this face diff --git a/math/persistence_updater.cpp b/math/persistence_updater.cpp index 99e93924..a6ac9667 100644 --- a/math/persistence_updater.cpp +++ b/math/persistence_updater.cpp @@ -64,7 +64,7 @@ PersistenceUpdater::PersistenceUpdater(Arrangement& m, SimplexTree& b, std::vect //computes and stores a barcode template in each 2-cell of arrangement //resets the matrices and does a standard persistence calculation for expensive crossings -void PersistenceUpdater::store_barcodes_with_reset(std::vector>& path, Progress& progress) +void PersistenceUpdater::store_barcodes_with_reset(std::vector& path, Progress& progress) { // PART 1: GET THE BOUNDARY MATRICES WITH PROPER SIMPLEX ORDERING @@ -140,7 +140,7 @@ void PersistenceUpdater::store_barcodes_with_reset(std::vector first_cell = arrangement.topleft->get_twin()->get_face(); + Face* first_cell = arrangement.topleft->get_twin()->get_face(); store_barcode_template(first_cell); if (verbosity >= 4) { @@ -180,12 +180,12 @@ void PersistenceUpdater::store_barcodes_with_reset(std::vector cur_anchor = (path[i])->get_anchor(); - std::shared_ptr at_anchor = cur_anchor->get_entry(); + Anchor* cur_anchor = (path[i])->get_anchor(); + TemplatePointsMatrixEntry* at_anchor = cur_anchor->get_entry(); //get equivalence classes for this anchor - std::shared_ptr down = at_anchor->down; - std::shared_ptr left = at_anchor->left; + TemplatePointsMatrixEntry* down = at_anchor->down; + TemplatePointsMatrixEntry* left = at_anchor->left; //if this is a strict anchor, then swap simplices if (down != nullptr && left != nullptr) //then this is a strict anchor and some simplices swap @@ -240,7 +240,7 @@ void PersistenceUpdater::store_barcodes_with_reset(std::vectorget_x() << ", " << cur_anchor->get_y() << ") into cell " << arrangement.FID((path[i])->get_face()) << "; edge weight: " << cur_anchor->get_weight(); } - std::shared_ptr generator = at_anchor->down; + TemplatePointsMatrixEntry* generator = at_anchor->down; if (generator == nullptr) generator = at_anchor->left; @@ -278,7 +278,7 @@ void PersistenceUpdater::store_barcodes_with_reset(std::vectortoggle(); //if this cell does not yet have a barcode template, then store it now - std::shared_ptr cur_face = (path[i])->get_face(); + Face* cur_face = (path[i])->get_face(); if (!cur_face->has_been_visited()) store_barcode_template(cur_face); @@ -350,7 +350,7 @@ void PersistenceUpdater::store_barcodes_with_reset(std::vector>& path) +void PersistenceUpdater::set_anchor_weights(std::vector& path) { // PART 1: GET THE PROPER SIMPLEX ORDERING @@ -376,8 +376,8 @@ void PersistenceUpdater::set_anchor_weights(std::vector cur_anchor = (path[i])->get_anchor(); - std::shared_ptr at_anchor = cur_anchor->get_entry(); + Anchor* cur_anchor = (path[i])->get_anchor(); + TemplatePointsMatrixEntry* at_anchor = cur_anchor->get_entry(); if (verbosity >= 8) { debug() << " step" << i << "of the short path: crossing anchor at (" << cur_anchor->get_x() << "," << cur_anchor->get_y() << ") into cell" << arrangement.FID((path[i])->get_face()); @@ -389,7 +389,7 @@ void PersistenceUpdater::set_anchor_weights(std::vectoris_above(), switches, separations); } else //this is a non-strict anchor, so there can be separations but not switches { - std::shared_ptr generator = (at_anchor->down != nullptr) ? at_anchor->down : at_anchor->left; + TemplatePointsMatrixEntry* generator = (at_anchor->down != nullptr) ? at_anchor->down : at_anchor->left; if ((cur_anchor->is_above() && generator == at_anchor->down) || (!cur_anchor->is_above() && generator == at_anchor->left)) //then merge classes @@ -430,7 +430,7 @@ void PersistenceUpdater::store_multigrades(IndexMatrix* ind, bool low) } //initialize linked list to track the "frontier" - typedef std::list> Frontier; + typedef std::list Frontier; Frontier frontier; //loop through rows of TemplatePointsMatrix, from top to bottom @@ -439,7 +439,7 @@ void PersistenceUpdater::store_multigrades(IndexMatrix* ind, bool low) //update the frontier for row y: // if the last element of frontier has the same x-coord as cur, then replace that element with cur // otherwise, append cur to the end of frontier - std::shared_ptr cur = template_points_matrix.get_row(y); + TemplatePointsMatrixEntry* cur = template_points_matrix.get_row(y); if (cur != nullptr) { Frontier::iterator it = frontier.end(); //the past-the-end element of frontier if (it != frontier.begin()) //then the frontier is not empty @@ -502,11 +502,11 @@ unsigned PersistenceUpdater::build_simplex_order(IndexMatrix* ind, bool low, std //count the number of simplices that will be in the order (i.e. simplices with grades less than the LUB of all xi support points) unsigned num_simplices = 0; for (unsigned row = 0; row < template_points_matrix.height(); row++) { - std::shared_ptr cur = template_points_matrix.get_row(row); + TemplatePointsMatrixEntry* cur = template_points_matrix.get_row(row); if (cur == nullptr) continue; - std::list>* mgrades = (low) ? &(cur->low_simplices) : &(cur->high_simplices); - for (std::list>::iterator it = mgrades->begin(); it != mgrades->end(); ++it) { + std::list* mgrades = (low) ? &(cur->low_simplices) : &(cur->high_simplices); + for (std::list::iterator it = mgrades->begin(); it != mgrades->end(); ++it) { num_simplices += (*it)->num_cols; } } @@ -521,7 +521,7 @@ unsigned PersistenceUpdater::build_simplex_order(IndexMatrix* ind, bool low, std //consider the rightmost TemplatePointsMatrixEntry in each row for (unsigned row = template_points_matrix.height(); row-- > 0;) //row counts down from (template_points_matrix->height() - 1) to 0 { - std::shared_ptr cur = template_points_matrix.get_row(row); + TemplatePointsMatrixEntry* cur = template_points_matrix.get_row(row); if (cur == nullptr) continue; @@ -534,14 +534,14 @@ unsigned PersistenceUpdater::build_simplex_order(IndexMatrix* ind, bool low, std *cur_ind = o_index; //get the multigrade list for this TemplatePointsMatrixEntry - std::list>* mgrades = (low) ? &(cur->low_simplices) : &(cur->high_simplices); + std::list* mgrades = (low) ? &(cur->low_simplices) : &(cur->high_simplices); //sort the multigrades in lexicographical order - mgrades->sort([](std::shared_ptr a, std::shared_ptr b) { return Multigrade::LexComparator(*a, *b); }); + mgrades->sort([](Multigrade* a, Multigrade* b) { return Multigrade::LexComparator(*a, *b); }); //store map values for all simplices at these multigrades - for (std::list>::iterator it = mgrades->begin(); it != mgrades->end(); ++it) { - std::shared_ptr mg = *it; + for (std::list::iterator it = mgrades->begin(); it != mgrades->end(); ++it) { + Multigrade* mg = *it; if (verbosity >= 10) { debug() << " multigrade (" << mg->x << "," << mg->y << ") has" << mg->num_cols << "simplices with last dim_index" << mg->simplex_index << "which will map to order_index" << o_index; } @@ -556,9 +556,9 @@ unsigned PersistenceUpdater::build_simplex_order(IndexMatrix* ind, bool low, std //if any simplices of the specified dimension were mapped to this equivalence class, then store information about this class if (*cur_ind != o_index) { if (low) - lift_low.insert(std::pair>(*cur_ind, cur)); + lift_low.insert(std::pair(*cur_ind, cur)); else - lift_high.insert(std::pair>(*cur_ind, cur)); + lift_high.insert(std::pair(*cur_ind, cur)); } } //end for(row > 0) @@ -567,12 +567,12 @@ unsigned PersistenceUpdater::build_simplex_order(IndexMatrix* ind, bool low, std //counts the number of transpositions that will happen if we cross an anchor and do vineyeard-updates //this function DOES NOT MODIFY the xiSupportMatrix -unsigned long PersistenceUpdater::count_transpositions(std::shared_ptr anchor, bool from_below) +unsigned long PersistenceUpdater::count_transpositions(TemplatePointsMatrixEntry* anchor, bool from_below) { //identify entries - std::shared_ptr first = from_below ? anchor->down : anchor->left; - std::shared_ptr second = from_below ? anchor->left : anchor->down; - std::shared_ptr temp(new TemplatePointsMatrixEntry(anchor->left->x, anchor->down->y)); + TemplatePointsMatrixEntry* first = from_below ? anchor->down : anchor->left; + TemplatePointsMatrixEntry* second = from_below ? anchor->left : anchor->down; + TemplatePointsMatrixEntry* temp(new TemplatePointsMatrixEntry(anchor->left->x, anchor->down->y)); //counters unsigned long count = 0; @@ -602,13 +602,13 @@ unsigned long PersistenceUpdater::count_transpositions(std::shared_ptr greater, std::shared_ptr lesser, bool horiz, bool low, unsigned long& count_trans, unsigned& count_lesser) +void PersistenceUpdater::count_transpositions_from_separations(TemplatePointsMatrixEntry* greater, TemplatePointsMatrixEntry* lesser, bool horiz, bool low, unsigned long& count_trans, unsigned& count_lesser) { int gr_col = greater->low_index; int cur_col = gr_col; - std::list> grades = low ? greater->low_simplices : greater->high_simplices; - for (std::list>::iterator it = grades.begin(); it != grades.end(); ++it) { - std::shared_ptr cur_grade = *it; + std::list grades = low ? greater->low_simplices : greater->high_simplices; + for (std::list::iterator it = grades.begin(); it != grades.end(); ++it) { + Multigrade* cur_grade = *it; if ((horiz && cur_grade->x > lesser->x) || (!horiz && cur_grade->y > lesser->y)) //then there will be transpositions from separations { count_trans += cur_grade->num_cols * (gr_col - cur_col); @@ -621,17 +621,17 @@ void PersistenceUpdater::count_transpositions_from_separations(std::shared_ptr greater, std::shared_ptr lesser, bool horiz) +unsigned long PersistenceUpdater::split_grade_lists(TemplatePointsMatrixEntry* greater, TemplatePointsMatrixEntry* lesser, bool horiz) { unsigned long swap_counter = 0; //low simplices int gr_col = greater->low_index; int cur_col = gr_col; - std::list> grades = greater->low_simplices; + std::list grades = greater->low_simplices; greater->low_simplices.clear(); - for (std::list>::iterator it = grades.begin(); it != grades.end(); ++it) { - std::shared_ptr cur_grade = *it; + for (std::list::iterator it = grades.begin(); it != grades.end(); ++it) { + Multigrade* cur_grade = *it; if ((horiz && cur_grade->x > lesser->x) || (!horiz && cur_grade->y > lesser->y)) //then this grade lifts to greater, so move columns to the right { if (cur_col != gr_col) //then we must move the columns @@ -653,8 +653,8 @@ unsigned long PersistenceUpdater::split_grade_lists(std::shared_ptrhigh_simplices; greater->high_simplices.clear(); - for (std::list>::iterator it = grades.begin(); it != grades.end(); ++it) { - std::shared_ptr cur_grade = *it; + for (std::list::iterator it = grades.begin(); it != grades.end(); ++it) { + Multigrade* cur_grade = *it; if ((horiz && cur_grade->x > lesser->x) || (!horiz && cur_grade->y > lesser->y)) //then this grade lifts to greater, so move columns to the right { if (cur_col != gr_col) //then we must move the columns @@ -675,17 +675,17 @@ unsigned long PersistenceUpdater::split_grade_lists(std::shared_ptr greater, std::shared_ptr lesser, bool horiz) +void PersistenceUpdater::split_grade_lists_no_vineyards(TemplatePointsMatrixEntry* greater, TemplatePointsMatrixEntry* lesser, bool horiz) { //STEP 1: update the lift map for all multigrades and store the current column index for each multigrade //first, low simpilices int gr_col = greater->low_index; int cur_col = gr_col; - std::list> grades = greater->low_simplices; + std::list grades = greater->low_simplices; greater->low_simplices.clear(); ///this isn't so efficient... - for (std::list>::iterator it = grades.begin(); it != grades.end(); ++it) { - std::shared_ptr cur_grade = *it; + for (std::list::iterator it = grades.begin(); it != grades.end(); ++it) { + Multigrade* cur_grade = *it; cur_grade->simplex_index = cur_col; if ((horiz && cur_grade->x > lesser->x) || (!horiz && cur_grade->y > lesser->y)) //then this grade lifts to greater { @@ -703,10 +703,10 @@ void PersistenceUpdater::split_grade_lists_no_vineyards(std::shared_ptr