OpenWalnut  1.5.0dev
WCenterlineParameterization.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <iostream>
27 #include <memory>
28 #include <vector>
29 
30 #include "WCenterlineParameterization.h"
31 #include "core/common/math/linearAlgebra/WVectorFixed.h"
32 
33 WCenterlineParameterization::WCenterlineParameterization( std::shared_ptr< WGridRegular3D > grid, std::shared_ptr< WFiber > centerline ):
35  m_paramValues( grid->size(), 0.0 ),
36  m_paramFinalValues( grid->size(), 0.0 ),
37  m_paramSetValues( grid->size(), false ),
38  m_centerline( centerline ),
39  m_currentStartParameter( 0.0 ),
40  m_currentEndParameter( 0.0 )
41 {
42  // initialize members
43 }
44 
46 {
47  // cleanup
48 }
49 
50 std::shared_ptr< WDataSetScalar > WCenterlineParameterization::getDataSet()
51 {
52  std::shared_ptr< WValueSet< double > > valueSet( new WValueSet< double >( 0,
53  1,
54  std::shared_ptr< std::vector< double > >(
55  new std::vector< double >( m_paramFinalValues ) ),
56  W_DT_DOUBLE ) );
57  return std::shared_ptr< WDataSetScalar >( new WDataSetScalar( valueSet, m_grid ) );
58 }
59 
60 namespace wcp // WCenterlineParameterization
61 {
62  size_t index( int x, int y, int z, std::shared_ptr< WGridRegular3D > grid )
63  {
64  // check validity of voxel
65  x = x < 0 ? 0 : x;
66  y = y < 0 ? 0 : y;
67  z = z < 0 ? 0 : z;
68  x = x >= static_cast< int >( grid->getNbCoordsX() ) ? static_cast< int >( grid->getNbCoordsX() ) - 1 : x;
69  y = y >= static_cast< int >( grid->getNbCoordsY() ) ? static_cast< int >( grid->getNbCoordsY() ) - 1 : y;
70  z = z >= static_cast< int >( grid->getNbCoordsZ() ) ? static_cast< int >( grid->getNbCoordsZ() ) - 1 : z;
71 
72  // calculate the index inside the grid
73  size_t nbX = grid->getNbCoordsX();
74  size_t nbXY = grid->getNbCoordsX() * grid->getNbCoordsY();
75  return x + y * nbX + z * nbXY;
76  }
77 
78  /**
79  * Neighborhood position
80  */
81  typedef struct
82  {
83  size_t indices[27]; //!< The indices of the neighbors.
84  }
86 
87  Neighbourhood neighbourhood( int x, int y, int z, std::shared_ptr< WGridRegular3D > grid )
88  {
89  Neighbourhood n;
90  n.indices[0] = index( x, y, z, grid );
91  n.indices[1] = index( x, y, z+1, grid );
92  n.indices[2] = index( x, y, z-1, grid );
93  n.indices[3] = index( x, y+1, z, grid );
94  n.indices[4] = index( x, y+1, z+1, grid );
95  n.indices[5] = index( x, y+1, z-1, grid );
96  n.indices[6] = index( x, y-1, z, grid );
97  n.indices[7] = index( x, y-1, z+1, grid );
98  n.indices[8] = index( x, y-1, z-1, grid );
99 
100  n.indices[9] = index( x+1, y, z, grid );
101  n.indices[10] = index( x+1, y, z+1, grid );
102  n.indices[11] = index( x+1, y, z-1, grid );
103  n.indices[12] = index( x+1, y+1, z, grid );
104  n.indices[13] = index( x+1, y+1, z+1, grid );
105  n.indices[14] = index( x+1, y+1, z-1, grid );
106  n.indices[15] = index( x+1, y-1, z, grid );
107  n.indices[16] = index( x+1, y-1, z+1, grid );
108  n.indices[17] = index( x+1, y-1, z-1, grid );
109 
110  n.indices[18] = index( x-1, y, z, grid );
111  n.indices[19] = index( x-1, y, z+1, grid );
112  n.indices[20] = index( x-1, y, z-1, grid );
113  n.indices[21] = index( x-1, y+1, z, grid );
114  n.indices[22] = index( x-1, y+1, z+1, grid );
115  n.indices[23] = index( x-1, y+1, z-1, grid );
116  n.indices[24] = index( x-1, y-1, z, grid );
117  n.indices[25] = index( x-1, y-1, z+1, grid );
118  n.indices[26] = index( x-1, y-1, z-1, grid );
119 
120  return n;
121  }
122 }
123 
124 void WCenterlineParameterization::parameterizeVoxel( const WVector3i& voxel, size_t /*voxelIdx*/, const int /*axis*/,
125  const double /*value*/,
126  const WPosition& /*start*/,
127  const WPosition& /*end*/ )
128 {
129  // update a 27 neighbourhood
130  wcp::Neighbourhood n = wcp::neighbourhood( voxel[0], voxel[1], voxel[2], m_grid );
131 
132  // now update the neighbourhood
133  for( unsigned int i = 0; i < 27; ++i )
134  {
135  if( m_paramSetValues[ n.indices[i] ] )
136  {
137  m_paramValues[ n.indices[i] ] = 0.5 * ( m_paramValues[ n.indices[i] ] + m_currentStartParameter );
138  //m_paramValues[ n.indices[i] ] = std::max( m_paramValues[ n.indices[i] ], m_currentStartParameter );
139  }
140  else
141  {
143  }
144 
145  m_paramSetValues[ n.indices[i] ] = true;
146  }
147 }
148 
150 {
151  // do nothing here
153 }
154 
156 {
157  double curLength = 0.0; // the accumulated length along the centerline
158  double bestDistStart = length( m_centerline->at( 0 ) - start ); // the currently best distance to the start point
159  double bestDistEnd = length( m_centerline->at( 0 ) - end ); // the currently best distance to the end point
160 
161  // the currently best parameter of the centerline for this line segment
163  m_currentEndParameter = 0.0;
164 
165  // for this line segment, find the best matching vertex in the centerline
166  for( size_t i = 1; i < m_centerline->size(); ++i )
167  {
168  curLength += length( m_centerline->at( i ) - m_centerline->at( i - 1 ) );
169 
170  // compare current distance
171  double curDist = length( m_centerline->at( i ) - start );
172  if( bestDistStart >= curDist )
173  {
174  bestDistStart = curDist;
175  m_currentStartParameter = curLength;
176  }
177  curDist = length( m_centerline->at( i ) - end );
178  if( bestDistEnd >= curDist )
179  {
180  bestDistEnd = curDist;
181  m_currentEndParameter = curLength;
182  }
183  }
184 
186 }
187 
189 {
190  // do some selective dilatation on the final grid
191 
192  for( size_t x = 0; x < m_grid->getNbCoordsX(); ++x )
193  {
194  for( size_t y = 0; y < m_grid->getNbCoordsY(); ++y )
195  {
196  for( size_t z = 0; z < m_grid->getNbCoordsZ(); ++z )
197  {
198  size_t idx = wcp::index( x, y, z, m_grid );
199 
200  // copy
201  m_paramFinalValues[ idx ] = m_paramValues[ idx ];
202 
203  // has been set during rasterization?
204  if( !m_paramSetValues[ idx ] )
205  {
206  m_paramSetValues[ idx ] = true;
207 
208  // find maximum in neighbourhood
209  wcp::Neighbourhood n = wcp::neighbourhood( x, y, z, m_grid );
210 
211  double maxVal = m_paramValues[ n.indices[ 0 ] ];
212  for( unsigned int i = 1; i < 27; ++i )
213  {
214  maxVal = std::max( m_paramValues[ n.indices[i] ], maxVal );
215  }
216 
217  m_paramFinalValues[ idx ] = maxVal;
218  }
219  }
220  }
221  }
222 }
223 
std::vector< bool > m_paramSetValues
Stores whether the voxel has been set in the past or not.
virtual void newSegment(const WPosition &start, const WPosition &end)
Gets called for each new line segment getting rasterized, as one segment can have multiple voxels.
double m_currentStartParameter
The current start parameter for the current segment.
virtual ~WCenterlineParameterization()
Destructor.
std::vector< double > m_paramFinalValues
The values with applied selective dilatation.
virtual std::shared_ptr< WDataSetScalar > getDataSet()
Gets the dataset representing the parameterization.
double m_currentEndParameter
The current end parameter for the current segment.
WCenterlineParameterization(std::shared_ptr< WGridRegular3D > grid, std::shared_ptr< WFiber > centerline)
Default constructor.
std::shared_ptr< WFiber > m_centerline
The centerline of the cluster.
virtual void newLine(const WLine &line)
Gets called for each new line getting rasterized.
std::vector< double > m_paramValues
Stores the current length of the centerline fiber at each voxel.
virtual void parameterizeVoxel(const WVector3i &voxel, size_t voxelIdx, const int axis, const double value, const WPosition &start, const WPosition &end)
This method allows this parameterization to update.
virtual void finished()
Gets called whenever all lines have been rasterized.
This data set type contains scalars as values.
A line is an ordered sequence of WPositions.
Definition: WLine.h:42
A fixed size matrix class.
Definition: WMatrixFixed.h:150
This only is a 3d double vector.
This class is the base for all specific parameterization algorithms.
std::shared_ptr< WGridRegular3D > m_grid
The grid, which needs to be used for the created dataset and to which the parameterizeVoxel method is...
virtual void newSegment(const WPosition &start, const WPosition &end)
Gets called for each new line segment getting rasterized, as one segment can have multiple voxels.
virtual void newLine(const WLine &line)
Gets called for each new line getting rasterized.
Base Class for all value set types.
Definition: WValueSet.h:47
size_t indices[27]
The indices of the neighbors.