]> SALOME platform Git repositories - modules/visu.git/commitdiff
Salome HOME
Adds the class VVTK_ImplicitFunctionWidget providing clipping functionality
authorpkv <pkv@opencascade.com>
Wed, 14 Sep 2005 06:12:46 +0000 (06:12 +0000)
committerpkv <pkv@opencascade.com>
Wed, 14 Sep 2005 06:12:46 +0000 (06:12 +0000)
src/VVTK/Makefile.in
src/VVTK/VVTK_ImplicitFunctionWidget.cxx [new file with mode: 0644]
src/VVTK/VVTK_ImplicitFunctionWidget.h [new file with mode: 0644]

index 6ebf0a3de667acaec95472439c99cfa754aa5156..90120485d1819a409c04500bc5e91588efad7d6c 100755 (executable)
@@ -17,7 +17,8 @@ EXPORT_HEADERS= VVTK.h \
                VVTK_ViewModel.h \
                VVTK_InteractorStyle.h \
                VVTK_ViewWindow.h \
-               VVTK_View.h 
+               VVTK_View.h \
+               VVTK_ImplicitFunctionWidget.h
 
 # Libraries targets
 LIB = libVVTK.la
@@ -27,7 +28,8 @@ LIB_SRC=      VVTK_ViewManager.cxx \
                VVTK_InteractorStyle.cxx \
                VVTK_ViewWindow.cxx \
                VVTK_Renderer.cxx \
-               VVTK_View.cxx 
+               VVTK_View.cxx \
+               VVTK_ImplicitFunctionWidget.cxx
 
 LIB_MOC =      VVTK_ViewWindow.h \
                VVTK_ViewModel.h \
diff --git a/src/VVTK/VVTK_ImplicitFunctionWidget.cxx b/src/VVTK/VVTK_ImplicitFunctionWidget.cxx
new file mode 100644 (file)
index 0000000..4e026f9
--- /dev/null
@@ -0,0 +1,1467 @@
+//  SALOME VTKViewer : build VTK viewer into Salome desktop
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : VVTK_ImplicitFunctionWidget.cxx
+//  Author : Peter KURNEV
+//  Module : SALOME
+//  $Header$
+
+#include <VVTK_ImplicitFunctionWidget.h>
+
+#include <vtkActor.h>
+#include <vtkAssemblyNode.h>
+#include <vtkAssemblyPath.h>
+#include <vtkCallbackCommand.h>
+#include <vtkCamera.h>
+#include <vtkCellPicker.h>
+#include <vtkConeSource.h>
+#include <vtkCutter.h>
+#include <vtkFeatureEdges.h>
+#include <vtkImageData.h>
+#include <vtkLineSource.h>
+#include <vtkMath.h>
+#include <vtkObjectFactory.h>
+#include <vtkOutlineFilter.h>
+#include <vtkPlane.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkProperty.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkRenderer.h>
+#include <vtkSphereSource.h>
+#include <vtkTransform.h>
+#include <vtkTubeFilter.h>
+#include <vtkImplicitBoolean.h>
+
+static float DistanceToPlane(const float x[3], 
+                            const float n[3], 
+                            const float p0[3]);
+
+vtkCxxRevisionMacro(VVTK_ImplicitFunctionWidget, "$Revision$");
+vtkStandardNewMacro(VVTK_ImplicitFunctionWidget);
+
+//==================================================================
+// function: VVTK_ImplicitFunctionWidget
+// purpose :
+//==================================================================
+VVTK_ImplicitFunctionWidget::VVTK_ImplicitFunctionWidget() 
+: 
+  vtkPolyDataSourceWidget()
+{
+  this->State = VVTK_ImplicitFunctionWidget::Start;
+  this->EventCallbackCommand->SetCallback(VVTK_ImplicitFunctionWidget::ProcessEvents);
+  
+  this->NormalToXAxis = 0;
+  this->NormalToYAxis = 0;
+  this->NormalToZAxis = 0;
+
+  // Build the representation of the widget
+  // 
+  this->Plane = vtkPlane::New();
+  this->Plane->SetNormal(0,0,1);
+  this->Plane->SetOrigin(0,0,0);
+  //
+  //modified by NIZNHY-PKV Mon Sep 12 12:55:49 2005f
+  myDistance=10.;
+  myPlane2 = vtkPlane::New();
+  myPlane2->SetNormal(0.,0.,-1.);
+  myPlane2->SetOrigin(0,0,myDistance);
+  //
+  myImplicitfunction=vtkImplicitBoolean::New();
+  myImplicitfunction->AddFunction(Plane);
+  myImplicitfunction->AddFunction(myPlane2);
+  myImplicitfunction->SetOperationType(VTK_UNION);  
+  //modified by NIZNHY-PKV Mon Sep 12 12:55:51 2005t
+  //
+  this->Box = vtkImageData::New();
+  this->Box->SetDimensions(2,2,2);
+  this->Outline = vtkOutlineFilter::New();
+  this->Outline->SetInput(this->Box);
+  this->OutlineMapper = vtkPolyDataMapper::New();
+  this->OutlineMapper->SetInput(this->Outline->GetOutput());
+  this->OutlineActor = vtkActor::New();
+  this->OutlineActor->SetMapper(this->OutlineMapper);
+  this->OutlineTranslation = 1;
+  
+  this->Cutter = vtkCutter::New();
+  this->Cutter->SetInput(this->Box);
+  this->Cutter->SetCutFunction(this->Plane);
+  this->CutMapper = vtkPolyDataMapper::New();
+  this->CutMapper->SetInput(this->Cutter->GetOutput());
+  this->CutActor = vtkActor::New();
+  this->CutActor->SetMapper(this->CutMapper);
+  this->DrawPlane = 1;
+
+  //modified by NIZNHY-PKV Mon Sep 12 12:58:18 2005f
+  myCutter2 = vtkCutter::New();
+  myCutter2->SetInput(this->Box);
+  myCutter2->SetCutFunction(myPlane2);
+  myCutMapper2 = vtkPolyDataMapper::New();
+  myCutMapper2->SetInput(myCutter2->GetOutput());
+  myCutActor2 = vtkActor::New();
+  myCutActor2->SetMapper(myCutMapper2);
+  //modified by NIZNHY-PKV Mon Sep 12 12:58:23 2005t
+
+  this->Edges = vtkFeatureEdges::New();
+  this->Edges->SetInput(this->Cutter->GetOutput());
+  this->EdgesTuber = vtkTubeFilter::New();
+  this->EdgesTuber->SetInput(this->Edges->GetOutput());
+  this->EdgesTuber->SetNumberOfSides(12);
+  this->EdgesMapper = vtkPolyDataMapper::New();
+  this->EdgesMapper->SetInput(this->EdgesTuber->GetOutput());
+  this->EdgesActor = vtkActor::New();
+  this->EdgesActor->SetMapper(this->EdgesMapper);
+  this->Tubing = 1; //control whether tubing is on
+
+  // Create the + plane normal
+  this->LineSource = vtkLineSource::New();
+  this->LineSource->SetResolution(1);
+  this->LineMapper = vtkPolyDataMapper::New();
+  this->LineMapper->SetInput(this->LineSource->GetOutput());
+  this->LineActor = vtkActor::New();
+  this->LineActor->SetMapper(this->LineMapper);
+
+  this->ConeSource = vtkConeSource::New();
+  this->ConeSource->SetResolution(12);
+  this->ConeSource->SetAngle(25.0);
+  this->ConeMapper = vtkPolyDataMapper::New();
+  this->ConeMapper->SetInput(this->ConeSource->GetOutput());
+  this->ConeActor = vtkActor::New();
+  this->ConeActor->SetMapper(this->ConeMapper);
+
+  // Create the - plane normal
+  this->LineSource2 = vtkLineSource::New();
+  this->LineSource2->SetResolution(1);
+  this->LineMapper2 = vtkPolyDataMapper::New();
+  this->LineMapper2->SetInput(this->LineSource2->GetOutput());
+  this->LineActor2 = vtkActor::New();
+  this->LineActor2->SetMapper(this->LineMapper2);
+
+  this->ConeSource2 = vtkConeSource::New();
+  this->ConeSource2->SetResolution(12);
+  this->ConeSource2->SetAngle(25.0);
+  this->ConeMapper2 = vtkPolyDataMapper::New();
+  this->ConeMapper2->SetInput(this->ConeSource2->GetOutput());
+  this->ConeActor2 = vtkActor::New();
+  this->ConeActor2->SetMapper(this->ConeMapper2);
+
+  // Create the origin handle
+  this->Sphere = vtkSphereSource::New();
+  this->Sphere->SetThetaResolution(16);
+  this->Sphere->SetPhiResolution(8);
+  this->SphereMapper = vtkPolyDataMapper::New();
+  this->SphereMapper->SetInput(this->Sphere->GetOutput());
+  this->SphereActor = vtkActor::New();
+  this->SphereActor->SetMapper(this->SphereMapper);
+
+  this->Transform = vtkTransform::New();
+
+  // Define the point coordinates
+  float bounds[6];
+  bounds[0] = -0.5;
+  bounds[1] = 0.5;
+  bounds[2] = -0.5;
+  bounds[3] = 0.5;
+  bounds[4] = -0.5;
+  bounds[5] = 0.5;
+
+  // Initial creation of the widget, serves to initialize it
+  this->PlaceWidget(bounds);
+
+  //Manage the picking stuff
+  this->Picker = vtkCellPicker::New();
+  this->Picker->SetTolerance(0.005);
+  this->Picker->AddPickList(this->CutActor);
+  this->Picker->AddPickList(myCutActor2);//pt
+  this->Picker->AddPickList(this->LineActor);
+  this->Picker->AddPickList(this->ConeActor);
+  this->Picker->AddPickList(this->LineActor2);
+  this->Picker->AddPickList(this->ConeActor2);
+  this->Picker->AddPickList(this->SphereActor);
+  this->Picker->AddPickList(this->OutlineActor);
+  this->Picker->PickFromListOn();
+  
+  // Set up the initial properties
+  this->CreateDefaultProperties();
+}
+//==================================================================
+// function: ~
+// purpose :
+//==================================================================
+VVTK_ImplicitFunctionWidget::~VVTK_ImplicitFunctionWidget()
+{  
+  this->Plane->Delete();
+  //modified by NIZNHY-PKV Mon Sep 12 13:03:11 2005f
+  myPlane2->Delete();
+  myImplicitfunction->Delete();
+  //modified by NIZNHY-PKV Mon Sep 12 13:03:13 2005t
+  this->Box->Delete();
+  this->Outline->Delete();
+  this->OutlineMapper->Delete();
+  this->OutlineActor->Delete();
+  
+  this->Cutter->Delete();
+  this->CutMapper->Delete();
+  this->CutActor->Delete();
+
+  //modified by NIZNHY-PKV Mon Sep 12 13:03:41 2005f
+  myCutter2->Delete();
+  myCutMapper2->Delete();
+  myCutActor2->Delete();
+  //modified by NIZNHY-PKV Mon Sep 12 13:03:44 2005t
+  
+  this->Edges->Delete();
+  this->EdgesTuber->Delete();
+  this->EdgesMapper->Delete();
+  this->EdgesActor->Delete();
+  
+  this->LineSource->Delete();
+  this->LineMapper->Delete();
+  this->LineActor->Delete();
+
+  this->ConeSource->Delete();
+  this->ConeMapper->Delete();
+  this->ConeActor->Delete();
+
+  this->LineSource2->Delete();
+  this->LineMapper2->Delete();
+  this->LineActor2->Delete();
+
+  this->ConeSource2->Delete();
+  this->ConeMapper2->Delete();
+  this->ConeActor2->Delete();
+
+  this->Sphere->Delete();
+  this->SphereMapper->Delete();
+  this->SphereActor->Delete();
+
+  this->Transform->Delete();
+
+  this->Picker->Delete();
+
+  this->NormalProperty->Delete();
+  this->SelectedNormalProperty->Delete();
+  this->PlaneProperty->Delete();
+  this->SelectedPlaneProperty->Delete();
+  this->OutlineProperty->Delete();
+  this->SelectedOutlineProperty->Delete();
+  this->EdgesProperty->Delete();
+}
+//==================================================================
+// function: ImplicitFunction
+// purpose :
+//==================================================================
+vtkImplicitFunction* VVTK_ImplicitFunctionWidget::ImplicitFunction()
+{
+  return myImplicitfunction;
+}
+//==================================================================
+// function: SetDistance
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetDistance(const float theDistance)
+{
+  myDistance=theDistance;
+  //
+  float *origin, *normal, oNew[3], aN2[3]; 
+  origin = Plane->GetOrigin();
+  normal = Plane->GetNormal();
+  vtkMath::Normalize(normal);
+  oNew[0] = origin[0] + myDistance*normal[0];
+  oNew[1] = origin[1] + myDistance*normal[1];
+  oNew[2] = origin[2] + myDistance*normal[2];
+  myPlane2->SetOrigin(oNew);
+  aN2[0]=-normal[0];
+  aN2[1]=-normal[1];
+  aN2[2]=-normal[2];
+  myPlane2->SetNormal(aN2);
+}
+//==================================================================
+// function: Distance
+// purpose :
+//==================================================================
+float VVTK_ImplicitFunctionWidget::Distance()const
+{
+  return myDistance;
+}
+//==================================================================
+// function: SetEnabled
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetEnabled(int enabling)
+{
+  if ( ! this->Interactor )    {
+    vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
+    return;
+  }
+
+  if ( enabling ) {//------------------------------------------------------------
+    vtkDebugMacro(<<"Enabling plane widget");
+    
+    if ( this->Enabled ){ //already enabled, just return
+      return;
+    }
+    
+    if ( ! this->CurrentRenderer ){
+      this->CurrentRenderer = this->Interactor->FindPokedRenderer(
+        this->Interactor->GetLastEventPosition()[0],
+        this->Interactor->GetLastEventPosition()[1]);
+      if (this->CurrentRenderer == NULL)        {
+        return;
+      }
+    }
+
+    this->Enabled = 1;
+
+    // listen for the following events
+    vtkRenderWindowInteractor *i = this->Interactor;
+    i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand, 
+                   this->Priority);
+    i->AddObserver(vtkCommand::LeftButtonPressEvent, 
+                   this->EventCallbackCommand, this->Priority);
+    i->AddObserver(vtkCommand::LeftButtonReleaseEvent, 
+                   this->EventCallbackCommand, this->Priority);
+    i->AddObserver(vtkCommand::MiddleButtonPressEvent, 
+                   this->EventCallbackCommand, this->Priority);
+    i->AddObserver(vtkCommand::MiddleButtonReleaseEvent, 
+                   this->EventCallbackCommand, this->Priority);
+    i->AddObserver(vtkCommand::RightButtonPressEvent, 
+                   this->EventCallbackCommand, this->Priority);
+    i->AddObserver(vtkCommand::RightButtonReleaseEvent, 
+                   this->EventCallbackCommand, this->Priority);
+
+    // add the outline
+    this->CurrentRenderer->AddActor(this->OutlineActor);
+    this->OutlineActor->SetProperty(this->OutlineProperty);
+
+    // add the edges
+    this->CurrentRenderer->AddActor(this->EdgesActor);
+    this->OutlineActor->SetProperty(this->EdgesProperty);
+
+    // add the normal vector
+    this->CurrentRenderer->AddActor(this->LineActor);
+    this->LineActor->SetProperty(this->NormalProperty);
+    this->CurrentRenderer->AddActor(this->ConeActor);
+    this->ConeActor->SetProperty(this->NormalProperty);
+
+    this->CurrentRenderer->AddActor(this->LineActor2);
+    this->LineActor2->SetProperty(this->NormalProperty);
+    this->CurrentRenderer->AddActor(this->ConeActor2);
+    this->ConeActor2->SetProperty(this->NormalProperty);
+    
+    // add the origin handle
+    this->CurrentRenderer->AddActor(this->SphereActor);
+    this->SphereActor->SetProperty(this->NormalProperty);
+
+    // add the plane (if desired)
+    if ( this->DrawPlane )
+      {
+      this->CurrentRenderer->AddActor(this->CutActor);
+      this->CurrentRenderer->AddActor(this->myCutActor2);//pkv ft
+      }
+    this->CutActor->SetProperty(this->PlaneProperty);
+    myCutActor2->SetProperty(this->PlaneProperty);//pkv ft
+
+    this->UpdateRepresentation();
+    this->SizeHandles();
+    this->InvokeEvent(vtkCommand::EnableEvent,NULL);
+    }
+  
+  else {//disabling----------------------------------------------------------
+    vtkDebugMacro(<<"Disabling plane widget");
+
+    if ( ! this->Enabled ) {//already disabled, just return
+      return;
+    }
+    
+    this->Enabled = 0;
+
+    // don't listen for events any more
+    this->Interactor->RemoveObserver(this->EventCallbackCommand);
+
+    // turn off the various actors
+    this->CurrentRenderer->RemoveActor(this->OutlineActor);
+    this->CurrentRenderer->RemoveActor(this->EdgesActor);
+    this->CurrentRenderer->RemoveActor(this->LineActor);
+    this->CurrentRenderer->RemoveActor(this->ConeActor);
+    this->CurrentRenderer->RemoveActor(this->LineActor2);
+    this->CurrentRenderer->RemoveActor(this->ConeActor2);
+    this->CurrentRenderer->RemoveActor(this->SphereActor);
+    this->CurrentRenderer->RemoveActor(this->CutActor);
+    this->CurrentRenderer->RemoveActor(myCutActor2);//pkv ft
+
+    this->InvokeEvent(vtkCommand::DisableEvent,NULL);
+    this->CurrentRenderer = NULL;
+  }
+  
+  this->Interactor->Render();
+}
+//==================================================================
+// function: ProcessEvents
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::ProcessEvents(vtkObject* vtkNotUsed(object), 
+                                               unsigned long event,
+                                               void* clientdata, 
+                                               void* vtkNotUsed(calldata))
+{
+  VVTK_ImplicitFunctionWidget* self = 
+    reinterpret_cast<VVTK_ImplicitFunctionWidget *>( clientdata );
+
+  //okay, let's do the right thing
+  switch(event)
+    {
+    case vtkCommand::LeftButtonPressEvent:
+      self->OnLeftButtonDown();
+      break;
+    case vtkCommand::LeftButtonReleaseEvent:
+      self->OnLeftButtonUp();
+      break;
+    case vtkCommand::MiddleButtonPressEvent:
+      self->OnMiddleButtonDown();
+      break;
+    case vtkCommand::MiddleButtonReleaseEvent:
+      self->OnMiddleButtonUp();
+      break;
+    case vtkCommand::RightButtonPressEvent:
+      self->OnRightButtonDown();
+      break;
+    case vtkCommand::RightButtonReleaseEvent:
+      self->OnRightButtonUp();
+      break;
+    case vtkCommand::MouseMoveEvent:
+      self->OnMouseMove();
+      break;
+    }
+}
+//==================================================================
+// function: HighlightNormal
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::HighlightNormal(int highlight)
+{
+  if ( highlight ) {
+    this->LineActor->SetProperty(this->SelectedNormalProperty);
+    this->ConeActor->SetProperty(this->SelectedNormalProperty);
+    this->LineActor2->SetProperty(this->SelectedNormalProperty);
+    this->ConeActor2->SetProperty(this->SelectedNormalProperty);
+    this->SphereActor->SetProperty(this->SelectedNormalProperty);
+    }
+  else
+    {
+    this->LineActor->SetProperty(this->NormalProperty);
+    this->ConeActor->SetProperty(this->NormalProperty);
+    this->LineActor2->SetProperty(this->NormalProperty);
+    this->ConeActor2->SetProperty(this->NormalProperty);
+    this->SphereActor->SetProperty(this->NormalProperty);
+    }
+}
+
+//==================================================================
+// function: HighlightPlane
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::HighlightPlane(int highlight)
+{
+  if ( highlight )    {
+    this->CutActor->SetProperty(this->SelectedPlaneProperty);
+    myCutActor2->SetProperty(this->SelectedPlaneProperty);//pkv ft
+  }
+  else    {
+    this->CutActor->SetProperty(this->PlaneProperty);
+    myCutActor2->SetProperty(this->PlaneProperty);//pkv ft
+  }
+}
+//==================================================================
+// function: HighlightOutline
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::HighlightOutline(int highlight)
+{
+  if ( highlight )    {
+    this->OutlineActor->SetProperty(this->SelectedOutlineProperty);
+  }
+  else    {
+    this->OutlineActor->SetProperty(this->OutlineProperty);
+  }
+}
+//==================================================================
+// function: OnLeftButtonDown
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::OnLeftButtonDown()
+{
+  // We're only here if we are enabled
+  int X = this->Interactor->GetEventPosition()[0];
+  int Y = this->Interactor->GetEventPosition()[1];
+  //
+  printf(" VVTK_ImplicitFunctionWidget::OnLeftButtonDown()\n");
+  //
+  // Okay, we can process this. See if we've picked anything.
+  // Make sure it's in the activated renderer
+  vtkRenderer *ren = this->Interactor->FindPokedRenderer(X,Y);
+  if ( ren != this->CurrentRenderer )    {
+    this->State = VVTK_ImplicitFunctionWidget::Outside;
+    return;
+  }
+  
+  vtkAssemblyPath *path;
+  this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
+  path = this->Picker->GetPath();
+
+  if ( path == NULL ) {//not picking this widget
+    this->HighlightPlane(0);
+    this->HighlightNormal(0);
+    this->HighlightOutline(0);
+    this->State = VVTK_ImplicitFunctionWidget::Outside;
+    return;
+  }
+
+  vtkProp *prop = path->GetFirstNode()->GetProp();
+  this->ValidPick = 1;
+  this->Picker->GetPickPosition(this->LastPickPosition);
+  //
+  if ( prop == this->ConeActor || prop == this->LineActor ||
+       prop == this->ConeActor2 || prop == this->LineActor2 )  {
+    this->HighlightPlane(1);
+    this->HighlightNormal(1);
+    this->State = VVTK_ImplicitFunctionWidget::Rotating;
+    printf("this->State = Rotating\n");
+  }
+  else if ( prop == this->CutActor)    {
+    this->HighlightPlane(1);
+    this->State = VVTK_ImplicitFunctionWidget::Pushing;
+    printf("this->State = Pushing\n");
+  }
+  else if ( prop == this->SphereActor )    {
+    this->HighlightNormal(1);
+    this->State = VVTK_ImplicitFunctionWidget::MovingOrigin;
+    printf("this->State = MovingOrigin\n");
+  }
+  else if (prop == myCutActor2)    {
+    this->HighlightPlane(1);
+    this->State = VVTK_ImplicitFunctionWidget::ChangeDistance;
+    printf("this->State = ChangeDistance (myCutActor2)\n");
+  }
+  else    {
+    if ( this->OutlineTranslation )      {
+      this->HighlightOutline(1);
+      this->State = VVTK_ImplicitFunctionWidget::MovingOutline;
+      printf("this->State = MovingOutline\n");
+    }
+  }
+  
+  this->EventCallbackCommand->SetAbortFlag(1);
+  this->StartInteraction();
+  this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
+  this->Interactor->Render();
+}
+//==================================================================
+// function: OnLeftButtonUp
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::OnLeftButtonUp()
+{
+  if ( this->State == VVTK_ImplicitFunctionWidget::Outside )    {
+    return;
+  }
+
+  this->State = VVTK_ImplicitFunctionWidget::Start;
+  this->HighlightPlane(0);
+  this->HighlightOutline(0);
+  this->HighlightNormal(0);
+  this->SizeHandles();
+  
+  this->EventCallbackCommand->SetAbortFlag(1);
+  this->EndInteraction();
+  this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
+  this->Interactor->Render();
+}
+//==================================================================
+// function: OnMiddleButtonDown
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::OnMiddleButtonDown()
+{
+  int X = this->Interactor->GetEventPosition()[0];
+  int Y = this->Interactor->GetEventPosition()[1];
+
+  // Okay, we can process this. See if we've picked anything.
+  // Make sure it's in the activated renderer
+  vtkRenderer *ren = this->Interactor->FindPokedRenderer(X,Y);
+  if ( ren != this->CurrentRenderer )    {
+    this->State = VVTK_ImplicitFunctionWidget::Outside;
+    return;
+  }
+  
+  // Okay, we can process this.
+  vtkAssemblyPath *path;
+  this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
+  path = this->Picker->GetPath();
+  
+  if ( path == NULL ) {//nothing picked
+    this->State = VVTK_ImplicitFunctionWidget::Outside;
+    return;
+  }
+
+  this->ValidPick = 1;
+  this->Picker->GetPickPosition(this->LastPickPosition);
+  this->State = VVTK_ImplicitFunctionWidget::MovingPlane;
+  this->HighlightNormal(1);
+  this->HighlightPlane(1);
+  
+  this->EventCallbackCommand->SetAbortFlag(1);
+  this->StartInteraction();
+  this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
+  this->Interactor->Render();
+}
+//==================================================================
+// function: OnMiddleButtonUp
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::OnMiddleButtonUp()
+{
+  if ( this->State == VVTK_ImplicitFunctionWidget::Outside )    {
+    return;
+  }
+
+  this->State = VVTK_ImplicitFunctionWidget::Start;
+  this->HighlightPlane(0);
+  this->HighlightOutline(0);
+  this->HighlightNormal(0);
+  this->SizeHandles();
+  
+  this->EventCallbackCommand->SetAbortFlag(1);
+  this->EndInteraction();
+  this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
+  this->Interactor->Render();
+}
+//==================================================================
+// function: OnRightButtonDown
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::OnRightButtonDown()
+{
+  this->State = VVTK_ImplicitFunctionWidget::Scaling;
+
+  int X = this->Interactor->GetEventPosition()[0];
+  int Y = this->Interactor->GetEventPosition()[1];
+
+  // Okay, we can process this. See if we've picked anything.
+  // Make sure it's in the activated renderer
+  vtkRenderer *ren = this->Interactor->FindPokedRenderer(X,Y);
+  if ( ren != this->CurrentRenderer )    {
+    this->State = VVTK_ImplicitFunctionWidget::Outside;
+    return;
+  }
+  
+  // Okay, we can process this. Try to pick handles first;
+  // if no handles picked, then pick the bounding box.
+  vtkAssemblyPath *path;
+  this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
+  path = this->Picker->GetPath();
+  if ( path == NULL ){ //nothing picked
+    this->State = VVTK_ImplicitFunctionWidget::Outside;
+    return;
+  }
+  
+  this->ValidPick = 1;
+  this->Picker->GetPickPosition(this->LastPickPosition);
+  this->HighlightPlane(1);
+  this->HighlightOutline(1);
+  this->HighlightNormal(1);
+  
+  this->EventCallbackCommand->SetAbortFlag(1);
+  this->StartInteraction();
+  this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
+  this->Interactor->Render();
+}
+//==================================================================
+// function: OnRightButtonUp
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::OnRightButtonUp()
+{
+  if ( this->State == VVTK_ImplicitFunctionWidget::Outside )    {
+    return;
+  }
+  
+  this->State = VVTK_ImplicitFunctionWidget::Start;
+  this->HighlightPlane(0);
+  this->HighlightOutline(0);
+  this->HighlightNormal(0);
+  this->SizeHandles();
+  
+  this->EventCallbackCommand->SetAbortFlag(1);
+  this->EndInteraction();
+  this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
+  this->Interactor->Render();
+}
+//==================================================================
+// function: OnMouseMove
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::OnMouseMove()
+{
+  // See whether we're active
+  if ( this->State == VVTK_ImplicitFunctionWidget::Outside || 
+       this->State == VVTK_ImplicitFunctionWidget::Start )    {
+    return;
+  }
+  
+  int X = this->Interactor->GetEventPosition()[0];
+  int Y = this->Interactor->GetEventPosition()[1];
+
+  // Do different things depending on state
+  // Calculations everybody does
+  double focalPoint[4], pickPoint[4], prevPickPoint[4];
+  double z, vpn[3];
+
+  vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
+  if ( !camera ) {
+    return;
+  }
+
+  // Compute the two points defining the motion vector
+  this->ComputeWorldToDisplay(this->LastPickPosition[0], this->LastPickPosition[1],
+                              this->LastPickPosition[2], focalPoint);
+  z = focalPoint[2];
+  this->ComputeDisplayToWorld(double(this->Interactor->GetLastEventPosition()[0]),
+                              double(this->Interactor->GetLastEventPosition()[1]),
+                              z, prevPickPoint);
+  this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
+
+  // Process the motion
+  if ( this->State == VVTK_ImplicitFunctionWidget::MovingPlane )    {
+    this->TranslatePlane(prevPickPoint, pickPoint);
+  }
+  else if ( this->State == VVTK_ImplicitFunctionWidget::MovingOutline )    {
+    this->TranslateOutline(prevPickPoint, pickPoint);
+  }
+  else if ( this->State == VVTK_ImplicitFunctionWidget::MovingOrigin )    {
+    this->TranslateOrigin(prevPickPoint, pickPoint);
+  }
+  else if ( this->State == VVTK_ImplicitFunctionWidget::Pushing )    {
+    this->Push(prevPickPoint, pickPoint);
+  }
+  else if ( this->State == VVTK_ImplicitFunctionWidget::Scaling )    {
+    this->Scale(prevPickPoint, pickPoint, X, Y);
+  }
+  else if ( this->State == VVTK_ImplicitFunctionWidget::Rotating )    {
+    camera->GetViewPlaneNormal(vpn);
+    this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
+  }
+  else if ( this->State == VVTK_ImplicitFunctionWidget::ChangeDistance )    {
+    this->PushDistance(prevPickPoint, pickPoint);
+  }
+  // Interact, if desired
+  this->EventCallbackCommand->SetAbortFlag(1);
+  this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
+  
+  this->Interactor->Render();
+}
+//==================================================================
+// function: Rotate
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn)
+{
+  double v[3]; //vector of motion
+  double axis[3]; //axis of rotation
+  double theta; //rotation angle
+
+  // mouse motion vector in world space
+  v[0] = p2[0] - p1[0];
+  v[1] = p2[1] - p1[1];
+  v[2] = p2[2] - p1[2];
+
+  float *origin = this->Plane->GetOrigin();
+  float *normal = this->Plane->GetNormal();
+
+  // Create axis of rotation and angle of rotation
+  vtkMath::Cross(vpn,v,axis);
+  if ( vtkMath::Normalize(axis) == 0.0 )    {
+    return;
+  }
+
+  int *size = this->CurrentRenderer->GetSize();
+  double l2 = (X-this->Interactor->GetLastEventPosition()[0])*
+    (X-this->Interactor->GetLastEventPosition()[0]) + 
+    (Y-this->Interactor->GetLastEventPosition()[1])*
+    (Y-this->Interactor->GetLastEventPosition()[1]);
+  theta = 360.0 * sqrt(l2/((double)size[0]*size[0]+size[1]*size[1]));
+
+  //Manipulate the transform to reflect the rotation
+  this->Transform->Identity();
+  this->Transform->Translate(origin[0],origin[1],origin[2]);
+  this->Transform->RotateWXYZ(theta,axis);
+  this->Transform->Translate(-origin[0],-origin[1],-origin[2]);
+
+  //Set the new normal
+  float nNew[3], aN2[3];
+  this->Transform->TransformNormal(normal,nNew);
+  this->Plane->SetNormal(nNew);
+  
+  //modified by NIZNHY-PKV Mon Sep 12 15:32:42 2005f
+  aN2[0]=-nNew[0];
+  aN2[1]=-nNew[1];
+  aN2[2]=-nNew[2];
+  myPlane2->SetNormal(aN2); 
+  float oNew[3]; 
+  vtkMath::Normalize(nNew);
+  oNew[0] = origin[0] + myDistance*nNew[0];
+  oNew[1] = origin[1] + myDistance*nNew[1];
+  oNew[2] = origin[2] + myDistance*nNew[2];
+  myPlane2->SetOrigin(oNew);
+  //modified by NIZNHY-PKV Mon Sep 12 15:32:45 2005t
+  
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: TranslatePlane
+// purpose : Loop through all points and translate them
+//==================================================================
+void VVTK_ImplicitFunctionWidget::TranslatePlane(double *p1, double *p2)
+{
+  //Get the motion vector
+  double v[3];
+  v[0] = p2[0] - p1[0];
+  v[1] = p2[1] - p1[1];
+  v[2] = p2[2] - p1[2];
+  
+  //Translate the plane
+  float oNew[3];
+  float *origin = this->Plane->GetOrigin();
+  oNew[0] = origin[0] + v[0];
+  oNew[1] = origin[1] + v[1];
+  oNew[2] = origin[2] + v[2];
+  this->Plane->SetOrigin(oNew);
+  
+  //modified by NIZNHY-PKV Mon Sep 12 14:05:11 2005f
+  origin = myPlane2->GetOrigin();
+  oNew[0] = origin[0] + v[0];
+  oNew[1] = origin[1] + v[1];
+  oNew[2] = origin[2] + v[2];
+  myPlane2->SetOrigin(oNew);
+  //modified by NIZNHY-PKV Mon Sep 12 14:05:14 2005t
+
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: TranslateOutline
+// purpose :Loop through all points and translate them
+//==================================================================
+void VVTK_ImplicitFunctionWidget::TranslateOutline(double *p1, double *p2)
+{
+  //Get the motion vector
+  double v[3];
+  v[0] = p2[0] - p1[0];
+  v[1] = p2[1] - p1[1];
+  v[2] = p2[2] - p1[2];
+  
+  //Translate the bounding box
+  float *origin = this->Box->GetOrigin();
+  float oNew[3];
+  oNew[0] = origin[0] + v[0];
+  oNew[1] = origin[1] + v[1];
+  oNew[2] = origin[2] + v[2];
+  this->Box->SetOrigin(oNew);
+
+  //Translate the plane
+  origin = this->Plane->GetOrigin();
+  oNew[0] = origin[0] + v[0];
+  oNew[1] = origin[1] + v[1];
+  oNew[2] = origin[2] + v[2];
+  this->Plane->SetOrigin(oNew);
+
+  //modified by NIZNHY-PKV Mon Sep 12 14:07:11 2005f
+  origin = myPlane2->GetOrigin();
+  oNew[0] = origin[0] + v[0];
+  oNew[1] = origin[1] + v[1];
+  oNew[2] = origin[2] + v[2];
+  myPlane2->SetOrigin(oNew);
+  //modified by NIZNHY-PKV Mon Sep 12 14:07:13 2005t
+
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: TranslateOrigin
+// purpose :Loop through all points and translate them
+//==================================================================
+void VVTK_ImplicitFunctionWidget::TranslateOrigin(double *p1, double *p2)
+{
+  //Get the motion vector
+  double v[3];
+  v[0] = p2[0] - p1[0];
+  v[1] = p2[1] - p1[1];
+  v[2] = p2[2] - p1[2];
+  
+  //Add to the current point, project back down onto plane
+  float *o = this->Plane->GetOrigin();
+  float *n = this->Plane->GetNormal();
+  float newOrigin[3];
+
+  newOrigin[0] = o[0] + v[0];
+  newOrigin[1] = o[1] + v[1];
+  newOrigin[2] = o[2] + v[2];
+  
+  vtkPlane::ProjectPoint(newOrigin,o,n,newOrigin);
+  this->SetOrigin(newOrigin);
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: Scale
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::Scale(double *p1, double *p2, 
+                                       int vtkNotUsed(X), int Y)
+{
+  //Get the motion vector
+  double v[3];
+  v[0] = p2[0] - p1[0];
+  v[1] = p2[1] - p1[1];
+  v[2] = p2[2] - p1[2];
+
+  //int res = this->PlaneSource->GetXResolution();
+  float *o = this->Plane->GetOrigin();
+
+  // Compute the scale factor
+  float sf = vtkMath::Norm(v) / this->Outline->GetOutput()->GetLength();
+  if ( Y > this->Interactor->GetLastEventPosition()[1] )    {
+    sf = 1.0 + sf;
+  }
+  else    {
+    sf = 1.0 - sf;
+  }
+  
+  this->Transform->Identity();
+  this->Transform->Translate(o[0],o[1],o[2]);
+  this->Transform->Scale(sf,sf,sf);
+  this->Transform->Translate(-o[0],-o[1],-o[2]);
+
+  float *origin = this->Box->GetOrigin();
+  float *spacing = this->Box->GetSpacing();
+  float oNew[3], p[3], pNew[3];
+  p[0] = origin[0] + spacing[0];
+  p[1] = origin[1] + spacing[1];
+  p[2] = origin[2] + spacing[2];
+
+  this->Transform->TransformPoint(origin,oNew);
+  this->Transform->TransformPoint(p,pNew);
+
+  this->Box->SetOrigin(oNew);
+  this->Box->SetSpacing( (pNew[0]-oNew[0]), (pNew[1]-oNew[1]), (pNew[2]-oNew[2]) );
+
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: Push
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::Push(double *p1, double *p2)
+{
+  //Get the motion vector
+  float v[3];
+  v[0] = p2[0] - p1[0];
+  v[1] = p2[1] - p1[1];
+  v[2] = p2[2] - p1[2];
+  
+  this->Plane->Push( vtkMath::Dot(v,this->Plane->GetNormal()) );
+  this->SetOrigin(this->Plane->GetOrigin());
+  myPlane2->Push( vtkMath::Dot(v,this->Plane->GetNormal()) );//pkv ft
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: PushDistance
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::PushDistance(double *p1, double *p2)
+{
+  float v[3],  *anOrigin1, *aN1, *anOrigin2, aD;
+  //Get the motion vector
+  v[0] = p2[0] - p1[0];
+  v[1] = p2[1] - p1[1];
+  v[2] = p2[2] - p1[2];
+  //
+  myPlane2->Push( vtkMath::Dot(v, myPlane2->GetNormal()));
+  anOrigin1 = Plane->GetOrigin();
+  aN1 = Plane->GetNormal();
+  vtkMath::Normalize(aN1);
+  anOrigin2 = myPlane2->GetOrigin();
+  aD=DistanceToPlane(anOrigin2, aN1, anOrigin1);
+  printf(" aD=%f\n",aD);
+  //
+  myDistance=aD;
+  //
+  this->UpdateRepresentation();
+}
+
+//==================================================================
+// function: CreateDefaultProperties
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::CreateDefaultProperties()
+{
+  // Normal properties
+  this->NormalProperty = vtkProperty::New();
+  this->NormalProperty->SetColor(1,1,1);
+  this->NormalProperty->SetLineWidth(2);
+
+  this->SelectedNormalProperty = vtkProperty::New();
+  this->SelectedNormalProperty->SetColor(1,0,0);
+  this->NormalProperty->SetLineWidth(2);
+
+  // Plane properties
+  this->PlaneProperty = vtkProperty::New();
+  this->PlaneProperty->SetAmbient(1.0);
+  this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
+
+  this->SelectedPlaneProperty = vtkProperty::New();
+  this->SelectedPlaneProperty->SetAmbient(1.0);
+  this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
+  this->SelectedPlaneProperty->SetOpacity(0.75);
+
+  // Outline properties
+  this->OutlineProperty = vtkProperty::New();
+  this->OutlineProperty->SetAmbient(1.0);
+  this->OutlineProperty->SetAmbientColor(1.0,1.0,1.0);
+
+  this->SelectedOutlineProperty = vtkProperty::New();
+  this->SelectedOutlineProperty->SetAmbient(1.0);
+  this->SelectedOutlineProperty->SetAmbientColor(0.0,1.0,0.0);
+
+  // Edge property
+  this->EdgesProperty = vtkProperty::New();
+  this->EdgesProperty->SetAmbient(1.0);
+  this->EdgesProperty->SetAmbientColor(1.0,1.0,1.0);
+}
+//==================================================================
+// function: PlaceWidget
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::PlaceWidget(float bds[6])
+{
+  int i;
+  float bounds[6], origin[3];
+
+  this->AdjustBounds(bds, bounds, origin);
+
+  // Set up the bounding box
+  this->Box->SetOrigin(bounds[0],bounds[2],bounds[4]);
+  this->Box->SetSpacing((bounds[1]-bounds[0]),(bounds[3]-bounds[2]),
+                        (bounds[5]-bounds[4]));
+  this->Outline->Update();
+
+  if (this->Input || this->Prop3D)    {
+    this->LineSource->SetPoint1(this->Plane->GetOrigin());
+    if ( this->NormalToYAxis )      {
+      this->Plane->SetNormal(0,1,0);
+      myPlane2->SetNormal(0,-1,0);//pkv ft
+      this->LineSource->SetPoint2(0,1,0);
+    }
+    else if ( this->NormalToZAxis )      {
+      this->Plane->SetNormal(0,0,1);
+      myPlane2->SetNormal(0,0,-1);//pkv ft
+      this->LineSource->SetPoint2(0,0,1);
+    }
+    else{ //default or x-normal
+      this->Plane->SetNormal(1,0,0);
+      myPlane2->SetNormal(-1,0,0);//pkv ft
+      this->LineSource->SetPoint2(1,0,0);
+    }
+    }
+  
+  for (i=0; i<6; i++)    {
+    this->InitialBounds[i] = bounds[i];
+  }
+
+  this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
+                             (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
+                             (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
+  
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: SetOrigin
+// purpose :Set the origin of the plane.
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetOrigin(float x, float y, float z) 
+{
+  float origin[3];
+  origin[0] = x;
+  origin[1] = y;
+  origin[2] = z;
+  this->SetOrigin(origin);
+}
+//==================================================================
+// function: SetOrigin
+// purpose :Set the origin of the plane.
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetOrigin(float x[3]) 
+{
+  float *bounds = this->Outline->GetOutput()->GetBounds();
+  for (int i=0; i<3; i++)    {
+    if ( x[i] < bounds[2*i] )      {
+      x[i] = bounds[2*i];
+    }
+    else if ( x[i] > bounds[2*i+1] )      {
+      x[i] = bounds[2*i+1];
+    }
+  }
+  this->Plane->SetOrigin(x);
+  //modified by NIZNHY-PKV Mon Sep 12 14:15:39 2005 f
+  float *origin, *normal, oNew[3]; 
+  origin = Plane->GetOrigin();
+  normal = Plane->GetNormal();
+  vtkMath::Normalize(normal);
+  oNew[0] = origin[0] + myDistance*normal[0];
+  oNew[1] = origin[1] + myDistance*normal[1];
+  oNew[2] = origin[2] + myDistance*normal[2];
+  myPlane2->SetOrigin(oNew);
+  //modified by NIZNHY-PKV Mon Sep 12 14:19:43 2005t
+  this->UpdateRepresentation();
+}
+//==================================================================
+// function: GetOrigin
+// purpose :Get the origin of the plane.
+//==================================================================
+float* VVTK_ImplicitFunctionWidget::GetOrigin() 
+{
+  return this->Plane->GetOrigin();
+}
+
+void VVTK_ImplicitFunctionWidget::GetOrigin(float xyz[3]) 
+{
+  this->Plane->GetOrigin(xyz);
+}
+//==================================================================
+// function: SetNormal
+// purpose :Set the normal to the plane.
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetNormal(float x, float y, float z) 
+{
+  float n[3];
+  n[0] = x;
+  n[1] = y;
+  n[2] = z;
+  vtkMath::Normalize(n);
+  this->Plane->SetNormal(n);
+  //modified by NIZNHY-PKV Mon Sep 12 14:21:24 2005f
+  n[0] =- x;
+  n[1] =- y;
+  n[2] =- z;
+  myPlane2->SetNormal(n);
+  //modified by NIZNHY-PKV Mon Sep 12 14:21:25 2005t
+  this->UpdateRepresentation();
+}
+
+//==================================================================
+// function: SetNormal
+// purpose :Set the normal to the plane.
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetNormal(float n[3]) 
+{
+  this->SetNormal(n[0], n[1], n[2]);
+}
+//==================================================================
+// function: GetNormal
+// purpose :Get the normal to the plane.
+//==================================================================
+float* VVTK_ImplicitFunctionWidget::GetNormal() 
+{
+  return this->Plane->GetNormal();
+}
+//==================================================================
+// function: GetNormal
+// purpose :Get the normal to the plane.
+//==================================================================
+void VVTK_ImplicitFunctionWidget::GetNormal(float xyz[3]) 
+{
+  this->Plane->GetNormal(xyz);
+}
+//==================================================================
+// function: SetDrawPlane
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetDrawPlane(int drawPlane)
+{
+  if ( drawPlane == this->DrawPlane )    {
+    return;
+  }
+  
+  this->Modified();
+  this->DrawPlane = drawPlane;
+  if ( this->Enabled )    {
+    if ( drawPlane )      {
+      this->CurrentRenderer->AddActor(this->CutActor);
+      this->CurrentRenderer->AddActor(myCutActor2);//pkv ft
+    }
+    else      {
+      this->CurrentRenderer->RemoveActor(this->CutActor);
+       this->CurrentRenderer->RemoveActor(myCutActor2);//pkv ft
+    }
+    this->Interactor->Render();
+  }
+}
+//==================================================================
+// function: SetNormalToXAxis
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetNormalToXAxis (int var)
+{
+  if (this->NormalToXAxis != var)    {
+    this->NormalToXAxis = var;
+    this->Modified();
+  }
+  if (var)    {
+    this->NormalToYAxisOff();
+    this->NormalToZAxisOff();
+  }
+}
+//==================================================================
+// function: SetNormalToYAxis
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetNormalToYAxis (int var)
+{
+  if (this->NormalToYAxis != var)    {
+    this->NormalToYAxis = var;
+    this->Modified();
+  }
+  if (var)    {
+    this->NormalToXAxisOff();
+    this->NormalToZAxisOff();
+  }
+}
+//==================================================================
+// function: SetNormalToZAxis
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SetNormalToZAxis (int var)
+{
+  if (this->NormalToZAxis != var)    {
+    this->NormalToZAxis = var;
+    this->Modified();
+  }
+  if (var)    {
+    this->NormalToXAxisOff();
+    this->NormalToYAxisOff();
+  }
+}
+//==================================================================
+// function: GetPolyData
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::GetPolyData(vtkPolyData *pd)
+{ 
+  pd->ShallowCopy(this->Cutter->GetOutput()); 
+}
+//==================================================================
+// function: GetPolyDataSource
+// purpose :
+//==================================================================
+vtkPolyDataSource *VVTK_ImplicitFunctionWidget::GetPolyDataSource()
+{
+  return this->Cutter;
+}
+//==================================================================
+// function:GetPlane
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::GetPlane(vtkPlane *plane)
+{
+  if ( plane == NULL )    {
+    return;
+  }
+  
+  plane->SetNormal(this->Plane->GetNormal());
+  plane->SetOrigin(this->Plane->GetOrigin());
+}
+//==================================================================
+// function:UpdatePlacement
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::UpdatePlacement(void)
+{
+  this->Outline->Update();
+  this->Cutter->Update();
+  this->Edges->Update();
+}
+//==================================================================
+// function:UpdateRepresentation
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::UpdateRepresentation()
+{
+  if ( ! this->CurrentRenderer )    {
+    return;
+  }
+
+  float *origin = this->Plane->GetOrigin();
+  float *normal = this->Plane->GetNormal();
+  float p2[3];
+
+  // Setup the plane normal
+  float d = this->Outline->GetOutput()->GetLength();
+
+  p2[0] = origin[0] + 0.30 * d * normal[0];
+  p2[1] = origin[1] + 0.30 * d * normal[1];
+  p2[2] = origin[2] + 0.30 * d * normal[2];
+
+  this->LineSource->SetPoint1(origin);
+  this->LineSource->SetPoint2(p2);
+  this->ConeSource->SetCenter(p2);
+  this->ConeSource->SetDirection(normal);
+
+  p2[0] = origin[0] - 0.30 * d * normal[0];
+  p2[1] = origin[1] - 0.30 * d * normal[1];
+  p2[2] = origin[2] - 0.30 * d * normal[2];
+
+  this->LineSource2->SetPoint1(origin);
+  this->LineSource2->SetPoint2(p2);
+  this->ConeSource2->SetCenter(p2);
+  this->ConeSource2->SetDirection(normal);
+
+  // Set up the position handle
+  this->Sphere->SetCenter(origin);
+
+  // Control the look of the edges
+  if ( this->Tubing )    {
+    this->EdgesMapper->SetInput(this->EdgesTuber->GetOutput());
+  }
+  else     {
+    this->EdgesMapper->SetInput(this->Edges->GetOutput());
+  }
+}
+//==================================================================
+// function:SizeHandles
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::SizeHandles()
+{
+  float radius = this->vtk3DWidget::SizeHandles(1.35);
+
+  this->ConeSource->SetHeight(2.0*radius);
+  this->ConeSource->SetRadius(radius);
+  this->ConeSource2->SetHeight(2.0*radius);
+  this->ConeSource2->SetRadius(radius);
+  
+  this->Sphere->SetRadius(radius);
+
+  this->EdgesTuber->SetRadius(0.25*radius);
+}
+//==================================================================
+// function:PrintSelf
+// purpose :
+//==================================================================
+void VVTK_ImplicitFunctionWidget::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  if ( this->NormalProperty )
+    {
+    os << indent << "Normal Property: " << this->NormalProperty << "\n";
+    }
+  else
+    {
+    os << indent << "Normal Property: (none)\n";
+    }
+  if ( this->SelectedNormalProperty )
+    {
+    os << indent << "Selected Normal Property: " 
+       << this->SelectedNormalProperty << "\n";
+    }
+  else
+    {
+    os << indent << "Selected Normal Property: (none)\n";
+    }
+
+  if ( this->PlaneProperty )
+    {
+    os << indent << "Plane Property: " << this->PlaneProperty << "\n";
+    }
+  else
+    {
+    os << indent << "Plane Property: (none)\n";
+    }
+  if ( this->SelectedPlaneProperty )
+    {
+    os << indent << "Selected Plane Property: " 
+       << this->SelectedPlaneProperty << "\n";
+    }
+  else
+    {
+    os << indent << "Selected Plane Property: (none)\n";
+    }
+
+  if ( this->OutlineProperty )
+    {
+    os << indent << "Outline Property: " << this->OutlineProperty << "\n";
+    }
+  else
+    {
+    os << indent << "Outline Property: (none)\n";
+    }
+  if ( this->SelectedOutlineProperty )
+    {
+    os << indent << "Selected Outline Property: " 
+       << this->SelectedOutlineProperty << "\n";
+    }
+  else
+    {
+    os << indent << "Selected Outline Property: (none)\n";
+    }
+
+  if ( this->EdgesProperty )
+    {
+    os << indent << "Edges Property: " << this->EdgesProperty << "\n";
+    }
+  else
+    {
+    os << indent << "Edges Property: (none)\n";
+    }
+
+  os << indent << "Normal To X Axis: " 
+     << (this->NormalToXAxis ? "On" : "Off") << "\n";
+  os << indent << "Normal To Y Axis: " 
+     << (this->NormalToYAxis ? "On" : "Off") << "\n";
+  os << indent << "Normal To Z Axis: " 
+     << (this->NormalToZAxis ? "On" : "Off") << "\n";
+
+  os << indent << "Tubing: " << (this->Tubing ? "On" : "Off") << "\n";
+  os << indent << "Outline Translation: " 
+     << (this->OutlineTranslation ? "On" : "Off") << "\n";
+  os << indent << "Draw Plane: " << (this->DrawPlane ? "On" : "Off") << "\n";
+}
+//==================================================================
+// function:DistanceToPlane
+// purpose :
+//==================================================================
+float DistanceToPlane(const float x[3], 
+                     const float n[3], 
+                     const float p0[3])
+{
+  return ((float) (n[0]*(x[0]-p0[0]) + 
+                  n[1]*(x[1]-p0[1]) +  
+                  n[2]*(x[2]-p0[2])));
+}
diff --git a/src/VVTK/VVTK_ImplicitFunctionWidget.h b/src/VVTK/VVTK_ImplicitFunctionWidget.h
new file mode 100644 (file)
index 0000000..b810f2f
--- /dev/null
@@ -0,0 +1,303 @@
+//  SALOME VTKViewer : build VTK viewer into Salome desktop
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : VVTK_ImplicitFunctionWidget.h
+//  Author : Peter KURNEV
+//  Module : SALOME
+//  $Header$
+#ifndef __VVTK_ImplicitFunctionWidget_h
+#define __VVTK_ImplicitFunctionWidget_h
+
+#include <vtkPolyDataSourceWidget.h>
+
+class vtkActor;
+class vtkPolyDataMapper;
+class vtkCellPicker;
+class vtkConeSource;
+class vtkLineSource;
+class vtkSphereSource;
+class vtkTubeFilter;
+class vtkPlane;
+class vtkCutter;
+class vtkProperty;
+class vtkImageData;
+class vtkOutlineFilter;
+class vtkFeatureEdges;
+class vtkPolyData;
+class vtkTransform;
+class vtkImplicitBoolean;
+class vtkImplicitFunction;
+class  VVTK_ImplicitFunctionWidget : public vtkPolyDataSourceWidget
+{
+public:
+  // Description:
+  // Instantiate the object.
+  static VVTK_ImplicitFunctionWidget *New();
+
+  vtkTypeRevisionMacro(VVTK_ImplicitFunctionWidget,vtkPolyDataSourceWidget);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  void SetDistance (const float theDistance);
+  float Distance()const;
+  vtkImplicitFunction* ImplicitFunction();
+
+  // Description:
+  // Methods that satisfy the superclass' API.
+  virtual void SetEnabled(int);
+  virtual void PlaceWidget(float bounds[6]);
+  void PlaceWidget()
+    {this->Superclass::PlaceWidget();}
+
+  // Description:
+  // Get the origin of the plane.
+  void SetOrigin(float x, float y, float z);
+  void SetOrigin(float x[3]);
+  float* GetOrigin();
+  void GetOrigin(float xyz[3]);
+
+  // Description:
+  // Get the normal to the plane.
+  void SetNormal(float x, float y, float z);
+  void SetNormal(float x[3]);
+  float* GetNormal();
+  void GetNormal(float xyz[3]);
+  
+  // Description:
+  // Force the plane widget to be aligned with one of the x-y-z axes.
+  // If one axis is set on, the other two will be set off.
+  // Remember that when the state changes, a ModifiedEvent is invoked.
+  // This can be used to snap the plane to the axes if it is orginally
+  // not aligned.
+  void SetNormalToXAxis(int);
+  vtkGetMacro(NormalToXAxis,int);
+  vtkBooleanMacro(NormalToXAxis,int);
+  void SetNormalToYAxis(int);
+  vtkGetMacro(NormalToYAxis,int);
+  vtkBooleanMacro(NormalToYAxis,int);
+  void SetNormalToZAxis(int);
+  vtkGetMacro(NormalToZAxis,int);
+  vtkBooleanMacro(NormalToZAxis,int);
+
+  // Description:
+  // Turn on/off tubing of the wire outline of the plane. The tube thickens
+  // the line by wrapping with a vtkTubeFilter.
+  vtkSetMacro(Tubing,int);
+  vtkGetMacro(Tubing,int);
+  vtkBooleanMacro(Tubing,int);
+
+  // Description:
+  // Enable/disable the drawing of the plane. In some cases the plane
+  // interferes with the object that it is operating on (i.e., the
+  // plane interferes with the cut surface it produces producing
+  // z-buffer artifacts.)
+  void SetDrawPlane(int plane);
+  vtkGetMacro(DrawPlane,int);
+  vtkBooleanMacro(DrawPlane,int);
+
+  // Description:
+  // Turn on/off the ability to translate the bounding box by grabbing it
+  // with the left mouse button.
+  vtkSetMacro(OutlineTranslation,int);
+  vtkGetMacro(OutlineTranslation,int);
+  vtkBooleanMacro(OutlineTranslation,int);
+
+  // Description:
+  // Grab the polydata that defines the plane. The polydata contains a single
+  // polygon that is clipped by the bounding box.
+  void GetPolyData(vtkPolyData *pd);
+
+  // Description:
+  // Satisfies superclass API.  This returns a pointer to the underlying
+  // PolyData (which represents the plane).
+  vtkPolyDataSource* GetPolyDataSource();
+   
+  // Description:
+  // Get the implicit function for the plane. The user must provide the
+  // instance of the class vtkPlane. Note that vtkPlane is a subclass of
+  // vtkImplicitFunction, meaning that it can be used by a variety of filters
+  // to perform clipping, cutting, and selection of data.
+  void GetPlane(vtkPlane *plane);
+
+  // Description:
+  // Satisfies the superclass API.  This will change the state of the widget
+  // to match changes that have been made to the underlying PolyDataSource
+  void UpdatePlacement(void);
+
+  // Description:
+  // Get the properties on the normal (line and cone).
+  vtkGetObjectMacro(NormalProperty,vtkProperty);
+  vtkGetObjectMacro(SelectedNormalProperty,vtkProperty);
+  
+  // Description:
+  // Get the plane properties. The properties of the plane when selected 
+  // and unselected can be manipulated.
+  vtkGetObjectMacro(PlaneProperty,vtkProperty);
+  vtkGetObjectMacro(SelectedPlaneProperty,vtkProperty);
+
+  // Description:
+  // Get the property of the outline.
+  vtkGetObjectMacro(OutlineProperty,vtkProperty);
+  vtkGetObjectMacro(SelectedOutlineProperty,vtkProperty);
+
+  // Description:
+  // Get the property of the intersection edges. (This property also
+  // applies to the edges when tubed.)
+  vtkGetObjectMacro(EdgesProperty,vtkProperty);
+
+protected:
+  VVTK_ImplicitFunctionWidget();
+  ~VVTK_ImplicitFunctionWidget();
+
+//BTX - manage the state of the widget
+  int State;
+  enum WidgetState
+  {
+    Start=0,
+    MovingPlane,
+    MovingOutline,
+    MovingOrigin,
+    Scaling,
+    Pushing,
+    Rotating,
+    Outside,
+    ChangeDistance //pkv ft
+  };
+//ETX
+    
+  //handles the events
+  static void ProcessEvents(vtkObject* object, unsigned long event,
+                            void* clientdata, void* calldata);
+
+  // ProcessEvents() dispatches to these methods.
+  void OnLeftButtonDown();
+  void OnLeftButtonUp();
+  void OnMiddleButtonDown();
+  void OnMiddleButtonUp();
+  void OnRightButtonDown();
+  void OnRightButtonUp();
+  void OnMouseMove();
+
+  // Controlling ivars
+  int NormalToXAxis;
+  int NormalToYAxis;
+  int NormalToZAxis;
+  void UpdateRepresentation();
+
+  // The actual plane which is being manipulated
+  vtkPlane *Plane;
+  //pkv f
+  vtkPlane *myPlane2;
+  float myDistance; 
+  vtkImplicitBoolean *myImplicitfunction;
+  //pkv t
+  // The bounding box is represented by a single voxel image data
+  vtkImageData      *Box;
+  vtkOutlineFilter  *Outline;
+  vtkPolyDataMapper *OutlineMapper;
+  vtkActor          *OutlineActor;
+  void HighlightOutline(int highlight);
+  int OutlineTranslation; //whether the outline can be moved
+  
+  // The cut plane is produced with a vtkCutter
+  vtkCutter         *Cutter;
+  vtkPolyDataMapper *CutMapper;
+  vtkActor          *CutActor;
+
+  vtkCutter         *myCutter2;//pkv ft
+  vtkPolyDataMapper *myCutMapper2;//pkv ft
+  vtkActor          *myCutActor2;//pkv ft
+
+  int               DrawPlane;
+  void HighlightPlane(int highlight);
+  
+  // Optional tubes are represented by extracting boundary edges and tubing
+  vtkFeatureEdges   *Edges;
+  vtkTubeFilter     *EdgesTuber;
+  vtkPolyDataMapper *EdgesMapper;
+  vtkActor          *EdgesActor;
+  int               Tubing; //control whether tubing is on
+
+  // The + normal cone
+  vtkConeSource     *ConeSource;
+  vtkPolyDataMapper *ConeMapper;
+  vtkActor          *ConeActor;
+  void HighlightNormal(int highlight);
+
+  // The + normal line
+  vtkLineSource     *LineSource;
+  vtkPolyDataMapper *LineMapper;
+  vtkActor          *LineActor;
+
+  // The - normal cone
+  vtkConeSource     *ConeSource2;
+  vtkPolyDataMapper *ConeMapper2;
+  vtkActor          *ConeActor2;
+
+  // The - normal line
+  vtkLineSource     *LineSource2;
+  vtkPolyDataMapper *LineMapper2;
+  vtkActor          *LineActor2;
+
+  // The origin positioning handle
+  vtkSphereSource   *Sphere;
+  vtkPolyDataMapper *SphereMapper;
+  vtkActor          *SphereActor;
+
+  // Do the picking
+  vtkCellPicker *Picker;
+  
+  // Transform the normal (used for rotation)
+  vtkTransform *Transform;
+  
+  // Methods to manipulate the plane
+  void ConstrainOrigin(float x[3]);
+  void Rotate(int X, int Y, double *p1, double *p2, double *vpn);
+  void TranslatePlane(double *p1, double *p2);
+  void TranslateOutline(double *p1, double *p2);
+  void TranslateOrigin(double *p1, double *p2);
+  void Push(double *p1, double *p2);
+  void Scale(double *p1, double *p2, int X, int Y);
+  void PushDistance(double *p1, double *p2);
+  
+  // Properties used to control the appearance of selected objects and
+  // the manipulator in general.
+  vtkProperty *NormalProperty;
+  vtkProperty *SelectedNormalProperty;
+  vtkProperty *PlaneProperty;
+  vtkProperty *SelectedPlaneProperty;
+  vtkProperty *OutlineProperty;
+  vtkProperty *SelectedOutlineProperty;
+  vtkProperty *EdgesProperty;
+  
+  void CreateDefaultProperties();
+  
+  void GeneratePlane();
+  virtual void SizeHandles();
+  
+private:
+  VVTK_ImplicitFunctionWidget(const VVTK_ImplicitFunctionWidget&);  //Not implemented
+  void operator=(const VVTK_ImplicitFunctionWidget&);  //Not implemented
+};
+
+#endif