1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPlaneWidget.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
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.
13
14 =========================================================================*/
15 #include "vtkPlaneWidget.h"
16
17 #include "vtkActor.h"
18 #include "vtkAssemblyNode.h"
19 #include "vtkAssemblyPath.h"
20 #include "vtkCallbackCommand.h"
21 #include "vtkCamera.h"
22 #include "vtkCellArray.h"
23 #include "vtkCellPicker.h"
24 #include "vtkConeSource.h"
25 #include "vtkDoubleArray.h"
26 #include "vtkFloatArray.h"
27 #include "vtkLineSource.h"
28 #include "vtkMath.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkPickingManager.h"
31 #include "vtkPlane.h"
32 #include "vtkPlaneSource.h"
33 #include "vtkPlanes.h"
34 #include "vtkPolyData.h"
35 #include "vtkPolyDataMapper.h"
36 #include "vtkProperty.h"
37 #include "vtkRenderWindowInteractor.h"
38 #include "vtkRenderer.h"
39 #include "vtkSphereSource.h"
40 #include "vtkTransform.h"
41
42 vtkStandardNewMacro(vtkPlaneWidget);
43
44 vtkCxxSetObjectMacro(vtkPlaneWidget,PlaneProperty,vtkProperty);
45
vtkPlaneWidget()46 vtkPlaneWidget::vtkPlaneWidget() : vtkPolyDataSourceWidget()
47 {
48 this->State = vtkPlaneWidget::Start;
49 this->EventCallbackCommand->SetCallback(vtkPlaneWidget::ProcessEvents);
50
51 this->NormalToXAxis = 0;
52 this->NormalToYAxis = 0;
53 this->NormalToZAxis = 0;
54 this->Representation = VTK_PLANE_WIREFRAME;
55
56 //Build the representation of the widget
57 int i;
58 // Represent the plane
59 this->PlaneSource = vtkPlaneSource::New();
60 this->PlaneSource->SetXResolution(4);
61 this->PlaneSource->SetYResolution(4);
62 this->PlaneOutline = vtkPolyData::New();
63 vtkPoints *pts = vtkPoints::New();
64 pts->SetNumberOfPoints(4);
65 vtkCellArray *outline = vtkCellArray::New();
66 outline->InsertNextCell(4);
67 outline->InsertCellPoint(0);
68 outline->InsertCellPoint(1);
69 outline->InsertCellPoint(2);
70 outline->InsertCellPoint(3);
71 this->PlaneOutline->SetPoints(pts);
72 pts->Delete();
73 this->PlaneOutline->SetPolys(outline);
74 outline->Delete();
75 this->PlaneMapper = vtkPolyDataMapper::New();
76 this->PlaneMapper->SetInputConnection(
77 this->PlaneSource->GetOutputPort());
78 this->PlaneActor = vtkActor::New();
79 this->PlaneActor->SetMapper(this->PlaneMapper);
80
81 // Create the handles
82 this->Handle = new vtkActor* [4];
83 this->HandleMapper = new vtkPolyDataMapper* [4];
84 this->HandleGeometry = new vtkSphereSource* [4];
85 for (i=0; i<4; i++)
86 {
87 this->HandleGeometry[i] = vtkSphereSource::New();
88 this->HandleGeometry[i]->SetThetaResolution(16);
89 this->HandleGeometry[i]->SetPhiResolution(8);
90 this->HandleMapper[i] = vtkPolyDataMapper::New();
91 this->HandleMapper[i]->SetInputConnection(
92 this->HandleGeometry[i]->GetOutputPort());
93 this->Handle[i] = vtkActor::New();
94 this->Handle[i]->SetMapper(this->HandleMapper[i]);
95 }
96
97 // Create the + plane normal
98 this->LineSource = vtkLineSource::New();
99 this->LineSource->SetResolution(1);
100 this->LineMapper = vtkPolyDataMapper::New();
101 this->LineMapper->SetInputConnection(
102 this->LineSource->GetOutputPort());
103 this->LineActor = vtkActor::New();
104 this->LineActor->SetMapper(this->LineMapper);
105
106 this->ConeSource = vtkConeSource::New();
107 this->ConeSource->SetResolution(12);
108 this->ConeSource->SetAngle(25.0);
109 this->ConeMapper = vtkPolyDataMapper::New();
110 this->ConeMapper->SetInputConnection(
111 this->ConeSource->GetOutputPort());
112 this->ConeActor = vtkActor::New();
113 this->ConeActor->SetMapper(this->ConeMapper);
114
115 // Create the - plane normal
116 this->LineSource2 = vtkLineSource::New();
117 this->LineSource2->SetResolution(1);
118 this->LineMapper2 = vtkPolyDataMapper::New();
119 this->LineMapper2->SetInputConnection(
120 this->LineSource2->GetOutputPort());
121 this->LineActor2 = vtkActor::New();
122 this->LineActor2->SetMapper(this->LineMapper2);
123
124 this->ConeSource2 = vtkConeSource::New();
125 this->ConeSource2->SetResolution(12);
126 this->ConeSource2->SetAngle(25.0);
127 this->ConeMapper2 = vtkPolyDataMapper::New();
128 this->ConeMapper2->SetInputConnection(
129 this->ConeSource2->GetOutputPort());
130 this->ConeActor2 = vtkActor::New();
131 this->ConeActor2->SetMapper(this->ConeMapper2);
132
133 this->Transform = vtkTransform::New();
134
135 // Define the point coordinates
136 double bounds[6];
137 bounds[0] = -0.5;
138 bounds[1] = 0.5;
139 bounds[2] = -0.5;
140 bounds[3] = 0.5;
141 bounds[4] = -0.5;
142 bounds[5] = 0.5;
143
144 //Manage the picking stuff
145 this->HandlePicker = vtkCellPicker::New();
146 this->HandlePicker->SetTolerance(0.001);
147 for (i=0; i<4; i++)
148 {
149 this->HandlePicker->AddPickList(this->Handle[i]);
150 }
151 this->HandlePicker->PickFromListOn();
152
153 this->PlanePicker = vtkCellPicker::New();
154 this->PlanePicker->SetTolerance(0.005); //need some fluff
155 this->PlanePicker->AddPickList(this->PlaneActor);
156 this->PlanePicker->AddPickList(this->ConeActor);
157 this->PlanePicker->AddPickList(this->LineActor);
158 this->PlanePicker->AddPickList(this->ConeActor2);
159 this->PlanePicker->AddPickList(this->LineActor2);
160 this->PlanePicker->PickFromListOn();
161
162 this->CurrentHandle = NULL;
163
164 this->LastPickValid = 0;
165 this->HandleSizeFactor = 1.25;
166 this->SetHandleSize( 0.05 );
167
168 // Set up the initial properties
169 this->CreateDefaultProperties();
170
171 this->SelectRepresentation();
172
173 // Initial creation of the widget, serves to initialize it
174 // Call PlaceWidget() LAST in the constructor as it depends on ivar
175 // values.
176 this->PlaceWidget(bounds);
177 }
178
~vtkPlaneWidget()179 vtkPlaneWidget::~vtkPlaneWidget()
180 {
181 this->PlaneActor->Delete();
182 this->PlaneMapper->Delete();
183 this->PlaneSource->Delete();
184 this->PlaneOutline->Delete();
185
186 for (int i=0; i<4; i++)
187 {
188 this->HandleGeometry[i]->Delete();
189 this->HandleMapper[i]->Delete();
190 this->Handle[i]->Delete();
191 }
192 delete [] this->Handle;
193 delete [] this->HandleMapper;
194 delete [] this->HandleGeometry;
195
196 this->ConeActor->Delete();
197 this->ConeMapper->Delete();
198 this->ConeSource->Delete();
199
200 this->LineActor->Delete();
201 this->LineMapper->Delete();
202 this->LineSource->Delete();
203
204 this->ConeActor2->Delete();
205 this->ConeMapper2->Delete();
206 this->ConeSource2->Delete();
207
208 this->LineActor2->Delete();
209 this->LineMapper2->Delete();
210 this->LineSource2->Delete();
211
212 this->HandlePicker->Delete();
213 this->PlanePicker->Delete();
214
215 if (this->HandleProperty)
216 {
217 this->HandleProperty->Delete();
218 this->HandleProperty = 0;
219 }
220
221 if (this->SelectedHandleProperty)
222 {
223 this->SelectedHandleProperty->Delete();
224 this->SelectedHandleProperty = 0;
225 }
226
227 if (this->PlaneProperty)
228 {
229 this->PlaneProperty->Delete();
230 this->PlaneProperty = 0;
231 }
232
233 if (this->SelectedPlaneProperty)
234 {
235 this->SelectedPlaneProperty->Delete();
236 this->SelectedPlaneProperty = 0;
237 }
238
239 this->Transform->Delete();
240 }
241
SetEnabled(int enabling)242 void vtkPlaneWidget::SetEnabled(int enabling)
243 {
244 if ( ! this->Interactor )
245 {
246 vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
247 return;
248 }
249
250 if ( enabling ) //-----------------------------------------------------------
251 {
252 vtkDebugMacro(<<"Enabling plane widget");
253
254 if ( this->Enabled ) //already enabled, just return
255 {
256 return;
257 }
258
259 if ( ! this->CurrentRenderer )
260 {
261 this->SetCurrentRenderer(this->Interactor->FindPokedRenderer(
262 this->Interactor->GetLastEventPosition()[0],
263 this->Interactor->GetLastEventPosition()[1]));
264 if (this->CurrentRenderer == NULL)
265 {
266 return;
267 }
268 }
269
270 this->Enabled = 1;
271
272 // listen for the following events
273 vtkRenderWindowInteractor *i = this->Interactor;
274 i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand,
275 this->Priority);
276 i->AddObserver(vtkCommand::LeftButtonPressEvent,
277 this->EventCallbackCommand, this->Priority);
278 i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
279 this->EventCallbackCommand, this->Priority);
280 i->AddObserver(vtkCommand::MiddleButtonPressEvent,
281 this->EventCallbackCommand, this->Priority);
282 i->AddObserver(vtkCommand::MiddleButtonReleaseEvent,
283 this->EventCallbackCommand, this->Priority);
284 i->AddObserver(vtkCommand::RightButtonPressEvent,
285 this->EventCallbackCommand, this->Priority);
286 i->AddObserver(vtkCommand::RightButtonReleaseEvent,
287 this->EventCallbackCommand, this->Priority);
288
289 // Add the plane
290 this->CurrentRenderer->AddActor(this->PlaneActor);
291 this->PlaneActor->SetProperty(this->PlaneProperty);
292
293 // turn on the handles
294 for (int j=0; j<4; j++)
295 {
296 this->CurrentRenderer->AddActor(this->Handle[j]);
297 this->Handle[j]->SetProperty(this->HandleProperty);
298 }
299
300 // add the normal vector
301 this->CurrentRenderer->AddActor(this->LineActor);
302 this->LineActor->SetProperty(this->HandleProperty);
303 this->CurrentRenderer->AddActor(this->ConeActor);
304 this->ConeActor->SetProperty(this->HandleProperty);
305 this->CurrentRenderer->AddActor(this->LineActor2);
306 this->LineActor2->SetProperty(this->HandleProperty);
307 this->CurrentRenderer->AddActor(this->ConeActor2);
308 this->ConeActor2->SetProperty(this->HandleProperty);
309
310 this->SelectRepresentation();
311 this->InvokeEvent(vtkCommand::EnableEvent,NULL);
312 }
313
314 else //disabling----------------------------------------------------------
315 {
316 vtkDebugMacro(<<"Disabling plane widget");
317
318 if ( ! this->Enabled ) //already disabled, just return
319 {
320 return;
321 }
322
323 this->Enabled = 0;
324
325 // don't listen for events any more
326 this->Interactor->RemoveObserver(this->EventCallbackCommand);
327
328 // turn off the plane
329 this->CurrentRenderer->RemoveActor(this->PlaneActor);
330
331 // turn off the handles
332 for (int i=0; i<4; i++)
333 {
334 this->CurrentRenderer->RemoveActor(this->Handle[i]);
335 }
336
337 // turn off the normal vector
338 this->CurrentRenderer->RemoveActor(this->LineActor);
339 this->CurrentRenderer->RemoveActor(this->ConeActor);
340 this->CurrentRenderer->RemoveActor(this->LineActor2);
341 this->CurrentRenderer->RemoveActor(this->ConeActor2);
342
343 this->CurrentHandle = NULL;
344 this->InvokeEvent(vtkCommand::DisableEvent,NULL);
345 this->SetCurrentRenderer(NULL);
346 }
347
348 this->Interactor->Render();
349 }
350
351 //------------------------------------------------------------------------------
RegisterPickers()352 void vtkPlaneWidget::RegisterPickers()
353 {
354 this->Interactor->GetPickingManager()->AddPicker(this->HandlePicker, this);
355 this->Interactor->GetPickingManager()->AddPicker(this->PlanePicker, this);
356 }
357
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))358 void vtkPlaneWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
359 unsigned long event,
360 void* clientdata,
361 void* vtkNotUsed(calldata))
362 {
363 vtkPlaneWidget* self = reinterpret_cast<vtkPlaneWidget *>( clientdata );
364
365 //okay, let's do the right thing
366 switch(event)
367 {
368 case vtkCommand::LeftButtonPressEvent:
369 self->OnLeftButtonDown();
370 break;
371 case vtkCommand::LeftButtonReleaseEvent:
372 self->OnLeftButtonUp();
373 break;
374 case vtkCommand::MiddleButtonPressEvent:
375 self->OnMiddleButtonDown();
376 break;
377 case vtkCommand::MiddleButtonReleaseEvent:
378 self->OnMiddleButtonUp();
379 break;
380 case vtkCommand::RightButtonPressEvent:
381 self->OnRightButtonDown();
382 break;
383 case vtkCommand::RightButtonReleaseEvent:
384 self->OnRightButtonUp();
385 break;
386 case vtkCommand::MouseMoveEvent:
387 self->OnMouseMove();
388 break;
389 }
390 }
391
PrintSelf(ostream & os,vtkIndent indent)392 void vtkPlaneWidget::PrintSelf(ostream& os, vtkIndent indent)
393 {
394 this->Superclass::PrintSelf(os,indent);
395
396 if ( this->HandleProperty )
397 {
398 os << indent << "Handle Property: " << this->HandleProperty << "\n";
399 }
400 else
401 {
402 os << indent << "Handle Property: (none)\n";
403 }
404 if ( this->SelectedHandleProperty )
405 {
406 os << indent << "Selected Handle Property: "
407 << this->SelectedHandleProperty << "\n";
408 }
409 else
410 {
411 os << indent << "SelectedHandle Property: (none)\n";
412 }
413
414 if ( this->PlaneProperty )
415 {
416 os << indent << "Plane Property: " << this->PlaneProperty << "\n";
417 }
418 else
419 {
420 os << indent << "Plane Property: (none)\n";
421 }
422 if ( this->SelectedPlaneProperty )
423 {
424 os << indent << "Selected Plane Property: "
425 << this->SelectedPlaneProperty << "\n";
426 }
427 else
428 {
429 os << indent << "Selected Plane Property: (none)\n";
430 }
431
432 os << indent << "Plane Representation: ";
433 if ( this->Representation == VTK_PLANE_WIREFRAME )
434 {
435 os << "Wireframe\n";
436 }
437 else if ( this->Representation == VTK_PLANE_SURFACE )
438 {
439 os << "Surface\n";
440 }
441 else //( this->Representation == VTK_PLANE_OUTLINE )
442 {
443 os << "Outline\n";
444 }
445
446 os << indent << "Normal To X Axis: "
447 << (this->NormalToXAxis ? "On" : "Off") << "\n";
448 os << indent << "Normal To Y Axis: "
449 << (this->NormalToYAxis ? "On" : "Off") << "\n";
450 os << indent << "Normal To Z Axis: "
451 << (this->NormalToZAxis ? "On" : "Off") << "\n";
452
453 int res = this->PlaneSource->GetXResolution();
454 double *o = this->PlaneSource->GetOrigin();
455 double *pt1 = this->PlaneSource->GetPoint1();
456 double *pt2 = this->PlaneSource->GetPoint2();
457
458 os << indent << "Resolution: " << res << "\n";
459 os << indent << "Origin: (" << o[0] << ", "
460 << o[1] << ", "
461 << o[2] << ")\n";
462 os << indent << "Point 1: (" << pt1[0] << ", "
463 << pt1[1] << ", "
464 << pt1[2] << ")\n";
465 os << indent << "Point 2: (" << pt2[0] << ", "
466 << pt2[1] << ", "
467 << pt2[2] << ")\n";
468 }
469
PositionHandles()470 void vtkPlaneWidget::PositionHandles()
471 {
472 double *o = this->PlaneSource->GetOrigin();
473 double *pt1 = this->PlaneSource->GetPoint1();
474 double *pt2 = this->PlaneSource->GetPoint2();
475
476 this->HandleGeometry[0]->SetCenter(o);
477 this->HandleGeometry[1]->SetCenter(pt1);
478 this->HandleGeometry[2]->SetCenter(pt2);
479
480 double x[3];
481 x[0] = pt1[0] + pt2[0] - o[0];
482 x[1] = pt1[1] + pt2[1] - o[1];
483 x[2] = pt1[2] + pt2[2] - o[2];
484 this->HandleGeometry[3]->SetCenter(x); //far corner
485
486 // set up the outline
487 if ( this->Representation == VTK_PLANE_OUTLINE )
488 {
489 this->PlaneOutline->GetPoints()->SetPoint(0,o);
490 this->PlaneOutline->GetPoints()->SetPoint(1,pt1);
491 this->PlaneOutline->GetPoints()->SetPoint(2,x);
492 this->PlaneOutline->GetPoints()->SetPoint(3,pt2);
493 this->PlaneOutline->Modified();
494 }
495 this->SelectRepresentation();
496
497 // Create the normal vector
498 double center[3];
499 this->PlaneSource->GetCenter(center);
500 this->LineSource->SetPoint1(center);
501 this->LineSource2->SetPoint1(center);
502 double p2[3];
503 this->PlaneSource->GetNormal(this->Normal);
504 vtkMath::Normalize(this->Normal);
505 double d = sqrt(
506 vtkMath::Distance2BetweenPoints(
507 this->PlaneSource->GetPoint1(),this->PlaneSource->GetPoint2()) );
508
509 p2[0] = center[0] + 0.35 * d * this->Normal[0];
510 p2[1] = center[1] + 0.35 * d * this->Normal[1];
511 p2[2] = center[2] + 0.35 * d * this->Normal[2];
512 this->LineSource->SetPoint2(p2);
513 this->ConeSource->SetCenter(p2);
514 this->ConeSource->SetDirection(this->Normal);
515
516 p2[0] = center[0] - 0.35 * d * this->Normal[0];
517 p2[1] = center[1] - 0.35 * d * this->Normal[1];
518 p2[2] = center[2] - 0.35 * d * this->Normal[2];
519 this->LineSource2->SetPoint2(p2);
520 this->ConeSource2->SetCenter(p2);
521 this->ConeSource2->SetDirection(this->Normal);
522 }
523
HighlightHandle(vtkProp * prop)524 int vtkPlaneWidget::HighlightHandle(vtkProp *prop)
525 {
526 // first unhighlight anything picked
527 if ( this->CurrentHandle )
528 {
529 this->CurrentHandle->SetProperty(this->HandleProperty);
530 }
531
532 this->CurrentHandle = static_cast<vtkActor *>(prop);
533
534 if ( this->CurrentHandle )
535 {
536 this->ValidPick = 1;
537 this->HandlePicker->GetPickPosition(this->LastPickPosition);
538 this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
539 for (int i=0; i<4; i++) //find handle
540 {
541 if ( this->CurrentHandle == this->Handle[i] )
542 {
543 return i;
544 }
545 }
546 }
547
548 return -1;
549 }
550
HighlightNormal(int highlight)551 void vtkPlaneWidget::HighlightNormal(int highlight)
552 {
553 if ( highlight )
554 {
555 this->ValidPick = 1;
556 this->PlanePicker->GetPickPosition(this->LastPickPosition);
557 this->LineActor->SetProperty(this->SelectedHandleProperty);
558 this->ConeActor->SetProperty(this->SelectedHandleProperty);
559 this->LineActor2->SetProperty(this->SelectedHandleProperty);
560 this->ConeActor2->SetProperty(this->SelectedHandleProperty);
561 }
562 else
563 {
564 this->LineActor->SetProperty(this->HandleProperty);
565 this->ConeActor->SetProperty(this->HandleProperty);
566 this->LineActor2->SetProperty(this->HandleProperty);
567 this->ConeActor2->SetProperty(this->HandleProperty);
568 }
569 }
570
HighlightPlane(int highlight)571 void vtkPlaneWidget::HighlightPlane(int highlight)
572 {
573 if ( highlight )
574 {
575 this->ValidPick = 1;
576 this->PlanePicker->GetPickPosition(this->LastPickPosition);
577 this->PlaneActor->SetProperty(this->SelectedPlaneProperty);
578 }
579 else
580 {
581 this->PlaneActor->SetProperty(this->PlaneProperty);
582 }
583 }
584
OnLeftButtonDown()585 void vtkPlaneWidget::OnLeftButtonDown()
586 {
587 int X = this->Interactor->GetEventPosition()[0];
588 int Y = this->Interactor->GetEventPosition()[1];
589
590 // Okay, make sure that the pick is in the current renderer
591 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
592 {
593 this->State = vtkPlaneWidget::Outside;
594 return;
595 }
596
597 // Okay, we can process this. Try to pick handles first;
598 // if no handles picked, then try to pick the plane.
599 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
600
601 if ( path != NULL )
602 {
603 this->State = vtkPlaneWidget::Moving;
604 this->HighlightHandle(path->GetFirstNode()->GetViewProp());
605 }
606 else
607 {
608 path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
609
610 if ( path != NULL )
611 {
612 vtkProp *prop = path->GetFirstNode()->GetViewProp();
613 if ( prop == this->ConeActor || prop == this->LineActor ||
614 prop == this->ConeActor2 || prop == this->LineActor2 )
615 {
616 this->State = vtkPlaneWidget::Rotating;
617 this->HighlightNormal(1);
618 }
619 else if (this->Interactor->GetControlKey())
620 {
621 this->State = vtkPlaneWidget::Spinning;
622 this->HighlightNormal(1);
623 }
624 else
625 {
626 this->State = vtkPlaneWidget::Moving;
627 this->HighlightPlane(1);
628 }
629 }
630 else
631 {
632 this->State = vtkPlaneWidget::Outside;
633 this->HighlightHandle(NULL);
634 return;
635 }
636 }
637
638 this->EventCallbackCommand->SetAbortFlag(1);
639 this->StartInteraction();
640 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
641 this->Interactor->Render();
642 }
643
OnLeftButtonUp()644 void vtkPlaneWidget::OnLeftButtonUp()
645 {
646 if ( this->State == vtkPlaneWidget::Outside ||
647 this->State == vtkPlaneWidget::Start )
648 {
649 return;
650 }
651
652 this->State = vtkPlaneWidget::Start;
653 this->HighlightHandle(NULL);
654 this->HighlightPlane(0);
655 this->HighlightNormal(0);
656 this->SizeHandles();
657
658 this->EventCallbackCommand->SetAbortFlag(1);
659 this->EndInteraction();
660 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
661 this->Interactor->Render();
662 }
663
OnMiddleButtonDown()664 void vtkPlaneWidget::OnMiddleButtonDown()
665 {
666 int X = this->Interactor->GetEventPosition()[0];
667 int Y = this->Interactor->GetEventPosition()[1];
668
669 // Okay, make sure that the pick is in the current renderer
670 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
671 {
672 this->State = vtkPlaneWidget::Outside;
673 return;
674 }
675
676 // Okay, we can process this. If anything is picked, then we
677 // can start pushing the plane.
678 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
679
680 if ( path != NULL )
681 {
682 this->State = vtkPlaneWidget::Pushing;
683 this->HighlightPlane(1);
684 this->HighlightNormal(1);
685 this->HighlightHandle(path->GetFirstNode()->GetViewProp());
686 }
687 else
688 {
689 path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
690
691 if ( path == NULL ) //nothing picked
692 {
693 this->State = vtkPlaneWidget::Outside;
694 return;
695 }
696 else
697 {
698 this->State = vtkPlaneWidget::Pushing;
699 this->HighlightNormal(1);
700 this->HighlightPlane(1);
701 }
702 }
703
704 this->EventCallbackCommand->SetAbortFlag(1);
705 this->StartInteraction();
706 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
707 this->Interactor->Render();
708 }
709
OnMiddleButtonUp()710 void vtkPlaneWidget::OnMiddleButtonUp()
711 {
712 if ( this->State == vtkPlaneWidget::Outside ||
713 this->State == vtkPlaneWidget::Start )
714 {
715 return;
716 }
717
718 this->State = vtkPlaneWidget::Start;
719 this->HighlightPlane(0);
720 this->HighlightNormal(0);
721 this->HighlightHandle(NULL);
722 this->SizeHandles();
723
724 this->EventCallbackCommand->SetAbortFlag(1);
725 this->EndInteraction();
726 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
727 this->Interactor->Render();
728 }
729
OnRightButtonDown()730 void vtkPlaneWidget::OnRightButtonDown()
731 {
732 int X = this->Interactor->GetEventPosition()[0];
733 int Y = this->Interactor->GetEventPosition()[1];
734
735 // Okay, make sure that the pick is in the current renderer
736 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
737 {
738 this->State = vtkPlaneWidget::Outside;
739 return;
740 }
741
742 // Okay, we can process this. Try to pick handles first;
743 // if no handles picked, then pick the bounding box.
744 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
745
746 if ( path != NULL )
747 {
748 this->State = vtkPlaneWidget::Scaling;
749 this->HighlightPlane(1);
750 this->HighlightHandle(path->GetFirstNode()->GetViewProp());
751 }
752 else //see if we picked the plane or a normal
753 {
754 path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
755
756 if ( path == NULL )
757 {
758 this->State = vtkPlaneWidget::Outside;
759 return;
760 }
761 else
762 {
763 this->State = vtkPlaneWidget::Scaling;
764 this->HighlightPlane(1);
765 }
766 }
767
768 this->EventCallbackCommand->SetAbortFlag(1);
769 this->StartInteraction();
770 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
771 this->Interactor->Render();
772 }
773
OnRightButtonUp()774 void vtkPlaneWidget::OnRightButtonUp()
775 {
776 if ( this->State == vtkPlaneWidget::Outside ||
777 this->State == vtkPlaneWidget::Start )
778 {
779 return;
780 }
781
782 this->State = vtkPlaneWidget::Start;
783 this->HighlightPlane(0);
784 this->SizeHandles();
785
786 this->EventCallbackCommand->SetAbortFlag(1);
787 this->EndInteraction();
788 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
789 this->Interactor->Render();
790 }
791
OnMouseMove()792 void vtkPlaneWidget::OnMouseMove()
793 {
794 // See whether we're active
795 if ( this->State == vtkPlaneWidget::Outside ||
796 this->State == vtkPlaneWidget::Start )
797 {
798 return;
799 }
800
801 int X = this->Interactor->GetEventPosition()[0];
802 int Y = this->Interactor->GetEventPosition()[1];
803
804 // Do different things depending on state
805 // Calculations everybody does
806 double focalPoint[4], pickPoint[4], prevPickPoint[4];
807 double z, vpn[3];
808
809 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
810 if ( !camera )
811 {
812 return;
813 }
814
815 // Compute the two points defining the motion vector
816 this->ComputeWorldToDisplay(this->LastPickPosition[0],
817 this->LastPickPosition[1],
818 this->LastPickPosition[2], focalPoint);
819 z = focalPoint[2];
820 this->ComputeDisplayToWorld(
821 double(this->Interactor->GetLastEventPosition()[0]),
822 double(this->Interactor->GetLastEventPosition()[1]),
823 z, prevPickPoint);
824 this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
825
826 // Process the motion
827 if ( this->State == vtkPlaneWidget::Moving )
828 {
829 // Okay to process
830 if ( this->CurrentHandle )
831 {
832 if ( this->CurrentHandle == this->Handle[0] )
833 {
834 this->MoveOrigin(prevPickPoint, pickPoint);
835 }
836 else if ( this->CurrentHandle == this->Handle[1] )
837 {
838 this->MovePoint1(prevPickPoint, pickPoint);
839 }
840 else if ( this->CurrentHandle == this->Handle[2] )
841 {
842 this->MovePoint2(prevPickPoint, pickPoint);
843 }
844 else if ( this->CurrentHandle == this->Handle[3] )
845 {
846 this->MovePoint3(prevPickPoint, pickPoint);
847 }
848 }
849 else //must be moving the plane
850 {
851 this->Translate(prevPickPoint, pickPoint);
852 }
853 }
854 else if ( this->State == vtkPlaneWidget::Scaling )
855 {
856 this->Scale(prevPickPoint, pickPoint, X, Y);
857 }
858 else if ( this->State == vtkPlaneWidget::Pushing )
859 {
860 this->Push(prevPickPoint, pickPoint);
861 }
862 else if ( this->State == vtkPlaneWidget::Rotating )
863 {
864 camera->GetViewPlaneNormal(vpn);
865 this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
866 }
867 else if ( this->State == vtkPlaneWidget::Spinning )
868 {
869 this->Spin(prevPickPoint, pickPoint);
870 }
871
872
873 // Interact, if desired
874 this->EventCallbackCommand->SetAbortFlag(1);
875 this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
876
877 this->Interactor->Render();
878 }
879
MoveOrigin(double * p1,double * p2)880 void vtkPlaneWidget::MoveOrigin(double *p1, double *p2)
881 {
882 //Get the plane definition
883 double *o = this->PlaneSource->GetOrigin();
884 double *pt1 = this->PlaneSource->GetPoint1();
885 double *pt2 = this->PlaneSource->GetPoint2();
886
887 //Get the vector of motion
888 double v[3];
889 v[0] = p2[0] - p1[0];
890 v[1] = p2[1] - p1[1];
891 v[2] = p2[2] - p1[2];
892
893 // The point opposite the origin (pt3) stays fixed
894 double pt3[3];
895 pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
896 pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
897 pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
898
899 // Define vectors from point pt3
900 double p13[3], p23[3];
901 p13[0] = pt1[0] - pt3[0];
902 p13[1] = pt1[1] - pt3[1];
903 p13[2] = pt1[2] - pt3[2];
904 p23[0] = pt2[0] - pt3[0];
905 p23[1] = pt2[1] - pt3[1];
906 p23[2] = pt2[2] - pt3[2];
907
908 double vN = vtkMath::Norm(v);
909 double n13 = vtkMath::Norm(p13);
910 double n23 = vtkMath::Norm(p23);
911
912 // Project v onto these vector to determine the amount of motion
913 // Scale it by the relative size of the motion to the vector length
914 double d1 = (vN/n13) * vtkMath::Dot(v,p13) / (vN*n13);
915 double d2 = (vN/n23) * vtkMath::Dot(v,p23) / (vN*n23);
916
917 double point1[3], point2[3], origin[3];
918 for (int i=0; i<3; i++)
919 {
920 point1[i] = pt3[i] + (1.0+d1)*p13[i];
921 point2[i] = pt3[i] + (1.0+d2)*p23[i];
922 origin[i] = pt3[i] + (1.0+d1)*p13[i] + (1.0+d2)*p23[i];
923 }
924
925 this->PlaneSource->SetOrigin(origin);
926 this->PlaneSource->SetPoint1(point1);
927 this->PlaneSource->SetPoint2(point2);
928 this->PlaneSource->Update();
929
930 this->PositionHandles();
931 }
932
MovePoint1(double * p1,double * p2)933 void vtkPlaneWidget::MovePoint1(double *p1, double *p2)
934 {
935 //Get the plane definition
936 double *o = this->PlaneSource->GetOrigin();
937 double *pt1 = this->PlaneSource->GetPoint1();
938 double *pt2 = this->PlaneSource->GetPoint2();
939
940 //Get the vector of motion
941 double v[3];
942 v[0] = p2[0] - p1[0];
943 v[1] = p2[1] - p1[1];
944 v[2] = p2[2] - p1[2];
945
946 // Need the point opposite the origin (pt3)
947 double pt3[3];
948 pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
949 pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
950 pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
951
952 // Define vectors from point pt2
953 double p32[3], p02[3];
954 p02[0] = o[0] - pt2[0];
955 p02[1] = o[1] - pt2[1];
956 p02[2] = o[2] - pt2[2];
957 p32[0] = pt3[0] - pt2[0];
958 p32[1] = pt3[1] - pt2[1];
959 p32[2] = pt3[2] - pt2[2];
960
961 double vN = vtkMath::Norm(v);
962 double n02 = vtkMath::Norm(p02);
963 double n32 = vtkMath::Norm(p32);
964
965 // Project v onto these vector to determine the amount of motion
966 // Scale it by the relative size of the motion to the vector length
967 double d1 = (vN/n02) * vtkMath::Dot(v,p02) / (vN*n02);
968 double d2 = (vN/n32) * vtkMath::Dot(v,p32) / (vN*n32);
969
970 double point1[3], origin[3];
971 for (int i=0; i<3; i++)
972 {
973 origin[i] = pt2[i] + (1.0+d1)*p02[i];
974 point1[i] = pt2[i] + (1.0+d1)*p02[i] + (1.0+d2)*p32[i];
975 }
976
977 this->PlaneSource->SetOrigin(origin);
978 this->PlaneSource->SetPoint1(point1);
979 this->PlaneSource->Update();
980
981 this->PositionHandles();
982 }
983
MovePoint2(double * p1,double * p2)984 void vtkPlaneWidget::MovePoint2(double *p1, double *p2)
985 {
986 //Get the plane definition
987 double *o = this->PlaneSource->GetOrigin();
988 double *pt1 = this->PlaneSource->GetPoint1();
989 double *pt2 = this->PlaneSource->GetPoint2();
990
991 //Get the vector of motion
992 double v[3];
993 v[0] = p2[0] - p1[0];
994 v[1] = p2[1] - p1[1];
995 v[2] = p2[2] - p1[2];
996
997 // The point opposite point2 (pt1) stays fixed
998 double pt3[3];
999 pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
1000 pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1001 pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1002
1003 // Define vectors from point pt1
1004 double p01[3], p31[3];
1005 p31[0] = pt3[0] - pt1[0];
1006 p31[1] = pt3[1] - pt1[1];
1007 p31[2] = pt3[2] - pt1[2];
1008 p01[0] = o[0] - pt1[0];
1009 p01[1] = o[1] - pt1[1];
1010 p01[2] = o[2] - pt1[2];
1011
1012 double vN = vtkMath::Norm(v);
1013 double n31 = vtkMath::Norm(p31);
1014 double n01 = vtkMath::Norm(p01);
1015
1016 // Project v onto these vector to determine the amount of motion
1017 // Scale it by the relative size of the motion to the vector length
1018 double d1 = (vN/n31) * vtkMath::Dot(v,p31) / (vN*n31);
1019 double d2 = (vN/n01) * vtkMath::Dot(v,p01) / (vN*n01);
1020
1021 double point2[3], origin[3];
1022 for (int i=0; i<3; i++)
1023 {
1024 point2[i] = pt1[i] + (1.0+d1)*p31[i] + (1.0+d2)*p01[i];
1025 origin[i] = pt1[i] + (1.0+d2)*p01[i];
1026 }
1027
1028 this->PlaneSource->SetOrigin(origin);
1029 this->PlaneSource->SetPoint2(point2);
1030 this->PlaneSource->Update();
1031
1032 this->PositionHandles();
1033 }
1034
MovePoint3(double * p1,double * p2)1035 void vtkPlaneWidget::MovePoint3(double *p1, double *p2)
1036 {
1037 //Get the plane definition
1038 double *o = this->PlaneSource->GetOrigin();
1039 double *pt1 = this->PlaneSource->GetPoint1();
1040 double *pt2 = this->PlaneSource->GetPoint2();
1041
1042 //Get the vector of motion
1043 double v[3];
1044 v[0] = p2[0] - p1[0];
1045 v[1] = p2[1] - p1[1];
1046 v[2] = p2[2] - p1[2];
1047
1048 // Define vectors from point pt3
1049 double p10[3], p20[3];
1050 p10[0] = pt1[0] - o[0];
1051 p10[1] = pt1[1] - o[1];
1052 p10[2] = pt1[2] - o[2];
1053 p20[0] = pt2[0] - o[0];
1054 p20[1] = pt2[1] - o[1];
1055 p20[2] = pt2[2] - o[2];
1056
1057 double vN = vtkMath::Norm(v);
1058 double n10 = vtkMath::Norm(p10);
1059 double n20 = vtkMath::Norm(p20);
1060
1061 // Project v onto these vector to determine the amount of motion
1062 // Scale it by the relative size of the motion to the vector length
1063 double d1 = (vN/n10) * vtkMath::Dot(v,p10) / (vN*n10);
1064 double d2 = (vN/n20) * vtkMath::Dot(v,p20) / (vN*n20);
1065
1066 double point1[3], point2[3];
1067 for (int i=0; i<3; i++)
1068 {
1069 point1[i] = o[i] + (1.0+d1)*p10[i];
1070 point2[i] = o[i] + (1.0+d2)*p20[i];
1071 }
1072
1073 this->PlaneSource->SetPoint1(point1);
1074 this->PlaneSource->SetPoint2(point2);
1075 this->PlaneSource->Update();
1076
1077 this->PositionHandles();
1078 }
1079
Rotate(int X,int Y,double * p1,double * p2,double * vpn)1080 void vtkPlaneWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn)
1081 {
1082 double *o = this->PlaneSource->GetOrigin();
1083 double *pt1 = this->PlaneSource->GetPoint1();
1084 double *pt2 = this->PlaneSource->GetPoint2();
1085 double *center = this->PlaneSource->GetCenter();
1086
1087 double v[3]; //vector of motion
1088 double axis[3]; //axis of rotation
1089 double theta; //rotation angle
1090
1091 // mouse motion vector in world space
1092 v[0] = p2[0] - p1[0];
1093 v[1] = p2[1] - p1[1];
1094 v[2] = p2[2] - p1[2];
1095
1096 // Create axis of rotation and angle of rotation
1097 vtkMath::Cross(vpn,v,axis);
1098 if ( vtkMath::Normalize(axis) == 0.0 )
1099 {
1100 return;
1101 }
1102 int *size = this->CurrentRenderer->GetSize();
1103 double l2 =
1104 (X-this->Interactor->GetLastEventPosition()[0])*
1105 (X-this->Interactor->GetLastEventPosition()[0]) +
1106 (Y-this->Interactor->GetLastEventPosition()[1])*
1107 (Y-this->Interactor->GetLastEventPosition()[1]);
1108 theta = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));
1109
1110 //Manipulate the transform to reflect the rotation
1111 this->Transform->Identity();
1112 this->Transform->Translate(center[0],center[1],center[2]);
1113 this->Transform->RotateWXYZ(theta,axis);
1114 this->Transform->Translate(-center[0],-center[1],-center[2]);
1115
1116 //Set the corners
1117 double oNew[3], pt1New[3], pt2New[3];
1118 this->Transform->TransformPoint(o,oNew);
1119 this->Transform->TransformPoint(pt1,pt1New);
1120 this->Transform->TransformPoint(pt2,pt2New);
1121
1122 this->PlaneSource->SetOrigin(oNew);
1123 this->PlaneSource->SetPoint1(pt1New);
1124 this->PlaneSource->SetPoint2(pt2New);
1125 this->PlaneSource->Update();
1126
1127 this->PositionHandles();
1128 }
1129
Spin(double * p1,double * p2)1130 void vtkPlaneWidget::Spin(double *p1, double *p2)
1131 {
1132 // Mouse motion vector in world space
1133 double v[3];
1134 v[0] = p2[0] - p1[0];
1135 v[1] = p2[1] - p1[1];
1136 v[2] = p2[2] - p1[2];
1137
1138 double* normal = this->PlaneSource->GetNormal();
1139 // Axis of rotation
1140 double axis[3] = { normal[0], normal[1], normal[2] };
1141 vtkMath::Normalize(axis);
1142
1143 double *o = this->PlaneSource->GetOrigin();
1144 double *pt1 = this->PlaneSource->GetPoint1();
1145 double *pt2 = this->PlaneSource->GetPoint2();
1146 double *center = this->PlaneSource->GetCenter();
1147
1148 // Radius vector (from center to cursor position)
1149 double rv[3] = {p2[0] - center[0],
1150 p2[1] - center[1],
1151 p2[2] - center[2]};
1152
1153 // Distance between center and cursor location
1154 double rs = vtkMath::Normalize(rv);
1155
1156 // Spin direction
1157 double ax_cross_rv[3];
1158 vtkMath::Cross(axis,rv,ax_cross_rv);
1159
1160 // Spin angle
1161 double theta = vtkMath::DegreesFromRadians( vtkMath::Dot( v, ax_cross_rv ) / rs );
1162
1163 // Manipulate the transform to reflect the rotation
1164 this->Transform->Identity();
1165 this->Transform->Translate(center[0],center[1],center[2]);
1166 this->Transform->RotateWXYZ(theta,axis);
1167 this->Transform->Translate(-center[0],-center[1],-center[2]);
1168
1169 //Set the corners
1170 double oNew[3], pt1New[3], pt2New[3];
1171 this->Transform->TransformPoint(o,oNew);
1172 this->Transform->TransformPoint(pt1,pt1New);
1173 this->Transform->TransformPoint(pt2,pt2New);
1174
1175 this->PlaneSource->SetOrigin(oNew);
1176 this->PlaneSource->SetPoint1(pt1New);
1177 this->PlaneSource->SetPoint2(pt2New);
1178 this->PlaneSource->Update();
1179
1180 this->PositionHandles();
1181 }
1182
1183 // Loop through all points and translate them
Translate(double * p1,double * p2)1184 void vtkPlaneWidget::Translate(double *p1, double *p2)
1185 {
1186 //Get the motion vector
1187 double v[3];
1188 v[0] = p2[0] - p1[0];
1189 v[1] = p2[1] - p1[1];
1190 v[2] = p2[2] - p1[2];
1191
1192 //int res = this->PlaneSource->GetXResolution();
1193 double *o = this->PlaneSource->GetOrigin();
1194 double *pt1 = this->PlaneSource->GetPoint1();
1195 double *pt2 = this->PlaneSource->GetPoint2();
1196
1197 double origin[3], point1[3], point2[3];
1198 for (int i=0; i<3; i++)
1199 {
1200 origin[i] = o[i] + v[i];
1201 point1[i] = pt1[i] + v[i];
1202 point2[i] = pt2[i] + v[i];
1203 }
1204
1205 this->PlaneSource->SetOrigin(origin);
1206 this->PlaneSource->SetPoint1(point1);
1207 this->PlaneSource->SetPoint2(point2);
1208 this->PlaneSource->Update();
1209
1210 this->PositionHandles();
1211 }
1212
Scale(double * p1,double * p2,int vtkNotUsed (X),int Y)1213 void vtkPlaneWidget::Scale(double *p1, double *p2, int vtkNotUsed(X), int Y)
1214 {
1215 //Get the motion vector
1216 double v[3];
1217 v[0] = p2[0] - p1[0];
1218 v[1] = p2[1] - p1[1];
1219 v[2] = p2[2] - p1[2];
1220
1221 //int res = this->PlaneSource->GetXResolution();
1222 double *o = this->PlaneSource->GetOrigin();
1223 double *pt1 = this->PlaneSource->GetPoint1();
1224 double *pt2 = this->PlaneSource->GetPoint2();
1225
1226 double center[3];
1227 center[0] = 0.5 * ( pt1[0] + pt2[0] );
1228 center[1] = 0.5 * ( pt1[1] + pt2[1] );
1229 center[2] = 0.5 * ( pt1[2] + pt2[2] );
1230
1231 // Compute the scale factor
1232 double sf =
1233 vtkMath::Norm(v) / sqrt(vtkMath::Distance2BetweenPoints(pt1,pt2));
1234 if ( Y > this->Interactor->GetLastEventPosition()[1] )
1235 {
1236 sf = 1.0 + sf;
1237 }
1238 else
1239 {
1240 sf = 1.0 - sf;
1241 }
1242
1243 // Move the corner points
1244 double origin[3], point1[3], point2[3];
1245 for (int i=0; i<3; i++)
1246 {
1247 origin[i] = sf * (o[i] - center[i]) + center[i];
1248 point1[i] = sf * (pt1[i] - center[i]) + center[i];
1249 point2[i] = sf * (pt2[i] - center[i]) + center[i];
1250 }
1251
1252 this->PlaneSource->SetOrigin(origin);
1253 this->PlaneSource->SetPoint1(point1);
1254 this->PlaneSource->SetPoint2(point2);
1255 this->PlaneSource->Update();
1256
1257 this->PositionHandles();
1258 }
1259
Push(double * p1,double * p2)1260 void vtkPlaneWidget::Push(double *p1, double *p2)
1261 {
1262 //Get the motion vector
1263 double v[3];
1264 v[0] = p2[0] - p1[0];
1265 v[1] = p2[1] - p1[1];
1266 v[2] = p2[2] - p1[2];
1267
1268 this->PlaneSource->Push( vtkMath::Dot(v,this->Normal) );
1269 this->PlaneSource->Update();
1270 this->PositionHandles();
1271 }
1272
CreateDefaultProperties()1273 void vtkPlaneWidget::CreateDefaultProperties()
1274 {
1275 // Handle properties
1276 this->HandleProperty = vtkProperty::New();
1277 this->HandleProperty->SetColor(1,1,1);
1278
1279 this->SelectedHandleProperty = vtkProperty::New();
1280 this->SelectedHandleProperty->SetColor(1,0,0);
1281
1282 // Plane properties
1283 this->PlaneProperty = vtkProperty::New();
1284 this->PlaneProperty->SetAmbient(1.0);
1285 this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
1286
1287 this->SelectedPlaneProperty = vtkProperty::New();
1288 this->SelectRepresentation();
1289 this->SelectedPlaneProperty->SetAmbient(1.0);
1290 this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
1291 }
1292
PlaceWidget(double bds[6])1293 void vtkPlaneWidget::PlaceWidget(double bds[6])
1294 {
1295 int i;
1296 double bounds[6], center[3];
1297
1298 this->AdjustBounds(bds, bounds, center);
1299
1300 if (this->GetInput() || this->Prop3D)
1301 {
1302 if ( this->NormalToYAxis )
1303 {
1304 this->PlaneSource->SetOrigin(bounds[0],center[1],bounds[4]);
1305 this->PlaneSource->SetPoint1(bounds[1],center[1],bounds[4]);
1306 this->PlaneSource->SetPoint2(bounds[0],center[1],bounds[5]);
1307 }
1308 else if ( this->NormalToZAxis )
1309 {
1310 this->PlaneSource->SetOrigin(bounds[0],bounds[2],center[2]);
1311 this->PlaneSource->SetPoint1(bounds[1],bounds[2],center[2]);
1312 this->PlaneSource->SetPoint2(bounds[0],bounds[3],center[2]);
1313 }
1314 else //default or x-normal
1315 {
1316 this->PlaneSource->SetOrigin(center[0],bounds[2],bounds[4]);
1317 this->PlaneSource->SetPoint1(center[0],bounds[3],bounds[4]);
1318 this->PlaneSource->SetPoint2(center[0],bounds[2],bounds[5]);
1319 }
1320 }
1321
1322 this->PlaneSource->Update();
1323
1324 // Position the handles at the end of the planes
1325 this->PositionHandles();
1326
1327 for (i=0; i<6; i++)
1328 {
1329 this->InitialBounds[i] = bounds[i];
1330 }
1331
1332
1333 if (this->GetInput() || this->Prop3D)
1334 {
1335 this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1336 (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1337 (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1338 }
1339 else
1340 {
1341 // this means we have to make use of the PolyDataSource, so
1342 // we just calculate the magnitude of the longest diagonal on
1343 // the plane and use that as InitialLength
1344 double origin[3], point1[3], point2[3];
1345 this->PlaneSource->GetOrigin(origin);
1346 this->PlaneSource->GetPoint1(point1);
1347 this->PlaneSource->GetPoint2(point2);
1348 double sqr1 = 0, sqr2 = 0;
1349 for (i = 0; i < 3; i++)
1350 {
1351 sqr1 += (point1[i] - origin[i]) * (point1[i] - origin[i]);
1352 sqr2 += (point2[i] - origin[i]) * (point2[i] - origin[i]);
1353 }
1354
1355 this->InitialLength = sqrt(sqr1 + sqr2);
1356 }
1357
1358 // Set the radius on the sphere handles
1359 this->SizeHandles();
1360 }
1361
SizeHandles()1362 void vtkPlaneWidget::SizeHandles()
1363 {
1364 double radius = this->vtk3DWidget::SizeHandles(this->HandleSizeFactor);
1365
1366 if (this->ValidPick && !this->LastPickValid)
1367 {
1368 // Adjust factor to preserve old radius.
1369 double oldradius = this->HandleGeometry[0]->GetRadius();
1370 if (oldradius != 0 && radius != 0)
1371 {
1372 this->HandleSizeFactor = oldradius / radius;
1373 radius = oldradius;
1374 }
1375 }
1376
1377 this->LastPickValid = this->ValidPick;
1378
1379 for(int i=0; i<4; i++)
1380 {
1381 this->HandleGeometry[i]->SetRadius(radius);
1382 }
1383
1384 // Set the height and radius of the cone
1385 this->ConeSource->SetHeight(2.0*radius);
1386 this->ConeSource->SetRadius(radius);
1387 this->ConeSource2->SetHeight(2.0*radius);
1388 this->ConeSource2->SetRadius(radius);
1389
1390 }
1391
1392
SelectRepresentation()1393 void vtkPlaneWidget::SelectRepresentation()
1394 {
1395 if ( ! this->CurrentRenderer )
1396 {
1397 return;
1398 }
1399
1400 if ( this->Representation == VTK_PLANE_OFF )
1401 {
1402 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1403 }
1404 else if ( this->Representation == VTK_PLANE_OUTLINE )
1405 {
1406 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1407 this->CurrentRenderer->AddActor(this->PlaneActor);
1408 this->PlaneMapper->SetInputData( this->PlaneOutline );
1409 this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1410 }
1411 else if ( this->Representation == VTK_PLANE_SURFACE )
1412 {
1413 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1414 this->CurrentRenderer->AddActor(this->PlaneActor);
1415 this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1416 this->PlaneActor->GetProperty()->SetRepresentationToSurface();
1417 }
1418 else //( this->Representation == VTK_PLANE_WIREFRAME )
1419 {
1420 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1421 this->CurrentRenderer->AddActor(this->PlaneActor);
1422 this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1423 this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1424 }
1425 }
1426
1427 // Description:
1428 // Set/Get the resolution (number of subdivisions) of the plane.
SetResolution(int r)1429 void vtkPlaneWidget::SetResolution(int r)
1430 {
1431 this->PlaneSource->SetXResolution(r);
1432 this->PlaneSource->SetYResolution(r);
1433 }
1434
GetResolution()1435 int vtkPlaneWidget::GetResolution()
1436 {
1437 return this->PlaneSource->GetXResolution();
1438 }
1439
1440 // Description:
1441 // Set/Get the origin of the plane.
SetOrigin(double x,double y,double z)1442 void vtkPlaneWidget::SetOrigin(double x, double y, double z)
1443 {
1444 this->PlaneSource->SetOrigin(x,y,z);
1445 this->PositionHandles();
1446 }
1447
SetOrigin(double x[3])1448 void vtkPlaneWidget::SetOrigin(double x[3])
1449 {
1450 this->SetOrigin(x[0], x[1], x[2]);
1451 }
1452
GetOrigin()1453 double* vtkPlaneWidget::GetOrigin()
1454 {
1455 return this->PlaneSource->GetOrigin();
1456 }
1457
GetOrigin(double xyz[3])1458 void vtkPlaneWidget::GetOrigin(double xyz[3])
1459 {
1460 this->PlaneSource->GetOrigin(xyz);
1461 }
1462
1463 // Description:
1464 // Set/Get the position of the point defining the first axis of the plane.
SetPoint1(double x,double y,double z)1465 void vtkPlaneWidget::SetPoint1(double x, double y, double z)
1466 {
1467 this->PlaneSource->SetPoint1(x,y,z);
1468 this->PositionHandles();
1469 }
1470
SetPoint1(double x[3])1471 void vtkPlaneWidget::SetPoint1(double x[3])
1472 {
1473 this->SetPoint1(x[0], x[1], x[2]);
1474 }
1475
GetPoint1()1476 double* vtkPlaneWidget::GetPoint1()
1477 {
1478 return this->PlaneSource->GetPoint1();
1479 }
1480
GetPoint1(double xyz[3])1481 void vtkPlaneWidget::GetPoint1(double xyz[3])
1482 {
1483 this->PlaneSource->GetPoint1(xyz);
1484 }
1485
1486 // Description:
1487 // Set/Get the position of the point defining the second axis of the plane.
SetPoint2(double x,double y,double z)1488 void vtkPlaneWidget::SetPoint2(double x, double y, double z)
1489 {
1490 this->PlaneSource->SetPoint2(x,y,z);
1491 this->PositionHandles();
1492 }
1493
SetPoint2(double x[3])1494 void vtkPlaneWidget::SetPoint2(double x[3])
1495 {
1496 this->SetPoint2(x[0], x[1], x[2]);
1497 }
1498
GetPoint2()1499 double* vtkPlaneWidget::GetPoint2()
1500 {
1501 return this->PlaneSource->GetPoint2();
1502 }
1503
GetPoint2(double xyz[3])1504 void vtkPlaneWidget::GetPoint2(double xyz[3])
1505 {
1506 this->PlaneSource->GetPoint2(xyz);
1507 }
1508
1509 // Description:
1510 // Set the center of the plane.
SetCenter(double x,double y,double z)1511 void vtkPlaneWidget::SetCenter(double x, double y, double z)
1512 {
1513 this->PlaneSource->SetCenter(x, y, z);
1514 this->PositionHandles();
1515 }
1516
1517 // Description:
1518 // Set the center of the plane.
SetCenter(double c[3])1519 void vtkPlaneWidget::SetCenter(double c[3])
1520 {
1521 this->SetCenter(c[0], c[1], c[2]);
1522 }
1523
1524 // Description:
1525 // Get the center of the plane.
GetCenter()1526 double* vtkPlaneWidget::GetCenter()
1527 {
1528 return this->PlaneSource->GetCenter();
1529 }
1530
GetCenter(double xyz[3])1531 void vtkPlaneWidget::GetCenter(double xyz[3])
1532 {
1533 this->PlaneSource->GetCenter(xyz);
1534 }
1535
1536 // Description:
1537 // Set the normal to the plane.
SetNormal(double x,double y,double z)1538 void vtkPlaneWidget::SetNormal(double x, double y, double z)
1539 {
1540 this->PlaneSource->SetNormal(x, y, z);
1541 this->PositionHandles();
1542 }
1543
1544 // Description:
1545 // Set the normal to the plane.
SetNormal(double n[3])1546 void vtkPlaneWidget::SetNormal(double n[3])
1547 {
1548 this->SetNormal(n[0], n[1], n[2]);
1549 }
1550
1551 // Description:
1552 // Get the normal to the plane.
GetNormal()1553 double* vtkPlaneWidget::GetNormal()
1554 {
1555 return this->PlaneSource->GetNormal();
1556 }
1557
GetNormal(double xyz[3])1558 void vtkPlaneWidget::GetNormal(double xyz[3])
1559 {
1560 this->PlaneSource->GetNormal(xyz);
1561 }
1562
GetPolyData(vtkPolyData * pd)1563 void vtkPlaneWidget::GetPolyData(vtkPolyData *pd)
1564 {
1565 pd->ShallowCopy(this->PlaneSource->GetOutput());
1566 }
1567
GetPolyDataAlgorithm()1568 vtkPolyDataAlgorithm *vtkPlaneWidget::GetPolyDataAlgorithm()
1569 {
1570 return this->PlaneSource;
1571 }
1572
GetPlane(vtkPlane * plane)1573 void vtkPlaneWidget::GetPlane(vtkPlane *plane)
1574 {
1575 if ( plane == NULL )
1576 {
1577 return;
1578 }
1579
1580 plane->SetNormal(this->GetNormal());
1581 plane->SetOrigin(this->GetCenter());
1582 }
1583
UpdatePlacement(void)1584 void vtkPlaneWidget::UpdatePlacement(void)
1585 {
1586 this->PlaneSource->Update();
1587 this->PositionHandles();
1588 }
1589