fw4spl
io/fwVtkIO/src/fwVtkIO/helper/Mesh.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwVtkIO/helper/Mesh.hpp"
8 
9 #include <fwData/Array.hpp>
10 
11 #include <fwDataTools/helper/Array.hpp>
12 #include <fwDataTools/helper/Mesh.hpp>
13 #include <fwDataTools/helper/MeshGetter.hpp>
14 
15 #include <vtkCell.h>
16 #include <vtkCellData.h>
17 #include <vtkDataArray.h>
18 #include <vtkExtractUnstructuredGrid.h>
19 #include <vtkFillHolesFilter.h>
20 #include <vtkFloatArray.h>
21 #include <vtkGeometryFilter.h>
22 #include <vtkMassProperties.h>
23 #include <vtkPointData.h>
24 #include <vtkPoints.h>
25 #include <vtkPolyDataNormals.h>
26 #include <vtkSmartPointer.h>
27 
28 namespace fwVtkIO
29 {
30 namespace helper
31 {
32 
33 //------------------------------------------------------------------------------
34 
35 void Mesh::fromVTKMesh( vtkSmartPointer<vtkPolyData> polyData, ::fwData::Mesh::sptr mesh )
36 {
37  vtkPoints* points = polyData->GetPoints();
38  if (points)
39  {
40  mesh->clear();
41  const vtkIdType numberOfPoints = points->GetNumberOfPoints();
42  const vtkIdType numberOfCells = polyData->GetNumberOfCells();
43 
44  mesh->allocate(numberOfPoints, numberOfCells, numberOfCells*3);
45  ::fwDataTools::helper::Mesh meshHelper(mesh);
46 
47  const double* point;
48  ::fwData::Mesh::Id idx;
49  for (vtkIdType i = 0; i < numberOfPoints; ++i)
50  {
51  point = points->GetPoint(i);
52  idx = meshHelper.insertNextPoint(point[0], point[1], point[2]);
53  SLM_ASSERT("Mesh index not correspond to VTK index point", idx == i);
54  }
55 
56  vtkCell* cell;
57  vtkIdList* idList;
58  int cellType;
59  for (vtkIdType i = 0; i < numberOfCells; ++i)
60  {
61  cell = polyData->GetCell(i);
62  idList = cell->GetPointIds();
63  cellType = cell->GetCellType();
64 
65  switch (cellType)
66  {
67  case VTK_VERTEX:
68  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 1);
69  meshHelper.insertNextCell( idList->GetId(0));
70  break;
71  case VTK_LINE:
72  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 2);
73  meshHelper.insertNextCell( idList->GetId(0), idList->GetId(1));
74  break;
75  case VTK_TRIANGLE:
76  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 3);
77  meshHelper.insertNextCell( idList->GetId(0), idList->GetId(1), idList->GetId(2));
78  break;
79  case VTK_QUAD:
80  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 4);
81  meshHelper.insertNextCell( idList->GetId(0), idList->GetId(1), idList->GetId(2), idList->GetId(3));
82  break;
83  case VTK_POLY_VERTEX:
84  for(vtkIdType i = 0; i < idList->GetNumberOfIds(); ++i)
85  {
86  meshHelper.insertNextCell( idList->GetId(i));
87  }
88  break;
89  default:
90  FW_RAISE("VTK Mesh type "<<cellType<< " not supported.");
91  }
92  }
93 
94  if(polyData->GetPointData()->HasArray("Colors"))
95  {
96  vtkSmartPointer<vtkUnsignedCharArray> colors;
97  colors = vtkUnsignedCharArray::SafeDownCast(polyData->GetPointData()->GetArray("Colors"));
98  FW_RAISE_IF("Only vtkUnsignedCharArray is supported to manage color.", !colors);
99 
100  const size_t nbComponents = colors->GetNumberOfComponents();
101  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")",
102  nbComponents == 3 || nbComponents == 4);
103  mesh->allocatePointColors((::fwData::Mesh::ColorArrayTypes)nbComponents);
104  meshHelper.updateLock();
105 
106  ::fwData::Mesh::Id nbPoints = mesh->getNumberOfPoints();
107  for (size_t i = 0; i != nbPoints; ++i)
108  {
109  meshHelper.setPointColor(i, colors->GetPointer(i*nbComponents));
110  }
111  }
112 
113  if(polyData->GetCellData()->HasArray("Colors"))
114  {
115  vtkSmartPointer<vtkUnsignedCharArray> colors;
116  colors = vtkUnsignedCharArray::SafeDownCast(polyData->GetCellData()->GetArray("Colors"));
117  FW_RAISE_IF("Only vtkUnsignedCharArray is supported to manage color.", !colors);
118 
119  size_t nbComponents = colors->GetNumberOfComponents();
120  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")",
121  nbComponents == 3 || nbComponents == 4);
122  mesh->allocateCellColors((::fwData::Mesh::ColorArrayTypes)nbComponents);
123  meshHelper.updateLock();
124 
125  const ::fwData::Mesh::Id nbCells = mesh->getNumberOfCells();
126  for (size_t i = 0; i != nbCells; ++i)
127  {
128  meshHelper.setCellColor(i, colors->GetPointer(i*nbComponents));
129  }
130  }
131 
132  if(polyData->GetPointData()->GetAttribute(vtkDataSetAttributes::NORMALS))
133  {
134  vtkSmartPointer<vtkFloatArray> normals;
135  normals = vtkFloatArray::SafeDownCast(polyData->GetPointData()->GetNormals());
136  FW_RAISE_IF("Only vtkFloatArray is supported to manage normals.", !normals);
137 
138  size_t nbComponents = normals->GetNumberOfComponents();
139  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 3);
140 
141  mesh->allocatePointNormals();
142  meshHelper.updateLock();
143 
144  const ::fwData::Mesh::Id nbPoints = mesh->getNumberOfPoints();
145  for (size_t i = 0; i != nbPoints; ++i)
146  {
147  meshHelper.setPointNormal(i, normals->GetPointer(i*nbComponents));
148  }
149  }
150 
151  if(polyData->GetCellData()->GetAttribute(vtkDataSetAttributes::NORMALS))
152  {
153  vtkSmartPointer<vtkFloatArray> normals;
154  normals = vtkFloatArray::SafeDownCast(polyData->GetCellData()->GetNormals());
155  FW_RAISE_IF("Only vtkFloatArray is supported to manage normals.", !normals);
156 
157  size_t nbComponents = normals->GetNumberOfComponents();
158  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 3);
159 
160  mesh->allocateCellNormals();
161  meshHelper.updateLock();
162 
163  const ::fwData::Mesh::Id nbCells = mesh->getNumberOfCells();
164  for (size_t i = 0; i != nbCells; ++i)
165  {
166  meshHelper.setCellNormal(i, normals->GetPointer(i*nbComponents));
167  }
168  }
169 
170  if(polyData->GetPointData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
171  {
172  vtkSmartPointer<vtkFloatArray> texCoords;
173  texCoords = vtkFloatArray::SafeDownCast(polyData->GetPointData()->GetTCoords());
174  FW_RAISE_IF("Only vtkFloatArray is supported to manage texCoords.", !texCoords);
175 
176  size_t nbComponents = texCoords->GetNumberOfComponents();
177  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 2);
178 
179  mesh->allocatePointTexCoords();
180  meshHelper.updateLock();
181 
182  const ::fwData::Mesh::Id nbPoints = mesh->getNumberOfPoints();
183  for (size_t i = 0; i != nbPoints; ++i)
184  {
185  meshHelper.setPointTexCoord(i, texCoords->GetPointer(i*nbComponents));
186  }
187  }
188 
189  if(polyData->GetCellData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
190  {
191  vtkSmartPointer<vtkFloatArray> texCoords;
192  texCoords = vtkFloatArray::SafeDownCast(polyData->GetCellData()->GetTCoords());
193  FW_RAISE_IF("Only vtkFloatArray is supported to manage texCoords.", !texCoords);
194 
195  size_t nbComponents = texCoords->GetNumberOfComponents();
196  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 2);
197 
198  mesh->allocateCellTexCoords();
199  meshHelper.updateLock();
200 
201  const ::fwData::Mesh::Id nbCells = mesh->getNumberOfCells();
202  for (size_t i = 0; i != nbCells; ++i)
203  {
204  meshHelper.setCellTexCoord(i, texCoords->GetPointer(i*nbComponents));
205  }
206  }
207 
208  mesh->adjustAllocatedMemory();
209  }
210 }
211 
212 //------------------------------------------------------------------------------
213 
214 void Mesh::fromVTKGrid(vtkSmartPointer<vtkUnstructuredGrid> grid, ::fwData::Mesh::sptr mesh)
215 {
216  vtkPoints* points = grid->GetPoints();
217  if(points)
218  {
219  mesh->clear();
220  const vtkIdType numberOfPoints = points->GetNumberOfPoints();
221  const vtkIdType numberOfCells = grid->GetNumberOfCells();
222 
223  mesh->allocate(numberOfPoints, numberOfCells, numberOfCells*3);
224  ::fwDataTools::helper::Mesh meshHelper(mesh);
225  double* point;
226  ::fwData::Mesh::Id idx;
227  for (vtkIdType i = 0; i < numberOfPoints; ++i)
228  {
229  point = points->GetPoint(i);
230  idx = meshHelper.insertNextPoint(point[0], point[1], point[2]);
231  SLM_ASSERT("Mesh index not correspond to VTK index point", idx == i);
232  }
233 
234  vtkCell* cell;
235  vtkIdList* idList;
236  int cellType;
237  for (vtkIdType i = 0; i < numberOfCells; ++i)
238  {
239  cell = grid->GetCell(i);
240  idList = cell->GetPointIds();
241  cellType = cell->GetCellType();
242 
243  switch (cellType)
244  {
245  case VTK_VERTEX:
246  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 1);
247  meshHelper.insertNextCell( idList->GetId(0));
248  break;
249  case VTK_LINE:
250  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 2);
251  meshHelper.insertNextCell( idList->GetId(0), idList->GetId(1));
252  break;
253  case VTK_TRIANGLE:
254  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 3);
255  meshHelper.insertNextCell( idList->GetId(0), idList->GetId(1), idList->GetId(2));
256  break;
257  case VTK_QUAD:
258  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 4);
259  meshHelper.insertNextCell( idList->GetId(0), idList->GetId(1), idList->GetId(2), idList->GetId(3));
260  break;
261  case VTK_TETRA:
262  SLM_ASSERT("Wrong number of ids: "<<idList->GetNumberOfIds(), idList->GetNumberOfIds() == 4);
263  meshHelper.insertNextCell( idList->GetId(0), idList->GetId(1), idList->GetId(2), idList->GetId(3),
264  ::fwData::Mesh::TETRA);
265  break;
266  default:
267  FW_RAISE("VTK Mesh type "<<cellType<< " not supported.");
268  }
269  }
270 
271  if(grid->GetPointData()->HasArray("Colors"))
272  {
273  vtkSmartPointer<vtkUnsignedCharArray> colors;
274  colors = vtkUnsignedCharArray::SafeDownCast(grid->GetPointData()->GetArray("Colors"));
275  FW_RAISE_IF("Only vtkUnsignedCharArray is supported to manage color.", !colors);
276 
277  size_t nbComponents = colors->GetNumberOfComponents();
278  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")",
279  nbComponents == 3 || nbComponents == 4);
280  mesh->allocatePointColors((::fwData::Mesh::ColorArrayTypes)nbComponents);
281  meshHelper.updateLock();
282 
283  const ::fwData::Mesh::Id nbPoints = mesh->getNumberOfPoints();
284  for (size_t i = 0; i != nbPoints; ++i)
285  {
286  meshHelper.setPointColor(i, colors->GetPointer(i*nbComponents));
287  }
288  }
289 
290  if(grid->GetCellData()->HasArray("Colors"))
291  {
292  vtkSmartPointer<vtkUnsignedCharArray> colors;
293  colors = vtkUnsignedCharArray::SafeDownCast(grid->GetCellData()->GetArray("Colors"));
294  FW_RAISE_IF("Only vtkUnsignedCharArray is supported to manage color.", !colors);
295 
296  size_t nbComponents = colors->GetNumberOfComponents();
297  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")",
298  nbComponents == 3 || nbComponents == 4);
299  mesh->allocateCellColors((::fwData::Mesh::ColorArrayTypes)nbComponents);
300  meshHelper.updateLock();
301 
302  const ::fwData::Mesh::Id nbCells = mesh->getNumberOfCells();
303  for (size_t i = 0; i != nbCells; ++i)
304  {
305  meshHelper.setCellColor(i, colors->GetPointer(i*nbComponents));
306  }
307  }
308 
309  if(grid->GetPointData()->GetAttribute(vtkDataSetAttributes::NORMALS))
310  {
311  vtkSmartPointer<vtkFloatArray> normals;
312  normals = vtkFloatArray::SafeDownCast(grid->GetPointData()->GetNormals());
313  FW_RAISE_IF("Only vtkFloatArray is supported to manage normals.", !normals);
314 
315  size_t nbComponents = normals->GetNumberOfComponents();
316  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 3);
317 
318  mesh->allocatePointNormals();
319  meshHelper.updateLock();
320 
321  const ::fwData::Mesh::Id nbPoints = mesh->getNumberOfPoints();
322  for (size_t i = 0; i != nbPoints; ++i)
323  {
324  meshHelper.setPointNormal(i, normals->GetPointer(i*nbComponents));
325  }
326  }
327 
328  if(grid->GetCellData()->GetAttribute(vtkDataSetAttributes::NORMALS))
329  {
330  vtkSmartPointer<vtkFloatArray> normals;
331  normals = vtkFloatArray::SafeDownCast(grid->GetCellData()->GetNormals());
332  FW_RAISE_IF("Only vtkFloatArray is supported to manage normals.", !normals);
333 
334  size_t nbComponents = normals->GetNumberOfComponents();
335  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 3);
336 
337  mesh->allocateCellNormals();
338  meshHelper.updateLock();
339 
340  const ::fwData::Mesh::Id nbCells = mesh->getNumberOfCells();
341  for (size_t i = 0; i != nbCells; ++i)
342  {
343  meshHelper.setCellNormal(i, normals->GetPointer(i*nbComponents));
344  }
345  }
346 
347  if(grid->GetPointData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
348  {
349  vtkSmartPointer<vtkFloatArray> texCoords;
350  texCoords = vtkFloatArray::SafeDownCast(grid->GetPointData()->GetTCoords());
351  FW_RAISE_IF("Only vtkFloatArray is supported to manage texCoords.", !texCoords);
352 
353  size_t nbComponents = texCoords->GetNumberOfComponents();
354  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 2);
355 
356  mesh->allocatePointTexCoords();
357  meshHelper.updateLock();
358 
359  const ::fwData::Mesh::Id nbPoints = mesh->getNumberOfPoints();
360  for (size_t i = 0; i != nbPoints; ++i)
361  {
362  meshHelper.setPointTexCoord(i, texCoords->GetPointer(i*nbComponents));
363  }
364  }
365 
366  if(grid->GetCellData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
367  {
368  vtkSmartPointer<vtkFloatArray> texCoords;
369  texCoords = vtkFloatArray::SafeDownCast(grid->GetCellData()->GetTCoords());
370  FW_RAISE_IF("Only vtkFloatArray is supported to manage texCoords.", !texCoords);
371 
372  size_t nbComponents = texCoords->GetNumberOfComponents();
373  SLM_ASSERT("Wrong nb of components ("<<nbComponents<<")", nbComponents == 2);
374 
375  mesh->allocateCellTexCoords();
376  meshHelper.updateLock();
377 
378  const ::fwData::Mesh::Id nbCells = mesh->getNumberOfCells();
379  for (size_t i = 0; i != nbCells; ++i)
380  {
381  meshHelper.setCellTexCoord(i, texCoords->GetPointer(i*nbComponents));
382  }
383  }
384 
385  mesh->adjustAllocatedMemory();
386 
387  }
388 
389 }
390 
391 //------------------------------------------------------------------------------
392 
393 void Mesh::toVTKMesh( const ::fwData::Mesh::csptr& mesh, vtkSmartPointer<vtkPolyData> polyData)
394 {
395  const vtkSmartPointer< vtkPoints > pts = vtkSmartPointer< vtkPoints >::New();
396  polyData->SetPoints(pts);
397  Mesh::updatePolyDataPoints(polyData, mesh);
398 
399  ::fwDataTools::helper::MeshGetter meshHelper(mesh);
400  const unsigned int nbCells = mesh->getNumberOfCells();
401 
402  const ::fwData::Mesh::ConstCellTypesMultiArrayType cellTypes = meshHelper.getCellTypes();
403  const ::fwData::Mesh::ConstCellDataMultiArrayType cellData = meshHelper.getCellData();
404  const ::fwData::Mesh::ConstCellDataOffsetsMultiArrayType cellDataOffsets = meshHelper.getCellDataOffsets();
405 
406  polyData->Allocate(static_cast< int >(nbCells));
407 
408  vtkIdType typeVtkCell;
409  vtkIdType cell[4];
410  for(unsigned int i = 0; i < nbCells; ++i )
411  {
412  const ::fwData::Mesh::CellTypes cellType = cellTypes[i];
413  const ::fwData::Mesh::Id offset = cellDataOffsets[i];
414  switch( cellType )
415  {
416  case ::fwData::Mesh::POINT:
417  typeVtkCell = VTK_VERTEX;
418  cell[0] = cellData[offset];
419  polyData->InsertNextCell( typeVtkCell, 1, cell );
420  break;
421  case ::fwData::Mesh::EDGE:
422  typeVtkCell = VTK_LINE;
423  cell[0] = cellData[offset];
424  cell[1] = cellData[offset+1];
425  polyData->InsertNextCell( typeVtkCell, 2, cell );
426  break;
427  case ::fwData::Mesh::TRIANGLE:
428  typeVtkCell = VTK_TRIANGLE;
429  cell[0] = cellData[offset];
430  cell[1] = cellData[offset+1];
431  cell[2] = cellData[offset+2];
432  polyData->InsertNextCell( typeVtkCell, 3, cell );
433  break;
434  case ::fwData::Mesh::QUAD:
435  typeVtkCell = VTK_QUAD;
436  cell[0] = cellData[offset];
437  cell[1] = cellData[offset+1];
438  cell[2] = cellData[offset+2];
439  cell[3] = cellData[offset+3];
440  polyData->InsertNextCell( typeVtkCell, 4, cell );
441  break;
442  case ::fwData::Mesh::TETRA:
443  typeVtkCell = VTK_LINE;
444 
445  cell[0] = cellData[offset+1];
446  cell[1] = cellData[offset+2];
447  polyData->InsertNextCell( typeVtkCell, 2, cell );
448 
449  cell[0] = cellData[offset+2];
450  cell[1] = cellData[offset+3];
451  polyData->InsertNextCell( typeVtkCell, 2, cell );
452 
453  cell[0] = cellData[offset+3];
454  cell[1] = cellData[offset];
455  polyData->InsertNextCell( typeVtkCell, 2, cell );
456 
457  cell[0] = cellData[offset+2];
458  cell[1] = cellData[offset];
459  polyData->InsertNextCell( typeVtkCell, 2, cell );
460 
461  cell[0] = cellData[offset+1];
462  cell[1] = cellData[offset+3];
463  polyData->InsertNextCell( typeVtkCell, 2, cell );
464 
465  }
466  }
467 
468  Mesh::updatePolyDataPointNormals(polyData, mesh);
469  Mesh::updatePolyDataCellNormals(polyData, mesh);
470 
471  Mesh::updatePolyDataPointColor(polyData, mesh);
472  Mesh::updatePolyDataCellColor(polyData, mesh);
473 
474  Mesh::updatePolyDataPointTexCoords(polyData, mesh);
475  Mesh::updatePolyDataCellTexCoords(polyData, mesh);
476 }
477 
478 //------------------------------------------------------------------------------
479 
480 void Mesh::toVTKGrid( const ::fwData::Mesh::csptr& mesh, vtkSmartPointer<vtkUnstructuredGrid> grid)
481 {
482  const vtkSmartPointer< vtkPoints > pts = vtkSmartPointer< vtkPoints >::New();
483  grid->SetPoints(pts);
484  Mesh::updateGridPoints(grid, mesh);
485 
486  ::fwDataTools::helper::MeshGetter meshHelper(mesh);
487  const unsigned int nbCells = mesh->getNumberOfCells();
488 
489  const ::fwData::Mesh::ConstCellTypesMultiArrayType cellTypes = meshHelper.getCellTypes();
490  const ::fwData::Mesh::ConstCellDataMultiArrayType cellData = meshHelper.getCellData();
491  const ::fwData::Mesh::ConstCellDataOffsetsMultiArrayType cellDataOffsets = meshHelper.getCellDataOffsets();
492 
493  grid->Allocate(static_cast<int>(nbCells));
494 
495  vtkIdType typeVtkCell;
496  vtkIdType cell[4];
497  for(unsigned int i = 0; i < nbCells; ++i )
498  {
499  const ::fwData::Mesh::CellTypes cellType = cellTypes[i];
500  const ::fwData::Mesh::Id offset = cellDataOffsets[i];
501  switch( cellType )
502  {
503  case ::fwData::Mesh::POINT:
504  typeVtkCell = VTK_VERTEX;
505  cell[0] = cellData[offset];
506  grid->InsertNextCell( typeVtkCell, 1, cell );
507  break;
508  case ::fwData::Mesh::EDGE:
509  typeVtkCell = VTK_LINE;
510  cell[0] = cellData[offset];
511  cell[1] = cellData[offset+1];
512  grid->InsertNextCell( typeVtkCell, 2, cell );
513  break;
514  case ::fwData::Mesh::TRIANGLE:
515  typeVtkCell = VTK_TRIANGLE;
516  cell[0] = cellData[offset];
517  cell[1] = cellData[offset+1];
518  cell[2] = cellData[offset+2];
519  grid->InsertNextCell( typeVtkCell, 3, cell );
520  break;
521  case ::fwData::Mesh::QUAD:
522  typeVtkCell = VTK_QUAD;
523  cell[0] = cellData[offset];
524  cell[1] = cellData[offset+1];
525  cell[2] = cellData[offset+2];
526  cell[3] = cellData[offset+3];
527  grid->InsertNextCell( typeVtkCell, 4, cell );
528  break;
529  case ::fwData::Mesh::TETRA:
530  typeVtkCell = VTK_TETRA;
531  cell[0] = cellData[offset];
532  cell[1] = cellData[offset+1];
533  cell[2] = cellData[offset+2];
534  cell[3] = cellData[offset+3];
535  grid->InsertNextCell( typeVtkCell, 4, cell );
536  }
537  }
538 
539  Mesh::updateGridPointNormals(grid, mesh);
540  Mesh::updateGridCellNormals(grid, mesh);
541 
542  Mesh::updateGridPointColor(grid, mesh);
543  Mesh::updateGridCellColor(grid, mesh);
544 
545  Mesh::updateGridPointTexCoords(grid, mesh);
546  Mesh::updateGridCellTexCoords(grid, mesh);
547 }
548 
549 //------------------------------------------------------------------------------
550 
551 void Mesh::updatePolyDataPoints(vtkSmartPointer<vtkPolyData> polyDataDst,
552  const ::fwData::Mesh::csptr& meshSrc )
553 {
554  SLM_ASSERT( "vtkPolyData should not be NULL", polyDataDst);
555  ::fwDataTools::helper::MeshGetter meshHelper(meshSrc);
556 
557  vtkPoints* polyDataPoints = polyDataDst->GetPoints();
558  const ::fwData::Mesh::Id nbPoints = meshSrc->getNumberOfPoints();
559  const ::fwData::Mesh::ConstPointsMultiArrayType points = meshHelper.getPoints();
560 
561  if (nbPoints != polyDataPoints->GetNumberOfPoints())
562  {
563  polyDataPoints->SetNumberOfPoints(nbPoints);
564  }
565 
566  vtkIdType id = 0;
567  typedef ::fwData::Mesh::PointsMultiArrayType::index PointTypesIndex;
568  for (PointTypesIndex i = 0; i != nbPoints; ++i)
569  {
570  polyDataPoints->SetPoint(id++, points[i][0], points[i][1], points[i][2]);
571  }
572 
573  polyDataPoints->Modified();
574 }
575 
576 //------------------------------------------------------------------------------
577 
578 void Mesh::updatePolyDataPointColor(vtkSmartPointer<vtkPolyData> polyDataDst,
579  const ::fwData::Mesh::csptr& meshSrc )
580 {
581  SLM_ASSERT( "vtkPolyData should not be NULL", polyDataDst);
582 
583  const ::fwData::Array::sptr pointColorArray = meshSrc->getPointColorsArray();
584  if(pointColorArray)
585  {
586  ::fwDataTools::helper::Array arrayHelper(pointColorArray);
587 
588  const vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
589  const size_t nbComponents = pointColorArray->getNumberOfComponents();
590  colors->SetNumberOfComponents(static_cast<int>(nbComponents));
591  colors->SetName("Colors");
592 
593  const unsigned char* pointColor = arrayHelper.begin< unsigned char >();
594  const unsigned char* pointColorEnd = arrayHelper.end< unsigned char >();
595 
596  for (; pointColor != pointColorEnd; pointColor += nbComponents)
597  {
598  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
599 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
600  colors->InsertNextTypedTuple(pointColor);
601 #else
602  colors->InsertNextTupleValue(pointColor);
603 #endif
604  }
605  polyDataDst->GetPointData()->SetScalars(colors);
606  polyDataDst->Modified();
607  }
608  else
609  {
610  if(polyDataDst->GetPointData()->HasArray("Colors"))
611  {
612  polyDataDst->GetPointData()->RemoveArray("Colors");
613  }
614  polyDataDst->Modified();
615  }
616 }
617 
618 //------------------------------------------------------------------------------
619 
620 void Mesh::updatePolyDataCellColor(vtkSmartPointer<vtkPolyData> polyDataDst,
621  const ::fwData::Mesh::csptr& meshSrc )
622 {
623  SLM_ASSERT( "vtkPolyData should not be NULL", polyDataDst);
624 
625  const ::fwData::Array::sptr cellColorArray = meshSrc->getCellColorsArray();
626  if(cellColorArray)
627  {
628  ::fwDataTools::helper::Array arrayHelper(cellColorArray);
629 
630  const vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
631  const size_t nbComponents = cellColorArray->getNumberOfComponents();
632  colors->SetNumberOfComponents(static_cast<int>(nbComponents));
633  colors->SetName("Colors");
634 
635  ::fwMemory::BufferObject::Lock lock = cellColorArray->getBufferObject()->lock();
636  const unsigned char* cellColor = arrayHelper.begin< unsigned char >();
637  const unsigned char* cellColorEnd = arrayHelper.end< unsigned char >();
638 
639  for (; cellColor != cellColorEnd; cellColor += nbComponents)
640  {
641  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
642 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
643  colors->InsertNextTypedTuple(cellColor);
644 #else
645  colors->InsertNextTupleValue(cellColor);
646 #endif
647  }
648 
649  polyDataDst->GetCellData()->SetScalars(colors);
650  polyDataDst->Modified();
651  }
652  else
653  {
654  if(polyDataDst->GetCellData()->HasArray("Colors"))
655  {
656  polyDataDst->GetCellData()->RemoveArray("Colors");
657  }
658  polyDataDst->Modified();
659  }
660 
661 }
662 
663 //------------------------------------------------------------------------------
664 
665 void Mesh::updatePolyDataPointNormals(vtkSmartPointer<vtkPolyData> polyDataDst,
666  const ::fwData::Mesh::csptr& meshSrc )
667 {
668  SLM_ASSERT( "vtkPolyData should not be NULL", polyDataDst);
669 
670  const ::fwData::Array::sptr pointNormalsArray = meshSrc->getPointNormalsArray();
671  if(pointNormalsArray)
672  {
673  ::fwDataTools::helper::Array arrayHelper(pointNormalsArray);
674 
675  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
676  const size_t nbComponents = pointNormalsArray->getNumberOfComponents();
677  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
678 
679  const float* pointNormal = arrayHelper.begin< float >();
680  const float* const pointNormalEnd = arrayHelper.end< float >();
681 
682  for (; pointNormal != pointNormalEnd; pointNormal += nbComponents)
683  {
684  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
685 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
686  normals->InsertNextTypedTuple(pointNormal);
687 #else
688  normals->InsertNextTupleValue(pointNormal);
689 #endif
690  }
691 
692  polyDataDst->GetPointData()->SetNormals(normals);
693  polyDataDst->Modified();
694  }
695  else
696  {
697  if(polyDataDst->GetPointData()->GetAttribute(vtkDataSetAttributes::NORMALS))
698  {
699  polyDataDst->GetPointData()->RemoveArray(vtkDataSetAttributes::NORMALS);
700  }
701  polyDataDst->Modified();
702  }
703 }
704 
705 //------------------------------------------------------------------------------
706 
707 void Mesh::updatePolyDataCellNormals(vtkSmartPointer<vtkPolyData> polyDataDst,
708  const ::fwData::Mesh::csptr& meshSrc )
709 {
710  SLM_ASSERT( "vtkPolyData should not be NULL", polyDataDst);
711 
712  const ::fwData::Array::sptr cellNormalsArray = meshSrc->getCellNormalsArray();
713 
714  if(cellNormalsArray)
715  {
716  ::fwDataTools::helper::Array arrayHelper(cellNormalsArray);
717 
718  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
719  const size_t nbComponents = cellNormalsArray->getNumberOfComponents();
720  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
721 
722  const float* cellNormal = arrayHelper.begin< float >();
723  const float* const cellNormalEnd = arrayHelper.end< float >();
724 
725  for (; cellNormal != cellNormalEnd; cellNormal += nbComponents)
726  {
727  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
728 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
729  normals->InsertNextTypedTuple(cellNormal);
730 #else
731  normals->InsertNextTupleValue(cellNormal);
732 #endif
733  }
734 
735  polyDataDst->GetCellData()->SetNormals(normals);
736  polyDataDst->Modified();
737  }
738  else
739  {
740  if(polyDataDst->GetCellData()->GetAttribute(vtkDataSetAttributes::NORMALS))
741  {
742  polyDataDst->GetCellData()->RemoveArray(vtkDataSetAttributes::NORMALS);
743  }
744  polyDataDst->Modified();
745  }
746 }
747 
748 //------------------------------------------------------------------------------
749 
750 void Mesh::updatePolyDataPointTexCoords(vtkSmartPointer<vtkPolyData> polyDataDst,
751  const ::fwData::Mesh::csptr& meshSrc )
752 {
753  SLM_ASSERT( "vtkPolyData should not be NULL", polyDataDst);
754 
755  const ::fwData::Array::sptr pointTexCoordsArray = meshSrc->getPointTexCoordsArray();
756  if(pointTexCoordsArray)
757  {
758  ::fwDataTools::helper::Array arrayHelper(pointTexCoordsArray);
759 
760  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
761  const size_t nbComponents = pointTexCoordsArray->getNumberOfComponents();
762  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
763 
764  const float* pointTexCoord = arrayHelper.begin< float >();
765  const float* const pointTexCoordEnd = arrayHelper.end< float >();
766 
767  for (; pointTexCoord != pointTexCoordEnd; pointTexCoord += nbComponents)
768  {
769  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
770 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
771  normals->InsertNextTypedTuple(pointTexCoord);
772 #else
773  normals->InsertNextTupleValue(pointTexCoord);
774 #endif
775  }
776 
777  polyDataDst->GetPointData()->SetTCoords(normals);
778  polyDataDst->Modified();
779  }
780  else
781  {
782  if(polyDataDst->GetPointData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
783  {
784  polyDataDst->GetPointData()->RemoveArray(vtkDataSetAttributes::TCOORDS);
785  }
786  polyDataDst->Modified();
787  }
788 }
789 
790 //------------------------------------------------------------------------------
791 
792 void Mesh::updatePolyDataCellTexCoords(vtkSmartPointer<vtkPolyData> polyDataDst,
793  const ::fwData::Mesh::csptr& meshSrc )
794 {
795  SLM_ASSERT( "vtkPolyData should not be NULL", polyDataDst);
796 
797  const ::fwData::Array::sptr cellTexCoordsArray = meshSrc->getCellTexCoordsArray();
798  if(cellTexCoordsArray)
799  {
800  ::fwDataTools::helper::Array arrayHelper(cellTexCoordsArray);
801 
802  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
803  const size_t nbComponents = cellTexCoordsArray->getNumberOfComponents();
804  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
805 
806  const float* cellTexCoord = arrayHelper.begin< float >();
807  const float* const cellTexCoordEnd = arrayHelper.end< float >();
808 
809  for (; cellTexCoord != cellTexCoordEnd; cellTexCoord += nbComponents)
810  {
811  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
812 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
813  normals->InsertNextTypedTuple(cellTexCoord);
814 #else
815  normals->InsertNextTupleValue(cellTexCoord);
816 #endif
817  }
818 
819  polyDataDst->GetCellData()->SetTCoords(normals);
820  polyDataDst->Modified();
821  }
822  else
823  {
824  if(polyDataDst->GetCellData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
825  {
826  polyDataDst->GetCellData()->RemoveArray(vtkDataSetAttributes::TCOORDS);
827  }
828  polyDataDst->Modified();
829  }
830 
831 }
832 
833 //-----------------------------------------------------------------------------
834 
835 double Mesh::computeVolume( const ::fwData::Mesh::csptr& mesh )
836 {
837  vtkSmartPointer< vtkPolyData > vtkMeshRaw = vtkSmartPointer< vtkPolyData >::New();
838  Mesh::toVTKMesh( mesh, vtkMeshRaw );
839 
840  // identify and fill holes in meshes
841  vtkSmartPointer< vtkFillHolesFilter > holesFilter = vtkSmartPointer< vtkFillHolesFilter >::New();
842  holesFilter->SetHoleSize(2000);
843  holesFilter->SetInputData(vtkMeshRaw);
844  holesFilter->Update();
845  if (holesFilter->GetOutput()->GetNumberOfCells() > 0) // Filter return empty mesh when no topological holes are
846  // present
847  {
848  vtkMeshRaw = holesFilter->GetOutput();
849  }
850 
851  // compute normals for polygonal mesh
852  const vtkSmartPointer< vtkPolyDataNormals > filter = vtkSmartPointer< vtkPolyDataNormals >::New();
853  filter->SetInputData(vtkMeshRaw);
854  filter->AutoOrientNormalsOn();
855  filter->FlipNormalsOff();
856 
857  // estimate volume, area, shape index of triangle mesh
858  const vtkSmartPointer< vtkMassProperties > calculator = vtkSmartPointer< vtkMassProperties >::New();
859  calculator->SetInputConnection( filter->GetOutputPort() );
860  calculator->Update();
861 
862  const double volume = calculator->GetVolume();
863  OSLM_DEBUG(
864  "GetVolume : " << volume << " vtkMassProperties::GetVolumeProjected = " <<
865  calculator->GetVolumeProjected() );
866  OSLM_DEBUG("Error : " << (calculator->GetVolume()- fabs(calculator->GetVolumeProjected()))*10000);
867  if ( (calculator->GetVolume()- fabs(calculator->GetVolumeProjected()))*10000 > calculator->GetVolume() )
868  {
869  std::stringstream ss;
870  ss << "volume - |volume projected| > volume/10000.0" << std::endl;
871  ss << "[volume = " << volume << "]" << std::endl;
872  ss << "[volume projected = " << calculator->GetVolumeProjected()<<"]";
873  throw (std::out_of_range( ss.str() ));
874  }
875 
876  return volume;
877 }
878 
879 //------------------------------------------------------------------------------
880 
881 void Mesh::updateGridPointNormals(vtkSmartPointer<vtkUnstructuredGrid> gridDst,
882  const ::fwData::Mesh::csptr& meshSrc )
883 {
884  SLM_ASSERT( "vtkUnstructuredGrid should not be NULL", gridDst);
885 
886  const ::fwData::Array::sptr pointNormalsArray = meshSrc->getPointNormalsArray();
887  if(pointNormalsArray)
888  {
889  ::fwDataTools::helper::Array arrayHelper(pointNormalsArray);
890 
891  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
892  const size_t nbComponents = pointNormalsArray->getNumberOfComponents();
893  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
894 
895  const float* pointNormal = arrayHelper.begin< float >();
896  const float* const pointNormalEnd = arrayHelper.end< float >();
897 
898  for (; pointNormal != pointNormalEnd; pointNormal += nbComponents)
899  {
900  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
901 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
902  normals->InsertNextTypedTuple(pointNormal);
903 #else
904  normals->InsertNextTupleValue(pointNormal);
905 #endif
906  }
907 
908  gridDst->GetPointData()->SetNormals(normals);
909  gridDst->Modified();
910  }
911  else
912  {
913  if(gridDst->GetPointData()->GetAttribute(vtkDataSetAttributes::NORMALS))
914  {
915  gridDst->GetPointData()->RemoveArray(vtkDataSetAttributes::NORMALS);
916  }
917  gridDst->Modified();
918  }
919 
920 }
921 
922 //------------------------------------------------------------------------------
923 
924 void Mesh::updateGridPoints(vtkSmartPointer<vtkUnstructuredGrid> gridDst,
925  const ::fwData::Mesh::csptr& meshSrc )
926 {
927  SLM_ASSERT( "vtkPolyData should not be NULL", gridDst);
928  ::fwDataTools::helper::MeshGetter meshHelper(meshSrc);
929 
930  vtkPoints* polyDataPoints = gridDst->GetPoints();
931  const ::fwData::Mesh::Id nbPoints = meshSrc->getNumberOfPoints();
932  const ::fwData::Mesh::ConstPointsMultiArrayType points = meshHelper.getPoints();
933 
934  if (nbPoints != polyDataPoints->GetNumberOfPoints())
935  {
936  polyDataPoints->SetNumberOfPoints(nbPoints);
937  }
938 
939  vtkIdType id = 0;
940  typedef ::fwData::Mesh::PointsMultiArrayType::index PointTypesIndex;
941  for (PointTypesIndex i = 0; i != nbPoints; ++i)
942  {
943  polyDataPoints->SetPoint(id++, points[i][0], points[i][1], points[i][2]);
944  }
945 
946  polyDataPoints->Modified();
947 }
948 
949 //------------------------------------------------------------------------------
950 void Mesh::updateGridPointColor(vtkSmartPointer<vtkUnstructuredGrid> gridDst,
951  const ::fwData::Mesh::csptr& meshSrc )
952 {
953  SLM_ASSERT( "vtkPolyData should not be NULL", gridDst);
954 
955  const ::fwData::Array::sptr pointColorArray = meshSrc->getPointColorsArray();
956  if(pointColorArray)
957  {
958  ::fwDataTools::helper::Array arrayHelper(pointColorArray);
959 
960  vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
961  const size_t nbComponents = pointColorArray->getNumberOfComponents();
962  colors->SetNumberOfComponents(static_cast<int>(nbComponents));
963  colors->SetName("Colors");
964 
965  const unsigned char* pointColor = arrayHelper.begin< unsigned char >();
966  const unsigned char* const pointColorEnd = arrayHelper.end< unsigned char >();
967 
968  for (; pointColor != pointColorEnd; pointColor += nbComponents)
969  {
970  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
971 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
972  colors->InsertNextTypedTuple(pointColor);
973 #else
974  colors->InsertNextTupleValue(pointColor);
975 #endif
976  }
977  gridDst->GetPointData()->SetScalars(colors);
978  gridDst->Modified();
979  }
980  else
981  {
982  if(gridDst->GetPointData()->HasArray("Colors"))
983  {
984  gridDst->GetPointData()->RemoveArray("Colors");
985  }
986  gridDst->Modified();
987  }
988 
989 }
990 
991 //------------------------------------------------------------------------------
992 
993 void Mesh::updateGridCellColor(vtkSmartPointer<vtkUnstructuredGrid> gridDst,
994  const ::fwData::Mesh::csptr& meshSrc )
995 {
996  SLM_ASSERT( "vtkPolyData should not be NULL", gridDst);
997 
998  const ::fwData::Array::sptr cellColorArray = meshSrc->getCellColorsArray();
999  if(cellColorArray)
1000  {
1001  ::fwDataTools::helper::Array arrayHelper(cellColorArray);
1002 
1003  vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
1004  const size_t nbComponents = cellColorArray->getNumberOfComponents();
1005  colors->SetNumberOfComponents(static_cast<int>(nbComponents));
1006  colors->SetName("Colors");
1007 
1008  const ::fwMemory::BufferObject::Lock lock = cellColorArray->getBufferObject()->lock();
1009  const unsigned char* cellColor = arrayHelper.begin< unsigned char >();
1010  const unsigned char* const cellColorEnd = arrayHelper.end< unsigned char >();
1011 
1012  for (; cellColor != cellColorEnd; cellColor += nbComponents)
1013  {
1014  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
1015 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
1016  colors->InsertNextTypedTuple(cellColor);
1017 #else
1018  colors->InsertNextTupleValue(cellColor);
1019 #endif
1020  }
1021 
1022  gridDst->GetCellData()->SetScalars(colors);
1023  gridDst->Modified();
1024  }
1025  else
1026  {
1027  if(gridDst->GetCellData()->HasArray("Colors"))
1028  {
1029  gridDst->GetCellData()->RemoveArray("Colors");
1030  }
1031  gridDst->Modified();
1032  }
1033 }
1034 
1035 //------------------------------------------------------------------------------
1036 
1037 void Mesh::updateGridCellNormals(vtkSmartPointer<vtkUnstructuredGrid> gridDst,
1038  const ::fwData::Mesh::csptr& meshSrc )
1039 {
1040  SLM_ASSERT( "vtkPolyData should not be NULL", gridDst);
1041 
1042  const ::fwData::Array::sptr cellNormalsArray = meshSrc->getCellNormalsArray();
1043 
1044  if(cellNormalsArray)
1045  {
1046  ::fwDataTools::helper::Array arrayHelper(cellNormalsArray);
1047 
1048  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
1049  const size_t nbComponents = cellNormalsArray->getNumberOfComponents();
1050  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
1051 
1052  const float* cellNormal = arrayHelper.begin< float >();
1053  const float* const cellNormalEnd = arrayHelper.end< float >();
1054 
1055  for (; cellNormal != cellNormalEnd; cellNormal += nbComponents)
1056  {
1057  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
1058 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
1059  normals->InsertNextTypedTuple(cellNormal);
1060 #else
1061  normals->InsertNextTupleValue(cellNormal);
1062 #endif
1063  }
1064 
1065  gridDst->GetCellData()->SetNormals(normals);
1066  gridDst->Modified();
1067  }
1068  else
1069  {
1070  if(gridDst->GetCellData()->GetAttribute(vtkDataSetAttributes::NORMALS))
1071  {
1072  gridDst->GetCellData()->RemoveArray(vtkDataSetAttributes::NORMALS);
1073  }
1074  gridDst->Modified();
1075  }
1076 
1077 }
1078 
1079 //------------------------------------------------------------------------------
1080 
1081 void Mesh::updateGridPointTexCoords(vtkSmartPointer<vtkUnstructuredGrid> gridDst,
1082  const ::fwData::Mesh::csptr& meshSrc )
1083 {
1084  SLM_ASSERT( "vtkPolyData should not be NULL", gridDst);
1085 
1086  const ::fwData::Array::sptr pointTexCoordsArray = meshSrc->getPointTexCoordsArray();
1087  if(pointTexCoordsArray)
1088  {
1089  ::fwDataTools::helper::Array arrayHelper(pointTexCoordsArray);
1090 
1091  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
1092  const size_t nbComponents = pointTexCoordsArray->getNumberOfComponents();
1093  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
1094 
1095  const float* pointTexCoord = arrayHelper.begin< float >();
1096  const float* const pointTexCoordEnd = arrayHelper.end< float >();
1097 
1098  for (; pointTexCoord != pointTexCoordEnd; pointTexCoord += nbComponents)
1099  {
1100  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
1101 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
1102  normals->InsertNextTypedTuple(pointTexCoord);
1103 #else
1104  normals->InsertNextTupleValue(pointTexCoord);
1105 #endif
1106  }
1107 
1108  gridDst->GetPointData()->SetTCoords(normals);
1109  gridDst->Modified();
1110  }
1111  else
1112  {
1113  if(gridDst->GetPointData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
1114  {
1115  gridDst->GetPointData()->RemoveArray(vtkDataSetAttributes::TCOORDS);
1116  }
1117  gridDst->Modified();
1118  }
1119 
1120 }
1121 
1122 //------------------------------------------------------------------------------
1123 
1124 void Mesh::updateGridCellTexCoords(vtkSmartPointer<vtkUnstructuredGrid> gridDst,
1125  const ::fwData::Mesh::csptr& meshSrc )
1126 {
1127  SLM_ASSERT( "vtkPolyData should not be NULL", gridDst);
1128 
1129  const ::fwData::Array::sptr cellTexCoordsArray = meshSrc->getCellTexCoordsArray();
1130 
1131  if(cellTexCoordsArray)
1132  {
1133  ::fwDataTools::helper::Array arrayHelper(cellTexCoordsArray);
1134 
1135  vtkSmartPointer<vtkFloatArray> normals = vtkSmartPointer<vtkFloatArray>::New();
1136  size_t nbComponents = cellTexCoordsArray->getNumberOfComponents();
1137  normals->SetNumberOfComponents(static_cast<int>(nbComponents));
1138 
1139  const float* cellTexCoord = arrayHelper.begin< float >();
1140  const float* const cellTexCoordEnd = arrayHelper.end< float >();
1141 
1142  for (; cellTexCoord != cellTexCoordEnd; cellTexCoord += nbComponents)
1143  {
1144  // Since VTK 7.1, InsertNextTupleValue is deprecated in favor of InsertNextTypedTuple.
1145 #if (VTK_MAJOR_VERSION == 7 && VTK_MINOR_VERSION >= 1) || VTK_MAJOR_VERSION > 7
1146  normals->InsertNextTypedTuple(cellTexCoord);
1147 #else
1148  normals->InsertNextTupleValue(cellTexCoord);
1149 #endif
1150  }
1151 
1152  gridDst->GetCellData()->SetTCoords(normals);
1153  gridDst->Modified();
1154  }
1155  else
1156  {
1157  if(gridDst->GetCellData()->GetAttribute(vtkDataSetAttributes::TCOORDS))
1158  {
1159  gridDst->GetCellData()->RemoveArray(vtkDataSetAttributes::TCOORDS);
1160  }
1161  gridDst->Modified();
1162  }
1163 
1164 }
1165 
1166 //-----------------------------------------------------------------------------
1167 
1168 } // namespace helper
1169 } // namespace fwVtkIO
static FWVTKIO_API void updatePolyDataPointColor(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point color of fwData::Mesh.
FWDATATOOLS_API void setPointTexCoord(::fwData::Mesh::Id id, const ::fwData::Mesh::TexCoordValueType t[2])
Set a point texCoord.
FWDATATOOLS_API::fwData::Mesh::Id insertNextPoint(const ::fwData::Mesh::PointValueType p[3])
Insert a point into the mesh. Reallocates the point array if needed.
static FWVTKIO_API void toVTKGrid(const ::fwData::Mesh::csptr &mesh, vtkSmartPointer< vtkUnstructuredGrid > grid)
Convert a ::fwData::Mesh::csptr to a vtkUnstructuredGrid.
FWDATATOOLS_API void setCellTexCoord(::fwData::Mesh::Id id, const ::fwData::Mesh::TexCoordValueType t[2])
Set a cell texCoord.
static FWVTKIO_API void toVTKMesh(const ::fwData::Mesh::csptr &_mesh, vtkSmartPointer< vtkPolyData > _polyData)
Convert a ::fwData::Mesh::csptr to a vtkPolyData.
static FWVTKIO_API void updateGridCellColor(vtkSmartPointer< vtkUnstructuredGrid > gridDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkUnstructuredGrid with cell color of fwData::Mesh.
FWDATATOOLS_API void setCellNormal(::fwData::Mesh::Id id, const ::fwData::Mesh::NormalValueType n[3])
Set a cell normal.
static FWVTKIO_API void updatePolyDataPoints(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with ::fwData::Mesh::sptr points.
FWDATATOOLS_API void setCellColor(::fwData::Mesh::Id id, const ::fwData::Mesh::ColorValueType c[4])
Set a cell color.
FWDATATOOLS_API::fwData::Mesh::ConstCellTypesMultiArrayType getCellTypes() const
Returns the internal corresponding array as a boost::multi_array_ref.
Definition: MeshGetter.cpp:87
base class for BufferObject Lock
static FWVTKIO_API void updateGridCellTexCoords(vtkSmartPointer< vtkUnstructuredGrid > gridDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkUnstructuredGrid with cell texCoords of fwData::Mesh.
static FWVTKIO_API void updateGridCellNormals(vtkSmartPointer< vtkUnstructuredGrid > gridDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkUnstructuredGrid with cell normals of fwData::Mesh.
static FWVTKIO_API void updateGridPoints(vtkSmartPointer< vtkUnstructuredGrid > gridDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkUnstructuredGrid with ::fwData::Mesh::sptr points.
static FWVTKIO_API void fromVTKGrid(vtkSmartPointer< vtkUnstructuredGrid > grid,::fwData::Mesh::sptr mesh)
Convert a vtkUnstructuredGrid to a ::fwData::Mesh::sptr.
static FWVTKIO_API void updatePolyDataCellColor(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with cell color of fwData::Mesh.
virtual FWDATATOOLS_API char * begin()
Returns the begining/end of the buffer interpreted as a char buffer.
static FWVTKIO_API void updateGridPointColor(vtkSmartPointer< vtkUnstructuredGrid > gridDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkUnstructuredGrid with point color of fwData::Mesh.
Helper to manage Mesh. Lock the mesh buffer before to modify it.
Definition: MeshGetter.hpp:28
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
FWDATATOOLS_API::fwData::Mesh::ConstCellDataMultiArrayType getCellData() const
Returns the internal corresponding array as a boost::multi_array_ref.
Definition: MeshGetter.cpp:97
static FWVTKIO_API void updatePolyDataCellTexCoords(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with cell texCoords of fwData::Mesh.
static FWVTKIO_API void updatePolyDataCellNormals(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with cell normals of fwData::Mesh.
static FWVTKIO_API double computeVolume(const ::fwData::Mesh::csptr &mesh)
Compute the volume of the mesh using MassProperties vtk class.
FWDATATOOLS_API void setPointNormal(::fwData::Mesh::Id id, const ::fwData::Mesh::NormalValueType n[3])
Set a point normal.
FWDATATOOLS_API::fwData::Mesh::ConstPointsMultiArrayType getPoints() const
Returns the internal corresponding array as a boost::multi_array_ref.
Definition: MeshGetter.cpp:77
static FWVTKIO_API void updateGridPointTexCoords(vtkSmartPointer< vtkUnstructuredGrid > gridDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkUnstructuredGrid with point texCoords of fwData::Mesh.
static FWVTKIO_API void updatePolyDataPointNormals(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point normals of fwData::Mesh.
static FWVTKIO_API void fromVTKMesh(vtkSmartPointer< vtkPolyData > _polyData,::fwData::Mesh::sptr _mesh)
Convert a vtkPolyData to a ::fwData::Mesh::sptr.
FWDATATOOLS_API::fwData::Mesh::ConstCellDataOffsetsMultiArrayType getCellDataOffsets() const
Returns the internal corresponding array as a boost::multi_array_ref.
Definition: MeshGetter.cpp:107
FWDATATOOLS_API void updateLock()
Updates locks on all internal data Array of Mesh.
static FWVTKIO_API void updatePolyDataPointTexCoords(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point texCoords of fwData::Mesh.
static FWVTKIO_API void updateGridPointNormals(vtkSmartPointer< vtkUnstructuredGrid > gridDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkUnstructuredGrid with point normals of fwData::Mesh.
FWDATATOOLS_API void setPointColor(::fwData::Mesh::Id id, const ::fwData::Mesh::ColorValueType c[4])
Set a point color.
Helper to manage array buffer. Lock the buffer before to modify it.
FWDATATOOLS_API::fwData::Mesh::Id insertNextCell(::fwData::Mesh::CellTypesEnum type, const ::fwData::Mesh::CellValueType *cell, size_t nb)
Insert a cell into the mesh.
#define OSLM_DEBUG(message)
Definition: spyLog.hpp:241
Helper to manage Mesh. Lock the mesh buffer before to modify it.