1 /*=========================================================================
3 Program: Visualization Toolkit
4 Module: vtkImplicitPlaneWidget.cxx
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
14 =========================================================================*/
15 #include "vtkImplicitPlaneWidget.h"
18 #include "vtkAssemblyNode.h"
19 #include "vtkAssemblyPath.h"
20 #include "vtkCallbackCommand.h"
21 #include "vtkCamera.h"
22 #include "vtkCellPicker.h"
23 #include "vtkConeSource.h"
24 #include "vtkCutter.h"
25 #include "vtkFeatureEdges.h"
26 #include "vtkImageData.h"
27 #include "vtkLineSource.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkOutlineFilter.h"
32 #include "vtkPolyData.h"
33 #include "vtkPolyDataMapper.h"
34 #include "vtkProperty.h"
35 #include "vtkRenderWindowInteractor.h"
36 #include "vtkRenderer.h"
37 #include "vtkSphereSource.h"
38 #include "vtkTransform.h"
39 #include "vtkTubeFilter.h"
41 vtkCxxRevisionMacro(vtkImplicitPlaneWidget, "1.10");
42 vtkStandardNewMacro(vtkImplicitPlaneWidget);
44 //----------------------------------------------------------------------------
45 vtkImplicitPlaneWidget::vtkImplicitPlaneWidget() : vtkPolyDataSourceWidget()
47 this->DiagonalRatio = 0.3;
48 this->State = vtkImplicitPlaneWidget::Start;
49 this->EventCallbackCommand->SetCallback(vtkImplicitPlaneWidget::ProcessEvents);
51 this->NormalToXAxis = 0;
52 this->NormalToYAxis = 0;
53 this->NormalToZAxis = 0;
55 // Build the representation of the widget
57 this->Plane = vtkPlane::New();
58 this->Plane->SetNormal(0,0,1);
59 this->Plane->SetOrigin(0,0,0);
61 this->Box = vtkImageData::New();
62 this->Box->SetDimensions(2,2,2);
63 this->Outline = vtkOutlineFilter::New();
64 this->Outline->SetInput(this->Box);
65 this->OutlineMapper = vtkPolyDataMapper::New();
66 this->OutlineMapper->SetInput(this->Outline->GetOutput());
67 this->OutlineActor = vtkActor::New();
68 this->OutlineActor->SetMapper(this->OutlineMapper);
69 this->OutlineTranslation = 1;
70 this->ScaleEnabled = 1;
71 this->OutsideBounds = 1;
73 this->Cutter = vtkCutter::New();
74 this->Cutter->SetInput(this->Box);
75 this->Cutter->SetCutFunction(this->Plane);
76 this->CutMapper = vtkPolyDataMapper::New();
77 this->CutMapper->SetInput(this->Cutter->GetOutput());
78 this->CutActor = vtkActor::New();
79 this->CutActor->SetMapper(this->CutMapper);
82 this->Edges = vtkFeatureEdges::New();
83 this->Edges->SetInput(this->Cutter->GetOutput());
84 this->EdgesTuber = vtkTubeFilter::New();
85 this->EdgesTuber->SetInput(this->Edges->GetOutput());
86 this->EdgesTuber->SetNumberOfSides(12);
87 this->EdgesMapper = vtkPolyDataMapper::New();
88 this->EdgesMapper->SetInput(this->EdgesTuber->GetOutput());
89 this->EdgesActor = vtkActor::New();
90 this->EdgesActor->SetMapper(this->EdgesMapper);
91 this->Tubing = 1; //control whether tubing is on
93 // Create the + plane normal
94 this->LineSource = vtkLineSource::New();
95 this->LineSource->SetResolution(1);
96 this->LineMapper = vtkPolyDataMapper::New();
97 this->LineMapper->SetInput(this->LineSource->GetOutput());
98 this->LineActor = vtkActor::New();
99 this->LineActor->SetMapper(this->LineMapper);
101 this->ConeSource = vtkConeSource::New();
102 this->ConeSource->SetResolution(12);
103 this->ConeSource->SetAngle(25.0);
104 this->ConeMapper = vtkPolyDataMapper::New();
105 this->ConeMapper->SetInput(this->ConeSource->GetOutput());
106 this->ConeActor = vtkActor::New();
107 this->ConeActor->SetMapper(this->ConeMapper);
109 // Create the - plane normal
110 this->LineSource2 = vtkLineSource::New();
111 this->LineSource2->SetResolution(1);
112 this->LineMapper2 = vtkPolyDataMapper::New();
113 this->LineMapper2->SetInput(this->LineSource2->GetOutput());
114 this->LineActor2 = vtkActor::New();
115 this->LineActor2->SetMapper(this->LineMapper2);
117 this->ConeSource2 = vtkConeSource::New();
118 this->ConeSource2->SetResolution(12);
119 this->ConeSource2->SetAngle(25.0);
120 this->ConeMapper2 = vtkPolyDataMapper::New();
121 this->ConeMapper2->SetInput(this->ConeSource2->GetOutput());
122 this->ConeActor2 = vtkActor::New();
123 this->ConeActor2->SetMapper(this->ConeMapper2);
125 // Create the origin handle
126 this->Sphere = vtkSphereSource::New();
127 this->Sphere->SetThetaResolution(16);
128 this->Sphere->SetPhiResolution(8);
129 this->SphereMapper = vtkPolyDataMapper::New();
130 this->SphereMapper->SetInput(this->Sphere->GetOutput());
131 this->SphereActor = vtkActor::New();
132 this->SphereActor->SetMapper(this->SphereMapper);
133 this->OriginTranslation = 1;
135 this->Transform = vtkTransform::New();
137 // Define the point coordinates
146 // Initial creation of the widget, serves to initialize it
147 this->PlaceWidget(bounds);
149 //Manage the picking stuff
150 this->Picker = vtkCellPicker::New();
151 this->Picker->SetTolerance(0.005);
152 this->Picker->AddPickList(this->CutActor);
153 this->Picker->AddPickList(this->LineActor);
154 this->Picker->AddPickList(this->ConeActor);
155 this->Picker->AddPickList(this->LineActor2);
156 this->Picker->AddPickList(this->ConeActor2);
157 this->Picker->AddPickList(this->SphereActor);
158 this->Picker->AddPickList(this->OutlineActor);
159 this->Picker->PickFromListOn();
161 // Set up the initial properties
162 this->CreateDefaultProperties();
165 //----------------------------------------------------------------------------
166 vtkImplicitPlaneWidget::~vtkImplicitPlaneWidget()
168 this->Plane->Delete();
170 this->Outline->Delete();
171 this->OutlineMapper->Delete();
172 this->OutlineActor->Delete();
174 this->Cutter->Delete();
175 this->CutMapper->Delete();
176 this->CutActor->Delete();
178 this->Edges->Delete();
179 this->EdgesTuber->Delete();
180 this->EdgesMapper->Delete();
181 this->EdgesActor->Delete();
183 this->LineSource->Delete();
184 this->LineMapper->Delete();
185 this->LineActor->Delete();
187 this->ConeSource->Delete();
188 this->ConeMapper->Delete();
189 this->ConeActor->Delete();
191 this->LineSource2->Delete();
192 this->LineMapper2->Delete();
193 this->LineActor2->Delete();
195 this->ConeSource2->Delete();
196 this->ConeMapper2->Delete();
197 this->ConeActor2->Delete();
199 this->Sphere->Delete();
200 this->SphereMapper->Delete();
201 this->SphereActor->Delete();
203 this->Transform->Delete();
205 this->Picker->Delete();
207 this->NormalProperty->Delete();
208 this->SelectedNormalProperty->Delete();
209 this->PlaneProperty->Delete();
210 this->SelectedPlaneProperty->Delete();
211 this->OutlineProperty->Delete();
212 this->SelectedOutlineProperty->Delete();
213 this->EdgesProperty->Delete();
216 //----------------------------------------------------------------------------
217 void vtkImplicitPlaneWidget::SetEnabled(int enabling)
219 if ( ! this->Interactor )
221 vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
225 if ( enabling ) //------------------------------------------------------------
227 vtkDebugMacro(<<"Enabling plane widget");
229 if ( this->Enabled ) //already enabled, just return
234 if ( ! this->CurrentRenderer )
236 this->SetCurrentRenderer(this->Interactor->FindPokedRenderer(
237 this->Interactor->GetLastEventPosition()[0],
238 this->Interactor->GetLastEventPosition()[1]));
239 if (this->CurrentRenderer == NULL)
247 // listen for the following events
248 vtkRenderWindowInteractor *i = this->Interactor;
249 i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand,
251 i->AddObserver(vtkCommand::LeftButtonPressEvent,
252 this->EventCallbackCommand, this->Priority);
253 i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
254 this->EventCallbackCommand, this->Priority);
255 i->AddObserver(vtkCommand::MiddleButtonPressEvent,
256 this->EventCallbackCommand, this->Priority);
257 i->AddObserver(vtkCommand::MiddleButtonReleaseEvent,
258 this->EventCallbackCommand, this->Priority);
259 i->AddObserver(vtkCommand::RightButtonPressEvent,
260 this->EventCallbackCommand, this->Priority);
261 i->AddObserver(vtkCommand::RightButtonReleaseEvent,
262 this->EventCallbackCommand, this->Priority);
265 this->CurrentRenderer->AddActor(this->OutlineActor);
266 this->OutlineActor->SetProperty(this->OutlineProperty);
269 this->CurrentRenderer->AddActor(this->EdgesActor);
270 this->EdgesActor->SetProperty(this->EdgesProperty);
272 // add the normal vector
273 this->CurrentRenderer->AddActor(this->LineActor);
274 this->LineActor->SetProperty(this->NormalProperty);
275 this->CurrentRenderer->AddActor(this->ConeActor);
276 this->ConeActor->SetProperty(this->NormalProperty);
278 this->CurrentRenderer->AddActor(this->LineActor2);
279 this->LineActor2->SetProperty(this->NormalProperty);
280 this->CurrentRenderer->AddActor(this->ConeActor2);
281 this->ConeActor2->SetProperty(this->NormalProperty);
283 // add the origin handle
284 this->CurrentRenderer->AddActor(this->SphereActor);
285 this->SphereActor->SetProperty(this->NormalProperty);
287 // add the plane (if desired)
288 if ( this->DrawPlane )
290 this->CurrentRenderer->AddActor(this->CutActor);
292 this->CutActor->SetProperty(this->PlaneProperty);
294 this->UpdateRepresentation();
296 this->InvokeEvent(vtkCommand::EnableEvent,NULL);
299 else //disabling----------------------------------------------------------
301 vtkDebugMacro(<<"Disabling plane widget");
303 if ( ! this->Enabled ) //already disabled, just return
310 // don't listen for events any more
311 this->Interactor->RemoveObserver(this->EventCallbackCommand);
313 // turn off the various actors
314 this->CurrentRenderer->RemoveActor(this->OutlineActor);
315 this->CurrentRenderer->RemoveActor(this->EdgesActor);
316 this->CurrentRenderer->RemoveActor(this->LineActor);
317 this->CurrentRenderer->RemoveActor(this->ConeActor);
318 this->CurrentRenderer->RemoveActor(this->LineActor2);
319 this->CurrentRenderer->RemoveActor(this->ConeActor2);
320 this->CurrentRenderer->RemoveActor(this->SphereActor);
321 this->CurrentRenderer->RemoveActor(this->CutActor);
323 this->InvokeEvent(vtkCommand::DisableEvent,NULL);
324 this->SetCurrentRenderer(NULL);
327 this->Interactor->Render();
330 //----------------------------------------------------------------------------
331 void vtkImplicitPlaneWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
334 void* vtkNotUsed(calldata))
336 vtkImplicitPlaneWidget* self =
337 reinterpret_cast<vtkImplicitPlaneWidget *>( clientdata );
339 //okay, let's do the right thing
342 case vtkCommand::LeftButtonPressEvent:
343 self->OnLeftButtonDown();
345 case vtkCommand::LeftButtonReleaseEvent:
346 self->OnLeftButtonUp();
348 case vtkCommand::MiddleButtonPressEvent:
349 self->OnMiddleButtonDown();
351 case vtkCommand::MiddleButtonReleaseEvent:
352 self->OnMiddleButtonUp();
354 case vtkCommand::RightButtonPressEvent:
355 self->OnRightButtonDown();
357 case vtkCommand::RightButtonReleaseEvent:
358 self->OnRightButtonUp();
360 case vtkCommand::MouseMoveEvent:
366 //----------------------------------------------------------------------------
367 void vtkImplicitPlaneWidget::PrintSelf(ostream& os, vtkIndent indent)
369 this->Superclass::PrintSelf(os,indent);
371 if ( this->NormalProperty )
373 os << indent << "Normal Property: " << this->NormalProperty << "\n";
377 os << indent << "Normal Property: (none)\n";
379 if ( this->SelectedNormalProperty )
381 os << indent << "Selected Normal Property: "
382 << this->SelectedNormalProperty << "\n";
386 os << indent << "Selected Normal Property: (none)\n";
389 if ( this->PlaneProperty )
391 os << indent << "Plane Property: " << this->PlaneProperty << "\n";
395 os << indent << "Plane Property: (none)\n";
397 if ( this->SelectedPlaneProperty )
399 os << indent << "Selected Plane Property: "
400 << this->SelectedPlaneProperty << "\n";
404 os << indent << "Selected Plane Property: (none)\n";
407 if ( this->OutlineProperty )
409 os << indent << "Outline Property: " << this->OutlineProperty << "\n";
413 os << indent << "Outline Property: (none)\n";
415 if ( this->SelectedOutlineProperty )
417 os << indent << "Selected Outline Property: "
418 << this->SelectedOutlineProperty << "\n";
422 os << indent << "Selected Outline Property: (none)\n";
425 if ( this->EdgesProperty )
427 os << indent << "Edges Property: " << this->EdgesProperty << "\n";
431 os << indent << "Edges Property: (none)\n";
434 os << indent << "Normal To X Axis: "
435 << (this->NormalToXAxis ? "On" : "Off") << "\n";
436 os << indent << "Normal To Y Axis: "
437 << (this->NormalToYAxis ? "On" : "Off") << "\n";
438 os << indent << "Normal To Z Axis: "
439 << (this->NormalToZAxis ? "On" : "Off") << "\n";
441 os << indent << "Tubing: " << (this->Tubing ? "On" : "Off") << "\n";
442 os << indent << "Origin Translation: "
443 << (this->OriginTranslation ? "On" : "Off") << "\n";
444 os << indent << "Outline Translation: "
445 << (this->OutlineTranslation ? "On" : "Off") << "\n";
446 os << indent << "Outside Bounds: "
447 << (this->OutsideBounds ? "On" : "Off") << "\n";
448 os << indent << "Scale Enabled: "
449 << (this->ScaleEnabled ? "On" : "Off") << "\n";
450 os << indent << "Draw Plane: " << (this->DrawPlane ? "On" : "Off") << "\n";
452 os << indent << "Diagonal Ratio: " << this->DiagonalRatio << "\n";
456 //----------------------------------------------------------------------------
457 void vtkImplicitPlaneWidget::HighlightNormal(int highlight)
461 this->LineActor->SetProperty(this->SelectedNormalProperty);
462 this->ConeActor->SetProperty(this->SelectedNormalProperty);
463 this->LineActor2->SetProperty(this->SelectedNormalProperty);
464 this->ConeActor2->SetProperty(this->SelectedNormalProperty);
465 this->SphereActor->SetProperty(this->SelectedNormalProperty);
469 this->LineActor->SetProperty(this->NormalProperty);
470 this->ConeActor->SetProperty(this->NormalProperty);
471 this->LineActor2->SetProperty(this->NormalProperty);
472 this->ConeActor2->SetProperty(this->NormalProperty);
473 this->SphereActor->SetProperty(this->NormalProperty);
478 //----------------------------------------------------------------------------
479 void vtkImplicitPlaneWidget::HighlightPlane(int highlight)
483 this->CutActor->SetProperty(this->SelectedPlaneProperty);
487 this->CutActor->SetProperty(this->PlaneProperty);
492 //----------------------------------------------------------------------------
493 void vtkImplicitPlaneWidget::HighlightOutline(int highlight)
497 this->OutlineActor->SetProperty(this->SelectedOutlineProperty);
501 this->OutlineActor->SetProperty(this->OutlineProperty);
506 //----------------------------------------------------------------------------
507 void vtkImplicitPlaneWidget::OnLeftButtonDown()
509 // We're only here if we are enabled
510 int X = this->Interactor->GetEventPosition()[0];
511 int Y = this->Interactor->GetEventPosition()[1];
513 // Okay, we can process this. See if we've picked anything.
514 // Make sure it's in the activated renderer
515 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
517 this->State = vtkImplicitPlaneWidget::Outside;
521 vtkAssemblyPath *path;
522 this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
523 path = this->Picker->GetPath();
525 if ( path == NULL ) //not picking this widget
527 this->HighlightPlane(0);
528 this->HighlightNormal(0);
529 this->HighlightOutline(0);
530 this->State = vtkImplicitPlaneWidget::Outside;
534 vtkProp *prop = path->GetFirstNode()->GetViewProp();
536 this->Picker->GetPickPosition(this->LastPickPosition);
537 if ( prop == this->ConeActor || prop == this->LineActor ||
538 prop == this->ConeActor2 || prop == this->LineActor2 )
540 this->HighlightPlane(1);
541 this->HighlightNormal(1);
542 this->State = vtkImplicitPlaneWidget::Rotating;
544 else if ( prop == this->CutActor )
546 this->HighlightPlane(1);
547 this->State = vtkImplicitPlaneWidget::Pushing;
549 else if ( prop == this->SphereActor )
551 if ( this->OriginTranslation )
553 this->HighlightNormal(1);
554 this->State = vtkImplicitPlaneWidget::MovingOrigin;
559 if ( this->OutlineTranslation )
561 this->HighlightOutline(1);
562 this->State = vtkImplicitPlaneWidget::MovingOutline;
566 this->EventCallbackCommand->SetAbortFlag(1);
567 this->StartInteraction();
568 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
569 this->Interactor->Render();
572 //----------------------------------------------------------------------------
573 void vtkImplicitPlaneWidget::OnLeftButtonUp()
575 if ( this->State == vtkImplicitPlaneWidget::Outside )
580 this->State = vtkImplicitPlaneWidget::Start;
581 this->HighlightPlane(0);
582 this->HighlightOutline(0);
583 this->HighlightNormal(0);
586 this->EventCallbackCommand->SetAbortFlag(1);
587 this->EndInteraction();
588 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
589 this->Interactor->Render();
592 //----------------------------------------------------------------------------
593 void vtkImplicitPlaneWidget::OnMiddleButtonDown()
595 int X = this->Interactor->GetEventPosition()[0];
596 int Y = this->Interactor->GetEventPosition()[1];
598 // Okay, we can process this. See if we've picked anything.
599 // Make sure it's in the activated renderer
600 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
602 this->State = vtkImplicitPlaneWidget::Outside;
606 // Okay, we can process this.
607 vtkAssemblyPath *path;
608 this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
609 path = this->Picker->GetPath();
611 if ( path == NULL ) //nothing picked
613 this->State = vtkImplicitPlaneWidget::Outside;
618 this->Picker->GetPickPosition(this->LastPickPosition);
619 this->State = vtkImplicitPlaneWidget::MovingPlane;
620 this->HighlightNormal(1);
621 this->HighlightPlane(1);
623 this->EventCallbackCommand->SetAbortFlag(1);
624 this->StartInteraction();
625 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
626 this->Interactor->Render();
629 //----------------------------------------------------------------------------
630 void vtkImplicitPlaneWidget::OnMiddleButtonUp()
632 if ( this->State == vtkImplicitPlaneWidget::Outside )
637 this->State = vtkImplicitPlaneWidget::Start;
638 this->HighlightPlane(0);
639 this->HighlightOutline(0);
640 this->HighlightNormal(0);
643 this->EventCallbackCommand->SetAbortFlag(1);
644 this->EndInteraction();
645 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
646 this->Interactor->Render();
649 //----------------------------------------------------------------------------
650 void vtkImplicitPlaneWidget::OnRightButtonDown()
652 if ( this->ScaleEnabled )
654 this->State = vtkImplicitPlaneWidget::Scaling;
656 int X = this->Interactor->GetEventPosition()[0];
657 int Y = this->Interactor->GetEventPosition()[1];
659 // Okay, we can process this. See if we've picked anything.
660 // Make sure it's in the activated renderer
661 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
663 this->State = vtkImplicitPlaneWidget::Outside;
667 // Okay, we can process this. Try to pick handles first;
668 // if no handles picked, then pick the bounding box.
669 vtkAssemblyPath *path;
670 this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
671 path = this->Picker->GetPath();
672 if ( path == NULL ) //nothing picked
674 this->State = vtkImplicitPlaneWidget::Outside;
679 this->Picker->GetPickPosition(this->LastPickPosition);
680 this->HighlightPlane(1);
681 this->HighlightOutline(1);
682 this->HighlightNormal(1);
684 this->EventCallbackCommand->SetAbortFlag(1);
685 this->StartInteraction();
686 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
687 this->Interactor->Render();
691 //----------------------------------------------------------------------------
692 void vtkImplicitPlaneWidget::OnRightButtonUp()
694 if ( this->State == vtkImplicitPlaneWidget::Outside )
699 this->State = vtkImplicitPlaneWidget::Start;
700 this->HighlightPlane(0);
701 this->HighlightOutline(0);
702 this->HighlightNormal(0);
705 this->EventCallbackCommand->SetAbortFlag(1);
706 this->EndInteraction();
707 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
708 this->Interactor->Render();
711 //----------------------------------------------------------------------------
712 void vtkImplicitPlaneWidget::OnMouseMove()
714 // See whether we're active
715 if ( this->State == vtkImplicitPlaneWidget::Outside ||
716 this->State == vtkImplicitPlaneWidget::Start )
721 int X = this->Interactor->GetEventPosition()[0];
722 int Y = this->Interactor->GetEventPosition()[1];
724 // Do different things depending on state
725 // Calculations everybody does
726 double focalPoint[4], pickPoint[4], prevPickPoint[4];
729 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
735 // Compute the two points defining the motion vector
736 this->ComputeWorldToDisplay(this->LastPickPosition[0], this->LastPickPosition[1],
737 this->LastPickPosition[2], focalPoint);
739 this->ComputeDisplayToWorld(double(this->Interactor->GetLastEventPosition()[0]),
740 double(this->Interactor->GetLastEventPosition()[1]),
742 this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
744 // Process the motion
745 if ( this->State == vtkImplicitPlaneWidget::MovingPlane )
747 this->TranslatePlane(prevPickPoint, pickPoint);
749 else if ( this->State == vtkImplicitPlaneWidget::MovingOutline )
751 this->TranslateOutline(prevPickPoint, pickPoint);
753 else if ( this->State == vtkImplicitPlaneWidget::MovingOrigin )
755 this->TranslateOrigin(prevPickPoint, pickPoint);
757 else if ( this->State == vtkImplicitPlaneWidget::Pushing )
759 this->Push(prevPickPoint, pickPoint);
761 else if ( this->State == vtkImplicitPlaneWidget::Scaling )
763 this->Scale(prevPickPoint, pickPoint, X, Y);
765 else if ( this->State == vtkImplicitPlaneWidget::Rotating )
767 camera->GetViewPlaneNormal(vpn);
768 this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
771 // Interact, if desired
772 this->EventCallbackCommand->SetAbortFlag(1);
773 this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
775 this->Interactor->Render();
778 //----------------------------------------------------------------------------
779 void vtkImplicitPlaneWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn)
781 double v[3]; //vector of motion
782 double axis[3]; //axis of rotation
783 double theta; //rotation angle
785 // mouse motion vector in world space
786 v[0] = p2[0] - p1[0];
787 v[1] = p2[1] - p1[1];
788 v[2] = p2[2] - p1[2];
790 double *origin = this->Plane->GetOrigin();
791 double *normal = this->Plane->GetNormal();
793 // Create axis of rotation and angle of rotation
794 vtkMath::Cross(vpn,v,axis);
795 if ( vtkMath::Normalize(axis) == 0.0 )
799 int *size = this->CurrentRenderer->GetSize();
800 double l2 = (X-this->Interactor->GetLastEventPosition()[0])
801 *(X-this->Interactor->GetLastEventPosition()[0])
802 +(Y-this->Interactor->GetLastEventPosition()[1])
803 *(Y-this->Interactor->GetLastEventPosition()[1]);
804 theta = 360.0 * sqrt(l2/((double)size[0]*size[0]+size[1]*size[1]));
806 //Manipulate the transform to reflect the rotation
807 this->Transform->Identity();
808 this->Transform->Translate(origin[0],origin[1],origin[2]);
809 this->Transform->RotateWXYZ(theta,axis);
810 this->Transform->Translate(-origin[0],-origin[1],-origin[2]);
814 this->Transform->TransformNormal(normal,nNew);
815 this->Plane->SetNormal(nNew);
817 this->UpdateRepresentation();
820 //----------------------------------------------------------------------------
821 // Loop through all points and translate them
822 void vtkImplicitPlaneWidget::TranslatePlane(double *p1, double *p2)
824 //Get the motion vector
826 v[0] = p2[0] - p1[0];
827 v[1] = p2[1] - p1[1];
828 v[2] = p2[2] - p1[2];
830 //Translate the plane
832 double *origin = this->Plane->GetOrigin();
833 oNew[0] = origin[0] + v[0];
834 oNew[1] = origin[1] + v[1];
835 oNew[2] = origin[2] + v[2];
836 this->Plane->SetOrigin(oNew);
838 this->UpdateRepresentation();
841 //----------------------------------------------------------------------------
842 // Loop through all points and translate them
843 void vtkImplicitPlaneWidget::TranslateOutline(double *p1, double *p2)
845 //Get the motion vector
847 v[0] = p2[0] - p1[0];
848 v[1] = p2[1] - p1[1];
849 v[2] = p2[2] - p1[2];
851 //Translate the bounding box
852 double *origin = this->Box->GetOrigin();
854 oNew[0] = origin[0] + v[0];
855 oNew[1] = origin[1] + v[1];
856 oNew[2] = origin[2] + v[2];
857 this->Box->SetOrigin(oNew);
859 //Translate the plane
860 origin = this->Plane->GetOrigin();
861 oNew[0] = origin[0] + v[0];
862 oNew[1] = origin[1] + v[1];
863 oNew[2] = origin[2] + v[2];
864 this->Plane->SetOrigin(oNew);
866 this->UpdateRepresentation();
869 //----------------------------------------------------------------------------
870 // Loop through all points and translate them
871 void vtkImplicitPlaneWidget::TranslateOrigin(double *p1, double *p2)
873 //Get the motion vector
875 v[0] = p2[0] - p1[0];
876 v[1] = p2[1] - p1[1];
877 v[2] = p2[2] - p1[2];
879 //Add to the current point, project back down onto plane
880 double *o = this->Plane->GetOrigin();
881 double *n = this->Plane->GetNormal();
884 newOrigin[0] = o[0] + v[0];
885 newOrigin[1] = o[1] + v[1];
886 newOrigin[2] = o[2] + v[2];
888 vtkPlane::ProjectPoint(newOrigin,o,n,newOrigin);
889 this->SetOrigin(newOrigin[0],newOrigin[1],newOrigin[2]);
890 this->UpdateRepresentation();
893 //----------------------------------------------------------------------------
894 void vtkImplicitPlaneWidget::Scale(double *p1, double *p2,
895 int vtkNotUsed(X), int Y)
897 //Get the motion vector
899 v[0] = p2[0] - p1[0];
900 v[1] = p2[1] - p1[1];
901 v[2] = p2[2] - p1[2];
903 double *o = this->Plane->GetOrigin();
905 // Compute the scale factor
906 double sf = vtkMath::Norm(v) / this->Outline->GetOutput()->GetLength();
907 if ( Y > this->Interactor->GetLastEventPosition()[1] )
916 this->Transform->Identity();
917 this->Transform->Translate(o[0],o[1],o[2]);
918 this->Transform->Scale(sf,sf,sf);
919 this->Transform->Translate(-o[0],-o[1],-o[2]);
921 double *origin = this->Box->GetOrigin();
922 double *spacing = this->Box->GetSpacing();
923 double oNew[3], p[3], pNew[3];
924 p[0] = origin[0] + spacing[0];
925 p[1] = origin[1] + spacing[1];
926 p[2] = origin[2] + spacing[2];
928 this->Transform->TransformPoint(origin,oNew);
929 this->Transform->TransformPoint(p,pNew);
931 this->Box->SetOrigin(oNew);
932 this->Box->SetSpacing( (pNew[0]-oNew[0]),
936 this->UpdateRepresentation();
939 //----------------------------------------------------------------------------
940 void vtkImplicitPlaneWidget::Push(double *p1, double *p2)
942 //Get the motion vector
944 v[0] = p2[0] - p1[0];
945 v[1] = p2[1] - p1[1];
946 v[2] = p2[2] - p1[2];
948 this->Plane->Push( vtkMath::Dot(v,this->Plane->GetNormal()) );
949 this->SetOrigin(this->Plane->GetOrigin());
950 this->UpdateRepresentation();
953 //----------------------------------------------------------------------------
954 void vtkImplicitPlaneWidget::CreateDefaultProperties()
957 this->NormalProperty = vtkProperty::New();
958 this->NormalProperty->SetColor(1,1,1);
959 this->NormalProperty->SetLineWidth(2);
961 this->SelectedNormalProperty = vtkProperty::New();
962 this->SelectedNormalProperty->SetColor(1,0,0);
963 this->NormalProperty->SetLineWidth(2);
966 this->PlaneProperty = vtkProperty::New();
967 this->PlaneProperty->SetAmbient(1.0);
968 this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
970 this->SelectedPlaneProperty = vtkProperty::New();
971 this->SelectedPlaneProperty->SetAmbient(1.0);
972 this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
973 this->SelectedPlaneProperty->SetOpacity(0.25);
975 // Outline properties
976 this->OutlineProperty = vtkProperty::New();
977 this->OutlineProperty->SetAmbient(1.0);
978 this->OutlineProperty->SetAmbientColor(1.0,1.0,1.0);
980 this->SelectedOutlineProperty = vtkProperty::New();
981 this->SelectedOutlineProperty->SetAmbient(1.0);
982 this->SelectedOutlineProperty->SetAmbientColor(0.0,1.0,0.0);
985 this->EdgesProperty = vtkProperty::New();
988 //----------------------------------------------------------------------------
989 void vtkImplicitPlaneWidget::PlaceWidget(double bds[6])
992 double bounds[6], origin[3];
994 this->AdjustBounds(bds, bounds, origin);
996 // Set up the bounding box
997 this->Box->SetOrigin(bounds[0],bounds[2],bounds[4]);
998 this->Box->SetSpacing((bounds[1]-bounds[0]),(bounds[3]-bounds[2]),
999 (bounds[5]-bounds[4]));
1000 this->Outline->Update();
1002 this->LineSource->SetPoint1(this->Plane->GetOrigin());
1003 if ( this->NormalToYAxis )
1005 this->Plane->SetNormal(0,1,0);
1006 this->LineSource->SetPoint2(0,1,0);
1008 else if ( this->NormalToZAxis )
1010 this->Plane->SetNormal(0,0,1);
1011 this->LineSource->SetPoint2(0,0,1);
1013 else //default or x-normal
1015 this->Plane->SetNormal(1,0,0);
1016 this->LineSource->SetPoint2(1,0,0);
1021 this->InitialBounds[i] = bounds[i];
1024 this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1025 (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1026 (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1028 this->UpdateRepresentation();
1030 this->SizeHandles();
1033 //----------------------------------------------------------------------------
1035 // Set the origin of the plane.
1036 void vtkImplicitPlaneWidget::SetOrigin(double x, double y, double z)
1042 this->SetOrigin(origin);
1045 //----------------------------------------------------------------------------
1047 // Set the origin of the plane.
1048 void vtkImplicitPlaneWidget::SetOrigin(double x[3])
1050 double *bounds = this->Outline->GetOutput()->GetBounds();
1051 for (int i=0; i<3; i++)
1053 if ( x[i] < bounds[2*i] )
1057 else if ( x[i] > bounds[2*i+1] )
1059 x[i] = bounds[2*i+1];
1062 this->Plane->SetOrigin(x);
1063 this->UpdateRepresentation();
1066 //----------------------------------------------------------------------------
1068 // Get the origin of the plane.
1069 double* vtkImplicitPlaneWidget::GetOrigin()
1071 return this->Plane->GetOrigin();
1074 //----------------------------------------------------------------------------
1075 void vtkImplicitPlaneWidget::GetOrigin(double xyz[3])
1077 this->Plane->GetOrigin(xyz);
1080 //----------------------------------------------------------------------------
1082 // Set the normal to the plane.
1083 void vtkImplicitPlaneWidget::SetNormal(double x, double y, double z)
1089 vtkMath::Normalize(n);
1090 this->Plane->SetNormal(n);
1091 this->UpdateRepresentation();
1094 //----------------------------------------------------------------------------
1096 // Set the normal to the plane.
1097 void vtkImplicitPlaneWidget::SetNormal(double n[3])
1099 this->SetNormal(n[0], n[1], n[2]);
1102 //----------------------------------------------------------------------------
1104 // Get the normal to the plane.
1105 double* vtkImplicitPlaneWidget::GetNormal()
1107 return this->Plane->GetNormal();
1110 //----------------------------------------------------------------------------
1111 void vtkImplicitPlaneWidget::GetNormal(double xyz[3])
1113 this->Plane->GetNormal(xyz);
1116 //----------------------------------------------------------------------------
1117 void vtkImplicitPlaneWidget::SetDrawPlane(int drawPlane)
1119 if ( drawPlane == this->DrawPlane )
1125 this->DrawPlane = drawPlane;
1126 if ( this->Enabled )
1130 this->CurrentRenderer->AddActor(this->CutActor);
1134 this->CurrentRenderer->RemoveActor(this->CutActor);
1136 this->Interactor->Render();
1140 //----------------------------------------------------------------------------
1141 void vtkImplicitPlaneWidget::SetNormalToXAxis (int var)
1143 if (this->NormalToXAxis != var)
1145 this->NormalToXAxis = var;
1150 this->NormalToYAxisOff();
1151 this->NormalToZAxisOff();
1155 //----------------------------------------------------------------------------
1156 void vtkImplicitPlaneWidget::SetNormalToYAxis (int var)
1158 if (this->NormalToYAxis != var)
1160 this->NormalToYAxis = var;
1165 this->NormalToXAxisOff();
1166 this->NormalToZAxisOff();
1170 //----------------------------------------------------------------------------
1171 void vtkImplicitPlaneWidget::SetNormalToZAxis (int var)
1173 if (this->NormalToZAxis != var)
1175 this->NormalToZAxis = var;
1180 this->NormalToXAxisOff();
1181 this->NormalToYAxisOff();
1185 //----------------------------------------------------------------------------
1186 void vtkImplicitPlaneWidget::GetPolyData(vtkPolyData *pd)
1188 pd->ShallowCopy(this->Cutter->GetOutput());
1191 //----------------------------------------------------------------------------
1192 vtkPolyDataAlgorithm *vtkImplicitPlaneWidget::GetPolyDataAlgorithm()
1194 return this->Cutter;
1197 //----------------------------------------------------------------------------
1198 void vtkImplicitPlaneWidget::GetPlane(vtkPlane *plane)
1200 if ( plane == NULL )
1205 plane->SetNormal(this->Plane->GetNormal());
1206 plane->SetOrigin(this->Plane->GetOrigin());
1209 //----------------------------------------------------------------------------
1210 void vtkImplicitPlaneWidget::UpdatePlacement()
1212 this->Outline->Update();
1213 this->Cutter->Update();
1214 this->Edges->Update();
1215 this->UpdateRepresentation();
1218 //----------------------------------------------------------------------------
1219 void vtkImplicitPlaneWidget::UpdateRepresentation()
1221 if ( ! this->CurrentRenderer )
1226 double *origin = this->Plane->GetOrigin();
1227 double *normal = this->Plane->GetNormal();
1229 if( !this->OutsideBounds )
1231 double *bounds = this->GetInput()->GetBounds();
1232 for (int i=0; i<3; i++)
1234 if ( origin[i] < bounds[2*i] )
1236 origin[i] = bounds[2*i];
1238 else if ( origin[i] > bounds[2*i+1] )
1240 origin[i] = bounds[2*i+1];
1245 // Setup the plane normal
1246 double d = this->Outline->GetOutput()->GetLength();
1248 const double ratio = this->DiagonalRatio;
1249 p2[0] = origin[0] + ratio * d * normal[0];
1250 p2[1] = origin[1] + ratio * d * normal[1];
1251 p2[2] = origin[2] + ratio * d * normal[2];
1253 this->LineSource->SetPoint1(origin);
1254 this->LineSource->SetPoint2(p2);
1255 this->ConeSource->SetCenter(p2);
1256 this->ConeSource->SetDirection(normal);
1258 p2[0] = origin[0] - ratio * d * normal[0];
1259 p2[1] = origin[1] - ratio * d * normal[1];
1260 p2[2] = origin[2] - ratio * d * normal[2];
1262 this->LineSource2->SetPoint1(origin[0],origin[1],origin[2]);
1263 this->LineSource2->SetPoint2(p2);
1264 this->ConeSource2->SetCenter(p2);
1265 this->ConeSource2->SetDirection(normal[0],normal[1],normal[2]);
1267 // Set up the position handle
1268 this->Sphere->SetCenter(origin[0],origin[1],origin[2]);
1270 // Control the look of the edges
1273 this->EdgesMapper->SetInput(this->EdgesTuber->GetOutput());
1277 this->EdgesMapper->SetInput(this->Edges->GetOutput());
1281 //----------------------------------------------------------------------------
1282 void vtkImplicitPlaneWidget::SizeHandles()
1284 double radius = this->vtk3DWidget::SizeHandles(1.35);
1286 this->ConeSource->SetHeight(2.0*radius);
1287 this->ConeSource->SetRadius(radius);
1288 this->ConeSource2->SetHeight(2.0*radius);
1289 this->ConeSource2->SetRadius(radius);
1291 this->Sphere->SetRadius(radius);
1293 this->EdgesTuber->SetRadius(0.25*radius);