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 = nullptr;
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 = nullptr;
219 }
220
221 if (this->SelectedHandleProperty)
222 {
223 this->SelectedHandleProperty->Delete();
224 this->SelectedHandleProperty = nullptr;
225 }
226
227 if (this->PlaneProperty)
228 {
229 this->PlaneProperty->Delete();
230 this->PlaneProperty = nullptr;
231 }
232
233 if (this->SelectedPlaneProperty)
234 {
235 this->SelectedPlaneProperty->Delete();
236 this->SelectedPlaneProperty = nullptr;
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 == nullptr)
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 i->AddObserver(vtkCommand::StartPinchEvent,
289 this->EventCallbackCommand, this->Priority);
290 i->AddObserver(vtkCommand::PinchEvent,
291 this->EventCallbackCommand, this->Priority);
292 i->AddObserver(vtkCommand::EndPinchEvent,
293 this->EventCallbackCommand, this->Priority);
294
295 // Add the plane
296 this->CurrentRenderer->AddActor(this->PlaneActor);
297 this->PlaneActor->SetProperty(this->PlaneProperty);
298
299 // turn on the handles
300 for (int j=0; j<4; j++)
301 {
302 this->CurrentRenderer->AddActor(this->Handle[j]);
303 this->Handle[j]->SetProperty(this->HandleProperty);
304 }
305
306 // add the normal vector
307 this->CurrentRenderer->AddActor(this->LineActor);
308 this->LineActor->SetProperty(this->HandleProperty);
309 this->CurrentRenderer->AddActor(this->ConeActor);
310 this->ConeActor->SetProperty(this->HandleProperty);
311 this->CurrentRenderer->AddActor(this->LineActor2);
312 this->LineActor2->SetProperty(this->HandleProperty);
313 this->CurrentRenderer->AddActor(this->ConeActor2);
314 this->ConeActor2->SetProperty(this->HandleProperty);
315
316 this->SelectRepresentation();
317 this->RegisterPickers();
318 this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
319 }
320
321 else //disabling----------------------------------------------------------
322 {
323 vtkDebugMacro(<<"Disabling plane widget");
324
325 if ( ! this->Enabled ) //already disabled, just return
326 {
327 return;
328 }
329
330 this->Enabled = 0;
331
332 // don't listen for events any more
333 this->Interactor->RemoveObserver(this->EventCallbackCommand);
334
335 // turn off the plane
336 this->CurrentRenderer->RemoveActor(this->PlaneActor);
337
338 // turn off the handles
339 for (int i=0; i<4; i++)
340 {
341 this->CurrentRenderer->RemoveActor(this->Handle[i]);
342 }
343
344 // turn off the normal vector
345 this->CurrentRenderer->RemoveActor(this->LineActor);
346 this->CurrentRenderer->RemoveActor(this->ConeActor);
347 this->CurrentRenderer->RemoveActor(this->LineActor2);
348 this->CurrentRenderer->RemoveActor(this->ConeActor2);
349
350 this->CurrentHandle = nullptr;
351 this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
352 this->SetCurrentRenderer(nullptr);
353 this->UnRegisterPickers();
354 }
355
356 this->Interactor->Render();
357 }
358
359 //------------------------------------------------------------------------------
RegisterPickers()360 void vtkPlaneWidget::RegisterPickers()
361 {
362 vtkPickingManager* pm = this->GetPickingManager();
363 if (!pm)
364 {
365 return;
366 }
367 pm->AddPicker(this->HandlePicker, this);
368 pm->AddPicker(this->PlanePicker, this);
369 }
370
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))371 void vtkPlaneWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
372 unsigned long event,
373 void* clientdata,
374 void* vtkNotUsed(calldata))
375 {
376 vtkPlaneWidget* self = reinterpret_cast<vtkPlaneWidget *>( clientdata );
377
378 //okay, let's do the right thing
379 switch(event)
380 {
381 case vtkCommand::LeftButtonPressEvent:
382 self->OnLeftButtonDown();
383 break;
384 case vtkCommand::LeftButtonReleaseEvent:
385 self->OnLeftButtonUp();
386 break;
387 case vtkCommand::MiddleButtonPressEvent:
388 self->OnMiddleButtonDown();
389 break;
390 case vtkCommand::MiddleButtonReleaseEvent:
391 self->OnMiddleButtonUp();
392 break;
393 case vtkCommand::RightButtonPressEvent:
394 self->OnRightButtonDown();
395 break;
396 case vtkCommand::RightButtonReleaseEvent:
397 self->OnRightButtonUp();
398 break;
399 case vtkCommand::MouseMoveEvent:
400 self->OnMouseMove();
401 break;
402 case vtkCommand::StartPinchEvent:
403 self->OnStartPinch();
404 break;
405 case vtkCommand::PinchEvent:
406 self->OnPinch();
407 break;
408 case vtkCommand::EndPinchEvent:
409 self->OnEndPinch();
410 break;
411 }
412 }
413
PrintSelf(ostream & os,vtkIndent indent)414 void vtkPlaneWidget::PrintSelf(ostream& os, vtkIndent indent)
415 {
416 this->Superclass::PrintSelf(os,indent);
417
418 if ( this->HandleProperty )
419 {
420 os << indent << "Handle Property: " << this->HandleProperty << "\n";
421 }
422 else
423 {
424 os << indent << "Handle Property: (none)\n";
425 }
426 if ( this->SelectedHandleProperty )
427 {
428 os << indent << "Selected Handle Property: "
429 << this->SelectedHandleProperty << "\n";
430 }
431 else
432 {
433 os << indent << "SelectedHandle Property: (none)\n";
434 }
435
436 if ( this->PlaneProperty )
437 {
438 os << indent << "Plane Property: " << this->PlaneProperty << "\n";
439 }
440 else
441 {
442 os << indent << "Plane Property: (none)\n";
443 }
444 if ( this->SelectedPlaneProperty )
445 {
446 os << indent << "Selected Plane Property: "
447 << this->SelectedPlaneProperty << "\n";
448 }
449 else
450 {
451 os << indent << "Selected Plane Property: (none)\n";
452 }
453
454 os << indent << "Plane Representation: ";
455 if ( this->Representation == VTK_PLANE_WIREFRAME )
456 {
457 os << "Wireframe\n";
458 }
459 else if ( this->Representation == VTK_PLANE_SURFACE )
460 {
461 os << "Surface\n";
462 }
463 else //( this->Representation == VTK_PLANE_OUTLINE )
464 {
465 os << "Outline\n";
466 }
467
468 os << indent << "Normal To X Axis: "
469 << (this->NormalToXAxis ? "On" : "Off") << "\n";
470 os << indent << "Normal To Y Axis: "
471 << (this->NormalToYAxis ? "On" : "Off") << "\n";
472 os << indent << "Normal To Z Axis: "
473 << (this->NormalToZAxis ? "On" : "Off") << "\n";
474
475 int res = this->PlaneSource->GetXResolution();
476 double *o = this->PlaneSource->GetOrigin();
477 double *pt1 = this->PlaneSource->GetPoint1();
478 double *pt2 = this->PlaneSource->GetPoint2();
479
480 os << indent << "Resolution: " << res << "\n";
481 os << indent << "Origin: (" << o[0] << ", "
482 << o[1] << ", "
483 << o[2] << ")\n";
484 os << indent << "Point 1: (" << pt1[0] << ", "
485 << pt1[1] << ", "
486 << pt1[2] << ")\n";
487 os << indent << "Point 2: (" << pt2[0] << ", "
488 << pt2[1] << ", "
489 << pt2[2] << ")\n";
490 }
491
PositionHandles()492 void vtkPlaneWidget::PositionHandles()
493 {
494 double *o = this->PlaneSource->GetOrigin();
495 double *pt1 = this->PlaneSource->GetPoint1();
496 double *pt2 = this->PlaneSource->GetPoint2();
497
498 this->HandleGeometry[0]->SetCenter(o);
499 this->HandleGeometry[1]->SetCenter(pt1);
500 this->HandleGeometry[2]->SetCenter(pt2);
501
502 double x[3];
503 x[0] = pt1[0] + pt2[0] - o[0];
504 x[1] = pt1[1] + pt2[1] - o[1];
505 x[2] = pt1[2] + pt2[2] - o[2];
506 this->HandleGeometry[3]->SetCenter(x); //far corner
507
508 // set up the outline
509 if ( this->Representation == VTK_PLANE_OUTLINE )
510 {
511 this->PlaneOutline->GetPoints()->SetPoint(0,o);
512 this->PlaneOutline->GetPoints()->SetPoint(1,pt1);
513 this->PlaneOutline->GetPoints()->SetPoint(2,x);
514 this->PlaneOutline->GetPoints()->SetPoint(3,pt2);
515 this->PlaneOutline->GetPoints()->Modified();
516 }
517 this->SelectRepresentation();
518
519 // Create the normal vector
520 double center[3];
521 this->PlaneSource->GetCenter(center);
522 this->LineSource->SetPoint1(center);
523 this->LineSource2->SetPoint1(center);
524 double p2[3];
525 this->PlaneSource->GetNormal(this->Normal);
526 vtkMath::Normalize(this->Normal);
527 double d = sqrt(
528 vtkMath::Distance2BetweenPoints(
529 this->PlaneSource->GetPoint1(),this->PlaneSource->GetPoint2()) );
530
531 p2[0] = center[0] + 0.35 * d * this->Normal[0];
532 p2[1] = center[1] + 0.35 * d * this->Normal[1];
533 p2[2] = center[2] + 0.35 * d * this->Normal[2];
534 this->LineSource->SetPoint2(p2);
535 this->ConeSource->SetCenter(p2);
536 this->ConeSource->SetDirection(this->Normal);
537
538 p2[0] = center[0] - 0.35 * d * this->Normal[0];
539 p2[1] = center[1] - 0.35 * d * this->Normal[1];
540 p2[2] = center[2] - 0.35 * d * this->Normal[2];
541 this->LineSource2->SetPoint2(p2);
542 this->ConeSource2->SetCenter(p2);
543 this->ConeSource2->SetDirection(this->Normal);
544 }
545
HighlightHandle(vtkProp * prop)546 int vtkPlaneWidget::HighlightHandle(vtkProp *prop)
547 {
548 // first unhighlight anything picked
549 if ( this->CurrentHandle )
550 {
551 this->CurrentHandle->SetProperty(this->HandleProperty);
552 }
553
554 this->CurrentHandle = static_cast<vtkActor *>(prop);
555
556 if ( this->CurrentHandle )
557 {
558 this->ValidPick = 1;
559 this->HandlePicker->GetPickPosition(this->LastPickPosition);
560 this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
561 for (int i=0; i<4; i++) //find handle
562 {
563 if ( this->CurrentHandle == this->Handle[i] )
564 {
565 return i;
566 }
567 }
568 }
569
570 return -1;
571 }
572
HighlightNormal(int highlight)573 void vtkPlaneWidget::HighlightNormal(int highlight)
574 {
575 if ( highlight )
576 {
577 this->ValidPick = 1;
578 this->PlanePicker->GetPickPosition(this->LastPickPosition);
579 this->LineActor->SetProperty(this->SelectedHandleProperty);
580 this->ConeActor->SetProperty(this->SelectedHandleProperty);
581 this->LineActor2->SetProperty(this->SelectedHandleProperty);
582 this->ConeActor2->SetProperty(this->SelectedHandleProperty);
583 }
584 else
585 {
586 this->LineActor->SetProperty(this->HandleProperty);
587 this->ConeActor->SetProperty(this->HandleProperty);
588 this->LineActor2->SetProperty(this->HandleProperty);
589 this->ConeActor2->SetProperty(this->HandleProperty);
590 }
591 }
592
HighlightPlane(int highlight)593 void vtkPlaneWidget::HighlightPlane(int highlight)
594 {
595 if ( highlight )
596 {
597 this->ValidPick = 1;
598 this->PlanePicker->GetPickPosition(this->LastPickPosition);
599 this->PlaneActor->SetProperty(this->SelectedPlaneProperty);
600 }
601 else
602 {
603 this->PlaneActor->SetProperty(this->PlaneProperty);
604 }
605 }
606
OnStartPinch()607 void vtkPlaneWidget::OnStartPinch()
608 {
609 int X = this->Interactor->GetEventPosition()[0];
610 int Y = this->Interactor->GetEventPosition()[1];
611
612 // Okay, make sure that the pick is in the current renderer
613 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
614 {
615 this->State = vtkPlaneWidget::Outside;
616 return;
617 }
618
619 // Okay, we can process this. try to pick the plane.
620 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
621
622 if ( path != nullptr )
623 {
624 this->State = vtkPlaneWidget::Pinching;
625 this->HighlightPlane(1);
626 this->StartInteraction();
627 this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
628 }
629 }
630
OnPinch()631 void vtkPlaneWidget::OnPinch()
632 {
633 if ( this->State != vtkPlaneWidget::Pinching)
634 {
635 return;
636 }
637
638 double sf = this->Interactor->GetScale()/this->Interactor->GetLastScale();
639 double *o = this->PlaneSource->GetOrigin();
640 double *pt1 = this->PlaneSource->GetPoint1();
641 double *pt2 = this->PlaneSource->GetPoint2();
642
643 double center[3];
644 center[0] = 0.5 * ( pt1[0] + pt2[0] );
645 center[1] = 0.5 * ( pt1[1] + pt2[1] );
646 center[2] = 0.5 * ( pt1[2] + pt2[2] );
647
648 // Move the corner points
649 double origin[3], point1[3], point2[3];
650 for (int i=0; i<3; i++)
651 {
652 origin[i] = sf * (o[i] - center[i]) + center[i];
653 point1[i] = sf * (pt1[i] - center[i]) + center[i];
654 point2[i] = sf * (pt2[i] - center[i]) + center[i];
655 }
656
657 this->PlaneSource->SetOrigin(origin);
658 this->PlaneSource->SetPoint1(point1);
659 this->PlaneSource->SetPoint2(point2);
660 this->PlaneSource->Update();
661
662 this->PositionHandles();
663
664 this->EventCallbackCommand->SetAbortFlag(1);
665 this->InvokeEvent(vtkCommand::InteractionEvent,nullptr);
666 this->Interactor->Render();
667 }
668
OnEndPinch()669 void vtkPlaneWidget::OnEndPinch()
670 {
671 if ( this->State != vtkPlaneWidget::Pinching)
672 {
673 return;
674 }
675
676 this->State = vtkPlaneWidget::Start;
677 this->HighlightHandle(nullptr);
678 this->HighlightPlane(0);
679 this->HighlightNormal(0);
680 this->SizeHandles();
681
682 this->EventCallbackCommand->SetAbortFlag(1);
683 this->EndInteraction();
684 this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
685 this->Interactor->Render();
686 }
687
OnLeftButtonDown()688 void vtkPlaneWidget::OnLeftButtonDown()
689 {
690 int X = this->Interactor->GetEventPosition()[0];
691 int Y = this->Interactor->GetEventPosition()[1];
692
693 // Okay, make sure that the pick is in the current renderer
694 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
695 {
696 this->State = vtkPlaneWidget::Outside;
697 return;
698 }
699
700 // Okay, we can process this. Try to pick handles first;
701 // if no handles picked, then try to pick the plane.
702 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
703
704 if ( path != nullptr )
705 {
706 this->State = vtkPlaneWidget::Moving;
707 this->HighlightHandle(path->GetFirstNode()->GetViewProp());
708 }
709 else
710 {
711 path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
712
713 if ( path != nullptr )
714 {
715 vtkProp *prop = path->GetFirstNode()->GetViewProp();
716 if ( prop == this->ConeActor || prop == this->LineActor ||
717 prop == this->ConeActor2 || prop == this->LineActor2 )
718 {
719 this->State = vtkPlaneWidget::Rotating;
720 this->HighlightNormal(1);
721 }
722 else if (this->Interactor->GetControlKey())
723 {
724 this->State = vtkPlaneWidget::Spinning;
725 this->HighlightNormal(1);
726 }
727 else
728 {
729 this->State = vtkPlaneWidget::Moving;
730 this->HighlightPlane(1);
731 }
732 }
733 else
734 {
735 this->State = vtkPlaneWidget::Outside;
736 this->HighlightHandle(nullptr);
737 return;
738 }
739 }
740
741 this->EventCallbackCommand->SetAbortFlag(1);
742 this->StartInteraction();
743 this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
744 this->Interactor->Render();
745 }
746
OnLeftButtonUp()747 void vtkPlaneWidget::OnLeftButtonUp()
748 {
749 if ( this->State == vtkPlaneWidget::Outside ||
750 this->State == vtkPlaneWidget::Start )
751 {
752 return;
753 }
754
755 this->State = vtkPlaneWidget::Start;
756 this->HighlightHandle(nullptr);
757 this->HighlightPlane(0);
758 this->HighlightNormal(0);
759 this->SizeHandles();
760
761 this->EventCallbackCommand->SetAbortFlag(1);
762 this->EndInteraction();
763 this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
764 this->Interactor->Render();
765 }
766
OnMiddleButtonDown()767 void vtkPlaneWidget::OnMiddleButtonDown()
768 {
769 int X = this->Interactor->GetEventPosition()[0];
770 int Y = this->Interactor->GetEventPosition()[1];
771
772 // Okay, make sure that the pick is in the current renderer
773 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
774 {
775 this->State = vtkPlaneWidget::Outside;
776 return;
777 }
778
779 // Okay, we can process this. If anything is picked, then we
780 // can start pushing the plane.
781 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
782
783 if ( path != nullptr )
784 {
785 this->State = vtkPlaneWidget::Pushing;
786 this->HighlightPlane(1);
787 this->HighlightNormal(1);
788 this->HighlightHandle(path->GetFirstNode()->GetViewProp());
789 }
790 else
791 {
792 path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
793
794 if ( path == nullptr ) //nothing picked
795 {
796 this->State = vtkPlaneWidget::Outside;
797 return;
798 }
799 else
800 {
801 this->State = vtkPlaneWidget::Pushing;
802 this->HighlightNormal(1);
803 this->HighlightPlane(1);
804 }
805 }
806
807 this->EventCallbackCommand->SetAbortFlag(1);
808 this->StartInteraction();
809 this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
810 this->Interactor->Render();
811 }
812
OnMiddleButtonUp()813 void vtkPlaneWidget::OnMiddleButtonUp()
814 {
815 if ( this->State == vtkPlaneWidget::Outside ||
816 this->State == vtkPlaneWidget::Start )
817 {
818 return;
819 }
820
821 this->State = vtkPlaneWidget::Start;
822 this->HighlightPlane(0);
823 this->HighlightNormal(0);
824 this->HighlightHandle(nullptr);
825 this->SizeHandles();
826
827 this->EventCallbackCommand->SetAbortFlag(1);
828 this->EndInteraction();
829 this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
830 this->Interactor->Render();
831 }
832
OnRightButtonDown()833 void vtkPlaneWidget::OnRightButtonDown()
834 {
835 int X = this->Interactor->GetEventPosition()[0];
836 int Y = this->Interactor->GetEventPosition()[1];
837
838 // Okay, make sure that the pick is in the current renderer
839 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
840 {
841 this->State = vtkPlaneWidget::Outside;
842 return;
843 }
844
845 // Okay, we can process this. Try to pick handles first;
846 // if no handles picked, then pick the bounding box.
847 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
848
849 if ( path != nullptr )
850 {
851 this->State = vtkPlaneWidget::Scaling;
852 this->HighlightPlane(1);
853 this->HighlightHandle(path->GetFirstNode()->GetViewProp());
854 }
855 else //see if we picked the plane or a normal
856 {
857 path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker);
858
859 if ( path == nullptr )
860 {
861 this->State = vtkPlaneWidget::Outside;
862 return;
863 }
864 else
865 {
866 this->State = vtkPlaneWidget::Scaling;
867 this->HighlightPlane(1);
868 }
869 }
870
871 this->EventCallbackCommand->SetAbortFlag(1);
872 this->StartInteraction();
873 this->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
874 this->Interactor->Render();
875 }
876
OnRightButtonUp()877 void vtkPlaneWidget::OnRightButtonUp()
878 {
879 if ( this->State == vtkPlaneWidget::Outside ||
880 this->State == vtkPlaneWidget::Start )
881 {
882 return;
883 }
884
885 this->State = vtkPlaneWidget::Start;
886 this->HighlightPlane(0);
887 this->SizeHandles();
888
889 this->EventCallbackCommand->SetAbortFlag(1);
890 this->EndInteraction();
891 this->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
892 this->Interactor->Render();
893 }
894
OnMouseMove()895 void vtkPlaneWidget::OnMouseMove()
896 {
897 // See whether we're active
898 if ( this->State == vtkPlaneWidget::Outside ||
899 this->State == vtkPlaneWidget::Start )
900 {
901 return;
902 }
903
904 int X = this->Interactor->GetEventPosition()[0];
905 int Y = this->Interactor->GetEventPosition()[1];
906
907 // Do different things depending on state
908 // Calculations everybody does
909 double focalPoint[4], pickPoint[4], prevPickPoint[4];
910 double z, vpn[3];
911
912 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
913 if ( !camera )
914 {
915 return;
916 }
917
918 // Compute the two points defining the motion vector
919 this->ComputeWorldToDisplay(this->LastPickPosition[0],
920 this->LastPickPosition[1],
921 this->LastPickPosition[2], focalPoint);
922 z = focalPoint[2];
923 this->ComputeDisplayToWorld(
924 double(this->Interactor->GetLastEventPosition()[0]),
925 double(this->Interactor->GetLastEventPosition()[1]),
926 z, prevPickPoint);
927 this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
928
929 // Process the motion
930 if ( this->State == vtkPlaneWidget::Moving )
931 {
932 // Okay to process
933 if ( this->CurrentHandle )
934 {
935 if ( this->CurrentHandle == this->Handle[0] )
936 {
937 this->MoveOrigin(prevPickPoint, pickPoint);
938 }
939 else if ( this->CurrentHandle == this->Handle[1] )
940 {
941 this->MovePoint1(prevPickPoint, pickPoint);
942 }
943 else if ( this->CurrentHandle == this->Handle[2] )
944 {
945 this->MovePoint2(prevPickPoint, pickPoint);
946 }
947 else if ( this->CurrentHandle == this->Handle[3] )
948 {
949 this->MovePoint3(prevPickPoint, pickPoint);
950 }
951 }
952 else //must be moving the plane
953 {
954 this->Translate(prevPickPoint, pickPoint);
955 }
956 }
957 else if ( this->State == vtkPlaneWidget::Scaling )
958 {
959 this->Scale(prevPickPoint, pickPoint, X, Y);
960 }
961 else if ( this->State == vtkPlaneWidget::Pushing )
962 {
963 this->Push(prevPickPoint, pickPoint);
964 }
965 else if ( this->State == vtkPlaneWidget::Rotating )
966 {
967 camera->GetViewPlaneNormal(vpn);
968 this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
969 }
970 else if ( this->State == vtkPlaneWidget::Spinning )
971 {
972 this->Spin(prevPickPoint, pickPoint);
973 }
974
975
976 // Interact, if desired
977 this->EventCallbackCommand->SetAbortFlag(1);
978 this->InvokeEvent(vtkCommand::InteractionEvent,nullptr);
979
980 this->Interactor->Render();
981 }
982
MoveOrigin(double * p1,double * p2)983 void vtkPlaneWidget::MoveOrigin(double *p1, double *p2)
984 {
985 //Get the plane definition
986 double *o = this->PlaneSource->GetOrigin();
987 double *pt1 = this->PlaneSource->GetPoint1();
988 double *pt2 = this->PlaneSource->GetPoint2();
989
990 //Get the vector of motion
991 double v[3];
992 v[0] = p2[0] - p1[0];
993 v[1] = p2[1] - p1[1];
994 v[2] = p2[2] - p1[2];
995
996 // The point opposite the origin (pt3) stays fixed
997 double pt3[3];
998 pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
999 pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1000 pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1001
1002 // Define vectors from point pt3
1003 double p13[3], p23[3];
1004 p13[0] = pt1[0] - pt3[0];
1005 p13[1] = pt1[1] - pt3[1];
1006 p13[2] = pt1[2] - pt3[2];
1007 p23[0] = pt2[0] - pt3[0];
1008 p23[1] = pt2[1] - pt3[1];
1009 p23[2] = pt2[2] - pt3[2];
1010
1011 double vN = vtkMath::Norm(v);
1012 double n13 = vtkMath::Norm(p13);
1013 double n23 = vtkMath::Norm(p23);
1014
1015 // Project v onto these vector to determine the amount of motion
1016 // Scale it by the relative size of the motion to the vector length
1017 double d1 = (vN/n13) * vtkMath::Dot(v,p13) / (vN*n13);
1018 double d2 = (vN/n23) * vtkMath::Dot(v,p23) / (vN*n23);
1019
1020 double point1[3], point2[3], origin[3];
1021 for (int i=0; i<3; i++)
1022 {
1023 point1[i] = pt3[i] + (1.0+d1)*p13[i];
1024 point2[i] = pt3[i] + (1.0+d2)*p23[i];
1025 origin[i] = pt3[i] + (1.0+d1)*p13[i] + (1.0+d2)*p23[i];
1026 }
1027
1028 this->PlaneSource->SetOrigin(origin);
1029 this->PlaneSource->SetPoint1(point1);
1030 this->PlaneSource->SetPoint2(point2);
1031 this->PlaneSource->Update();
1032
1033 this->PositionHandles();
1034 }
1035
MovePoint1(double * p1,double * p2)1036 void vtkPlaneWidget::MovePoint1(double *p1, double *p2)
1037 {
1038 //Get the plane definition
1039 double *o = this->PlaneSource->GetOrigin();
1040 double *pt1 = this->PlaneSource->GetPoint1();
1041 double *pt2 = this->PlaneSource->GetPoint2();
1042
1043 //Get the vector of motion
1044 double v[3];
1045 v[0] = p2[0] - p1[0];
1046 v[1] = p2[1] - p1[1];
1047 v[2] = p2[2] - p1[2];
1048
1049 // Need the point opposite the origin (pt3)
1050 double pt3[3];
1051 pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
1052 pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1053 pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1054
1055 // Define vectors from point pt2
1056 double p32[3], p02[3];
1057 p02[0] = o[0] - pt2[0];
1058 p02[1] = o[1] - pt2[1];
1059 p02[2] = o[2] - pt2[2];
1060 p32[0] = pt3[0] - pt2[0];
1061 p32[1] = pt3[1] - pt2[1];
1062 p32[2] = pt3[2] - pt2[2];
1063
1064 double vN = vtkMath::Norm(v);
1065 double n02 = vtkMath::Norm(p02);
1066 double n32 = vtkMath::Norm(p32);
1067
1068 // if there is no motion then return
1069 if (vN == 0.0)
1070 {
1071 return;
1072 }
1073
1074 // Project v onto these vector to determine the amount of motion
1075 // Scale it by the relative size of the motion to the vector length
1076 double d1 = (vN/n02) * vtkMath::Dot(v,p02) / (vN*n02);
1077 double d2 = (vN/n32) * vtkMath::Dot(v,p32) / (vN*n32);
1078
1079 double point1[3], origin[3];
1080 for (int i=0; i<3; i++)
1081 {
1082 origin[i] = pt2[i] + (1.0+d1)*p02[i];
1083 point1[i] = pt2[i] + (1.0+d1)*p02[i] + (1.0+d2)*p32[i];
1084 }
1085
1086 this->PlaneSource->SetOrigin(origin);
1087 this->PlaneSource->SetPoint1(point1);
1088 this->PlaneSource->Update();
1089
1090 this->PositionHandles();
1091 }
1092
MovePoint2(double * p1,double * p2)1093 void vtkPlaneWidget::MovePoint2(double *p1, double *p2)
1094 {
1095 //Get the plane definition
1096 double *o = this->PlaneSource->GetOrigin();
1097 double *pt1 = this->PlaneSource->GetPoint1();
1098 double *pt2 = this->PlaneSource->GetPoint2();
1099
1100 //Get the vector of motion
1101 double v[3];
1102 v[0] = p2[0] - p1[0];
1103 v[1] = p2[1] - p1[1];
1104 v[2] = p2[2] - p1[2];
1105
1106 // The point opposite point2 (pt1) stays fixed
1107 double pt3[3];
1108 pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]);
1109 pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]);
1110 pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]);
1111
1112 // Define vectors from point pt1
1113 double p01[3], p31[3];
1114 p31[0] = pt3[0] - pt1[0];
1115 p31[1] = pt3[1] - pt1[1];
1116 p31[2] = pt3[2] - pt1[2];
1117 p01[0] = o[0] - pt1[0];
1118 p01[1] = o[1] - pt1[1];
1119 p01[2] = o[2] - pt1[2];
1120
1121 double vN = vtkMath::Norm(v);
1122 double n31 = vtkMath::Norm(p31);
1123 double n01 = vtkMath::Norm(p01);
1124
1125 // if there is no motion then return
1126 if (vN == 0.0)
1127 {
1128 return;
1129 }
1130
1131 // Project v onto these vector to determine the amount of motion
1132 // Scale it by the relative size of the motion to the vector length
1133 double d1 = (vN/n31) * vtkMath::Dot(v,p31) / (vN*n31);
1134 double d2 = (vN/n01) * vtkMath::Dot(v,p01) / (vN*n01);
1135
1136 double point2[3], origin[3];
1137 for (int i=0; i<3; i++)
1138 {
1139 point2[i] = pt1[i] + (1.0+d1)*p31[i] + (1.0+d2)*p01[i];
1140 origin[i] = pt1[i] + (1.0+d2)*p01[i];
1141 }
1142
1143 this->PlaneSource->SetOrigin(origin);
1144 this->PlaneSource->SetPoint2(point2);
1145 this->PlaneSource->Update();
1146
1147 this->PositionHandles();
1148 }
1149
MovePoint3(double * p1,double * p2)1150 void vtkPlaneWidget::MovePoint3(double *p1, double *p2)
1151 {
1152 //Get the plane definition
1153 double *o = this->PlaneSource->GetOrigin();
1154 double *pt1 = this->PlaneSource->GetPoint1();
1155 double *pt2 = this->PlaneSource->GetPoint2();
1156
1157 //Get the vector of motion
1158 double v[3];
1159 v[0] = p2[0] - p1[0];
1160 v[1] = p2[1] - p1[1];
1161 v[2] = p2[2] - p1[2];
1162
1163 // Define vectors from point pt3
1164 double p10[3], p20[3];
1165 p10[0] = pt1[0] - o[0];
1166 p10[1] = pt1[1] - o[1];
1167 p10[2] = pt1[2] - o[2];
1168 p20[0] = pt2[0] - o[0];
1169 p20[1] = pt2[1] - o[1];
1170 p20[2] = pt2[2] - o[2];
1171
1172 double vN = vtkMath::Norm(v);
1173 double n10 = vtkMath::Norm(p10);
1174 double n20 = vtkMath::Norm(p20);
1175
1176 // if there is no motion then return
1177 if (vN == 0.0)
1178 {
1179 return;
1180 }
1181
1182 // Project v onto these vector to determine the amount of motion
1183 // Scale it by the relative size of the motion to the vector length
1184 double d1 = (vN/n10) * vtkMath::Dot(v,p10) / (vN*n10);
1185 double d2 = (vN/n20) * vtkMath::Dot(v,p20) / (vN*n20);
1186
1187 double point1[3], point2[3];
1188 for (int i=0; i<3; i++)
1189 {
1190 point1[i] = o[i] + (1.0+d1)*p10[i];
1191 point2[i] = o[i] + (1.0+d2)*p20[i];
1192 }
1193
1194 this->PlaneSource->SetPoint1(point1);
1195 this->PlaneSource->SetPoint2(point2);
1196 this->PlaneSource->Update();
1197
1198 this->PositionHandles();
1199 }
1200
Rotate(int X,int Y,double * p1,double * p2,double * vpn)1201 void vtkPlaneWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn)
1202 {
1203 double *o = this->PlaneSource->GetOrigin();
1204 double *pt1 = this->PlaneSource->GetPoint1();
1205 double *pt2 = this->PlaneSource->GetPoint2();
1206 double *center = this->PlaneSource->GetCenter();
1207
1208 double v[3]; //vector of motion
1209 double axis[3]; //axis of rotation
1210 double theta; //rotation angle
1211
1212 // mouse motion vector in world space
1213 v[0] = p2[0] - p1[0];
1214 v[1] = p2[1] - p1[1];
1215 v[2] = p2[2] - p1[2];
1216
1217 // Create axis of rotation and angle of rotation
1218 vtkMath::Cross(vpn,v,axis);
1219 if ( vtkMath::Normalize(axis) == 0.0 )
1220 {
1221 return;
1222 }
1223 int *size = this->CurrentRenderer->GetSize();
1224 double l2 =
1225 (X-this->Interactor->GetLastEventPosition()[0])*
1226 (X-this->Interactor->GetLastEventPosition()[0]) +
1227 (Y-this->Interactor->GetLastEventPosition()[1])*
1228 (Y-this->Interactor->GetLastEventPosition()[1]);
1229 theta = 360.0 * sqrt(l2/(size[0]*size[0]+size[1]*size[1]));
1230
1231 //Manipulate the transform to reflect the rotation
1232 this->Transform->Identity();
1233 this->Transform->Translate(center[0],center[1],center[2]);
1234 this->Transform->RotateWXYZ(theta,axis);
1235 this->Transform->Translate(-center[0],-center[1],-center[2]);
1236
1237 //Set the corners
1238 double oNew[3], pt1New[3], pt2New[3];
1239 this->Transform->TransformPoint(o,oNew);
1240 this->Transform->TransformPoint(pt1,pt1New);
1241 this->Transform->TransformPoint(pt2,pt2New);
1242
1243 this->PlaneSource->SetOrigin(oNew);
1244 this->PlaneSource->SetPoint1(pt1New);
1245 this->PlaneSource->SetPoint2(pt2New);
1246 this->PlaneSource->Update();
1247
1248 this->PositionHandles();
1249 }
1250
Spin(double * p1,double * p2)1251 void vtkPlaneWidget::Spin(double *p1, double *p2)
1252 {
1253 // Mouse motion vector in world space
1254 double v[3];
1255 v[0] = p2[0] - p1[0];
1256 v[1] = p2[1] - p1[1];
1257 v[2] = p2[2] - p1[2];
1258
1259 double* normal = this->PlaneSource->GetNormal();
1260 // Axis of rotation
1261 double axis[3] = { normal[0], normal[1], normal[2] };
1262 vtkMath::Normalize(axis);
1263
1264 double *o = this->PlaneSource->GetOrigin();
1265 double *pt1 = this->PlaneSource->GetPoint1();
1266 double *pt2 = this->PlaneSource->GetPoint2();
1267 double *center = this->PlaneSource->GetCenter();
1268
1269 // Radius vector (from center to cursor position)
1270 double rv[3] = {p2[0] - center[0],
1271 p2[1] - center[1],
1272 p2[2] - center[2]};
1273
1274 // Distance between center and cursor location
1275 double rs = vtkMath::Normalize(rv);
1276
1277 // Spin direction
1278 double ax_cross_rv[3];
1279 vtkMath::Cross(axis,rv,ax_cross_rv);
1280
1281 // Spin angle
1282 double theta = vtkMath::DegreesFromRadians( vtkMath::Dot( v, ax_cross_rv ) / rs );
1283
1284 // Manipulate the transform to reflect the rotation
1285 this->Transform->Identity();
1286 this->Transform->Translate(center[0],center[1],center[2]);
1287 this->Transform->RotateWXYZ(theta,axis);
1288 this->Transform->Translate(-center[0],-center[1],-center[2]);
1289
1290 //Set the corners
1291 double oNew[3], pt1New[3], pt2New[3];
1292 this->Transform->TransformPoint(o,oNew);
1293 this->Transform->TransformPoint(pt1,pt1New);
1294 this->Transform->TransformPoint(pt2,pt2New);
1295
1296 this->PlaneSource->SetOrigin(oNew);
1297 this->PlaneSource->SetPoint1(pt1New);
1298 this->PlaneSource->SetPoint2(pt2New);
1299 this->PlaneSource->Update();
1300
1301 this->PositionHandles();
1302 }
1303
1304 // Loop through all points and translate them
Translate(double * p1,double * p2)1305 void vtkPlaneWidget::Translate(double *p1, double *p2)
1306 {
1307 //Get the motion vector
1308 double v[3];
1309 v[0] = p2[0] - p1[0];
1310 v[1] = p2[1] - p1[1];
1311 v[2] = p2[2] - p1[2];
1312
1313 //int res = this->PlaneSource->GetXResolution();
1314 double *o = this->PlaneSource->GetOrigin();
1315 double *pt1 = this->PlaneSource->GetPoint1();
1316 double *pt2 = this->PlaneSource->GetPoint2();
1317
1318 double origin[3], point1[3], point2[3];
1319 for (int i=0; i<3; i++)
1320 {
1321 origin[i] = o[i] + v[i];
1322 point1[i] = pt1[i] + v[i];
1323 point2[i] = pt2[i] + v[i];
1324 }
1325
1326 this->PlaneSource->SetOrigin(origin);
1327 this->PlaneSource->SetPoint1(point1);
1328 this->PlaneSource->SetPoint2(point2);
1329 this->PlaneSource->Update();
1330
1331 this->PositionHandles();
1332 }
1333
Scale(double * p1,double * p2,int vtkNotUsed (X),int Y)1334 void vtkPlaneWidget::Scale(double *p1, double *p2, int vtkNotUsed(X), int Y)
1335 {
1336 //Get the motion vector
1337 double v[3];
1338 v[0] = p2[0] - p1[0];
1339 v[1] = p2[1] - p1[1];
1340 v[2] = p2[2] - p1[2];
1341
1342 //int res = this->PlaneSource->GetXResolution();
1343 double *o = this->PlaneSource->GetOrigin();
1344 double *pt1 = this->PlaneSource->GetPoint1();
1345 double *pt2 = this->PlaneSource->GetPoint2();
1346
1347 double center[3];
1348 center[0] = 0.5 * ( pt1[0] + pt2[0] );
1349 center[1] = 0.5 * ( pt1[1] + pt2[1] );
1350 center[2] = 0.5 * ( pt1[2] + pt2[2] );
1351
1352 // Compute the scale factor
1353 double sf =
1354 vtkMath::Norm(v) / sqrt(vtkMath::Distance2BetweenPoints(pt1,pt2));
1355 if ( Y > this->Interactor->GetLastEventPosition()[1] )
1356 {
1357 sf = 1.0 + sf;
1358 }
1359 else
1360 {
1361 sf = 1.0 - sf;
1362 }
1363
1364 // Move the corner points
1365 double origin[3], point1[3], point2[3];
1366 for (int i=0; i<3; i++)
1367 {
1368 origin[i] = sf * (o[i] - center[i]) + center[i];
1369 point1[i] = sf * (pt1[i] - center[i]) + center[i];
1370 point2[i] = sf * (pt2[i] - center[i]) + center[i];
1371 }
1372
1373 this->PlaneSource->SetOrigin(origin);
1374 this->PlaneSource->SetPoint1(point1);
1375 this->PlaneSource->SetPoint2(point2);
1376 this->PlaneSource->Update();
1377
1378 this->PositionHandles();
1379 }
1380
Push(double * p1,double * p2)1381 void vtkPlaneWidget::Push(double *p1, double *p2)
1382 {
1383 //Get the motion vector
1384 double v[3];
1385 v[0] = p2[0] - p1[0];
1386 v[1] = p2[1] - p1[1];
1387 v[2] = p2[2] - p1[2];
1388
1389 this->PlaneSource->Push( vtkMath::Dot(v,this->Normal) );
1390 this->PlaneSource->Update();
1391 this->PositionHandles();
1392 }
1393
CreateDefaultProperties()1394 void vtkPlaneWidget::CreateDefaultProperties()
1395 {
1396 // Handle properties
1397 this->HandleProperty = vtkProperty::New();
1398 this->HandleProperty->SetColor(1,1,1);
1399
1400 this->SelectedHandleProperty = vtkProperty::New();
1401 this->SelectedHandleProperty->SetColor(1,0,0);
1402
1403 // Plane properties
1404 this->PlaneProperty = vtkProperty::New();
1405 this->PlaneProperty->SetAmbient(1.0);
1406 this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
1407
1408 this->SelectedPlaneProperty = vtkProperty::New();
1409 this->SelectRepresentation();
1410 this->SelectedPlaneProperty->SetAmbient(1.0);
1411 this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
1412 }
1413
PlaceWidget(double bds[6])1414 void vtkPlaneWidget::PlaceWidget(double bds[6])
1415 {
1416 int i;
1417 double bounds[6], center[3];
1418
1419 this->AdjustBounds(bds, bounds, center);
1420
1421 if (this->GetInput() || this->Prop3D)
1422 {
1423 if ( this->NormalToYAxis )
1424 {
1425 this->PlaneSource->SetOrigin(bounds[0],center[1],bounds[4]);
1426 this->PlaneSource->SetPoint1(bounds[1],center[1],bounds[4]);
1427 this->PlaneSource->SetPoint2(bounds[0],center[1],bounds[5]);
1428 }
1429 else if ( this->NormalToZAxis )
1430 {
1431 this->PlaneSource->SetOrigin(bounds[0],bounds[2],center[2]);
1432 this->PlaneSource->SetPoint1(bounds[1],bounds[2],center[2]);
1433 this->PlaneSource->SetPoint2(bounds[0],bounds[3],center[2]);
1434 }
1435 else //default or x-normal
1436 {
1437 this->PlaneSource->SetOrigin(center[0],bounds[2],bounds[4]);
1438 this->PlaneSource->SetPoint1(center[0],bounds[3],bounds[4]);
1439 this->PlaneSource->SetPoint2(center[0],bounds[2],bounds[5]);
1440 }
1441 }
1442
1443 this->PlaneSource->Update();
1444
1445 // Position the handles at the end of the planes
1446 this->PositionHandles();
1447
1448 for (i=0; i<6; i++)
1449 {
1450 this->InitialBounds[i] = bounds[i];
1451 }
1452
1453
1454 if (this->GetInput() || this->Prop3D)
1455 {
1456 this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1457 (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1458 (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1459 }
1460 else
1461 {
1462 // this means we have to make use of the PolyDataSource, so
1463 // we just calculate the magnitude of the longest diagonal on
1464 // the plane and use that as InitialLength
1465 double origin[3], point1[3], point2[3];
1466 this->PlaneSource->GetOrigin(origin);
1467 this->PlaneSource->GetPoint1(point1);
1468 this->PlaneSource->GetPoint2(point2);
1469 double sqr1 = 0, sqr2 = 0;
1470 for (i = 0; i < 3; i++)
1471 {
1472 sqr1 += (point1[i] - origin[i]) * (point1[i] - origin[i]);
1473 sqr2 += (point2[i] - origin[i]) * (point2[i] - origin[i]);
1474 }
1475
1476 this->InitialLength = sqrt(sqr1 + sqr2);
1477 }
1478
1479 // Set the radius on the sphere handles
1480 this->SizeHandles();
1481 }
1482
SizeHandles()1483 void vtkPlaneWidget::SizeHandles()
1484 {
1485 double radius = this->vtk3DWidget::SizeHandles(this->HandleSizeFactor);
1486
1487 if (this->ValidPick && !this->LastPickValid)
1488 {
1489 // Adjust factor to preserve old radius.
1490 double oldradius = this->HandleGeometry[0]->GetRadius();
1491 if (oldradius != 0 && radius != 0)
1492 {
1493 this->HandleSizeFactor = oldradius / radius;
1494 radius = oldradius;
1495 }
1496 }
1497
1498 this->LastPickValid = this->ValidPick;
1499
1500 for(int i=0; i<4; i++)
1501 {
1502 this->HandleGeometry[i]->SetRadius(radius);
1503 }
1504
1505 // Set the height and radius of the cone
1506 this->ConeSource->SetHeight(2.0*radius);
1507 this->ConeSource->SetRadius(radius);
1508 this->ConeSource2->SetHeight(2.0*radius);
1509 this->ConeSource2->SetRadius(radius);
1510
1511 }
1512
1513
SelectRepresentation()1514 void vtkPlaneWidget::SelectRepresentation()
1515 {
1516 if ( ! this->CurrentRenderer )
1517 {
1518 return;
1519 }
1520
1521 if ( this->Representation == VTK_PLANE_OFF )
1522 {
1523 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1524 }
1525 else if ( this->Representation == VTK_PLANE_OUTLINE )
1526 {
1527 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1528 this->CurrentRenderer->AddActor(this->PlaneActor);
1529 this->PlaneMapper->SetInputData( this->PlaneOutline );
1530 this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1531 }
1532 else if ( this->Representation == VTK_PLANE_SURFACE )
1533 {
1534 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1535 this->CurrentRenderer->AddActor(this->PlaneActor);
1536 this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1537 this->PlaneActor->GetProperty()->SetRepresentationToSurface();
1538 }
1539 else //( this->Representation == VTK_PLANE_WIREFRAME )
1540 {
1541 this->CurrentRenderer->RemoveActor(this->PlaneActor);
1542 this->CurrentRenderer->AddActor(this->PlaneActor);
1543 this->PlaneMapper->SetInputConnection( this->PlaneSource->GetOutputPort() );
1544 this->PlaneActor->GetProperty()->SetRepresentationToWireframe();
1545 }
1546 }
1547
1548 // Description:
1549 // Set/Get the resolution (number of subdivisions) of the plane.
SetResolution(int r)1550 void vtkPlaneWidget::SetResolution(int r)
1551 {
1552 this->PlaneSource->SetXResolution(r);
1553 this->PlaneSource->SetYResolution(r);
1554 }
1555
GetResolution()1556 int vtkPlaneWidget::GetResolution()
1557 {
1558 return this->PlaneSource->GetXResolution();
1559 }
1560
1561 // Description:
1562 // Set/Get the origin of the plane.
SetOrigin(double x,double y,double z)1563 void vtkPlaneWidget::SetOrigin(double x, double y, double z)
1564 {
1565 this->PlaneSource->SetOrigin(x,y,z);
1566 this->PositionHandles();
1567 }
1568
SetOrigin(double x[3])1569 void vtkPlaneWidget::SetOrigin(double x[3])
1570 {
1571 this->SetOrigin(x[0], x[1], x[2]);
1572 }
1573
GetOrigin()1574 double* vtkPlaneWidget::GetOrigin()
1575 {
1576 return this->PlaneSource->GetOrigin();
1577 }
1578
GetOrigin(double xyz[3])1579 void vtkPlaneWidget::GetOrigin(double xyz[3])
1580 {
1581 this->PlaneSource->GetOrigin(xyz);
1582 }
1583
1584 // Description:
1585 // Set/Get the position of the point defining the first axis of the plane.
SetPoint1(double x,double y,double z)1586 void vtkPlaneWidget::SetPoint1(double x, double y, double z)
1587 {
1588 this->PlaneSource->SetPoint1(x,y,z);
1589 this->PositionHandles();
1590 }
1591
SetPoint1(double x[3])1592 void vtkPlaneWidget::SetPoint1(double x[3])
1593 {
1594 this->SetPoint1(x[0], x[1], x[2]);
1595 }
1596
GetPoint1()1597 double* vtkPlaneWidget::GetPoint1()
1598 {
1599 return this->PlaneSource->GetPoint1();
1600 }
1601
GetPoint1(double xyz[3])1602 void vtkPlaneWidget::GetPoint1(double xyz[3])
1603 {
1604 this->PlaneSource->GetPoint1(xyz);
1605 }
1606
1607 // Description:
1608 // Set/Get the position of the point defining the second axis of the plane.
SetPoint2(double x,double y,double z)1609 void vtkPlaneWidget::SetPoint2(double x, double y, double z)
1610 {
1611 this->PlaneSource->SetPoint2(x,y,z);
1612 this->PositionHandles();
1613 }
1614
SetPoint2(double x[3])1615 void vtkPlaneWidget::SetPoint2(double x[3])
1616 {
1617 this->SetPoint2(x[0], x[1], x[2]);
1618 }
1619
GetPoint2()1620 double* vtkPlaneWidget::GetPoint2()
1621 {
1622 return this->PlaneSource->GetPoint2();
1623 }
1624
GetPoint2(double xyz[3])1625 void vtkPlaneWidget::GetPoint2(double xyz[3])
1626 {
1627 this->PlaneSource->GetPoint2(xyz);
1628 }
1629
1630 // Description:
1631 // Set the center of the plane.
SetCenter(double x,double y,double z)1632 void vtkPlaneWidget::SetCenter(double x, double y, double z)
1633 {
1634 this->PlaneSource->SetCenter(x, y, z);
1635 this->PositionHandles();
1636 }
1637
1638 // Description:
1639 // Set the center of the plane.
SetCenter(double c[3])1640 void vtkPlaneWidget::SetCenter(double c[3])
1641 {
1642 this->SetCenter(c[0], c[1], c[2]);
1643 }
1644
1645 // Description:
1646 // Get the center of the plane.
GetCenter()1647 double* vtkPlaneWidget::GetCenter()
1648 {
1649 return this->PlaneSource->GetCenter();
1650 }
1651
GetCenter(double xyz[3])1652 void vtkPlaneWidget::GetCenter(double xyz[3])
1653 {
1654 this->PlaneSource->GetCenter(xyz);
1655 }
1656
1657 // Description:
1658 // Set the normal to the plane.
SetNormal(double x,double y,double z)1659 void vtkPlaneWidget::SetNormal(double x, double y, double z)
1660 {
1661 this->PlaneSource->SetNormal(x, y, z);
1662 this->PositionHandles();
1663 }
1664
1665 // Description:
1666 // Set the normal to the plane.
SetNormal(double n[3])1667 void vtkPlaneWidget::SetNormal(double n[3])
1668 {
1669 this->SetNormal(n[0], n[1], n[2]);
1670 }
1671
1672 // Description:
1673 // Get the normal to the plane.
GetNormal()1674 double* vtkPlaneWidget::GetNormal()
1675 {
1676 return this->PlaneSource->GetNormal();
1677 }
1678
GetNormal(double xyz[3])1679 void vtkPlaneWidget::GetNormal(double xyz[3])
1680 {
1681 this->PlaneSource->GetNormal(xyz);
1682 }
1683
GetPolyData(vtkPolyData * pd)1684 void vtkPlaneWidget::GetPolyData(vtkPolyData *pd)
1685 {
1686 pd->ShallowCopy(this->PlaneSource->GetOutput());
1687 }
1688
GetPolyDataAlgorithm()1689 vtkPolyDataAlgorithm *vtkPlaneWidget::GetPolyDataAlgorithm()
1690 {
1691 return this->PlaneSource;
1692 }
1693
GetPlane(vtkPlane * plane)1694 void vtkPlaneWidget::GetPlane(vtkPlane *plane)
1695 {
1696 if ( plane == nullptr )
1697 {
1698 return;
1699 }
1700
1701 plane->SetNormal(this->GetNormal());
1702 plane->SetOrigin(this->GetCenter());
1703 }
1704
UpdatePlacement(void)1705 void vtkPlaneWidget::UpdatePlacement(void)
1706 {
1707 this->PlaneSource->Update();
1708 this->PositionHandles();
1709 }
1710