]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/DataObjects/BoundingBox.cxx
dfceb29f255081a30e7baac44e0be4e2c06848fa
[cpPlugins.git] / lib / cpPlugins / DataObjects / BoundingBox.cxx
1 #include <cpPlugins/DataObjects/BoundingBox.h>
2 #include <limits>
3 #include <vtkDataSet.h>
4 #include <cpInstances_SimpleImages.h>
5 #include <cpInstances_Meshes.h>
6
7 // -------------------------------------------------------------------------
8 void cpPlugins::DataObjects::BoundingBox::
9 SetDataObject( DataObject* o )
10 {
11   auto i = o->GetITK< itk::LightObject >( );
12   auto v = o->GetVTK< vtkObjectBase >( );
13   if( v != NULL )      this->SetVTK( v );
14   else if( i != NULL ) this->SetITK( i );
15 }
16
17 // -------------------------------------------------------------------------
18 void cpPlugins::DataObjects::BoundingBox::
19 SetITK( itk::LightObject* o )
20 {
21   bool     r = this->_ITKImage< 1 >( o );
22   if( !r ) r = this->_ITKImage< 2 >( o );
23   if( !r ) r = this->_ITKImage< 3 >( o );
24   if( !r ) r = this->_ITKImage< 4 >( o );
25   if( !r ) r = this->_ITKPointSet< float, 2 >( o );
26   if( !r ) r = this->_ITKPointSet< double, 2 >( o );
27   if( !r ) r = this->_ITKPointSet< float, 3 >( o );
28   if( !r ) r = this->_ITKPointSet< double, 3 >( o );
29   if( r )
30     this->_UpdateVTK( );
31 }
32
33 // -------------------------------------------------------------------------
34 void cpPlugins::DataObjects::BoundingBox::
35 SetVTK( vtkObjectBase* o )
36 {
37   auto ds = dynamic_cast< vtkDataSet* >( o );
38   if( ds != NULL )
39   {
40     double bounds[ 6 ];
41     ds->GetBounds( bounds );
42     this->m_Points[ 0 ].clear( );
43     this->m_Points[ 1 ].clear( );
44     this->m_Points[ 0 ].push_back( bounds[ 0 ] );
45     this->m_Points[ 1 ].push_back( bounds[ 1 ] );
46     this->m_Points[ 0 ].push_back( bounds[ 2 ] );
47     this->m_Points[ 1 ].push_back( bounds[ 3 ] );
48     this->m_Points[ 0 ].push_back( bounds[ 4 ] );
49     this->m_Points[ 1 ].push_back( bounds[ 5 ] );
50     this->_UpdateVTK( );
51
52   } // fi
53 }
54
55 // -------------------------------------------------------------------------
56 void cpPlugins::DataObjects::BoundingBox::
57 Copy( Self* other )
58 {
59   this->m_Points[ 0 ] = other->m_Points[ 0 ];
60   this->m_Points[ 1 ] = other->m_Points[ 1 ];
61   this->Modified( );
62 }
63
64 // -------------------------------------------------------------------------
65 void cpPlugins::DataObjects::BoundingBox::
66 Blend( Self* other )
67 {
68   if( this->m_Points[ 0 ].size( ) < other->m_Points[ 0 ].size( ) )
69     this->m_Points[ 0 ].resize(
70       other->m_Points[ 0 ].size( ),
71       std::numeric_limits< double >::max( )
72       );
73   if( this->m_Points[ 1 ].size( ) < other->m_Points[ 1 ].size( ) )
74     this->m_Points[ 1 ].resize(
75       other->m_Points[ 1 ].size( ),
76       -std::numeric_limits< double >::max( )
77       );
78   for( unsigned int d = 0; d < this->m_Points[ 0 ].size( ); ++d )
79     if( other->m_Points[ 0 ][ d ] < this->m_Points[ 0 ][ d ] )
80       this->m_Points[ 0 ][ d ] = other->m_Points[ 0 ][ d ];
81   for( unsigned int d = 0; d < this->m_Points[ 1 ].size( ); ++d )
82     if( other->m_Points[ 1 ][ d ] > this->m_Points[ 1 ][ d ] )
83       this->m_Points[ 1 ][ d ] = other->m_Points[ 1 ][ d ];
84   this->Modified( );
85 }
86
87 // -------------------------------------------------------------------------
88 template< class _TPoint >
89 void cpPlugins::DataObjects::BoundingBox::
90 SetMinimum( const _TPoint& p )
91 {
92   this->_SetPoint( 0, p );
93 }
94
95 // -------------------------------------------------------------------------
96 template< class _TPoint >
97 void cpPlugins::DataObjects::BoundingBox::
98 SetMaximum( const _TPoint& p )
99 {
100   this->_SetPoint( 1, p );
101 }
102
103 // -------------------------------------------------------------------------
104 template< class _TPoint >
105 _TPoint cpPlugins::DataObjects::BoundingBox::
106 GetMinimum( ) const
107 {
108   return( this->_GetPoint< _TPoint >( 0 ) );
109 }
110
111 // -------------------------------------------------------------------------
112 template< class _TPoint >
113 _TPoint cpPlugins::DataObjects::BoundingBox::
114 GetMaximum( ) const
115 {
116   return( this->_GetPoint< _TPoint >( 1 ) );
117 }
118
119 // -------------------------------------------------------------------------
120 cpPlugins::DataObjects::BoundingBox::
121 BoundingBox( )
122   : Superclass( )
123 {
124   this->m_Points[ 0 ].push_back( double( 0 ) );
125   this->m_Points[ 1 ].push_back( double( 0 ) );
126   this->m_Outline = vtkSmartPointer< vtkOutlineSource >::New( );
127   this->_UpdateVTK( );
128 }
129
130 // -------------------------------------------------------------------------
131 cpPlugins::DataObjects::BoundingBox::
132 ~BoundingBox( )
133 {
134 }
135
136 // -------------------------------------------------------------------------
137 void cpPlugins::DataObjects::BoundingBox::
138 _UpdateVTK( )
139 {
140   // Get bounds
141   double bounds[ 6 ] = { 0 };
142   unsigned int dim = this->m_Points[ 0 ].size( );
143   dim = ( this->m_Points[ 1 ].size( ) < dim )? this->m_Points[ 1 ].size( ): dim;
144   dim = ( dim < 3 )? dim: 3;
145   for( unsigned int d = 0; d < dim; ++d )
146   {
147     bounds[ d << 1 ] = this->m_Points[ 0 ][ d ];
148     bounds[ ( d << 1 ) + 1 ] = this->m_Points[ 1 ][ d ];
149
150   } // rof
151
152   // Update vtk objects
153   this->m_Outline->SetBounds( bounds );
154   this->m_Outline->Update( );
155   this->m_VTK = this->m_Outline->GetOutput( );
156 }
157
158 // -------------------------------------------------------------------------
159 template< class _TPoint >
160 void cpPlugins::DataObjects::BoundingBox::
161 _SetPoint( unsigned int m, const _TPoint& p )
162 {
163   this->m_Points[ m ].clear( );
164   for( unsigned int d = 0; d < _TPoint::PointDimension; ++d )
165     this->m_Points[ m ].push_back( double( p[ d ] ) );
166   this->_UpdateVTK( );
167   this->Modified( );
168 }
169
170 // -------------------------------------------------------------------------
171 template< class _TPoint >
172 _TPoint cpPlugins::DataObjects::BoundingBox::
173 _GetPoint( unsigned int m ) const
174 {
175   unsigned int dim = this->m_Points[ m ].size( );
176   dim = ( _TPoint::PointDimension < dim )? _TPoint::PointDimension: dim;
177   _TPoint p;
178   p.Fill( 0 );
179   for( unsigned int d = 0; d < dim; ++d )
180     p[ d ] = this->m_Points[ m ][ d ];
181   return( p );
182 }
183
184 // -------------------------------------------------------------------------
185 template< unsigned int _NDim >
186 bool cpPlugins::DataObjects::BoundingBox::
187 _ITKImage( itk::LightObject* o )
188 {
189   auto image = dynamic_cast< itk::ImageBase< _NDim >* >( o );
190   if( image == NULL )
191     return( false );
192
193   auto region = image->GetLargestPossibleRegion( );
194   auto i0 = region.GetIndex( );
195   auto i1 = i0 + region.GetSize( );
196
197   typename itk::ImageBase< _NDim >::PointType p0, p1;
198   image->TransformIndexToPhysicalPoint( i0, p0 );
199   image->TransformIndexToPhysicalPoint( i1, p1 );
200   this->m_Points[ 0 ].clear( );
201   this->m_Points[ 1 ].clear( );
202
203   for( unsigned int d = 0; d < _NDim; ++d )
204   {
205     this->m_Points[ 0 ].push_back( double( p0[ d ] ) );
206     this->m_Points[ 1 ].push_back( double( p1[ d ] ) );
207
208   } // rof
209   this->Modified( );
210   return( true );
211 }
212
213 // -------------------------------------------------------------------------
214 template< class _TScalar, unsigned int _NDim >
215 bool cpPlugins::DataObjects::BoundingBox::
216 _ITKPointSet( itk::LightObject* o )
217 {
218   typedef itk::PointSet< _TScalar, _NDim > _TPointSet;
219   typedef itk::BoundingBox< typename _TPointSet::PointIdentifier, _NDim, _TScalar, typename _TPointSet::PointsContainer > _TBBox;
220
221   auto ps = dynamic_cast< _TPointSet* >( o );
222   if( ps == NULL )
223     return( false );
224
225   this->m_Points[ 0 ].clear( );
226   this->m_Points[ 1 ].clear( );
227
228   typename _TBBox::Pointer bb = _TBBox::New( );
229   bb->SetPoints( ps->GetPoints( ) );
230   if( bb->ComputeBoundingBox( ) )
231   {
232     auto p0 = bb->GetMinimum( );
233     auto p1 = bb->GetMaximum( );
234     for( unsigned int d = 0; d < _NDim; ++d )
235     {
236       this->m_Points[ 0 ].push_back( double( p0[ d ] ) );
237       this->m_Points[ 1 ].push_back( double( p1[ d ] ) );
238
239     } // rof
240     this->Modified( );
241     return( true );
242   }
243   else
244     return( false );
245 }
246
247 // eof - $RCSfile$