1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkBoxWidget.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 "vtkBoxWidget.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 "vtkDoubleArray.h"
25 #include "vtkFloatArray.h"
26 #include "vtkMath.h"
27 #include "vtkObjectFactory.h"
28 #include "vtkPickingManager.h"
29 #include "vtkPlanes.h"
30 #include "vtkPolyData.h"
31 #include "vtkPolyDataMapper.h"
32 #include "vtkProperty.h"
33 #include "vtkRenderWindowInteractor.h"
34 #include "vtkRenderer.h"
35 #include "vtkSphereSource.h"
36 #include "vtkTransform.h"
37
38 vtkStandardNewMacro(vtkBoxWidget);
39
vtkBoxWidget()40 vtkBoxWidget::vtkBoxWidget()
41 {
42 this->State = vtkBoxWidget::Start;
43 this->EventCallbackCommand->SetCallback(vtkBoxWidget::ProcessEvents);
44
45 // Enable/disable the translation, rotation, and scaling of the widget
46 this->TranslationEnabled = 1;
47 this->RotationEnabled = 1;
48 this->ScalingEnabled = 1;
49
50 // Build the representation of the widget
51 int i;
52
53 // Control orientation of normals
54 this->InsideOut = 0;
55 this->OutlineFaceWires = 0;
56 this->OutlineCursorWires = 1;
57
58 // Construct the poly data representing the hex
59 this->HexPolyData = vtkPolyData::New();
60 this->HexMapper = vtkPolyDataMapper::New();
61 this->HexMapper->SetInputData(HexPolyData);
62 this->HexActor = vtkActor::New();
63 this->HexActor->SetMapper(this->HexMapper);
64
65 // Construct initial points
66 this->Points = vtkPoints::New(VTK_DOUBLE);
67 this->Points->SetNumberOfPoints(15); // 8 corners; 6 faces; 1 center
68 this->HexPolyData->SetPoints(this->Points);
69
70 // Construct connectivity for the faces. These are used to perform
71 // the picking.
72 vtkIdType pts[4];
73 vtkCellArray* cells = vtkCellArray::New();
74 cells->AllocateEstimate(6, 4);
75 pts[0] = 3;
76 pts[1] = 0;
77 pts[2] = 4;
78 pts[3] = 7;
79 cells->InsertNextCell(4, pts);
80 pts[0] = 1;
81 pts[1] = 2;
82 pts[2] = 6;
83 pts[3] = 5;
84 cells->InsertNextCell(4, pts);
85 pts[0] = 0;
86 pts[1] = 1;
87 pts[2] = 5;
88 pts[3] = 4;
89 cells->InsertNextCell(4, pts);
90 pts[0] = 2;
91 pts[1] = 3;
92 pts[2] = 7;
93 pts[3] = 6;
94 cells->InsertNextCell(4, pts);
95 pts[0] = 0;
96 pts[1] = 3;
97 pts[2] = 2;
98 pts[3] = 1;
99 cells->InsertNextCell(4, pts);
100 pts[0] = 4;
101 pts[1] = 5;
102 pts[2] = 6;
103 pts[3] = 7;
104 cells->InsertNextCell(4, pts);
105 this->HexPolyData->SetPolys(cells);
106 cells->Delete();
107 this->HexPolyData->BuildCells();
108
109 // The face of the hexahedra
110 cells = vtkCellArray::New();
111 cells->AllocateEstimate(1, 4);
112 cells->InsertNextCell(4, pts); // temporary, replaced later
113 this->HexFacePolyData = vtkPolyData::New();
114 this->HexFacePolyData->SetPoints(this->Points);
115 this->HexFacePolyData->SetPolys(cells);
116 this->HexFaceMapper = vtkPolyDataMapper::New();
117 this->HexFaceMapper->SetInputData(HexFacePolyData);
118 this->HexFace = vtkActor::New();
119 this->HexFace->SetMapper(this->HexFaceMapper);
120 cells->Delete();
121
122 // Create the outline for the hex
123 this->OutlinePolyData = vtkPolyData::New();
124 this->OutlinePolyData->SetPoints(this->Points);
125 this->OutlineMapper = vtkPolyDataMapper::New();
126 this->OutlineMapper->SetInputData(this->OutlinePolyData);
127 this->HexOutline = vtkActor::New();
128 this->HexOutline->SetMapper(this->OutlineMapper);
129 cells = vtkCellArray::New();
130 cells->AllocateEstimate(15, 2);
131 this->OutlinePolyData->SetLines(cells);
132 cells->Delete();
133
134 // Set up the initial properties
135 this->CreateDefaultProperties();
136
137 // Create the outline
138 this->GenerateOutline();
139
140 // Create the handles
141 this->Handle = new vtkActor*[7];
142 this->HandleMapper = new vtkPolyDataMapper*[7];
143 this->HandleGeometry = new vtkSphereSource*[7];
144 for (i = 0; i < 7; i++)
145 {
146 this->HandleGeometry[i] = vtkSphereSource::New();
147 this->HandleGeometry[i]->SetThetaResolution(16);
148 this->HandleGeometry[i]->SetPhiResolution(8);
149 this->HandleMapper[i] = vtkPolyDataMapper::New();
150 this->HandleMapper[i]->SetInputConnection(this->HandleGeometry[i]->GetOutputPort());
151 this->Handle[i] = vtkActor::New();
152 this->Handle[i]->SetMapper(this->HandleMapper[i]);
153 }
154
155 // Define the point coordinates
156 double bounds[6];
157 bounds[0] = -0.5;
158 bounds[1] = 0.5;
159 bounds[2] = -0.5;
160 bounds[3] = 0.5;
161 bounds[4] = -0.5;
162 bounds[5] = 0.5;
163 // Points 8-14 are down by PositionHandles();
164 this->PlaceWidget(bounds);
165
166 // Manage the picking stuff
167 this->HandlePicker = vtkCellPicker::New();
168 this->HandlePicker->SetTolerance(0.001);
169 for (i = 0; i < 7; i++)
170 {
171 this->HandlePicker->AddPickList(this->Handle[i]);
172 }
173 this->HandlePicker->PickFromListOn();
174
175 this->HexPicker = vtkCellPicker::New();
176 this->HexPicker->SetTolerance(0.001);
177 this->HexPicker->AddPickList(HexActor);
178 this->HexPicker->PickFromListOn();
179
180 this->CurrentHandle = nullptr;
181
182 this->Transform = vtkTransform::New();
183 }
184
~vtkBoxWidget()185 vtkBoxWidget::~vtkBoxWidget()
186 {
187 this->HexActor->Delete();
188 this->HexMapper->Delete();
189 this->HexPolyData->Delete();
190 this->Points->Delete();
191
192 this->HexFace->Delete();
193 this->HexFaceMapper->Delete();
194 this->HexFacePolyData->Delete();
195
196 this->HexOutline->Delete();
197 this->OutlineMapper->Delete();
198 this->OutlinePolyData->Delete();
199
200 for (int i = 0; i < 7; i++)
201 {
202 this->HandleGeometry[i]->Delete();
203 this->HandleMapper[i]->Delete();
204 this->Handle[i]->Delete();
205 }
206 delete[] this->Handle;
207 delete[] this->HandleMapper;
208 delete[] this->HandleGeometry;
209
210 this->HandlePicker->Delete();
211 this->HexPicker->Delete();
212
213 this->Transform->Delete();
214
215 this->HandleProperty->Delete();
216 this->SelectedHandleProperty->Delete();
217 this->FaceProperty->Delete();
218 this->SelectedFaceProperty->Delete();
219 this->OutlineProperty->Delete();
220 this->SelectedOutlineProperty->Delete();
221 }
222
SetEnabled(int enabling)223 void vtkBoxWidget::SetEnabled(int enabling)
224 {
225 if (!this->Interactor)
226 {
227 vtkErrorMacro(<< "The interactor must be set prior to enabling/disabling widget");
228 return;
229 }
230
231 if (enabling) //------------------------------------------------------------
232 {
233 vtkDebugMacro(<< "Enabling widget");
234
235 if (this->Enabled) // already enabled, just return
236 {
237 return;
238 }
239
240 if (!this->CurrentRenderer)
241 {
242 this->SetCurrentRenderer(this->Interactor->FindPokedRenderer(
243 this->Interactor->GetLastEventPosition()[0], this->Interactor->GetLastEventPosition()[1]));
244 if (this->CurrentRenderer == nullptr)
245 {
246 return;
247 }
248 }
249
250 this->Enabled = 1;
251
252 // listen to the following events
253 vtkRenderWindowInteractor* i = this->Interactor;
254 i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand, this->Priority);
255 i->AddObserver(vtkCommand::LeftButtonPressEvent, this->EventCallbackCommand, this->Priority);
256 i->AddObserver(vtkCommand::LeftButtonReleaseEvent, this->EventCallbackCommand, this->Priority);
257 i->AddObserver(vtkCommand::MiddleButtonPressEvent, this->EventCallbackCommand, this->Priority);
258 i->AddObserver(
259 vtkCommand::MiddleButtonReleaseEvent, this->EventCallbackCommand, this->Priority);
260 i->AddObserver(vtkCommand::RightButtonPressEvent, this->EventCallbackCommand, this->Priority);
261 i->AddObserver(vtkCommand::RightButtonReleaseEvent, this->EventCallbackCommand, this->Priority);
262
263 // Add the various actors
264 // Add the outline
265 this->CurrentRenderer->AddActor(this->HexActor);
266 this->CurrentRenderer->AddActor(this->HexOutline);
267 this->HexActor->SetProperty(this->OutlineProperty);
268 this->HexOutline->SetProperty(this->OutlineProperty);
269
270 // Add the hex face
271 this->CurrentRenderer->AddActor(this->HexFace);
272 this->HexFace->SetProperty(this->FaceProperty);
273
274 // turn on the handles
275 for (int j = 0; j < 7; j++)
276 {
277 this->CurrentRenderer->AddActor(this->Handle[j]);
278 this->Handle[j]->SetProperty(this->HandleProperty);
279 }
280 this->RegisterPickers();
281
282 this->InvokeEvent(vtkCommand::EnableEvent, nullptr);
283 }
284
285 else // disabling-------------------------------------------------------------
286 {
287 vtkDebugMacro(<< "Disabling widget");
288
289 if (!this->Enabled) // already disabled, just return
290 {
291 return;
292 }
293
294 this->Enabled = 0;
295
296 // don't listen for events any more
297 this->Interactor->RemoveObserver(this->EventCallbackCommand);
298
299 // turn off the outline
300 this->CurrentRenderer->RemoveActor(this->HexActor);
301 this->CurrentRenderer->RemoveActor(this->HexOutline);
302
303 // turn off the hex face
304 this->CurrentRenderer->RemoveActor(this->HexFace);
305
306 // turn off the handles
307 for (int i = 0; i < 7; i++)
308 {
309 this->CurrentRenderer->RemoveActor(this->Handle[i]);
310 }
311
312 this->CurrentHandle = nullptr;
313 this->InvokeEvent(vtkCommand::DisableEvent, nullptr);
314 this->SetCurrentRenderer(nullptr);
315 this->UnRegisterPickers();
316 }
317
318 this->Interactor->Render();
319 }
320
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))321 void vtkBoxWidget::ProcessEvents(
322 vtkObject* vtkNotUsed(object), unsigned long event, void* clientdata, void* vtkNotUsed(calldata))
323 {
324 vtkBoxWidget* self = reinterpret_cast<vtkBoxWidget*>(clientdata);
325
326 // okay, let's do the right thing
327 switch (event)
328 {
329 case vtkCommand::LeftButtonPressEvent:
330 self->OnLeftButtonDown();
331 break;
332 case vtkCommand::LeftButtonReleaseEvent:
333 self->OnLeftButtonUp();
334 break;
335 case vtkCommand::MiddleButtonPressEvent:
336 self->OnMiddleButtonDown();
337 break;
338 case vtkCommand::MiddleButtonReleaseEvent:
339 self->OnMiddleButtonUp();
340 break;
341 case vtkCommand::RightButtonPressEvent:
342 self->OnRightButtonDown();
343 break;
344 case vtkCommand::RightButtonReleaseEvent:
345 self->OnRightButtonUp();
346 break;
347 case vtkCommand::MouseMoveEvent:
348 self->OnMouseMove();
349 break;
350 }
351 }
352
PrintSelf(ostream & os,vtkIndent indent)353 void vtkBoxWidget::PrintSelf(ostream& os, vtkIndent indent)
354 {
355 this->Superclass::PrintSelf(os, indent);
356
357 double* bounds = this->InitialBounds;
358 os << indent << "Initial Bounds: "
359 << "(" << bounds[0] << "," << bounds[1] << ") "
360 << "(" << bounds[2] << "," << bounds[3] << ") "
361 << "(" << bounds[4] << "," << bounds[5] << ")\n";
362
363 if (this->HandleProperty)
364 {
365 os << indent << "Handle Property: " << this->HandleProperty << "\n";
366 }
367 else
368 {
369 os << indent << "Handle Property: (none)\n";
370 }
371 if (this->SelectedHandleProperty)
372 {
373 os << indent << "Selected Handle Property: " << this->SelectedHandleProperty << "\n";
374 }
375 else
376 {
377 os << indent << "SelectedHandle Property: (none)\n";
378 }
379
380 if (this->FaceProperty)
381 {
382 os << indent << "Face Property: " << this->FaceProperty << "\n";
383 }
384 else
385 {
386 os << indent << "Face Property: (none)\n";
387 }
388 if (this->SelectedFaceProperty)
389 {
390 os << indent << "Selected Face Property: " << this->SelectedFaceProperty << "\n";
391 }
392 else
393 {
394 os << indent << "Selected Face Property: (none)\n";
395 }
396
397 if (this->OutlineProperty)
398 {
399 os << indent << "Outline Property: " << this->OutlineProperty << "\n";
400 }
401 else
402 {
403 os << indent << "Outline Property: (none)\n";
404 }
405 if (this->SelectedOutlineProperty)
406 {
407 os << indent << "Selected Outline Property: " << this->SelectedOutlineProperty << "\n";
408 }
409 else
410 {
411 os << indent << "Selected Outline Property: (none)\n";
412 }
413
414 os << indent << "Outline Face Wires: " << (this->OutlineFaceWires ? "On\n" : "Off\n");
415 os << indent << "Outline Cursor Wires: " << (this->OutlineCursorWires ? "On\n" : "Off\n");
416 os << indent << "Inside Out: " << (this->InsideOut ? "On\n" : "Off\n");
417 os << indent << "Translation Enabled: " << (this->TranslationEnabled ? "On\n" : "Off\n");
418 os << indent << "Scaling Enabled: " << (this->ScalingEnabled ? "On\n" : "Off\n");
419 os << indent << "Rotation Enabled: " << (this->RotationEnabled ? "On\n" : "Off\n");
420 }
421
422 #define VTK_AVERAGE(a, b, c) \
423 c[0] = (a[0] + b[0]) / 2.0; \
424 c[1] = (a[1] + b[1]) / 2.0; \
425 c[2] = (a[2] + b[2]) / 2.0;
426
PositionHandles()427 void vtkBoxWidget::PositionHandles()
428 {
429 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
430 double* p0 = pts;
431 double* p1 = pts + 3 * 1;
432 double* p2 = pts + 3 * 2;
433 double* p3 = pts + 3 * 3;
434 // double *p4 = pts + 3*4;
435 double* p5 = pts + 3 * 5;
436 double* p6 = pts + 3 * 6;
437 double* p7 = pts + 3 * 7;
438 double x[3];
439
440 VTK_AVERAGE(p0, p7, x);
441 this->Points->SetPoint(8, x);
442 VTK_AVERAGE(p1, p6, x);
443 this->Points->SetPoint(9, x);
444 VTK_AVERAGE(p0, p5, x);
445 this->Points->SetPoint(10, x);
446 VTK_AVERAGE(p2, p7, x);
447 this->Points->SetPoint(11, x);
448 VTK_AVERAGE(p1, p3, x);
449 this->Points->SetPoint(12, x);
450 VTK_AVERAGE(p5, p7, x);
451 this->Points->SetPoint(13, x);
452 VTK_AVERAGE(p0, p6, x);
453 this->Points->SetPoint(14, x);
454
455 int i;
456 for (i = 0; i < 7; ++i)
457 {
458 this->HandleGeometry[i]->SetCenter(this->Points->GetPoint(8 + i));
459 }
460
461 this->Points->GetData()->Modified();
462 this->HexFacePolyData->Modified();
463 this->HexPolyData->Modified();
464 this->GenerateOutline();
465 }
466 #undef VTK_AVERAGE
467
HandlesOn()468 void vtkBoxWidget::HandlesOn()
469 {
470 for (int i = 0; i < 7; i++)
471 {
472 this->Handle[i]->VisibilityOn();
473 }
474 }
475
HandlesOff()476 void vtkBoxWidget::HandlesOff()
477 {
478 for (int i = 0; i < 7; i++)
479 {
480 this->Handle[i]->VisibilityOff();
481 }
482 }
483
SizeHandles()484 void vtkBoxWidget::SizeHandles()
485 {
486 double radius = this->vtk3DWidget::SizeHandles(1.5);
487 for (int i = 0; i < 7; i++)
488 {
489 this->HandleGeometry[i]->SetRadius(radius);
490 }
491 }
492
HighlightHandle(vtkProp * prop)493 int vtkBoxWidget::HighlightHandle(vtkProp* prop)
494 {
495 // first unhighlight anything picked
496 this->HighlightOutline(0);
497 if (this->CurrentHandle)
498 {
499 this->CurrentHandle->SetProperty(this->HandleProperty);
500 }
501
502 this->CurrentHandle = static_cast<vtkActor*>(prop);
503
504 if (this->CurrentHandle)
505 {
506 this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
507 for (int i = 0; i < 6; i++) // find attached face
508 {
509 if (this->CurrentHandle == this->Handle[i])
510 {
511 return i;
512 }
513 }
514 }
515
516 if (this->CurrentHandle == this->Handle[6])
517 {
518 this->HighlightOutline(1);
519 }
520
521 return -1;
522 }
523
HighlightFace(int cellId)524 void vtkBoxWidget::HighlightFace(int cellId)
525 {
526 if (cellId >= 0)
527 {
528 vtkIdType npts;
529 const vtkIdType* pts;
530 vtkCellArray* cells = this->HexFacePolyData->GetPolys();
531 this->HexPolyData->GetCellPoints(cellId, npts, pts);
532 cells->ReplaceCellAtId(0, npts, pts);
533 cells->Modified();
534 this->CurrentHexFace = cellId;
535 this->HexFace->SetProperty(this->SelectedFaceProperty);
536 if (!this->CurrentHandle)
537 {
538 this->CurrentHandle = this->HexFace;
539 }
540 }
541 else
542 {
543 this->HexFace->SetProperty(this->FaceProperty);
544 this->CurrentHexFace = -1;
545 }
546 }
547
HighlightOutline(int highlight)548 void vtkBoxWidget::HighlightOutline(int highlight)
549 {
550 if (highlight)
551 {
552 this->HexActor->SetProperty(this->SelectedOutlineProperty);
553 this->HexOutline->SetProperty(this->SelectedOutlineProperty);
554 }
555 else
556 {
557 this->HexActor->SetProperty(this->OutlineProperty);
558 this->HexOutline->SetProperty(this->OutlineProperty);
559 }
560 }
561
OnLeftButtonDown()562 void vtkBoxWidget::OnLeftButtonDown()
563 {
564 int X = this->Interactor->GetEventPosition()[0];
565 int Y = this->Interactor->GetEventPosition()[1];
566
567 // Okay, we can process this. Try to pick handles first;
568 // if no handles picked, then pick the bounding box.
569 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
570 {
571 this->State = vtkBoxWidget::Outside;
572 return;
573 }
574
575 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
576
577 if (path != nullptr)
578 {
579 this->State = vtkBoxWidget::Moving;
580 this->HighlightFace(this->HighlightHandle(path->GetFirstNode()->GetViewProp()));
581 this->HandlePicker->GetPickPosition(this->LastPickPosition);
582 this->ValidPick = 1;
583 }
584 else
585 {
586 path = this->GetAssemblyPath(X, Y, 0., this->HexPicker);
587
588 if (path != nullptr)
589 {
590 this->State = vtkBoxWidget::Moving;
591 this->HexPicker->GetPickPosition(this->LastPickPosition);
592 this->ValidPick = 1;
593 if (!this->Interactor->GetShiftKey())
594 {
595 this->HighlightHandle(nullptr);
596 this->HighlightFace(this->HexPicker->GetCellId());
597 }
598 else
599 {
600 this->CurrentHandle = this->Handle[6];
601 this->HighlightOutline(1);
602 }
603 }
604 else
605 {
606 this->HighlightFace(this->HighlightHandle(nullptr));
607 this->State = vtkBoxWidget::Outside;
608 return;
609 }
610 }
611
612 this->EventCallbackCommand->SetAbortFlag(1);
613 this->StartInteraction();
614 this->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr);
615 this->Interactor->Render();
616 }
617
OnLeftButtonUp()618 void vtkBoxWidget::OnLeftButtonUp()
619 {
620 if (this->State == vtkBoxWidget::Outside || this->State == vtkBoxWidget::Start)
621 {
622 return;
623 }
624
625 this->State = vtkBoxWidget::Start;
626 this->HighlightFace(this->HighlightHandle(nullptr));
627 this->SizeHandles();
628
629 this->EventCallbackCommand->SetAbortFlag(1);
630 this->EndInteraction();
631 this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
632 this->Interactor->Render();
633 }
634
OnMiddleButtonDown()635 void vtkBoxWidget::OnMiddleButtonDown()
636 {
637 int X = this->Interactor->GetEventPosition()[0];
638 int Y = this->Interactor->GetEventPosition()[1];
639
640 // Okay, we can process this. Try to pick handles first;
641 // if no handles picked, then pick the bounding box.
642 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
643 {
644 this->State = vtkBoxWidget::Outside;
645 return;
646 }
647
648 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
649
650 if (path != nullptr)
651 {
652 this->State = vtkBoxWidget::Moving;
653 this->CurrentHandle = this->Handle[6];
654 this->HighlightOutline(1);
655 this->HandlePicker->GetPickPosition(this->LastPickPosition);
656 this->ValidPick = 1;
657 }
658 else
659 {
660 path = this->GetAssemblyPath(X, Y, 0., this->HexPicker);
661
662 if (path != nullptr)
663 {
664 this->State = vtkBoxWidget::Moving;
665 this->CurrentHandle = this->Handle[6];
666 this->HighlightOutline(1);
667 this->HexPicker->GetPickPosition(this->LastPickPosition);
668 this->ValidPick = 1;
669 }
670 else
671 {
672 this->HighlightFace(this->HighlightHandle(nullptr));
673 this->State = vtkBoxWidget::Outside;
674 return;
675 }
676 }
677
678 this->EventCallbackCommand->SetAbortFlag(1);
679 this->StartInteraction();
680 this->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr);
681 this->Interactor->Render();
682 }
683
OnMiddleButtonUp()684 void vtkBoxWidget::OnMiddleButtonUp()
685 {
686 if (this->State == vtkBoxWidget::Outside || this->State == vtkBoxWidget::Start)
687 {
688 return;
689 }
690
691 this->State = vtkBoxWidget::Start;
692 this->HighlightFace(this->HighlightHandle(nullptr));
693 this->SizeHandles();
694
695 this->EventCallbackCommand->SetAbortFlag(1);
696 this->EndInteraction();
697 this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
698 this->Interactor->Render();
699 }
700
OnRightButtonDown()701 void vtkBoxWidget::OnRightButtonDown()
702 {
703 int X = this->Interactor->GetEventPosition()[0];
704 int Y = this->Interactor->GetEventPosition()[1];
705
706 // Okay, we can process this. Try to pick handles first;
707 // if no handles picked, then pick the bounding box.
708 if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
709 {
710 this->State = vtkBoxWidget::Outside;
711 return;
712 }
713
714 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker);
715
716 if (path != nullptr)
717 {
718 this->State = vtkBoxWidget::Scaling;
719 this->HighlightOutline(1);
720 this->HandlePicker->GetPickPosition(this->LastPickPosition);
721 this->ValidPick = 1;
722 }
723 else
724 {
725 path = this->GetAssemblyPath(X, Y, 0., this->HexPicker);
726
727 if (path != nullptr)
728 {
729 this->State = vtkBoxWidget::Scaling;
730 this->HighlightOutline(1);
731 this->HexPicker->GetPickPosition(this->LastPickPosition);
732 this->ValidPick = 1;
733 }
734 else
735 {
736 this->State = vtkBoxWidget::Outside;
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
OnRightButtonUp()747 void vtkBoxWidget::OnRightButtonUp()
748 {
749 if (this->State == vtkBoxWidget::Outside)
750 {
751 return;
752 }
753
754 this->State = vtkBoxWidget::Start;
755 this->HighlightOutline(0);
756 this->SizeHandles();
757
758 this->EventCallbackCommand->SetAbortFlag(1);
759 this->EndInteraction();
760 this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
761 this->Interactor->Render();
762 }
763
OnMouseMove()764 void vtkBoxWidget::OnMouseMove()
765 {
766 // See whether we're active
767 if (this->State == vtkBoxWidget::Outside || this->State == vtkBoxWidget::Start)
768 {
769 return;
770 }
771
772 int X = this->Interactor->GetEventPosition()[0];
773 int Y = this->Interactor->GetEventPosition()[1];
774
775 // Do different things depending on state
776 // Calculations everybody does
777 double focalPoint[4], pickPoint[4], prevPickPoint[4];
778 double z, vpn[3];
779
780 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
781 if (!camera)
782 {
783 return;
784 }
785
786 // Compute the two points defining the motion vector
787 this->ComputeWorldToDisplay(
788 this->LastPickPosition[0], this->LastPickPosition[1], this->LastPickPosition[2], focalPoint);
789 z = focalPoint[2];
790 this->ComputeDisplayToWorld(double(this->Interactor->GetLastEventPosition()[0]),
791 double(this->Interactor->GetLastEventPosition()[1]), z, prevPickPoint);
792 this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
793
794 // Process the motion
795 if (this->State == vtkBoxWidget::Moving)
796 {
797 // Okay to process
798 if (this->CurrentHandle)
799 {
800 if (this->RotationEnabled && this->CurrentHandle == this->HexFace)
801 {
802 camera->GetViewPlaneNormal(vpn);
803 this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
804 }
805 else if (this->TranslationEnabled && this->CurrentHandle == this->Handle[6])
806 {
807 this->Translate(prevPickPoint, pickPoint);
808 }
809 else if (this->TranslationEnabled && this->ScalingEnabled)
810 {
811 if (this->CurrentHandle == this->Handle[0])
812 {
813 this->MoveMinusXFace(prevPickPoint, pickPoint);
814 }
815 else if (this->CurrentHandle == this->Handle[1])
816 {
817 this->MovePlusXFace(prevPickPoint, pickPoint);
818 }
819 else if (this->CurrentHandle == this->Handle[2])
820 {
821 this->MoveMinusYFace(prevPickPoint, pickPoint);
822 }
823 else if (this->CurrentHandle == this->Handle[3])
824 {
825 this->MovePlusYFace(prevPickPoint, pickPoint);
826 }
827 else if (this->CurrentHandle == this->Handle[4])
828 {
829 this->MoveMinusZFace(prevPickPoint, pickPoint);
830 }
831 else if (this->CurrentHandle == this->Handle[5])
832 {
833 this->MovePlusZFace(prevPickPoint, pickPoint);
834 }
835 }
836 }
837 }
838 else if (this->ScalingEnabled && this->State == vtkBoxWidget::Scaling)
839 {
840 this->Scale(prevPickPoint, pickPoint, X, Y);
841 }
842
843 // Interact, if desired
844 this->EventCallbackCommand->SetAbortFlag(1);
845 this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
846 this->Interactor->Render();
847 }
848
MoveFace(double * p1,double * p2,double * dir,double * x1,double * x2,double * x3,double * x4,double * x5)849 void vtkBoxWidget::MoveFace(
850 double* p1, double* p2, double* dir, double* x1, double* x2, double* x3, double* x4, double* x5)
851 {
852 int i;
853 double v[3], v2[3];
854
855 for (i = 0; i < 3; i++)
856 {
857 v[i] = p2[i] - p1[i];
858 v2[i] = dir[i];
859 }
860
861 vtkMath::Normalize(v2);
862 double f = vtkMath::Dot(v, v2);
863
864 for (i = 0; i < 3; i++)
865 {
866 v[i] = f * v2[i];
867
868 x1[i] += v[i];
869 x2[i] += v[i];
870 x3[i] += v[i];
871 x4[i] += v[i];
872 x5[i] += v[i];
873 }
874 this->PositionHandles();
875 }
876
GetDirection(const double Nx[3],const double Ny[3],const double Nz[3],double dir[3])877 void vtkBoxWidget::GetDirection(
878 const double Nx[3], const double Ny[3], const double Nz[3], double dir[3])
879 {
880 double dotNy, dotNz;
881 double y[3];
882
883 if (vtkMath::Dot(Nx, Nx) != 0)
884 {
885 dir[0] = Nx[0];
886 dir[1] = Nx[1];
887 dir[2] = Nx[2];
888 }
889 else
890 {
891 dotNy = vtkMath::Dot(Ny, Ny);
892 dotNz = vtkMath::Dot(Nz, Nz);
893 if (dotNy != 0 && dotNz != 0)
894 {
895 vtkMath::Cross(Ny, Nz, dir);
896 }
897 else if (dotNy != 0)
898 {
899 // dir must have been initialized to the
900 // corresponding coordinate direction before calling
901 // this method
902 vtkMath::Cross(Ny, dir, y);
903 vtkMath::Cross(y, Ny, dir);
904 }
905 else if (dotNz != 0)
906 {
907 // dir must have been initialized to the
908 // corresponding coordinate direction before calling
909 // this method
910 vtkMath::Cross(Nz, dir, y);
911 vtkMath::Cross(y, Nz, dir);
912 }
913 }
914 }
MovePlusXFace(double * p1,double * p2)915 void vtkBoxWidget::MovePlusXFace(double* p1, double* p2)
916 {
917 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
918
919 double* h1 = pts + 3 * 9;
920
921 double* x1 = pts + 3 * 1;
922 double* x2 = pts + 3 * 2;
923 double* x3 = pts + 3 * 5;
924 double* x4 = pts + 3 * 6;
925
926 double dir[3] = { 1, 0, 0 };
927 this->ComputeNormals();
928 this->GetDirection(this->N[1], this->N[3], this->N[5], dir);
929 this->MoveFace(p1, p2, dir, x1, x2, x3, x4, h1);
930 }
931
MoveMinusXFace(double * p1,double * p2)932 void vtkBoxWidget::MoveMinusXFace(double* p1, double* p2)
933 {
934 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
935
936 double* h1 = pts + 3 * 8;
937
938 double* x1 = pts + 3 * 0;
939 double* x2 = pts + 3 * 3;
940 double* x3 = pts + 3 * 4;
941 double* x4 = pts + 3 * 7;
942
943 double dir[3] = { -1, 0, 0 };
944 this->ComputeNormals();
945 this->GetDirection(this->N[0], this->N[4], this->N[2], dir);
946
947 this->MoveFace(p1, p2, dir, x1, x2, x3, x4, h1);
948 }
949
MovePlusYFace(double * p1,double * p2)950 void vtkBoxWidget::MovePlusYFace(double* p1, double* p2)
951 {
952 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
953
954 double* h1 = pts + 3 * 11;
955
956 double* x1 = pts + 3 * 2;
957 double* x2 = pts + 3 * 3;
958 double* x3 = pts + 3 * 6;
959 double* x4 = pts + 3 * 7;
960
961 double dir[3] = { 0, 1, 0 };
962 this->ComputeNormals();
963 this->GetDirection(this->N[3], this->N[5], this->N[1], dir);
964
965 this->MoveFace(p1, p2, dir, x1, x2, x3, x4, h1);
966 }
967
MoveMinusYFace(double * p1,double * p2)968 void vtkBoxWidget::MoveMinusYFace(double* p1, double* p2)
969 {
970 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
971
972 double* h1 = pts + 3 * 10;
973
974 double* x1 = pts + 3 * 0;
975 double* x2 = pts + 3 * 1;
976 double* x3 = pts + 3 * 4;
977 double* x4 = pts + 3 * 5;
978
979 double dir[3] = { 0, -1, 0 };
980 this->ComputeNormals();
981 this->GetDirection(this->N[2], this->N[0], this->N[4], dir);
982
983 this->MoveFace(p1, p2, dir, x1, x2, x3, x4, h1);
984 }
985
MovePlusZFace(double * p1,double * p2)986 void vtkBoxWidget::MovePlusZFace(double* p1, double* p2)
987 {
988 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
989
990 double* h1 = pts + 3 * 13;
991
992 double* x1 = pts + 3 * 4;
993 double* x2 = pts + 3 * 5;
994 double* x3 = pts + 3 * 6;
995 double* x4 = pts + 3 * 7;
996
997 double dir[3] = { 0, 0, 1 };
998 this->ComputeNormals();
999 this->GetDirection(this->N[5], this->N[1], this->N[3], dir);
1000
1001 this->MoveFace(p1, p2, dir, x1, x2, x3, x4, h1);
1002 }
1003
MoveMinusZFace(double * p1,double * p2)1004 void vtkBoxWidget::MoveMinusZFace(double* p1, double* p2)
1005 {
1006 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
1007
1008 double* h1 = pts + 3 * 12;
1009
1010 double* x1 = pts + 3 * 0;
1011 double* x2 = pts + 3 * 1;
1012 double* x3 = pts + 3 * 2;
1013 double* x4 = pts + 3 * 3;
1014
1015 double dir[3] = { 0, 0, -1 };
1016 this->ComputeNormals();
1017 this->GetDirection(this->N[4], this->N[2], this->N[0], dir);
1018
1019 this->MoveFace(p1, p2, dir, x1, x2, x3, x4, h1);
1020 }
1021
1022 // Loop through all points and translate them
Translate(double * p1,double * p2)1023 void vtkBoxWidget::Translate(double* p1, double* p2)
1024 {
1025 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
1026 double v[3];
1027
1028 v[0] = p2[0] - p1[0];
1029 v[1] = p2[1] - p1[1];
1030 v[2] = p2[2] - p1[2];
1031
1032 // Move the corners
1033 for (int i = 0; i < 8; i++)
1034 {
1035 *pts++ += v[0];
1036 *pts++ += v[1];
1037 *pts++ += v[2];
1038 }
1039 this->PositionHandles();
1040 }
1041
Scale(double * vtkNotUsed (p1),double * vtkNotUsed (p2),int vtkNotUsed (X),int Y)1042 void vtkBoxWidget::Scale(double* vtkNotUsed(p1), double* vtkNotUsed(p2), int vtkNotUsed(X), int Y)
1043 {
1044 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
1045 double* center = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(3 * 14);
1046 double sf;
1047
1048 if (Y > this->Interactor->GetLastEventPosition()[1])
1049 {
1050 sf = 1.03;
1051 }
1052 else
1053 {
1054 sf = 0.97;
1055 }
1056
1057 // Move the corners
1058 for (int i = 0; i < 8; i++, pts += 3)
1059 {
1060 pts[0] = sf * (pts[0] - center[0]) + center[0];
1061 pts[1] = sf * (pts[1] - center[1]) + center[1];
1062 pts[2] = sf * (pts[2] - center[2]) + center[2];
1063 }
1064 this->PositionHandles();
1065 }
1066
ComputeNormals()1067 void vtkBoxWidget::ComputeNormals()
1068 {
1069 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
1070 double* p0 = pts;
1071 double* px = pts + 3 * 1;
1072 double* py = pts + 3 * 3;
1073 double* pz = pts + 3 * 4;
1074 int i;
1075
1076 for (i = 0; i < 3; i++)
1077 {
1078 this->N[0][i] = p0[i] - px[i];
1079 this->N[2][i] = p0[i] - py[i];
1080 this->N[4][i] = p0[i] - pz[i];
1081 }
1082 vtkMath::Normalize(this->N[0]);
1083 vtkMath::Normalize(this->N[2]);
1084 vtkMath::Normalize(this->N[4]);
1085 for (i = 0; i < 3; i++)
1086 {
1087 this->N[1][i] = -this->N[0][i];
1088 this->N[3][i] = -this->N[2][i];
1089 this->N[5][i] = -this->N[4][i];
1090 }
1091 }
1092
GetPlanes(vtkPlanes * planes)1093 void vtkBoxWidget::GetPlanes(vtkPlanes* planes)
1094 {
1095 if (!planes)
1096 {
1097 return;
1098 }
1099
1100 this->ComputeNormals();
1101
1102 vtkPoints* pts = vtkPoints::New(VTK_DOUBLE);
1103 pts->SetNumberOfPoints(6);
1104
1105 vtkDoubleArray* normals = vtkDoubleArray::New();
1106 normals->SetNumberOfComponents(3);
1107 normals->SetNumberOfTuples(6);
1108
1109 // Set the normals and coordinate values
1110 double factor = (this->InsideOut ? -1.0 : 1.0);
1111 for (int i = 0; i < 6; i++)
1112 {
1113 pts->SetPoint(i, this->Points->GetPoint(8 + i));
1114 normals->SetTuple3(i, factor * this->N[i][0], factor * this->N[i][1], factor * this->N[i][2]);
1115 }
1116
1117 planes->SetPoints(pts);
1118 planes->SetNormals(normals);
1119
1120 pts->Delete();
1121 normals->Delete();
1122 }
1123
Rotate(int X,int Y,double * p1,double * p2,double * vpn)1124 void vtkBoxWidget::Rotate(int X, int Y, double* p1, double* p2, double* vpn)
1125 {
1126 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
1127 double* center = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(3 * 14);
1128 double v[3]; // vector of motion
1129 double axis[3]; // axis of rotation
1130 double theta; // rotation angle
1131 int i;
1132
1133 v[0] = p2[0] - p1[0];
1134 v[1] = p2[1] - p1[1];
1135 v[2] = p2[2] - p1[2];
1136
1137 // Create axis of rotation and angle of rotation
1138 vtkMath::Cross(vpn, v, axis);
1139 if (vtkMath::Normalize(axis) == 0.0)
1140 {
1141 return;
1142 }
1143 const int* size = this->CurrentRenderer->GetSize();
1144 double l2 = (X - this->Interactor->GetLastEventPosition()[0]) *
1145 (X - this->Interactor->GetLastEventPosition()[0]) +
1146 (Y - this->Interactor->GetLastEventPosition()[1]) *
1147 (Y - this->Interactor->GetLastEventPosition()[1]);
1148 theta = 360.0 * sqrt(l2 / (size[0] * size[0] + size[1] * size[1]));
1149
1150 // Manipulate the transform to reflect the rotation
1151 this->Transform->Identity();
1152 this->Transform->Translate(center[0], center[1], center[2]);
1153 this->Transform->RotateWXYZ(theta, axis);
1154 this->Transform->Translate(-center[0], -center[1], -center[2]);
1155
1156 // Set the corners
1157 vtkPoints* newPts = vtkPoints::New(VTK_DOUBLE);
1158 this->Transform->TransformPoints(this->Points, newPts);
1159
1160 for (i = 0; i < 8; i++, pts += 3)
1161 {
1162 this->Points->SetPoint(i, newPts->GetPoint(i));
1163 }
1164
1165 newPts->Delete();
1166 this->PositionHandles();
1167 }
1168
CreateDefaultProperties()1169 void vtkBoxWidget::CreateDefaultProperties()
1170 {
1171 // Handle properties
1172 this->HandleProperty = vtkProperty::New();
1173 this->HandleProperty->SetColor(1, 1, 1);
1174
1175 this->SelectedHandleProperty = vtkProperty::New();
1176 this->SelectedHandleProperty->SetColor(1, 0, 0);
1177
1178 // Face properties
1179 this->FaceProperty = vtkProperty::New();
1180 this->FaceProperty->SetColor(1, 1, 1);
1181 this->FaceProperty->SetOpacity(0.0);
1182
1183 this->SelectedFaceProperty = vtkProperty::New();
1184 this->SelectedFaceProperty->SetColor(1, 1, 0);
1185 this->SelectedFaceProperty->SetOpacity(0.25);
1186
1187 // Outline properties
1188 this->OutlineProperty = vtkProperty::New();
1189 this->OutlineProperty->SetRepresentationToWireframe();
1190 this->OutlineProperty->SetAmbient(1.0);
1191 this->OutlineProperty->SetAmbientColor(1.0, 1.0, 1.0);
1192 this->OutlineProperty->SetLineWidth(2.0);
1193
1194 this->SelectedOutlineProperty = vtkProperty::New();
1195 this->SelectedOutlineProperty->SetRepresentationToWireframe();
1196 this->SelectedOutlineProperty->SetAmbient(1.0);
1197 this->SelectedOutlineProperty->SetAmbientColor(0.0, 1.0, 0.0);
1198 this->SelectedOutlineProperty->SetLineWidth(2.0);
1199 }
1200
PlaceWidget(double bds[6])1201 void vtkBoxWidget::PlaceWidget(double bds[6])
1202 {
1203 int i;
1204 double bounds[6], center[3];
1205
1206 this->AdjustBounds(bds, bounds, center);
1207
1208 this->Points->SetPoint(0, bounds[0], bounds[2], bounds[4]);
1209 this->Points->SetPoint(1, bounds[1], bounds[2], bounds[4]);
1210 this->Points->SetPoint(2, bounds[1], bounds[3], bounds[4]);
1211 this->Points->SetPoint(3, bounds[0], bounds[3], bounds[4]);
1212 this->Points->SetPoint(4, bounds[0], bounds[2], bounds[5]);
1213 this->Points->SetPoint(5, bounds[1], bounds[2], bounds[5]);
1214 this->Points->SetPoint(6, bounds[1], bounds[3], bounds[5]);
1215 this->Points->SetPoint(7, bounds[0], bounds[3], bounds[5]);
1216
1217 for (i = 0; i < 6; i++)
1218 {
1219 this->InitialBounds[i] = bounds[i];
1220 }
1221 this->InitialLength = sqrt((bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) +
1222 (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) +
1223 (bounds[5] - bounds[4]) * (bounds[5] - bounds[4]));
1224
1225 this->PositionHandles();
1226 this->ComputeNormals();
1227 this->SizeHandles();
1228 }
1229
GetTransform(vtkTransform * t)1230 void vtkBoxWidget::GetTransform(vtkTransform* t)
1231 {
1232 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
1233 double* p0 = pts;
1234 double* p1 = pts + 3 * 1;
1235 double* p3 = pts + 3 * 3;
1236 double* p4 = pts + 3 * 4;
1237 double* p14 = pts + 3 * 14;
1238 double center[3], translate[3], scale[3], scaleVec[3][3];
1239 double InitialCenter[3];
1240 int i;
1241
1242 // The transformation is relative to the initial bounds.
1243 // Initial bounds are set when PlaceWidget() is invoked.
1244 t->Identity();
1245
1246 // Translation
1247 for (i = 0; i < 3; i++)
1248 {
1249 InitialCenter[i] = (this->InitialBounds[2 * i + 1] + this->InitialBounds[2 * i]) / 2.0;
1250 center[i] = p14[i] - InitialCenter[i];
1251 }
1252 translate[0] = center[0] + InitialCenter[0];
1253 translate[1] = center[1] + InitialCenter[1];
1254 translate[2] = center[2] + InitialCenter[2];
1255 t->Translate(translate[0], translate[1], translate[2]);
1256
1257 // Orientation
1258 vtkMatrix4x4* matrix = vtkMatrix4x4::New();
1259 this->PositionHandles();
1260 this->ComputeNormals();
1261 for (i = 0; i < 3; i++)
1262 {
1263 matrix->SetElement(i, 0, this->N[1][i]);
1264 matrix->SetElement(i, 1, this->N[3][i]);
1265 matrix->SetElement(i, 2, this->N[5][i]);
1266 }
1267 t->Concatenate(matrix);
1268 matrix->Delete();
1269
1270 // Scale
1271 for (i = 0; i < 3; i++)
1272 {
1273 scaleVec[0][i] = (p1[i] - p0[i]);
1274 scaleVec[1][i] = (p3[i] - p0[i]);
1275 scaleVec[2][i] = (p4[i] - p0[i]);
1276 }
1277
1278 scale[0] = vtkMath::Norm(scaleVec[0]);
1279 if (this->InitialBounds[1] != this->InitialBounds[0])
1280 {
1281 scale[0] = scale[0] / (this->InitialBounds[1] - this->InitialBounds[0]);
1282 }
1283 scale[1] = vtkMath::Norm(scaleVec[1]);
1284 if (this->InitialBounds[3] != this->InitialBounds[2])
1285 {
1286 scale[1] = scale[1] / (this->InitialBounds[3] - this->InitialBounds[2]);
1287 }
1288 scale[2] = vtkMath::Norm(scaleVec[2]);
1289 if (this->InitialBounds[5] != this->InitialBounds[4])
1290 {
1291 scale[2] = scale[2] / (this->InitialBounds[5] - this->InitialBounds[4]);
1292 }
1293 t->Scale(scale[0], scale[1], scale[2]);
1294
1295 // Add back in the contribution due to non-origin center
1296 t->Translate(-InitialCenter[0], -InitialCenter[1], -InitialCenter[2]);
1297 }
1298
SetTransform(vtkTransform * t)1299 void vtkBoxWidget::SetTransform(vtkTransform* t)
1300 {
1301 if (!t)
1302 {
1303 vtkErrorMacro(<< "vtkTransform t must be non-nullptr");
1304 return;
1305 }
1306
1307 double* pts = static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0);
1308 double xIn[3];
1309 // make sure the transform is up-to-date before using it
1310 t->Update();
1311
1312 // Position the eight points of the box and then update the
1313 // position of the other handles.
1314 double* bounds = this->InitialBounds;
1315
1316 xIn[0] = bounds[0];
1317 xIn[1] = bounds[2];
1318 xIn[2] = bounds[4];
1319 t->InternalTransformPoint(xIn, pts);
1320
1321 xIn[0] = bounds[1];
1322 xIn[1] = bounds[2];
1323 xIn[2] = bounds[4];
1324 t->InternalTransformPoint(xIn, pts + 3);
1325
1326 xIn[0] = bounds[1];
1327 xIn[1] = bounds[3];
1328 xIn[2] = bounds[4];
1329 t->InternalTransformPoint(xIn, pts + 6);
1330
1331 xIn[0] = bounds[0];
1332 xIn[1] = bounds[3];
1333 xIn[2] = bounds[4];
1334 t->InternalTransformPoint(xIn, pts + 9);
1335
1336 xIn[0] = bounds[0];
1337 xIn[1] = bounds[2];
1338 xIn[2] = bounds[5];
1339 t->InternalTransformPoint(xIn, pts + 12);
1340
1341 xIn[0] = bounds[1];
1342 xIn[1] = bounds[2];
1343 xIn[2] = bounds[5];
1344 t->InternalTransformPoint(xIn, pts + 15);
1345
1346 xIn[0] = bounds[1];
1347 xIn[1] = bounds[3];
1348 xIn[2] = bounds[5];
1349 t->InternalTransformPoint(xIn, pts + 18);
1350
1351 xIn[0] = bounds[0];
1352 xIn[1] = bounds[3];
1353 xIn[2] = bounds[5];
1354 t->InternalTransformPoint(xIn, pts + 21);
1355
1356 this->PositionHandles();
1357 }
1358
GetPolyData(vtkPolyData * pd)1359 void vtkBoxWidget::GetPolyData(vtkPolyData* pd)
1360 {
1361 pd->SetPoints(this->HexPolyData->GetPoints());
1362 pd->SetPolys(this->HexPolyData->GetPolys());
1363 }
1364
SetOutlineFaceWires(int newValue)1365 void vtkBoxWidget::SetOutlineFaceWires(int newValue)
1366 {
1367 if (this->OutlineFaceWires != newValue)
1368 {
1369 this->OutlineFaceWires = newValue;
1370 this->Modified();
1371 // the outline is dependent on this value, so we have to regen
1372 this->GenerateOutline();
1373 }
1374 }
1375
SetOutlineCursorWires(int newValue)1376 void vtkBoxWidget::SetOutlineCursorWires(int newValue)
1377 {
1378 if (this->OutlineCursorWires != newValue)
1379 {
1380 this->OutlineCursorWires = newValue;
1381 this->Modified();
1382 // the outline is dependent on this value, so we have to regen
1383 this->GenerateOutline();
1384 }
1385 }
1386
GenerateOutline()1387 void vtkBoxWidget::GenerateOutline()
1388 {
1389 // Whatever the case may be, we have to reset the Lines of the
1390 // OutlinePolyData (i.e. nuke all current line data)
1391 vtkCellArray* cells = this->OutlinePolyData->GetLines();
1392 cells->Reset();
1393
1394 // Now the outline lines
1395 if (!this->OutlineFaceWires && !this->OutlineCursorWires)
1396 {
1397 return;
1398 }
1399
1400 vtkIdType pts[2];
1401
1402 if (this->OutlineFaceWires)
1403 {
1404 pts[0] = 0;
1405 pts[1] = 7; // the -x face
1406 cells->InsertNextCell(2, pts);
1407 pts[0] = 3;
1408 pts[1] = 4;
1409 cells->InsertNextCell(2, pts);
1410 pts[0] = 1;
1411 pts[1] = 6; // the +x face
1412 cells->InsertNextCell(2, pts);
1413 pts[0] = 2;
1414 pts[1] = 5;
1415 cells->InsertNextCell(2, pts);
1416 pts[0] = 1;
1417 pts[1] = 4; // the -y face
1418 cells->InsertNextCell(2, pts);
1419 pts[0] = 0;
1420 pts[1] = 5;
1421 cells->InsertNextCell(2, pts);
1422 pts[0] = 3;
1423 pts[1] = 6; // the +y face
1424 cells->InsertNextCell(2, pts);
1425 pts[0] = 2;
1426 pts[1] = 7;
1427 cells->InsertNextCell(2, pts);
1428 pts[0] = 0;
1429 pts[1] = 2; // the -z face
1430 cells->InsertNextCell(2, pts);
1431 pts[0] = 1;
1432 pts[1] = 3;
1433 cells->InsertNextCell(2, pts);
1434 pts[0] = 4;
1435 pts[1] = 6; // the +Z face
1436 cells->InsertNextCell(2, pts);
1437 pts[0] = 5;
1438 pts[1] = 7;
1439 cells->InsertNextCell(2, pts);
1440 }
1441 if (this->OutlineCursorWires)
1442 {
1443 pts[0] = 8;
1444 pts[1] = 9; // the x cursor line
1445 cells->InsertNextCell(2, pts);
1446 pts[0] = 10;
1447 pts[1] = 11; // the y cursor line
1448 cells->InsertNextCell(2, pts);
1449 pts[0] = 12;
1450 pts[1] = 13; // the z cursor line
1451 cells->InsertNextCell(2, pts);
1452 }
1453 this->OutlinePolyData->Modified();
1454 if (this->OutlineProperty)
1455 {
1456 this->OutlineProperty->SetRepresentationToWireframe();
1457 this->SelectedOutlineProperty->SetRepresentationToWireframe();
1458 }
1459 }
1460
1461 //------------------------------------------------------------------------------
RegisterPickers()1462 void vtkBoxWidget::RegisterPickers()
1463 {
1464 vtkPickingManager* pm = this->GetPickingManager();
1465 if (!pm)
1466 {
1467 return;
1468 }
1469 pm->AddPicker(this->HandlePicker, this);
1470 pm->AddPicker(this->HexPicker, this);
1471 }
1472