fw4spl
DicomSurface.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 "fwGdcmIO/container/DicomSurface.hpp"
8 
9 #include "fwGdcmIO/exception/Failed.hpp"
10 
11 #include <fwDataTools/helper/Array.hpp>
12 #include <fwDataTools/Mesh.hpp>
13 
14 namespace fwGdcmIO
15 {
16 namespace container
17 {
18 
19 //------------------------------------------------------------------------------
20 
22 {
23  ::fwData::Mesh::CellDataOffsetType current;
25  current(0)
26  {
27  }
28 
29  //------------------------------------------------------------------------------
30 
31  ::fwData::Mesh::CellDataOffsetType operator()()
32  {
33  ::fwData::Mesh::CellDataOffsetType res = current;
34  current += 3;
35  return res;
36  }
37 };
38 
39 //------------------------------------------------------------------------------
40 DicomSurface::DicomSurface(const ::fwData::Reconstruction::csptr& reconstruction)
41 {
42  // Get mesh
43  ::fwData::Mesh::csptr mesh = reconstruction->getMesh();
44  FW_RAISE_EXCEPTION_IF(::fwGdcmIO::exception::Failed("Can't save this mesh. It must contain only triangles !"),
45  !::fwDataTools::Mesh::hasUniqueCellType(mesh, ::fwData::Mesh::TRIANGLE));
46 
47  // Coordinates
48  {
49  // Retrieve & copy data
50  ::fwDataTools::helper::Array pointsArrayHelper(mesh->getPointsArray());
51  m_pointBuffer.reserve(mesh->getNumberOfPoints() * 3);
52  m_pointBuffer.assign(pointsArrayHelper.begin< ::fwData::Mesh::PointValueType >(),
53  pointsArrayHelper.end< ::fwData::Mesh::PointValueType >());
54  }
55 
56  // Cells
57  {
58  // Retrieve & copy data
59  ::fwDataTools::helper::Array cellDataHelper(mesh->getCellDataArray());
60  m_cellBuffer.resize(mesh->getNumberOfCells() * 3);
61 
62  std::size_t index = 0;
63  for(auto cellIt = cellDataHelper.begin< ::fwData::Mesh::CellValueType >();
64  cellIt != cellDataHelper.end< ::fwData::Mesh::CellValueType >();
65  ++cellIt)
66  {
67  // Index shall start at 1 in DICOM
68  m_cellBuffer[index++] = static_cast< DicomCellValueType >(*cellIt) + 1;
69  }
70  }
71 
72  // Normals
73  if (mesh->getPointNormalsArray())
74  {
75  // Retrieve & copy data
76  ::fwDataTools::helper::Array normalsArrayHelper(mesh->getPointNormalsArray());
77  m_normalBuffer.reserve(mesh->getNumberOfPoints() * 3);
78  m_normalBuffer.assign(normalsArrayHelper.begin< ::fwData::Mesh::NormalValueType >(),
79  normalsArrayHelper.end< ::fwData::Mesh::NormalValueType >());
80  }
81 
82 }
83 
84 //------------------------------------------------------------------------------
85 
86 DicomSurface::DicomSurface(const ::fwData::Mesh::PointValueType* pointBuffer,
87  const ::fwData::Mesh::Id pointBufferSize,
88  const DicomCellValueType* cellBuffer,
89  const ::fwData::Mesh::Id cellBufferSize,
90  const ::fwData::Mesh::NormalValueType* normalBuffer)
91 {
92  // Coordinates
93  m_pointBuffer.reserve(pointBufferSize);
94  m_pointBuffer.assign(pointBuffer, pointBuffer + pointBufferSize);
95 
96  // Cells
97  m_cellBuffer.reserve(cellBufferSize);
98  m_cellBuffer.assign(cellBuffer, cellBuffer + cellBufferSize);
99 
100  // Normals
101  if(normalBuffer)
102  {
103  m_normalBuffer.reserve(pointBufferSize);
104  m_normalBuffer.assign(normalBuffer, normalBuffer + pointBufferSize);
105  }
106 }
107 
108 //------------------------------------------------------------------------------
109 
111 {
112  SLM_TRACE_FUNC();
113 }
114 
115 //------------------------------------------------------------------------------
116 
117 ::fwData::Mesh::sptr DicomSurface::convertToData()
118 {
119  ::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
120 
121  // Initialize number of points
122  mesh->setNumberOfPoints(m_pointBuffer.size() / 3);
123  mesh->setNumberOfCells(m_cellBuffer.size() / 3);
124  mesh->setCellDataSize(m_cellBuffer.size());
125  mesh->adjustAllocatedMemory();
126 
127  // Coordinates
128  {
129  ::fwDataTools::helper::Array pointsArrayHelper(mesh->getPointsArray());
130  std::copy(m_pointBuffer.begin(),
131  m_pointBuffer.end(),
132  pointsArrayHelper.begin< ::fwData::Mesh::PointValueType >());
133  }
134 
135  // Cells
136  {
137  ::fwDataTools::helper::Array cellDataHelper(mesh->getCellDataArray());
138 
139  std::size_t index = 0;
140  for(auto cellIt = cellDataHelper.begin< ::fwData::Mesh::CellValueType >();
141  cellIt != cellDataHelper.end< ::fwData::Mesh::CellValueType >();
142  ++cellIt)
143  {
144  // Index shall start at 0 in FW4SPL
145  *cellIt = static_cast< ::fwData::Mesh::CellValueType >(m_cellBuffer[index++]) - 1;
146  }
147  }
148 
149  // Normals
150  if(!m_normalBuffer.empty())
151  {
152  mesh->allocatePointNormals();
153  ::fwDataTools::helper::Array normalsArrayHelper(mesh->getPointNormalsArray());
154  std::copy(m_normalBuffer.begin(),
155  m_normalBuffer.end(),
156  normalsArrayHelper.begin< ::fwData::Mesh::NormalValueType >());
157  }
158 
159  // Cells types
160  ::fwDataTools::helper::Array cellTypesHelper(mesh->getCellTypesArray());
161  std::fill(cellTypesHelper.begin< ::fwData::Mesh::CellTypes >(),
162  cellTypesHelper.end< ::fwData::Mesh::CellTypes >(),
163  static_cast< ::fwData::Mesh::CellTypes >(::fwData::Mesh::TRIANGLE));
164 
165  // Cell data offset
166  ::fwDataTools::helper::Array cellDataOffsetsHelper(mesh->getCellDataOffsetsArray());
167  CellDataOffsetGenerator cellDataOffsetGenerator;
168  std::generate(cellDataOffsetsHelper.begin< ::fwData::Mesh::CellDataOffsetType >(),
169  cellDataOffsetsHelper.end< ::fwData::Mesh::CellDataOffsetType >(),
170  cellDataOffsetGenerator);
171 
172  return mesh;
173 
174 }
175 
176 //------------------------------------------------------------------------------
177 
179 {
180  return m_pointBuffer;
181 }
182 
183 //------------------------------------------------------------------------------
184 
186 {
187  return m_cellBuffer;
188 }
189 
190 //------------------------------------------------------------------------------
191 
193 {
194  return m_normalBuffer;
195 }
196 
197 //------------------------------------------------------------------------------
198 
200 {
201  return m_pointBuffer.size();
202 }
203 
204 //------------------------------------------------------------------------------
205 
207 {
208  return m_cellBuffer.size();
209 }
210 
211 //------------------------------------------------------------------------------
212 
214 {
215  return m_normalBuffer.size();
216 }
217 
218 //------------------------------------------------------------------------------
219 
220 } //namespace container
221 } //namespace fwGdcmIO
FWGDCMIO_API DicomSurface(const ::fwData::Reconstruction::csptr &reconstruction)
Constructor.
#define SLM_TRACE_FUNC()
Trace contextual function signature.
Definition: spyLog.hpp:329
FWGDCMIO_API std::size_t getCellBufferSize() const
Return cell buffer size.
FWGDCMIO_API ~DicomSurface()
Destructor.
The namespace fwGdcmIO contains reader, writer and helper for dicom data.
FWGDCMIO_API const DicomNormalBufferType & getNormalBuffer() const
Return normal buffer.
FWGDCMIO_API const DicomCellBufferType & getCellBuffer() const
Return cell buffer.
Implements a failed exception class for fwGdcmIO.
std::vector< float > DicomNormalBufferType
Container types to store points, cells and normals.
std::vector< DicomCellValueType > DicomCellBufferType
Container types to store points, cells and normals.
FWGDCMIO_API const DicomPointBufferType & getPointBuffer() const
Return point coordinates buffer.
std::vector< float > DicomPointBufferType
Container types to store points, cells and normals.
FWGDCMIO_API::fwData::Mesh::sptr convertToData()
Convert DicomSurface container to FW4SPL Mesh.
FWGDCMIO_API std::size_t getNormalBufferSize() const
Return normal buffer size.
FWGDCMIO_API std::size_t getPointBufferSize() const
Return point coordinates buffer size.
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)