--- /dev/null
+#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$