Commit dc0aee72 authored by JasonPries's avatar JasonPries
Browse files

Fix memory leaks

parent 8e5011bb
......@@ -363,7 +363,7 @@ bool Mesh::is_protruding(size_t ei) const {
size_t nxt = next(next(ei));
while (nxt != prev(ei)) {
Point const p4 = point(nxt);
Point const p4 = base(nxt);
double v2x = p2.X - p4.X;
double v2y = p2.Y - p4.Y;
......@@ -566,7 +566,7 @@ void Mesh::create_boundary_polygon() {
bool any_split = true;
while (any_split) {
any_split = false;
for (size_t i = 0; i != Edges.size(); ++i) {
for (size_t i = 0; i != Edges.size() - 1; ++i) {
for (size_t j = i + 1; j != Edges.size(); ++j) {
if (are_intersecting(i, j)) {
any_split = true;
......
......@@ -100,7 +100,13 @@ public:
Point const base(size_t ei) const { return Points[node(ei)]; };
Point const point(size_t i) const { return Points[i]; };
Point const point(size_t i) const {
if (i >= Points.size()) {
throw;
} else {
return Points[i];
}
}; //return Points[i]; };
Point const point(Edge const e) const { return Points[e.Node]; };
......
......@@ -199,7 +199,7 @@ bool CircularArc::on_manifold(const double x, const double y) const {
}
}
bool CircularArc::is_identical(std::shared_ptr<Curve> c) const {
bool CircularArc::is_identical(std::shared_ptr<Curve> const &c) const {
//const CircularArc *cc = dynamic_cast<const CircularArc *>(c);
auto cc = std::dynamic_pointer_cast<CircularArc>(c);
......@@ -218,7 +218,7 @@ bool CircularArc::is_identical(std::shared_ptr<Curve> c) const {
}
}
bool CircularArc::is_identical(std::shared_ptr<Curve> c, std::shared_ptr<Vertex> origin, const double angle) const {
bool CircularArc::is_identical(std::shared_ptr<Curve> const &c, std::shared_ptr<Vertex> const &origin, double const angle) const {
//const CircularArc *cc = dynamic_cast<const CircularArc *>(c);
auto cc = std::dynamic_pointer_cast<CircularArc>(c);
......@@ -249,7 +249,7 @@ bool CircularArc::is_identical(const double r, const double xc, const double yc,
&& abs(end()->y() - ye) < tol;
}
bool CircularArc::is_coincident(std::shared_ptr<Curve> c) const {
bool CircularArc::is_coincident(std::shared_ptr<Curve> const &c) const {
//const CircularArc *cc = dynamic_cast<const CircularArc *>(c);
auto cc = std::dynamic_pointer_cast<CircularArc>(c);
......
......@@ -60,11 +60,11 @@ public:
using Curve::on_segment;
bool is_identical(std::shared_ptr<Curve> c) const override;
bool is_identical(std::shared_ptr<Curve> const &c) const override;
bool is_identical(std::shared_ptr<Curve> c, std::shared_ptr<Vertex> origin, const double angle) const override;
bool is_identical(std::shared_ptr<Curve> const &c, std::shared_ptr<Vertex> const &origin, double const angle) const override;
bool is_coincident(std::shared_ptr<Curve> c) const override;
bool is_coincident(std::shared_ptr<Curve> const &c) const override;
std::shared_ptr<Curve> clone() const override { return std::make_shared<CircularArc>(this); };
......
#include "Sketch.hpp"
Constellation::Constellation(const Sketch *s) {
Constellation::Constellation(Sketch const *s) {
for (size_t i = 0; i != s->size_verticies(); ++i) {
Stars.push_back(Star{s->vertex(i), s});
}
......@@ -8,8 +8,6 @@ Constellation::Constellation(const Sketch *s) {
}
bool Constellation::twin(std::list<Star>::iterator &s_out, std::list<Branch>::iterator &b_out) {
std::shared_ptr<Curve> c = b_out->Path; // #TODO: Local variable 'c' is only assigned but never accessed
for (auto s = Stars.begin(); s != Stars.end(); ++s) {
if (s != s_out) {
for (auto b = s->begin(); b != s->end(); ++b) {
......@@ -75,7 +73,7 @@ void Constellation::pop(std::shared_ptr<Curve> c) {
}
}
bool Constellation::boundary(std::shared_ptr<Contour> c) {
std::shared_ptr<Contour> Constellation::boundary() {
std::vector<std::shared_ptr<Curve>> curves;
std::vector<bool> orientation;
......@@ -95,24 +93,23 @@ bool Constellation::boundary(std::shared_ptr<Contour> c) {
bool has_twin = twin(s, b);
if (!has_twin) {
return false;
return std::make_shared<Contour>();
} else {
b = s->prev(b);
angle += 2.0 * M_PI - b->Angle;
}
if (b->Path == curves.back()) { //excludes self-closed contours
return false;
return std::make_shared<Contour>();
} else if (b->Path == curves[0]) {
double tol = (FLT_EPSILON * M_PI * (curves.size() - 1));
double expected = (curves.size() - 2) * M_PI;
double diff = abs(angle - expected);
if (diff <= tol) {
c->initialize(curves, orientation);
return true;
return std::make_shared<Contour>(curves,orientation);
} else {
return false;
return std::make_shared<Contour>();
}
} else {
curves.push_back(b->Path);
......@@ -121,20 +118,20 @@ bool Constellation::boundary(std::shared_ptr<Contour> c) {
}
}
bool Constellation::contours(std::vector<std::shared_ptr<Contour>> &contours) {
std::vector<std::shared_ptr<Contour>> Constellation::contours() {
std::vector<std::shared_ptr<Contour>> contours;
std::vector<std::shared_ptr<Curve>> contour_curves;
std::vector<bool> orientation;
while (size() > 0) {
bool success = find_closed_contour(contour_curves, orientation);
if (success) {
if (find_closed_contour(contour_curves, orientation)) {
contours.push_back(std::make_shared<Contour>(contour_curves, orientation));
} else {
return false;
return std::vector<std::shared_ptr<Contour>>(); // TODO: Ugly multiple return points
}
}
return true;
return contours;
}
bool Constellation::find_closed_contour(std::vector<std::shared_ptr<Curve>> &curves, std::vector<bool> &orientation) {
......
......@@ -8,18 +8,18 @@ public:
// Constructors
Constellation() {};
Constellation(const Sketch *s);
Constellation(Sketch const *s);
size_t size() { return Stars.size(); };
bool contours(std::vector<std::shared_ptr<Contour>> &contours);
std::vector<std::shared_ptr<Contour>> contours();
bool boundary(std::shared_ptr<Contour>);
std::shared_ptr<Contour> boundary();
private:
std::list<Star> Stars;
void pop(std::shared_ptr<Curve> c = nullptr);
void pop(std::shared_ptr<Curve> c = std::shared_ptr<Curve>());
bool twin(std::list<Star>::iterator &s_out, std::list<Branch>::iterator &b_out);
......
......@@ -65,10 +65,13 @@ Contour::Contour(std::vector<std::shared_ptr<Curve>> const &c, std::vector<bool>
}
bool Contour::initialize(std::vector<std::shared_ptr<Curve>> const &c, std::vector<bool> const &dir) {
Curves.resize(0);
Orientation.resize(0);
Curves = std::vector<std::shared_ptr<Curve>>();
Curves.reserve(c.size());
Orientation = std::vector<bool>();
Orientation.reserve(c.size());
for (size_t i = 0; i < c.size(); ++i) {
for (size_t i = 0; i != c.size(); ++i) {
Curves.push_back(c[i]);
Orientation.push_back(dir[i]);
......
#include "Sketch.hpp"
bool Curve::on_segment(std::shared_ptr<Vertex> v) const {
bool Curve::on_segment(std::shared_ptr<Vertex> const &v) const {
return on_segment(v->x(), v->y());
}
bool Curve::on_segment(std::shared_ptr<Vertex> v, std::shared_ptr<Vertex> origin, const double angle) const {
bool Curve::on_segment(std::shared_ptr<Vertex> const &v, std::shared_ptr<Vertex> const &origin, double const angle) const {
double x, y;
std::tie(x, y) = v->rotate(origin, angle);
return on_segment(x, y);
}
bool Curve::on_manifold(std::shared_ptr<Vertex> v) const {
bool Curve::on_manifold(std::shared_ptr<Vertex> const &v) const {
return on_manifold(v->x(), v->y());
}
bool Curve::on_manifold(std::shared_ptr<Vertex> v, std::shared_ptr<Vertex> origin, const double angle) const {
bool Curve::on_manifold(std::shared_ptr<Vertex> const &v, std::shared_ptr<Vertex> const &origin, double const angle) const {
double x, y;
std::tie(x, y) = v->rotate(origin, angle);
......
......@@ -8,9 +8,9 @@ public:
friend class MirrorCopy;
// Constructors
Curve() : Start(nullptr), End(nullptr) {};
Curve() : Start(std::make_shared<Vertex>()), End(std::make_shared<Vertex>()), ForConstruction(false) {};
Curve(std::shared_ptr<Vertex> v0, std::shared_ptr<Vertex>v1, bool fc = false) : Start(v0), End(v1), ForConstruction(fc) {};
Curve(std::shared_ptr<Vertex> v0, std::shared_ptr<Vertex> v1, bool fc = false) : Start(v0), End(v1), ForConstruction(fc) {};
//Curve(Vertex *v0, Vertex *v1, bool fc = false) : Start(v0), End(v1), ForConstruction(fc) {};
......@@ -39,20 +39,20 @@ public:
virtual std::pair<double, double> supremum() const = 0; // maximum length of vector between origin and point on curve
// Curve-Vertex Comparison
virtual bool on_manifold(std::shared_ptr<Vertex> v) const final; // true if vertex is on manifold defined by curve
virtual bool on_manifold(std::shared_ptr<Vertex> v, std::shared_ptr<Vertex> origin, const double angle) const final;
virtual bool on_manifold(std::shared_ptr<Vertex> const &v) const final; // true if vertex is on manifold defined by curve
virtual bool on_manifold(std::shared_ptr<Vertex> const &v, std::shared_ptr<Vertex> const &origin, double const angle) const final;
virtual bool on_segment(std::shared_ptr<Vertex> v) const final; // true if vertex is on curve segment
virtual bool on_segment(std::shared_ptr<Vertex> v, std::shared_ptr<Vertex> origin, const double angle) const final;
virtual bool on_segment(std::shared_ptr<Vertex> const &v) const final; // true if vertex is on curve segment
virtual bool on_segment(std::shared_ptr<Vertex> const &v, std::shared_ptr<Vertex> const &origin, double const angle) const final;
// Curve-Curve Comparison
virtual bool is_identical(std::shared_ptr<Curve> c) const = 0; // true if (input curve) XOR (object curve) is a set with measure < tol
virtual bool is_identical(std::shared_ptr<Curve> c, std::shared_ptr<Vertex> origin, const double angle) const = 0;
virtual bool is_identical(std::shared_ptr<Curve> const &c) const = 0; // true if (input curve) XOR (object curve) is a set with measure < tol
virtual bool is_identical(std::shared_ptr<Curve> const &c, std::shared_ptr<Vertex> const &origin, double const angle) const = 0;
// #TODO: virtual bool is_overlapping(const Curve* c) const = 0; // true if (input curve) AND (object curve) is a set with measure > tol
// #TODO: virtual bool is_overlapping(const Curve* c, const Vertex* origin, const double_t angle) const = 0;
virtual bool is_coincident(std::shared_ptr<Curve> c) const = 0; // true if (input curve) AND (object curve + parametric extension) is a set with measure > tol
virtual bool is_coincident(std::shared_ptr<Curve> const &c) const = 0; // true if (input curve) AND (object curve + parametric extension) is a set with measure > tol
// #TODO: virtual bool is_coincident(const Curve* c, const Vertex* origin, const double_t angle) const = 0;
// Modification
......
......@@ -105,7 +105,7 @@ bool LineSegment::on_segment(const double x, const double y) const {
}
}
bool LineSegment::is_identical(std::shared_ptr<Curve> c) const {
bool LineSegment::is_identical(std::shared_ptr<Curve> const &c) const {
auto l = std::dynamic_pointer_cast<LineSegment>(c);
if (l.get() == nullptr) {
......@@ -115,7 +115,7 @@ bool LineSegment::is_identical(std::shared_ptr<Curve> c) const {
}
}
bool LineSegment::is_identical(std::shared_ptr<Curve> c, std::shared_ptr<Vertex> origin, const double angle) const {
bool LineSegment::is_identical(std::shared_ptr<Curve> const &c, std::shared_ptr<Vertex> const &origin, double const angle) const {
auto l = std::dynamic_pointer_cast<LineSegment>(c);
if (l.get() == nullptr) {
......@@ -143,7 +143,7 @@ bool LineSegment::is_identical(const double x0, const double y0, const double x1
|| (abs(xs - x1) < tol && abs(ys - y1) < tol && abs(xe - x0) < tol && abs(ye - y0) < tol);
}
bool LineSegment::is_coincident(std::shared_ptr<Curve> c) const {
bool LineSegment::is_coincident(std::shared_ptr<Curve> const &c) const {
auto l = std::dynamic_pointer_cast<LineSegment>(c);
if (l.get() == nullptr) {
......
......@@ -3,7 +3,7 @@
#include "Curve.h"
class LineSegment final : public Curve {
class LineSegment final : public Curve { // TODO: Use interface instead of friend class
public:
friend class Angle;
......@@ -22,7 +22,7 @@ public:
//Constructors
LineSegment() : Curve() {};
LineSegment(const LineSegment *l) : Curve(l->Start, l->End, l->ForConstruction) {};
LineSegment(LineSegment const *l) : Curve(l->Start, l->End, l->ForConstruction) {};
LineSegment(std::shared_ptr<Vertex> v0, std::shared_ptr<Vertex> v1, bool fc = false) : Curve(v0, v1, fc) {};
......@@ -62,11 +62,11 @@ public:
using Curve::on_segment;
// Curve-Curve Comparison
bool is_identical(std::shared_ptr<Curve> c) const override;
bool is_identical(std::shared_ptr<Curve> const &c) const override;
bool is_identical(std::shared_ptr<Curve> c, std::shared_ptr<Vertex> origin, const double angle) const override;
bool is_identical(std::shared_ptr<Curve> const &c, std::shared_ptr<Vertex> const &origin, double const angle) const override;
bool is_coincident(std::shared_ptr<Curve> c) const override;
bool is_coincident(std::shared_ptr<Curve> const &c) const override;
// Modification
std::shared_ptr<Curve> clone() const override { return std::make_shared<LineSegment>(this); };
......
#include "Sketch.hpp"
RotateCopy::RotateCopy(std::vector<std::shared_ptr<Curve>> &input, std::shared_ptr<Vertex> center, double angle, size_t copies, bool remove_internal) {
RotateCopy::RotateCopy(std::vector<std::shared_ptr<Curve>> input, std::shared_ptr<Vertex> center, double angle, size_t copies, bool remove_internal) {
// Creates rotated copies of the input curves about an vertex
// #TODO: Need to rearrange code and reserve vector sizes in a way that makes more sense (much code copied from MirrorCopy constructor)
// #TODO: Restructure to obviate the need for local_curves and local_verticies
......
......@@ -5,7 +5,7 @@
class RotateCopy : public Pattern {
public:
RotateCopy(std::vector<std::shared_ptr<Curve>> &input, std::shared_ptr<Vertex> center, double angle, size_t copies, bool remove_internal = false);
RotateCopy(std::vector<std::shared_ptr<Curve>> input, std::shared_ptr<Vertex> center, double angle, size_t copies, bool remove_internal = false);
private:
std::shared_ptr<Vertex> Center;
......
#include "Sketch.hpp"
Sketch::Sketch() {
/*
* Sketch::Sketch() {
NumEquations = 0;
NumVariables = 0;
Boundary = std::make_shared<Contour>();
}
*/
void Sketch::delete_me() {
Variables.clear();
Verticies.clear();
Curves.clear();
Constraints.clear();
Patterns.clear();
Contours.clear();
};
void Sketch::solve() {
double Sketch::solve() {
// #TODO: Tolerance based iteration convergence monitoring
// #TODO: Use sparse matrix representation for Jacobian
......@@ -32,22 +23,22 @@ void Sketch::solve() {
Eigen::FullPivLU<Eigen::MatrixXd> LU;
for (size_t j = 0; j < 32; ++j) {
// #TODO: Use QR or LDLT decomposition instead
// #TODO: Check for over/underdetermined system
// #TODO: Try extracting sub matrix and solving
// #TODO: Extract newton_update over Verticies, Curves, and Constraints into a private method
// TODO: Use QR or LDLT decomposition instead
// TODO: Check for over/underdetermined system
// TODO: Try extracting sub matrix and solving
// TODO: Extract newton_update over Verticies, Curves, and Constraints into a private method
J.setZero();
for (size_t i = 0; i < Verticies.size(); ++i) {
for (size_t i = 0; i != Verticies.size(); ++i) {
Verticies[i]->update(J, r);
}
for (size_t i = 0; i < Curves.size(); ++i) {
for (size_t i = 0; i != Curves.size(); ++i) {
Curves[i]->update(J, r);
}
for (size_t i = 0; i < Constraints.size(); ++i) {
for (size_t i = 0; i != Constraints.size(); ++i) {
Constraints[i]->update(J, r);
}
......@@ -59,15 +50,18 @@ void Sketch::solve() {
Variables[i]->update(delta);
}
}
return r.norm();
}
bool Sketch::build() {
Constellation c = Constellation(this);
bool success = c.boundary(Boundary);
Boundary = c.boundary();
bool success = (Boundary->size() > 0);
Contours.resize(0);
success = c.contours(Contours) && success;
Contours = c.contours();
success = success && (Contours.size() > 0);
return success;
}
......
......@@ -140,7 +140,7 @@ enum class SaveMethod {
class Sketch {
public:
// Constructors
Sketch();
Sketch() : NumVariables(0), NumEquations(0), Boundary() {};
void delete_me();
......@@ -151,7 +151,7 @@ public:
std::shared_ptr<Curve> curve(size_t i) const { return Curves[i]; };
std::vector<std::shared_ptr<Curve>> const curves() {return std::vector<std::shared_ptr<Curve>>(Curves.begin(),Curves.end());};
std::vector<std::shared_ptr<Curve>> const curves() { return std::vector<std::shared_ptr<Curve>>(Curves.begin(),Curves.end());};
std::shared_ptr<Constraint> constraint(size_t i) const { return Constraints[i]; };
......@@ -169,14 +169,8 @@ public:
size_t size_contours() const { return Contours.size(); };
template<typename T, typename...Args>
T *new_parameter(Args &&... args);
template<typename T, typename...Args>
T &new_element(Args &&... args);
template<class T, class...ArgT>
std::shared_ptr<T> new_element_SHARED_PTR(ArgT &&... args);
std::shared_ptr<T> new_element(ArgT &&... args);
void add_element(std::shared_ptr<Vertex> v);
......@@ -186,24 +180,16 @@ public:
void add_element(std::shared_ptr<Pattern> p);
void solve();
double solve();
bool build();
void add_parameter(std::shared_ptr<Variable> v) { add_parameter(Variables, v); };
// Save Functions
template<SaveMethod S>
void save_as(std::string path, std::string file_name) const;
private:
// SketchParameter
template<class T>
void add_parameter(std::vector<T *> &parameters, T *p);
template<class T>
void add_element(std::vector<T *> &elements, T &e);
template<class T>
void add_element(std::vector<std::shared_ptr<T>> &elements, std::shared_ptr<T> e);
......@@ -224,22 +210,6 @@ private:
size_t NumEquations;
};
// Template Member Functions
// #TODO: Pass elements by pointer
template<class T>
void Sketch::add_element(std::vector<T *> &elements, T &e) {
bool unique = true;
for (size_t i = 0; i < elements.size() && unique; ++i) {
unique = (elements[i] != &e);
}
if (unique) {
NumEquations += e.set_equation_index(NumEquations);
elements.push_back(&e);
}
e.register_parameters(this);
}
template<class T>
void Sketch::add_element(std::vector<std::shared_ptr<T>> &elements, std::shared_ptr<T> e) {
......@@ -256,20 +226,6 @@ void Sketch::add_element(std::vector<std::shared_ptr<T>> &elements, std::shared_
e->register_parameters(this);
}
template<class T>
void Sketch::add_parameter(std::vector<T *> &parameters, T *p) {
bool unique = true;
for (size_t i = 0; i < parameters.size() && unique; ++i) {
unique = (parameters[i] != p);
}
if (unique) {
NumVariables += p->set_index(NumVariables);
parameters.push_back(p);
}
}
template<class T>
void Sketch::add_parameter(std::vector<std::shared_ptr<T>> &parameters, std::shared_ptr<T> p) {
bool unique = true;
......@@ -283,26 +239,12 @@ void Sketch::add_parameter(std::vector<std::shared_ptr<T>> &parameters, std::sha
}
}
template<typename T, typename...ArgT>
T &Sketch::new_element(ArgT &&... args) {
T *e = new T(std::forward<ArgT>(args)...);
add_element(*e);
return *e;
}
template<class T, class...ArgT>
std::shared_ptr<T> Sketch::new_element_SHARED_PTR(ArgT &&... args) {
std::shared_ptr<T> Sketch::new_element(ArgT &&... args) {
std::shared_ptr<T> e = std::make_shared<T>(std::forward<ArgT>(args)...);
add_element(e);
return e;
};
template<typename T, typename...Args>
T *Sketch::new_parameter(Args &&... args) {
T *p = new T(std::forward<Args>(args)..., this);
add_parameter(p);
return p;
}
#endif //OERSTED_SKETCH_H
\ No newline at end of file
#include "test_Mesh.hpp"
TEST(Mesh, create__triangle_domain) {
TEST(Mesh, create_triangle_domain) {
Sketch s;
auto v0 = s.new_element_SHARED_PTR<Vertex>(1.0, 0.0);
auto v1 = s.new_element_SHARED_PTR<Vertex>(0.0, sqrt(3.0));
auto v2 = s.new_element_SHARED_PTR<Vertex>(-1.0, 0.0);
auto v0 = s.new_element<Vertex>(1.0, 0.0);
auto v1 = s.new_element<Vertex>(0.0, sqrt(3.0));
auto v2 = s.new_element<Vertex>(-1.0, 0.0);
auto l0 = s.new_element_SHARED_PTR<LineSegment>(v0, v1);
auto l1 = s.new_element_SHARED_PTR<LineSegment>(v1, v2);
auto l2 = s.new_element_SHARED_PTR<LineSegment>(v2, v0);
auto l0 = s.new_element<LineSegment>(v0, v1);
auto l1 = s.new_element<LineSegment>(v1, v2);
auto l2 = s.new_element<LineSegment>(v2, v0);
s.solve();
s.build();
......@@ -83,18 +83,18 @@ TEST(Mesh, create__triangle_domain) {
size_t i = m.num_points();
}
TEST(Mesh, create__square_domain) {
TEST(Mesh, create_square_domain) {
Sketch s;
auto v0 = s.new_element_SHARED_PTR<Vertex>(0.0, 0.0);
auto v1 = s.new_element_SHARED_PTR<Vertex>(1.0, 0.0);
auto v2 = s.new_element_SHARED_PTR<Vertex>(1.0, 1.0);