Commit 1f8fb21b authored by Lisa Avila's avatar Lisa Avila
Browse files

ENH: Added vtkImageActorPointPlacer to use a vtkImageActor to constrain the...

ENH: Added vtkImageActorPointPlacer to use a vtkImageActor to constrain the placement of points. Updated VolView to use this
parent 4ce8adc8
......@@ -37,6 +37,7 @@ vtkEvent.cxx
vtkFocalPlanePointPlacer.cxx
vtkHandleRepresentation.cxx
vtkHandleWidget.cxx
vtkImageActorPointPlacer.cxx
vtkImagePlaneWidget.cxx
vtkImageTracerWidget.cxx
vtkImplicitPlaneWidget.cxx
......
......@@ -20,7 +20,7 @@
#include "vtkPlaneCollection.h"
#include "vtkRenderer.h"
vtkCxxRevisionMacro(vtkBoundedPlanePointPlacer, "1.3");
vtkCxxRevisionMacro(vtkBoundedPlanePointPlacer, "1.4");
vtkStandardNewMacro(vtkBoundedPlanePointPlacer);
vtkCxxSetObjectMacro(vtkBoundedPlanePointPlacer, ObliquePlane, vtkPlane);
......@@ -163,6 +163,16 @@ int vtkBoundedPlanePointPlacer::ComputeWorldPosition( vtkRenderer *ren,
normal, origin,
distance, position ) )
{
// Fill in the information now before validating it.
// This is because we should return the best information
// we can since this may be part of an UpdateWorldPosition
// call - we need to do the best at updating the position
// even if it is not valid.
this->GetCurrentOrientation( worldOrient );
worldPos[0] = position[0];
worldPos[1] = position[1];
worldPos[2] = position[2];
// Now check against the bounding planes
if ( this->BoundingPlanes )
{
......@@ -178,13 +188,6 @@ int vtkBoundedPlanePointPlacer::ComputeWorldPosition( vtkRenderer *ren,
}
}
}
worldPos[0] = position[0];
worldPos[1] = position[1];
worldPos[2] = position[2];
this->GetCurrentOrientation( worldOrient );
return 1;
}
......@@ -219,6 +222,29 @@ int vtkBoundedPlanePointPlacer::ValidateWorldPosition( double worldPos[3] )
return 1;
}
//----------------------------------------------------------------------
int vtkBoundedPlanePointPlacer::UpdateWorldPosition( vtkRenderer *ren,
double worldPos[3],
double worldOrient[9] )
{
double displayPoint[2];
double tmp[4];
tmp[0] = worldPos[0];
tmp[1] = worldPos[1];
tmp[2] = worldPos[2];
tmp[3] = 1.0;
ren->SetWorldPoint( tmp );
ren->WorldToDisplay();
ren->GetDisplayPoint( tmp );
displayPoint[0] = tmp[0];
displayPoint[1] = tmp[1];
return this->ComputeWorldPosition( ren, displayPoint,
worldPos, worldOrient );
}
//----------------------------------------------------------------------
void vtkBoundedPlanePointPlacer::GetCurrentOrientation( double worldOrient[9] )
{
......
......@@ -96,29 +96,78 @@ public:
};
//ETX
// Description:
// Given a renderer and a display position, compute the
// world position and world orientation for this point.
// A plane is defined by a combination of the
// ProjectionNormal, ProjectionOrigin, and ObliquePlane
// ivars. The display position is projected onto this
// plane to determine a world position, and the
// orientation is set to the normal of the plane. If
// the point cannot project onto the plane or if it
// falls outside the bounds imposed by the
// BoundingPlanes, then 0 is returned, otherwise 1 is
// returned to indicate a valid return position and
// orientation.
int ComputeWorldPosition( vtkRenderer *ren,
double displayPos[2],
double worldPos[3],
double worldOrient[9] );
// Description:
// For this point placer the reference position is
// meaningless, so this ivar is ignored and the
// above method is called instead.
int ComputeWorldPosition( vtkRenderer *ren,
double displayPos[2],
double refWorldPos[2],
double worldPos[3],
double worldOrient[9] );
// Description:
// Give a world position check if it is valid - does
// it lie on the plane and within the bounds? Returns
// 1 if it is valid, 0 otherwise.
int ValidateWorldPosition( double worldPos[3] );
// Descrption:
// Orientationation is ignored, and the above method
// is called instead.
int ValidateWorldPosition( double worldPos[3],
double worldOrient[9]);
// Description:
// If the constraints on this placer are changed, then
// this method will be called by the representation on
// each of its points. For this placer, the world
// position will be converted to a display position, then
// ComputeWorldPosition will be used to update the
// point.
virtual int UpdateWorldPosition( vtkRenderer *ren,
double worldPos[3],
double worldOrient[9] );
protected:
vtkBoundedPlanePointPlacer();
~vtkBoundedPlanePointPlacer();
// Controlling vars
// Indicates the projection normal as lying along the
// XAxis, YAxis, ZAxis, or Oblique. For X, Y, and Z axes,
// the projection normal is assumed to be anchored at
// (0,0,0)
int ProjectionNormal;
// Indicates a distance from the origin of the projection
// normal where the project plane will be placed
double ProjectionPosition;
int ProjectToPlane;
// If the ProjectionNormal is oblique, this is the oblique
// plane
vtkPlane *ObliquePlane;
// A collection of planes used to bound the projection
// plane
vtkPlaneCollection *BoundingPlanes;
// Internal method for getting the project normal as a vector
......@@ -128,6 +177,8 @@ protected:
// constraining plane as a 3-tuple
void GetProjectionOrigin( double origin[3] );
// Internal method for getting the orientation of
// the projection plane
void GetCurrentOrientation( double worldOrient[9] );
private:
......
......@@ -32,7 +32,7 @@
#include <vtkstd/algorithm>
#include <vtkstd/iterator>
vtkCxxRevisionMacro(vtkContourRepresentation, "1.6");
vtkCxxRevisionMacro(vtkContourRepresentation, "1.7");
vtkCxxSetObjectMacro(vtkContourRepresentation, PointPlacer, vtkPointPlacer);
vtkCxxSetObjectMacro(vtkContourRepresentation, LineInterpolator, vtkContourLineInterpolator);
......@@ -954,6 +954,41 @@ int vtkContourRepresentation::ComputeInteractionState(int vtkNotUsed(X), int vtk
return this->InteractionState;
}
//---------------------------------------------------------------------
int vtkContourRepresentation::UpdateContour()
{
this->PointPlacer->UpdateInternalState();
if ( this->ContourBuildTime > this->PointPlacer->GetMTime() )
{
// Contour does not need to be rebuilt
return 0;
}
for(unsigned int i=0;i<this->Internal->Nodes.size();i++)
{
this->PointPlacer->
UpdateWorldPosition( this->Renderer,
this->Internal->Nodes[i]->WorldPosition,
this->Internal->Nodes[i]->WorldOrientation );
}
for(unsigned int i=0;(i+1)<this->Internal->Nodes.size();i++)
{
this->UpdateLine(i, i+1);
}
if ( this->ClosedLoop )
{
this->UpdateLine( this->Internal->Nodes.size()-1, 0);
}
this->BuildLines();
this->ContourBuildTime.Modified();
return 1;
}
//----------------------------------------------------------------------
void vtkContourRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -41,58 +41,167 @@ public:
vtkTypeRevisionMacro(vtkContourRepresentation,vtkWidgetRepresentation);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Add a node at a specific world position. Returns 0 if the
// node could not be added, 1 otherwise.
virtual int AddNodeAtWorldPosition( double worldPos[3] );
virtual int AddNodeAtWorldPosition( double worldPos[3],
double worldOrient[9] );
// Description:
// Add a node at a specific display position. This will be
// converted into a world position according to the current
// constrains of the point placer. Return 0 if a point could
// not be added, 1 otherwise.
virtual int AddNodeAtDisplayPosition( double displayPos[2] );
virtual int AddNodeAtDisplayPosition( int displayPos[2] );
virtual int AddNodeAtDisplayPosition( int X, int Y );
// Description:
// Given a display position, activate a node. The closest
// node within tolerance will be activated. If a node is
// activated, 1 will be returned, otherwise 0 will be
// returned.
virtual int ActivateNode( double displayPos[2] );
virtual int ActivateNode( int displayPos[2] );
virtual int ActivateNode( int X, int Y );
// Descirption:
// Move the active node to a specified world position.
// Will return 0 if there is no active node or the node
// could not be moved to that position. 1 will be returned
// on success.
virtual int SetActiveNodeToWorldPosition( double pos[3] );
virtual int SetActiveNodeToWorldPosition( double pos[3],
double orient[9] );
// Description:
// Move the active node based on a specified display position.
// The display position will be converted into a world
// position. If the new position is not valid or there is
// no active node, a 0 will be returned. Otherwise, on
// success a 1 will be returned.
virtual int SetActiveNodeToDisplayPosition( double pos[2] );
virtual int SetActiveNodeToDisplayPosition( int pos[2] );
virtual int SetActiveNodeToDisplayPosition( int X, int Y );
// Description:
// Get the world position of the active node. Will return
// 0 if there is no active node, or 1 otherwise.
virtual int GetActiveNodeWorldPosition( double pos[3] );
// Description:
// Get the world orientation of the active node. Will return
// 0 if there is no active node, or 1 otherwise.
virtual int GetActiveNodeWorldOrientation( double orient[9] );
// Description:
// Get the display position of the active node. Will return
// 0 if there is no active node, or 1 otherwise.
virtual int GetActiveNodeDisplayPosition( double pos[2] );
// Description:
// Get the number of nodes.
virtual int GetNumberOfNodes();
// Description:
// Get the nth node's display position. Will return
// 1 on success, or 0 if there are not at least
// (n+1) nodes (0 based counting).
virtual int GetNthNodeDisplayPosition( int n, double pos[2] );
// Description:
// Get the nth node's world position. Will return
// 1 on success, or 0 if there are not at least
// (n+1) nodes (0 based counting).
virtual int GetNthNodeWorldPosition( int n, double pos[3] );
// Description:
// Get the nth node's world orientation. Will return
// 1 on success, or 0 if there are not at least
// (n+1) nodes (0 based counting).
virtual int GetNthNodeWorldOrientation( int n, double orient[9] );
// Description:
// Set the nth node's display position. Display position
// will be converted into world position according to the
// constraints of the point placer. Will return
// 1 on success, or 0 if there are not at least
// (n+1) nodes (0 based counting) or the world position
// is not valid.
virtual int SetNthNodeDisplayPosition( int n, int X, int Y );
virtual int SetNthNodeDisplayPosition( int n, int pos[2] );
virtual int SetNthNodeDisplayPosition( int n, double pos[2] );
// Description:
// Set the nth node's world position. Will return
// 1 on success, or 0 if there are not at least
// (n+1) nodes (0 based counting) or the world
// position is not valid according to the point
// placer.
virtual int SetNthNodeWorldPosition( int n, double pos[3] );
virtual int SetNthNodeWorldPosition( int n, double pos[3],
double orient[9] );
// Description:
// Get the nth node's slope. Will return
// 1 on success, or 0 if there are not at least
// (n+1) nodes (0 based counting).
virtual int GetNthNodeSlope( int idx, double slope[3] );
// Descirption:
// For a given node n, get the number of intermediate
// points between this node and the node at
// (n+1). If n is the last node and the loop is
// closed, this is the number of intermediate points
// between node n and node 0. 0 is returned if n is
// out of range.
virtual int GetNumberOfIntermediatePoints( int n );
// Description:
// Get the world position of the intermediate point at
// index idx between nodes n and (n+1) (or n and 0 if
// n is the last node and the loop is closed). Returns
// 1 on success or 0 if n or idx are out of range.
virtual int GetIntermediatePointWorldPosition( int n,
int idx, double point[3] );
// Description:
// Add an intermediate point between node n and n+1
// (or n and 0 if n is the last node and the loop is closed).
// Returns 1 on success or 0 if n is out of range.
virtual int AddIntermediatePointWorldPosition( int n,
double point[3] );
// Description:
// Delete the last node. Returns 1 on success or 0 if
// there were not any nodes.
virtual int DeleteLastNode();
// Description:
// Delete the active node. Returns 1 on success or 0 if
// the active node did not indicate a valid node.
virtual int DeleteActiveNode();
// Description:
// Delete the nth node. Return 1 on success or 0 if n
// is out of range.
virtual int DeleteNthNode( int n );
// Description:
// Given a specific X, Y pixel location, add a new node
// on the contour at this location.
virtual int AddNodeOnContour( int X, int Y );
// Description:
// The tolerance representing the distance to the widget (in pixels) in
// which the cursor is considered near enough to the end points of
// the widget to be active.
// The tolerance to use when calculations are performed in
// display coordinates
vtkSetClampMacro(PixelTolerance,int,1,100);
vtkGetMacro(PixelTolerance,int);
// Description:
// The tolerance to use when calculations are performed in
// world coordinates
vtkSetClampMacro(WorldTolerance, double, 0.0, VTK_FLOAT_MAX);
vtkGetMacro(WorldTolerance, double);
......@@ -108,6 +217,9 @@ public:
};
//ETX
// Description:
// Set / get the current operation. The widget is either
// inactive, or it is being translated.
vtkGetMacro( CurrentOperation, int );
vtkSetClampMacro( CurrentOperation, int,
vtkContourRepresentation::Inactive,
......@@ -117,9 +229,18 @@ public:
void SetCurrentOperationToTranslate()
{ this->SetCurrentOperation( vtkContourRepresentation::Translate ); }
// Descirption:
// Set / get the Point Placer. The point placer is
// responsible for converting display coordinates into
// world coordinates according to some constraints, and
// for validating world positions.
void SetPointPlacer( vtkPointPlacer * );
vtkGetObjectMacro( PointPlacer, vtkPointPlacer );
// Description:
// Set / Get the Line Interpolator. The line interpolator
// is repsonsible for generating the line segments connecting
// nodes.
void SetLineInterpolator( vtkContourLineInterpolator *);
vtkGetObjectMacro( LineInterpolator, vtkContourLineInterpolator );
......@@ -137,6 +258,9 @@ public:
virtual int RenderOpaqueGeometry(vtkViewport *viewport)=0;
virtual int RenderTranslucentGeometry(vtkViewport *viewport)=0;
// Description:
// Set / Get the ClosedLoop value. This ivar indicates whether the contour
// forms a closed loop.
void SetClosedLoop( int val );
vtkGetMacro( ClosedLoop, int );
vtkBooleanMacro( ClosedLoop, int );
......@@ -198,6 +322,14 @@ protected:
virtual void BuildLines()=0;
// This method is called when something changes in the point
// placer. It will cause all points to
// be updates, and all lines to be regenerated.
// Should be extended to detect changes in the line interpolator
// too.
virtual int UpdateContour();
vtkTimeStamp ContourBuildTime;
void ComputeMidpoint( double p1[3], double p2[3], double mid[3] )
{
mid[0] = (p1[0] + p2[0])/2;
......
......@@ -30,7 +30,7 @@
#include <vtkstd/algorithm>
#include <vtkstd/iterator>
vtkCxxRevisionMacro(vtkContourWidget, "1.7");
vtkCxxRevisionMacro(vtkContourWidget, "1.8");
vtkStandardNewMacro(vtkContourWidget);
//----------------------------------------------------------------------
......@@ -225,8 +225,7 @@ void vtkContourWidget::AddNode()
this->WidgetState = vtkContourWidget::Manipulate;
reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->ClosedLoopOn();
this->EventCallbackCommand->SetAbortFlag(1);
this->InvokeEvent( vtkCommand::WidgetValueChangedEvent, NULL );
this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
return;
}
}
......@@ -234,6 +233,11 @@ void vtkContourWidget::AddNode()
if ( reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->
AddNodeAtDisplayPosition( X, Y ) )
{
if ( this->WidgetState == vtkContourWidget::Start )
{
this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
}
this->WidgetState = vtkContourWidget::Define;
reinterpret_cast<vtkContourRepresentation*>(this->WidgetRep)->VisibilityOn();
this->EventCallbackCommand->SetAbortFlag(1);
......
......@@ -37,15 +37,37 @@ public:
vtkTypeRevisionMacro(vtkFocalPlanePointPlacer,vtkPointPlacer);
void PrintSelf(ostream& os, vtkIndent indent);
// Descirption:
// Given a renderer and a display position, compute
// the world position and orientation. The orientation
// computed by the placer will always line up with the
// standard coordinate axes. The world position will be
// computed by projecting the display position onto the
// focal plane. This method is typically used to place a
// point for the first time.
int ComputeWorldPosition( vtkRenderer *ren,
double displayPos[2],
double refWorldPos[3],
double worldPos[3],
double worldOrient[9] );
// Description:
// Given a renderer, a display position, and a reference
// world position, compute a new world position. The
// orientation will be the standard coordinate axes, and the
// computed world position will be created by projecting
// the display point onto a plane that is parallel to
// the focal plane and runs through the reference world
// position. This method is typically used to move existing
// points.
int ComputeWorldPosition( vtkRenderer *ren,
double displayPos[2],
double refWorldPos[3],
double worldPos[3],
double worldOrient[9] );
// Description:
// Validate a world position. All world positions
// are valid so these methods always return 1.
int ValidateWorldPosition( double worldPos[3] );
int ValidateWorldPosition( double worldPos[3],
double worldOrient[9]);
......
......@@ -40,7 +40,7 @@
#include "vtkFocalPlanePointPlacer.h"
#include "vtkBezierContourLineInterpolator.h"
vtkCxxRevisionMacro(vtkOrientedGlyphContourRepresentation, "1.5");
vtkCxxRevisionMacro(vtkOrientedGlyphContourRepresentation, "1.6");
vtkStandardNewMacro(vtkOrientedGlyphContourRepresentation);
//----------------------------------------------------------------------
......@@ -388,8 +388,6 @@ void vtkOrientedGlyphContourRepresentation::Translate(double eventPos[2])
//----------------------------------------------------------------------
void vtkOrientedGlyphContourRepresentation::Scale(double eventPos[2])
{
cout << "SCALE!!!" << endl;
// Get the current scale factor
double sf = this->Glypher->GetScaleFactor();
......@@ -504,6 +502,9 @@ vtkOrientedGlyphContourRepresentation::GetContourRepresentationAsPolyData() cons
//----------------------------------------------------------------------
void vtkOrientedGlyphContourRepresentation::BuildRepresentation()
{
// Make sure we are up to date with any changes made in the placer
this->UpdateContour();
double p1[4], p2[4];
this->Renderer->GetActiveCamera()->GetFocalPoint(p1);
p1[3] = 1.0;
......@@ -624,7 +625,6 @@ void vtkOrientedGlyphContourRepresentation::ReleaseGraphicsResources(vtkWindow *
int vtkOrientedGlyphContourRepresentation::RenderOverlay(vtkViewport *viewport)
{
int count=0;
this->BuildRepresentation();
count += this->LinesActor->RenderOverlay(viewport);
if ( this->Actor->GetVisibility() )
{
......@@ -640,8 +640,11 @@ int vtkOrientedGlyphContourRepresentation::RenderOverlay(vtkViewport *viewport)
//----------------------------------------------------------------------
int vtkOrientedGlyphContourRepresentation::RenderOpaqueGeometry(vtkViewport *viewport)
{
int count=0;
// Since we know RenderOpaqueGeometry gets called first, will do the
// build here
this->BuildRepresentation();
int count=0;
count += this->LinesActor->RenderOpaqueGeometry(viewport);
if ( this->Actor->GetVisibility() )
{
......@@ -658,7 +661,6 @@ int vtkOrientedGlyphContourRepresentation::RenderOpaqueGeometry(vtkViewport *vie
int vtkOrientedGlyphContourRepresentation::RenderTranslucentGeometry(vtkViewport *viewport)
{
int count=0;
this->BuildRepresentation();
count += this->LinesActor->RenderTranslucentGeometry(viewport);
if ( this->Actor->GetVisibility() )
{
......
......@@ -16,7 +16,7 @@
#include "vtkRenderer.h"
vtkCxxRevisionMacro(vtkPointPlacer, "1.2");
vtkCxxRevisionMacro(vtkPointPlacer, "1.3");
//----------------------------------------------------------------------
vtkPointPlacer::vtkPointPlacer()
......@@ -30,6 +30,14 @@ vtkPointPlacer::~vtkPointPlacer()
{
}
//----------------------------------------------------------------------
int vtkPointPlacer::UpdateWorldPosition( vtkRenderer *vtkNotUsed(ren),
double *vtkNotUsed(worldPos),
double *vtkNotUsed(worldOrient) )
{
return 1;
}
//----------------------------------------------------------------------
void vtkPointPlacer::PrintSelf(ostream& os, vtkIndent indent)
{
......
......@@ -35,23 +35,67 @@ public:
vtkTypeRevisionMacro(vtkPointPlacer,vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Given a renderer and a display position in pixel coordinates,
// compute the world position and orientation where this point
// will be placed. This method is typically used by the
// representation to place the point initially.
virtual int ComputeWorldPosition( vtkRenderer *ren,
double displayPos[2],
double worldPos[3],
double worldOrient[9] )=0;
// Description:
// Given a renderer, a display position, and a reference world
// position, compute the new world position and orientation
// of this point. This method is typically used by the
// representation to move the point.
virtual int ComputeWorldPosition( vtkRenderer *ren,
double displayPos[2],
double refWorldPos[3],
double worldPos[3],
double worldOrient[9] )=0;
// Description: