mirror of https://github.com/CGAL/cgal
285 lines
7.0 KiB
C++
285 lines
7.0 KiB
C++
|
|
#include "SM_common.h"
|
|
|
|
#include <CGAL/Surface_mesh.h>
|
|
#include <CGAL/Simple_cartesian.h>
|
|
|
|
#include <CGAL/use.h>
|
|
|
|
void constructors_test()
|
|
{
|
|
Sm mesh;
|
|
Sm mesh2(mesh);
|
|
mesh = mesh2;
|
|
// Surface_mesh::assign
|
|
}
|
|
|
|
template<typename Iterator>
|
|
void test_iterator(Iterator begin, Iterator end,
|
|
typename std::iterator_traits<Iterator>::difference_type distance)
|
|
{
|
|
assert(begin != end);
|
|
assert(begin == begin);
|
|
assert(std::distance(begin, end) == distance);
|
|
}
|
|
|
|
void standard_iterators()
|
|
{
|
|
Surface_fixture f;
|
|
|
|
Sm::Vertex_iterator vb, ve;
|
|
std::tie(vb, ve) = f.m.vertices();
|
|
test_iterator(vb, ve, 5);
|
|
|
|
Sm::Halfedge_iterator hb, he;
|
|
std::tie(hb, he) = f.m.halfedges();
|
|
test_iterator(hb, he, 14);
|
|
|
|
Sm::Edge_iterator eb, ee;
|
|
std::tie(eb, ee) = f.m.edges();
|
|
test_iterator(eb, ee, 7);
|
|
|
|
Sm::Face_iterator fb, fe;
|
|
std::tie(fb, fe) = f.m.faces();
|
|
test_iterator(fb, fe, 3);
|
|
}
|
|
|
|
void test_descriptors()
|
|
{
|
|
Sm::Vertex_index v;
|
|
Sm::Halfedge_index h;
|
|
CGAL_USE(v < v);
|
|
CGAL_USE(h == h);
|
|
}
|
|
|
|
void test_remove_edge ()
|
|
{
|
|
Surface_fixture f;
|
|
Sm::Halfedge_index wv, uw, wx, xv, vu;
|
|
wv = f.m.halfedge(f.w, f.v);
|
|
assert(f.m.target(wv) == f.v);
|
|
assert(wv.is_valid());
|
|
uw = f.m.halfedge(f.u, f.w);
|
|
assert(uw.is_valid());
|
|
wx = f.m.halfedge(f.w, f.x);
|
|
assert(wx.is_valid());
|
|
xv = f.m.halfedge(f.x, f.v);
|
|
assert(xv.is_valid());
|
|
vu = f.m.halfedge(f.v, f.u);
|
|
assert(vu.is_valid());
|
|
assert(f.m.degree(f.v)== 4);
|
|
assert(f.m.degree(f.w)== 3);
|
|
|
|
f.m.set_next(uw, wx);
|
|
f.m.set_next(xv, vu);
|
|
f.m.remove_edge(Sm::Edge_index(wv));
|
|
Sm::Halfedge_around_target_circulator a(f.m.halfedge(f.w),f.m), b(a);
|
|
assert(CGAL::circulator_distance(a, b)== 2);
|
|
assert(f.m.degree(f.w)== 2);
|
|
a = b = Sm::Halfedge_around_target_circulator(f.m.halfedge(f.v),f.m);
|
|
assert(CGAL::circulator_distance(a, b)== 3);
|
|
assert(f.m.degree(f.v)== 3);
|
|
|
|
// now remove a border edge to check if this works
|
|
// this should not lower the number of faces
|
|
Sm::size_type old_removed_faces_size = f.m.number_of_removed_faces();
|
|
f.m.remove_edge(Sm::Edge_index(wx));
|
|
assert(f.m.number_of_removed_faces()== old_removed_faces_size);
|
|
}
|
|
|
|
|
|
void memory_reuse_test()
|
|
{
|
|
Cube_fixture f;
|
|
// buffer all faces
|
|
typedef std::vector<Sm::Vertex_index> VecFace;
|
|
typedef std::vector<VecFace> Faces;
|
|
|
|
Faces faces;
|
|
Sm::Face_iterator fb, fe;
|
|
for(std::tie(fb, fe) = f.m.faces(); fb != fe; ++fb) {
|
|
faces.push_back(VecFace());
|
|
Sm::Vertex_around_face_circulator vafb(f.m.halfedge(*fb), f.m), vafe(vafb);
|
|
if(vafb)
|
|
do {
|
|
faces.back().push_back(*vafb);
|
|
} while(++vafb != vafe);
|
|
assert(f.m.degree(*fb)== faces.back().size());
|
|
}
|
|
|
|
Sm::Vertex_iterator vb, ve;
|
|
for(std::tie(vb, ve) = f.m.vertices(); vb != ve; ++vb) {
|
|
f.m.set_halfedge(*vb, Sm::Halfedge_index());
|
|
}
|
|
|
|
// remove all faces
|
|
std::size_t old_face_size = f.m.number_of_faces();
|
|
std::size_t old_removed_face_size = f.m.number_of_removed_faces();
|
|
for(auto face : f.m.faces()) f.m.remove_face(face);
|
|
assert(f.m.number_of_faces()== 0);
|
|
assert(f.m.number_of_removed_faces()== old_face_size + old_removed_face_size);
|
|
// remove all edges
|
|
std::size_t old_edge_size = f.m.number_of_edges();
|
|
std::size_t old_removed_edge_size = f.m.number_of_removed_edges();
|
|
for(auto e : f.m.edges()) f.m.remove_edge(e);
|
|
assert(f.m.number_of_faces() == 0);
|
|
assert(f.m.number_of_removed_edges()== old_edge_size + old_removed_edge_size);
|
|
|
|
// add all again
|
|
for(Faces::iterator it = faces.begin(); it != faces.end(); ++it) {
|
|
Sm::Face_index fd = f.m.add_face(*it);
|
|
assert(fd.is_valid());
|
|
f.m.set_vertex_halfedge_to_border_halfedge(f.m.halfedge(fd));
|
|
for(VecFace::iterator it2 = it->begin(); it2 != it->end(); ++it2) {
|
|
|
|
Sm::Halfedge_index h = f.m.halfedge(*it2);
|
|
Sm::Face_index fa = f.m.face(h);
|
|
CGAL_USE(fa);
|
|
}
|
|
}
|
|
|
|
assert(f.m.number_of_edges() == old_edge_size);
|
|
assert(f.m.number_of_faces() == old_face_size);
|
|
|
|
|
|
// remove all vertices
|
|
std::size_t old_size = f.m.number_of_vertices();
|
|
std::size_t old_removed_size = f.m.number_of_removed_vertices();
|
|
|
|
for(auto v : f.m.vertices()) f.m.remove_vertex(v);
|
|
assert(f.m.number_of_vertices() == 0);
|
|
assert(f.m.number_of_removed_vertices()== old_size + old_removed_size);
|
|
|
|
for(unsigned int i = 0; i < old_size; ++i)
|
|
{
|
|
f.m.add_vertex(K::Point_3());
|
|
}
|
|
|
|
// the size must remain the same
|
|
assert(f.m.number_of_vertices()== old_size);
|
|
}
|
|
|
|
void test_validate()
|
|
{
|
|
Cube_fixture cf;
|
|
Surface_fixture f1;
|
|
Surface_fixture_2 f2;
|
|
Surface_fixture_3 f3;
|
|
assert(cf.m.is_valid());
|
|
assert(f1.m.is_valid());
|
|
assert(f2.m.is_valid());
|
|
assert(f3.m.is_valid());
|
|
}
|
|
|
|
void isolated_vertex_check()
|
|
{
|
|
Surface_fixture f;
|
|
Sm::Vertex_index isolated = f.m.add_vertex(Point_3(10, 10, 10));
|
|
assert(f.m.is_isolated(isolated));
|
|
assert(!f.m.halfedge(isolated).is_valid());
|
|
assert(f.m.is_border(isolated));
|
|
assert(f.m.is_border(isolated, false));
|
|
assert(f.m.degree(isolated) == 0);
|
|
}
|
|
|
|
void embedded_vertex_check()
|
|
{
|
|
Surface_fixture_2 f;
|
|
assert(!f.m.is_isolated(f.y));
|
|
assert(!f.m.is_border(f.y));
|
|
assert(f.m.halfedge(f.y).is_valid());
|
|
assert(f.m.degree(f.y) == 4);
|
|
}
|
|
|
|
void border_vertex_check()
|
|
{
|
|
Surface_fixture f;
|
|
assert(!f.m.is_isolated(f.y));
|
|
assert(f.m.is_border(f.y));
|
|
assert(f.m.degree(f.y) == 2);
|
|
assert(f.m.halfedge(f.y).is_valid());
|
|
set_halfedge(f.y, opposite(next(f.m.halfedge(f.y),f.m), f.m), f.m);
|
|
assert(f.m.is_border(f.y));
|
|
assert(! f.m.is_border(f.y, false));
|
|
}
|
|
|
|
|
|
void point_position_accessor ()
|
|
{
|
|
Surface_fixture f;
|
|
// by property
|
|
f.m.points()[f.x];
|
|
// non-const
|
|
f.m.point(f.x);
|
|
// const as an lvalue
|
|
f.m.point(f.x) = CGAL::ORIGIN;
|
|
assert(f.m.point(f.x) == CGAL::ORIGIN);
|
|
}
|
|
|
|
void properties () {
|
|
Surface_fixture f;
|
|
|
|
|
|
Sm::Property_map<Sm::Vertex_index, int> prop;
|
|
bool created = false;
|
|
|
|
std::tie(prop,created) = f.m.add_property_map<Sm::Vertex_index, int>("illuminatiproperty", 23);
|
|
assert(created == true);
|
|
|
|
std::tie(prop, created)= f.m.add_property_map<Sm::Vertex_index, int>("illuminatiproperty");
|
|
assert(created == false);
|
|
}
|
|
|
|
void move () {
|
|
Surface_fixture f;
|
|
|
|
auto nf = num_faces(f.m);
|
|
|
|
// test move-constructor
|
|
Sm m2{std::move(f.m)};
|
|
assert(f.m.is_valid());
|
|
assert(m2.is_valid());
|
|
assert(num_faces(m2) == nf);
|
|
assert(num_faces(f.m) == 0);
|
|
|
|
// test move-assignment
|
|
f.m = std::move(m2);
|
|
assert(f.m.is_valid());
|
|
assert(m2.is_valid());
|
|
assert(num_faces(f.m) == nf);
|
|
assert(num_faces(m2) == 0);
|
|
|
|
// test copy-assignment
|
|
m2 = f.m;
|
|
assert(f.m.is_valid());
|
|
assert(m2.is_valid());
|
|
assert(num_faces(f.m) == nf);
|
|
assert(num_faces(m2) == nf);
|
|
|
|
// test copy-constructor
|
|
Sm m3 {f.m};
|
|
assert(f.m.is_valid());
|
|
assert(m2.is_valid());
|
|
assert(num_faces(f.m) == nf);
|
|
assert(num_faces(m2) == nf);
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
constructors_test();
|
|
standard_iterators();
|
|
test_descriptors();
|
|
test_remove_edge();
|
|
memory_reuse_test();
|
|
test_validate();
|
|
isolated_vertex_check();
|
|
embedded_vertex_check();
|
|
border_vertex_check();
|
|
point_position_accessor();
|
|
properties();
|
|
move();
|
|
std::cout << "done" << std::endl;
|
|
return 0;
|
|
}
|