(Mesh): improve the API of ::fwData::Mesh
What does this MR do?
Refactor the mesh API:
- deprecate the access to the points, cells and other arrays
- rename allocate method to reserve
- allow to allocate the color, normal and texture arrays in the same reserve method
- add resize method to allocate the memory and set the number of points and cells
- add iterator to iterate through the points and cells
Allocation:
The two methods reserve()
and resize()
allow to allocate the mesh arrays. The difference between the two methods is
that resize modify the number of points and cells.
-
pushPoint()
andpushCell()
methods allow to add new points or cells, it increments the number of points and allocate the memory if needed. -
setPoint()
andsetCell()
methods allow to change the value in a given index.
Example with resize()
, setPoint()
and setCell()
:
::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
mesh->resize(NB_POINTS, NB_CELLS, CELL_TYPE, EXTRA_ARRAY);
const auto lock = mesh->lock();
for (size_t i = 0; i < NB_POINTS; ++i)
{
const std::uint8_t val = static_cast<uint8_t>(i);
const ::fwData::Mesh::ColorValueType color[4] = {val, val, val, val};
const float floatVal = static_cast<float>(i);
const ::fwData::Mesh::NormalValueType normal[3] = {floatVal, floatVal, floatVal};
const ::fwData::Mesh::TexCoordValueType texCoords[2] = {floatVal, floatVal};
const size_t value = 3*i;
mesh->setPoint(i, static_cast<float>(value), static_cast<float>(value+1), static_cast<float>(value+2));
mesh->setPointColor(i, color);
mesh->setPointNormal(i, normal);
mesh->setPointTexCoord(i, texCoords);
}
for (size_t i = 0; i < NB_CELLS; ++i)
{
mesh->setCell(i, i, i+1, i+2);
const ::fwData::Mesh::ColorValueType val = static_cast< ::fwData::Mesh::ColorValueType >(i);
const ::fwData::Mesh::ColorValueType color[4] = {val, val, val, val};
const float floatVal = static_cast<float>(i);
const ::fwData::Mesh::NormalValueType normal[3] = {floatVal, floatVal, floatVal};
const ::fwData::Mesh::TexCoordValueType texCoords[2] = {floatVal, floatVal};
mesh->setCellColor(i, color);
mesh->setCellNormal(i, normal);
mesh->setCellTexCoord(i, texCoords);
}
Example with reseve()
, pushPoint()
and pushCell()
::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
mesh->reserve(NB_POINTS, NB_CELLS, CELL_TYPE, EXTRA_ARRAY);
const auto lock = mesh->lock();
for (size_t i = 0; i < NB_POINTS; ++i)
{
const std::uint8_t val = static_cast<uint8_t>(i);
const ::fwData::Mesh::ColorValueType color[4] = {val, val, val, val};
const float floatVal = static_cast<float>(i);
const ::fwData::Mesh::NormalValueType normal[3] = {floatVal, floatVal, floatVal};
const ::fwData::Mesh::TexCoordValueType texCoords[2] = {floatVal, floatVal};
const size_t value = 3*i;
const auto id =
mesh->pushPoint(static_cast<float>(value), static_cast<float>(value+1), static_cast<float>(value+2));
mesh->setPointColor(id, color);
mesh->setPointNormal(id, normal);
mesh->setPointTexCoord(id, texCoords);
}
for (size_t i = 0; i < NB_CELLS; ++i)
{
const auto id = mesh->pushCell(i, i+1, i+2);
const ::fwData::Mesh::ColorValueType val = static_cast< ::fwData::Mesh::ColorValueType >(i);
const ::fwData::Mesh::ColorValueType color[4] = {val, val, val, val};
const float floatVal = static_cast<float>(i);
const ::fwData::Mesh::NormalValueType normal[3] = {floatVal, floatVal, floatVal};
const ::fwData::Mesh::TexCoordValueType texCoords[2] = {floatVal, floatVal};
mesh->setCellColor(id, color);
mesh->setCellNormal(id, normal);
mesh->setCellTexCoord(id, texCoords);
}
Iterators
To access the mesh points and cells, you should uses the following iterators:
- ::fwData::iterator::PointIterator: to iterate through mesh points
- ::fwData::iterator::ConstPointIterator: to iterate through mesh points read-only
- ::fwData::iterator::CellIterator: to iterate through mesh cells
- ::fwData::iterator::ConstCellIterator: to iterate through mesh cells read-only
Example to iterate through points:
::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
mesh->resize(25, 33, ::fwData::Mesh::TRIANGLE);
auto iter = mesh->begin< ::fwData::iterator::PointIterator >();
const auto iterEnd = mesh->end< ::fwData::iterator::PointIterator >();
float p[3] = {12.f, 16.f, 18.f};
for (; iter != iterEnd; ++iter)
{
iter->point->x = p[0];
iter->point->y = p[1];
iter->point->z = p[2];
}
Example to iterate through cells:
::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
mesh->resize(25, 33, ::fwData::Mesh::TRIANGLE);
auto iter = mesh->begin< ::fwData::iterator::ConstCellIterator >();
const auto endItr = mesh->end< ::fwData::iterator::ConstCellIterator >();
auto itrPt = mesh->begin< ::fwData::iterator::ConstPointIterator >();
float p[3];
for(; iter != endItr; ++iter)
{
const auto nbPoints = iter->nbPoints;
for(size_t i = 0 ; i < nbPoints ; ++i)
{
auto pIdx = static_cast< ::fwData::iterator::ConstCellIterator::difference_type >(iter->pointIdx[i]);
::fwData::iterator::ConstPointIterator pointItr(itrPt + pIdx);
p[0] = pointItr->point->x;
p[1] = pointItr->point->y;
p[2] = pointItr->point->z;
}
}
pushCell()
and setCell()
may not be very efficient, you can use CellIterator
to define the cell. But take care to
properly define all the cell attribute.
Example of defining cells usign iterators
::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
mesh->resize(25, 33, ::fwData::Mesh::QUAD);
auto it = mesh->begin< ::fwData::iterator::CellIterator >();
const auto itEnd = mesh->end< ::fwData::iterator::CellIterator >();
const auto cellType = ::fwData::Mesh::QUAD;
const size_t nbPointPerCell = 4;
size_t count = 0;
for (; it != itEnd; ++it)
{
// define the cell type and cell offset
(*it->type) = cellType;
(*it->offset) = nbPointPerCell*count;
// /!\ define the next offset to be able to iterate through point indices
if (it != itEnd-1)
{
(*(it+1)->offset) = nbPointPerCell*(count+1);
}
// define the point indices
for (size_t i = 0; i < 4; ++i)
{
::fwData::Mesh::CellValueType ptIdx = val;
it->pointIdx[i] = ptIdx;
}
}
How to test it?
Launch the unit tests and some applications
Some results
nbPoints: 100002
nbCells: 100000 Triangles
Point iterator | Cell iterator | const cell iterator | |
---|---|---|---|
Linux(Debug) | 1.2ms | 59.8ms | 60.3333ms |
Linux(Release) | 0.666667ms | 59ms | 59.8667ms |
Associated Issues/Merge Requests
- Issues
- Fixes #66 (closed)