13 #include <boost/graph/graph_traits.hpp>
14 #include <boost/graph/properties.hpp>
19 #include <CGAL/boost/graph/helpers.h>
20 #include <CGAL/boost/graph/internal/helpers.h>
21 #include <CGAL/boost/graph/Euler_operations.h>
40 for(
int row = 0; row < (*cimg).height(); row++)
42 for(
int col = 0; col < (*cimg).width(); col++)
45 (*cimg)(col, row, 0, 0) = col;
46 (*cimg)(col, row, 0, 1) = row;
47 (*cimg)(col, row, 0, 2) = 0;
53 const unsigned char gray[] = { 128, 128, 128 };
56 (*cimg).draw_text(20, 128-(size1/2),
"NO TEX", gray, 0, 1.0, size1);
59 (*cimg).draw_text( 2, 0,
"(0;0)", gray, 0, 1.0, size2);
60 (*cimg).draw_text(255-50, 0,
"(1;0)", gray, 0, 1.0, size2);
61 (*cimg).draw_text( 2, 255-size2,
"(0;1)", gray, 0, 1.0, size2);
62 (*cimg).draw_text(255-50, 255-size2,
"(1;1)", gray, 0, 1.0, size2);
70 template<
typename BoostGraph >
78 template<
typename FaceGraph >
80 typename boost::graph_traits< FaceGraph >::face_descriptor >;
90 template<
typename FaceGraph >
97 bool _use_corner_texcoord)
134 template<
typename HalfedgeGraph,
135 typename coordP_type,
136 typename coordN_type,
137 typename coordT_type,
138 typename coordC_type,
140 typename GeometryTraits >
145 unsigned int &dup_v_nbr,
152 const GeometryTraits &)
154 typedef boost::graph_traits< HalfedgeGraph > GraphTraits;
157 typedef typename GraphTraits::face_descriptor face_descriptor;
158 typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor;
167 if(mvr.vertex_color_coords.size() != mvr.points_coords.size())
168 mvr.vertex_color_coords.clear();
169 for(
auto &color : mvr.vertex_color_coords)
171 if(color.size() != 3)
173 std::cout << __func__
174 <<
"(): found vertex color with size != 3. Disabling "
175 "vertex color for all vertices."
177 mvr.vertex_color_coords.clear();
183 if(mvr.face_color_coords.size() != mvr.faces_indices.size())
184 mvr.face_color_coords.clear();
185 for(
auto &color : mvr.face_color_coords)
187 if(color.size() != 3)
189 std::cout << __func__
190 <<
"(): found face color with size != 3. Disabling "
191 "face color for all vertices."
193 mvr.face_color_coords.clear();
199 bool is_vertex_color_0_255 =
false;
200 if(! mvr.vertex_color_coords.empty())
202 for(
auto &color : mvr.vertex_color_coords)
204 if(color[0] > 1 || color[1] > 1 || color[2] > 1)
206 is_vertex_color_0_255 =
true;
207 std::cout << __func__
208 <<
"(): vertex color will be converted from [0,255] "
217 bool is_face_color_0_255 =
false;
218 if(! mvr.face_color_coords.empty())
220 for(
auto &color : mvr.face_color_coords)
222 if(color[0] > 1 || color[1] > 1 || color[2] > 1)
224 is_face_color_0_255 =
true;
225 std::cout << __func__
226 <<
"(): face color will be converted from [0,255] "
235 if(! mvr.face_material.empty())
237 if(mvr.face_material.size() != mvr.faces_indices.size())
239 std::cout << __func__
240 <<
"(): found some faces with a material and some "
241 "without. Disabling material for all faces."
243 mvr.face_material.clear();
248 if(! mvr.face_material.empty())
250 for(
auto &mtl_id : mvr.face_material)
252 if(mtl_id ==
static_cast< index_type
>(-1))
254 std::cout << __func__
255 <<
"(): found some faces with an invalid material. "
256 "Disabling material for all faces."
258 mvr.face_material.clear();
265 if(! mvr.materials.empty())
268 for(
size_t i = 0; i < mvr.materials.size(); i++)
270 auto &material = mvr.materials[i];
272 for(
const auto &texture_filename : { material.ambient_texture_filename,
273 material.diffuse_texture_filename,
274 material.specular_texture_filename,
275 material.emissive_texture_filename,
276 material.transparency_texture_filename,
277 material.normal_map_filename,
278 material.metallic_map_filename,
279 material.roughness_map_filename })
281 if(texture_filename.empty())
286 material.images[texture_filename] =
287 std::shared_ptr< FEVV::Types::Image >(
290 catch(
const cimg_library::CImgIOException &)
292 material.images[texture_filename] =
293 std::shared_ptr< FEVV::Types::Image >(
304 for(
size_t i = 0; i < mvr.materials.size(); i++)
305 put(mtl_pm, i, mvr.materials[i]);
310 std::cout << __func__
311 <<
"(): property map for materials created."
317 bool use_vertex_normal =
false;
318 bool use_vertex_color =
false;
319 bool use_vertex_texture_coord =
false;
320 bool use_face_color =
false;
321 bool use_face_material =
false;
322 bool use_face_normal =
false;
326 if(! mvr.texture_coords.empty())
329 if(use_corner_texture_coord)
334 else if(mvr.texture_coords.size() == mvr.points_coords.size())
337 use_vertex_texture_coord =
true;
339 else if(mvr.texture_face_indices.size() == mvr.faces_indices.size())
342 use_corner_texture_coord =
true;
346 if(use_vertex_texture_coord)
352 std::cout << __func__
353 <<
"(): property map for vertex-texture-coordinate created."
356 else if(use_corner_texture_coord)
362 std::cout << __func__
363 <<
"(): property map for halfedge-texture-coordinate "
371 use_corner_texture_coord =
false;
375 if(! mvr.normals_coords.empty())
380 if(mvr.normals_coords.size() == mvr.points_coords.size())
382 use_vertex_normal =
true;
388 std::cout << __func__
389 <<
"(): property map for vertex-normal created."
392 else if(! mvr.normal_face_indices[0].empty())
395 use_face_normal =
true;
401 std::cout << __func__
402 <<
"(): property map for face-normal created."
407 if(! mvr.vertex_color_coords.empty())
409 use_vertex_color =
true;
415 std::cout << __func__
416 <<
"(): property map for vertex-color created."
420 if(! mvr.face_color_coords.empty())
422 use_face_color =
true;
428 std::cout << __func__
429 <<
"(): property map for face-color created."
433 if(! mvr.face_material.empty())
435 use_face_material =
true;
441 std::cout << __func__
442 <<
"(): property map for face-material created."
453 std::vector< vertex_descriptor >
vertices;
454 vertices.reserve(mvr.points_coords.size());
456 typedef typename std::vector< std::vector< coordP_type > >::const_iterator
458 auto point_pm =
get(boost::vertex_point, g);
461 for(point_it it_p = mvr.points_coords.begin();
462 it_p != mvr.points_coords.end();
468 put(point_pm, current_vertex,
Point((*it_p)[0], (*it_p)[1], (*it_p)[2]));
475 if(use_vertex_normal || use_vertex_color || use_vertex_texture_coord)
477 if(use_vertex_normal)
481 std::vector< coordN_type > &coords = mvr.normals_coords[vertex_nbr - 1];
483 if(coords.size() != 3)
484 throw std::runtime_error(
"Support of normal coordinates of size != 3 "
485 "not yet implemented!");
487 Vector vn(coords[0], coords[1], coords[2]);
489 put(vn_pm, current_vertex, vn);
495 std::vector< coordC_type > &coords =
496 mvr.vertex_color_coords[vertex_nbr - 1];
501 if(is_vertex_color_0_255)
506 rgb[0] = (int)floor(coords[0] + 0.5);
507 rgb[1] = (int)floor(coords[1] + 0.5);
508 rgb[2] = (int)floor(coords[2] + 0.5);
509 coords[0] = (coordC_type)((
float)rgb[0] / 255.0);
510 coords[1] = (coordC_type)((
float)rgb[1] / 255.0);
511 coords[2] = (coordC_type)((
float)rgb[2] / 255.0);
515 Vector vc(coords[0], coords[1], coords[2]);
517 put(vc_pm, current_vertex, vc);
519 if(use_vertex_texture_coord)
523 std::vector< coordT_type > &coords = mvr.texture_coords[vertex_nbr - 1];
525 if(coords.size() != 2)
526 throw std::runtime_error(
"Support of texture coordinates of size != "
527 "2 not yet implemented!");
530 Vector tex_coords(coords[0], coords[1], 0);
532 put(vt_pm, current_vertex, tex_coords);
547 typedef typename std::vector< std::vector< index_type > >::const_iterator
549 typedef typename std::vector< index_type >::const_iterator index_it;
552 for(face_it it_f = mvr.faces_indices.begin();
553 it_f != mvr.faces_indices.end();
558 throw std::runtime_error(std::string(__func__) +
559 "(): find a face with less than two "
560 "vertices : not conform.");
562 else if(it_f->size() == 2)
564 throw std::runtime_error(std::string(__func__) +
565 "(): found a face with two vertices, "
566 "isolated edge not supported.");
572 std::vector< vertex_descriptor > face_vertices;
575 for(index_it it = it_f->begin(); it != it_f->end(); ++it)
578 face_vertices.push_back(
vertices[(*it)]);
590 if(current_face == GraphTraits::null_face())
593 auto duplicate_v = [ &face_vertices,
599 &use_vertex_texture_coord ](
size_t i) ->
void
605 face_vertices[i] = vnew;
609 auto point_pm =
get(boost::vertex_point, g);
610 put(point_pm, vnew,
get(point_pm, vold));
613 if(use_vertex_normal)
619 put(vn_pm, vnew, normal);
627 put(vc_pm, vnew, color);
629 if(use_vertex_texture_coord)
635 put(vt_pm, vnew, coord);
652 bool face_vertex_duplicated =
false;
653 size_t n = face_vertices.size();
654 for(
size_t i = 0, ii = 1; i < n; ++i, ++ii, ii %= n)
658 std::pair< halfedge_descriptor, bool > he =
659 halfedge(face_vertices[i], face_vertices[ii], g);
661 if((! CGAL::internal::is_isolated(face_vertices[i], g) &&
662 ! CGAL::is_border(face_vertices[i], g)) ||
663 (he.second && ! CGAL::is_border(he.first, g)))
674 face_vertex_duplicated =
true;
680 if(! face_vertex_duplicated)
686 for(
size_t i = 0; i < n; ++i)
695 if(current_face == GraphTraits::null_face())
698 std::cout <<
"Warning: failed to create one face." << std::endl;
711 for(index_type face_vertex_id = 0;
712 face_vertex_id < face_vertices.size();
715 current_vertex = face_vertices[face_vertex_id];
718 if(use_corner_texture_coord)
725 if(! mvr.texture_face_indices[face_id].empty())
727 index_type texture_id =
728 mvr.texture_face_indices[face_id][face_vertex_id];
729 std::vector< coordT_type > &coords = mvr.texture_coords[texture_id];
730 if(coords.size() != 2)
731 throw std::runtime_error(std::string(__func__) +
732 "(): texture coordinates of "
733 "size != 2 not yet supported!");
734 texcoords =
Vector(coords[0], coords[1], 0);
737 texcoords =
Vector(0, 0, 0);
745 halfedge_descriptor h =
halfedge(current_face, g);
747 !(
source(h, g) == prev_vertex &&
target(h, g) == current_vertex))
753 put(htexcoord_pm, h, texcoords);
771 index_type normal_id =
772 mvr.normal_face_indices[face_id][face_vertex_id];
773 std::vector< coordN_type > &normal = mvr.normals_coords[normal_id];
774 if(normal.size() != 3)
775 throw std::runtime_error(std::string(__func__) +
776 "(): normals of size != 3 not yet "
778 Vector vnormal =
Vector(normal[0], normal[1], normal[2]);
782 Vector fnormal =
get(fn_pm, current_face);
785 fnormal = fnormal + vnormal;
786 if(face_vertex_id == face_vertices.size() - 1)
788 fnormal / (
static_cast< unsigned long >(face_vertex_id) + 1);
791 put(fn_pm, current_face, fnormal);
794 prev_vertex = current_vertex;
800 std::vector< coordC_type > &color = mvr.face_color_coords[face_id];
805 if(is_face_color_0_255)
810 rgb[0] = (int)floor(color[0] + 0.5);
811 rgb[1] = (int)floor(color[1] + 0.5);
812 rgb[2] = (int)floor(color[2] + 0.5);
813 color[0] = (coordC_type)((
float)rgb[0] / 255.0);
814 color[1] = (coordC_type)((
float)rgb[1] / 255.0);
815 color[2] = (coordC_type)((
float)rgb[2] / 255.0);
819 Vector fc(color[0], color[1], color[2]);
821 put(fc_pm, current_face, fc);
825 if(use_face_material)
827 size_t mtl_id = mvr.face_material[face_id];
831 put(fm_pm, current_face, mtl_id);
855 template<
typename HalfedgeGraph,
856 typename coordP_type,
857 typename coordN_type,
858 typename coordT_type,
859 typename coordC_type,
864 const HalfedgeGraph &g,
866 unsigned int &dup_v_nbr,
875 GeometryTraits gt(g);