19 #if defined(__APPLE__) && defined(__clang__)
21 #define VTK_LEGACY_SILENT
24 #pragma clang diagnostic push
25 #pragma clang diagnostic ignored "-Winconsistent-missing-override"
27 #include <vtkSmartPointer.h>
28 #include <vtkPointData.h>
29 #include <vtkCellData.h>
30 #include <vtkCellArray.h>
31 #include <vtkPolyData.h>
32 #include <vtkUnstructuredGrid.h>
33 #include <vtkDoubleArray.h>
34 #include <vtkFieldData.h>
36 #include <vtkPolyDataWriter.h>
37 #include <vtkXMLPolyDataWriter.h>
38 #include <vtkUnstructuredGridWriter.h>
39 #include <vtkXMLUnstructuredGridWriter.h>
40 #if defined(__APPLE__) && defined(__clang__)
41 #pragma clang diagnostic pop
46 template<
typename CoordType,
52 const std::vector< std::vector< CoordType > > &points_coords,
53 const std::vector< std::vector< CoordNType > > &normals_coords,
54 const std::vector< std::vector< CoordCType > > &vertex_color_coords,
55 const std::vector< std::vector< IndexType > >
57 const std::vector< std::vector< CoordCType > > &lines_color_coords,
59 const std::vector< std::vector< IndexType > >
61 const std::vector< std::vector< CoordCType > > &face_color_coords,
62 const std::vector< std::vector< std::vector< double > > >
64 const std::vector< std::string > &field_names,
65 vtkSmartPointer< vtkPolyData > &poly_data)
68 size_t nb_points = points_coords.size(), nb_normals = normals_coords.size(),
69 nb_point_colors = vertex_color_coords.size(),
70 nb_lines = line_indices.size(),
71 nb_line_colors = lines_color_coords.size(),
72 nb_faces = face_indices.size(),
73 nb_face_colors = face_color_coords.size(),
74 nb_arrays_in_field = field_attributes.size();
75 bool has_one_name_for_each_field = (nb_arrays_in_field == field_names.size());
78 assert((nb_normals == 0u) || (nb_points == nb_normals));
80 poly_data = vtkSmartPointer< vtkPolyData >::New();
84 vtkSmartPointer< vtkPoints > ptr_points = vtkSmartPointer< vtkPoints >::New();
85 for(
size_t i = 0; i < nb_points;
91 ptr_points->InsertNextPoint(
92 points_coords[i][0], points_coords[i][1], points_coords[i][2]);
95 poly_data->SetPoints(ptr_points);
100 if((nb_normals > 0u) &&
105 vtkSmartPointer< vtkDoubleArray > ptr_normals =
106 vtkSmartPointer< vtkDoubleArray >::New();
107 ptr_normals->SetName(
"vertex_normals");
109 ptr_normals->SetNumberOfComponents(3);
110 ptr_normals->SetNumberOfTuples(poly_data->GetNumberOfPoints());
112 for(
size_t i = 0; i < nb_normals; ++i)
114 ptr_normals->SetTuple3(
115 i, normals_coords[i][0], normals_coords[i][1], normals_coords[i][2]);
121 poly_data->GetPointData()->SetNormals(ptr_normals);
125 assert(poly_data->GetNumberOfPoints() ==
126 poly_data->GetPointData()->GetNormals()->GetNumberOfTuples());
131 if((nb_point_colors > 0u) && (vertex_color_coords[0].size() > 2u) &&
132 (nb_points == nb_point_colors))
134 vtkSmartPointer< vtkDoubleArray > ptr_colors =
135 vtkSmartPointer< vtkDoubleArray >::New();
136 ptr_colors->SetName(
"vertex_colors");
137 ptr_colors->SetNumberOfComponents(
138 static_cast< int >(vertex_color_coords[0].size()));
139 ptr_colors->SetNumberOfTuples(nb_point_colors);
141 for(
size_t i = 0; i < nb_point_colors; ++i)
143 if(vertex_color_coords[0].size() == 3)
144 ptr_colors->SetTuple3(i,
145 vertex_color_coords[i][0],
146 vertex_color_coords[i][1],
147 vertex_color_coords[i][2]);
149 ptr_colors->SetTuple4(i,
150 vertex_color_coords[i][0],
151 vertex_color_coords[i][1],
152 vertex_color_coords[i][2],
153 vertex_color_coords[i][3]);
156 poly_data->GetPointData()->AddArray(ptr_colors);
162 vtkSmartPointer< vtkCellArray > polys =
163 vtkSmartPointer< vtkCellArray >::New();
164 for(
size_t i = 0; i < nb_faces; ++i)
166 vtkIdType *pt_indices =
new vtkIdType[face_indices[i].size()];
167 typename std::vector< IndexType >::const_iterator it_begin(
168 face_indices[i].begin()),
169 it_end(face_indices[i].end());
170 unsigned long cpt = 0;
171 while(it_begin != it_end)
173 pt_indices[cpt++] =
static_cast< vtkIdType
>(*it_begin);
177 polys->InsertNextCell(
static_cast< int >(face_indices[i].size()),
182 poly_data->SetPolys(polys);
186 if((nb_face_colors > 0u) && (face_color_coords[0].size() > 2u) &&
187 (nb_faces == nb_face_colors))
189 vtkSmartPointer< vtkDoubleArray > ptr_colors =
190 vtkSmartPointer< vtkDoubleArray >::New();
191 ptr_colors->SetName(
"face_colors");
192 ptr_colors->SetNumberOfComponents(
193 static_cast< int >(face_color_coords[0].size()));
194 ptr_colors->SetNumberOfTuples(nb_face_colors);
196 for(
size_t i = 0; i < nb_face_colors; ++i)
198 if(face_color_coords[0].size() == 3)
199 ptr_colors->SetTuple3(i,
200 face_color_coords[i][0],
201 face_color_coords[i][1],
202 face_color_coords[i][2]);
204 ptr_colors->SetTuple4(i,
205 face_color_coords[i][0],
206 face_color_coords[i][1],
207 face_color_coords[i][2],
208 face_color_coords[i][3]);
211 poly_data->GetCellData()->AddArray(ptr_colors);
213 poly_data->GetFieldData()->AddArray(ptr_colors);
218 vtkSmartPointer< vtkCellArray > lines_of_volume_cell =
219 vtkSmartPointer< vtkCellArray >::New();
220 for(
size_t i = 0; i < nb_lines; ++i)
222 vtkIdType *pt_indices =
new vtkIdType[line_indices[i].size()];
223 typename std::vector< IndexType >::const_iterator it_begin(
224 line_indices[i].begin()),
225 it_end(line_indices[i].end());
226 unsigned long cpt = 0;
227 while(it_begin != it_end)
229 pt_indices[cpt++] =
static_cast< vtkIdType
>(*it_begin);
233 lines_of_volume_cell->InsertNextCell(
234 static_cast< int >(line_indices[i].size()), pt_indices);
238 poly_data->SetLines(lines_of_volume_cell);
241 if((nb_line_colors > 0u) && (lines_color_coords[0].size() > 2u) &&
242 (nb_lines == nb_line_colors))
244 vtkSmartPointer< vtkDoubleArray > ptr_colors =
245 vtkSmartPointer< vtkDoubleArray >::New();
246 if(line_indices[0].size() > 2)
247 ptr_colors->SetName(
"cell_colors");
249 ptr_colors->SetName(
"edge_colors");
251 ptr_colors->SetNumberOfComponents(
252 static_cast< int >(lines_color_coords[0].size()));
253 ptr_colors->SetNumberOfTuples(nb_line_colors);
255 for(
size_t i = 0; i < nb_line_colors; ++i)
257 if(lines_color_coords[0].size() == 3)
258 ptr_colors->SetTuple3(i,
259 lines_color_coords[i][0],
260 lines_color_coords[i][1],
261 lines_color_coords[i][2]);
263 ptr_colors->SetTuple4(i,
264 lines_color_coords[i][0],
265 lines_color_coords[i][1],
266 lines_color_coords[i][2],
267 lines_color_coords[i][3]);
270 poly_data->GetCellData()->AddArray(ptr_colors);
272 poly_data->GetFieldData()->AddArray(ptr_colors);
277 if(nb_arrays_in_field > 0u)
281 for(
size_t id_array = 0; id_array < nb_arrays_in_field; id_array++)
285 vtkSmartPointer< vtkDoubleArray > ptr_data =
286 vtkSmartPointer< vtkDoubleArray >::New();
287 if(has_one_name_for_each_field)
289 if(field_names[id_array].find(
"POINT_DATA_") != std::string::npos)
291 ptr_data->SetName((field_names[id_array].substr(11)).c_str());
294 else if(field_names[id_array].find(
"CELL_DATA_") != std::string::npos)
296 ptr_data->SetName((field_names[id_array].substr(10)).c_str());
299 else if(field_names[id_array].find(
"ELEMENT_DATA_") != std::string::npos)
301 ptr_data->SetName((field_names[id_array].substr(13)).c_str());
306 ptr_data->SetName(field_names[id_array].c_str());
317 ptr_data->SetNumberOfComponents(
318 ((field_attributes[id_array].size() > 0u)
319 ?
static_cast< int >(field_attributes[id_array][0].size())
321 ptr_data->SetNumberOfTuples(field_attributes[id_array].size());
326 for(vtkIdType i = 0; i < ptr_data->GetNumberOfTuples();
329 assert(i <
static_cast< vtkIdType
>(field_attributes[id_array].size()));
330 for(vtkIdType j = 0; j < ptr_data->GetNumberOfComponents();
334 static_cast< vtkIdType
>(field_attributes[id_array][i].size())) ||
335 (ptr_data->GetNumberOfComponents() !=
336 static_cast< vtkIdType
>(field_attributes[id_array][i].size())))
338 std::cerr <<
" Trying to access index " << j <<
" but only "
339 << field_attributes[id_array][i].size()
340 <<
" components in the data field." << std::endl;
341 std::cerr <<
" We should find " << ptr_data->GetNumberOfComponents()
342 <<
" components in the provided data field. "
352 ptr_data->SetComponent(i, j, field_attributes[id_array][i][j]);
359 poly_data->GetPointData()->AddArray(ptr_data);
362 poly_data->GetCellData()->AddArray(ptr_data);
365 poly_data->GetFieldData()->AddArray(ptr_data);
371 template<
typename CoordType,
377 const std::vector< std::vector< CoordType > > &points_coords,
378 const std::vector< std::vector< CoordNType > > &normals_coords,
379 const std::vector< std::vector< CoordCType > > &vertex_color_coords,
380 const std::vector< std::vector< IndexType > >
382 const std::vector< std::vector< CoordCType > > &lines_color_coords,
384 const std::vector< std::vector< IndexType > >
386 const std::vector< std::vector< CoordCType > > &face_color_coords,
387 const std::vector< std::vector< std::vector< double > > >
389 const std::vector< std::string > &field_names,
390 vtkSmartPointer< vtkUnstructuredGrid > &unstructured_grid)
393 size_t nb_points = points_coords.size(), nb_normals = normals_coords.size(),
394 nb_point_colors = vertex_color_coords.size(),
395 nb_lines = line_indices.size(),
396 nb_line_colors = lines_color_coords.size(),
397 nb_faces = face_indices.size(),
398 nb_face_colors = face_color_coords.size(),
399 nb_arrays_in_field = field_attributes.size();
400 bool has_one_name_for_each_field = (nb_arrays_in_field == field_names.size());
403 assert((nb_normals == 0u) || (nb_points == nb_normals));
405 unstructured_grid = vtkSmartPointer< vtkUnstructuredGrid >::New();
409 vtkSmartPointer< vtkPoints > ptr_points = vtkSmartPointer< vtkPoints >::New();
410 for(
size_t i = 0; i < nb_points;
416 ptr_points->InsertNextPoint(
417 points_coords[i][0], points_coords[i][1], points_coords[i][2]);
419 unstructured_grid->SetPoints(ptr_points);
424 if((nb_normals > 0u) &&
429 vtkSmartPointer< vtkDoubleArray > ptr_normals =
430 vtkSmartPointer< vtkDoubleArray >::New();
431 ptr_normals->SetName(
"vertex_normals");
433 ptr_normals->SetNumberOfComponents(3);
434 ptr_normals->SetNumberOfTuples(unstructured_grid->GetNumberOfPoints());
436 for(
size_t i = 0; i < nb_normals; ++i)
438 ptr_normals->SetTuple3(
439 i, normals_coords[i][0], normals_coords[i][1], normals_coords[i][2]);
445 unstructured_grid->GetPointData()->SetNormals(ptr_normals);
450 unstructured_grid->GetNumberOfPoints() ==
451 unstructured_grid->GetPointData()->GetNormals()->GetNumberOfTuples());
456 if((nb_point_colors > 0u) && (vertex_color_coords[0].size() > 2u) &&
457 (nb_points == nb_point_colors))
459 vtkSmartPointer< vtkDoubleArray > ptr_colors =
460 vtkSmartPointer< vtkDoubleArray >::New();
461 ptr_colors->SetName(
"vertex_colors");
462 ptr_colors->SetNumberOfComponents(
463 static_cast< int >(vertex_color_coords[0].size()));
464 ptr_colors->SetNumberOfTuples(nb_point_colors);
466 for(
size_t i = 0; i < nb_point_colors; ++i)
468 if(vertex_color_coords[0].size() == 3)
469 ptr_colors->SetTuple3(i,
470 vertex_color_coords[i][0],
471 vertex_color_coords[i][1],
472 vertex_color_coords[i][2]);
474 ptr_colors->SetTuple4(i,
475 vertex_color_coords[i][0],
476 vertex_color_coords[i][1],
477 vertex_color_coords[i][2],
478 vertex_color_coords[i][3]);
481 unstructured_grid->GetPointData()->AddArray(ptr_colors);
487 int *type_array = NULL;
488 if(nb_faces > 0 || nb_lines > 0)
489 type_array =
new(std::nothrow)
int[nb_faces + nb_lines];
490 vtkSmartPointer< vtkCellArray > cells =
491 vtkSmartPointer< vtkCellArray >::New();
492 for(
size_t i = 0; i < nb_faces; ++i)
494 vtkIdType *pt_indices =
new vtkIdType[face_indices[i].size()];
495 typename std::vector< IndexType >::const_iterator it_begin(
496 face_indices[i].begin()),
497 it_end(face_indices[i].end());
498 unsigned long cpt = 0;
499 while(it_begin != it_end)
501 pt_indices[cpt++] =
static_cast< vtkIdType
>(*it_begin);
505 cells->InsertNextCell(
static_cast< int >(face_indices[i].size()),
508 switch(face_indices[i].size())
513 throw std::runtime_error(
514 "Writer::load_vtkUnstructuredGrid: a face seems to be not valid.");
516 type_array[i] = VTK_TRIANGLE;
519 type_array[i] = VTK_QUAD;
522 type_array[i] = VTK_POLYGON;
528 if((nb_face_colors > 0u) && (face_color_coords[0].size() > 2u) &&
529 (nb_faces == nb_face_colors))
531 vtkSmartPointer< vtkDoubleArray > ptr_colors =
532 vtkSmartPointer< vtkDoubleArray >::New();
533 ptr_colors->SetName(
"face_colors");
534 ptr_colors->SetNumberOfComponents(
535 static_cast< int >(face_color_coords[0].size()));
536 ptr_colors->SetNumberOfTuples(nb_face_colors);
538 for(
size_t i = 0; i < nb_face_colors; ++i)
540 if(face_color_coords[0].size() == 3)
541 ptr_colors->SetTuple3(i,
542 face_color_coords[i][0],
543 face_color_coords[i][1],
544 face_color_coords[i][2]);
546 ptr_colors->SetTuple4(i,
547 face_color_coords[i][0],
548 face_color_coords[i][1],
549 face_color_coords[i][2],
550 face_color_coords[i][3]);
553 unstructured_grid->GetCellData()->AddArray(ptr_colors);
555 unstructured_grid->GetFieldData()->AddArray(ptr_colors);
559 for(
size_t i = 0; i < nb_lines; ++i)
561 vtkIdType *pt_indices =
new vtkIdType[line_indices[i].size()];
562 typename std::vector< IndexType >::const_iterator it_begin(
563 line_indices[i].begin()),
564 it_end(line_indices[i].end());
565 unsigned long cpt = 0;
566 while(it_begin != it_end)
568 pt_indices[cpt++] =
static_cast< vtkIdType
>(*it_begin);
572 cells->InsertNextCell(
static_cast< int >(line_indices[i].size()),
577 type_array[nb_faces + i] = VTK_TETRA;
580 type_array[nb_faces + i] = VTK_HEXAHEDRON;
583 throw std::runtime_error(
584 "Writer::load_vtkUnstructuredGrid: a face seems to be not valid.");
589 unstructured_grid->SetCells(type_array, cells);
590 if(type_array != NULL)
595 if((nb_line_colors > 0u) && (lines_color_coords[0].size() > 2u) &&
596 (nb_lines == nb_line_colors))
598 vtkSmartPointer< vtkDoubleArray > ptr_colors =
599 vtkSmartPointer< vtkDoubleArray >::New();
600 ptr_colors->SetName(
"cell_colors");
602 ptr_colors->SetNumberOfComponents(
603 static_cast< int >(lines_color_coords[0].size()));
604 ptr_colors->SetNumberOfTuples(nb_line_colors);
606 for(
size_t i = 0; i < nb_line_colors; ++i)
608 if(lines_color_coords[0].size() == 3)
609 ptr_colors->SetTuple3(i,
610 lines_color_coords[i][0],
611 lines_color_coords[i][1],
612 lines_color_coords[i][2]);
614 ptr_colors->SetTuple4(i,
615 lines_color_coords[i][0],
616 lines_color_coords[i][1],
617 lines_color_coords[i][2],
618 lines_color_coords[i][3]);
620 unstructured_grid->GetCellData()->AddArray(ptr_colors);
626 if(nb_arrays_in_field > 0u)
630 for(
size_t id_array = 0; id_array < nb_arrays_in_field; id_array++)
633 vtkSmartPointer< vtkDoubleArray > ptr_data =
634 vtkSmartPointer< vtkDoubleArray >::New();
635 if(has_one_name_for_each_field)
637 if(field_names[id_array].find(
"POINT_DATA_") != std::string::npos)
639 ptr_data->SetName((field_names[id_array].substr(11)).c_str());
642 else if(field_names[id_array].find(
"CELL_DATA_") != std::string::npos)
644 ptr_data->SetName((field_names[id_array].substr(10)).c_str());
647 else if(field_names[id_array].find(
"ELEMENT_DATA_") != std::string::npos)
649 ptr_data->SetName((field_names[id_array].substr(13)).c_str());
654 ptr_data->SetName(field_names[id_array].c_str());
665 ptr_data->SetNumberOfComponents(
666 ((field_attributes[id_array].size() > 0u)
667 ?
static_cast< int >(field_attributes[id_array][0].size())
669 ptr_data->SetNumberOfTuples(field_attributes[id_array].size());
674 for(vtkIdType i = 0; i < ptr_data->GetNumberOfTuples();
677 assert(i <
static_cast< vtkIdType
>(field_attributes[id_array].size()));
678 for(vtkIdType j = 0; j < ptr_data->GetNumberOfComponents();
682 static_cast< vtkIdType
>(field_attributes[id_array][i].size())) ||
683 (ptr_data->GetNumberOfComponents() !=
684 static_cast< vtkIdType
>(field_attributes[id_array][i].size())))
686 std::cout <<
" Trying to access index " << j <<
" but only "
687 << field_attributes[id_array][i].size()
688 <<
" components in the data field." << std::endl;
689 std::cout <<
" We should find " << ptr_data->GetNumberOfComponents()
690 <<
" components in the provided data field. "
700 ptr_data->SetComponent(i, j, field_attributes[id_array][i][j]);
707 unstructured_grid->GetPointData()->AddArray(ptr_data);
710 unstructured_grid->GetCellData()->AddArray(ptr_data);
716 unstructured_grid->GetFieldData()->AddArray(ptr_data);
722 template<
typename CoordType,
728 std::string file_path,
729 const std::vector< std::vector< CoordType > > &points_coords,
730 const std::vector< std::vector< CoordNType > > &normals_coords,
731 const std::vector< std::vector< CoordCType > > &vertex_color_coords,
732 const std::vector< std::vector< IndexType > >
734 const std::vector< std::vector< CoordCType > > &lines_color_coords,
736 const std::vector< std::vector< IndexType > >
738 const std::vector< std::vector< CoordCType > > &face_color_coords,
739 const std::vector< std::vector< std::vector< double > > >
741 const std::vector< std::string > &field_names)
743 bool is_a_poly_data =
744 ((line_indices.size() == 0) ||
745 ((line_indices.size() > 0) && (face_indices.size() == 0) &&
752 vtkSmartPointer< vtkPolyData > poly_data;
753 vtkSmartPointer< vtkUnstructuredGrid > unstructured_grid;
755 std::vector<std::string> names;
756 if (field_names.size() != field_attributes.size())
758 names.resize(field_attributes.size());
762 for (
unsigned long i(0); i<field_attributes.size(); ++i){
763 if( (points_coords.size() == field_attributes[i].size()) &&
764 ((points_coords.size() != face_indices.size()) || (field_attributes[i][0].size()>1)))
765 names[i] = std::string(
"Shifting_") +
convert(i);
767 names[i] = std::string(
"cell_law_")+
convert(i);
789 std::vector< std::vector< IndexType > > new_facets;
790 std::vector< std::vector< CoordCType > > new_facets_c;
808 vtkSmartPointer< vtkXMLPolyDataWriter > writer =
809 vtkSmartPointer< vtkXMLPolyDataWriter >::New();
810 writer->SetFileName(file_path.c_str());
811 #if VTK_MAJOR_VERSION <= 5
812 writer->SetInput(poly_data);
816 writer->SetInputData(poly_data);
823 throw std::runtime_error(
"Writer::write_vtk_or_vtp_or_vtu_file -> file "
824 "extension .vtp is reserved for PolyData.");
833 vtkSmartPointer< vtkPolyDataWriter > writer =
834 vtkSmartPointer< vtkPolyDataWriter >::New();
835 writer->SetFileName(file_path.c_str());
837 if(face_indices.size() > 0)
839 "vtk file: 2D data (surface mesh) generated by MEPP software "
840 "available at https://github.com/MEPP-team/MEPP2");
843 if(line_indices.size() == 0)
845 "vtk file: 1D data (point cloud) generated by MEPP software "
846 "available at https://github.com/MEPP-team/MEPP2");
849 if(line_indices[0].size() == 2)
851 "vtk file: 1D data (polyline(s)) generated by MEPP software "
852 "available at https://github.com/MEPP-team/MEPP2");
855 "vtk file: 3D data (volume cells) generated by MEPP software "
856 "available at https://github.com/MEPP-team/MEPP2");
860 #if VTK_MAJOR_VERSION <= 5
861 writer->SetInput(poly_data);
865 writer->SetInputData(poly_data);
872 vtkSmartPointer< vtkUnstructuredGridWriter > writer =
873 vtkSmartPointer< vtkUnstructuredGridWriter >::New();
874 writer->SetFileName(file_path.c_str());
875 writer->SetHeader(
"vtk file: 3D data (volume mesh) generated by MEPP "
876 "software available at https://github.com/MEPP-team/MEPP2");
878 #if VTK_MAJOR_VERSION <= 5
879 writer->SetInput(unstructured_grid);
883 writer->SetInputData(unstructured_grid);
893 vtkSmartPointer< vtkXMLUnstructuredGridWriter > writer =
894 vtkSmartPointer< vtkXMLUnstructuredGridWriter >::New();
895 writer->SetFileName(file_path.c_str());
897 #if VTK_MAJOR_VERSION <= 5
898 writer->SetInput(unstructured_grid);
902 writer->SetInputData(unstructured_grid);
909 throw std::runtime_error(
910 "Writer::write_vtk_or_vtp_or_vtu_file -> file extension .vtu is "
911 "reserved for UnstructuredGrid.");
916 throw std::runtime_error(
917 "Writer::write_vtk_or_vtp_or_vtu_file -> file extension is "
918 "inappropriate (neither .vtk, .vtp nor .vtu)");