1 #ifndef TIL_MESH_DECIMATION_TPP_
2 #define TIL_MESH_DECIMATION_TPP_
4 #include "til/miscTools.h"
9 //-------------------------------------------------------------------------------------------
14 template < typename TFaces, typename TPoints, typename TNeighbors >
15 void remove_delaunay_faces(TFaces & faces, TNeighbors & neighbors, const TPoints & points)
17 typename TFaces::iterator f = faces.begin();
18 while (f != faces.end())
20 if (til::geo::is_in_circumcircle<double>(points[i], points[(*f)[0]], points[(*f)[1]], points[(*f)[2]]))
22 neighbors.insert((*f)[0]);
23 neighbors.insert((*f)[1]);
24 neighbors.insert((*f)[2]);
36 template < typename TFace >
37 std::list<boost::array<std::size_t,3> >
38 SimpleDelaunayTriangulation::operator()(std::vector<til::numeric_array<float, 2> > points)
40 typedef std::vector<til::numeric_array<float, 2> > Points;
42 typedef std::list<Face> FaceList;
44 // Don't waste time calling this for less than 4 points.
45 assert(points.size() >= 4);
49 // compute bounding triangle and add points to list
50 bounding_triangle(points.begin(), points.end(), std::back_inserter(points));
51 // add triangle to list
52 boost::array<std::size_t,3> face = { points.size()-1, points.size()-2, points.size()-3 };
53 faces.push_back(face);
55 for (std::size_t i = 0; i < n; ++i)
57 // Remove triangles if we lie in their circumcircle, and collect their vertex.
58 std::set<std::size_t> neighbors;
59 remove_delaunay_faces(faces, neighbors, points);
61 FaceList::iterator f = faces.begin();
62 while (f != faces.end())
64 if (til::geo::is_in_circumcircle<double>(points[i], points[(*f)[0]], points[(*f)[1]], points[(*f)[2]]))
66 neighbors.insert((*f)[0]);
67 neighbors.insert((*f)[1]);
68 neighbors.insert((*f)[2]);
78 assert(neighbors.size() >= 3);
80 // order neighbors according to the angle they make with the current point
82 std::vector<Temp> tmp;
83 tmp.reserve(neighbors.size());
84 for (std::set<std::size_t>::iterator iNeighbor = neighbors.begin(); iNeighbor != neighbors.end(); ++iNeighbor)
88 til::numeric_array<float,2> v = points[*iNeighbor]-points[i];
89 t.angle = til::geo::angle(v[0], v[1]);
92 //std::sort(tmp.begin(), tmp.end(), TempComp());
93 std::sort(tmp.begin(), tmp.end());
96 for (std::size_t it = 0; it < tmp.size(); ++it)
98 //std::cout << "Adding face " << i << " " << tmp[it].index << " " << tmp[ (it+1) % til::size(tmp) ].index << std::endl;
99 Face face = {i, tmp[it].index, tmp[ (it+1) % til::size(tmp) ].index };
100 faces.push_back(face);
105 std::cout << "faces" << std::endl;
106 for (FaceList::iterator f = faces.begin(); f != faces.end(); ++f)
108 std::cout << (*f)[0] << " " << (*f)[1] << " " << (*f)[2] << std::endl;
110 std::cout << "endfaces" << std::endl;
114 // Remove extra faces
116 FaceList::iterator f = faces.begin();
117 while (f != faces.end())
119 // Remove faces with supertriangle vertex
134 FaceList::iterator f = faces.begin();
135 std::cout << "cross2D: " << til::cross(points[(*f)[1]] - points[(*f)[0]], points[(*f)[2]] - points[(*f)[0]]) << std::endl;
139 // Check that normals are ok
141 for (FaceList::iterator f = faces.begin(); f != faces.end(); ++f)
143 if (til::cross(points[(*f)[1]] - points[(*f)[0]], points[(*f)[2]] - points[(*f)[0]]) < 0)
151 // Check if we have to resort to normal testing to remove faces
152 if (faces.size() != n-2)
155 std::cout << "NI!" << faces.size() << "-" << n << std::endl;
157 std::cout << "faces2" << std::endl;
158 for (FaceList::iterator f = faces.begin(); f != faces.end(); ++f)
160 std::cout << (*f)[0] << " " << (*f)[1] << " " << (*f)[2] << std::endl;
162 std::cout << "endfaces" << std::endl;
166 // Remove faces with bad normal
169 FaceList::iterator f = faces.begin();
170 while (f != faces.end())
172 if (til::cross(points[(*f)[1]] - points[(*f)[0]], points[(*f)[2]] - points[(*f)[0]]) < 0)
185 FaceList::iterator f = faces.begin();
186 while (f != faces.end())
188 bool flagdel = false;
190 for (int i = 0; i < 3; ++i)
192 if ((*f)[i] > (*f)[(i+1)%3])
197 //f = faces.erase(f);
202 if (flagdel) f = faces.erase(f);
207 // Check again that we have the expected number of faces
208 if (faces.size() != n-2)
210 std::cout << "NI2!" << faces.size() << "-" << n << std::endl;
212 std::cout << "faces2" << std::endl;
213 for (FaceList::iterator f = faces.begin(); f != faces.end(); ++f)
215 std::cout << (*f)[0] << " " << (*f)[1] << " " << (*f)[2] << std::endl;
217 std::cout << "endfaces" << std::endl;
218 std::cout << "points" << std::endl;
219 for (std::size_t i = 0; i < n; ++i) std::cout << points[i] << std::endl;
220 std::cout << "end points" << std::endl;
225 // check that all outer edges is missing
227 std::set<boost::array<std::size_t,2> > outer_edges;
228 for (FaceList::iterator f = faces.begin(); f != faces.end(); ++f)
230 for (std::size_t i = 0; i < 3; ++i)
232 std::size_t delta = std::abs(int((*f)[i]) - int((*f)[(i+1)%3]));
233 if (delta == 1 || delta == (n-1))
235 boost::array<std::size_t,2> tmp = {min((*f)[i], (*f)[(i+1)%3]), max((*f)[i], (*f)[(i+1)%3])};
236 outer_edges.insert(tmp);
240 if (outer_edges.size() != n)
249 std::cout << "nfaces: " << til::size(faces) << std::endl;
250 for (FaceList::const_iterator i = faces.begin(); i != faces.end(); ++i)
252 std::cout << (*i)[0] << " " << (*i)[1] << " " << (*i)[2] << std::endl;
262 #endif /*MESH_DECIMATION_TPP_*/