Commit 6a2f26e4 authored by JasonPries's avatar JasonPries
Browse files

Rewrote Mesh::locate_triangle function

The new implementation could be improved by removing calculations that get repeated when changing triangles and further optimizing return paths.
parent df6efdc2
......@@ -5,13 +5,14 @@
<sourceFolder url="file://$MODULE_DIR$/src/CMakeLists.txt" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Angle.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Vertical.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Curve.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Sketch.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Coincident.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Vertical.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Angle.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Vertex.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Curve.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Pattern.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Radius.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Length.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Coincident.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Constellation.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Radius.cpp" isTestSource="false" />
......@@ -19,44 +20,43 @@
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Vertex.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/LineSegment.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Curve.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Branch.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Rotation.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Tangency.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Rotation.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Branch.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Constraint.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/RotateCopy.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Branch.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Tangency.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Constraint.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Star.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Symmetry.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Constraint.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Length.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Length.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Constellation.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Contour.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Fixation.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Radius.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Horizontal.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/CircularArc.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Distance.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Symmetry.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Distance.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/MirrorCopy.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Constraint.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Star.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/LineSegment.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/MirrorCopy.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Fixation.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Sketch.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/RotateCopy.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Tangency.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/RotateCopy.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Contour.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Pattern.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Sketch.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/Rotation.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/src/CircularArc.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/include/Sketch.hpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Sketch/CMakeLists.txt" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Point.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Mesh.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Point.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Edge.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Point.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Mesh.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Mesh.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/util.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/Mesh/src/Edge.h" isTestSource="false" />
......@@ -71,8 +71,10 @@
<sourceFolder url="file://$MODULE_DIR$/lib/GoogleTest/googletest/cmake/internal_utils.cmake" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/CMakeLists.txt" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/main.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/Mesh/util.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/Mesh/test_Mesh.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/Mesh/test_Mesh.hpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/Mesh/util.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/CMakeLists.txt" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/Sketch/test_Curve.cpp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/Sketch/test_LineSegment.cpp" isTestSource="false" />
......
#include "Mesh.hpp"
// Edge
Edge::Edge(Curve *c, bool direction) {
ConstraintCurve = c;
Node = new Point(direction ? c->start() : c->end());
......@@ -19,7 +18,6 @@ Edge::Edge(Curve *c, bool direction, const Point *v) {
Orientation = direction;
}
// Test Methods
bool Edge::is_protruding() const {
/*
See Chapter 1.4 of "Triangulations and Applications" by Øyvind Hjelle and Morten Dæhlen
......@@ -224,13 +222,13 @@ bool Edge::swap() {
bool Edge::recursive_swap() {
// TODO, May need to have two different recursive swap methods, one for midpoint insertion and one for circumcenter insertion
if (!is_locally_optimal() && swap()) {
Edge * next = Next;
Edge * prev = Prev;
Edge * enext = Next;
Edge * eprev = Prev;
Edge * tnext = Twin->Next;
Edge * tprev = Twin->Prev;
next->recursive_swap();
prev->recursive_swap();
enext->recursive_swap();
eprev->recursive_swap();
tnext->recursive_swap();
tprev->recursive_swap();
......@@ -251,7 +249,7 @@ void Edge::split_edge(std::vector<const Point *> &points, std::vector<Edge *> &e
Curve *c;
if (ConstraintCurve != nullptr) { // Constrained Edge
Vertex *v = new Vertex; // #TODO: Need to manage this memory. Destructors.
Vertex *v = new Vertex; // TODO: Need to manage this memory. Destructors.
c = ConstraintCurve->split(v, 0.5);
p->X = v->x();
......@@ -339,7 +337,6 @@ void Edge::split_edge(std::vector<const Point *> &points, std::vector<Edge *> &e
}
}
// Calculation Methods
Point Edge::circumcenter() const {
double xa = Node->X;
double ya = Node->Y;
......@@ -403,118 +400,9 @@ double Edge::shortest_edge_length() const {
return sqrt(dl);
}
// Auxillary Method
void Edge::recursive_mark() {
if (Mark && Next->Mark && Prev->Mark) {
Next->Mark = false;
Prev->Mark = false;
}
}
// Friend Utility
bool are_intersecting(const Edge *e0, const Edge *e1) {
// #TODO, Make more detailed return type enumeration
if (e0->ConstraintCurve != nullptr && e0->ConstraintCurve == e1->ConstraintCurve) {
return false;
}
const Point *v00 = e0->base();
const Point *v01 = e0->tip();
const Point *v10 = e1->base();
const Point *v11 = e1->tip();
double xs0 = (v00->X + v01->X) / 2.0;
double ys0 = (v00->Y + v01->Y) / 2.0;
double xs1 = (v10->X + v11->X) / 2.0;
double ys1 = (v10->Y + v11->Y) / 2.0;
double xd0 = (v00->X - v01->X) / 2.0;
double yd0 = (v00->Y - v01->Y) / 2.0;
double xd1 = (v10->X - v11->X) / 2.0;
double yd1 = (v10->Y - v11->Y) / 2.0;
double d0 = xd0 * xd0 + yd0 * yd0;
double d1 = xd1 * xd1 + yd1 * yd1;
double cross = abs(xd0 * yd1 - xd1 * yd0);
double tol = (d0 * d1) * FLT_EPSILON;
if (cross < tol) {
/*
Lines are nearly parallel
There are four possible minimum distance points between the lines
*/
double s, dx, dy, dmin = DBL_MAX;
s = ((xd0 - xd1) * (xs0 - xs1) + (yd0 - yd1) * (ys0 - ys1)) /
((xd0 - xd1) * (xd0 - xd1) + (yd0 - yd1) * (yd0 - yd1));
if (abs(s) < 1.0 - FLT_EPSILON) {
dx = xs0 + xd0 * s - xs1 - xd1 * s;
dy = ys0 + yd0 * s - ys1 - yd1 * s;
dmin = fmin(dmin, dx * dx + dy * dy);
dx = xs0 - xd0 * s - xs1 + xd1 * s;
dy = ys0 - yd0 * s - ys1 + yd1 * s;
dmin = fmin(dmin, dx * dx + dy * dy);
}
s = ((xd0 + xd1) * (xs0 - xs1) + (yd0 + yd1) * (ys0 - ys1)) /
((xd0 + xd1) * (xd0 + xd1) + (yd0 + yd1) * (yd0 + yd1));
if (abs(s) < 1.0 - FLT_EPSILON) {
dx = xs0 + xd0 * s - xs1 + xd1 * s;
dy = ys0 + yd0 * s - ys1 + yd1 * s;
dmin = fmin(dmin, dx * dx + dy * dy);
dx = xs0 - xd0 * s - xs1 - xd1 * s;
dy = ys0 - yd0 * s - ys1 - yd1 * s;
dmin = fmin(dmin, dx * dx + dy * dy);
}
tol = (d0 + d1) * FLT_EPSILON;
return (dmin < tol);
} else {
// Lines are not parallel
double s0 = abs(xd1 * (ys0 - ys1) - yd1 * (xs0 - xs1));
double s1 = abs(xd0 * (ys0 - ys1) - yd0 * (xs0 - xs1));
tol = cross * (1.0 - FLT_EPSILON);
return (s0 < tol && s1 < tol);
}
}
// External Utility
void circumradius(std::vector<Edge *> &triangles, std::vector<double> &radii) {
radii.resize(0);
radii.reserve(triangles.size());
for (size_t i = 0; i < triangles.size(); ++i) {
radii.push_back(triangles[i]->circumradius());
}
}
void shortest_edge_length(std::vector<Edge *> &triangle, std::vector<double> &length) {
length.resize(0);
length.reserve(triangle.size());
for (size_t i = 0; i < triangle.size(); ++i) {
length.push_back(triangle[i]->shortest_edge_length());
}
}
void element_quality(std::vector<Edge *> &triangle, std::vector<double> &radii, std::vector<double> &quality) {
radii.resize(0);
quality.resize(0);
radii.reserve(triangle.size());
quality.reserve(triangle.size());
for (size_t i = 0; i < triangle.size(); ++i) {
double r = triangle[i]->circumradius();
double l = triangle[i]->shortest_edge_length();
radii.push_back(r);
quality.push_back(l / r);
}
}
void sort_permutation(std::vector<double> &values, std::vector<size_t> &index) {
index.resize(values.size());
std::iota(index.begin(), index.end(), 0);
std::sort(index.begin(), index.end(), [&](size_t i, size_t j) { return (values[i] < values[j]); });
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ public:
Edge(Point &v, Edge &n, Edge &p, Edge &t) : Node(&v), Next(&n), Prev(&p), Twin(&t), ConstraintCurve(nullptr), Orientation(true), Mark(false) {};
Edge(Curve *c, bool Orientaiton);
Edge(Curve *c, bool Orientation);
Edge(Curve *c, bool Orientation, const Point *v);
......@@ -37,12 +37,10 @@ public:
bool mark() const { return Mark; };
// Overloads
bool operator==(const Edge &e) const {
return (node() == e.node()) && (constraint_curve() == e.constraint_curve()) && (twin()->node() == e.twin()->node());
};
// Calculation Methods
Point circumcenter() const;
double circumradius() const;
......@@ -51,7 +49,6 @@ public:
double shortest_edge_length() const;
// Test Methods
bool is_protruding() const;
bool is_constrained() const { return (ConstraintCurve != nullptr); };
......@@ -64,26 +61,24 @@ public:
bool is_attached(const Point *p, Edge *&e) const;
// Topology Alterating Methods
bool swap();
bool recursive_swap();
void split_edge(std::vector<const Point *> &verts, std::vector<Edge *> &edges);
// Auxillary Methods
void recursive_mark();
protected:
const Point *Node; //Start of edge
Edge *Next; //In triangle
Edge *Twin; //Adjacent triangle
Edge *Prev; //In triangle
const Point *Node; //Start of edge
Edge *Next; //In triangle
Edge *Twin; //Adjacent triangle
Edge *Prev; //In triangle
Curve *ConstraintCurve; //==nullptr if unconstrained
bool Orientation; //undefined if unconstrained
bool Orientation; //undefined if unconstrained
bool Mark; // Auxillary variable for mesh refinement
bool Mark; // Auxillary variable for mesh refinement
};
#endif //OERSTED_EDGE_H
#include "Mesh.hpp"
Mesh::Mesh(Sketch &s) {
Boundary = s.boundary();
Mesh::Mesh(Sketch &sketch) {
Boundary = sketch.boundary();
for (size_t i = 0; i != s.size_curves(); ++i) {
Curves.push_back(s.curve(i));
for (size_t i = 0; i != sketch.size_curves(); ++i) {
auto c = sketch.curve(i);
if(!(c->ForConstruction)) {
Curves.push_back(c);
}
}
for (size_t i = 0; i != s.size_contours(); ++i) {
Contours.push_back(s.contour(i));
for (size_t i = 0; i != sketch.size_contours(); ++i) {
Contours.push_back(sketch.contour(i));
}
}
......@@ -34,59 +37,115 @@ LocateTriangleResult Mesh::locate_triangle(const Point *p, Edge *&e) const {
}
LocateTriangleResult Mesh::locate_triangle(const Point *p, const Edge *&e) const {
// TODO: Need to search along boundary triangles in order to ensure the internal/external status
const Edge *start = e;
double xp = p->X;
double yp = p->Y;
while (true) {
// Verticies
const Point *p0 = e->base();
const Point *p1 = e->tip();
const Point *p0 = e->node();
const Point *p1 = e->next()->node();
const Point *p2 = e->prev()->node();
if (*p == *p0) {
return LocateTriangleResult::Point;
} else if (*p == *p1) {
}
if (*p == *p1) {
e = e->next();
return LocateTriangleResult::Point;
}
// Signed area of triangle
if (*p == *p2) {
e = e->prev();
return LocateTriangleResult::Point;
}
double dx0p = p0->X - xp;
double dy0p = p0->Y - yp;
double dp0 = sqrt(dx0p * dx0p + dy0p * dy0p);
double dx1p = p1->X - xp;
double dy1p = p1->Y - yp;
double dp1 = sqrt(dx1p * dx1p + dy1p * dy1p);
double dx2p = p2->X - xp;
double dy2p = p2->Y - yp;
double dp2 = sqrt(dx2p * dx2p + dy2p * dy2p);
double dx01 = p0->X - p1->X;
double dy01 = p0->Y - p1->Y;
double d01 = sqrt(dx01 * dx01 + dy01 * dy01);
double dx12 = p1->X - p2->X;
double dy12 = p1->Y - p2->Y;
double d12 = sqrt(dx12 * dx12 + dy12 * dy12);
double dx20 = p2->X - p0->X;
double dy20 = p2->Y - p0->Y;
double d20 = sqrt(dx20 * dx20 + dy20 * dy20);
double tola = abs(dx20 * dy01 - dy20 * dx01);
double tole = FLT_EPSILON * sqrt(tola);
tola *= FLT_EPSILON;
double area = dx0p * dy1p - dx1p * dy0p;
double tol = FLT_EPSILON * (dx01 * dx01 + dy01 * dy01);
double area01 = dx0p * dy1p - dx1p * dy0p;
double area12 = dx1p * dy2p - dx2p * dy1p;
double area20 = dx2p * dy0p - dx0p * dy2p;
if (area < -tol) {
if (area01 > tola && area12 > tola && area20 > tola) {
return LocateTriangleResult::Interior;
}
if (area01 < -tola) {
if (e != e->twin()) {
start = e->twin();
e = start->next();
} else {
return LocateTriangleResult::Exterior;
e = e->twin()->next();
continue;
}
} else if (area < tol) {
double dp0 = sqrt(dx0p * dx0p + dy0p * dy0p);
double dp1 = sqrt(dx1p * dx1p + dy1p * dy1p);
double d01 = sqrt(dx01 * dx01 + dy01 * dy01);
double tol = FLT_EPSILON * d01;
if (abs(dp0 + dp1 - d01) < tol) {
} else if (area01 < tola) {
if (abs(dp0 + dp1 - d01) < tole) {
return LocateTriangleResult::Edge;
} else if (e->next() != start) {
}
}
if (area12 < -tola) {
if (e->next() != e->next()->twin()) {
e = e->next()->twin()->next();
continue;
}
} else if (area12 < tola) {
if (abs(dp1 + dp2 - d12) < tole) {
e = e->next();
} else {
throw std::exception(); //TODO: This branch should never be reached. Supply return value"
return LocateTriangleResult::Edge;
}
}
if (area20 < -tola) {
if (e->prev() != e->prev()->twin()) {
e = e->prev()->twin()->next();
continue;
}
} else if (area20 < tola) {
if (abs(dp2 + dp0 - d20) < tole) {
e = e->prev();
return LocateTriangleResult::Edge;
}
} else if (e->next() != start) {
}
// If not Interior, not on Edge, and cannot continue, point is exterior
if (area01 < -tola) {
return LocateTriangleResult::Exterior;
}
if (area12 < -tola) {
e = e->next();
} else {
return LocateTriangleResult::Interior;
return LocateTriangleResult::Exterior;
}
if (area20 < -tola) {
e = e->prev();
return LocateTriangleResult::Exterior;
}
throw std::exception();
}
}
......@@ -649,7 +708,7 @@ void Mesh::insert_internal_boundaries() {
}
}
// Insert interior curve midpoints until constraints are naturally satisified
// Insert interior curve midpoints until constraints are naturally satisfied
std::vector<Curve *> queue;
for (size_t i = 0; i != interior.size(); ++i) {
Edge * e = Edges.back();
......@@ -661,14 +720,7 @@ void Mesh::insert_internal_boundaries() {
LocateTriangleResult result = locate_triangle(&p0, e);
if (result != LocateTriangleResult::Point) {
//TODO: Could not locate point within triangulation while inserting internal constraints
//TODO: Need to fix locate_triangle method so that search continues along boundary until the edge extrusion strip contains the point (verifying the internal/external status)
LocateTriangleResult result = locate_triangle(&p1, e);
if (result == LocateTriangleResult::Point) {
std::swap(p0, p1);
} else {
throw std::exception();
}
throw std::exception();
}
if (e->is_attached(&p1, e)) {
......@@ -796,4 +848,59 @@ void Mesh::refine_once(std::vector<size_t> index, std::vector<double> radii, std
}
}
get_triangles();
}
const Edge* Mesh::edges_are_valid() {
for (size_t i = 0; i < size_edges(); ++i) {
const Edge *e = edge(i);
if (e != e->next()->prev()) {
return e;
}
if (e != e->prev()->next()) {
return e;
}
if (e != e->twin()->twin()) {
return e;
}
if (!(e->twin() == e)) {
if (e->node() != e->twin()->next()->node()) {
return e;
}
if (e->constraint_curve() != e->twin()->constraint_curve()) {
return e;
}
if (e->constraint_curve() != nullptr) {
if (e->orientation() == e->twin()->orientation()) {
return e;
}
}
if (e->node() == e->twin()->node()) {
return e;
}
}
if (e->constraint_curve() != nullptr) {
if (e->orientation()) {
if (*e->base() != *e->constraint_curve()->start()) {
return e;
}
if (*e->tip() != *e->constraint_curve()->end()) {
return e;
}
} else {
if (*e->base() != *e->constraint_curve()->end()) {
return e;
}
if (*e->tip() != *e->constraint_curve()->start()) {
return e;
}
}
}
}
return nullptr;
}
\ No newline at end of file
......@@ -21,17 +21,14 @@ class Edge;
class Mesh {
public:
// Global Mesh Quality Constraints
double MinimumElementQuality = 0.0;
double MinimumElementSize = 0.0;
double MaximumElementSize = DBL_MAX;
// Constructors
Mesh(Sketch &s);
void create();
// Accessors
const Point *point(size_t i) const { return Points[i]; };
const Edge *edge(size_t i) const { return Edges[i]; };
......@@ -50,10 +47,8 @@ public:
size_t num_triangles() const { return Triangles.size(); };
// Save
void save_as(std::string path, std::string file_name) const;
// Topological Queries
LocateTriangleResult locate_triangle(const Point *p, Edge *&e) const;
LocateTriangleResult locate_triangle(const Point *p, const Edge *&e) const;
......@@ -63,7 +58,6 @@ public:
return locate_triangle(p, e);
};
// Point Insertion
InsertPointResult insert_point(const Point *p, Edge *e);
InsertPointResult insert_point(const Point *p) { return insert_point(p, Edges.back()); };
......@@ -72,13 +66,14 @@ public:
InsertPointResult insert_midpoint(Edge *e);
// Refinement
void refine();
void refine_once();
void refine_once(std::vector<size_t> index, std::vector<double> circumradius, std::vector<double> quality);
const Edge* edges_are_valid();