00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkGeometry2DDataToSurfaceFilter.h"
00020 #include "mitkSurface.h"
00021 #include "mitkGeometry3D.h"
00022 #include "mitkGeometry2DData.h"
00023 #include "mitkPlaneGeometry.h"
00024 #include "mitkAbstractTransformGeometry.h"
00025
00026 #include <vtkPolyData.h>
00027 #include <vtkPlaneSource.h>
00028 #include <vtkTransformPolyDataFilter.h>
00029
00030 #include <vtkCubeSource.h>
00031 #include <vtkTransformPolyDataFilter.h>
00032 #include <vtkTransform.h>
00033 #include <vtkGeneralTransform.h>
00034 #include <vtkPlane.h>
00035 #include <vtkPPolyDataNormals.h>
00036 #include <vtkCutter.h>
00037 #include <vtkStripper.h>
00038 #include <vtkTriangleFilter.h>
00039 #include <vtkBox.h>
00040 #include <vtkClipPolyData.h>
00041 #include <vtkTextureMapToPlane.h>
00042
00043
00044 mitk::Geometry2DDataToSurfaceFilter::Geometry2DDataToSurfaceFilter()
00045 : m_UseGeometryParametricBounds( true ), m_XResolution( 10 ),
00046 m_YResolution( 10 ), m_PlaceByGeometry( false ), m_UseBoundingBox( false )
00047 {
00048 m_PlaneSource = vtkPlaneSource::New();
00049 m_Transform = vtkTransform::New();
00050
00051 m_CubeSource = vtkCubeSource::New();
00052 m_PolyDataTransformer = vtkTransformPolyDataFilter::New();
00053
00054 m_Plane = vtkPlane::New();
00055 m_PlaneCutter = vtkCutter::New();
00056 m_PlaneStripper = vtkStripper::New();
00057 m_PlanePolyData = vtkPolyData::New();
00058 m_NormalsUpdater = vtkPPolyDataNormals::New();
00059 m_PlaneTriangler = vtkTriangleFilter::New();
00060 m_TextureMapToPlane = vtkTextureMapToPlane::New();
00061
00062 m_Box = vtkBox::New();
00063 m_PlaneClipper = vtkClipPolyData::New();
00064
00065 m_VtkTransformPlaneFilter = vtkTransformPolyDataFilter::New();
00066 m_VtkTransformPlaneFilter->SetInput( m_PlaneSource->GetOutput() );
00067 }
00068
00069
00070 mitk::Geometry2DDataToSurfaceFilter::~Geometry2DDataToSurfaceFilter()
00071 {
00072 m_PlaneSource->Delete();
00073 m_Transform->Delete();
00074
00075 m_CubeSource->Delete();
00076 m_PolyDataTransformer->Delete();
00077
00078 m_Plane->Delete();
00079 m_PlaneCutter->Delete();
00080 m_PlaneStripper->Delete();
00081 m_PlanePolyData->Delete();
00082 m_NormalsUpdater->Delete();
00083 m_PlaneTriangler->Delete();
00084 m_TextureMapToPlane->Delete();
00085
00086 m_Box->Delete();
00087 m_PlaneClipper->Delete();
00088
00089 m_VtkTransformPlaneFilter->Delete();
00090 }
00091
00092
00093 void mitk::Geometry2DDataToSurfaceFilter::GenerateOutputInformation()
00094 {
00095 mitk::Geometry2DData::ConstPointer input = this->GetInput();
00096 mitk::Surface::Pointer output = this->GetOutput();
00097
00098 if ( input.IsNull() || (input->GetGeometry2D() == NULL)
00099 || (input->GetGeometry2D()->IsValid() == false)
00100 || (m_UseBoundingBox && (m_BoundingBox.IsNull() || (m_BoundingBox->GetDiagonalLength2() < mitk::eps))) )
00101 {
00102 return;
00103 }
00104
00105 Point3D origin;
00106 Point3D right, bottom;
00107
00108 vtkPolyData *planeSurface = NULL;
00109
00110
00111
00112 if ( dynamic_cast< PlaneGeometry * >( input->GetGeometry2D() ) != NULL )
00113 {
00114 mitk::PlaneGeometry *planeGeometry =
00115 dynamic_cast< PlaneGeometry * >( input->GetGeometry2D() );
00116
00117 if ( m_PlaceByGeometry )
00118 {
00119
00120
00121 mitk::AffineGeometryFrame3D::TransformType *affineTransform =
00122 planeGeometry->GetIndexToWorldTransform();
00123
00124 mitk::TimeSlicedGeometry *timeGeometry = output->GetTimeSlicedGeometry();
00125 timeGeometry->SetIndexToWorldTransform( affineTransform );
00126
00127 mitk::Geometry3D *g3d = timeGeometry->GetGeometry3D( 0 );
00128 g3d->SetIndexToWorldTransform( affineTransform );
00129 }
00130
00131 if ( !m_UseBoundingBox)
00132 {
00133
00134
00135 if ( m_PlaceByGeometry )
00136 {
00137
00138 origin.Fill( 0.0 );
00139 FillVector3D( right, planeGeometry->GetExtent(0), 0.0, 0.0 );
00140 FillVector3D( bottom, 0.0, planeGeometry->GetExtent(1), 0.0 );
00141 }
00142 else
00143 {
00144
00145 origin = planeGeometry->GetOrigin();
00146 right = planeGeometry->GetCornerPoint( false, true );
00147 bottom = planeGeometry->GetCornerPoint( true, false );
00148 }
00149
00150
00151
00152 m_PlaneSource->SetXResolution( 1 );
00153 m_PlaneSource->SetYResolution( 1 );
00154
00155 m_PlaneSource->SetOrigin( origin[0], origin[1], origin[2] );
00156 m_PlaneSource->SetPoint1( right[0], right[1], right[2] );
00157 m_PlaneSource->SetPoint2( bottom[0], bottom[1], bottom[2] );
00158
00159 planeSurface = m_PlaneSource->GetOutput();
00160 planeSurface->Update();
00161 }
00162 else
00163 {
00164
00165
00166
00167
00168
00169
00170
00171
00172 mitk::BoundingBox::PointType boundingBoxMin = m_BoundingBox->GetMinimum();
00173 mitk::BoundingBox::PointType boundingBoxMax = m_BoundingBox->GetMaximum();
00174 mitk::BoundingBox::PointType boundingBoxCenter = m_BoundingBox->GetCenter();
00175
00176 m_CubeSource->SetXLength( boundingBoxMax[0] - boundingBoxMin[0] );
00177 m_CubeSource->SetYLength( boundingBoxMax[1] - boundingBoxMin[1] );
00178 m_CubeSource->SetZLength( boundingBoxMax[2] - boundingBoxMin[2] );
00179 m_CubeSource->SetCenter(
00180 boundingBoxCenter[0],
00181 boundingBoxCenter[1],
00182 boundingBoxCenter[2] );
00183
00184
00185
00186
00187
00188
00189
00190 m_Transform->Identity();
00191 m_Transform->Concatenate(
00192 planeGeometry->GetVtkTransform()->GetLinearInverse()
00193 );
00194
00195 Geometry3D *referenceGeometry = planeGeometry->GetReferenceGeometry();
00196 if ( referenceGeometry )
00197 {
00198 m_Transform->Concatenate(
00199 referenceGeometry->GetVtkTransform()
00200 );
00201 }
00202
00203
00204 m_PolyDataTransformer->SetInput( m_CubeSource->GetOutput() );
00205 m_PolyDataTransformer->SetTransform( m_Transform );
00206
00207
00208 m_Plane->SetOrigin( 0.0, 0.0, 0.0 );
00209 m_Plane->SetNormal( 0.0, 0.0, 1.0 );
00210
00211
00212 m_PlaneCutter->SetInput( m_PolyDataTransformer->GetOutput() );
00213 m_PlaneCutter->SetCutFunction( m_Plane );
00214
00215
00216 m_PlaneStripper->SetInput( m_PlaneCutter->GetOutput() );
00217 m_PlaneStripper->Update();
00218
00219 if ( m_PlaneStripper->GetOutput()->GetNumberOfPoints() < 3 )
00220 {
00221 return;
00222 }
00223
00224 m_PlanePolyData->SetPoints( m_PlaneStripper->GetOutput()->GetPoints() );
00225 m_PlanePolyData->SetPolys( m_PlaneStripper->GetOutput()->GetLines() );
00226
00227 m_PlaneTriangler->SetInput( m_PlanePolyData );
00228
00229
00230
00231
00232 m_PlaneTriangler->Update();
00233 m_PlaneTriangler->GetOutput()->ComputeBounds();
00234 vtkFloatingPointType *surfaceBounds =
00235 m_PlaneTriangler->GetOutput()->GetBounds();
00236
00237 origin[0] = surfaceBounds[0];
00238 origin[1] = surfaceBounds[2];
00239 origin[2] = surfaceBounds[4];
00240
00241 right[0] = surfaceBounds[1];
00242 right[1] = surfaceBounds[2];
00243 right[2] = surfaceBounds[4];
00244
00245 bottom[0] = surfaceBounds[0];
00246 bottom[1] = surfaceBounds[3];
00247 bottom[2] = surfaceBounds[4];
00248
00249
00250
00251 m_TextureMapToPlane->SetInput( m_PlaneTriangler->GetOutput() );
00252 m_TextureMapToPlane->AutomaticPlaneGenerationOn();
00253 m_TextureMapToPlane->SetOrigin( origin[0], origin[1], origin[2] );
00254 m_TextureMapToPlane->SetPoint1( right[0], right[1], right[2] );
00255 m_TextureMapToPlane->SetPoint2( bottom[0], bottom[1], bottom[2] );
00256
00257
00258
00259 m_TextureMapToPlane->Update();
00260
00261
00262
00263 planeSurface = dynamic_cast< vtkPolyData * >(
00264 m_TextureMapToPlane->GetOutput()
00265 );
00266 }
00267 }
00268
00269
00270 else if ( mitk::AbstractTransformGeometry *abstractGeometry =
00271 dynamic_cast< AbstractTransformGeometry * >( input->GetGeometry2D() ) )
00272 {
00273
00274
00275
00276
00277
00278 origin = abstractGeometry->GetPlane()->GetOrigin();
00279 right = origin + abstractGeometry->GetPlane()->GetAxisVector( 0 );
00280 bottom = origin + abstractGeometry->GetPlane()->GetAxisVector( 1 );
00281
00282
00283 m_PlaneSource->SetOrigin( origin[0], origin[1], origin[2] );
00284 m_PlaneSource->SetPoint1( right[0], right[1], right[2] );
00285 m_PlaneSource->SetPoint2( bottom[0], bottom[1], bottom[2] );
00286
00287
00288
00289
00290 if ( m_UseGeometryParametricBounds )
00291 {
00292 m_PlaneSource->SetXResolution(
00293 (int)abstractGeometry->GetParametricExtent(0)
00294 );
00295 m_PlaneSource->SetYResolution(
00296 (int)abstractGeometry->GetParametricExtent(1)
00297 );
00298 }
00299 else
00300 {
00301 m_PlaneSource->SetXResolution( m_XResolution );
00302 m_PlaneSource->SetYResolution( m_YResolution );
00303 }
00304 if ( m_PlaceByGeometry )
00305 {
00306
00307
00308 mitk::AffineGeometryFrame3D::TransformType *affineTransform =
00309 abstractGeometry->GetIndexToWorldTransform();
00310
00311 mitk::TimeSlicedGeometry *timeGeometry = output->GetTimeSlicedGeometry();
00312 timeGeometry->SetIndexToWorldTransform( affineTransform );
00313
00314 mitk::Geometry3D *g3d = timeGeometry->GetGeometry3D( 0 );
00315 g3d->SetIndexToWorldTransform( affineTransform );
00316
00317 vtkGeneralTransform *composedResliceTransform = vtkGeneralTransform::New();
00318 composedResliceTransform->Identity();
00319 composedResliceTransform->Concatenate(
00320 abstractGeometry->GetVtkTransform()->GetLinearInverse() );
00321 composedResliceTransform->Concatenate(
00322 abstractGeometry->GetVtkAbstractTransform()
00323 );
00324
00325 m_VtkTransformPlaneFilter->SetTransform(
00326 composedResliceTransform
00327 );
00328 }
00329 else
00330 {
00331
00332 m_VtkTransformPlaneFilter->SetTransform(
00333 abstractGeometry->GetVtkAbstractTransform()
00334 );
00335 }
00336
00337 if ( m_UseBoundingBox )
00338 {
00339 mitk::BoundingBox::PointType boundingBoxMin = m_BoundingBox->GetMinimum();
00340 mitk::BoundingBox::PointType boundingBoxMax = m_BoundingBox->GetMaximum();
00341 mitk::BoundingBox::PointType boundingBoxCenter = m_BoundingBox->GetCenter();
00342
00343 m_Box->SetXMin( boundingBoxMin[0], boundingBoxMin[1], boundingBoxMin[2] );
00344 m_Box->SetXMax( boundingBoxMax[0], boundingBoxMax[1], boundingBoxMax[2] );
00345 }
00346 else
00347 {
00348
00349 m_Box->SetXMin( -10000.0, -10000.0, -10000.0 );
00350 m_Box->SetXMax( 10000.0, 10000.0, 10000.0 );
00351 }
00352
00353 m_Transform->Identity();
00354 m_Transform->Concatenate( input->GetGeometry2D()->GetVtkTransform() );
00355 m_Transform->PreMultiply();
00356
00357 m_Box->SetTransform( m_Transform );
00358
00359 m_PlaneClipper->SetInput( m_VtkTransformPlaneFilter->GetOutput() );
00360 m_PlaneClipper->SetClipFunction( m_Box );
00361 m_PlaneClipper->GenerateClippedOutputOff();
00362 m_PlaneClipper->InsideOutOn();
00363 m_PlaneClipper->SetValue( 0.0 );
00364
00365 planeSurface = m_PlaneClipper->GetOutput();
00366 }
00367
00368 m_NormalsUpdater->SetInput( planeSurface );
00369 m_NormalsUpdater->AutoOrientNormalsOn();
00370
00371 m_NormalsUpdater->ComputePointNormalsOn();
00372 m_NormalsUpdater->Update();
00373
00374 output->SetVtkPolyData( m_NormalsUpdater->GetOutput() );
00375 output->CalculateBoundingBox();
00376 }
00377
00378
00379 void mitk::Geometry2DDataToSurfaceFilter::GenerateData()
00380 {
00381 mitk::Surface::Pointer output = this->GetOutput();
00382
00383 if (output.IsNull()) return;
00384 if (output->GetVtkPolyData()==NULL) return;
00385
00386 output->GetVtkPolyData()->Update();
00387 }
00388
00389 const mitk::Geometry2DData *mitk::Geometry2DDataToSurfaceFilter::GetInput()
00390 {
00391 if (this->GetNumberOfInputs() < 1)
00392 {
00393 return 0;
00394 }
00395
00396 return static_cast<const mitk::Geometry2DData * >
00397 ( this->ProcessObject::GetInput(0) );
00398 }
00399
00400
00401 const mitk::Geometry2DData *
00402 mitk::Geometry2DDataToSurfaceFilter
00403 ::GetInput(unsigned int idx)
00404 {
00405 return static_cast< const mitk::Geometry2DData * >
00406 ( this->ProcessObject::GetInput(idx) );
00407 }
00408
00409
00410 void
00411 mitk::Geometry2DDataToSurfaceFilter
00412 ::SetInput(const mitk::Geometry2DData *input)
00413 {
00414
00415 this->ProcessObject::SetNthInput( 0,
00416 const_cast< mitk::Geometry2DData * >( input )
00417 );
00418 }
00419
00420
00421 void
00422 mitk::Geometry2DDataToSurfaceFilter
00423 ::SetInput(unsigned int index, const mitk::Geometry2DData *input)
00424 {
00425 if( index+1 > this->GetNumberOfInputs() )
00426 {
00427 this->SetNumberOfRequiredInputs( index + 1 );
00428 }
00429
00430 this->ProcessObject::SetNthInput(index,
00431 const_cast< mitk::Geometry2DData *>( input )
00432 );
00433 }
00434
00435
00436 void
00437 mitk::Geometry2DDataToSurfaceFilter
00438 ::SetBoundingBox( const mitk::BoundingBox *boundingBox )
00439 {
00440 m_BoundingBox = boundingBox;
00441 this->UseBoundingBoxOn();
00442 }
00443
00444
00445 const mitk::BoundingBox *
00446 mitk::Geometry2DDataToSurfaceFilter
00447 ::GetBoundingBox() const
00448 {
00449 return m_BoundingBox.GetPointer();
00450 }