]> Creatis software - cpPlugins.git/blobdiff - lib/cpExtensions/Interaction/ImageSlicePointPlacer.cxx
yet another refactoring
[cpPlugins.git] / lib / cpExtensions / Interaction / ImageSlicePointPlacer.cxx
diff --git a/lib/cpExtensions/Interaction/ImageSlicePointPlacer.cxx b/lib/cpExtensions/Interaction/ImageSlicePointPlacer.cxx
new file mode 100644 (file)
index 0000000..45c020b
--- /dev/null
@@ -0,0 +1,275 @@
+#include <cpExtensions/Interaction/ImageSlicePointPlacer.h>
+#include <cpExtensions/Visualization/ImageSliceMapper.h>
+#include <vtkBoundedPlanePointPlacer.h>
+#include <vtkImageData.h>
+#include <vtkImageMapper3D.h>
+#include <vtkImageSlice.h>
+#include <vtkPlane.h>
+
+// -------------------------------------------------------------------------
+vtkCxxSetObjectMacro(
+  cpExtensions::Interaction::ImageSlicePointPlacer, ImageSlice, vtkImageSlice
+  );
+
+// -------------------------------------------------------------------------
+cpExtensions::Interaction::ImageSlicePointPlacer::
+Self* cpExtensions::Interaction::ImageSlicePointPlacer::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+int cpExtensions::Interaction::ImageSlicePointPlacer::
+ComputeWorldPosition(
+  vtkRenderer* ren,
+  double displayPos[ 2 ],
+  double worldPos[ 3 ],
+  double worldOrient[ 9 ]
+  )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return(
+    this->Placer->ComputeWorldPosition(
+      ren, displayPos, worldPos, worldOrient
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+int cpExtensions::Interaction::ImageSlicePointPlacer::
+ComputeWorldPosition(
+  vtkRenderer* ren,
+  double displayPos[ 2 ],
+  double refWorldPos[ 2 ],
+  double worldPos[ 3 ],
+  double worldOrient[ 9 ]
+  )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return(
+    this->Placer->ComputeWorldPosition(
+      ren, displayPos, refWorldPos, worldPos, worldOrient
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+int cpExtensions::Interaction::ImageSlicePointPlacer::
+ValidateWorldPosition( double worldPos[ 3 ] )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return( this->Placer->ValidateWorldPosition( worldPos ) );
+}
+
+// -------------------------------------------------------------------------
+int cpExtensions::Interaction::ImageSlicePointPlacer::
+ValidateWorldPosition( double worldPos[ 3 ], double worldOrient[ 9 ] )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return( this->Placer->ValidateWorldPosition( worldPos, worldOrient ) );
+}
+
+// -------------------------------------------------------------------------
+int cpExtensions::Interaction::ImageSlicePointPlacer::
+UpdateWorldPosition(
+  vtkRenderer* ren, double worldPos[ 3 ], double worldOrient[ 9 ]
+  )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return( this->Placer->UpdateWorldPosition( ren, worldPos, worldOrient ) );
+}
+
+// -------------------------------------------------------------------------
+int cpExtensions::Interaction::ImageSlicePointPlacer::
+UpdateInternalState( )
+{
+  if( !this->ImageSlice )
+    return( 0 );
+
+  vtkImageData* input = this->ImageSlice->GetMapper( )->GetInput( );
+  if( !input )
+    return( 0 );
+
+  double spacing[ 3 ];
+  input->GetSpacing( spacing );
+
+  double origin[ 3 ];
+  input->GetOrigin( origin );
+
+  double b[ 6 ];
+  this->ImageSlice->GetBounds( b );
+  if( this->Bounds[ 0 ] != VTK_DOUBLE_MAX)
+  {
+    b[ 0 ] = ( b[ 0 ] < this->Bounds[ 0 ] )? this->Bounds[ 0 ] : b[ 0 ];
+    b[ 1 ] = ( b[ 1 ] > this->Bounds[ 1 ] )? this->Bounds[ 1 ] : b[ 1 ];
+    b[ 2 ] = ( b[ 2 ] < this->Bounds[ 2 ] )? this->Bounds[ 2 ] : b[ 2 ];
+    b[ 3 ] = ( b[ 3 ] > this->Bounds[ 3 ] )? this->Bounds[ 3 ] : b[ 3 ];
+    b[ 4 ] = ( b[ 4 ] < this->Bounds[ 4 ] )? this->Bounds[ 4 ] : b[ 4 ];
+    b[ 5 ] = ( b[ 5 ] > this->Bounds[ 5 ] )? this->Bounds[ 5 ] : b[ 5 ];
+
+  } // fi
+
+  int displayExtent[ 6 ] = { 0, 1, 0, 1, 0, 1 };
+  input->GetExtent( displayExtent );
+  auto mapper =
+    dynamic_cast< cpExtensions::Visualization::ImageSliceMapper* >(
+      this->ImageSlice->GetMapper( )
+      );
+  if( mapper != NULL )
+  {
+    auto ori = mapper->GetOrientation( );
+    displayExtent[ ( ori << 1 ) + 1 ] =
+      displayExtent[ ori << 1 ] =
+      mapper->GetSliceNumber( );
+
+  } // fi
+
+  int axis;
+  double position;
+  if( displayExtent[ 0 ] == displayExtent[ 1 ] )
+  {
+    axis = vtkBoundedPlanePointPlacer::XAxis;
+    position = origin[ 0 ] + displayExtent[ 0 ] * spacing[ 0 ];
+  }
+  else if( displayExtent[ 2 ] == displayExtent[ 3 ] )
+  {
+    axis = vtkBoundedPlanePointPlacer::YAxis;
+    position = origin[ 1 ] + displayExtent[ 2 ] * spacing[ 1 ];
+  }
+  else if( displayExtent[ 4 ] == displayExtent[ 5 ] )
+  {
+    axis = vtkBoundedPlanePointPlacer::ZAxis;
+    position = origin[ 2 ] + displayExtent[ 4 ] * spacing[ 2 ];
+  }
+  else
+  {
+    vtkErrorMacro( "Incorrect display extent in Image Slice" );
+    return( 0 );
+
+  } // fi
+
+  if(
+    axis != this->Placer->GetProjectionNormal( ) ||
+    position != this->Placer->GetProjectionPosition( ) ||
+    b[ 0 ] != this->SavedBounds[ 0 ] ||
+    b[ 1 ] != this->SavedBounds[ 1 ] ||
+    b[ 2 ] != this->SavedBounds[ 2 ] ||
+    b[ 3 ] != this->SavedBounds[ 3 ] ||
+    b[ 4 ] != this->SavedBounds[ 4 ] ||
+    b[ 5 ] != this->SavedBounds[ 5 ]
+    )
+  {
+    this->SavedBounds[ 0 ] = b[ 0 ];
+    this->SavedBounds[ 1 ] = b[ 1 ];
+    this->SavedBounds[ 2 ] = b[ 2 ];
+    this->SavedBounds[ 3 ] = b[ 3 ];
+    this->SavedBounds[ 4 ] = b[ 4 ];
+    this->SavedBounds[ 5 ] = b[ 5 ];
+
+    this->Placer->SetProjectionNormal( axis );
+    this->Placer->SetProjectionPosition( position );
+
+    this->Placer->RemoveAllBoundingPlanes( );
+
+    vtkPlane* plane;
+    if( axis != vtkBoundedPlanePointPlacer::XAxis )
+    {
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
+      plane->SetNormal( 1.0, 0.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+      plane = vtkPlane::New();
+      plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
+      plane->SetNormal( -1.0, 0.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+    } // fi
+
+    if( axis != vtkBoundedPlanePointPlacer::YAxis )
+    {
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
+      plane->SetNormal( 0.0, 1.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
+      plane->SetNormal( 0.0, -1.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+    } // fi
+
+    if( axis != vtkBoundedPlanePointPlacer::ZAxis )
+    {
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
+      plane->SetNormal( 0.0, 0.0, 1.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
+      plane->SetNormal( 0.0, 0.0, -1.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+    } // fi
+
+    this->Modified( );
+
+  } // fi
+  return( 1 );
+}
+
+// -------------------------------------------------------------------------
+void cpExtensions::Interaction::ImageSlicePointPlacer::
+SetWorldTolerance( double tol )
+{
+  double t =
+    ( tol < 0.0 )? 0.0: ( ( tol > VTK_DOUBLE_MAX )? VTK_DOUBLE_MAX: tol );
+  if( this->WorldTolerance != t )
+  {
+    this->WorldTolerance = t;
+    this->Placer->SetWorldTolerance( tol );
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+cpExtensions::Interaction::ImageSlicePointPlacer::
+ImageSlicePointPlacer( )
+  : Superclass( )
+{
+  this->Placer = vtkBoundedPlanePointPlacer::New( );
+  this->ImageSlice = NULL;
+  this->SavedBounds[ 0 ] = 0.0;
+  this->SavedBounds[ 1 ] = 0.0;
+  this->SavedBounds[ 2 ] = 0.0;
+  this->SavedBounds[ 3 ] = 0.0;
+  this->SavedBounds[ 4 ] = 0.0;
+  this->SavedBounds[ 5 ] = 0.0;
+  this->Bounds[ 0 ] = this->Bounds[ 2 ] = this->Bounds[ 4 ] = VTK_DOUBLE_MAX;
+  this->Bounds[ 1 ] = this->Bounds[ 3 ] = this->Bounds[ 5 ] = VTK_DOUBLE_MIN;
+}
+
+// -------------------------------------------------------------------------
+cpExtensions::Interaction::ImageSlicePointPlacer::
+~ImageSlicePointPlacer( )
+{
+  this->Placer->Delete( );
+  this->SetImageSlice( NULL );
+}
+
+// eof - $RCSfile$