5#include <boost/range/algorithm.hpp>
15template <
typename Real,
size_t N>
21 using typename parent_type::edge;
23 using typename parent_type::order_independent_edge_compare;
28 using parent_type::operator[];
54 :
public boost::iterator_facade<
55 face_iterator, face, boost::bidirectional_traversal_tag, face> {
102 template <
typename T>
104 using property_type<T>::property_type;
105 auto&
at(
face f) {
return property_type<T>::at(f.
i); }
106 const auto&
at(
face f)
const {
return property_type<T>::at(f.
i); }
109 return property_type<T>::operator[](f.
i);
111 std::unique_ptr<property>
clone()
const override {
112 return std::unique_ptr<face_prop<T>>(
new face_prop<T>{*
this});
141 for (
int i = 0; i < io.numberoftriangles; ++i)
142 insert_face(io.trianglelist[i * 3], io.trianglelist[i * 3 + 1],
143 io.trianglelist[i * 3 + 2]);
184 m_faces = std::move(other.m_faces);
195 &this->
template add_vertex_property<std::vector<face>>(
"v:faces"));
197 &this->
template add_edge_property<std::vector<face>>(
"e:faces"));
200 &this->
template add_face_property<std::vector<edge>>(
"f:edges"));
206 &this->
template vertex_property<std::vector<face>>(
"v:faces"));
208 &this->
template edge_property<std::vector<face>>(
"e:faces"));
210 &face_property<std::vector<edge>>(
"f:edges"));
230 boost::rotate(new_face, boost::min_element(new_face));
232 for (
auto f :
faces())
233 if (eq(
at(f), new_face))
return f;
241 for (
auto v : new_face) {
faces(v).push_back(f); }
243 for (
auto e : inserted_edges) {
244 faces(e).push_back(f);
245 edges(f).push_back(e);
253 using namespace boost;
255 for (
auto f :
faces(v))
260 void remove(edge e,
bool remove_orphaned_vertices =
true) {
261 using namespace boost;
263 for (
auto f :
faces(e))
268 constexpr void remove(
face f,
bool remove_orphaned_vertices =
true,
269 bool remove_orphaned_edges =
true) {
270 using namespace boost;
274 if (remove_orphaned_vertices)
278 if (remove_orphaned_edges)
279 for (
auto e :
edges(f))
294 if (polygon.size() == 3)
296 else if (polygon.size() == 4) {
301 api.behaviour().firstnumber = 0;
302 api.behaviour().poly =
true;
303 api.behaviour().usesegments =
true;
305 contour.numberofsegments = polygon.size();
306 contour.segmentlist =
new int[contour.numberofsegments * 2];
307 for (
size_t i = 0; i < polygon.size(); ++i) {
308 contour.segmentlist[i * 2] = i;
309 contour.segmentlist[i * 2 + 1] = (i + 1) % polygon.size();
312 api.mesh_create(contour);
313 auto triangulated_contour = api.mesh_copy();
315 for (
int i = 0; i < contour.numberofpoints * 2; ++i)
316 assert(contour.pointlist[i] == triangulated_contour.pointlist[i]);
317 for (
int i = 0; i < triangulated_contour.numberoftriangles; ++i)
318 if (triangulated_contour.trianglelist[i * 3] < polygon.size() &&
319 triangulated_contour.trianglelist[i * 3 + 1] < polygon.size() &&
320 triangulated_contour.trianglelist[i * 3 + 2] < polygon.size())
321 insert_face(polygon[triangulated_contour.trianglelist[i * 3]],
322 polygon[triangulated_contour.trianglelist[i * 3 + 1]],
323 polygon[triangulated_contour.trianglelist[i * 3 + 2]]);
329 std::vector<vertex> polygon;
331 for (
auto v :
vertices(f)) polygon.push_back(v);
339 using namespace boost;
344 for (
auto& f :
faces)
345 if (f.i > invalid_f.i) --f.i;
350 for (
auto& f :
faces)
351 if (f.i > invalid_f.i) --f.i;
355 for (
auto invalid_e : this->m_invalid_edges)
357 for (
auto& e :
edges)
358 if (e.i >= invalid_e.i) --e.i;
361 for (
const auto v : this->m_invalid_points)
362 for (
auto f :
faces())
363 for (
auto& f_v :
at(f))
364 if (f_v.i > v.i) --f_v.i;
370 if (f_to_reindex.i > f.i) --f_to_reindex.i;
389 std::vector<edge>
edges;
391 for (
size_t i = 0; i <
vertices.size(); ++i)
430 std::vector<face> neighbors;
431 for (
auto e :
edges(f)) {
432 for (
auto nf :
faces(e)) {
433 if (nf != f) { neighbors.push_back(nf); }
441 return boost::find(
at(f), v) !=
end(
at(f));
460 io.numberofcorners = 3;
463 io.trianglelist =
new int[io.numberoftriangles * io.numberofcorners];
465 for (
auto f :
faces()) {
467 for (
unsigned int j = 0; j < 3; ++j) io.pointlist[i + j] =
face[i].
i;
481 for (
auto f :
faces(v)) fs.insert(f);
484 io.numberoftriangles = fs.size();
485 io.numberofcorners = 3;
488 io.trianglelist =
new int[io.numberoftriangles * io.numberofcorners];
493 for (
unsigned int j = 0; j < 3; ++j) io.trianglelist[i + j] =
face[j].
i;
498 for (
int i = 0; i < io.numberoftriangleattributes * 3; ++i)
499 for (
size_t j = 0; j <
vertices.size(); ++j)
500 if (io.trianglelist[i] ==
int(
vertices[j].i)) {
501 io.trianglelist[i] = j;
580 template <
typename T>
586 template <
typename T>
592 template <
typename T>
595 std::pair{name, std::make_unique<face_prop<T>>(value)});
596 auto prop =
dynamic_cast<face_prop<T>*
>(it->second.get());
602 void write(
const std::string& path) {
603 auto ext = path.substr(path.find_last_of(
".") + 1);
604 if constexpr (N == 2 || N == 3) {
607 }
else if (ext ==
"obj") {
614 void write_obj(
const std::string& path)
requires(N == 2 || N == 3) {
615 std::ofstream fout(path);
618 if constexpr (N == 2)
619 fout <<
"v " <<
at(v)(0) <<
' ' <<
at(v)(1) <<
" 0\n";
620 else if constexpr (N == 3)
621 fout <<
"v " <<
at(v)(0) <<
' ' <<
at(v)(1) <<
" " <<
at(v)(2)
623 for (
auto f :
faces())
624 fout <<
"f " <<
at(f)[0].i + 1 <<
' ' <<
at(f)[1].i + 1 <<
' '
625 <<
at(f)[2].i + 1 <<
'\n';
632 const std::string& title =
"tatooine mesh") const requires(N == 2 || N == 3){
639 std::vector<std::array<Real, 3>> points;
640 points.reserve(this->m_points.size());
641 for (
const auto& p : this->m_points) {
642 if constexpr (N == 3) {
643 points.push_back({p(0), p(1), p(2)});
645 points.push_back({p(0), p(1), 0});
651 std::vector<std::vector<size_t>> polygons;
652 polygons.reserve(
m_faces.size());
653 for (
const auto& f :
faces()) {
654 polygons.emplace_back();
655 for (
const auto v :
at(f)) polygons.back().push_back(v.i);
664 if (name !=
"v:edges" && name !=
"v:faces") {
665 std::vector<std::vector<Real>> data;
666 data.reserve(this->m_points.size());
669 for (
const auto& v4 :
672 data.push_back({v4(0), v4(1), v4(2), v4(3)});
675 for (
const auto& v3 :
678 data.push_back({v3(0), v3(1), v3(2)});
681 const auto& casted_prop =
683 for (
const auto& v2 : casted_prop) data.push_back({v2(0), v2(1)});
685 }
else if (prop->type() ==
typeid(Real)) {
686 for (
const auto& scalar :
688 data.push_back({scalar});
699 if (name !=
"f:edges") {
701 std::vector<std::vector<Real>> data;
703 for (
const auto& v4 :
705 data.push_back({v4(0), v4(1), v4(2), v4(3)});
709 std::vector<std::vector<Real>> data;
711 for (
const auto& v3 :
713 data.push_back({v3(0), v3(1), v3(2)});
717 std::vector<std::vector<Real>> data;
719 for (
const auto& v2 :
721 data.push_back({v2(0), v2(1)});
724 }
else if (prop->type() ==
typeid(
double)) {
725 std::vector<std::vector<double>> data;
727 for (
const auto& scalar :
729 data.push_back({scalar});
732 }
else if (prop->type() ==
typeid(float)) {
733 std::vector<std::vector<float>> data;
735 for (
const auto& scalar :
737 data.push_back({scalar});
751 if (v0 == v1) {
return true; }
758 template <
typename face_cont_t>
760 using groups_t = std::list<std::vector<face>>;
761 using groups_it_t =
typename groups_t::iterator;
763 for (
auto f :
faces) {
764 std::vector<groups_it_t> insertions;
765 for (
auto groups_it = groups.begin(); groups_it != groups.end();
767 for (
auto gf : *groups_it)
769 insertions.push_back(groups_it);
774 if (insertions.empty()) groups.emplace_back().push_back(f);
776 else if (insertions.size() == 1)
777 insertions.front()->push_back(f);
781 insertions.front()->push_back(f);
782 for (
size_t i = 1; i < insertions.size(); ++i) {
783 boost::copy(*insertions[i], std::back_inserter(*insertions.front()));
784 groups.erase(insertions[i]);
796 template <
typename face_cont_t>
798 std::map<edge, size_t> edge_counts;
800 for (
auto e :
edges(f)) ++edge_counts[e];
803 for (
const auto& [e, cnt] : edge_counts)
804 if (cnt == 1) es.insert(e);
811 template <
typename edge_cont_t>
813 std::vector<std::set<edge>> splitted_edges;
814 bool inserted =
false;
815 for (
auto e :
edges) {
817 for (
auto& cont : splitted_edges)
818 for (
auto inserted_edge : cont) {
819 if (
at(inserted_edge)[0] ==
at(e)[0] ||
820 at(inserted_edge)[0] ==
at(e)[1] ||
821 at(inserted_edge)[1] ==
at(e)[0] ||
822 at(inserted_edge)[1] ==
at(e)[1]) {
829 if (!inserted) splitted_edges.emplace_back().insert(e);
831 return splitted_edges;
838 template <
typename edge_cont_t>
840 std::vector<vertex> polygon;
842 polygon.push_back(
at(*
edges.begin())[0]);
843 polygon.push_back(
at(*
edges.begin())[1]);
845 bool searching =
true;
851 if (
at(e)[0] == polygon.back() &&
at(e)[1] != *
prev(
end(polygon), 2))
854 else if (
at(e)[1] == polygon.back() &&
862 if (polygon.front() ==
at(e)[i])
865 polygon.push_back(
at(e)[i]);
876 return ((b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0])) >= 0;
881 const std::vector<vertex>& polygon)
requires(N == 2) {
882 size_t left_turns = 0;
883 size_t right_turns = 0;
884 for (
size_t i_0 = 0; i_0 < polygon.size(); ++i_0) {
885 auto i_1 = (i_0 + 1) % polygon.size();
886 auto i_2 = (i_0 + 2) % polygon.size();
887 if (
is_left(
at(polygon[i_0]),
at(polygon[i_1]),
at(polygon[i_2])))
892 return left_turns > right_turns;
896 template <
typename face_cont_t>
898 bool check_counterclockwise =
true) {
900 std::vector<std::vector<vertex>> polygons;
901 for (
const auto& loop : border_loops) {
903 if (check_counterclockwise &&
905 reverse(
begin(polygons.back()),
end(polygons.back()));
913 const std::vector<vertex>& rhs) {
914 auto lit =
begin(lhs);
915 auto rit =
begin(rhs);
917 for (; lit !=
end(lhs); ++lit, ++rit) {
928 const std::vector<vertex>& rhs) {
929 auto lit =
begin(lhs);
930 auto rit =
begin(rhs);
932 for (; lit !=
end(lhs); ++lit, --rit) {
937 if (rit ==
begin(rhs)) rit =
end(rhs);
944 const std::vector<vertex>& rhs)
const {
945 if (lhs.size() != rhs.size())
return false;
954template <
typename Real>
957 api.behaviour().firstnumber = 0;
958 api.mesh_create(ps.to_triangle_io());
963template <
typename Real>
968 api.behaviour().firstnumber = 0;
969 api.mesh_create(ps.to_triangle_io(
vertices));
974template <
typename Real>
977 api.behaviour().firstnumber = 0;
978 api.behaviour().poly =
true;
979 api.behaviour().usesegments =
true;
980 auto contour = es.to_triangle_io();
981 contour.numberofsegments = es.num_edges();
985 contour.segmentlist =
new int[contour.numberofsegments * 2];
986 for (
auto e : es.
edges()) {
987 contour.segmentlist[i] = es[e][0].i;
988 contour.segmentlist[i + 1] = es[e][1].i;
992 api.mesh_create(contour);
997template <
typename Real>
1002 api.behaviour().firstnumber = 0;
1003 api.behaviour().poly =
true;
1004 api.behaviour().usesegments =
true;
1005 auto contour = ps.to_triangle_io(polygon);
1006 contour.numberofsegments = polygon.size();
1008 contour.segmentlist =
new int[contour.numberofsegments * 2];
1009 for (
size_t j = 0; j < polygon.size(); ++j, i += 2) {
1010 contour.segmentlist[i] = j;
1011 contour.segmentlist[i + 1] = (j + 1) % polygon.size();
1014 api.mesh_create(contour);
1019template <
typename Real>
1021 triangle::real_type minangle = 0,
1022 triangle::real_type maxarea = 0) {
1024 api.options(
"zpq" + std::to_string(minangle));
1026 api.options(
"zpq" + std::to_string(minangle) +
"a" +
1027 std::to_string(maxarea));
1029 api.options(
"zpq" + std::to_string(minangle));
1031 auto contour = es.to_triangle_io();
1032 contour.numberofsegments = es.num_edges();
1034 contour.segmentlist =
new int[contour.numberofsegments * 2];
1035 for (
auto e : es.
edges()) {
1036 contour.segmentlist[i++] = es[e][0].i;
1037 contour.segmentlist[i++] = es[e][1].i;
1040 api.mesh_create(contour);
void clear()
Definition: cache.h:145
auto & operator=(const cache &other)
Definition: cache.h:48
auto is_valid() const -> bool
Definition: grid_edge.h:207
constexpr const auto & at(face f) const
Definition: mesh.h:216
face_prop< std::vector< edge > > * m_edges_of_faces
Definition: mesh.h:125
auto & faces(edge e)
Definition: mesh.h:423
void remove(vertex v)
Definition: mesh.h:252
const auto & face_property(std::string const &name) const
Definition: mesh.h:587
typename parent_type::template vertex_prop< T > vertex_prop
Definition: mesh.h:95
auto border_polygons(const face_cont_t &faces, bool check_counterclockwise=true)
Definition: mesh.h:897
constexpr bool is_valid(face f) const
Definition: mesh.h:382
constexpr auto insert_face(same_as< vertex > auto const ... vs)
Definition: mesh.h:223
constexpr void clear_faces()
Definition: mesh.h:398
bool are_neighbors(face f0, face f1)
checks if two faces are neighbors
Definition: mesh.h:748
std::vector< std::vector< vertex > > m_faces
Definition: mesh.h:118
auto to_triangle_io(const std::vector< vertex > &vertices) const
Definition: mesh.h:476
auto & add_face_property(const std::string &name, const T &value=T{})
Definition: mesh.h:593
mesh(mesh &&other)
Definition: mesh.h:162
void find_link_properties()
Definition: mesh.h:204
auto to_triangle_io() const
Definition: mesh.h:455
constexpr mesh()
Definition: mesh.h:129
static bool is_left(const pos_type &a, const pos_type &b, const pos_type &c)
Definition: mesh.h:875
constexpr auto num_edges(face f) const
Definition: mesh.h:417
constexpr auto num_vertices(face f) const
Definition: mesh.h:451
mesh(const triangle::io &io)
Definition: mesh.h:139
constexpr auto num_faces(vertex v) const
Definition: mesh.h:412
auto & operator=(const mesh &other)
Definition: mesh.h:171
void triangulate_face(const std::vector< vertex > &polygon)
Definition: mesh.h:293
edge_prop< std::vector< face > > * m_faces_of_edges
Definition: mesh.h:123
auto neighbor_faces(face f) const
Definition: mesh.h:429
void tidy_up()
tidies up invalid vertices, edges and faces
Definition: mesh.h:338
constexpr auto faces() const
Definition: mesh.h:420
void remove(edge e, bool remove_orphaned_vertices=true)
Definition: mesh.h:260
auto & vertices(face f)
Definition: mesh.h:427
void write(const std::string &path)
Definition: mesh.h:602
constexpr auto num_faces() const
Definition: mesh.h:414
auto border_edges_to_vertices(const edge_cont_t &edges)
Definition: mesh.h:839
constexpr mesh(std::initializer_list< pos_type > &&vertices)
Definition: mesh.h:132
auto adjacent_faces(const face_cont_t &faces)
Definition: mesh.h:759
auto & faces(vertex v)
Definition: mesh.h:421
constexpr auto & at(face f)
Definition: mesh.h:215
const auto & faces(vertex v) const
Definition: mesh.h:422
constexpr const auto & operator[](face f) const
Definition: mesh.h:220
const auto & faces(edge e) const
Definition: mesh.h:424
constexpr auto & operator[](face f)
Definition: mesh.h:219
auto & edges(face f)
Definition: mesh.h:425
vertex_prop< std::vector< face > > * m_faces_of_vertices
Definition: mesh.h:122
typename parent_type::template edge_prop< T > edge_prop
Definition: mesh.h:99
constexpr bool has_vertex(face f, vertex v) const
Definition: mesh.h:440
constexpr auto insert_edges(face f)
Definition: mesh.h:387
std::vector< face > m_invalid_faces
Definition: mesh.h:119
auto border_edges(const face_cont_t &faces) const
Definition: mesh.h:797
constexpr bool face_has_edge(face f, edge e) const
Definition: mesh.h:445
void clear()
Definition: mesh.h:406
constexpr auto num_faces(edge e) const
Definition: mesh.h:413
constexpr auto insert_face(std::vector< vertex > new_face)
Definition: mesh.h:228
std::map< std::string, std::unique_ptr< property > > m_face_properties
Definition: mesh.h:120
const auto & edges(face f) const
Definition: mesh.h:426
void add_link_properties()
Definition: mesh.h:193
const auto & vertices(face f) const
Definition: mesh.h:428
auto triangulate_face(face f)
Definition: mesh.h:328
void write_vtk(const std::string &path, const std::string &title="tatooine mesh") const
Definition: mesh.h:631
void write_obj(const std::string &path)
Definition: mesh.h:614
mesh(const mesh &other)
Definition: mesh.h:151
bool polygon_is_counter_clockwise(const std::vector< vertex > &polygon)
Definition: mesh.h:880
auto & operator=(mesh &&other)
Definition: mesh.h:182
auto & face_property(const std::string &name)
Definition: mesh.h:581
auto split_border_edges(const edge_cont_t &edges)
searches coherent border edge loops
Definition: mesh.h:812
constexpr void remove(face f, bool remove_orphaned_vertices=true, bool remove_orphaned_edges=true)
Definition: mesh.h:268
Definition: vtk_legacy.h:448
auto write_point_data(std::size_t i) -> void
auto set_title(std::string const &title) -> void
Definition: vtk_legacy.h:632
auto write_cell_data(std::size_t i) -> void
auto write_scalars(std::string const &name, std::vector< Data > const &data, std::string const &lookup_table_name="default") -> void
Definition: vtk_legacy.h:760
auto write_points(std::vector< std::array< Real, 2 > > const &points) -> void
Definition: vtk_legacy.h:637
auto write_polygons(std::vector< std::vector< std::size_t > > const &polygons) -> void
auto write_header() -> void
Definition: concepts.h:15
typename tatooine::edgeset< Real, NumDimensions >::vertex_handle vertex
Definition: post_triangulation.h:13
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
auto constrained_delaunay(const edgeset< 2, Real > &es)
Definition: mesh.h:975
auto vertices(pointset< Real, NumDimensions > const &ps)
Definition: vertex_container.h:278
auto conforming_delaunay(const edgeset< 2, Real > &es, triangle::real_type minangle=0, triangle::real_type maxarea=0)
Definition: mesh.h:1020
auto next(Iter iter)
Definition: iterator_facade.h:325
auto delaunay(const pointset< 2, Real > &ps)
Definition: mesh.h:955
auto prev(Iter iter)
Definition: iterator_facade.h:343
vec_type pos_type
Definition: axis_aligned_bounding_box.h:109
auto insert_edge(vertex_handle const v0, vertex_handle const v1)
Definition: edgeset.h:16
auto edges() const
Definition: edgeset.h:21
static constexpr auto invalid_idx
Definition: handle.h:16
Int i
Definition: handle.h:21
auto begin() const
Definition: mesh.h:85
auto end() const
Definition: mesh.h:90
const mesh * m_mesh
Definition: mesh.h:83
face f
Definition: mesh.h:60
void decrement()
Definition: mesh.h:69
bool equal(const face_iterator &other) const
Definition: mesh.h:75
face_iterator(face _f, const mesh *_m)
Definition: mesh.h:56
void increment()
Definition: mesh.h:64
friend class boost::iterator_core_access
Definition: mesh.h:62
const mesh * m
Definition: mesh.h:61
auto dereference() const
Definition: mesh.h:76
face_iterator(const face_iterator &other)
Definition: mesh.h:57
const auto & at(face f) const
Definition: mesh.h:106
auto & at(face f)
Definition: mesh.h:105
std::unique_ptr< property > clone() const override
Definition: mesh.h:111
const auto & operator[](face f) const
Definition: mesh.h:108
auto & operator[](face f)
Definition: mesh.h:107
bool operator==(const face &other) const
Definition: mesh.h:46
face & operator=(face &&)=default
static constexpr auto invalid()
Definition: mesh.h:49
bool operator<(const face &other) const
Definition: mesh.h:48
face & operator=(const face &)=default
face(const face &)=default
bool operator!=(const face &other) const
Definition: mesh.h:47
face(size_t i)
Definition: mesh.h:41
bool operator()(const std::vector< vertex > &lhs, const std::vector< vertex > &rhs) const
Definition: mesh.h:943
static bool different_rotation(const std::vector< vertex > &lhs, const std::vector< vertex > &rhs)
Definition: mesh.h:927
static bool same_rotation(const std::vector< vertex > &lhs, const std::vector< vertex > &rhs)
Definition: mesh.h:912
Definition: pointset.h:69
auto num_vertices() const
Definition: pointset.h:229
vertex_property_container_type m_vertex_properties
Definition: pointset.h:119
auto vertices() const
Definition: pointset.h:226
type_list_at< this_type, I > at
Definition: type_list.h:269
std::map< std::string, data_array > vertices
Definition: piece.h:26
std::size_t num_vertices
Definition: piece.h:16