15 #include <Eigen/Dense>
25 template<
typename HalfedgeGraph,
34 typename boost::graph_traits< HalfedgeGraph >::halfedge_descriptor;
36 typename boost::graph_traits< HalfedgeGraph >::edge_iterator;
38 typename boost::graph_traits< HalfedgeGraph >::edge_descriptor;
40 typename boost::graph_traits< HalfedgeGraph >::face_descriptor;
50 typedef typename std::tuple< Matrix, VectorX, double >
Quadric;
79 auto face_it = face_pair.first;
80 auto face_it_end = face_pair.second;
82 for( ; face_it != face_it_end; ++face_it)
89 auto vertices_it = vertices_pair.first;
90 auto vertices_it_end = vertices_pair.second;
92 for( ; vertices_it != vertices_it_end; ++vertices_it)
100 auto edge_ite = edge_iterator_pair.first;
103 for( ; edge_ite != edge_iterator_pair.second;
114 std::make_tuple(*edge_ite, weight, collapsePos));
116 *edge_ite, std::make_pair(weight, collapsePos));
128 Point dequantized_collapsePos =
135 auto vt = v.transpose();
140 Matrix A1 = std::get< 0 >(Q1);
141 Matrix A2 = std::get< 0 >(Q2);
142 VectorX B1 = std::get< 1 >(Q1);
143 VectorX B2 = std::get< 1 >(Q2);
144 double d1 = std::get< 2 >(Q1);
145 double d2 = std::get< 2 >(Q2);
146 for(
int i = 0; i < 3; i++)
148 for(
int j = 0; j < 3; j++)
150 Q(i, j) = A1(i, j) + A2(i, j);
153 for(
int k = 0; k < 3; k++)
155 Q(3, k) = B1(k) + B2(k);
156 Q(k, 3) = B1(k) + B2(k);
161 double cost = VtQV(0, 0);
178 double area2 = (2*(a2*b2 + b2*c2 + a2*c2) - (a2*a2 + b2*b2 + c2*c2))*0.0625f;
225 v1 << x2 - x1, y2 - y1, z2 - z1;
227 v2 << x3 - x1, y3 - y1, z3 - z1;
229 Eigen::Vector3d cp = v1.cross(v2);
235 cp = Eigen::Vector3d(0, 0, 0);
240 double d = -(a * x1 + b * y1 + c * z1);
241 std::vector< double > plane_eq;
243 plane_eq.push_back(a);
244 plane_eq.push_back(b);
245 plane_eq.push_back(c);
246 plane_eq.push_back(d);
255 Eigen::Vector3d n(plane_eq[0], plane_eq[1], plane_eq[2]);
257 double d = plane_eq[3];
263 for(
size_t i = 0; i < 3; i++)
265 for(
size_t j = 0; j < 3; j++)
267 Af(i, j) = n(i) * n(j);
287 return std::make_tuple(Af, Bf, Cf);
293 boost::iterator_range<
294 CGAL::Halfedge_around_target_iterator< HalfedgeGraph > >
300 M << 0, 0, 0, 0, 0, 0, 0, 0, 0;
303 for(
auto h_v : iterator_range)
307 if(f != boost::graph_traits< HalfedgeGraph >::null_face())
314 M = M + area * std::get< 0 >(it_curr_quadric->second);
315 V = V + area * std::get< 1 >(it_curr_quadric->second);
316 D = D + area * std::get< 2 >(it_curr_quadric->second);
319 if(f == boost::graph_traits< HalfedgeGraph >::null_face() ||
325 if(f == boost::graph_traits< HalfedgeGraph >::null_face())
335 Eigen::Vector3d n(plane_eq_opp[0], plane_eq_opp[1], plane_eq_opp[2]);
353 v1 << x2 - x1, y2 - y1, z2 - z1;
355 v2 << x1 + n(0), y1 + n(1), z1 + n(2);
357 Eigen::Vector3d perpendicular_equation = v1.cross(v2);
359 perpendicular_equation.normalize();
360 if(perpendicular_equation.hasNaN())
362 perpendicular_equation = Eigen::Vector3d(0, 0, 0);
364 double a = perpendicular_equation[0];
365 double b = perpendicular_equation[1];
366 double c = perpendicular_equation[2];
367 double d = -(a * x1 + b * y1 + c * z1);
373 for(
size_t i = 0; i < 3; i++)
375 for(
size_t j = 0; j < 3; j++)
377 Af(i, j) = perpendicular_equation(i) * perpendicular_equation(j);
380 Bf[0] = d * perpendicular_equation(0);
381 Bf[1] = d * perpendicular_equation(1);
382 Bf[2] = d * perpendicular_equation(2);
388 return std::make_tuple(M, V, D);