10 #include <boost/shared_ptr.hpp> 14 #include "aims/mesh/surface.h" 15 #include "aims/vector/vector.h" 45 const Point3df ¢er,
54 template <
typename TMesh >
59 template <
typename TMesh,
typename TVertex >
64 typename boost::enable_if<is_same_naked<typename MeshTraits<TMesh>::Vertex, TVertex>, std::size_t>::type
101 int size = meshFrom.vertex().size();
106 std::transform(meshFrom.vertex().begin(), meshFrom.vertex().end(),
getVertices(meshTo).begin(),
108 size = meshFrom.polygon().size();
119 meshTo.vertex().resize(size);
126 meshTo.polygon().resize(size);
133 template <
class TMeshFrom,
class TMeshTo >
161 template <
class TMeshFrom,
class TMeshTo >
231 template <
typename TFaceCollection >
236 typedef std::pair<index_type,index_type>
Edge;
237 typedef std::map<Edge, std::vector<index_type> >
Edges;
241 TFaceCollection
const & faces,
242 std::vector<Edge> & res,
243 std::vector<std::vector<index_type> > & newfaces
256 template <
typename TFaceCollection >
264 typename Edges::iterator pos = edges.find(edge);
265 if (pos != edges.end())
267 pos->second.push_back(i);
271 edges.insert(
typename Edges::value_type(edge, std::vector<std::size_t>(1,i)));
277 template <
typename TFaceCollection >
280 TFaceCollection
const & faces,
281 std::vector<Edge> & res,
282 std::vector<std::vector<index_type> > & newfaces
286 typename TFaceCollection::const_iterator iFace;
288 for (i = 0, iFace = faces.begin(); iFace != faces.end(); ++iFace, ++i)
298 res.resize(edges.size());
302 newfaces.resize(faces.size());
303 typename Edges::const_iterator ie;
304 for (i = 0, ie = edges.begin(); ie != edges.end(); ++ie, ++i)
307 assert(ie->second.size() == 2);
308 for (std::size_t j = 0; j < ie->second.size(); ++j)
310 newfaces[ie->second[j]].push_back(i);
317 template <
typename TFaceCollection >
322 TFaceCollection
const & faces,
323 std::vector<std::pair<std::size_t, std::size_t> > & res,
324 std::vector<std::vector<std::size_t> > & newfaces
333 template <
typename TFaceCollection >
337 typedef std::size_t index_type;
338 typedef std::pair<index_type,index_type> Edge;
340 std::set<Edge> edges;
341 typename TFaceCollection::const_iterator iFace = faces.begin();
342 for (; iFace != faces.end(); ++iFace)
353 std::copy(edges.begin(), edges.end(), res->begin());
361 template <
typename TNeighborhoodCollection >
365 TNeighborhoodCollection
const & neigh,
366 std::vector<std::pair<std::size_t, std::size_t> > & edges
369 typedef std::pair<std::size_t, std::size_t> Edge;
370 std::set<Edge> my_edges;
371 for (std::size_t i = 0; i < neigh.size(); ++i)
373 for (std::size_t j = 0; j < neigh[i].size(); ++j)
378 edges.resize(edges.size());
379 std::copy(my_edges.begin(), my_edges.end(), edges.begin());
382 assert(edges.size() * 2 == neigh.size());
393 template <
typename TFaceCollection >
399 template <
typename TVertexCollection,
typename TFaceCollection >
408 template <
typename TMesh >
424 for (;iFi2 != iFic->end(); ++iFi1, ++iFi2)
440 for (std::size_t i = 0; i <
size(res); ++i)
454 template <
typename TVertexCollection,
typename TFaceIndexCollection >
457 const TVertexCollection & vertices,
458 const TFaceIndexCollection & faces,
459 std::vector<std::vector<std::size_t> > & neigh
462 typedef typename TFaceIndexCollection::value_type FaceIndices;
463 typedef std::size_t VertexIndex;
466 std::vector<std::set<VertexIndex> > res(vertices.size());
468 for (
typename TFaceIndexCollection::const_iterator iFic = faces.begin(); iFic != faces.end(); ++iFic)
471 typename FaceIndices::const_iterator iFi1 = iFic->begin();
472 typename FaceIndices::const_iterator iFi2 = iFi1+1;
473 for (;iFi2 != iFic->end(); ++iFi1, ++iFi2)
475 res[*iFi2].insert(*iFi1);
476 res[*iFi1].insert(*iFi2);
480 res[*(iFic->begin())].insert(*iFi1);
481 res[*iFi1].insert(*(iFic->begin()));
484 neigh.resize(res.size());
487 for (std::size_t i = 0; i <
size(res); ++i)
489 neigh[i].resize(res[i].
size());
497 template <
typename TParam >
516 template <
typename TMesh,
typename TContainer,
typename TFunctor >
533 typename TContainer::iterator iC = c.begin();
538 typename TContainer::value_type::iterator iL = iC->begin();
539 for (; iNi != iNic->end(); ++iNi, ++iL)
549 template <
typename TMesh,
typename TContainer,
typename TFunctor >
566 typename TContainer::iterator iC = c.begin();
571 for (; iNi != iNic->end(); ++iNi)
581 template <
typename TMesh,
typename TContainer,
typename TFunctor >
582 inline typename boost::enable_if_c<
583 is_container<typename TContainer::value_type>::value
592 template <
typename TMesh,
typename TContainer,
typename TFunctor >
593 inline typename boost::enable_if_c<
594 !is_container<typename TContainer::value_type>::value
611 template <
typename TMesh,
typename TContainer1,
typename TContainer2,
typename TFunctor >
634 typename TContainer1::iterator iC1 = c1.begin();
635 typename TContainer2::iterator iC2 = c2.begin();
640 typename TContainer1::value_type::iterator iL1 = iC1->begin();
641 typename TContainer2::value_type::iterator iL2 = iC2->begin();
642 for (; iNi != iNic->end(); ++iNi, ++iL1, ++iL2)
653 template <
typename TMesh,
typename TContainer1,
typename TContainer2,
typename TFunctor >
683 for (; iNi != iNic->end(); ++iNi, ++iL1)
702 template <
typename TMesh,
typename TContainer1,
typename TContainer2,
typename TFunctor >
703 inline typename boost::enable_if_c<
704 is_container<typename TContainer1::value_type>::value &&
705 is_container<typename TContainer2::value_type>::value
716 template <
typename TMesh,
typename TContainer1,
typename TContainer2,
typename TFunctor >
717 inline typename boost::enable_if_c<
718 is_container<typename TContainer1::value_type>::value &&
719 !is_container<typename TContainer2::value_type>::value
736 template <
typename TPrecision,
typename TMesh >
737 inline typename boost::enable_if_c<
744 std::vector<std::vector<TPrecision> > & lengths
756 template <
typename TVertexXsr,
typename TCircularNeighborXsr,
typename prec_type >
774 : m_vertexXsr(vertexXsr)
775 , m_neighXsr(neighXsr)
804 NeighborhoodRef nh = m_neighXsr(i);
806 assert(
size(nh) >= 2);
807 VertexRef p = m_vertexXsr(i);
813 std::fill(m_normal.begin(), m_normal.end(), prec_type(0));
815 m_gaussianCurvature = 0;
820 typename Neighborhood::const_iterator iNh1 = nh.
begin();
822 for (; iNh1 != nh.end(); ++iNh1, ++iNh2)
825 e1 = p - m_vertexXsr(*iNh1);
826 prec_type n21 = norm2<prec_type>(e1);
829 e2 = p - m_vertexXsr(*iNh2);
830 prec_type n22 = norm2<prec_type>(e2);
833 e3 = m_vertexXsr(*iNh2) - m_vertexXsr(*iNh1);
834 prec_type n23 = norm2<prec_type>(e3);
838 prec_type d1 =
dot(e1, e3);
839 prec_type d2 =
dot(e2, e3);
841 prec_type biarea =
std::sqrt(n21*n23 - d1*d1);
844 m_gaussianCurvature -= std::acos(
max(prec_type(-1),
min(prec_type(1),
dot(e1, e2) / (n1*n2))));
859 m_normal += (d1 * e2 - d2 * e1) * (prec_type(1)/biarea);
861 if (
dot(e1, e2) <= 0)
865 m_voronoiArea += biarea / 4;
869 if (d1 <= 0 || d2 >= 0)
873 m_voronoiArea += biarea / 8;
877 m_voronoiArea += 1.0/8.0 * (n22 * d1 - n21 * d2 ) / biarea;
883 m_gaussianCurvature += 2*
M_PI;
884 m_gaussianCurvature /= m_voronoiArea;
887 m_meanCurvature = norm<prec_type>(m_normal) / (4*m_voronoiArea);
889 prec_type delta =
std::sqrt(
max(prec_type(0),
square(m_meanCurvature) - m_gaussianCurvature));
890 m_principalCurvatures.first = m_meanCurvature + delta;
891 m_principalCurvatures.second = m_meanCurvature - delta;
895 if (
dot(m_normal,
cross(e1, e2)) < 0)
897 m_orientedMeanCurvature = -m_meanCurvature;
898 m_orientedGaussianCurvature = -m_gaussianCurvature;
899 m_principalCurvatures.first = -m_principalCurvatures.first;
900 m_principalCurvatures.second = -m_principalCurvatures.second;
901 m_normal *= -1/
norm(m_normal);
905 m_orientedMeanCurvature = m_meanCurvature;
906 m_orientedGaussianCurvature = m_gaussianCurvature;
907 m_normal *= 1/
norm(m_normal);
913 TVertexXsr m_vertexXsr;
914 TCircularNeighborXsr m_neighXsr;
918 prec_type m_gaussianCurvature;
919 prec_type m_meanCurvature;
920 prec_type m_orientedGaussianCurvature;
921 prec_type m_orientedMeanCurvature;
922 prec_type m_voronoiArea;
923 std::pair<prec_type, prec_type> m_principalCurvatures;
929 template <
typename TVertexCollection,
typename TCircularNeighborIndices,
typename prec_type >
936 typedef typename TVertexCollection::value_type
Vertex;
940 Mesh_curvature(
const TVertexCollection & vertices,
const TCircularNeighborIndices & neighs)
941 : m_vertices(vertices), m_neighs(neighs) {}
969 Neighborhood nh = m_neighs[i];
971 assert(
size(nh) >= 2);
972 const Vertex & p = m_vertices[i];
978 std::fill(m_normal.begin(), m_normal.end(), prec_type(0));
980 m_gaussianCurvature = 0;
985 typename Neighborhood::const_iterator iNh1 = nh.
begin();
987 for (; iNh1 != nh.end(); ++iNh1, ++iNh2)
990 e1 = p - m_vertices[*iNh1];
991 prec_type n21 = norm2<prec_type>(e1);
994 e2 = p - m_vertices[*iNh2];
995 prec_type n22 = norm2<prec_type>(e2);
998 e3 = m_vertices[*iNh2] - m_vertices[*iNh1];
999 prec_type n23 = norm2<prec_type>(e3);
1003 prec_type d1 =
dot(e1, e3);
1004 prec_type d2 =
dot(e2, e3);
1006 prec_type biarea =
std::sqrt(n21*n23 - d1*d1);
1009 m_gaussianCurvature -= std::acos(
max(prec_type(-1),
min(prec_type(1),
dot(e1, e2) / (n1*n2))));
1024 m_normal += (d1 * e2 - d2 * e1) * (prec_type(1)/biarea);
1026 if (
dot(e1, e2) <= 0)
1030 m_voronoiArea += biarea / 4;
1034 if (d1 <= 0 || d2 >= 0)
1038 m_voronoiArea += biarea / 8;
1042 m_voronoiArea += 1.0/8.0 * (n22 * d1 - n21 * d2 ) / biarea;
1048 m_gaussianCurvature += 2*
M_PI;
1049 m_gaussianCurvature /= m_voronoiArea;
1052 m_meanCurvature = norm<prec_type>(m_normal) / (4*m_voronoiArea);
1054 prec_type delta =
std::sqrt(
max(prec_type(0),
square(m_meanCurvature) - m_gaussianCurvature));
1055 m_principalCurvatures.first = m_meanCurvature + delta;
1056 m_principalCurvatures.second = m_meanCurvature - delta;
1060 if (
dot(m_normal,
cross(e1, e2)) < 0)
1062 m_orientedMeanCurvature = -m_meanCurvature;
1063 m_orientedGaussianCurvature = -m_gaussianCurvature;
1064 m_principalCurvatures.first = -m_principalCurvatures.first;
1065 m_principalCurvatures.second = -m_principalCurvatures.second;
1066 m_normal *= -1/
norm(m_normal);
1070 m_orientedMeanCurvature = m_meanCurvature;
1071 m_orientedGaussianCurvature = m_gaussianCurvature;
1072 m_normal *= 1/
norm(m_normal);
1079 const TVertexCollection & m_vertices;
1080 const TCircularNeighborIndices & m_neighs;
1084 prec_type m_gaussianCurvature;
1085 prec_type m_meanCurvature;
1086 prec_type m_orientedGaussianCurvature;
1087 prec_type m_orientedMeanCurvature;
1088 prec_type m_voronoiArea;
1089 std::pair<prec_type, prec_type> m_principalCurvatures;
1103 template <
typename TCollection >
1117 {
return m_data[i]; }
1118 typename TCollection::const_reference
operator()(index_type i)
const 1119 {
return m_data[i]; }
1122 TCollection & m_data;
1139 template <
typename TIterator >
1152 template <
typename TIterator >
1163 {
return i->pos(); }
1169 template <
typename TIterator >
1173 typedef typename TIterator::value_type::VertexIndexCollection
value_type;
1177 {
return i->neighbors(); }
1186 template <
typename TVertexAccessPolicy,
typename TCircularNeighborhoodAccessPolicy,
typename prec_type >
1192 typedef typename TCircularNeighborhoodAccessPolicy::value_type
Neighborhood;
1194 typedef typename TVertexAccessPolicy::value_type
Vertex;
1200 MeshCurvature2(TVertexAccessPolicy vertexAccess, TCircularNeighborhoodAccessPolicy neighborAccess)
1201 : m_vertexAccess(vertexAccess), m_neighborAccess(neighborAccess) {}
1229 const Neighborhood & nh = m_neighborAccess(i);
1231 assert(
size(nh) >= 2);
1232 const Vertex & p = m_vertexAccess(i);
1239 m_gaussianCurvature = 0;
1243 typename Neighborhood::const_iterator iNh1 = nh.
begin();
1245 for (; iNh1 != nh.end(); ++iNh1, ++iNh2)
1248 e1 = p - m_vertexAccess(*iNh1);
1249 prec_type n21 = norm2<prec_type>(e1);
1252 e2 = p - m_vertexAccess(*iNh2);
1253 prec_type n22 = norm2<prec_type>(e2);
1256 e3 = m_vertexAccess(*iNh2) - m_vertexAccess(*iNh1);
1257 prec_type n23 = norm2<prec_type>(e3);
1261 prec_type d1 =
dot(e1, e3);
1262 prec_type d2 =
dot(e2, e3);
1264 prec_type biarea =
std::sqrt(n21*n23 - d1*d1);
1267 m_gaussianCurvature -= std::acos(
max(prec_type(-1),
min(prec_type(1),
dot(e1, e2) / (n1*n2))));
1282 m_normal += (d1 * e2 - d2 * e1) * (prec_type(1)/biarea);
1284 if (
dot(e1, e2) <= 0)
1288 m_voronoiArea += biarea / 4;
1292 if (d1 <= 0 || d2 >= 0)
1296 m_voronoiArea += biarea / 8;
1300 m_voronoiArea += 1.0/8.0 * (n22 * d1 - n21 * d2 ) / biarea;
1306 m_gaussianCurvature += 2*
M_PI;
1307 m_gaussianCurvature /= m_voronoiArea;
1310 m_meanCurvature = norm<prec_type>(m_normal) / (4*m_voronoiArea);
1312 prec_type delta =
std::sqrt(
max(prec_type(0),
square(m_meanCurvature) - m_gaussianCurvature));
1313 m_principalCurvatures.first = m_meanCurvature + delta;
1314 m_principalCurvatures.second = m_meanCurvature - delta;
1317 if (
dot(m_normal,
cross(e1, e2)) < 0)
1319 m_orientedMeanCurvature = -m_meanCurvature;
1320 m_orientedGaussianCurvature = -m_gaussianCurvature;
1321 m_principalCurvatures.first = -m_principalCurvatures.first;
1322 m_principalCurvatures.second = -m_principalCurvatures.second;
1323 m_normal *= -1/
norm(m_normal);
1327 m_orientedMeanCurvature = m_meanCurvature;
1328 m_orientedGaussianCurvature = m_gaussianCurvature;
1329 m_normal *= 1/
norm(m_normal);
1335 TVertexAccessPolicy m_vertexAccess;
1336 TCircularNeighborhoodAccessPolicy m_neighborAccess;
1340 prec_type m_gaussianCurvature;
1341 prec_type m_meanCurvature;
1342 prec_type m_orientedGaussianCurvature;
1343 prec_type m_orientedMeanCurvature;
1344 prec_type m_voronoiArea;
1345 std::pair<prec_type, prec_type> m_principalCurvatures;
1356 template <
typename TData,
typename TPrec,
typename TDist = SquaredEucl
ideanDist<TPrec> >
1360 typedef typename TData::const_iterator iterator;
1369 : m_begin(data.begin())
1372 , m_quant(new
std::vector<iterator>(1, data.begin()))
1373 , m_labels(new
std::vector<
std::size_t>(data.
size(), 0))
1388 unsigned int niter = 0;
1394 this->computeClusters();
1395 this->moveClusterSeeds();
1398 std::size_t count = 0;
1401 for (iterator i = m_begin; i != m_end; ++i, ++count)
1403 std::size_t label = (*m_labels)[count];
1404 if (m_dist(*i, *(*m_quant)[label]) > maxDiam)
1413 this->addNewClusterSeed();
1415 if (m_quant->size() != (niter+1))
1417 std::cerr <<
"Warning: early termination of clustering" << std::endl;
1429 std::size_t count = 0;
1430 for (iterator i = m_begin; i != m_end; ++i, ++count)
1434 for (std::size_t j = 0; j < m_quant->size(); ++j)
1436 prec_type tmp = m_dist(*i, *(*m_quant)[j]);
1440 (*m_labels)[count] = j;
1449 std::vector<value_type> centers(m_quant->size(), value_type());
1452 std::vector<unsigned int> counts(m_quant->size(), 0);
1453 std::size_t count = 0;
1454 for (iterator i = m_begin; i != m_end; ++i, ++count)
1456 std::size_t label = (*m_labels)[count];
1458 centers[label] += *i;
1462 for (std::size_t i = 0; i < centers.size(); ++i)
1464 assert(counts[i] > 0);
1465 centers[i] *= prec_type(1)/counts[i];
1471 std::size_t count = 0;
1472 for (iterator i = m_begin; i != m_end; ++i, ++count)
1474 std::size_t label = (*m_labels)[count];
1476 prec_type tmp = m_dist(*i, centers[label]);
1477 if (tmp < dists[label])
1480 (*m_quant)[label] = i;
1488 prec_type max_dist = 0.0;
1489 iterator newSeed = m_begin;
1491 std::size_t count = 0;
1492 for (iterator i = m_begin; i != m_end; ++i, ++count)
1494 std::size_t label = (*m_labels)[count];
1496 prec_type tmp = m_dist(*i, *(*m_quant)[label]);
1504 if (max_dist == 0.0)
1506 std::cerr <<
"Seed cannot be added" << std::endl;
1512 typename std::vector<iterator>::iterator i = std::find(m_quant->begin(), m_quant->end(), newSeed);
1513 assert( i == m_quant->end() );
1517 m_quant->push_back(newSeed);
1540 template <
typename TCollection,
typename TPrec >
1632 template <
typename TPrec,
typename TVertexIndex,
typename TVertexCollection,
typename TNeighborhood,
typename TVertex >
1634 dist2_surface(
const TVertex & p, TVertexIndex i,
const TVertexCollection & vertices,
const TNeighborhood & neighc)
1636 typedef typename TVertex::value_type prec_type;
1639 typename TNeighborhood::const_iterator ineigh = neighc.
begin();
1642 for (; ineigh != neighc.end(); ++ineigh, ++ineigh2)
1657 template <
typename TPrec,
typename TVertexIndex,
typename TVertexCollection,
typename TNeighborhood,
typename TVertex >
1659 closest_normal(
const TVertex & p, TVertexIndex i,
const TVertexCollection & vertices,
const TNeighborhood & neighc)
1661 typedef typename TVertex::value_type prec_type;
1664 typename TNeighborhood::const_iterator ineigh = neighc.
begin();
1668 for (; ineigh != neighc.end(); ++ineigh, ++ineigh2)
1689 template <
typename TVertexAccessPolicy,
typename TNeighborhoodAccessPolicy,
typename TVertexAccessPolicy2 >
1695 typedef typename TVertexAccessPolicy::value_type
Vertex;
1704 TVertexAccessPolicy vertexAccess,
1705 TNeighborhoodAccessPolicy neighborAccess,
1706 TVertexAccessPolicy2 vertexAccess2,
1709 : m_vertexAccess(vertexAccess)
1710 , m_neighborAccess(neighborAccess)
1711 , m_vertexAccess2(vertexAccess2)
1717 void operator()(VertexIndex begin, VertexIndex end, VertexIndex2 begin2)
1719 for (; begin != end; ++begin, ++begin2)
1721 m_buffer[0] = m_buffer[1] = m_buffer[2] = 0;
1723 m_vertexAccess2(begin2) = m_vertexAccess(begin);
1725 for (
typename Neighborhood::const_iterator iNeigh = m_neighborAccess(begin).begin(); iNeigh != m_neighborAccess(begin).end(); ++iNeigh)
1727 m_tmp = m_vertexAccess(*iNeigh) - m_vertexAccess(begin);
1728 prec_type d =
norm(m_tmp);
1734 m_vertexAccess2(begin2) += m_lambda * (2/E) * m_buffer;
1740 TVertexAccessPolicy m_vertexAccess;
1741 TNeighborhoodAccessPolicy m_neighborAccess;
1742 TVertexAccessPolicy2 m_vertexAccess2;
1759 template <
typename TInputAccessPolicy,
typename TOutputAccessPolicy,
typename TNeighborhoodAccessPolicy >
1765 typedef typename TInputAccessPolicy::value_type
Data;
1774 TInputAccessPolicy inputAccess,
1775 TOutputAccessPolicy outputAccess,
1776 TNeighborhoodAccessPolicy neighborAccess,
1779 : m_inputAccess(inputAccess)
1780 , m_outputAccess(outputAccess)
1781 , m_neighborAccess(neighborAccess)
1787 void operator()(InputIndex begin, InputIndex end, OutputIndex begin2)
1789 for (; begin != end; ++begin, ++begin2)
1792 assert(m_neighborAccess(begin).
size() > 0);
1794 m_outputAccess(begin2) = m_inputAccess(begin) * (1 - m_lambda);
1795 prec_type coeff = m_lambda / m_neighborAccess(begin).size();
1796 typename Neighborhood::const_iterator iNeigh = m_neighborAccess(begin).begin();
1797 for (; iNeigh != m_neighborAccess(begin).end(); ++iNeigh)
1799 m_outputAccess(begin2) += coeff * m_inputAccess(*iNeigh);
1802 if (
is_nan(m_outputAccess(begin2)))
1804 std::cout <<
"(LS:is-nan)";
1812 TInputAccessPolicy m_inputAccess;
1813 TOutputAccessPolicy m_outputAccess;
1814 TNeighborhoodAccessPolicy m_neighborAccess;
1820 template <
typename TVertex >
1823 std::vector<TVertex> & vertices,
1824 std::vector<std::vector<std::size_t> > & neighbors,
1829 typedef std::vector<TVertex> TVertexCollection;
1834 std::size_t n = vertices.size();
1836 std::vector<TVertex> verticesBuff(n);
1837 VertexIndexing indVertex(vertices);
1838 VertexIndexing indVertexBuff(verticesBuff);
1839 NeighborIndexing indNeigh(neighbors);
1840 Smoother smoothToBuffer(indVertex, indVertexBuff, indNeigh, coeff);
1841 Smoother smoothFromBuffer(indVertexBuff, indVertex, indNeigh, coeff);
1842 for (
unsigned int i = 0; i < nstep; ++i)
1844 smoothToBuffer(0, n, 0);
1845 smoothFromBuffer(0, n, 0);
1852 template <
typename TVertexAccessPolicy,
typename TNeighborhoodAccessPolicy >
1859 typedef typename TVertexAccessPolicy::value_type
Vertex;
1867 TVertexAccessPolicy vertexAccess,
1868 TNeighborhoodAccessPolicy neighborAccess,
1869 const prec_type lambda,
1873 : m_vertexAccess(vertexAccess)
1874 , m_neighborAccess(neighborAccess)
1878 this->setBufferSize(bufferSize);
1885 prec_type &
mu() {
return m_mu; }
1892 this->lambda_step(begin, end);
1893 this->mu_step(begin, end);
1898 void lambda_step(VertexIndex begin, VertexIndex end)
1900 for (std::size_t i = 0; begin != end; ++begin, ++i)
1902 m_vertices[i] = m_vertexAccess(begin) * (1 - m_lambda);
1903 prec_type coeff = m_lambda / m_neighborAccess(begin).size();
1904 typename Neighborhood::const_iterator iNeigh = m_neighborAccess(begin).begin();
1905 for (; iNeigh != m_neighborAccess(begin).end(); ++iNeigh)
1907 m_vertices[i] += coeff * m_vertexAccess(*iNeigh);
1912 void mu_step(VertexIndex begin, VertexIndex end)
1914 for (std::size_t i = 0; begin != end; ++begin, ++i)
1916 m_vertexAccess(begin) = m_vertices[i] * (1 + m_mu);
1917 prec_type coeff = m_mu / m_neighborAccess(begin).size();
1918 typename Neighborhood::const_iterator iNeigh = m_neighborAccess(begin).begin();
1919 for (; iNeigh != m_neighborAccess(begin).end(); ++iNeigh)
1921 m_vertexAccess(begin) -= coeff * m_vertexAccess(*iNeigh);
1928 TVertexAccessPolicy m_vertexAccess;
1929 TNeighborhoodAccessPolicy m_neighborAccess;
1935 std::vector<Vertex> m_vertices;
1941 template <
typename NeighborCollection,
typename NeighborCollectionOut >
1945 NeighborCollection
const & neigh
1946 , NeighborCollectionOut & neigh_n_out
1955 template <
typename T >
1959 std::vector<std::vector<T> >
const & neighbors
1960 , std::vector<std::pair<T, T> > & edges
1965 template <
typename T >
1976 std::vector<std::vector<T> >
const & cneighs
1977 , std::vector<til::numeric_array<T, 3> >
const & faces
1978 , std::vector<std::vector<T> > & neighborfaces
1987 template <
typename T >
1991 std::vector<std::vector<T> >
const & cneighs
1993 , std::vector<std::vector<T> > & neighborfaces
2007 #endif //_MESHUTILS_H_ prec_type voronoiArea() const
Return computed voronoi area at vertex.
namespace for template expressions.
Project a point onto a 3D triangle.
std::pair< T, T > make_sorted_pair(T a, T b)
Return (a, b) if a >= b, (b, a) else.
A class to represent a very basic mesh, consisting of a set of vertices and a set of edges...
Numerical precision of the data for storage classes.
void operator()(VertexIndex begin, VertexIndex end, VertexIndex2 begin2)
numeric_array< double, 3 > closest_normal(const TVertex &p, TVertexIndex i, const TVertexCollection &vertices, const TNeighborhood &neighc)
Returns the index of the neighborhood that is the closest.
TVertexAccessPolicy::value_type Vertex
numeric_array< TPrec, 3 > cross(const numeric_array< T1, 3 > &vec1, const numeric_array< T2, 3 > &vec2, prec< TPrec >)
Return the cross product of two 3D vectors.
Vertex::value_type prec_type
boost::enable_if< is_Image< TImage >, typename TImage::value_type >::type min(const TImage &im)
TCollection::reference operator()(index_type i)
void sqrt(const TImage &in, TImage &out)
TNeighborhoodAccessPolicy::value_type Neighborhood
prec_type unorientedGaussianCurvature() const
Return unoriented Gaussian curvature at vertex.
TInputAccessPolicy::index_type InputIndex
shared_ptr< std::vector< std::vector< typename TFaceCollection::value_type::value_type > > > circular_neighborhoods(TFaceCollection const &faces, std::size_t nVertices)
Get point neighbors so that they form a loop around points.
boost::enable_if_c< is_container< typename TContainer::value_type >::value >::type for_each_neighbors(const TMesh &mesh, TContainer &c1, TFunctor f)
shared_ptr< std::vector< std::pair< std::size_t, std::size_t > > > faces2edges(TFaceCollection const &faces)
Collects edges from a set of faces.
std::map< Edge, std::vector< index_type > > Edges
IntegerIndexing(TCollection &data)
MeshTraits< Mesh_N >::NeighborIndexCollection & getNeighborIndices(Mesh_N &mesh)
Return value pointed at by an iterator.
TCollection::const_reference operator()(index_type i) const
Mesh_curvature2(TVertexXsr vertexXsr, TCircularNeighborXsr neighXsr)
void process(VertexIndex i)
Computes all the good stuff at the i-th vertex.
const numeric_array< prec_type, 3 > & normal() const
Return computed normal.
shared_ptr< std::vector< typename TCollection::const_iterator > > gonzalez_clustering(const TCollection &data, TPrec maxDiam)
Gonzalez clustering.
TCircularNeighborXsr::value_type Neighborhood
prec_type meanCurvature() const
Return computed (signed) mean curvature at vertex.
TPrec dot(const numeric_array< T1, D > &a1, const numeric_array< T2, D > &a2, prec< TPrec >)
Return the dot product of two vectors.
std::size_t getVertexNumber(const TMesh &, std::size_t i)
Return the index of vertex v[i] – which is, obviously, i.
void convert_mesh1Toaimsmesh(const til::Mesh1 &meshFrom, AimsTimeSurface< 3, Void > &meshTo)
INLINE double norm(const T &a, const T &b)
< Euclidean norm of 2D vector (a, b)
TVertexXsr::reference VertexRef
TVertexXsr::index_type index_type
Belongs to package Box Do not include directly, include til/Box.h instead.
TExpr< TExprBinaryOperator< Expr1, Expr2, functor::CastTo > > castTo(TExpr< Expr1 > e1, TExpr< Expr2 > e2)
bool triangle_normal(const TArray &A, const TArray &B, const TArray &C, TResArray &result)
Compute the normal of a triangle.
A const cyclic iterator is a const iterator that goes back to the begining of the container when it r...
value_type & operator()(index_type i) const
TIterator::value_type::VertexIndex index_type
value_type & operator()(index_type i) const
void addNewClusterSeed()
Add a new cluster to the list.
TNeighborhoodAccessPolicy::value_type Neighborhood
numeric_array< T, D > size(const Box< T, D > &box)
Return the size of a box.
prec_type unorientedMeanCurvature() const
Return unoriented mean curvature at vertex.
prec_type gaussianCurvature() const
Return computed (signed) Gaussian curvature at vertex.
MeshCurvature2(TVertexAccessPolicy vertexAccess, TCircularNeighborhoodAccessPolicy neighborAccess)
TCollection::value_type value_type
prec_type meanCurvature() const
Return computed (signed) mean curvature at vertex.
void setBufferSize(int bufferSize)
void convert_mesh_3(const TMeshFrom &meshFrom, TMeshTo &meshTo)
TVertexAccessPolicy::index_type VertexIndex
void for_each_neighbors_NV(const TMesh &mesh, TContainer1 &c1, TContainer2 &c2, TFunctor f)
Apply a functor for each pair (vertex, neighbor_of_vertex), given a mesh and two extra containers...
void for_each_neighbors_V(const TMesh &mesh, TContainer &c, TFunctor f)
Apply a functor for each pair (vertex, neighbor_of_vertex), given a mesh and another container...
TVertexAccessPolicy::index_type VertexIndex
TPrec dist2_surface(const TVertex &p, TVertexIndex i, const TVertexCollection &vertices, const TNeighborhood &neighc)
Simple flattening of a point and its neighborhood.
void get_edges_and_faces(TFaceCollection const &faces, std::vector< std::pair< std::size_t, std::size_t > > &res, std::vector< std::vector< std::size_t > > &newfaces)
TData::value_type value_type
TIterator::value_type::Vertex value_type
Mesh policy for vertices indexed with an integer.
void laplacian_smoothing(std::vector< TVertex > &vertices, std::vector< std::vector< std::size_t > > &neighbors, unsigned int nstep, double coeff)
Laplacian smoothing – helper function.
value_type & operator()(index_type i) const
TVertexCollection::value_type Vertex
TImage::value_type max(const TImage &im)
Returns the maximum intensity of the input image.
void computeClusters()
update labels to reflect current clustering.
void process(index_type i)
Computes all the good stuff at the i-th vertex.
void loop_xx(expr::TExpr< Expr > expr, TIterator1 start1, const TIterator1 end1, TIterator2 start2)
prec_type unorientedGaussianCurvature() const
Return unoriented Gaussian curvature at vertex.
const numeric_array< prec_type, 3 > & normal() const
Return computed normal.
void copy(const TImage &in, TImage &out)
Copy one image to another.
std::pair< prec_type, prec_type > principalCurvatures() const
Return computed (signed) principal curvatures at vertex.
void get_n_neighborhood(NeighborCollection const &neigh, NeighborCollectionOut &neigh_n_out, unsigned int n)
Computes the n-neighborhood, i.e. collection of neighbors that are at most n jumps away...
TIterator::value_type::VertexIndexCollection value_type
const TExpr< expr::SecondArgument > _2
Placeholder for the second argument.
TVertexAccessPolicy::value_type Vertex
const TExpr< expr::FirstArgument > _1
Placeholder for the first argument.
void convert_mesh_2(const TMeshFrom &meshFrom, TMeshTo &meshTo)
When indices of from are numbers and two are pointers.
void clusterize_maxDiam(prec_type maxDiam)
Clustering, until max cluster diameter is less than a threshold.
TCircularNeighborIndices::value_type Neighborhood
AimsSurfaceTriangle * makeSphere(const Point3df ¢er, float radius, int iter)
TInputAccessPolicy::value_type Data
Computes the Euclidean distance between two vectors.
shared_ptr< std::vector< std::size_t > > labels()
TIterator::value_type value_type
prec_type unorientedGaussianCurvature() const
Return unoriented Gaussian curvature at vertex.
detail::AddNeighborIndexAttribute< Mesh< TParam > > addNeighborsToMesh(const Mesh< TParam > &mesh)
std::pair< prec_type, prec_type > principalCurvatures() const
Return computed (signed) principal curvatures at vertex.
void allocate_sameSize(const TContainer1 &c1, TContainer2 &c2)
A simple function to allocate a container so that its size matches the size of a second container...
prec_type unorientedMeanCurvature() const
Return unoriented mean curvature at vertex.
void neighboring_faces(std::vector< std::vector< T > > const &cneighs, std::vector< til::numeric_array< T, 3 > > const &faces, std::vector< std::vector< T > > &neighborfaces)
Computes the index of the neighboring faces.
This file contains all the material a library user should need to use template expressions.
Discrete Laplacian smoothing.
const MeshTraits< Mesh_N >::Vertex & getVertexNeighbor(const Mesh_N &mesh, const MeshTraits< Mesh_N >::NeighborIndex::value_type &iNi)
Returns the vertex neighbors of a mesh of type Mesh_N given by its index.
std::pair< prec_type, prec_type > principalCurvatures() const
Return computed (signed) principal curvatures at vertex.
const MeshTraits< AimsSurface< D, T > >::FaceIndexCollection & getFaceIndices(const AimsSurface< D, T > &mesh)
prec_type gaussianCurvature() const
Return computed (signed) Gaussian curvature at vertex.
GonzalezClustering(const TData &data)
void operator()(InputIndex begin, InputIndex end, OutputIndex begin2)
prec_type voronoiArea() const
Return computed voronoi area at vertex.
void neighborhoods2edges(TNeighborhoodCollection const &neigh, std::vector< std::pair< std::size_t, std::size_t > > &edges)
Collects edges from a set of neighbors.
void for_each_neighbors_N(const TMesh &mesh, TContainer &c, TFunctor f)
Apply a functor for each pair (vertex, neighbor_of_vertex), given a mesh and another container...
void neighbors2edges(std::vector< std::vector< T > > const &neighbors, std::vector< std::pair< T, T > > &edges)
Convert a set of neighborhoods into a set of edges.
void operator()(VertexIndex begin, VertexIndex end)
TNeighborhoodAccessPolicy::value_type Neighborhood
precision< Data >::type prec_type
const numeric_array< prec_type, 3 > & normal() const
Return computed normal.
void square(const TImage &in, TImage &out)
void convert_aimsmeshTomesh1(const AimsTimeSurface< 3, Void > &meshFrom, til::Mesh1 &meshTo)
prec_type voronoiArea() const
Return computed voronoi area at vertex.
Mesh_curvature(const TVertexCollection &vertices, const TCircularNeighborIndices &neighs)
TVertexAccessPolicy2::index_type VertexIndex2
This class enhance a mesh class with a neighbor index attribute.
shared_ptr< std::vector< iterator > > quantization()
Returns data quantization, i.e. a subset of the original data of representative of its clusters...
void for_each_neighbors_NN(const TMesh &mesh, TContainer1 &c1, TContainer2 &c2, TFunctor f)
Apply a functor for each pair (vertex, neighbor_of_vertex), given a mesh and two extra containers...
std::pair< index_type, index_type > Edge
void fill(sparse_vector< T, BaselinePolicy > &v, typename boost::call_traits< T >::param_type value)
Specialized fill for sparse_vector.
prec_type gaussianCurvature() const
Return computed (signed) Gaussian curvature at vertex.
void moveClusterSeeds()
Move cluster quantized vector as close to cluster center as possible.
boost::enable_if_c< MeshTraits< TMesh >::has_neighbor_indices >::type getEdgeLengths(const TMesh &mesh, std::vector< std::vector< TPrecision > > &lengths)
Computes edge lengths of a mesh.
TCircularNeighborhoodAccessPolicy::value_type Neighborhood
TOutputAccessPolicy::index_type OutputIndex
TVertexAccessPolicy::index_type VertexIndex
prec_type meanCurvature() const
Return computed (signed) mean curvature at vertex.
TIterator::value_type::VertexIndex index_type
prec_type unorientedMeanCurvature() const
Return unoriented mean curvature at vertex.
Vertex::value_type prec_type
A dummy class used to pass a precision type for computations to some functions.
void process(std::size_t i)
Computes all the good stuff at the i-th vertex.
TCircularNeighborXsr::reference NeighborhoodRef
TVertexAccessPolicy::value_type Vertex
const MeshTraits< AimsSurface< D, T > >::VertexCollection & getVertices(const AimsSurface< D, T > &mesh)
TPrec dist2(const numeric_array< T1, D > &v1, const numeric_array< T2, D > &v2, prec< TPrec >)
Return the squared Euclidean distance between two vectors, computed with a precision given as the fir...
bool is_nan(const numeric_array< T, D > &a)
Check that numeric_array does not contain any NAN TODO: Actually, is_nan should be a functor...