fw4spl
core/fwDataTools/src/fwDataTools/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 "fwDataTools/helper/Mesh.hpp"
8 
9 #include <fwMath/MeshFunctions.hpp>
10 
11 #include <boost/assign/list_of.hpp>
12 
13 using namespace boost::assign;
14 
15 namespace fwDataTools
16 {
17 
18 namespace helper
19 {
20 
21 #define POINT_REALLOC_STEP 1000
22 #define CELL_REALLOC_STEP 1000
23 #define CELLDATA_REALLOC_STEP 1000
24 
25 Mesh::Mesh( ::fwData::Mesh::sptr mesh ) :
26  m_mesh(mesh)
27 {
28  SLM_ASSERT("Mesh ptr is null.", mesh);
29  this->updateLock();
30 }
31 
32 //-----------------------------------------------------------------------------
33 
35 {
36 }
37 
38 //-----------------------------------------------------------------------------
39 
40 void Mesh::updateLock()
41 {
42  SLM_ASSERT("Mesh ptr is null.", m_mesh);
43  m_helperPoints = ::fwDataTools::helper::Array::New(m_mesh->getPointsArray());
44  m_helperCellTypes = ::fwDataTools::helper::Array::New(m_mesh->getCellTypesArray());
45  m_helperCellData = ::fwDataTools::helper::Array::New(m_mesh->getCellDataArray());
46  m_helperCellDataOffsets = ::fwDataTools::helper::Array::New(m_mesh->getCellDataOffsetsArray());
47 
48  ::fwData::Array::sptr pointColors = m_mesh->getPointColorsArray();
49  ::fwData::Array::sptr cellColors = m_mesh->getCellColorsArray();
50  ::fwData::Array::sptr pointNormals = m_mesh->getPointNormalsArray();
51  ::fwData::Array::sptr cellNormals = m_mesh->getCellNormalsArray();
52  ::fwData::Array::sptr pointTexCoords = m_mesh->getPointTexCoordsArray();
53  ::fwData::Array::sptr cellTexCoords = m_mesh->getCellTexCoordsArray();
54 
55  if(pointColors)
56  {
57  m_helperPointColors = ::fwDataTools::helper::Array::New(pointColors);
58  }
59  if(cellColors)
60  {
61  m_helperCellColors = ::fwDataTools::helper::Array::New(cellColors);
62  }
63  if(pointNormals)
64  {
65  m_helperPointNormals = ::fwDataTools::helper::Array::New(pointNormals);
66  }
67  if(cellNormals)
68  {
69  m_helperCellNormals = ::fwDataTools::helper::Array::New(cellNormals);
70  }
71  if(pointTexCoords)
72  {
73  m_helperPointTexCoords = ::fwDataTools::helper::Array::New(pointTexCoords);
74  }
75  if(cellTexCoords)
76  {
77  m_helperCellTexCoords = ::fwDataTools::helper::Array::New(cellTexCoords);
78  }
79 }
80 
81 //-----------------------------------------------------------------------------
82 
83 ::fwData::Mesh::Id Mesh::insertNextPoint(const ::fwData::Mesh::PointValueType p[3])
84 {
85  ::fwData::Mesh::Id nbPoints = m_mesh->getNumberOfPoints();
86  ::fwData::Array::sptr points = m_mesh->getPointsArray();
87  size_t allocatedPts = points->empty() ? 0 : points->getSize().at(0);
88  if( allocatedPts <= nbPoints )
89  {
90  points->resize(list_of(allocatedPts + POINT_REALLOC_STEP), true);
91  }
92  m_helperPoints->setItem(list_of(nbPoints), p);
93  m_mesh->setNumberOfPoints(nbPoints+1);
94  return nbPoints;
95 }
96 
97 //------------------------------------------------------------------------------
98 
99 ::fwData::Mesh::Id Mesh::insertNextPoint(::fwData::Mesh::PointValueType x,
100  ::fwData::Mesh::PointValueType y,
101  ::fwData::Mesh::PointValueType z)
102 {
103  const ::fwData::Mesh::PointValueType p[3] = {x, y, z};
104  return this->insertNextPoint(p);
105 }
106 
107 //------------------------------------------------------------------------------
108 
109 void Mesh::setPoint(::fwData::Mesh::Id id, const ::fwData::Mesh::PointValueType p[3])
110 {
111  m_helperPoints->setItem(list_of(id), p);
112 }
113 
114 //------------------------------------------------------------------------------
115 
116 void Mesh::setPoint(::fwData::Mesh::Id id,
117  ::fwData::Mesh::PointValueType x,
118  ::fwData::Mesh::PointValueType y,
119  ::fwData::Mesh::PointValueType z )
120 {
121  const ::fwData::Mesh::PointValueType p[3] = {x, y, z};
122  this->setPoint(id, p);
123 }
124 
125 //------------------------------------------------------------------------------
126 
127 void Mesh::setPointColor(::fwData::Mesh::Id id, const ::fwData::Mesh::ColorValueType c[4])
128 {
129  m_helperPointColors->setItem(list_of(id), c);
130 }
131 
132 //------------------------------------------------------------------------------
133 
134 void Mesh::setCellColor(::fwData::Mesh::Id id, const ::fwData::Mesh::ColorValueType c[4])
135 {
136  m_helperCellColors->setItem(list_of(id), c);
137 }
138 
139 //------------------------------------------------------------------------------
140 
141 void Mesh::setPointNormal(::fwData::Mesh::Id id, const ::fwData::Mesh::NormalValueType n[3])
142 {
143  m_helperPointNormals->setItem(list_of(id), n);
144 }
145 
146 //------------------------------------------------------------------------------
147 
148 void Mesh::setCellNormal(::fwData::Mesh::Id id, const ::fwData::Mesh::NormalValueType n[3])
149 {
150  m_helperCellNormals->setItem(list_of(id), n);
151 }
152 
153 //------------------------------------------------------------------------------
154 
155 void Mesh::setPointTexCoord(::fwData::Mesh::Id id, const ::fwData::Mesh::TexCoordValueType t[2])
156 {
157  m_helperPointTexCoords->setItem(list_of(id), t);
158 }
159 
160 //------------------------------------------------------------------------------
161 
162 void Mesh::setCellTexCoord(::fwData::Mesh::Id id, const ::fwData::Mesh::TexCoordValueType t[2])
163 {
164  m_helperCellTexCoords->setItem(list_of(id), t);
165 }
166 
167 //------------------------------------------------------------------------------
168 
169 ::fwData::Mesh::Id Mesh::insertNextCell(::fwData::Mesh::CellTypesEnum type,
170  const ::fwData::Mesh::CellValueType* cell,
171  size_t nb)
172 {
173  SLM_ASSERT("Bad number of points ("<< nb << ") for cell type: 'NO_CELL'",
174  type != ::fwData::Mesh::NO_CELL || nb == 0);
175  SLM_ASSERT("Bad number of points ("<< nb << ") for cell type: 'POINT'",
176  type != ::fwData::Mesh::POINT || nb == 1);
177  SLM_ASSERT("Bad number of points ("<< nb << ") for cell type: 'EDGE'",
178  type != ::fwData::Mesh::EDGE || nb == 2);
179  SLM_ASSERT("Bad number of points ("<< nb << ") for cell type: 'TRIANGLE'",
180  type != ::fwData::Mesh::TRIANGLE || nb == 3);
181  SLM_ASSERT("Bad number of points ("<< nb << ") for cell type: 'QUAD'",
182  type != ::fwData::Mesh::QUAD || nb == 4);
183  SLM_ASSERT("Bad number of points ("<< nb << ") for cell type: 'TETRA'",
184  type != ::fwData::Mesh::TETRA || nb == 4);
185  SLM_ASSERT("Bad number of points ("<< nb << ") for cell type: 'POLY'",
186  type != ::fwData::Mesh::POLY || nb > 4);
187 
188  ::fwData::Mesh::Id cellsDataSize = m_mesh->getCellDataSize();
189  ::fwData::Mesh::Id nbCells = m_mesh->getNumberOfCells();
190  ::fwData::Array::sptr cellTypes = m_mesh->getCellTypesArray();
191  ::fwData::Array::sptr cellDataOffsets = m_mesh->getCellDataOffsetsArray();
192  ::fwData::Array::sptr cellData = m_mesh->getCellDataArray();
193 
194  size_t allocatedCellTypes = cellTypes->empty() ? 0 : cellTypes->getSize().at(0);
195  size_t allocatedCellDataOffsets = cellDataOffsets->empty() ? 0 : cellDataOffsets->getSize().at(0);
196 
197  if( allocatedCellTypes <= nbCells )
198  {
199  cellTypes->resize(list_of(allocatedCellTypes + CELL_REALLOC_STEP), true);
200  }
201  if( allocatedCellDataOffsets <= nbCells )
202  {
203  cellDataOffsets->resize(list_of(allocatedCellDataOffsets + CELL_REALLOC_STEP), true);
204  }
205 
206  size_t allocatedCellData = cellData->empty() ? 0 : cellData->getSize().at(0);
207 
208  if( allocatedCellData <= cellsDataSize + nb )
209  {
210  cellData->resize(list_of(allocatedCellData + CELLDATA_REALLOC_STEP), true);
211  }
212 
213  const ::fwData::Mesh::CellTypes t[1] = {static_cast< ::fwData::Mesh::CellTypes >(type)};
214  m_helperCellTypes->setItem(list_of(nbCells), t);
215 
216  ::fwData::Mesh::CellValueType* buf = reinterpret_cast< ::fwData::Mesh::CellValueType* >(
217  m_helperCellData->getBufferPtr(list_of(cellsDataSize), 0, sizeof(::fwData::Mesh::CellValueType))
218  );
219  std::copy(cell, cell+nb, buf);
220 
221  const ::fwData::Mesh::CellDataOffsetType id[1] = {cellsDataSize};
222  m_helperCellDataOffsets->setItem(list_of(nbCells), id);
223 
224  cellsDataSize += nb;
225  m_mesh->setCellDataSize(cellsDataSize);
226  m_mesh->setNumberOfCells(nbCells + 1);
227  return nbCells;
228 }
229 
230 //------------------------------------------------------------------------------
231 
232 ::fwData::Mesh::Id Mesh::insertNextCell(::fwData::Mesh::CellValueType p)
233 {
234  ::fwData::Mesh::CellValueType point[1] = {p};
235  return this->insertNextCell(::fwData::Mesh::POINT, point, 1);
236 }
237 
238 //------------------------------------------------------------------------------
239 
240 ::fwData::Mesh::Id Mesh::insertNextCell(::fwData::Mesh::CellValueType p1,
241  ::fwData::Mesh::CellValueType p2)
242 {
243  ::fwData::Mesh::CellValueType p[2] = {p1, p2};
244  return this->insertNextCell(::fwData::Mesh::EDGE, p, 2);
245 }
246 
247 //------------------------------------------------------------------------------
248 
249 ::fwData::Mesh::Id Mesh::insertNextCell(::fwData::Mesh::CellValueType p1,
250  ::fwData::Mesh::CellValueType p2,
251  ::fwData::Mesh::CellValueType p3)
252 {
253  ::fwData::Mesh::CellValueType p[3] = {p1, p2, p3};
254  return this->insertNextCell(::fwData::Mesh::TRIANGLE, p, 3);
255 }
256 
257 //------------------------------------------------------------------------------
258 
259 ::fwData::Mesh::Id Mesh::insertNextCell(::fwData::Mesh::CellValueType p1,
260  ::fwData::Mesh::CellValueType p2,
261  ::fwData::Mesh::CellValueType p3,
262  ::fwData::Mesh::CellValueType p4,
263  ::fwData::Mesh::CellTypesEnum type)
264 {
265  ::fwData::Mesh::CellValueType p[4] = {p1, p2, p3, p4};
266 
267  return this->insertNextCell(type, p, 4);
268 }
269 
270 //------------------------------------------------------------------------------
271 
272 ::fwData::Mesh::PointsMultiArrayType Mesh::getPoints() const
273 {
274  return ::fwData::Mesh::PointsMultiArrayType(
275  static_cast< ::fwData::Mesh::PointsMultiArrayType::element* >(m_helperPoints->getBuffer()),
276  ::boost::extents[m_mesh->getNumberOfPoints()][3]
277  );
278 }
279 
280 //------------------------------------------------------------------------------
281 
282 ::fwData::Mesh::CellTypesMultiArrayType Mesh::getCellTypes() const
283 {
284  return ::fwData::Mesh::CellTypesMultiArrayType(
285  static_cast< ::fwData::Mesh::CellTypesMultiArrayType::element*> (m_helperCellTypes->getBuffer()),
286  boost::extents[m_mesh->getNumberOfCells()]
287  );
288 }
289 
290 //------------------------------------------------------------------------------
291 
292 ::fwData::Mesh::CellDataMultiArrayType Mesh::getCellData() const
293 {
294  return ::fwData::Mesh::CellDataMultiArrayType(
295  static_cast< ::fwData::Mesh::CellDataMultiArrayType::element* >(m_helperCellData->getBuffer()),
296  ::boost::extents[m_mesh->getCellDataSize()]
297  );
298 }
299 
300 //------------------------------------------------------------------------------
301 
302 ::fwData::Mesh::CellDataOffsetsMultiArrayType Mesh::getCellDataOffsets() const
303 {
304  return ::fwData::Mesh::CellDataOffsetsMultiArrayType(
305  static_cast< ::fwData::Mesh::CellDataOffsetsMultiArrayType::element*>(m_helperCellDataOffsets->getBuffer()),
306  ::boost::extents[m_mesh->getNumberOfCells()]
307  );
308 }
309 
310 //------------------------------------------------------------------------------
311 
312 ::fwData::Mesh::PointColorsMultiArrayType Mesh::getPointColors() const
313 {
314  ::fwData::Array::sptr pointColors = m_mesh->getPointColorsArray();
315  return ::fwData::Mesh::PointColorsMultiArrayType(
316  static_cast< ::fwData::Mesh::PointColorsMultiArrayType::element*>(m_helperPointColors->getBuffer()),
317  ::boost::extents[m_mesh->getNumberOfPoints()][pointColors->getNumberOfComponents()]
318  );
319 }
320 
321 //------------------------------------------------------------------------------
322 
323 ::fwData::Mesh::CellColorsMultiArrayType Mesh::getCellColors() const
324 {
325  ::fwData::Array::sptr cellColors = m_mesh->getCellColorsArray();
326  return ::fwData::Mesh::CellColorsMultiArrayType(
327  static_cast< ::fwData::Mesh::CellColorsMultiArrayType::element*>(m_helperCellColors->getBuffer()),
328  ::boost::extents[m_mesh->getNumberOfCells()][cellColors->getNumberOfComponents()]
329  );
330 }
331 
332 //------------------------------------------------------------------------------
333 
334 ::fwData::Mesh::PointNormalsMultiArrayType Mesh::getPointNormals() const
335 {
336  ::fwData::Array::sptr pointNormals = m_mesh->getPointNormalsArray();
337  return ::fwData::Mesh::PointNormalsMultiArrayType(
338  static_cast< ::fwData::Mesh::PointNormalsMultiArrayType::element*>(m_helperPointNormals->getBuffer()),
339  ::boost::extents[m_mesh->getNumberOfPoints()][pointNormals->getNumberOfComponents()]
340  );
341 }
342 
343 //------------------------------------------------------------------------------
344 
345 ::fwData::Mesh::CellNormalsMultiArrayType Mesh::getCellNormals() const
346 {
347  ::fwData::Array::sptr cellNormals = m_mesh->getCellNormalsArray();
348  return ::fwData::Mesh::CellNormalsMultiArrayType(
349  static_cast< ::fwData::Mesh::CellNormalsMultiArrayType::element*>(m_helperCellNormals->getBuffer()),
350  ::boost::extents[m_mesh->getNumberOfCells()][cellNormals->getNumberOfComponents()]
351  );
352 }
353 
354 //------------------------------------------------------------------------------
355 
356 ::fwData::Mesh::PointTexCoordsMultiArrayType Mesh::getPointTexCoords() const
357 {
358  ::fwData::Array::sptr pointTexCoords = m_mesh->getPointTexCoordsArray();
359  return ::fwData::Mesh::PointTexCoordsMultiArrayType(
360  static_cast< ::fwData::Mesh::PointTexCoordsMultiArrayType::element*>(m_helperPointTexCoords->getBuffer()),
361  ::boost::extents[m_mesh->getNumberOfPoints()][pointTexCoords->getNumberOfComponents()]
362  );
363 }
364 
365 //------------------------------------------------------------------------------
366 
367 ::fwData::Mesh::CellTexCoordsMultiArrayType Mesh::getCellTexCoords() const
368 {
369  ::fwData::Array::sptr cellTexCoords = m_mesh->getCellTexCoordsArray();
370  return ::fwData::Mesh::CellTexCoordsMultiArrayType(
371  static_cast< ::fwData::Mesh::CellTexCoordsMultiArrayType::element*>(m_helperCellTexCoords->getBuffer()),
372  ::boost::extents[m_mesh->getNumberOfCells()][cellTexCoords->getNumberOfComponents()]
373  );
374 }
375 
376 //------------------------------------------------------------------------------
377 
378 ::fwData::Mesh::csptr Mesh::getMesh() const
379 {
380  return m_mesh;
381 }
382 
383 //------------------------------------------------------------------------------
384 
385 bool Mesh::isClosed()
386 {
387  bool isClosed = false;
388 
389  ::fwData::Mesh::Id cellDataSize = m_mesh->getCellDataSize();
390  ::fwData::Mesh::Id nbOfCells = m_mesh->getNumberOfCells();
391 
392  ::fwData::Mesh::CellValueType* cellDataBegin =
393  m_helperCellData->begin< ::fwData::Mesh::CellValueType >();
394  ::fwData::Mesh::CellValueType* cellDataEnd = cellDataBegin + cellDataSize;
395  ::fwData::Mesh::CellDataOffsetType* cellDataOffsetsBegin =
396  m_helperCellDataOffsets->begin< ::fwData::Mesh::CellDataOffsetType >();
397  ::fwData::Mesh::CellDataOffsetType* cellDataOffsetsEnd = cellDataOffsetsBegin + nbOfCells;
398  ::fwData::Mesh::CellTypes* cellTypesBegin = m_helperCellTypes->begin< ::fwData::Mesh::CellTypes >();
399 
400  isClosed = ::fwMath::isBorderlessSurface(cellDataBegin,
401  cellDataEnd, cellDataOffsetsBegin,
402  cellDataOffsetsEnd, cellTypesBegin );
403  return isClosed;
404 }
405 
406 //------------------------------------------------------------------------------
407 
408 } // namespace helper
409 
410 } // namespace fwDataTools
The namespace fwDataTools contains classes which provide helpers to manipulate fwData::Object. *.
virtual FWDATA_API ~Mesh()
Destructor.
#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