Commit 58c9322e authored by JasonPries's avatar JasonPries
Browse files

Add ForwardDart and ReverseDart index to DartConstraint

Allows for two-way traversal between Edges and DartConstraint
parent 1f394810
......@@ -3,8 +3,11 @@ PROJECT(Oersted_Mesh)
set(SOURCE_FILES
./include/Mesh.hpp
./src/Mesh.h ./src/Mesh.cpp
./src/BoundaryConstraint.h ./src/BoundaryConstraint.cpp
./src/DartConstraint.h ./src/DartConstraint.cpp
./src/Edge.h ./src/Edge.cpp
./src/InsertionQueuer.h ./src/InsertionQueuer.cpp
./src/Mesh.h ./src/Mesh.cpp
./src/Point.h ./src/Point.cpp
)
......
#ifndef OERSTED_MESH_HPP
#define OERSTED_MESH_HPP
#include "../src/Mesh.h"
#include "../src/Edge.h"
#include "../src/InsertionQueuer.h"
#include "../src/Mesh.h"
#include "../src/Point.h"
#endif //OERSTED_MESH_HPP
\ No newline at end of file
#include "BoundaryConstraint.h"
\ No newline at end of file
#ifndef OERSTED_BOUNDARYCONSTRAINT_H
#define OERSTED_BOUNDARYCONSTRAINT_H
#include <cstddef>
#include <vector>
#include "Sketch.hpp"
class BoundaryConstraint {
public:
BoundaryConstraint(std::shared_ptr<Curve const> cc) : ConstraintCurve(cc) {};
void add_dart(size_t d) { Darts.push_back(d); }; // TODO: Enforce uniqueness (std::set?)
std::shared_ptr<Curve const> curve() const { return ConstraintCurve; };
protected:
std::vector<size_t> Darts;
std::shared_ptr<Curve const> ConstraintCurve;
};
#endif //OERSTED_BOUNDARYCONSTRAINT_H
\ No newline at end of file
#include "DartConstraint.h"
\ No newline at end of file
#ifndef OERSTED_DARTCONSTRAINT_H
#define OERSTED_DARTCONSTRAINT_H
#include <cstddef>
#include <memory>
#include "Sketch.hpp"
#include "BoundaryConstraint.h"
class DartConstraint {
public:
DartConstraint(double s0, double s1, std::shared_ptr<BoundaryConstraint> bc, size_t self) : S0{s0}, S1{s1}, Constraint{bc}, Self{self}, ForwardDart{SIZE_MAX}, ReverseDart{SIZE_MAX} {};
std::shared_ptr<BoundaryConstraint> boundary_constraint() const { return Constraint; };
std::shared_ptr<Curve const> constraint_curve() const { return Constraint->curve(); };
size_t self() const { return Self; };
size_t forward_dart() const { return ForwardDart; };
size_t reverse_dart() const { return ReverseDart; };
void forward_dart(size_t d) { ForwardDart = d; };
void reverse_dart(size_t d) { ReverseDart = d; };
double S0;
double S1;
size_t Self;
size_t ForwardDart;
size_t ReverseDart;
protected:
std::shared_ptr<BoundaryConstraint> Constraint;
};
#endif //OERSTED_DARTCONSTRAINT_H
#ifndef OERSTED_EDGE_H
#define OERSTED_EDGE_H
#include "DartConstraint.h"
#include "Point.h"
#include "InsertionQueuer.h"
class Mesh;
......@@ -17,6 +19,10 @@ public:
Edge(size_t n, size_t s, size_t c, bool d) : Node(n), Self(s), Next(SIZE_MAX), Twin(SIZE_MAX), Prev(SIZE_MAX), Constraint(c), Orientation(d), Mark(false) {};
void add_to_queue(std::vector<std::unique_ptr<InsertionQueuer>> &queue, std::vector<DartConstraint> &constraints) {
queue.push_back(std::make_unique<MidpointQueuer>(Self));
}
size_t node() const { return Node; };
size_t self() const { return Self; };
......@@ -27,6 +33,8 @@ public:
size_t prev() const { return Prev; };
size_t constraint() const { return Constraint; };
bool orientation() const { return Orientation; };
bool mark() const { return Mark; };
......
#include "InsertionQueuer.h"
#include "Mesh.h"
void MidpointQueuer::insert(Mesh &m) const {
m.insert_midpoint(EdgeToSplit);
}
void CircumcenterQueuer::insert(Mesh &m) const {
m.insert_point(Circumcenter, Triangle);
}
\ No newline at end of file
#ifndef OERSTED_INSERTIONQUEUER_H
#define OERSTED_INSERTIONQUEUER_H
#include <cstddef>
#include "Point.h"
class Mesh;
enum class AddToQueueResult {
Circumcenter, Midpoint, Duplicate
};
class InsertionQueuer {
public:
virtual ~InsertionQueuer() {};
virtual void insert(Mesh &m) const = 0;
};
class MidpointQueuer : public InsertionQueuer {
public:
MidpointQueuer(size_t edge_to_split) : EdgeToSplit(edge_to_split) {};
void insert(Mesh &m) const override;
protected:
size_t EdgeToSplit;
};
class CircumcenterQueuer : public InsertionQueuer {
public:
CircumcenterQueuer(Point const cc, size_t triangle) : Circumcenter(cc), Triangle(triangle) {};
void insert(Mesh &m) const override;
protected:
Point const Circumcenter;
size_t Triangle;
};
#endif //OERSTED_INSERTIONQUEUER_H
......@@ -336,7 +336,7 @@ bool Mesh::is_locally_optimal(size_t ei) const {
double d2 = std::sqrt(v2x * v2x + v2y * v2y);
double d3 = std::sqrt(v3x * v3x + v3y * v3y);
double d4 = std::sqrt(v4x * v4x + v4y * v4y);
double tol = -(d1 * d2 * d3 * d4 * FLT_EPSILON);
double tol = -std::sqrt(d1 * d2 * d3 * d4) * FLT_EPSILON;
double sina = v1x * v2y - v1y * v2x;
double sinb = v3x * v4y - v3y * v4x;
......@@ -344,7 +344,7 @@ bool Mesh::is_locally_optimal(size_t ei) const {
double cosb = v3x * v4x + v3y * v4y;
double cct = sina * cosb + cosa * sinb;
return cct >= 0; // cct >= 0 > tol?
return cct >= tol; // TODO: Optional tol for testing purposes
}
}
......@@ -556,7 +556,13 @@ void Mesh::create_boundary_polygon() {
e.Twin = e.Self;
BoundaryConstraints.push_back(std::make_shared<BoundaryConstraint>(cc));
new_dart_constraint(0.0, 1.0, BoundaryConstraints.back());
DartConstraint &dc = new_dart_constraint(0.0, 1.0, BoundaryConstraints.back());
if (dir) {
dc.forward_dart(e.self());
} else {
dc.reverse_dart(e.self());
}
Points.push_back(Point(dir ? cc->start() : cc->end()));
}
......@@ -810,8 +816,6 @@ void Mesh::split_edge(size_t ei) {
return;
}
size_t c{DartConstraints.size()};
DartConstraint &dci = DartConstraints[Edges[ei].Constraint];
double s0 = dci.S0;
double s1 = dci.S1;
......@@ -820,6 +824,7 @@ void Mesh::split_edge(size_t ei) {
double sn = (s0 + s1) / 2.0;
dci.S1 = sn;
size_t c{DartConstraints.size()};
new_dart_constraint(sn, s1, dci.boundary_constraint());
Points.push_back(cc->point(sn));
......@@ -828,13 +833,21 @@ void Mesh::split_edge(size_t ei) {
Edge &e = Edges[ei];
Edge &nxt = Edges[e.Next];
DartConstraint &dcc = DartConstraints[c];
DartConstraint &dce = DartConstraints[e.Constraint];
// Constraint Curve
newe.Orientation = e.Orientation;
if (e.Orientation) {
newe.Constraint = c;
dcc.forward_dart(newe.self());
} else {
newe.Constraint = e.Constraint;
e.Constraint = c;
dce.reverse_dart(newe.self());
dcc.reverse_dart(e.self());
}
// Connectivity
......@@ -1119,13 +1132,21 @@ InsertPointResult Mesh::insert_midpoint(size_t ei) {
Edge &nxt = Edges[e.Next];
Edge &prv = Edges[e.Prev];
DartConstraint &dcc = DartConstraints[c];
DartConstraint &dce = DartConstraints[e.Constraint];
// Handle constraint curves
e2.Orientation = e.Orientation;
if (e.Orientation) {
e2.Constraint = c;
dcc.forward_dart(e2.self());
} else {
e2.Constraint = e.Constraint;
e.Constraint = c;
dcc.reverse_dart(e.self());
dce.reverse_dart(e2.self());
}
// Construct edges
......@@ -1177,18 +1198,35 @@ InsertPointResult Mesh::insert_midpoint(size_t ei) {
Edge &tnxt = Edges[twn.Next];
Edge &tprv = Edges[twn.Prev];
DartConstraint &dcc = DartConstraints[c];
DartConstraint &dce = DartConstraints[e.Constraint];
// Handle constraint curves
e1.Orientation = e.Orientation;
e4.Orientation = !e.Orientation;
twn.Orientation = !e.Orientation;
if (e.Orientation) {
e1.Constraint = c;
dcc.forward_dart(e1.self());
twn.Constraint = e1.Constraint;
e4.Constraint = e.Constraint;
dce.reverse_dart(e4.self());
dcc.reverse_dart(twn.self());
} else {
e1.Constraint = e.Constraint;
e.Constraint = c;
dcc.reverse_dart(e.self());
dce.reverse_dart(e1.self());
twn.Constraint = e1.Constraint;
e4.Constraint = e.Constraint;
dcc.forward_dart(e4.self());
dce.forward_dart(twn.self());
}
twn.Constraint = e1.Constraint;
e4.Constraint = e.Constraint;
// Construct Edges
e0.Node = Points.size() - 1;
......@@ -1277,7 +1315,8 @@ AddToQueueResult Mesh::add_point_to_queue(Point const vc, size_t ei) {
if (any_encroached) {
for (size_t e : encroached_edges) {
Queue.push_back(std::make_unique<MidpointQueuer>(e));
//Queue.push_back(std::make_unique<MidpointQueuer>(e));
Edges[e].add_to_queue(Queue, DartConstraints);
}
return AddToQueueResult::Midpoint;
......
#ifndef OERSTED_MESH_H
#define OERSTED_MESH_H
#include "Sketch.hpp"
#include "Point.h"
#include "Edge.h"
#include <algorithm>
#include <fstream>
#include <numeric>
#include <set>
#include "Sketch.hpp"
#include "Point.h"
#include "Edge.h"
#include "InsertionQueuer.h"
enum class LocateTriangleResult {
Interior, Exterior, Boundary, Point // TODO: Enumerate cases in function when triangle is located by a point near the boundary
};
......@@ -18,49 +20,6 @@ enum class InsertPointResult {
Success, Midpoint, Duplicate, Failure
};
enum class AddToQueueResult {
Circumcenter, Midpoint, Duplicate
};
class PointQueuer {
public:
virtual ~PointQueuer() {};
virtual void insert(Mesh &m) const = 0;
};
class BoundaryConstraint {
public:
BoundaryConstraint(std::shared_ptr<Curve const> cc) : ConstraintCurve(cc) {};
void add_dart(size_t d) { Darts.push_back(d); }; // TODO: Enforce uniqueness (std::set?)
std::shared_ptr<Curve const> curve() const { return ConstraintCurve; };
protected:
std::vector<size_t> Darts;
std::shared_ptr<Curve const> ConstraintCurve;
};
class CircumcenterQueuer;
class MidpointQueuer;
class DartConstraint {
public:
DartConstraint(double s0, double s1, std::shared_ptr<BoundaryConstraint> bc, size_t self) : S0{s0}, S1{s1}, Constraint{bc}, Self{self} {};
std::shared_ptr<BoundaryConstraint> boundary_constraint() const { return Constraint; };
std::shared_ptr<Curve const> constraint_curve() const { return Constraint->curve(); };
double S0;
double S1;
size_t Self;
protected:
std::shared_ptr<BoundaryConstraint> Constraint;
};
/* TODO: Reverse relationship between Edge and DartConstraint
* TODO: Have DartConstraint point to the Edge it constrains
* TODO: Edge will only contain a bool IsConstrained value in order to quickly test for encroachment
......@@ -128,6 +87,7 @@ public:
Mesh(Sketch &s);
friend class CircumcenterQueuer;
friend class MidpointQueuer;
double MinimumElementQuality = 0.0;
......@@ -176,10 +136,12 @@ public:
size_t prev(size_t ei) const { return Edges[ei].Prev; };
size_t size_points() const { return Points.size(); };
size_t size_dart_constraints() const {return DartConstraints.size(); };
size_t size_edges() const { return Edges.size(); };
size_t size_points() const { return Points.size(); };
size_t size_triangles() const { return Triangles.size(); };
size_t twin(size_t ei) const { return Edges[ei].Twin; };
......@@ -194,6 +156,8 @@ public:
Point circumcenter(size_t ei) const;
DartConstraint const dart_constraint(size_t i) { return DartConstraints[i]; };
Point const base(Edge const e) const { return Points[e.Node]; };
Point const base(size_t ei) const { return Points[node(ei)]; };
......@@ -242,7 +206,7 @@ protected:
std::vector<size_t> Triangles;
std::vector<std::unique_ptr<PointQueuer>> Queue;
std::vector<std::unique_ptr<InsertionQueuer>> Queue;
private:
bool find_attached(Point const p, size_t &ei);
......@@ -305,29 +269,4 @@ private:
InsertPointResult insert_midpoint(size_t ei);
};
class MidpointQueuer : public PointQueuer {
public:
MidpointQueuer(size_t edge_to_split) : EdgeToSplit(edge_to_split) {};
void insert(Mesh &m) const override {
m.insert_midpoint(EdgeToSplit);
}
protected:
size_t EdgeToSplit;
};
class CircumcenterQueuer : public PointQueuer {
public:
CircumcenterQueuer(Point const cc, size_t triangle) : Circumcenter(cc), Triangle(triangle) {};
void insert(Mesh &m) const override {
m.insert_point(Circumcenter, Triangle);
}
protected:
Point const Circumcenter;
size_t Triangle;
};
#endif //OERSTED_MESH_H
#ifndef OERSTED_POINT_H
#define OERSTED_POINT_H
#include "Sketch.hpp"
class Point {
public:
Point() : X{0.0}, Y{0.0} {};
......
......@@ -10,7 +10,7 @@ bool edges_are_optimal(Mesh &m) {
bool edges_are_valid(Mesh &m) {
// TODO: Test for self-encroachment of triangle edges/verticies
for (size_t i = 0;i < m.size_edges();++i) {
for (size_t i = 0;i != m.size_edges();++i) {
const Edge e = m.edge(i);
EXPECT_TRUE(e.self() == m.edge(e.next()).prev());
......@@ -50,6 +50,23 @@ bool edges_are_valid(Mesh &m) {
}
}
for (size_t i = 0; i != m.size_dart_constraints(); ++i) {
DartConstraint const &d = m.dart_constraint(i);
EXPECT_EQ(i, d.self());
if (d.forward_dart() != SIZE_MAX) {
Edge const &e = m.edge(d.forward_dart());
EXPECT_TRUE(e.orientation());
EXPECT_EQ(i, e.constraint());
}
if (d.reverse_dart() != SIZE_MAX) {
Edge const &e = m.edge(d.reverse_dart());
EXPECT_FALSE(e.orientation());
EXPECT_EQ(i, e.constraint());
}
}
return true;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment