14 #include <boost/foreach.hpp>
40 template<
typename HalfedgeGraph,
42 typename GeometryTraits,
43 typename FaceNormalMap,
50 const PointMap &point_map,
51 const HalfedgeGraph &mesh,
52 const FaceNormalMap &f_nm,
54 const DirType &displacement,
61 bool both_faces_move =
true)
64 boost::graph_traits< HalfedgeGraph >::null_face() ||
66 boost::graph_traits< HalfedgeGraph >::null_face())
69 double init_contrast =
72 cam, point_map, mesh, geom,
halfedge, screen, user, scene);
74 double visibility = 0.0;
96 geom.get_x(v1), geom.get_y(v1), geom.get_z(v1));
98 geom.get_x(v2), geom.get_y(v2), geom.get_z(v2));
100 geom.get_x(v3), geom.get_y(v3), geom.get_z(v3));
102 geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
104 geom.get_x(v3), geom.get_y(v3), geom.get_z(v3));
106 geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
108 n1 = geom.unit_normal(p1 + displacement, p2, p3);
109 n2 = geom.unit_normal(p1 + displacement, p4, p2);
131 geom.get_x(v1), geom.get_y(v1), geom.get_z(v1));
133 geom.get_x(v2), geom.get_y(v2), geom.get_z(v2));
135 geom.get_x(v3), geom.get_y(v3), geom.get_z(v3));
137 geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
139 geom.get_x(v1), geom.get_y(v1), geom.get_z(v1));
141 geom.get_x(v4), geom.get_y(v4), geom.get_z(v4));
143 n1 = geom.unit_normal(p2, p3, p1 + displacement);
144 n2 = geom.unit_normal(p2, p4, p3);
148 cam, _v1 + displacement, _v4, geom, screen, user, scene);
153 init_contrast, std::max(.1, init_frequency)));
154 double T2 = threshold(
159 bool is_ambigous = !(new_contrast < 0.) != !(init_contrast < 0.);
161 double dc = is_ambigous ?
fabs(init_contrast) +
fabs(new_contrast)
162 :
fabs(init_contrast - new_contrast);
173 template<
typename HalfedgeGraph,
175 typename GeometryTraits,
176 typename FaceNormalMap,
183 const PointMap &point_map,
184 const HalfedgeGraph &mesh,
185 const FaceNormalMap &f_nm,
186 const VertexType &vertex,
194 double max_displacement)
196 double tolerence = 0.80;
197 double precision = 0.1;
198 double int_width = 1.e-8;
201 double b = max_displacement;
204 double visibility = 0.0;
212 double visibility_b = 0.0;
213 if(
face(h, mesh) != boost::graph_traits< HalfedgeGraph >::null_face())
219 geom.scalar_mult(dir, T),
227 visibility = std::max(visibility, visibility_b);
228 if(visibility >= 1.0)
231 boost::graph_traits< HalfedgeGraph >::null_face())
237 geom.scalar_mult(dir, T),
245 visibility = std::max(visibility, visibility_b);
246 if(visibility >= 1.0)
252 while(
fabs(visibility - tolerence) > precision)
259 double visibility_b = 0.0;
260 if(
face(h, mesh) != boost::graph_traits< HalfedgeGraph >::null_face())
266 geom.scalar_mult(dir, T),
274 visibility = std::max(visibility, visibility_b);
275 if(visibility >= 1.0)
278 boost::graph_traits< HalfedgeGraph >::null_face())
284 geom.scalar_mult(dir, T),
292 visibility = std::max(visibility, visibility_b);
293 if(visibility >= 1.0)
298 if(visibility > tolerence)
303 if((b - a) < int_width)
329 template<
typename HalfedgeGraph,
331 typename VertexNormalMap,
333 typename FaceNormalMap,
338 const VertexNormalMap &vertex_normal_map,
339 const GeometryTraits &geometry_traits,
340 const FaceNormalMap &face_normal_map,
345 const int nb_light_sources,
346 bool data_output =
false,
347 bool use_random =
true)
349 typedef boost::graph_traits< HalfedgeGraph > GraphTraits;
353 typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor;
355 typedef typename boost::property_traits< VertexNormalMap >::value_type Normal;
370 typename boost::property_traits< PointMap >::value_type minAABB, maxAABB;
371 Filters::compute_mesh_bounding_box< HalfedgeGraph, PointMap, GeometryTraits >(
372 halfedge_graph, point_map, minAABB, maxAABB, geometry_traits);
375 geometry_traits.get_y(minAABB),
376 geometry_traits.get_z(minAABB));
378 geometry_traits.get_y(maxAABB),
379 geometry_traits.get_z(maxAABB));
382 double bbox_diag_len = geometry_traits.
length(maxbb - minbb);
386 geometry_traits.add_v(bbox_c,
392 std::cout <<
"Cam:" << cam << std::endl;
396 Eigen::MatrixX3d lights;
401 int step = mesh_size * nb_light_sources < 120000 ? 10 : 1;
403 clock_t start = clock();
408 if(!data_output && (counter > (avance + step) * (mesh_size / 100)))
412 double estimated_time =
413 static_cast< double >(clock() - start) /
414 (
static_cast< double >(CLOCKS_PER_SEC * 100) / step);
415 std::cout <<
"Estimated time of computation : " << estimated_time
416 <<
" s for " << mesh_size <<
" vertices." << std::endl;
419 std::cout <<
"Progression: " << avance <<
"%\r" << std::flush;
424 Normal n =
get(vertex_normal_map, vi);
426 halfedge_descriptor h0 =
next(
halfedge(vi, halfedge_graph), halfedge_graph);
427 halfedge_descriptor h = h0;
430 typedef typename boost::property_traits< PointMap >::value_type
Point;
435 std::cout <<
"processing vertex #" << counter <<
" : "
436 << geometry_traits.get_x(p) <<
" " << geometry_traits.get_y(p)
437 <<
" " << geometry_traits.get_z(p) << std::endl;
438 std::cout <<
"\tnormal :" << n[0] <<
" " << n[1] <<
" " << n[2]
443 Eigen::Vector3d p_n(n[0], n[1], n[2]);
448 double avg_angle = 0.0;
449 double valence = 0.0;
452 if(
face(h, halfedge_graph) !=
453 boost::graph_traits< HalfedgeGraph >::null_face())
458 avg_angle +=
std::acos(p_n.normalized().dot(f_n.normalized()));
463 avg_angle = avg_angle / valence;
465 (avg_angle != avg_angle)
467 : M_PI_2 - avg_angle;
471 std::cout <<
"\tMean angle: " << avg_angle << std::endl;
483 T.resize(lights.rows());
484 T.setConstant(0.1 * bbox_diag_len);
487 for(
unsigned int i = 0; i < lights.rows(); ++i)
490 lights.row(i)[0], lights.row(i)[1], lights.row(i)[2]);
491 if(geometry_traits.dot_product(light, n) > 0.)
506 0.1 * bbox_diag_len);
509 std::cout <<
"\t" << light <<
" -> " << T(i) << std::endl;
516 std::cout <<
"\tUsed lights :" << count << std::endl;
527 put(jnd_map, vi, jnd);
529 clock_t end = clock();
530 std::cout <<
"Average jnd computing time : "
531 <<
static_cast< double >(end - start) /
532 static_cast< double >(CLOCKS_PER_SEC * counter)
533 <<
" s/vertex" << std::endl;
551 template<
typename HalfedgeGraph,
553 typename VertexNormalMap,
555 typename FaceNormalMap,
560 const VertexNormalMap &v_nm,
561 const FaceNormalMap &f_nm,
566 const int lights = 128,
567 bool data_output =
false,
568 bool use_random =
true)
570 GeometryTraits gt(g);