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