7 #include "fwDataTools/Mesh.hpp" 9 #include "fwDataTools/helper/ArrayGetter.hpp" 10 #include "fwDataTools/helper/MeshGetter.hpp" 11 #include "fwDataTools/thread/RegionThreader.hpp" 12 #include "fwDataTools/TransformationMatrix3D.hpp" 14 #include <fwTools/NumericRoundCast.hxx> 16 #include <glm/mat4x4.hpp> 17 #include <glm/vec3.hpp> 18 #include <glm/vec4.hpp> 34 return ((rand() % 101 - 50.f)) / 500.f;
42 std::srand(::fwTools::numericRoundCast<unsigned int>(std::time(NULL)));
51 ::fwData::Mesh::ConstCellTypesMultiArrayType cellTypes = meshHelper.
getCellTypes();
53 for(::fwData::Mesh::CellTypes type : cellTypes)
65 typedef boost::multi_array_ref<Point, 1> PointsMultiArrayType;
80 Vector<float>& computeTriangleNormal(
const PointsMultiArrayType& points, const ::fwData::Mesh::CellValueType* cell,
83 const Point& p1 = points[cell[0]];
84 const Point& p2 = points[cell[1]];
85 const Point& p3 = points[cell[2]];
87 computeTriangleNormal(p1, p2, p3, n);
93 Vector<float>& computeCellNormal(
const PointsMultiArrayType& points, const ::fwData::Mesh::CellValueType* cell,
99 for (
size_t i = 0; i < cellSize; ++i)
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]];
105 computeTriangleNormal(p1, p2, p3, n);
110 n /= ::fwTools::numericRoundCast<float>(cellSize);
117 void generateRegionCellNormals(::fwDataTools::helper::Mesh::sptr meshHelper, const ::fwData::Mesh::Id regionMin,
118 const ::fwData::Mesh::Id regionMax)
120 ::fwData::Mesh::csptr mesh = meshHelper->getMesh();
124 PointsMultiArrayType
point = PointsMultiArrayType(
125 static_cast<PointsMultiArrayType::element*>(pointArrayHelper.getBuffer()),
126 ::boost::extents[mesh->getNumberOfPoints()]
129 ::fwData::Mesh::CellTypesMultiArrayType cellTypes = meshHelper->getCellTypes();
130 ::fwData::Mesh::CellDataMultiArrayType cellData = meshHelper->getCellData();
131 ::fwData::Mesh::CellDataOffsetsMultiArrayType cellDataOffsets = meshHelper->getCellDataOffsets();
134 ::fwData::Mesh::CellTypes type;
135 ::fwData::Mesh::CellDataOffsetType offset;
136 ::fwData::Mesh::CellValueType* cell;
137 ::fwData::Mesh::Id cellLen = 0;
139 const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
140 const ::fwData::Mesh::Id cellDataSize = mesh->getCellDataSize();
145 for(::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
150 offset = cellDataOffsets[i];
151 cell = &cellData[offset];
161 computeTriangleNormal(point, cell, n);
167 const ::fwData::Mesh::Id i1 = i+1;
168 cellLen = (( i1 < numberOfCells ) ? cellDataOffsets[i1] : cellDataSize) - cellDataOffsets[i];
170 computeCellNormal(point, cell, cellLen, n);
178 template <
typename T>
179 void vectorSum( std::vector< std::vector<T> >& vectors,
size_t regionMin,
size_t regionMax )
186 typename std::vector< std::vector<T> >::iterator vIter = vectors.begin();
188 std::vector<T>& res = vectors[0];
190 for (++vIter; vIter != vectors.end(); ++vIter)
192 for (
size_t i = regionMin; i < regionMax; ++i)
194 res[i] += (*vIter)[i];
204 const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
205 if(numberOfCells > 0)
207 mesh->allocateCellNormals();
208 ::fwDataTools::helper::Mesh::sptr meshHelper;
209 meshHelper = ::fwDataTools::helper::Mesh::New(mesh);
212 rt( std::bind(&generateRegionCellNormals, meshHelper, std::placeholders::_1, std::placeholders::_2),
219 typedef std::vector< std::vector< unsigned char > > CharVectors;
220 typedef std::vector< std::vector< float > > FloatVectors;
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)
228 ::fwData::Mesh::csptr mesh = meshHelper->getMesh();
229 FloatVectors::value_type& normalsResults = normalsData[dataId];
230 CharVectors::value_type& normalCount = normalCounts[dataId];
232 const ::fwData::Mesh::Id nbOfPoints = mesh->getNumberOfPoints();
233 normalsResults.resize(3*nbOfPoints, 0.f);
234 normalCount.resize(nbOfPoints, 0);
236 ::fwData::Mesh::CellTypesMultiArrayType cellTypes = meshHelper->getCellTypes();
237 ::fwData::Mesh::CellDataMultiArrayType cellData = meshHelper->getCellData();
238 ::fwData::Mesh::CellDataOffsetsMultiArrayType cellDataOffsets = meshHelper->getCellDataOffsets();
240 ::fwData::Mesh::CellTypes type;
241 ::fwData::Mesh::CellDataOffsetType offset;
242 ::fwData::Mesh::CellValueType* cell;
243 ::fwData::Mesh::Id cellLen = 0;
245 const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
246 const ::fwData::Mesh::Id cellDataSize = mesh->getCellDataSize();
254 ::fwData::Mesh::CellValueType* pointId;
255 ::fwData::Mesh::CellValueType* cellEnd;
257 for(::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
260 offset = cellDataOffsets[i];
261 cell = &cellData[offset];
275 const ::fwData::Mesh::Id i1 = i+1;
276 cellLen = (( i1 < numberOfCells ) ? cellDataOffsets[i1] : cellDataSize) - cellDataOffsets[i];
280 cellEnd = cell + cellLen;
282 for(pointId = cell; pointId != cellEnd; ++pointId)
286 normalCount[*pointId] += 1;
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)
305 for ( ::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
307 CharVectors::value_type::value_type count = normalCount[i];
308 normals[i] = normalSum[i];
321 const ::fwData::Mesh::Id nbOfPoints = mesh->getNumberOfPoints();
324 const ::fwData::Mesh::Id numberOfCells = mesh->getNumberOfCells();
325 ::fwData::Array::sptr oldCellNormals = mesh->getCellNormalsArray();
326 mesh->clearCellNormals();
328 generateCellNormals(mesh);
330 mesh->allocatePointNormals();
332 ::fwDataTools::helper::Mesh::sptr meshHelper;
333 meshHelper = ::fwDataTools::helper::Mesh::New(mesh);
337 FloatVectors normalsData(rt.numberOfThread());
338 CharVectors normalCounts(rt.numberOfThread());
340 rt( std::bind(&generateRegionCellNormalsByPoints,
341 std::ref(normalsData),
342 std::ref(normalCounts),
343 std::placeholders::_3,
345 std::placeholders::_1,
346 std::placeholders::_2),
349 rt( std::bind(&vectorSum<FloatVectors::value_type::value_type>,
350 std::ref(normalsData),
351 std::placeholders::_1, std::placeholders::_2),
354 rt( std::bind(&vectorSum<CharVectors::value_type::value_type>,
355 std::ref(normalCounts),
356 std::placeholders::_1, std::placeholders::_2),
359 rt( std::bind( &normalizeRegionCellNormalsByPoints,
360 std::ref(normalsData[0]),
361 std::ref(normalCounts[0]),
362 mesh, std::placeholders::_1, std::placeholders::_2),
366 mesh->setCellNormalsArray(oldCellNormals);
372 template <
typename T>
373 void regionShakeNormals(T normals, const ::fwData::Mesh::Id regionMin, const ::fwData::Mesh::Id regionMax)
376 for (::fwData::Mesh::Id i = regionMin; i < regionMax; ++i)
380 normals[i].normalize();
390 && array->getType() == ::fwTools::Type::create<float>()
392 && array->getNumberOfComponents() == 3
393 && array->getNumberOfDimensions() == 1
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]
407 rt( std::bind(®ionShakeNormals<NormalsMultiArrayType>,
409 std::placeholders::_1, std::placeholders::_2),
418 shakeNormals(mesh->getPointNormalsArray());
425 shakeNormals(mesh->getCellNormalsArray());
432 mesh->allocatePointColors(::fwData::Mesh::RGB);
436 ::fwData::Mesh::ColorValueType color[4];
437 size_t numberOfPoints = mesh->getNumberOfPoints();
438 for(
size_t i = 0; i < numberOfPoints; ++i)
440 color[0] = rand()%256;
441 color[1] = rand()%256;
442 color[2] = rand()%256;
450 mesh->allocateCellColors(::fwData::Mesh::RGBA);
454 ::fwData::Mesh::ColorValueType color[4];
455 size_t numberOfCells = mesh->getNumberOfCells();
456 for(
size_t i = 0; i < numberOfCells; ++i)
458 color[0] = rand()%256;
459 color[1] = rand()%256;
460 color[2] = rand()%256;
461 color[3] = rand()%256;
472 size_t nbPts = mesh->getNumberOfPoints();
473 ::fwData::Mesh::PointsMultiArrayType points = meshHelper.
getPoints();
475 for(
size_t i = 0; i < nbPts; ++i )
477 points[i][0] += randFloat()*5;
478 points[i][1] += randFloat()*5;
479 points[i][2] += randFloat()*5;
485 void Mesh::transform( ::fwData::Mesh::csptr inMesh, ::fwData::Mesh::sptr outMesh,
486 ::fwData::TransformationMatrix3D::csptr t )
489 const ::fwData::Mesh::PointValueType* inPoints = arrayHelper.
begin< ::fwData::Mesh::PointValueType >();
492 ::fwData::Mesh::PointValueType* outPoints = outArrayHelper.
begin< ::fwData::Mesh::PointValueType >();
496 const size_t numPts = inMesh->getNumberOfPoints();
497 SLM_ASSERT(
"In and out meshes should have the same number of points", numPts == outMesh->getNumberOfPoints());
499 for(
size_t i = 0; i < numPts; ++i )
501 const ::glm::vec4 pt(inPoints[i*3], inPoints[i*3 + 1], inPoints[i*3 + 2], 1.);
502 const ::glm::vec4 transformedPt = matrix * pt;
504 outPoints[i*3] = transformedPt.x;
505 outPoints[i*3 + 1] = transformedPt.y;
506 outPoints[i*3 + 2] = transformedPt.z;
509 auto pointNormalsArray = inMesh->getPointNormalsArray();
510 if(pointNormalsArray !=
nullptr)
512 SLM_ASSERT(
"in and out meshes should have the same number of points normals",
513 inMesh->getPointNormalsArray()->getSize() == outMesh->getPointNormalsArray()->getSize());
516 const ::fwData::Mesh::NormalValueType* normals =
517 pointNormalsArrayHelper.
begin< ::fwData::Mesh::NormalValueType >();
520 ::fwData::Mesh::NormalValueType* outNormals =
521 outPointNormalsArrayHelper.
begin< ::fwData::Mesh::NormalValueType >();
523 for(
size_t i = 0; i < numPts; ++i )
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);
528 outNormals[i*3] = transformedNormal.x;
529 outNormals[i*3 + 1] = transformedNormal.y;
530 outNormals[i*3 + 2] = transformedNormal.z;
534 auto cellNormalsArray = inMesh->getCellNormalsArray();
535 if(cellNormalsArray !=
nullptr)
537 SLM_ASSERT(
"in and out meshes should have the same number of cells normals",
538 inMesh->getPointNormalsArray()->getSize() == outMesh->getPointNormalsArray()->getSize());
541 const ::fwData::Mesh::NormalValueType* normals =
542 cellNormalsArrayHelper.
begin< ::fwData::Mesh::NormalValueType >();
545 ::fwData::Mesh::NormalValueType* outNormals =
546 outCellNormalsArrayHelper.
begin< ::fwData::Mesh::NormalValueType >();
548 for(
size_t i = 0; i < numPts; ++i )
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);
553 outNormals[i*3] = transformedNormal.x;
554 outNormals[i*3 + 1] = transformedNormal.y;
555 outNormals[i*3 + 2] = transformedNormal.z;
562 void Mesh::transform( ::fwData::Mesh::sptr mesh, ::fwData::TransformationMatrix3D::csptr t )
570 const std::uint8_t colorB,
const std::uint8_t colorA)
572 ::fwData::Array::sptr itemColors = mesh->getPointColorsArray();
573 SLM_ASSERT(
"color array must be allocated", itemColors);
575 if ( itemColors && itemColors->getBufferObject() )
579 ::fwData::Mesh::ColorValueType* itemColorsBuffer = hArray.
begin< ::fwData::Mesh::ColorValueType >();
583 const size_t nbrVertex = arraySize[0];
585 const size_t nbComponents = itemColors->getNumberOfComponents();
587 for (
size_t numVertex = 0; numVertex < nbrVertex; ++numVertex)
589 itemColorsBuffer[numVertex * nbComponents + 0] = colorR;
590 itemColorsBuffer[numVertex * nbComponents + 1] = colorG;
591 itemColorsBuffer[numVertex * nbComponents + 2] = colorB;
592 if (nbComponents == 4)
594 itemColorsBuffer[numVertex * nbComponents + 3] = colorA;
598 ::fwData::Mesh::PointColorsModifiedSignalType::sptr sig;
607 const std::uint8_t _colorR,
const std::uint8_t _colorG,
const std::uint8_t _colorB,
608 const std::uint8_t _colorA)
611 const ::fwData::Mesh::CellValueType* cellsMesh = helperCells.
begin< ::fwData::Mesh::CellValueType >();
613 ::fwData::Array::sptr itemColors = _mesh->getPointColorsArray();
614 SLM_ASSERT(
"color array must be allocated", itemColors);
618 ::fwData::Mesh::ColorValueType* itemColorsBuffer =
619 static_cast< ::fwData::Mesh::ColorValueType*
>( hArray.
getBuffer() );
621 const size_t nbrTriangle = _vectorNumTriangle.size();
622 const size_t nbComponents = itemColors->getNumberOfComponents();
624 for (
size_t numTriangle = 0; numTriangle < nbrTriangle; ++numTriangle)
626 const size_t indiceTriangle = _vectorNumTriangle[numTriangle];
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];
632 itemColorsBuffer[indexPoint0 * nbComponents + 0] = _colorR;
633 itemColorsBuffer[indexPoint0 * nbComponents + 1] = _colorG;
634 itemColorsBuffer[indexPoint0 * nbComponents + 2] = _colorB;
636 itemColorsBuffer[indexPoint1 * nbComponents + 0] = _colorR;
637 itemColorsBuffer[indexPoint1 * nbComponents + 1] = _colorG;
638 itemColorsBuffer[indexPoint1 * nbComponents + 2] = _colorB;
640 itemColorsBuffer[indexPoint2 * nbComponents + 0] = _colorR;
641 itemColorsBuffer[indexPoint2 * nbComponents + 1] = _colorG;
642 itemColorsBuffer[indexPoint2 * nbComponents + 2] = _colorB;
644 if (nbComponents == 4)
646 itemColorsBuffer[indexPoint0 * nbComponents + 3] = _colorA;
647 itemColorsBuffer[indexPoint1 * nbComponents + 3] = _colorA;
648 itemColorsBuffer[indexPoint2 * nbComponents + 3] = _colorA;
651 ::fwData::Mesh::PointColorsModifiedSignalType::sptr sig;
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)
666 ::fwData::Array::sptr itemColors = mesh->getCellColorsArray();
667 SLM_ASSERT(
"color array must be allocated", itemColors);
671 ::fwData::Mesh::ColorValueType* itemColorsBuffer =
672 static_cast< ::fwData::Mesh::ColorValueType*
>( hArray.
getBuffer() );
674 size_t triangleNbr = mesh->getNumberOfCells();
675 const size_t nbComponents = itemColors->getNumberOfComponents();
677 for (
size_t triangleNum = 0; triangleNum < triangleNbr; ++triangleNum)
679 itemColorsBuffer[triangleNum * nbComponents + 0] = colorR;
680 itemColorsBuffer[triangleNum * nbComponents + 1] = colorG;
681 itemColorsBuffer[triangleNum * nbComponents + 2] = colorB;
682 if (nbComponents == 4)
684 itemColorsBuffer[triangleNum * nbComponents + 3] = colorA;
688 ::fwData::Mesh::CellColorsModifiedSignalType::sptr sig;
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)
704 ::fwData::Array::sptr itemColors = mesh->getCellColorsArray();
705 SLM_ASSERT(
"color array must be allocated", itemColors);
709 ::fwData::Mesh::ColorValueType* itemColorsBuffer =
710 static_cast< ::fwData::Mesh::ColorValueType*
>( hArray.
getBuffer() );
712 const size_t triangleNbr = triangleIndexVector.size();
713 const size_t nbComponents = itemColors->getNumberOfComponents();
715 for (
size_t triangleNum = 0; triangleNum < triangleNbr; ++triangleNum)
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)
723 itemColorsBuffer[triangleIndex * nbComponents + 3] = colorA;
727 ::fwData::Mesh::CellColorsModifiedSignalType::sptr sig;
std::vector< size_t > SizeType
Array size type.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CELL_COLORS_MODIFIED_SIG
Key in m_signals map of signal m_sigCellColorsModified.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_COLORS_MODIFIED_SIG
Key in m_signals map of signal m_sigPointColorsModified.