fw4spl
core/fwDataTools/src/fwDataTools/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 "fwDataTools/Mesh.hpp"
8 
9 #include "fwDataTools/helper/ArrayGetter.hpp"
10 #include "fwDataTools/helper/MeshGetter.hpp"
11 #include "fwDataTools/thread/RegionThreader.hpp"
12 #include "fwDataTools/TransformationMatrix3D.hpp"
13 
14 #include <fwTools/NumericRoundCast.hxx>
15 
16 #include <glm/mat4x4.hpp>
17 #include <glm/vec3.hpp>
18 #include <glm/vec4.hpp>
19 
20 #include <cstdlib>
21 #include <ctime>
22 #include <functional>
23 #include <map>
24 
25 namespace fwDataTools
26 {
27 
28 struct RandFloat
29 {
30  //------------------------------------------------------------------------------
31 
32  float operator()()
33  {
34  return ((rand() % 101 - 50.f)) / 500.f;
35  }
36 };
37 
38 //------------------------------------------------------------------------------
39 
41 {
42  std::srand(::fwTools::numericRoundCast<unsigned int>(std::time(NULL)));
43 }
44 
45 //------------------------------------------------------------------------------
46 
47 bool Mesh::hasUniqueCellType(::fwData::Mesh::csptr mesh, ::fwData::Mesh::CellTypes cell)
48 {
49  bool res = true;
50  ::fwDataTools::helper::MeshGetter meshHelper(mesh);
51  ::fwData::Mesh::ConstCellTypesMultiArrayType cellTypes = meshHelper.getCellTypes();
52 
53  for(::fwData::Mesh::CellTypes type : cellTypes)
54  {
55  if(type != cell)
56  {
57  return false;
58  }
59  }
60  return res;
61 }
62 
63 //------------------------------------------------------------------------------
64 
65 typedef boost::multi_array_ref<Point, 1> PointsMultiArrayType;
66 
67 //------------------------------------------------------------------------------
68 
69 Vector<float>& computeTriangleNormal(const Point& p1, const Point& p2, const Point& p3, Vector<float>& n)
70 {
71  n = Vector<float>(p1, p2);
72  Vector<float> v(p1, p3);
73  n.crossWith(v);
74  n.normalize();
75  return n;
76 }
77 
78 //------------------------------------------------------------------------------
79 
80 Vector<float>& computeTriangleNormal( const PointsMultiArrayType& points, const ::fwData::Mesh::CellValueType* cell,
81  Vector<float>& n)
82 {
83  const Point& p1 = points[cell[0]];
84  const Point& p2 = points[cell[1]];
85  const Point& p3 = points[cell[2]];
86 
87  computeTriangleNormal(p1, p2, p3, n);
88  return n;
89 }
90 
91 //------------------------------------------------------------------------------
92 
93 Vector<float>& computeCellNormal( const PointsMultiArrayType& points, const ::fwData::Mesh::CellValueType* cell,
94  size_t cellSize, Vector<float>& n)
95 {
96  n = Vector<float>();
97  Vector<float> v;
98 
99  for (size_t i = 0; i < cellSize; ++i)
100  {
101  const Point& p1 = points[cell[i ]];
102  const Point& p2 = points[cell[(i+1)% cellSize]];
103  const Point& p3 = points[cell[(i+2)% cellSize]];
104 
105  computeTriangleNormal(p1, p2, p3, n);
106 
107  n += v;
108  }
109 
110  n /= ::fwTools::numericRoundCast<float>(cellSize);
111  n.normalize();
112  return n;
113 }
114 
115 //------------------------------------------------------------------------------
116 
117 void generateRegionCellNormals(::fwDataTools::helper::Mesh::sptr meshHelper, const ::fwData::Mesh::Id regionMin,
118  const ::fwData::Mesh::Id regionMax)
119 {
120  ::fwData::Mesh::csptr mesh = meshHelper->getMesh();
121  ::fwDataTools::helper::Array pointArrayHelper(mesh->getPointsArray());
122  ::fwDataTools::helper::Array cellNormalsArrayHelper(mesh->getCellNormalsArray());
123 
124  PointsMultiArrayType point = PointsMultiArrayType(
125  static_cast<PointsMultiArrayType::element*>(pointArrayHelper.getBuffer()),
126  ::boost::extents[mesh->getNumberOfPoints()]
127  );
128 
129  ::fwData::Mesh::CellTypesMultiArrayType cellTypes = meshHelper->getCellTypes();
130  ::fwData::Mesh::CellDataMultiArrayType cellData = meshHelper->getCellData();
131  ::fwData::Mesh::CellDataOffsetsMultiArrayType cellDataOffsets = meshHelper->getCellDataOffsets();
132 
133  const Vector<float> vZero;
134  ::fwData::Mesh::CellTypes type;
135  ::fwData::Mesh::CellDataOffsetType offset;
136  ::fwData::Mesh::CellValueType* cell;
137  ::fwData::Mesh::Id cellLen = 0;
138 
139  const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
140  const ::fwData::Mesh::Id cellDataSize = mesh->getCellDataSize();
141 
143  cellNormalsArrayHelper.begin< Vector< ::fwData::Mesh::NormalValueType > >();
144 
145  for(::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
146  {
147  Vector<float>& n = normals[i];
148 
149  type = cellTypes[i];
150  offset = cellDataOffsets[i];
151  cell = &cellData[offset];
152  switch (type)
153  {
154  case 0:
155  case 1:
156  case 2:
157  n = vZero;
158  break;
159  case 3:
160  {
161  computeTriangleNormal(point, cell, n);
162  }
163  break;
164  case 4:
165  case 5:
166  {
167  const ::fwData::Mesh::Id i1 = i+1;
168  cellLen = (( i1 < numberOfCells ) ? cellDataOffsets[i1] : cellDataSize) - cellDataOffsets[i];
169 
170  computeCellNormal(point, cell, cellLen, n);
171  }
172  }
173  }
174 }
175 
176 //------------------------------------------------------------------------------
177 
178 template <typename T>
179 void vectorSum( std::vector< std::vector<T> >& vectors, size_t regionMin, size_t regionMax )
180 {
181  if (vectors.empty())
182  {
183  return;
184  }
185 
186  typename std::vector< std::vector<T> >::iterator vIter = vectors.begin();
187 
188  std::vector<T>& res = vectors[0];
189 
190  for (++vIter; vIter != vectors.end(); ++vIter)
191  {
192  for (size_t i = regionMin; i < regionMax; ++i)
193  {
194  res[i] += (*vIter)[i];
195  }
196  }
197 
198 }
199 
200 //------------------------------------------------------------------------------
201 
202 void Mesh::generateCellNormals(::fwData::Mesh::sptr mesh)
203 {
204  const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
205  if(numberOfCells > 0)
206  {
207  mesh->allocateCellNormals();
208  ::fwDataTools::helper::Mesh::sptr meshHelper;
209  meshHelper = ::fwDataTools::helper::Mesh::New(mesh);
210 
211  ::fwDataTools::thread::RegionThreader rt((numberOfCells >= 200000) ? 4 : 1);
212  rt( std::bind(&generateRegionCellNormals, meshHelper, std::placeholders::_1, std::placeholders::_2),
213  numberOfCells );
214  }
215 }
216 
217 //------------------------------------------------------------------------------
218 
219 typedef std::vector< std::vector< unsigned char > > CharVectors;
220 typedef std::vector< std::vector< float > > FloatVectors;
221 
222 //------------------------------------------------------------------------------
223 
224 void generateRegionCellNormalsByPoints(FloatVectors& normalsData, CharVectors& normalCounts, size_t dataId,
225  ::fwDataTools::helper::Mesh::sptr meshHelper, const ::fwData::Mesh::Id regionMin,
226  const ::fwData::Mesh::Id regionMax)
227 {
228  ::fwData::Mesh::csptr mesh = meshHelper->getMesh();
229  FloatVectors::value_type& normalsResults = normalsData[dataId];
230  CharVectors::value_type& normalCount = normalCounts[dataId];
231 
232  const ::fwData::Mesh::Id nbOfPoints = mesh->getNumberOfPoints();
233  normalsResults.resize(3*nbOfPoints, 0.f);
234  normalCount.resize(nbOfPoints, 0);
235 
236  ::fwData::Mesh::CellTypesMultiArrayType cellTypes = meshHelper->getCellTypes();
237  ::fwData::Mesh::CellDataMultiArrayType cellData = meshHelper->getCellData();
238  ::fwData::Mesh::CellDataOffsetsMultiArrayType cellDataOffsets = meshHelper->getCellDataOffsets();
239 
240  ::fwData::Mesh::CellTypes type;
241  ::fwData::Mesh::CellDataOffsetType offset;
242  ::fwData::Mesh::CellValueType* cell;
243  ::fwData::Mesh::Id cellLen = 0;
244 
245  const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
246  const ::fwData::Mesh::Id cellDataSize = mesh->getCellDataSize();
247 
248  ::fwDataTools::helper::Array arrayHelper(mesh->getCellNormalsArray());
250  arrayHelper.begin< Vector< ::fwData::Mesh::NormalValueType > >();
252  reinterpret_cast< Vector< ::fwData::Mesh::NormalValueType >* >( &(*normalsResults.begin()));
253 
254  ::fwData::Mesh::CellValueType* pointId;
255  ::fwData::Mesh::CellValueType* cellEnd;
256 
257  for(::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
258  {
259  type = cellTypes[i];
260  offset = cellDataOffsets[i];
261  cell = &cellData[offset];
262  cellLen = type;
263 
264  switch (type)
265  {
266  case 0:
267  case 1:
268  case 2:
269  case 3:
270  case 4:
271  cellLen = type;
272  break;
273  case 5:
274  {
275  const ::fwData::Mesh::Id i1 = i+1;
276  cellLen = (( i1 < numberOfCells ) ? cellDataOffsets[i1] : cellDataSize) - cellDataOffsets[i];
277  }
278  }
279 
280  cellEnd = cell + cellLen;
281 
282  for(pointId = cell; pointId != cellEnd; ++pointId)
283  {
284  Vector< ::fwData::Mesh::NormalValueType >& res = normalResults[*pointId];
285  res += normals[i];
286  normalCount[*pointId] += 1;
287  }
288 
289  }
290 }
291 
292 //------------------------------------------------------------------------------
293 
294 void normalizeRegionCellNormalsByPoints(FloatVectors::value_type& normalsData, CharVectors::value_type& normalCount,
295  ::fwData::Mesh::sptr mesh, const ::fwData::Mesh::Id regionMin,
296  const ::fwData::Mesh::Id regionMax)
297 {
299  reinterpret_cast< Vector< ::fwData::Mesh::NormalValueType >* >( &(*normalsData.begin()) );
300 
301  ::fwDataTools::helper::Array arrayHelper(mesh->getPointNormalsArray());
303  arrayHelper.begin< Vector< ::fwData::Mesh::NormalValueType > >();
304 
305  for ( ::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
306  {
307  CharVectors::value_type::value_type count = normalCount[i];
308  normals[i] = normalSum[i];
309 
310  if(count > 1)
311  {
312  normals[i] /= count;
313  }
314  }
315 }
316 
317 //------------------------------------------------------------------------------
318 
319 void Mesh::generatePointNormals(::fwData::Mesh::sptr mesh)
320 {
321  const ::fwData::Mesh::Id nbOfPoints = mesh->getNumberOfPoints();
322  if(nbOfPoints > 0)
323  {
324  const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
325  ::fwData::Array::sptr oldCellNormals = mesh->getCellNormalsArray();
326  mesh->clearCellNormals();
327 
328  generateCellNormals(mesh);
329 
330  mesh->allocatePointNormals();
331 
332  ::fwDataTools::helper::Mesh::sptr meshHelper;
333  meshHelper = ::fwDataTools::helper::Mesh::New(mesh);
334 
335  ::fwDataTools::thread::RegionThreader rt((nbOfPoints >= 100000) ? 4 : 1);
336 
337  FloatVectors normalsData(rt.numberOfThread());
338  CharVectors normalCounts(rt.numberOfThread());
339 
340  rt( std::bind(&generateRegionCellNormalsByPoints,
341  std::ref(normalsData),
342  std::ref(normalCounts),
343  std::placeholders::_3,
344  meshHelper,
345  std::placeholders::_1,
346  std::placeholders::_2),
347  numberOfCells);
348 
349  rt( std::bind(&vectorSum<FloatVectors::value_type::value_type>,
350  std::ref(normalsData),
351  std::placeholders::_1, std::placeholders::_2),
352  nbOfPoints*3);
353 
354  rt( std::bind(&vectorSum<CharVectors::value_type::value_type>,
355  std::ref(normalCounts),
356  std::placeholders::_1, std::placeholders::_2),
357  nbOfPoints);
358 
359  rt( std::bind( &normalizeRegionCellNormalsByPoints,
360  std::ref(normalsData[0]),
361  std::ref(normalCounts[0]),
362  mesh, std::placeholders::_1, std::placeholders::_2),
363  nbOfPoints);
364 
365  meshHelper.reset();
366  mesh->setCellNormalsArray(oldCellNormals);
367  }
368 }
369 
370 //------------------------------------------------------------------------------
371 
372 template <typename T>
373 void regionShakeNormals(T normals, const ::fwData::Mesh::Id regionMin, const ::fwData::Mesh::Id regionMax)
374 {
375  RandFloat randFloat;
376  for (::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
377  {
378  Vector<float> v(randFloat(), randFloat(), randFloat());
379  normals[i] += v;
380  normals[i].normalize();
381  }
382 }
383 
384 //------------------------------------------------------------------------------
385 
386 void Mesh::shakeNormals(::fwData::Array::sptr array)
387 {
388 
389  if(array
390  && array->getType() == ::fwTools::Type::create<float>()
391  && !array->empty()
392  && array->getNumberOfComponents() == 3
393  && array->getNumberOfDimensions() == 1
394  )
395  {
396  ::fwDataTools::helper::Array arrayHelper(array);
397  void* buf;
398  buf = arrayHelper.getBuffer();
399  const ::fwData::Mesh::Id nbOfNormals = array->getSize().at(0);
400  typedef boost::multi_array_ref<Vector<float>, 1> NormalsMultiArrayType;
401  NormalsMultiArrayType normals = NormalsMultiArrayType(
402  static_cast<NormalsMultiArrayType::element*>(buf),
403  ::boost::extents[nbOfNormals]
404  );
405 
406  ::fwDataTools::thread::RegionThreader rt((nbOfNormals >= 150000) ? 4 : 1);
407  rt( std::bind(&regionShakeNormals<NormalsMultiArrayType>,
408  std::ref(normals),
409  std::placeholders::_1, std::placeholders::_2),
410  nbOfNormals);
411  }
412 }
413 
414 //------------------------------------------------------------------------------
415 
416 void Mesh::shakePointNormals(::fwData::Mesh::sptr mesh)
417 {
418  shakeNormals(mesh->getPointNormalsArray());
419 }
420 
421 //------------------------------------------------------------------------------
422 
423 void Mesh::shakeCellNormals(::fwData::Mesh::sptr mesh)
424 {
425  shakeNormals(mesh->getCellNormalsArray());
426 }
427 
428 //------------------------------------------------------------------------------
429 
430 void Mesh::colorizeMeshPoints(::fwData::Mesh::sptr mesh)
431 {
432  mesh->allocatePointColors(::fwData::Mesh::RGB);
433 
434  ::fwDataTools::helper::Mesh meshHelper(mesh);
435 
436  ::fwData::Mesh::ColorValueType color[4];
437  size_t numberOfPoints = mesh->getNumberOfPoints();
438  for(size_t i = 0; i < numberOfPoints; ++i)
439  {
440  color[0] = rand()%256;
441  color[1] = rand()%256;
442  color[2] = rand()%256;
443  meshHelper.setPointColor(i, color);
444  }
445 }
446 //------------------------------------------------------------------------------
447 
448 void Mesh::colorizeMeshCells(::fwData::Mesh::sptr mesh)
449 {
450  mesh->allocateCellColors(::fwData::Mesh::RGBA);
451 
452  ::fwDataTools::helper::Mesh meshHelper(mesh);
453 
454  ::fwData::Mesh::ColorValueType color[4];
455  size_t numberOfCells = mesh->getNumberOfCells();
456  for(size_t i = 0; i < numberOfCells; ++i)
457  {
458  color[0] = rand()%256;
459  color[1] = rand()%256;
460  color[2] = rand()%256;
461  color[3] = rand()%256;
462  meshHelper.setCellColor(i, color);
463  }
464 }
465 
466 //------------------------------------------------------------------------------
467 
468 void Mesh::shakePoint(::fwData::Mesh::sptr mesh)
469 {
470  ::fwDataTools::helper::Mesh meshHelper(mesh);
471 
472  size_t nbPts = mesh->getNumberOfPoints();
473  ::fwData::Mesh::PointsMultiArrayType points = meshHelper.getPoints();
474  RandFloat randFloat;
475  for(size_t i = 0; i < nbPts; ++i )
476  {
477  points[i][0] += randFloat()*5;
478  points[i][1] += randFloat()*5;
479  points[i][2] += randFloat()*5;
480  }
481 }
482 
483 //------------------------------------------------------------------------------
484 
485 void Mesh::transform( ::fwData::Mesh::csptr inMesh, ::fwData::Mesh::sptr outMesh,
486  ::fwData::TransformationMatrix3D::csptr t )
487 {
488  ::fwDataTools::helper::ArrayGetter arrayHelper(inMesh->getPointsArray());
489  const ::fwData::Mesh::PointValueType* inPoints = arrayHelper.begin< ::fwData::Mesh::PointValueType >();
490 
491  ::fwDataTools::helper::Array outArrayHelper(outMesh->getPointsArray());
492  ::fwData::Mesh::PointValueType* outPoints = outArrayHelper.begin< ::fwData::Mesh::PointValueType >();
493 
494  const ::glm::dmat4x4 matrix = ::fwDataTools::TransformationMatrix3D::getMatrixFromTF3D(t);
495 
496  const size_t numPts = inMesh->getNumberOfPoints();
497  SLM_ASSERT("In and out meshes should have the same number of points", numPts == outMesh->getNumberOfPoints());
498 
499  for(size_t i = 0; i < numPts; ++i )
500  {
501  const ::glm::vec4 pt(inPoints[i*3], inPoints[i*3 + 1], inPoints[i*3 + 2], 1.);
502  const ::glm::vec4 transformedPt = matrix * pt;
503 
504  outPoints[i*3] = transformedPt.x;
505  outPoints[i*3 + 1] = transformedPt.y;
506  outPoints[i*3 + 2] = transformedPt.z;
507  }
508 
509  auto pointNormalsArray = inMesh->getPointNormalsArray();
510  if(pointNormalsArray != nullptr)
511  {
512  SLM_ASSERT("in and out meshes should have the same number of points normals",
513  inMesh->getPointNormalsArray()->getSize() == outMesh->getPointNormalsArray()->getSize());
514 
515  ::fwDataTools::helper::ArrayGetter pointNormalsArrayHelper(inMesh->getPointNormalsArray());
516  const ::fwData::Mesh::NormalValueType* normals =
517  pointNormalsArrayHelper.begin< ::fwData::Mesh::NormalValueType >();
518 
519  ::fwDataTools::helper::Array outPointNormalsArrayHelper(outMesh->getPointNormalsArray());
520  ::fwData::Mesh::NormalValueType* outNormals =
521  outPointNormalsArrayHelper.begin< ::fwData::Mesh::NormalValueType >();
522 
523  for(size_t i = 0; i < numPts; ++i )
524  {
525  const ::glm::vec4 normal(normals[i*3], normals[i*3 + 1], normals[i*3 + 2], 0.);
526  const ::glm::vec4 transformedNormal = ::glm::normalize(matrix * normal);
527 
528  outNormals[i*3] = transformedNormal.x;
529  outNormals[i*3 + 1] = transformedNormal.y;
530  outNormals[i*3 + 2] = transformedNormal.z;
531  }
532  }
533 
534  auto cellNormalsArray = inMesh->getCellNormalsArray();
535  if(cellNormalsArray != nullptr)
536  {
537  SLM_ASSERT("in and out meshes should have the same number of cells normals",
538  inMesh->getPointNormalsArray()->getSize() == outMesh->getPointNormalsArray()->getSize());
539 
540  ::fwDataTools::helper::ArrayGetter cellNormalsArrayHelper(inMesh->getCellNormalsArray());
541  const ::fwData::Mesh::NormalValueType* normals =
542  cellNormalsArrayHelper.begin< ::fwData::Mesh::NormalValueType >();
543 
544  ::fwDataTools::helper::Array outCellNormalsArrayHelper(outMesh->getCellNormalsArray());
545  ::fwData::Mesh::NormalValueType* outNormals =
546  outCellNormalsArrayHelper.begin< ::fwData::Mesh::NormalValueType >();
547 
548  for(size_t i = 0; i < numPts; ++i )
549  {
550  const ::glm::vec4 normal(normals[i*3], normals[i*3 + 1], normals[i*3 + 2], 0.);
551  const ::glm::vec4 transformedNormal = ::glm::normalize(matrix * normal);
552 
553  outNormals[i*3] = transformedNormal.x;
554  outNormals[i*3 + 1] = transformedNormal.y;
555  outNormals[i*3 + 2] = transformedNormal.z;
556  }
557  }
558 }
559 
560 //------------------------------------------------------------------------------
561 
562 void Mesh::transform( ::fwData::Mesh::sptr mesh, ::fwData::TransformationMatrix3D::csptr t )
563 {
564  Mesh::transform(mesh, mesh, t);
565 }
566 
567 //------------------------------------------------------------------------------
568 
569 void Mesh::colorizeMeshPoints( const ::fwData::Mesh::sptr& mesh, const std::uint8_t colorR, const std::uint8_t colorG,
570  const std::uint8_t colorB, const std::uint8_t colorA)
571 {
572  ::fwData::Array::sptr itemColors = mesh->getPointColorsArray();
573  SLM_ASSERT("color array must be allocated", itemColors);
574 
575  if ( itemColors && itemColors->getBufferObject() )
576  {
577  ::fwDataTools::helper::Array hArray( itemColors );
578 
579  ::fwData::Mesh::ColorValueType* itemColorsBuffer = hArray.begin< ::fwData::Mesh::ColorValueType >();
580 
581  fwData::Array::SizeType arraySize = itemColors->getSize();
582 
583  const size_t nbrVertex = arraySize[0];
584 
585  const size_t nbComponents = itemColors->getNumberOfComponents();
586 
587  for (size_t numVertex = 0; numVertex < nbrVertex; ++numVertex)
588  {
589  itemColorsBuffer[numVertex * nbComponents + 0] = colorR;
590  itemColorsBuffer[numVertex * nbComponents + 1] = colorG;
591  itemColorsBuffer[numVertex * nbComponents + 2] = colorB;
592  if (nbComponents == 4)
593  {
594  itemColorsBuffer[numVertex * nbComponents + 3] = colorA;
595  }
596  }
597  }
598  ::fwData::Mesh::PointColorsModifiedSignalType::sptr sig;
599  sig = mesh->signal< ::fwData::Mesh::PointColorsModifiedSignalType >(
601  sig->asyncEmit();
602 }
603 
604 //-----------------------------------------------------------------------------
605 
606 void Mesh::colorizeMeshPoints( const ::fwData::Mesh::sptr& _mesh, const std::vector< size_t >& _vectorNumTriangle,
607  const std::uint8_t _colorR, const std::uint8_t _colorG, const std::uint8_t _colorB,
608  const std::uint8_t _colorA)
609 {
610  ::fwDataTools::helper::ArrayGetter helperCells(_mesh->getCellDataArray());
611  const ::fwData::Mesh::CellValueType* cellsMesh = helperCells.begin< ::fwData::Mesh::CellValueType >();
612 
613  ::fwData::Array::sptr itemColors = _mesh->getPointColorsArray();
614  SLM_ASSERT("color array must be allocated", itemColors);
615 
616  ::fwDataTools::helper::Array hArray( itemColors );
617 
618  ::fwData::Mesh::ColorValueType* itemColorsBuffer =
619  static_cast< ::fwData::Mesh::ColorValueType* >( hArray.getBuffer() );
620 
621  const size_t nbrTriangle = _vectorNumTriangle.size();
622  const size_t nbComponents = itemColors->getNumberOfComponents();
623 
624  for (size_t numTriangle = 0; numTriangle < nbrTriangle; ++numTriangle)
625  {
626  const size_t indiceTriangle = _vectorNumTriangle[numTriangle];
627 
628  const size_t indexPoint0 = cellsMesh[indiceTriangle * 3 + 0];
629  const size_t indexPoint1 = cellsMesh[indiceTriangle * 3 + 1];
630  const size_t indexPoint2 = cellsMesh[indiceTriangle * 3 + 2];
631 
632  itemColorsBuffer[indexPoint0 * nbComponents + 0] = _colorR;
633  itemColorsBuffer[indexPoint0 * nbComponents + 1] = _colorG;
634  itemColorsBuffer[indexPoint0 * nbComponents + 2] = _colorB;
635 
636  itemColorsBuffer[indexPoint1 * nbComponents + 0] = _colorR;
637  itemColorsBuffer[indexPoint1 * nbComponents + 1] = _colorG;
638  itemColorsBuffer[indexPoint1 * nbComponents + 2] = _colorB;
639 
640  itemColorsBuffer[indexPoint2 * nbComponents + 0] = _colorR;
641  itemColorsBuffer[indexPoint2 * nbComponents + 1] = _colorG;
642  itemColorsBuffer[indexPoint2 * nbComponents + 2] = _colorB;
643 
644  if (nbComponents == 4)
645  {
646  itemColorsBuffer[indexPoint0 * nbComponents + 3] = _colorA;
647  itemColorsBuffer[indexPoint1 * nbComponents + 3] = _colorA;
648  itemColorsBuffer[indexPoint2 * nbComponents + 3] = _colorA;
649  }
650  }
651  ::fwData::Mesh::PointColorsModifiedSignalType::sptr sig;
652  sig = _mesh->signal< ::fwData::Mesh::PointColorsModifiedSignalType >(
654  sig->asyncEmit();
655 }
656 
657 //-----------------------------------------------------------------------------
658 
660  const ::fwData::Mesh::sptr& mesh,
661  const std::uint8_t colorR,
662  const std::uint8_t colorG,
663  const std::uint8_t colorB,
664  const std::uint8_t colorA)
665 {
666  ::fwData::Array::sptr itemColors = mesh->getCellColorsArray();
667  SLM_ASSERT("color array must be allocated", itemColors);
668 
669  ::fwDataTools::helper::Array hArray( itemColors );
670 
671  ::fwData::Mesh::ColorValueType* itemColorsBuffer =
672  static_cast< ::fwData::Mesh::ColorValueType* >( hArray.getBuffer() );
673 
674  size_t triangleNbr = mesh->getNumberOfCells();
675  const size_t nbComponents = itemColors->getNumberOfComponents();
676 
677  for (size_t triangleNum = 0; triangleNum < triangleNbr; ++triangleNum)
678  {
679  itemColorsBuffer[triangleNum * nbComponents + 0] = colorR;
680  itemColorsBuffer[triangleNum * nbComponents + 1] = colorG;
681  itemColorsBuffer[triangleNum * nbComponents + 2] = colorB;
682  if (nbComponents == 4)
683  {
684  itemColorsBuffer[triangleNum * nbComponents + 3] = colorA;
685  }
686  }
687 
688  ::fwData::Mesh::CellColorsModifiedSignalType::sptr sig;
689  sig = mesh->signal< ::fwData::Mesh::CellColorsModifiedSignalType >(
691  sig->asyncEmit();
692 }
693 
694 //------------------------------------------------------------------------------
695 
697  const ::fwData::Mesh::sptr& mesh,
698  const std::vector < size_t >& triangleIndexVector,
699  const std::uint8_t colorR,
700  const std::uint8_t colorG,
701  const std::uint8_t colorB,
702  const std::uint8_t colorA)
703 {
704  ::fwData::Array::sptr itemColors = mesh->getCellColorsArray();
705  SLM_ASSERT("color array must be allocated", itemColors);
706 
707  ::fwDataTools::helper::Array hArray( itemColors );
708 
709  ::fwData::Mesh::ColorValueType* itemColorsBuffer =
710  static_cast< ::fwData::Mesh::ColorValueType* >( hArray.getBuffer() );
711 
712  const size_t triangleNbr = triangleIndexVector.size();
713  const size_t nbComponents = itemColors->getNumberOfComponents();
714 
715  for (size_t triangleNum = 0; triangleNum < triangleNbr; ++triangleNum)
716  {
717  const size_t triangleIndex = triangleIndexVector[triangleNum];
718  itemColorsBuffer[triangleIndex * nbComponents + 0] = colorR;
719  itemColorsBuffer[triangleIndex * nbComponents + 1] = colorG;
720  itemColorsBuffer[triangleIndex * nbComponents + 2] = colorB;
721  if (nbComponents == 4)
722  {
723  itemColorsBuffer[triangleIndex * nbComponents + 3] = colorA;
724  }
725  }
726 
727  ::fwData::Mesh::CellColorsModifiedSignalType::sptr sig;
728  sig = mesh->signal< ::fwData::Mesh::CellColorsModifiedSignalType >(
730  sig->asyncEmit();
731 }
732 //------------------------------------------------------------------------------
733 
734 } // namespace fwDataTools
static FWDATATOOLS_API void shakeCellNormals(::fwData::Mesh::sptr mesh)
Shake cell Normals.
std::vector< size_t > SizeType
Array size type.
static FWDATATOOLS_API void shakePointNormals(::fwData::Mesh::sptr mesh)
Shake point Normals.
static FWDATATOOLS_API void generateCellNormals(::fwData::Mesh::sptr mesh)
Generate cell normals for the mesh.
The namespace fwDataTools contains classes which provide helpers to manipulate fwData::Object. *.
static FWDATATOOLS_API void shakeNormals(::fwData::Array::sptr array)
Shake Array of Normals.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CELL_COLORS_MODIFIED_SIG
Key in m_signals map of signal m_sigCellColorsModified.
FWDATATOOLS_API void setCellColor(::fwData::Mesh::Id id, const ::fwData::Mesh::ColorValueType c[4])
Set a cell color.
virtual FWDATATOOLS_API void * getBuffer()
Getter for the array buffer.
FWDATATOOLS_API::fwData::Mesh::ConstCellTypesMultiArrayType getCellTypes() const
Returns the internal corresponding array as a boost::multi_array_ref.
Definition: MeshGetter.cpp:87
static FWDATATOOLS_API void colorizeMeshCells(::fwData::Mesh::sptr mesh)
Colorize mesh (cell color).
virtual FWDATATOOLS_API const char * begin() const
Returns the begining/end of the buffer interpreted as a char buffer.
Definition: ArrayGetter.cpp:37
static FWDATATOOLS_API void generatePointNormals(::fwData::Mesh::sptr mesh)
Generate point normals for the mesh.
FWDATATOOLS_API::fwData::Mesh::PointsMultiArrayType getPoints() const
Returns the internal corresponding array as a boost::multi_array_ref.
Helper to manage array buffer. Lock the buffer before to modify it.
Definition: ArrayGetter.hpp:28
virtual FWDATATOOLS_API char * begin()
Returns the begining/end of the buffer interpreted as a char buffer.
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
static FWDATATOOLS_API void transform(fwData::Mesh::csptr inMesh,::fwData::Mesh::sptr outMesh,::fwData::TransformationMatrix3D::csptr t)
Apply a transformation 4x4 from an input mesh to an output mesh.
static FWDATATOOLS_API::glm::dmat4x4 getMatrixFromTF3D(const ::fwData::TransformationMatrix3D::csptr &_trf)
Convert a fwData::TransformationMatrix3D into a GLM matrix.
static FWDATATOOLS_API void initRand()
Initialize &#39;rand&#39; seed.
static FWDATATOOLS_API void shakePoint(::fwData::Mesh::sptr mesh)
Shake points of the mesh.
static FWDATATOOLS_API void colorizeMeshPoints(::fwData::Mesh::sptr mesh)
Colorize mesh (vertex point color).
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.
static FWDATATOOLS_API bool hasUniqueCellType(::fwData::Mesh::csptr mesh,::fwData::Mesh::CellTypes cell)
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_COLORS_MODIFIED_SIG
Key in m_signals map of signal m_sigPointColorsModified.
Helper to manage Mesh. Lock the mesh buffer before to modify it.