00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00029 #ifndef __vtkKWEPaintbrushUtilities_h
00030 #define __vtkKWEPaintbrushUtilities_h
00031
00032 #include "VTKEdgeConfigure.h"
00033 #include "vtkObject.h"
00034 #include "vtkImageData.h"
00035 #include "vtkImageStencilData.h"
00036 #include "vtkKWEPaintbrushStencilData.h"
00037 #include "vtkKWEPaintbrushLabelData.h"
00038 #include "vtkImageIterator.h"
00039 #include "vtkSmartPointer.h"
00040 #include <vtkstd/map>
00041 #include <vtkstd/vector>
00042
00043 class vtkImageData;
00044 class vtkImageStencilData;
00045
00046 class VTKEdge_WIDGETS_EXPORT vtkKWEPaintbrushUtilities: public vtkObject
00047 {
00048 public:
00049 static vtkKWEPaintbrushUtilities * New();
00050 vtkTypeRevisionMacro(vtkKWEPaintbrushUtilities, vtkObject);
00051 void PrintSelf(ostream& os, vtkIndent indent);
00052
00054
00056 static int GetIntersectingExtents( int extent1[6], int extent2[6],
00057 int extent[6]);
00059
00060
00071 class vtkFunctorEqualTo
00072 {
00073 public:
00074 inline bool operator()( const double &a, const double &b )
00075 { return (a == b); }
00076 };
00077
00078 class vtkFunctorGreaterThanEqualTo
00079 {
00080 public:
00081 inline bool operator()( const double &a, const double &b )
00082 { return (a >= b); }
00083 };
00084
00085 class vtkFunctorGreaterThan
00086 {
00087 public:
00088 inline bool operator()( const double &a, const double &b )
00089 { return (a > b); }
00090 };
00091
00092 class vtkFunctorLessThan
00093 {
00094 public:
00095 inline bool operator()( const double &a, const double &b )
00096 { return (a < b); }
00097 };
00098
00099 class vtkFunctorLessThanEqualTo
00100 {
00101 public:
00102 inline bool operator()( const double &a, const double &b )
00103 { return (a < b); }
00104 };
00105
00106 template < class TFunctor, class T >
00107 static void vtkKWEPaintbrushUtilitiesGetStencilFromImage( vtkImageData *image,
00108 vtkImageStencilData *stencilData, T threshold)
00109 {
00110 TFunctor f;
00111
00112 int extent[6];
00113 double spacing[3], origin[3];
00114 image->GetExtent(extent);
00115 image->GetSpacing(spacing);
00116 image->GetOrigin(origin);
00117
00118 stencilData->SetExtent(extent);
00119 stencilData->SetSpacing(spacing);
00120 stencilData->SetOrigin(origin);
00121 stencilData->AllocateExtents();
00122
00123 vtkImageIterator< T > it(image, extent);
00124
00125 int ends[2], index[3];
00126 index[1] = extent[2];
00127 index[2] = extent[4];
00128
00129 while( !it.IsAtEnd() )
00130 {
00131 T *inSI = it.BeginSpan();
00132 T *inSIEnd = it.EndSpan();
00133
00134 index[0] = extent[0];
00135 ends[0] = -1;
00136 ends[1] = -1;
00137 if (f(static_cast<double>(*inSI), static_cast<double>(threshold)))
00138 {
00139 ends[0] = extent[0];
00140 }
00141
00142
00143
00144 while (inSI != inSIEnd)
00145 {
00146
00147 if (ends[0] == -1 &&
00148 f(static_cast<double>(*inSI), static_cast<double>(threshold)))
00149 {
00150
00151 ends[0] = index[0];
00152 ++index[0];
00153 ++inSI;
00154 continue;
00155 }
00156
00157 if (ends[0] != -1 && ends[1] == -1 &&
00158 !f(static_cast<double>(*inSI), static_cast<double>(threshold)))
00159 {
00160 ends[1] = index[0];
00161 stencilData->InsertNextExtent(ends[0], ends[1]-1, index[1], index[2]);
00162 ends[0] = ends[1] = -1;
00163 }
00164
00165 ++index[0];
00166 ++inSI;
00167 }
00168
00169 if (f(static_cast<double>(*(inSI-1)),
00170 static_cast<double>(threshold)))
00171 {
00172 stencilData->InsertNextExtent(ends[0], extent[1], index[1], index[2]);
00173 }
00174
00175 it.NextSpan();
00176
00177 if (index[1] == extent[3])
00178 {
00179 ++index[2];
00180 index[1] = extent[2];
00181 }
00182 else
00183 {
00184 ++index[1];
00185 }
00186 }
00187 }
00188
00189 template< class T >
00190 static vtkstd::map< vtkKWEPaintbrushEnums::LabelType,
00191 vtkSmartPointer< vtkKWEPaintbrushStencilData > >
00192 vtkKWEPaintbrushUtilitiesGetStencilsFromImage(
00193 vtkImageData *image,
00194 vtkstd::vector< vtkKWEPaintbrushEnums::LabelType > labels,
00195 T )
00196 {
00197 int extent[6];
00198 double spacing[3], origin[3];
00199 image->GetExtent(extent);
00200 image->GetSpacing(spacing);
00201 image->GetOrigin(origin);
00202
00203 vtkstd::map< vtkKWEPaintbrushEnums::LabelType,
00204 vtkSmartPointer< vtkKWEPaintbrushStencilData > > pstrokeDatas;
00205 vtkstd::map< vtkKWEPaintbrushEnums::LabelType,
00206 vtkSmartPointer< vtkImageStencilData > > strokeDatas;
00207 for (vtkstd::vector< vtkKWEPaintbrushEnums::LabelType >::const_iterator lit = labels.begin();
00208 lit != labels.end(); ++lit)
00209 {
00210 vtkKWEPaintbrushEnums::LabelType l = *lit;
00211 pstrokeDatas[l] = vtkSmartPointer< vtkKWEPaintbrushStencilData >::New();
00212 pstrokeDatas[l]->SetLabel(*lit);
00213 pstrokeDatas[l]->SetExtent(extent);
00214 pstrokeDatas[l]->SetSpacing(spacing);
00215 pstrokeDatas[l]->SetOrigin(origin);
00216 pstrokeDatas[l]->Allocate();
00217 strokeDatas[l] = pstrokeDatas[l]->GetImageStencilData();
00218 }
00219
00220 vtkImageIterator< T > it(image, extent);
00221
00222 int ends[2], index[3];
00223 index[1] = extent[2];
00224 index[2] = extent[4];
00225 vtkKWEPaintbrushEnums::LabelType label = vtkKWEPaintbrushLabelData::NoLabelValue;
00226
00227 while( !it.IsAtEnd() )
00228 {
00229 T *inSI = it.BeginSpan();
00230 T *inSIEnd = it.EndSpan();
00231
00232 index[0] = extent[0];
00233 ends[0] = -1;
00234 ends[1] = -1;
00235
00236
00237
00238 while (inSI != inSIEnd)
00239 {
00240
00241 if (ends[0] == -1 && *inSI != vtkKWEPaintbrushLabelData::NoLabelValue)
00242 {
00243
00244 ends[0] = index[0];
00245 ++index[0];
00246 label = static_cast< vtkKWEPaintbrushEnums::LabelType >(*inSI);
00247 ++inSI;
00248 continue;
00249 }
00250
00251 if (ends[0] != -1 && ends[1] == -1 && *inSI != label)
00252 {
00253 ends[1] = index[0];
00254 strokeDatas[label]->InsertNextExtent(ends[0], ends[1]-1, index[1], index[2]);
00255 ends[0] = ends[1] = -1;
00256
00257 if (*inSI != vtkKWEPaintbrushLabelData::NoLabelValue)
00258 {
00259 ends[0] = index[0];
00260 label = static_cast< vtkKWEPaintbrushEnums::LabelType >(*inSI);
00261 }
00262 }
00263
00264 ++index[0];
00265 ++inSI;
00266 }
00267
00268 if (ends[0] != -1 && ends[1] == -1)
00269 {
00270 strokeDatas[label]->InsertNextExtent(ends[0], extent[1], index[1], index[2]);
00271 }
00272
00273 it.NextSpan();
00274
00275 if (index[1] == extent[3])
00276 {
00277 ++index[2];
00278 index[1] = extent[2];
00279 }
00280 else
00281 {
00282 ++index[1];
00283 }
00284 }
00285
00286 return pstrokeDatas;
00287 }
00288
00290
00297 template < class TFunctor >
00298 static void GetStencilFromImage( vtkImageData * image,
00299 vtkImageStencilData * stencilData,
00300 double threshold )
00301 {
00302 switch (image->GetScalarType())
00303 {
00304 vtkTemplateMacro( vtkKWEPaintbrushUtilitiesGetStencilFromImage< TFunctor >(
00305 image, stencilData, static_cast<VTK_TT>(threshold)));
00306 }
00307 }
00309
00310 static vtkstd::map< vtkKWEPaintbrushEnums::LabelType,
00311 vtkSmartPointer< vtkKWEPaintbrushStencilData > >
00312 GetStencilsFromImage( vtkImageData * image,
00313 vtkstd::vector< vtkKWEPaintbrushEnums::LabelType > labels)
00314 {
00315 typedef vtkstd::map< vtkKWEPaintbrushEnums::LabelType,
00316 vtkSmartPointer< vtkKWEPaintbrushStencilData > > StrokeToLabelMapType;
00317 StrokeToLabelMapType r;
00318 switch (image->GetScalarType())
00319 {
00320 vtkTemplateMacro( (r =
00321 vtkKWEPaintbrushUtilitiesGetStencilsFromImage(
00322 image, labels, static_cast<VTK_TT>(0))));
00323 }
00324 return r;
00325 }
00326
00328
00332 static void GetImageFromStencil( vtkImageData *,
00333 vtkImageStencilData *,
00334 unsigned char inVal,
00335 unsigned char outVal,
00336 bool UseImageExtent = false );
00337
00339
00341 static int ExtentIsEqualToExtent( int e1[6], int e2[6] );
00342
00343 protected:
00344 vtkKWEPaintbrushUtilities();
00345 ~vtkKWEPaintbrushUtilities();
00346
00347 private:
00348 vtkKWEPaintbrushUtilities(const vtkKWEPaintbrushUtilities &);
00349 void operator=(const vtkKWEPaintbrushUtilities &);
00350 };
00351
00352 #endif
00353