1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageTracerWidget.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 "vtkImageTracerWidget.h"
16
17 #include "vtkAbstractPicker.h"
18 #include "vtkActor.h"
19 #include "vtkAssemblyPath.h"
20 #include "vtkAssemblyNode.h"
21 #include "vtkCallbackCommand.h"
22 #include "vtkCamera.h"
23 #include "vtkCellArray.h"
24 #include "vtkCellPicker.h"
25 #include "vtkFloatArray.h"
26 #include "vtkGlyphSource2D.h"
27 #include "vtkImageData.h"
28 #include "vtkMath.h"
29 #include "vtkObjectFactory.h"
30 #include "vtkPickingManager.h"
31 #include "vtkPolyData.h"
32 #include "vtkPolyDataMapper.h"
33 #include "vtkPolyLine.h"
34 #include "vtkProperty.h"
35 #include "vtkPropPicker.h"
36 #include "vtkRenderer.h"
37 #include "vtkRenderWindowInteractor.h"
38 #include "vtkTransformPolyDataFilter.h"
39 #include "vtkTransform.h"
40
41 vtkStandardNewMacro(vtkImageTracerWidget);
42
43 vtkCxxSetObjectMacro(vtkImageTracerWidget, HandleProperty, vtkProperty);
44 vtkCxxSetObjectMacro(vtkImageTracerWidget, SelectedHandleProperty, vtkProperty);
45 vtkCxxSetObjectMacro(vtkImageTracerWidget, LineProperty, vtkProperty);
46 vtkCxxSetObjectMacro(vtkImageTracerWidget, SelectedLineProperty, vtkProperty);
47
vtkImageTracerWidget()48 vtkImageTracerWidget::vtkImageTracerWidget()
49 {
50 this->HandleLeftMouseButton = true;
51 this->HandleMiddleMouseButton = true;
52 this->HandleRightMouseButton = true;
53
54 this->State = vtkImageTracerWidget::Start;
55 this->EventCallbackCommand->SetCallback(vtkImageTracerWidget::ProcessEvents);
56
57 this->Interaction = 1;
58 this->ViewProp = NULL;
59 this->PickCount = 0;
60 this->SnapToImage = 0;
61 this->AutoClose = 0;
62 this->CaptureRadius = 1.0;
63 this->IsSnapping = 0;
64 this->ImageSnapType = VTK_ITW_SNAP_CELLS;
65 this->CurrentPicker = NULL;
66 this->CurrentHandle = NULL;
67 this->CurrentHandleIndex = -1;
68 this->ProjectionNormal = VTK_ITW_PROJECTION_XY;
69 this->ProjectionPosition = 0.0;
70 this->ProjectToPlane = 0;
71 this->NumberOfHandles = 0;
72 this->LastX = 0;
73 this->LastY = 0;
74
75 this->PropPicker = vtkPropPicker::New();
76 this->PropPicker->PickFromListOn();
77
78 // Build the representation of the widget
79 this->HandleGenerator = vtkGlyphSource2D::New();
80 this->HandleGenerator->SetGlyphTypeToCross();
81 this->HandleGenerator->FilledOff();
82 this->HandleGenerator->SetCenter(0,0,0);
83
84 this->TransformFilter = vtkTransformPolyDataFilter::New();
85 this->Transform = vtkTransform::New();
86 this->TransformFilter->SetTransform(this->Transform);
87 this->Transform->Identity();
88 this->TransformFilter->SetInputConnection(
89 this->HandleGenerator->GetOutputPort());
90 this->TransformFilter->Update();
91
92 this->TemporaryHandlePoints = vtkFloatArray::New();
93 this->TemporaryHandlePoints->SetNumberOfComponents(3);
94
95 this->LinePoints = vtkPoints::New();
96 this->LinePoints->Allocate(1001);
97 this->LineCells = vtkCellArray::New();
98 this->LineCells->Allocate(this->LineCells->EstimateSize(1000,2));
99 this->LineActor = vtkActor::New();
100 vtkPolyDataMapper* lineMapper = vtkPolyDataMapper::New();
101 this->LineData = vtkPolyData::New();
102
103 lineMapper->SetInputData(this->LineData);
104 lineMapper->SetResolveCoincidentTopologyToPolygonOffset();
105 lineMapper->ScalarVisibilityOff();
106 this->LineActor->SetMapper(lineMapper);
107 this->LineActor->PickableOff();
108 this->LineActor->VisibilityOff();
109 lineMapper->Delete();
110
111 // Manage the picking stuff
112 this->HandlePicker = vtkCellPicker::New();
113 this->HandlePicker->SetTolerance(0.005);
114 this->HandlePicker->PickFromListOn();
115
116 this->LinePicker = vtkCellPicker::New();
117 this->LinePicker->SetTolerance(0.005);
118 this->LinePicker->PickFromListOn();
119
120 // Set up the initial properties
121 this->HandleProperty = NULL;
122 this->SelectedHandleProperty = NULL;
123 this->LineProperty = NULL;
124 this->SelectedLineProperty = NULL;
125 this->CreateDefaultProperties();
126
127 // Initialize ivars
128 this->Handle = NULL;
129 this->HandleGeometry = NULL;
130
131 // Create one handle
132 this->AllocateHandles(1);
133 this->AdjustHandlePosition(0,this->HandleGenerator->GetCenter());
134
135 // Initial creation of the widget, serves to initialize it
136 // using default bounds to get started
137 double bounds[6];
138 vtkMath::UninitializeBounds(bounds);
139
140 this->PlaceFactor = 1.0;
141 this->PlaceWidget(bounds);
142 }
143
~vtkImageTracerWidget()144 vtkImageTracerWidget::~vtkImageTracerWidget()
145 {
146 for ( int i = 0; i < this->NumberOfHandles; ++i )
147 {
148 this->HandleGeometry[i]->Delete();
149 this->Handle[i]->Delete();
150 }
151 delete [] this->Handle;
152 this->Handle = NULL;
153
154 delete [] this->HandleGeometry;
155 this->HandleGeometry = NULL;
156
157 if ( this->HandleProperty )
158 {
159 this->HandleProperty->Delete();
160 }
161 if ( this->SelectedHandleProperty )
162 {
163 this->SelectedHandleProperty->Delete();
164 }
165 if ( this->LineProperty )
166 {
167 this->LineProperty->Delete();
168 }
169 if ( this->SelectedLineProperty )
170 {
171 this->SelectedLineProperty->Delete();
172 }
173 if ( this->ViewProp )
174 {
175 this->ViewProp->UnRegister(this);
176 }
177
178 this->LinePoints->Delete();
179 this->LineCells->Delete();
180 this->LineActor->Delete();
181 this->LineData->Delete();
182
183 this->LinePicker->Delete();
184 this->HandlePicker->Delete();
185 this->CurrentPicker = NULL;
186 this->CurrentHandle = NULL;
187
188 this->PropPicker->Delete();
189 this->TransformFilter->Delete();
190 this->Transform->Delete();
191 this->TemporaryHandlePoints->Delete();
192 this->HandleGenerator->Delete();
193 }
194
195 //----------------------------------------------------------------------------
SetViewProp(vtkProp * prop)196 void vtkImageTracerWidget::SetViewProp(vtkProp* prop)
197 {
198 if ( this->ViewProp != prop )
199 {
200 // Avoid destructor recursion
201 vtkProp *temp = this->ViewProp;
202 this->ViewProp = prop;
203 if ( temp )
204 {
205 temp->UnRegister(this);
206 }
207 if ( this->ViewProp )
208 {
209 this->ViewProp->Register(this);
210 this->PropPicker->InitializePickList();
211 this->PropPicker->AddPickList(this->ViewProp);
212 }
213 }
214 }
215
216 //------------------------------------------------------------------------------
RegisterPickers()217 void vtkImageTracerWidget::RegisterPickers()
218 {
219 this->Interactor->GetPickingManager()->AddPicker(this->PropPicker, this);
220 this->Interactor->GetPickingManager()->AddPicker(this->HandlePicker, this);
221 this->Interactor->GetPickingManager()->AddPicker(this->LinePicker, this);
222 }
223
SetEnabled(int enabling)224 void vtkImageTracerWidget::SetEnabled(int enabling)
225 {
226 if ( !this->Interactor )
227 {
228 vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
229 return;
230 }
231
232 if ( !this->ViewProp )
233 {
234 vtkErrorMacro(<<"The external prop must be set prior to enabling/disabling widget");
235 return;
236 }
237
238 if ( enabling )
239 {
240 vtkDebugMacro(<<"Enabling line widget");
241
242 if ( this->Enabled ) //already enabled, just return
243 {
244 return;
245 }
246
247 if ( !this->CurrentRenderer )
248 {
249 this->SetCurrentRenderer(this->Interactor->FindPokedRenderer(
250 this->Interactor->GetLastEventPosition()[0],
251 this->Interactor->GetLastEventPosition()[1]));
252 if ( !this->CurrentRenderer )
253 {
254 return;
255 }
256 }
257
258 this->Enabled = 1;
259
260 this->AddObservers();
261
262 // Turn on the handles
263 for ( int i = 0; i < this->NumberOfHandles; ++i )
264 {
265 this->CurrentRenderer->AddViewProp(this->Handle[i]);
266 this->Handle[i]->SetProperty(this->HandleProperty);
267 this->Handle[i]->PickableOff();
268 }
269
270 this->SizeHandles();
271
272 this->CurrentRenderer->AddViewProp(this->LineActor);
273 this->LineActor->SetProperty(this->LineProperty);
274 this->LineActor->PickableOff();
275
276 this->InvokeEvent(vtkCommand::EnableEvent,NULL);
277 }
278
279 else // disabling
280 {
281 vtkDebugMacro(<<"Disabling tracer widget");
282
283 if ( !this->Enabled ) //already disabled, just return
284 {
285 return;
286 }
287
288 // if disabling occurs without finishing an activity, cleanup states
289 if ( this->State == vtkImageTracerWidget::Tracing )
290 {
291 this->OnLeftButtonUp();
292 }
293 else if ( this->State == vtkImageTracerWidget::Snapping )
294 {
295 this->Interactor->SetControlKey( 1 );
296 this->OnMiddleButtonUp();
297 }
298
299 this->Enabled = 0;
300
301 // Don't listen for events any more
302 this->Interactor->RemoveObserver(this->EventCallbackCommand);
303
304 // Turn off the handles
305 for ( int i = 0; i < this->NumberOfHandles; ++i )
306 {
307 this->CurrentRenderer->RemoveViewProp(this->Handle[i]);
308 }
309
310 this->CurrentRenderer->RemoveViewProp(this->LineActor);
311
312 this->CurrentHandle = NULL;
313 this->InvokeEvent(vtkCommand::DisableEvent,NULL);
314 this->SetCurrentRenderer(NULL);
315 }
316
317 this->Interactor->Render();
318 }
319
ProcessEvents(vtkObject * vtkNotUsed (object),unsigned long event,void * clientdata,void * vtkNotUsed (calldata))320 void vtkImageTracerWidget::ProcessEvents(vtkObject* vtkNotUsed(object),
321 unsigned long event,
322 void* clientdata,
323 void* vtkNotUsed(calldata))
324 {
325 vtkImageTracerWidget* self = reinterpret_cast<vtkImageTracerWidget *>( clientdata );
326
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
AddObservers(void)353 void vtkImageTracerWidget::AddObservers(void)
354 {
355 // Listen for the following events
356 vtkRenderWindowInteractor *i = this->Interactor;
357 if(!i)
358 {
359 return;
360 }
361
362 i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand,
363 this->Priority);
364 if(this->HandleLeftMouseButton)
365 {
366 i->AddObserver(vtkCommand::LeftButtonPressEvent,
367 this->EventCallbackCommand, this->Priority);
368 i->AddObserver(vtkCommand::LeftButtonReleaseEvent,
369 this->EventCallbackCommand, this->Priority);
370 }
371 if(this->HandleMiddleMouseButton)
372 {
373 i->AddObserver(vtkCommand::MiddleButtonPressEvent,
374 this->EventCallbackCommand, this->Priority);
375 i->AddObserver(vtkCommand::MiddleButtonReleaseEvent,
376 this->EventCallbackCommand, this->Priority);
377 }
378 if(this->HandleRightMouseButton)
379 {
380 i->AddObserver(vtkCommand::RightButtonPressEvent,
381 this->EventCallbackCommand, this->Priority);
382 i->AddObserver(vtkCommand::RightButtonReleaseEvent,
383 this->EventCallbackCommand, this->Priority);
384 }
385 }
386
SetInteraction(int interact)387 void vtkImageTracerWidget::SetInteraction(int interact)
388 {
389 if ( this->Interactor && this->Enabled )
390 {
391 if ( this->Interaction == interact )
392 {
393 return;
394 }
395 if ( interact == 0 )
396 {
397 this->Interactor->RemoveObserver(this->EventCallbackCommand);
398 }
399 else
400 {
401 this->AddObservers();
402 }
403 this->Interaction = interact;
404 }
405 else
406 {
407 vtkGenericWarningMacro(<<"Set interactor and Enabled before changing interaction...");
408 }
409 }
410
PrintSelf(ostream & os,vtkIndent indent)411 void vtkImageTracerWidget::PrintSelf(ostream& os, vtkIndent indent)
412 {
413 this->Superclass::PrintSelf(os,indent);
414
415 if ( this->HandleProperty )
416 {
417 os << indent << "Handle Property: " << this->HandleProperty << "\n";
418 }
419 else
420 {
421 os << indent << "Handle Property: (none)\n";
422 }
423
424 if ( this->SelectedHandleProperty )
425 {
426 os << indent << "Selected Handle Property: "
427 << this->SelectedHandleProperty << "\n";
428 }
429 else
430 {
431 os << indent << "Selected Handle Property: (none)\n";
432 }
433
434 if ( this->LineProperty )
435 {
436 os << indent << "Line Property: " << this->LineProperty << "\n";
437 }
438 else
439 {
440 os << indent << "Line Property: (none)\n";
441 }
442
443 if ( this->SelectedLineProperty )
444 {
445 os << indent << "Selected Line Property: "
446 << this->SelectedLineProperty << "\n";
447 }
448 else
449 {
450 os << indent << "Selected Line Property: (none)\n";
451 }
452
453 if ( this->ViewProp )
454 {
455 os << indent << "ViewProp: " << this->ViewProp << "\n";
456 }
457 else
458 {
459 os << indent << "ViewProp: (none)\n";
460 }
461
462 os << indent << "Interaction: "
463 << (this->Interaction ? "On\n" : "Off\n") ;
464 os << indent << "ProjectionNormal: " << this->ProjectionNormal << "\n";
465 os << indent << "ProjectionPosition: " << this->ProjectionPosition << "\n";
466 os << indent << "ProjectToPlane: "
467 << (this->ProjectToPlane ? "On\n" : "Off\n") ;
468 os << indent << "ImageSnapType: " << this->ImageSnapType << "\n";
469 os << indent << "SnapToImage: "
470 << (this->SnapToImage ? "On\n" : "Off\n") ;
471 os << indent << "CaptureRadius: " << this->CaptureRadius << "\n";
472 os << indent << "NumberOfHandles: " << this->NumberOfHandles << "\n";
473 os << indent << "HandleLeftMouseButton: " << this->HandleLeftMouseButton << "\n";
474 os << indent << "HandleMiddleMouseButton: " << this->HandleMiddleMouseButton << "\n";
475 os << indent << "HandleRightMouseButton: " << this->HandleRightMouseButton << "\n";
476 os << indent << "AutoClose: "
477 << (this->AutoClose ? "On\n" : "Off\n") ;
478 }
479
HighlightHandle(vtkProp * prop)480 int vtkImageTracerWidget::HighlightHandle(vtkProp* prop)
481 {
482 // First unhighlight anything picked
483 if ( this->CurrentHandle )
484 {
485 this->CurrentHandle->SetProperty(this->HandleProperty);
486 this->Interactor->Render();
487 }
488
489 this->CurrentHandle = static_cast<vtkActor *>(prop);
490
491 if ( this->CurrentHandle )
492 {
493 this->ValidPick = 1;
494 this->CurrentPicker->GetPickPosition(this->LastPickPosition);
495 this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
496 for ( int i = 0; i < this->NumberOfHandles; ++i ) // find handle
497 {
498 if ( this->CurrentHandle == this->Handle[i] )
499 {
500 return i;
501 }
502 }
503 }
504 return -1;
505 }
506
HighlightLine(const int & highlight)507 void vtkImageTracerWidget::HighlightLine(const int& highlight)
508 {
509 if ( highlight )
510 {
511 this->ValidPick = 1;
512 this->CurrentPicker->GetPickPosition(this->LastPickPosition);
513 this->LineActor->SetProperty(this->SelectedLineProperty);
514 }
515 else
516 {
517 this->LineActor->SetProperty(this->LineProperty);
518 }
519 }
520
AdjustHandlePosition(const int & handle,double pos[3])521 void vtkImageTracerWidget::AdjustHandlePosition(const int& handle, double pos[3])
522 {
523 if ( handle < 0 || handle >= this->NumberOfHandles ){ return; }
524
525 if ( this->ProjectToPlane )
526 {
527 pos[this->ProjectionNormal] = this->ProjectionPosition;
528 }
529
530 this->HandleGenerator->SetCenter(0.0,0.0,0.0);
531 this->Transform->Identity();
532 this->Transform->PostMultiply();
533
534 if ( this->ProjectionNormal == VTK_ITW_PROJECTION_YZ )
535 {
536 this->Transform->RotateY(90.0);
537 }
538 else if ( this->ProjectionNormal == VTK_ITW_PROJECTION_XZ )
539 {
540 this->Transform->RotateX(90.0);
541 }
542
543 this->Transform->Translate(pos);
544 this->TransformFilter->Update();
545
546 this->HandleGeometry[handle]->CopyStructure(this->TransformFilter->GetOutput());
547 this->HandleGeometry[handle]->Modified();
548 }
549
SetProjectionPosition(double position)550 void vtkImageTracerWidget::SetProjectionPosition(double position)
551 {
552 this->ProjectionPosition = position;
553
554 int i;
555 for ( i = 0; i < this->NumberOfHandles; ++i )
556 {
557 this->AdjustHandlePosition(i,this->HandleGeometry[i]->GetCenter());
558 }
559
560 double pt[3];
561 for ( i = 0; i < this->NumberOfHandles; ++i )
562 {
563 this->LinePoints->GetPoint(i,pt);
564 pt[ this->ProjectionNormal ] = this->ProjectionPosition;
565 this->LinePoints->SetPoint(i,pt);
566 }
567
568 this->LinePoints->GetData()->Modified();
569 this->LineData->Modified();
570 }
571
SetHandlePosition(int handle,double xyz[3])572 void vtkImageTracerWidget::SetHandlePosition(int handle, double xyz[3])
573 {
574 this->AdjustHandlePosition(handle, xyz);
575 }
576
SetHandlePosition(int handle,double x,double y,double z)577 void vtkImageTracerWidget::SetHandlePosition(int handle, double x, double y, double z)
578 {
579 double xyz[3] = {x,y,z};
580 this->AdjustHandlePosition(handle, xyz);
581 }
582
GetHandlePosition(int handle,double xyz[3])583 void vtkImageTracerWidget::GetHandlePosition(int handle, double xyz[3])
584 {
585 if ( handle < 0 || handle >= this->NumberOfHandles ){ return; }
586 this->HandleGeometry[handle]->GetCenter(xyz);
587 }
588
GetHandlePosition(int handle)589 double* vtkImageTracerWidget::GetHandlePosition(int handle)
590 {
591 if ( handle < 0 || handle >= this->NumberOfHandles ){ return NULL; }
592 return this->HandleGeometry[handle]->GetCenter();
593 }
594
OnLeftButtonDown()595 void vtkImageTracerWidget::OnLeftButtonDown()
596 {
597 // If the user is snap defining a line by middle mouse button,
598 // ignore this button
599 if ( this->State == vtkImageTracerWidget::Snapping ){ return; }
600
601 int X = this->Interactor->GetEventPosition()[0];
602 int Y = this->Interactor->GetEventPosition()[1];
603
604 // Okay, make sure that the pick is in the current renderer
605 if ( !this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X,Y) )
606 {
607 this->State = vtkImageTracerWidget::Outside;
608 return;
609 }
610
611 int found = 0;
612 if ( this->PropPicker->PickProp(X,Y,this->CurrentRenderer) )
613 {
614 if ( this->ViewProp == this->PropPicker->GetViewProp() )
615 {
616 found = 1;
617 this->State = vtkImageTracerWidget::Tracing;
618 }
619 }
620
621 if ( !found )
622 {
623 this->State = vtkImageTracerWidget::Outside;
624 return;
625 }
626
627 // first erase any handles if there any
628 if ( this->NumberOfHandles > 1 )
629 {
630 this->AllocateHandles(1);
631 }
632
633 this->CurrentPicker = this->PropPicker; //collect the pick position from the prop picker
634 this->CurrentHandleIndex = this->HighlightHandle(this->Handle[0]);
635
636 if ( this->CurrentHandleIndex == -1 ) //this should never happen
637 {
638 this->State = vtkImageTracerWidget::Outside;
639 return;
640 }
641
642 // set the handle to the picked position
643 this->AdjustHandlePosition(this->CurrentHandleIndex,this->LastPickPosition);
644
645 // erase the line and initialize it
646 this->ResetLine(this->LastPickPosition);
647
648 this->LastX = X;
649 this->LastY = Y;
650
651 this->EventCallbackCommand->SetAbortFlag(1);
652 this->StartInteraction();
653 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
654 this->Interactor->Render();
655 }
656
OnLeftButtonUp()657 void vtkImageTracerWidget::OnLeftButtonUp()
658 {
659 if ( this->State == vtkImageTracerWidget::Outside ||
660 this->State == vtkImageTracerWidget::Start ||
661 this->State == vtkImageTracerWidget::Snapping )
662 {
663 return;
664 }
665
666 this->State = vtkImageTracerWidget::Start;
667 this->CurrentHandleIndex = this->HighlightHandle(NULL);
668
669 if ( this->AutoClose ) // attempt to close by tolerance
670 {
671 this->ClosePath();
672 if ( this->IsClosed() ) // if successful, remove the overlapping handle
673 {
674 this->EraseHandle(this->NumberOfHandles - 1);
675 }
676 }
677
678 this->SizeHandles();
679
680 this->EventCallbackCommand->SetAbortFlag(1);
681 this->EndInteraction();
682 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
683 this->Interactor->Render();
684 this->CurrentPicker = NULL;
685 }
686
OnMiddleButtonDown()687 void vtkImageTracerWidget::OnMiddleButtonDown()
688 {
689 int X = this->Interactor->GetEventPosition()[0];
690 int Y = this->Interactor->GetEventPosition()[1];
691
692 if ( !this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X,Y) )
693 {
694 this->State = vtkImageTracerWidget::Outside;
695 return;
696 }
697
698 int found = 0;
699 if ( this->PropPicker->PickProp(X,Y,this->CurrentRenderer) )
700 {
701 if ( this->ViewProp == this->PropPicker->GetViewProp() )
702 {
703 found = 1;
704 this->State = vtkImageTracerWidget::Snapping; // do snap tracing
705 }
706 }
707
708 if ( !found )
709 {
710 this->State = vtkImageTracerWidget::Outside;
711 return;
712 }
713
714 if ( !this->IsSnapping ) // this is the first time so reset the handles
715 {
716 if ( this->NumberOfHandles > 1 )
717 {
718 this->AllocateHandles(1);
719 }
720 }
721
722 this->CurrentPicker = this->PropPicker; // highlight the last handle
723 this->CurrentHandleIndex = this->HighlightHandle(this->Handle[this->NumberOfHandles - 1]);
724
725 if ( this->CurrentHandleIndex == -1 ) // sanity check: this should never happen
726 {
727 this->State = vtkImageTracerWidget::Outside;
728 return;
729 }
730
731 this->AdjustHandlePosition(this->CurrentHandleIndex,this->LastPickPosition);
732
733 if ( !this->IsSnapping ) // this is the first time so initialize the line
734 {
735 this->ResetLine(this->GetHandlePosition(this->CurrentHandleIndex));
736 }
737
738 this->IsSnapping = this->NumberOfHandles;
739
740 this->EventCallbackCommand->SetAbortFlag(1);
741 this->StartInteraction();
742 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
743 this->Interactor->Render();
744 }
745
OnMiddleButtonUp()746 void vtkImageTracerWidget::OnMiddleButtonUp()
747 {
748 if ( this->State == vtkImageTracerWidget::Outside ||
749 this->State == vtkImageTracerWidget::Start )
750 {
751 return;
752 }
753
754 if ( this->Interactor->GetControlKey() ) // finished the snapping
755 {
756 this->IsSnapping = 0;
757 }
758 else // continue snap drawing
759 {
760 return;
761 }
762
763 this->State = vtkImageTracerWidget::Start;
764 this->CurrentHandleIndex = this->HighlightHandle(NULL);
765
766 if ( this->AutoClose )
767 {
768 this->ClosePath();
769 if ( this->IsClosed() ) // if successful, remove the last overlapping handle
770 {
771 this->EraseHandle(this->NumberOfHandles - 1);
772 }
773 }
774
775 this->SizeHandles();
776
777 this->EventCallbackCommand->SetAbortFlag(1);
778 this->EndInteraction();
779 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
780 this->Interactor->Render();
781 this->CurrentPicker = NULL;
782 }
783
OnRightButtonDown()784 void vtkImageTracerWidget::OnRightButtonDown()
785 {
786 if ( this->State == vtkImageTracerWidget::Snapping ){ return; }
787
788 int X = this->Interactor->GetEventPosition()[0];
789 int Y = this->Interactor->GetEventPosition()[1];
790
791 if ( !this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X,Y) )
792 {
793 this->State = vtkImageTracerWidget::Outside;
794 return;
795 }
796
797 if ( this->Interactor->GetControlKey() && (this->NumberOfHandles > 1) )
798 {
799 this->State = vtkImageTracerWidget::Erasing; // pick a handle to delete
800 for ( int i = 0; i < this->NumberOfHandles; ++i )
801 {
802 this->Handle[i]->PickableOn();
803 }
804 this->CurrentPicker = this->HandlePicker;
805 }
806 else if ( this->Interactor->GetShiftKey() && (this->NumberOfHandles > 1) )
807 {
808 this->State = vtkImageTracerWidget::Inserting; // pick a line to insert on
809 this->LineActor->PickableOn();
810 this->LinePicker->AddPickList(this->LineActor);
811 this->CurrentPicker = this->LinePicker;
812 }
813 else
814 {
815 if ( this->NumberOfHandles < 3 && this->LinePoints->GetNumberOfPoints() > this->NumberOfHandles )
816 {
817 this->State = vtkImageTracerWidget::Translating;
818 }
819 else
820 {
821 this->State = vtkImageTracerWidget::Moving;
822 }
823 for ( int i = 0; i < this->NumberOfHandles; ++i )
824 {
825 this->Handle[i]->PickableOn();
826 }
827 this->CurrentPicker = this->HandlePicker;
828 }
829
830 if ( this->ViewProp ) // don't pick the prop
831 {
832 this->ViewProp->PickableOff();
833 }
834
835 int found = 0;
836 vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->CurrentPicker);
837
838 if ( path )
839 {
840 found = 1;
841 if ( this->State == vtkImageTracerWidget::Erasing ||
842 this->State == vtkImageTracerWidget::Moving ||
843 this->State == vtkImageTracerWidget::Translating )
844 {
845 this->CurrentHandleIndex = this->HighlightHandle(path->GetFirstNode()->GetViewProp());
846 if ( this->CurrentHandleIndex == -1 )
847 {
848 found = 0; // we didn't hit a handle
849 for ( int i = 0; i < this->NumberOfHandles; ++i )
850 {
851 this->Handle[i]->PickableOff();
852 }
853 }
854 }
855 else if ( this->State == vtkImageTracerWidget::Inserting )
856 {
857 if ( static_cast<vtkActor*>(path->GetFirstNode()->GetViewProp()) == this->LineActor )
858 {
859 this->HighlightLine(1);
860 }
861 else
862 {
863 found = 0;
864 this->LineActor->PickableOff();
865 }
866 }
867 }
868
869 if ( !found )
870 {
871 this->State = vtkImageTracerWidget::Outside;
872 if ( this->ViewProp )
873 {
874 this->ViewProp->PickableOn();
875 }
876 this->CurrentPicker = NULL;
877 return;
878 }
879
880 this->EventCallbackCommand->SetAbortFlag(1);
881 this->StartInteraction();
882 this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
883 this->Interactor->Render();
884 }
885
OnRightButtonUp()886 void vtkImageTracerWidget::OnRightButtonUp()
887 {
888 if ( this->State == vtkImageTracerWidget::Outside ||
889 this->State == vtkImageTracerWidget::Start ||
890 this->State == vtkImageTracerWidget::Snapping)
891 {
892 return;
893 }
894
895 if ( this->State == vtkImageTracerWidget::Erasing )
896 {
897 int index = this->CurrentHandleIndex;
898 this->CurrentHandleIndex = this->HighlightHandle(NULL);
899 int closed = this->IsClosed();
900 this->EraseHandle(index);
901 this->BuildLinesFromHandles();
902 if ( closed && this->NumberOfHandles > 2 )
903 {
904 this->AppendLine(this->HandleGeometry[0]->GetCenter());
905 }
906 }
907 else if ( this->State == vtkImageTracerWidget::Inserting )
908 {
909 this->HighlightLine(0);
910 int closed = this->IsClosed();
911 this->InsertHandleOnLine(this->LastPickPosition);
912 this->BuildLinesFromHandles();
913 if ( closed )
914 {
915 this->AppendLine(this->HandleGeometry[0]->GetCenter());
916 }
917 }
918 else if ( this->State == vtkImageTracerWidget::Moving )
919 {
920 this->CurrentHandleIndex = this->HighlightHandle(NULL);
921 if ( this->AutoClose && !this->IsClosed() )
922 {
923 this->ClosePath();
924 if ( this->IsClosed() ) // if successful, remove the last overlapping handle
925 {
926 this->EraseHandle(this->NumberOfHandles - 1);
927 }
928 }
929 }
930 else if ( this->State == vtkImageTracerWidget::Translating )
931 {
932 this->CurrentHandleIndex = this->HighlightHandle(NULL);
933 }
934
935 this->State = vtkImageTracerWidget::Start;
936
937 this->SizeHandles();
938
939 if ( this->ViewProp )
940 {
941 this->ViewProp->PickableOn();
942 }
943
944 this->EventCallbackCommand->SetAbortFlag(1);
945 this->EndInteraction();
946 this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
947 this->Interactor->Render();
948 this->CurrentPicker = NULL;
949 }
950
OnMouseMove()951 void vtkImageTracerWidget::OnMouseMove()
952 {
953 // See whether we're active
954 if ( this->State == vtkImageTracerWidget::Outside ||
955 this->State == vtkImageTracerWidget::Start )
956 {
957 return;
958 }
959
960 int X = this->Interactor->GetEventPosition()[0];
961 int Y = this->Interactor->GetEventPosition()[1];
962 double z;
963
964 // Process the motion
965 if ( this->CurrentHandle )
966 {
967 if ( this->State == vtkImageTracerWidget::Tracing ||
968 this->State == vtkImageTracerWidget::Snapping )
969 {
970 this->Trace(X,Y);
971 }
972 else if ( this->State == vtkImageTracerWidget::Moving ||
973 this->State == vtkImageTracerWidget::Translating )
974 {
975 double focalPoint[4], pickPoint[4], prevPickPoint[4];
976
977 vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
978 if ( !camera ){ return; }
979
980 // Compute the two points defining the motion vector
981 this->ComputeWorldToDisplay(this->LastPickPosition[0],
982 this->LastPickPosition[1],
983 this->LastPickPosition[2], focalPoint);
984 z = focalPoint[2];
985 this->ComputeDisplayToWorld(
986 double(this->Interactor->GetLastEventPosition()[0]),
987 double(this->Interactor->GetLastEventPosition()[1]),
988 z, prevPickPoint);
989 this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
990
991 if ( this->State == vtkImageTracerWidget::Moving )
992 {
993 this->MovePoint(prevPickPoint, pickPoint);
994 }
995 else
996 {
997 this->Translate(prevPickPoint, pickPoint);
998 }
999 }
1000 }
1001
1002 // Interact, if desired
1003 this->EventCallbackCommand->SetAbortFlag(1);
1004 this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
1005 this->Interactor->Render();
1006 }
1007
Trace(int X,int Y)1008 void vtkImageTracerWidget::Trace(int X, int Y)
1009 {
1010 if ( !this->PropPicker->PickProp(X,Y,this->CurrentRenderer) ){ return; }
1011 if ( this->ViewProp != this->PropPicker->GetViewProp() ){ return; }
1012
1013 double pos[3];
1014 this->PropPicker->GetPickPosition(pos);
1015
1016 if ( this->SnapToImage )
1017 {
1018 this->Snap(pos);
1019 }
1020
1021 if ( this->ProjectToPlane )
1022 {
1023 pos[this->ProjectionNormal] = this->ProjectionPosition;
1024 }
1025
1026 if ( this->LastX != X || this->LastY != Y )
1027 {
1028 if ( this->State == vtkImageTracerWidget::Tracing )
1029 {
1030 if ( this->NumberOfHandles == 1 )
1031 {
1032 this->AppendHandles(pos);
1033 }
1034 else
1035 {
1036 this->AdjustHandlePosition(this->CurrentHandleIndex,pos);
1037 }
1038 this->AppendLine(pos);
1039 }
1040 else if ( this->State == vtkImageTracerWidget::Snapping )
1041 {
1042 if ( this->IsSnapping != this->CurrentHandleIndex )
1043 {
1044 this->AppendHandles(pos);
1045 this->AppendLine(pos);
1046 this->IsSnapping = this->CurrentHandleIndex;
1047 }
1048 else
1049 {
1050 this->AdjustHandlePosition(this->CurrentHandleIndex,pos);
1051 this->LinePoints->SetPoint(this->PickCount,pos);
1052 this->LinePoints->GetData()->Modified();
1053 this->LineData->Modified();
1054 }
1055 }
1056 }
1057
1058 this->LastX = X;
1059 this->LastY = Y;
1060 }
1061
MovePoint(const double * p1,const double * p2)1062 void vtkImageTracerWidget::MovePoint(const double *p1, const double *p2)
1063 {
1064 // Get the motion vector
1065 double v[3];
1066 v[0] = p2[0] - p1[0];
1067 v[1] = p2[1] - p1[1];
1068 v[2] = p2[2] - p1[2];
1069
1070 double *ctr = this->HandleGeometry[this->CurrentHandleIndex]->GetCenter();
1071
1072 double newCtr[3];
1073 newCtr[0] = ctr[0] + v[0];
1074 newCtr[1] = ctr[1] + v[1];
1075 newCtr[2] = ctr[2] + v[2];
1076
1077 // Move the widget handle
1078 this->AdjustHandlePosition(this->CurrentHandleIndex,newCtr);
1079
1080 // Enforce consistency with the line
1081 int closed = this->IsClosed();
1082
1083 this->LinePoints->SetPoint(this->CurrentHandleIndex,
1084 this->HandleGeometry[this->CurrentHandleIndex]->GetCenter());
1085
1086 // Special case when moving the first point
1087 if ( closed && (this->CurrentHandleIndex == 0) )
1088 {
1089 this->LinePoints->SetPoint(this->LinePoints->GetNumberOfPoints()-1,
1090 this->HandleGeometry[0]->GetCenter());
1091 }
1092
1093 this->LinePoints->GetData()->Modified();
1094 this->LineData->Modified();
1095 }
1096
Translate(const double * p1,const double * p2)1097 void vtkImageTracerWidget::Translate(const double *p1, const double *p2)
1098 {
1099 // Get the motion vector
1100 double v[3];
1101 v[0] = p2[0] - p1[0];
1102 v[1] = p2[1] - p1[1];
1103 v[2] = p2[2] - p1[2];
1104
1105 double newCtr[3];
1106 int i;
1107 for ( i = 0; i < this->NumberOfHandles; ++i )
1108 {
1109 double *ctr = this->HandleGeometry[i]->GetCenter();
1110 newCtr[0] = ctr[0] + v[0];
1111 newCtr[1] = ctr[1] + v[1];
1112 newCtr[2] = ctr[2] + v[2];
1113 this->AdjustHandlePosition(i,newCtr);
1114 }
1115
1116 for ( i = 0; i < this->LinePoints->GetNumberOfPoints(); ++i )
1117 {
1118 double *ctr = this->LinePoints->GetPoint(i);
1119 newCtr[0] = ctr[0] + v[0];
1120 newCtr[1] = ctr[1] + v[1];
1121 newCtr[2] = ctr[2] + v[2];
1122 if ( this->ProjectToPlane )
1123 {
1124 newCtr[this->ProjectionNormal] = this->ProjectionPosition;
1125 }
1126 this->LinePoints->SetPoint(i,newCtr);
1127 }
1128
1129 this->LinePoints->GetData()->Modified();
1130 this->LineData->Modified();
1131 }
1132
ResetHandles(void)1133 void vtkImageTracerWidget::ResetHandles(void)
1134 {
1135 if ( this->NumberOfHandles == 0 ){ return; }
1136
1137 if ( this->CurrentHandle )
1138 {
1139 this->CurrentHandle = NULL;
1140 }
1141
1142 this->HandlePicker->InitializePickList();
1143
1144 int i;
1145 if ( this->CurrentRenderer )
1146 {
1147 for (i = 0; i < this->NumberOfHandles; ++i )
1148 {
1149 this->CurrentRenderer->RemoveViewProp(this->Handle[i]);
1150 }
1151 }
1152
1153 for ( i = 0; i < this->NumberOfHandles; ++i )
1154 {
1155 this->HandleGeometry[i]->Delete();
1156 this->Handle[i]->Delete();
1157 }
1158
1159 this->NumberOfHandles = 0;
1160
1161 delete [] this->Handle;
1162 this->Handle = NULL;
1163
1164 delete [] this->HandleGeometry;
1165 this->HandleGeometry = NULL;
1166 }
1167
AllocateHandles(const int & nhandles)1168 void vtkImageTracerWidget::AllocateHandles(const int& nhandles)
1169 {
1170 if ( (this->NumberOfHandles == nhandles) || (nhandles < 1) ){ return; }
1171
1172 // De-allocate the handles
1173 this->ResetHandles();
1174 this->NumberOfHandles = nhandles;
1175
1176 // Create the handles
1177 this->Handle = new vtkActor* [this->NumberOfHandles];
1178 this->HandleGeometry = new vtkPolyData* [this->NumberOfHandles];
1179
1180 int i;
1181 for ( i = 0; i < this->NumberOfHandles; ++i )
1182 {
1183 this->HandleGeometry[i] = vtkPolyData::New();
1184 vtkPolyDataMapper* handleMapper = vtkPolyDataMapper::New();
1185 handleMapper->SetInputData(this->HandleGeometry[i]);
1186 this->Handle[i] = vtkActor::New();
1187 this->Handle[i]->SetMapper(handleMapper);
1188 handleMapper->Delete();
1189 this->Handle[i]->SetProperty(this->HandleProperty);
1190 this->Handle[i]->PickableOff();
1191 this->HandlePicker->AddPickList(this->Handle[i]);
1192 }
1193
1194 if ( this->CurrentRenderer && this->Enabled )
1195 {
1196 for ( i = 0; i < this->NumberOfHandles; ++i )
1197 {
1198 this->CurrentRenderer->AddViewProp(this->Handle[i]);
1199 }
1200 }
1201 }
1202
AppendHandles(double * pos)1203 void vtkImageTracerWidget::AppendHandles(double* pos)
1204 {
1205 this->TemporaryHandlePoints->Reset();
1206 this->TemporaryHandlePoints->SetNumberOfTuples(this->NumberOfHandles+1);
1207 int i;
1208 for ( i = 0; i < this->NumberOfHandles; ++i )
1209 {
1210 this->TemporaryHandlePoints->SetTuple(i,this->HandleGeometry[i]->GetCenter());
1211 }
1212
1213 this->TemporaryHandlePoints->SetTuple(this->NumberOfHandles,pos);
1214
1215 this->AllocateHandles(this->TemporaryHandlePoints->GetNumberOfTuples());
1216
1217 for ( i = 0; i < this->NumberOfHandles; ++i )
1218 {
1219 this->AdjustHandlePosition(i,this->TemporaryHandlePoints->GetTuple(i));
1220 }
1221
1222 if ( this->CurrentHandleIndex != -1 )
1223 {
1224 this->CurrentHandleIndex = this->NumberOfHandles - 1;
1225 this->CurrentHandle = this->Handle[this->CurrentHandleIndex];
1226 this->CurrentHandle->SetProperty(this->SelectedHandleProperty);
1227 }
1228 }
1229
InsertHandleOnLine(double * pos)1230 void vtkImageTracerWidget::InsertHandleOnLine(double* pos)
1231 {
1232 if ( this->NumberOfHandles < 3 &&
1233 this->LinePoints->GetNumberOfPoints() > 2 )
1234 {
1235 return; // don't insert on a continuously traced line
1236 }
1237
1238 int id = this->LinePicker->GetCellId();
1239 if ( id == -1 ){ return; }
1240
1241 this->TemporaryHandlePoints->Reset();
1242 this->TemporaryHandlePoints->SetNumberOfTuples(this->NumberOfHandles+1);
1243 int i;
1244 for ( i = 0; i <= id; i++ )
1245 {
1246 this->TemporaryHandlePoints->SetTuple(i,this->HandleGeometry[i]->GetCenter());
1247 }
1248
1249 this->TemporaryHandlePoints->SetTuple(id+1,pos);
1250
1251 for ( i = id + 1; i < this->NumberOfHandles; ++i )
1252 {
1253 this->TemporaryHandlePoints->SetTuple(i+1,this->HandleGeometry[i]->GetCenter());
1254 }
1255
1256 this->AllocateHandles(this->TemporaryHandlePoints->GetNumberOfTuples());
1257
1258 for ( i = 0; i < this->NumberOfHandles; ++i )
1259 {
1260 this->AdjustHandlePosition(i,this->TemporaryHandlePoints->GetTuple(i));
1261 }
1262 }
1263
InitializeHandles(vtkPoints * points)1264 void vtkImageTracerWidget::InitializeHandles(vtkPoints* points)
1265 {
1266 if ( !points ){ return; }
1267
1268 int npts = points->GetNumberOfPoints();
1269 if ( npts == 0 ){ return; }
1270
1271 this->AllocateHandles( npts );
1272
1273 for ( int i = 0; i < npts; ++i )
1274 {
1275 this->AdjustHandlePosition(i,points->GetPoint(i));
1276 }
1277
1278 if ( npts > 1 )
1279 {
1280 this->BuildLinesFromHandles();
1281 if ( this->AutoClose )
1282 {
1283 this->ClosePath();
1284 if ( this->IsClosed() ) // if successful, remove the overlapping handle
1285 {
1286 this->EraseHandle(this->NumberOfHandles - 1);
1287 }
1288 }
1289 }
1290 }
1291
EraseHandle(const int & index)1292 void vtkImageTracerWidget::EraseHandle(const int& index)
1293 {
1294 if ( this->NumberOfHandles == 1 ){ return; }
1295
1296 this->TemporaryHandlePoints->Reset();
1297 this->TemporaryHandlePoints->SetNumberOfTuples(this->NumberOfHandles-1);
1298 int i;
1299 int count = 0;
1300 for ( i = 0; i < this->NumberOfHandles; ++i )
1301 {
1302 if ( i != index )
1303 {
1304 this->TemporaryHandlePoints->SetTuple(count++,this->HandleGeometry[i]->GetCenter());
1305 }
1306 }
1307
1308 this->AllocateHandles(this->TemporaryHandlePoints->GetNumberOfTuples());
1309
1310 for ( i = 0; i < this->NumberOfHandles; ++i )
1311 {
1312 this->AdjustHandlePosition(i,this->TemporaryHandlePoints->GetTuple(i));
1313 }
1314 }
1315
ResetLine(double * pos)1316 void vtkImageTracerWidget::ResetLine(double* pos)
1317 {
1318 this->LinePicker->DeletePickList(this->LineActor);
1319 this->LineActor->VisibilityOff();
1320 this->LineActor->PickableOff();
1321
1322 this->LinePoints->Delete();
1323 this->LineCells->Delete();
1324
1325 this->LineData->Initialize();
1326 this->LineData->Squeeze();
1327
1328 this->LinePoints = vtkPoints::New();
1329 this->LineCells = vtkCellArray::New();
1330
1331 this->LineData->SetPoints( this->LinePoints );
1332 this->LineData->SetLines( this->LineCells );
1333
1334 this->PickCount = 0;
1335
1336 this->LinePoints->InsertPoint(this->PickCount,pos);
1337 }
1338
AppendLine(double * pos)1339 void vtkImageTracerWidget::AppendLine(double* pos)
1340 {
1341 this->CurrentPoints[0] = this->PickCount++;
1342 this->CurrentPoints[1] = this->PickCount;
1343
1344 this->LinePoints->InsertPoint(this->PickCount,pos);
1345 this->LineCells->InsertNextCell(2,this->CurrentPoints);
1346
1347 this->LinePoints->GetData()->Modified();
1348 this->LineData->SetPoints(this->LinePoints);
1349 this->LineData->SetLines(this->LineCells);
1350 this->LineData->Modified();
1351
1352 this->LineActor->VisibilityOn();
1353 }
1354
BuildLinesFromHandles()1355 void vtkImageTracerWidget::BuildLinesFromHandles()
1356 {
1357 this->ResetLine(this->HandleGeometry[0]->GetCenter());
1358
1359 for ( int i = 1; i < this->NumberOfHandles; ++i )
1360 {
1361 this->AppendLine(this->HandleGeometry[i]->GetCenter());
1362 }
1363 }
1364
ClosePath()1365 void vtkImageTracerWidget::ClosePath()
1366 {
1367 int npts = this->LinePoints->GetNumberOfPoints();
1368 if ( npts < 4 ){ return; }
1369
1370 double p0[3];
1371 this->LinePoints->GetPoint(0,p0);
1372 double p1[3];
1373 this->LinePoints->GetPoint(npts-1,p1);
1374
1375 if ( sqrt(vtkMath::Distance2BetweenPoints(p0,p1)) <= this->CaptureRadius )
1376 {
1377 this->LinePoints->SetPoint(npts-1,p0);
1378 this->LinePoints->GetData()->Modified();
1379 this->LineData->Modified();
1380 }
1381 }
1382
IsClosed()1383 int vtkImageTracerWidget::IsClosed() // can only be based on line data
1384 {
1385 int npts = this->LinePoints->GetNumberOfPoints();
1386 if ( npts < 4 ) { return 0; }
1387
1388 double p0[3];
1389 this->LinePoints->GetPoint(0,p0);
1390 double p1[3];
1391 this->LinePoints->GetPoint(npts-1,p1);
1392
1393 return (p0[0] == p1[0] && p0[1] == p1[1] && p0[2] == p1[2]);
1394 }
1395
GetPath(vtkPolyData * pd)1396 void vtkImageTracerWidget::GetPath(vtkPolyData *pd)
1397 {
1398 pd->ShallowCopy(this->LineData);
1399 }
1400
SetSnapToImage(int snap)1401 void vtkImageTracerWidget::SetSnapToImage(int snap)
1402 {
1403 if ( this->GetInput() )
1404 {
1405 if ( this->GetInput()->GetDataObjectType() != VTK_IMAGE_DATA )
1406 {
1407 vtkErrorMacro(<<"Input data must be of type vtkImageData");
1408 return;
1409 }
1410 else
1411 {
1412 this->SnapToImage = snap;
1413 }
1414 }
1415 else
1416 {
1417 vtkGenericWarningMacro(<<"SetInput with type vtkImageData first");
1418 return;
1419 }
1420 }
1421
Snap(double * pos)1422 void vtkImageTracerWidget::Snap(double* pos) // overwrites pos
1423 {
1424 vtkImageData* ptr = vtkImageData::SafeDownCast(this->GetInput());
1425 if ( !ptr ){ return; }
1426
1427 if ( this->ImageSnapType == VTK_ITW_SNAP_CELLS ) // snap to cell center
1428 {
1429 double bounds[6];
1430 double weights[8];
1431 double pcoords[3];
1432 int subId;
1433 vtkIdType cellId = ptr->FindCell(pos,NULL,-1,0.0,subId,pcoords,weights);
1434 if ( cellId != -1 )
1435 {
1436 ptr->GetCellBounds(cellId,bounds);
1437 for ( int i = 0; i < 3; ++i )
1438 {
1439 pos[i] = bounds[i*2]+ 0.5*(bounds[i*2+1]-bounds[i*2]);
1440 }
1441 }
1442 }
1443 else // snap to nearest point
1444 {
1445 vtkIdType ptId = ptr->FindPoint(pos);
1446 if ( ptId != -1 )
1447 {
1448 ptr->GetPoint(ptId,pos);
1449 }
1450 }
1451 }
1452
CreateDefaultProperties()1453 void vtkImageTracerWidget::CreateDefaultProperties()
1454 {
1455 if ( !this->HandleProperty )
1456 {
1457 this->HandleProperty = vtkProperty::New();
1458 this->HandleProperty->SetAmbient(1.0);
1459 this->HandleProperty->SetDiffuse(0.0);
1460 this->HandleProperty->SetColor(1,0,1);
1461 this->HandleProperty->SetLineWidth(2);
1462 this->HandleProperty->SetRepresentationToWireframe();
1463 this->HandleProperty->SetInterpolationToFlat();
1464 }
1465 if ( !this->SelectedHandleProperty )
1466 {
1467 this->SelectedHandleProperty = vtkProperty::New();
1468 this->SelectedHandleProperty->SetAmbient(1.0);
1469 this->SelectedHandleProperty->SetDiffuse(0.0);
1470 this->SelectedHandleProperty->SetColor(0,1,0);
1471 this->SelectedHandleProperty->SetLineWidth(2);
1472 this->SelectedHandleProperty->SetRepresentationToWireframe();
1473 this->SelectedHandleProperty->SetInterpolationToFlat();
1474 }
1475 if ( !this->LineProperty )
1476 {
1477 this->LineProperty = vtkProperty::New();
1478 this->LineProperty->SetAmbient(1.0);
1479 this->LineProperty->SetDiffuse(0.0);
1480 this->LineProperty->SetColor(0,1,0);
1481 this->LineProperty->SetLineWidth(2);
1482 this->LineProperty->SetRepresentationToWireframe();
1483 this->LineProperty->SetInterpolationToFlat();
1484 }
1485 if ( !this->SelectedLineProperty )
1486 {
1487 this->SelectedLineProperty = vtkProperty::New();
1488 this->SelectedLineProperty->SetAmbient(1.0);
1489 this->SelectedLineProperty->SetDiffuse(0.0);
1490 this->SelectedLineProperty->SetColor(0,1,1);
1491 this->SelectedLineProperty->SetLineWidth(2);
1492 this->SelectedLineProperty->SetRepresentationToWireframe();
1493 this->SelectedLineProperty->SetInterpolationToFlat();
1494 }
1495 }
1496
PlaceWidget(double bds[6])1497 void vtkImageTracerWidget::PlaceWidget(double bds[6])
1498 {
1499 double bounds[6], center[3];
1500 this->AdjustBounds(bds, bounds, center);
1501
1502 // create a default handle within the data bounds
1503 double x0 = bounds[0];
1504 double x1 = bounds[1];
1505 double y0 = bounds[2];
1506 double y1 = bounds[3];
1507 double z0 = bounds[4];
1508 double z1 = bounds[5];
1509 double xyz[3];
1510 double position = 0.5;
1511 xyz[0] = (1.0-position)*x0 + position*x1;
1512 xyz[1] = (1.0-position)*y0 + position*y1;
1513 xyz[2] = (1.0-position)*z0 + position*z1;
1514
1515 this->AdjustHandlePosition(0,xyz);
1516
1517 for ( int i = 0; i < 6; ++i )
1518 {
1519 this->InitialBounds[i] = bounds[i];
1520 }
1521 this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1522 (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1523 (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1524 this->SizeHandles();
1525 }
1526
SizeHandles()1527 void vtkImageTracerWidget::SizeHandles()
1528 {
1529 // TODO...
1530 return;
1531 }
1532
1533 //----------------------------------------------------------------------------
1534 #ifndef VTK_LEGACY_REMOVE
1535 # ifdef VTK_WORKAROUND_WINDOWS_MANGLE
1536 # undef SetProp
SetPropA(vtkProp * prop)1537 void vtkImageTracerWidget::SetPropA(vtkProp* prop)
1538 {
1539 VTK_LEGACY_REPLACED_BODY(vtkImageTracerWidget::SetProp, "VTK 5.0",
1540 vtkImageTracerWidget::SetViewProp);
1541 this->SetViewProp(prop);
1542 }
SetPropW(vtkProp * prop)1543 void vtkImageTracerWidget::SetPropW(vtkProp* prop)
1544 {
1545 VTK_LEGACY_REPLACED_BODY(vtkImageTracerWidget::SetProp, "VTK 5.0",
1546 vtkImageTracerWidget::SetViewProp);
1547 this->SetViewProp(prop);
1548 }
1549 # endif
SetProp(vtkProp * prop)1550 void vtkImageTracerWidget::SetProp(vtkProp* prop)
1551 {
1552 VTK_LEGACY_REPLACED_BODY(vtkImageTracerWidget::SetProp, "VTK 5.0",
1553 vtkImageTracerWidget::SetViewProp);
1554 this->SetViewProp(prop);
1555 }
1556 #endif
1557