From 5e61ae0a3702a1344f08e610d35c5856cfe5c82f Mon Sep 17 00:00:00 2001 From: pkv Date: Wed, 14 Sep 2005 06:12:46 +0000 Subject: [PATCH] Adds the class VVTK_ImplicitFunctionWidget providing clipping functionality --- src/VVTK/Makefile.in | 6 +- src/VVTK/VVTK_ImplicitFunctionWidget.cxx | 1467 ++++++++++++++++++++++ src/VVTK/VVTK_ImplicitFunctionWidget.h | 303 +++++ 3 files changed, 1774 insertions(+), 2 deletions(-) create mode 100644 src/VVTK/VVTK_ImplicitFunctionWidget.cxx create mode 100644 src/VVTK/VVTK_ImplicitFunctionWidget.h diff --git a/src/VVTK/Makefile.in b/src/VVTK/Makefile.in index 6ebf0a3d..90120485 100755 --- a/src/VVTK/Makefile.in +++ b/src/VVTK/Makefile.in @@ -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 index 00000000..4e026f9a --- /dev/null +++ b/src/VVTK/VVTK_ImplicitFunctionWidget.cxx @@ -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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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( 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 index 00000000..b810f2f0 --- /dev/null +++ b/src/VVTK/VVTK_ImplicitFunctionWidget.h @@ -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 + +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 -- 2.39.2