Salome HOME
Merge from V6_4_BR 05/12/2011
[modules/visu.git] / src / PIPELINE / VISU_PlanesWidget.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME VTKViewer : build VTK viewer into Salome desktop
24 //  File   : VVTK_ImplicitFunctionWidget.cxx
25 //  Author : Peter KURNEV
26 //  Module : SALOME
27 //  $Header$
28 //
29 #include "VISU_PlanesWidget.hxx"
30 #include "VISU_ImplicitFunctionWidget.hxx"
31
32 #include <vtkActor.h>
33 #include <vtkAssemblyNode.h>
34 #include <vtkAssemblyPath.h>
35 #include <vtkCallbackCommand.h>
36 #include <vtkCamera.h>
37 #include <vtkCellPicker.h>
38 #include <vtkConeSource.h>
39 #include <vtkCutter.h>
40 #include <vtkFeatureEdges.h>
41 #include <vtkImageData.h>
42 #include <vtkLineSource.h>
43 #include <vtkMath.h>
44 #include <vtkObjectFactory.h>
45 #include <vtkOutlineFilter.h>
46 #include <vtkPlane.h>
47 #include <vtkPolyData.h>
48 #include <vtkPolyDataMapper.h>
49 #include <vtkProperty.h>
50 #include <vtkRenderWindowInteractor.h>
51 #include <vtkRenderer.h>
52 #include <vtkSphereSource.h>
53 #include <vtkTransform.h>
54 #include <vtkTubeFilter.h>
55 #include <vtkImplicitBoolean.h>
56 #include <vtkImplicitFunctionCollection.h>
57 ////
58 #include <vtkFollower.h>
59 #include <vtkObjectFactory.h>
60 #include <vtkDataSet.h>
61 #include <vtkRenderWindow.h>
62
63 static
64 bool 
65 IsValidPlane2Position(vtkPlane *pPx,
66                       vtkDataSet *pDataSet,
67                       vtkFloatingPointType aTol=0.003);
68 static 
69 void 
70 GetBndPoints(vtkDataSet *pDataSet, 
71              vtkFloatingPointType aPnts[24]);
72 static 
73 vtkFloatingPointType
74 DistanceToPlane(const vtkFloatingPointType x[3], 
75                 const vtkFloatingPointType n[3], 
76                 const vtkFloatingPointType p0[3]);
77
78 vtkCxxRevisionMacro(VISU_PlanesWidget, "$Revision$");
79 vtkStandardNewMacro(VISU_PlanesWidget);
80
81 //==================================================================
82 // function: VISU_PlanesWidget
83 // purpose :
84 //==================================================================
85 VISU_PlanesWidget::VISU_PlanesWidget() 
86
87   VISU_ImplicitFunctionWidget()
88 {
89   State = VISU_PlanesWidget::Start;
90   EventCallbackCommand->SetCallback(VISU_PlanesWidget::ProcessEvents);
91   
92   NormalToXAxis = 0;
93   NormalToYAxis = 0;
94   NormalToZAxis = 0;
95
96   HandleMoveEvent = true;
97   HandleLeftButtonEvent = true;
98   HandleMiddleButtonEvent = false;
99   HandleRightButtonEvent = false;
100
101   // Build the representation of the widget
102   // 
103   myPlane1 = vtkPlane::New();
104   myPlane1->SetNormal(0,0,1);
105   myPlane1->SetOrigin(0,0,0);
106   //
107   myDistance = 10.;
108   myPlane2 = vtkPlane::New();
109   myPlane2->SetNormal(0.,0.,-1.);
110   myPlane2->SetOrigin(0,0,myDistance);
111   //
112   myImplicitFunction = vtkImplicitBoolean::New();
113   myImplicitFunction->SetOperationType(VTK_UNION);  
114   //
115   myBox = vtkImageData::New();
116   myBox->SetDimensions(2,2,2);
117   myOutline = vtkOutlineFilter::New();
118   myOutline->SetInput(myBox);
119   myOutlineMapper = vtkPolyDataMapper::New();
120   myOutlineMapper->SetInput(myOutline->GetOutput());
121   myOutlineActor = vtkActor::New();
122   this->myOutlineActor->SetMapper(this->myOutlineMapper);
123   this->myOutlineActor->PickableOff();
124   this->OutlineTranslation = 0;
125   
126   this->myCutter1 = vtkCutter::New();
127   this->myCutter1->SetInput(myBox);
128   this->myCutter1->SetCutFunction(myPlane1);
129   this->myCutMapper1 = vtkPolyDataMapper::New();
130   this->myCutMapper1->SetInput(this->myCutter1->GetOutput());
131   this->myCutActor1 = vtkActor::New();
132   this->myCutActor1->SetMapper(this->myCutMapper1);
133   this->myDrawPlane = 1;
134
135   this->myEdges1 = vtkFeatureEdges::New();
136   myEdges1->SetColoring(0); 
137   this->myEdges1->SetInput(this->myCutter1->GetOutput());
138   this->myEdgesMapper1 = vtkPolyDataMapper::New();
139   this->myEdgesMapper1->SetInput(this->myEdges1->GetOutput());
140   this->myEdgesActor1 = vtkActor::New();
141   this->myEdgesActor1->SetMapper(this->myEdgesMapper1);
142   myEdgesActor1->GetProperty()->SetLineWidth(4.); 
143   myEdgesActor1->GetProperty()->SetColor(0., .5, .7); 
144
145   this->myCutter2 = vtkCutter::New();
146   this->myCutter2->SetInput(myBox);
147   this->myCutter2->SetCutFunction(this->myPlane2);
148   this->myCutMapper2 = vtkPolyDataMapper::New();
149   this->myCutMapper2->SetInput(this->myCutter2->GetOutput());
150   this->myCutActor2 = vtkActor::New();
151   this->myCutActor2->SetMapper(this->myCutMapper2);
152
153   myEdges2 = vtkFeatureEdges::New();
154   myEdges2->SetColoring(0); 
155   myEdges2->SetInput(myCutter2->GetOutput());
156   myEdgesMapper2 = vtkPolyDataMapper::New();
157   myEdgesMapper2->SetInput(myEdges2->GetOutput());
158   myEdgesActor2 = vtkActor::New();
159   myEdgesActor2->SetMapper(myEdgesMapper2);
160   myEdgesActor2->GetProperty()->SetLineWidth(4.); 
161   myEdgesActor2->GetProperty()->SetColor(.7, .0, .0); 
162
163   // Create the + plane normal
164   this->LineSource = vtkLineSource::New();
165   this->LineSource->SetResolution(1);
166   this->LineMapper = vtkPolyDataMapper::New();
167   this->LineMapper->SetInput(this->LineSource->GetOutput());
168   this->LineActor = vtkActor::New();
169   this->LineActor->SetMapper(this->LineMapper);
170
171   this->ConeSource = vtkConeSource::New();
172   this->ConeSource->SetResolution(12);
173   this->ConeSource->SetAngle(20.);
174   this->ConeMapper = vtkPolyDataMapper::New();
175   this->ConeMapper->SetInput(this->ConeSource->GetOutput());
176   this->ConeActor = VISU_UnScaledActor::New();
177   this->ConeActor->SetMapper(this->ConeMapper);
178   ConeActor->SetSize(36);
179   ConeActor->SetCenter(ConeSource->GetCenter());
180
181   // Create the - plane normal
182   this->LineSource2 = vtkLineSource::New();
183   this->LineSource2->SetResolution(1);
184   this->LineMapper2 = vtkPolyDataMapper::New();
185   this->LineMapper2->SetInput(this->LineSource2->GetOutput());
186   this->LineActor2 = vtkActor::New();
187   this->LineActor2->SetMapper(this->LineMapper2);
188
189   this->ConeSource2 = vtkConeSource::New();
190   this->ConeSource2->SetResolution(12);
191   this->ConeSource2->SetAngle(20.);
192   this->ConeMapper2 = vtkPolyDataMapper::New();
193   this->ConeMapper2->SetInput(this->ConeSource2->GetOutput());
194   this->ConeActor2 = VISU_UnScaledActor::New();
195   this->ConeActor2->SetMapper(this->ConeMapper2);
196   ConeActor2->SetSize(36);
197   ConeActor2->SetCenter(ConeSource2->GetCenter());
198
199   // Create the origin handle
200   this->Sphere = vtkSphereSource::New();
201   this->Sphere->SetThetaResolution(16);
202   this->Sphere->SetPhiResolution(8);
203   this->SphereMapper = vtkPolyDataMapper::New();
204   this->SphereMapper->SetInput(this->Sphere->GetOutput());
205   this->SphereActor = VISU_UnScaledActor::New();
206   this->SphereActor->SetMapper(this->SphereMapper);
207   SphereActor->SetSize(36);
208   SphereActor->SetCenter(Sphere->GetCenter());
209
210   this->Transform = vtkTransform::New();
211
212   // Define the point coordinates
213   vtkFloatingPointType bounds[6];
214   bounds[0] = -0.5;
215   bounds[1] = 0.5;
216   bounds[2] = -0.5;
217   bounds[3] = 0.5;
218   bounds[4] = -0.5;
219   bounds[5] = 0.5;
220
221   // Initial creation of the widget, serves to initialize it
222   this->PlaceWidget(bounds);
223
224   //Manage the picking stuff
225   this->Picker = vtkCellPicker::New();
226   this->Picker->SetTolerance(0.005);
227   this->Picker->AddPickList(this->myCutActor1);
228   this->Picker->AddPickList(this->myCutActor2);
229   this->Picker->AddPickList(this->LineActor);
230   this->Picker->AddPickList(this->ConeActor);
231   this->Picker->AddPickList(this->LineActor2);
232   this->Picker->AddPickList(this->ConeActor2);
233   this->Picker->AddPickList(this->SphereActor);
234   this->Picker->AddPickList(this->myOutlineActor);
235   this->Picker->PickFromListOn();
236   
237   // Set up the initial properties
238   this->CreateDefaultProperties();
239   
240 }
241 //==================================================================
242 // function: ~
243 // purpose :
244 //==================================================================
245 VISU_PlanesWidget::~VISU_PlanesWidget()
246 {  
247   myPlane1->Delete();
248
249   this->myPlane2->Delete();
250   this->myImplicitFunction->Delete();
251
252   myBox->Delete();
253   this->myOutline->Delete();
254   this->myOutlineMapper->Delete();
255   this->myOutlineActor->Delete();
256   
257   this->myCutter1->Delete();
258   this->myCutMapper1->Delete();
259   this->myCutActor1->Delete();
260
261   this->myEdges1->Delete();
262   this->myEdgesMapper1->Delete();
263   this->myEdgesActor1->Delete();
264   
265   myCutter2->Delete();
266   myCutMapper2->Delete();
267   myCutActor2->Delete();
268
269   myEdges2->Delete();
270   myEdgesMapper2->Delete();
271   myEdgesActor2->Delete();
272   
273   this->LineSource->Delete();
274   this->LineMapper->Delete();
275   this->LineActor->Delete();
276
277   this->ConeSource->Delete();
278   this->ConeMapper->Delete();
279   this->ConeActor->Delete();
280
281   this->LineSource2->Delete();
282   this->LineMapper2->Delete();
283   this->LineActor2->Delete();
284
285   this->ConeSource2->Delete();
286   this->ConeMapper2->Delete();
287   this->ConeActor2->Delete();
288
289   this->Sphere->Delete();
290   this->SphereMapper->Delete();
291   this->SphereActor->Delete();
292
293   this->Transform->Delete();
294
295   this->Picker->Delete();
296
297   this->NormalProperty->Delete();
298   this->SelectedNormalProperty->Delete();
299   this->PlaneProperty->Delete();
300   this->SelectedPlaneProperty->Delete();
301   this->OutlineProperty->Delete();
302   this->SelectedOutlineProperty->Delete();
303   this->EdgesProperty->Delete();
304 }
305 //==================================================================
306 // function: ImplicitFunction
307 // purpose :
308 //==================================================================
309 vtkImplicitFunction* VISU_PlanesWidget::ImplicitFunction()
310 {
311   return this->myImplicitFunction;
312 }
313 //==================================================================
314 // function: SetDistance
315 // purpose :
316 //==================================================================
317 void 
318 VISU_PlanesWidget
319 ::SetDistance(const vtkFloatingPointType theDistance)
320 {
321   if( theDistance <= 0.0 || theDistance == myDistance )
322     return;
323
324   myDistance=theDistance;
325   //
326   vtkFloatingPointType *origin, *normal, oNew[3], aN2[3]; 
327   origin = myPlane1->GetOrigin();
328   normal = myPlane1->GetNormal();
329   vtkMath::Normalize(normal);
330   oNew[0] = origin[0] + myDistance*normal[0];
331   oNew[1] = origin[1] + myDistance*normal[1];
332   oNew[2] = origin[2] + myDistance*normal[2];
333   myPlane2->SetOrigin(oNew);
334   aN2[0] = -normal[0];
335   aN2[1] = -normal[1];
336   aN2[2] = -normal[2];
337   myPlane2->SetNormal(aN2);
338 }
339 //==================================================================
340 // function: Distance
341 // purpose :
342 //==================================================================
343 vtkFloatingPointType
344 VISU_PlanesWidget
345 ::Distance() const
346 {
347   return myDistance;
348 }
349 //==================================================================
350 // function: SetEnabled
351 // purpose :
352 //==================================================================
353 void VISU_PlanesWidget::SetEnabled(int enabling)
354 {
355   if ( ! this->Interactor )    {
356     vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
357     return;
358   }
359
360   if ( enabling ) {//------------------------------------------------------------
361     vtkDebugMacro(<<"Enabling plane widget");
362     
363     if ( this->Enabled ){ //already enabled, just return
364       return;
365     }
366     
367     if ( ! this->CurrentRenderer ){
368       this->CurrentRenderer = this->Interactor->FindPokedRenderer(
369         this->Interactor->GetLastEventPosition()[0],
370         this->Interactor->GetLastEventPosition()[1]);
371       if (this->CurrentRenderer == NULL)        {
372         return;
373       }
374     }
375     //
376     vtkCamera *pCamera=CurrentRenderer->GetActiveCamera();
377     pCamera->SetParallelProjection(1);
378     //
379     this->myImplicitFunction->AddFunction(myPlane1);
380     this->myImplicitFunction->AddFunction(this->myPlane2);
381
382     this->Enabled = 1;
383
384     // listen for the following events
385     vtkRenderWindowInteractor *i = this->Interactor;
386     if( this->HandleMoveEvent )    {
387       i->AddObserver(vtkCommand::MouseMoveEvent, 
388                      this->EventCallbackCommand, 
389                      this->Priority);
390     }
391     if( this->HandleLeftButtonEvent )    {
392       i->AddObserver(vtkCommand::LeftButtonPressEvent, 
393                      this->EventCallbackCommand, 
394                      this->Priority);
395       i->AddObserver(vtkCommand::LeftButtonReleaseEvent, 
396                      this->EventCallbackCommand, 
397                      this->Priority);
398     }
399     if( this->HandleMiddleButtonEvent )    {
400       i->AddObserver(vtkCommand::MiddleButtonPressEvent, 
401                      this->EventCallbackCommand, 
402                      this->Priority);
403       i->AddObserver(vtkCommand::MiddleButtonReleaseEvent, 
404                      this->EventCallbackCommand, 
405                      this->Priority);
406     }
407     if( this->HandleRightButtonEvent )    {
408       i->AddObserver(vtkCommand::RightButtonPressEvent, 
409                      this->EventCallbackCommand, 
410                      this->Priority);
411       i->AddObserver(vtkCommand::RightButtonReleaseEvent, 
412                      this->EventCallbackCommand, 
413                      this->Priority);
414     }
415     // add the outline
416     this->CurrentRenderer->AddActor(this->myOutlineActor);
417     this->myOutlineActor->SetProperty(this->OutlineProperty);
418
419     // add the edges
420     this->CurrentRenderer->AddActor(this->myEdgesActor1);
421     this->CurrentRenderer->AddActor(myEdgesActor2);
422
423     this->myOutlineActor->SetProperty(this->EdgesProperty);
424
425     // add the normal vector
426     this->CurrentRenderer->AddActor(this->LineActor);
427     this->LineActor->SetProperty(this->NormalProperty);
428     this->CurrentRenderer->AddActor(this->ConeActor);
429     this->ConeActor->SetProperty(this->NormalProperty);
430
431     this->CurrentRenderer->AddActor(this->LineActor2);
432     this->LineActor2->SetProperty(this->NormalProperty);
433     this->CurrentRenderer->AddActor(this->ConeActor2);
434     this->ConeActor2->SetProperty(this->NormalProperty);
435     
436     // add the origin handle
437     this->CurrentRenderer->AddActor(this->SphereActor);
438     this->SphereActor->SetProperty(this->NormalProperty);
439
440     // add the plane (if desired)
441     if ( this->myDrawPlane )      {
442       this->CurrentRenderer->AddActor(this->myCutActor1);
443       this->CurrentRenderer->AddActor(this->myCutActor2);
444     }
445     this->myCutActor1->SetProperty(this->PlaneProperty);
446     myCutActor2->SetProperty(this->PlaneProperty);
447     
448     this->UpdateRepresentation();
449     //this->SizeHandles();
450     this->InvokeEvent(vtkCommand::EnableEvent,NULL);
451   }
452   
453   else {//disabling----------------------------------------------------------
454     vtkDebugMacro(<<"Disabling plane widget");
455
456     if ( ! this->Enabled ) {//already disabled, just return
457       return;
458     }
459     
460     if(vtkImplicitFunctionCollection* aFunction = this->myImplicitFunction->GetFunction()){
461       aFunction->RemoveAllItems();
462       this->myImplicitFunction->Modified(); // VTK bug
463     }
464
465     this->Enabled = 0;
466
467     // don't listen for events any more
468     this->Interactor->RemoveObserver(this->EventCallbackCommand);
469
470     // turn off the various actors
471     this->CurrentRenderer->RemoveActor(this->myOutlineActor);
472     this->CurrentRenderer->RemoveActor(this->myEdgesActor1);
473     this->CurrentRenderer->RemoveActor(myEdgesActor2);
474     this->CurrentRenderer->RemoveActor(this->LineActor);
475     this->CurrentRenderer->RemoveActor(this->ConeActor);
476     this->CurrentRenderer->RemoveActor(this->LineActor2);
477     this->CurrentRenderer->RemoveActor(this->ConeActor2);
478     this->CurrentRenderer->RemoveActor(this->SphereActor);
479     this->CurrentRenderer->RemoveActor(this->myCutActor1);
480     this->CurrentRenderer->RemoveActor(myCutActor2);
481
482     this->InvokeEvent(vtkCommand::DisableEvent,NULL);
483     this->CurrentRenderer = NULL;
484   }
485   
486   this->Interactor->Render();
487 }
488 //==================================================================
489 // function: ProcessEvents
490 // purpose :
491 //==================================================================
492 void VISU_PlanesWidget::ProcessEvents(vtkObject* vtkNotUsed(object), 
493                                                 unsigned long event,
494                                                 void* clientdata, 
495                                                 void* vtkNotUsed(calldata))
496 {
497   VISU_PlanesWidget* self = 
498     reinterpret_cast<VISU_PlanesWidget *>( clientdata );
499
500   //okay, let's do the right thing
501   switch(event)
502     {
503     case vtkCommand::LeftButtonPressEvent:
504       self->OnLeftButtonDown();
505       break;
506     case vtkCommand::LeftButtonReleaseEvent:
507       self->OnLeftButtonUp();
508       break;
509     case vtkCommand::MiddleButtonPressEvent:
510       self->OnMiddleButtonDown();
511       break;
512     case vtkCommand::MiddleButtonReleaseEvent:
513       self->OnMiddleButtonUp();
514       break;
515     case vtkCommand::RightButtonPressEvent:
516       self->OnRightButtonDown();
517       break;
518     case vtkCommand::RightButtonReleaseEvent:
519       self->OnRightButtonUp();
520       break;
521     case vtkCommand::MouseMoveEvent:
522       self->OnMouseMove();
523       break;
524     default:
525       break;
526     }
527 }
528 //==================================================================
529 // function: HighlightNormal
530 // purpose :
531 //==================================================================
532 void VISU_PlanesWidget::HighlightNormal(int highlight)
533 {
534   if ( highlight ) {
535     this->LineActor->SetProperty(this->SelectedNormalProperty);
536     this->ConeActor->SetProperty(this->SelectedNormalProperty);
537     this->LineActor2->SetProperty(this->SelectedNormalProperty);
538     this->ConeActor2->SetProperty(this->SelectedNormalProperty);
539     this->SphereActor->SetProperty(this->SelectedNormalProperty);
540     }
541   else
542     {
543     this->LineActor->SetProperty(this->NormalProperty);
544     this->ConeActor->SetProperty(this->NormalProperty);
545     this->LineActor2->SetProperty(this->NormalProperty);
546     this->ConeActor2->SetProperty(this->NormalProperty);
547     this->SphereActor->SetProperty(this->NormalProperty);
548     }
549 }
550 //==================================================================
551 // function: HighlightPlane
552 // purpose :
553 //==================================================================
554 void VISU_PlanesWidget::HighlightPlane(int highlight)
555 {
556   if ( highlight )    {
557     this->myCutActor1->SetProperty(this->SelectedPlaneProperty);
558     myCutActor2->SetProperty(this->SelectedPlaneProperty);
559   }
560   else    {
561     this->myCutActor1->SetProperty(this->PlaneProperty);
562     myCutActor2->SetProperty(this->PlaneProperty);
563   }
564 }
565 //==================================================================
566 // function: HighlightOutline
567 // purpose :
568 //==================================================================
569 void VISU_PlanesWidget::HighlightOutline(int highlight)
570 {
571   if (highlight)    {
572     this->myOutlineActor->SetProperty(this->SelectedOutlineProperty);
573   }
574   else    {
575     this->myOutlineActor->SetProperty(this->OutlineProperty);
576   }
577 }
578 //==================================================================
579 // function: OnLeftButtonDown
580 // purpose :
581 //==================================================================
582 void VISU_PlanesWidget::OnLeftButtonDown()
583 {
584   // We're only here if we are enabled
585   int X = this->Interactor->GetEventPosition()[0];
586   int Y = this->Interactor->GetEventPosition()[1];
587   //
588   // Okay, we can process this. See if we've picked anything.
589   // Make sure it's in the activated renderer
590   vtkRenderer *ren = this->Interactor->FindPokedRenderer(X,Y);
591   if ( ren != this->CurrentRenderer )    {
592     this->State = VISU_PlanesWidget::Outside;
593     return;
594   }
595   
596   vtkAssemblyPath *path;
597   this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
598   path = this->Picker->GetPath();
599
600   if ( path == NULL ) {//not picking this widget
601     this->HighlightPlane(0);
602     this->HighlightNormal(0);
603     this->HighlightOutline(0);
604     this->State = VISU_PlanesWidget::Outside;
605     return;
606   }
607
608   vtkProp *prop = path->GetFirstNode()->GetViewProp();
609   this->ValidPick = 1;
610   this->Picker->GetPickPosition(this->LastPickPosition);
611   //
612   if ( prop == this->ConeActor || prop == this->LineActor ||
613        prop == this->ConeActor2 || prop == this->LineActor2 )  {
614     this->HighlightPlane(1);
615     this->HighlightNormal(1);
616     this->State = VISU_PlanesWidget::Rotating;
617   }
618   else if ( prop == this->myCutActor1)    {
619     this->HighlightPlane(1);
620     this->State = VISU_PlanesWidget::Pushing;
621   }
622   else if ( prop == this->SphereActor )    {
623     this->HighlightNormal(1);
624     this->State = VISU_PlanesWidget::MovingOrigin;
625   }
626   else if (prop == myCutActor2)    {
627     this->HighlightPlane(1);
628     this->State = VISU_PlanesWidget::ChangeDistance;
629   }
630   else    {
631     if ( this->OutlineTranslation )      {
632       this->HighlightOutline(1);
633       this->State = VISU_PlanesWidget::MovingOutline;
634     }
635   }
636   
637   this->EventCallbackCommand->SetAbortFlag(1);
638   this->StartInteraction();
639   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
640   this->Interactor->Render();
641 }
642 //==================================================================
643 // function: OnLeftButtonUp
644 // purpose :
645 //==================================================================
646 void VISU_PlanesWidget::OnLeftButtonUp()
647 {
648   if ( this->State == VISU_PlanesWidget::Outside )    {
649     return;
650   }
651
652   this->State = VISU_PlanesWidget::Start;
653   this->HighlightPlane(0);
654   this->HighlightOutline(0);
655   this->HighlightNormal(0);
656   //this->SizeHandles();
657   
658   this->EventCallbackCommand->SetAbortFlag(1);
659   this->EndInteraction();
660   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
661   this->Interactor->Render();
662 }
663 //==================================================================
664 // function: OnMiddleButtonDown
665 // purpose :
666 //==================================================================
667 void VISU_PlanesWidget::OnMiddleButtonDown()
668 {
669   int X = this->Interactor->GetEventPosition()[0];
670   int Y = this->Interactor->GetEventPosition()[1];
671
672   // Okay, we can process this. See if we've picked anything.
673   // Make sure it's in the activated renderer
674   vtkRenderer *ren = this->Interactor->FindPokedRenderer(X,Y);
675   if ( ren != this->CurrentRenderer )    {
676     this->State = VISU_PlanesWidget::Outside;
677     return;
678   }
679   
680   // Okay, we can process this.
681   vtkAssemblyPath *path;
682   this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
683   path = this->Picker->GetPath();
684   
685   if ( path == NULL ) {//nothing picked
686     this->State = VISU_PlanesWidget::Outside;
687     return;
688   }
689
690   this->ValidPick = 1;
691   this->Picker->GetPickPosition(this->LastPickPosition);
692   this->State = VISU_PlanesWidget::MovingPlane;
693   this->HighlightNormal(1);
694   this->HighlightPlane(1);
695   
696   this->EventCallbackCommand->SetAbortFlag(1);
697   this->StartInteraction();
698   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
699   this->Interactor->Render();
700 }
701 //==================================================================
702 // function: OnMiddleButtonUp
703 // purpose :
704 //==================================================================
705 void VISU_PlanesWidget::OnMiddleButtonUp()
706 {
707   if ( this->State == VISU_PlanesWidget::Outside )    {
708     return;
709   }
710
711   this->State = VISU_PlanesWidget::Start;
712   this->HighlightPlane(0);
713   this->HighlightOutline(0);
714   this->HighlightNormal(0);
715   //this->SizeHandles();
716   
717   this->EventCallbackCommand->SetAbortFlag(1);
718   this->EndInteraction();
719   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
720   this->Interactor->Render();
721 }
722 //==================================================================
723 // function: OnRightButtonDown
724 // purpose :
725 //==================================================================
726 void VISU_PlanesWidget::OnRightButtonDown()
727 {
728   this->State = VISU_PlanesWidget::Scaling;
729
730   int X = this->Interactor->GetEventPosition()[0];
731   int Y = this->Interactor->GetEventPosition()[1];
732
733   // Okay, we can process this. See if we've picked anything.
734   // Make sure it's in the activated renderer
735   vtkRenderer *ren = this->Interactor->FindPokedRenderer(X,Y);
736   if ( ren != this->CurrentRenderer )    {
737     this->State = VISU_PlanesWidget::Outside;
738     return;
739   }
740   
741   // Okay, we can process this. Try to pick handles first;
742   // if no handles picked, then pick the bounding box.
743   vtkAssemblyPath *path;
744   this->Picker->Pick(X,Y,0.0,this->CurrentRenderer);
745   path = this->Picker->GetPath();
746   if ( path == NULL ){ //nothing picked
747     this->State = VISU_PlanesWidget::Outside;
748     return;
749   }
750   
751   this->ValidPick = 1;
752   this->Picker->GetPickPosition(this->LastPickPosition);
753   this->HighlightPlane(1);
754   this->HighlightOutline(1);
755   this->HighlightNormal(1);
756   
757   this->EventCallbackCommand->SetAbortFlag(1);
758   this->StartInteraction();
759   this->InvokeEvent(vtkCommand::StartInteractionEvent,NULL);
760   this->Interactor->Render();
761 }
762 //==================================================================
763 // function: OnRightButtonUp
764 // purpose :
765 //==================================================================
766 void VISU_PlanesWidget::OnRightButtonUp()
767 {
768   if ( this->State == VISU_PlanesWidget::Outside )    {
769     return;
770   }
771   
772   this->State = VISU_PlanesWidget::Start;
773   this->HighlightPlane(0);
774   this->HighlightOutline(0);
775   this->HighlightNormal(0);
776   //this->SizeHandles();
777   
778   this->EventCallbackCommand->SetAbortFlag(1);
779   this->EndInteraction();
780   this->InvokeEvent(vtkCommand::EndInteractionEvent,NULL);
781   this->Interactor->Render();
782 }
783 //==================================================================
784 // function: OnMouseMove
785 // purpose :
786 //==================================================================
787 void VISU_PlanesWidget::OnMouseMove()
788 {
789   //this->SizeHandles();
790
791   // See whether we're active
792   if ( this->State == VISU_PlanesWidget::Outside || 
793        this->State == VISU_PlanesWidget::Start )    {
794     return;
795   }
796   
797   int X = this->Interactor->GetEventPosition()[0];
798   int Y = this->Interactor->GetEventPosition()[1];
799
800   // Do different things depending on state
801   // Calculations everybody does
802   double focalPoint[4], pickPoint[4], prevPickPoint[4];
803   double z, vpn[3];
804
805   vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
806   if ( !camera ) {
807     return;
808   }
809
810   // Compute the two points defining the motion vector
811   this->ComputeWorldToDisplay(this->LastPickPosition[0], this->LastPickPosition[1],
812                               this->LastPickPosition[2], focalPoint);
813   z = focalPoint[2];
814   this->ComputeDisplayToWorld(double(this->Interactor->GetLastEventPosition()[0]),
815                               double(this->Interactor->GetLastEventPosition()[1]),
816                               z, prevPickPoint);
817   this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint);
818
819   // Process the motion
820   if ( this->State == VISU_PlanesWidget::MovingPlane )    {
821     //this->TranslatePlane(prevPickPoint, pickPoint);
822     //printf(" TranslatePlane\n");
823   }
824   else if ( this->State == VISU_PlanesWidget::MovingOutline )    {
825     //this->TranslateOutline(prevPickPoint, pickPoint);
826     //printf(" TranslateOutline\n");
827   }
828   else if ( this->State == VISU_PlanesWidget::MovingOrigin )    {
829     this->TranslateOrigin(prevPickPoint, pickPoint);
830     //printf(" TranslateOrigin\n");
831   }
832   else if ( this->State == VISU_PlanesWidget::Pushing )    {
833     this->Push(prevPickPoint, pickPoint);
834    // printf(" Push\n");
835   }
836   else if ( this->State == VISU_PlanesWidget::Scaling )    {
837     //this->Scale(prevPickPoint, pickPoint, X, Y);
838     //printf(" Scale\n");
839   }
840   else if ( this->State == VISU_PlanesWidget::Rotating )    {
841     camera->GetViewPlaneNormal(vpn);
842     this->Rotate(X, Y, prevPickPoint, pickPoint, vpn);
843     //printf(" Rotate\n");
844   }
845   else if ( this->State == VISU_PlanesWidget::ChangeDistance )    {
846     this->PushDistance(prevPickPoint, pickPoint);
847     //printf(" PushDistance\n");
848   }
849   // Interact, if desired
850   this->EventCallbackCommand->SetAbortFlag(1);
851   this->InvokeEvent(vtkCommand::InteractionEvent,NULL);
852   
853   this->Interactor->Render();
854 }
855 //==================================================================
856 // function: Push
857 // purpose :
858 //==================================================================
859 void VISU_PlanesWidget::Push(double *p1, double *p2)
860 {
861   //Get the motion vector
862   int i;
863   vtkFloatingPointType v[3];
864   //
865   for (i=0; i<3; ++i){  
866     v[i] = p2[i] - p1[i];
867   }
868   //
869   vtkFloatingPointType aOr1[3], aNr1[3], aNr2[3], aD, z1;
870   //
871   myPlane1->GetOrigin(aOr1);
872   myPlane1->GetNormal(aNr1);
873   myPlane2->GetNormal(aNr2);
874   //
875   aD=vtkMath::Dot(v, aNr2);
876   z1 = aOr1[2]+aD*aNr2[2];
877   if( z1 <= myBox->GetOrigin()[2] ){
878     return;
879   }
880   //  
881   aD=vtkMath::Dot(v, aNr1);
882   for (i=0; i < 3; ++i) {
883     aOr1[i]=aOr1[i]+aD*aNr1[i];
884   }
885   SetOriginInternal(aOr1);
886   this->UpdateRepresentation();
887 }
888 //==================================================================
889 // function: TranslateOrigin
890 // purpose :
891 //==================================================================
892 void VISU_PlanesWidget::TranslateOrigin(double *p1, double *p2)
893 {
894   //Get the motion vector
895   int i;
896   double v[3];
897   //
898   for (i=0; i<3; ++i){  
899     v[i] = p2[i] - p1[i];
900   }
901   //
902   //Add to the current point, project back down onto plane
903   vtkFloatingPointType *o = myPlane1->GetOrigin();
904   vtkFloatingPointType *n = myPlane1->GetNormal();
905   vtkFloatingPointType newOrigin[3];
906   //
907   for (i=0; i<3; ++i){
908     newOrigin[i]=o[i] + v[i];
909   }
910   vtkPlane::ProjectPoint(newOrigin, o, n, newOrigin);
911   SetOriginInternal(newOrigin); 
912   this->UpdateRepresentation();
913 }
914 //==================================================================
915 // function: SetOriginInternal
916 // purpose : Set the origin of the plane.(for Internal calls)
917 //==================================================================
918 void VISU_PlanesWidget::SetOriginInternal(vtkFloatingPointType x[3]) 
919 {
920   vtkFloatingPointType *bounds = this->myOutline->GetOutput()->GetBounds();
921   int i, j;
922   for (i=0; i<3; ++i)    {
923     j=2*i;
924     if ( x[i] < bounds[j] ) {
925       x[i] = bounds[j];
926     }
927     else if ( x[i] > bounds[j+1] ) {
928       x[i] = bounds[j+1];
929     }
930   }
931   //
932   bool bFlag;
933   vtkFloatingPointType aOr2[3], aNr2[3], aNr1[3];
934   vtkPlane *pPx;
935   //
936   myPlane1->GetNormal(aNr1);
937   myPlane2->GetNormal(aNr2);
938   for (i=0; i<3; ++i)    {
939     aOr2[i]=x[i]+myDistance*aNr1[i];
940   }
941   pPx=vtkPlane::New();
942   pPx->SetOrigin(aOr2);
943   pPx->SetNormal(aNr2);
944   bFlag=IsValidPlane2Position(pPx, myBox);
945   if (bFlag){
946     myPlane1->SetOrigin(x);
947     myPlane2->SetOrigin(aOr2);
948   }
949   pPx->Delete();
950 }
951 //==================================================================
952 // function: Rotate
953 // purpose :
954 //==================================================================
955 void VISU_PlanesWidget::Rotate(int X, int Y, 
956                                          double *p1, double *p2, 
957                                          double *vpn)
958 {
959   double v[3];    //vector of motion
960   double axis[3]; //axis of rotation
961   double theta;   //rotation angle
962   int i;
963
964   // mouse motion vector in world space
965   for (i=0; i<3; ++i){ 
966     v[i] = p2[i] - p1[i];
967   }
968   //
969   vtkFloatingPointType *origin = myPlane1->GetOrigin();
970   vtkFloatingPointType *normal = myPlane1->GetNormal();
971
972   // Create axis of rotation and angle of rotation
973   vtkMath::Cross(vpn,v,axis);
974   if ( vtkMath::Normalize(axis) == 0.0 )    {
975     return;
976   }
977
978   int *size = this->CurrentRenderer->GetSize();
979   double l2 = (X-this->Interactor->GetLastEventPosition()[0])*
980     (X-this->Interactor->GetLastEventPosition()[0]) + 
981     (Y-this->Interactor->GetLastEventPosition()[1])*
982     (Y-this->Interactor->GetLastEventPosition()[1]);
983   theta = 360.0 * sqrt(l2/((double)size[0]*size[0]+size[1]*size[1]));
984
985   //Manipulate the transform to reflect the rotation
986   this->Transform->Identity();
987   this->Transform->Translate(origin[0],origin[1],origin[2]);
988   this->Transform->RotateWXYZ(theta,axis);
989   this->Transform->Translate(-origin[0],-origin[1],-origin[2]);
990
991   //Set the new normal
992   vtkFloatingPointType nNew[3], aN2[3], oNew[3];
993   this->Transform->TransformNormal(normal,nNew);
994   //
995   for (i=0; i<3; ++i){  
996     aN2[i] = -nNew[i];
997   }
998   vtkMath::Normalize(nNew);
999   for (i=0; i<3; ++i){  
1000     oNew[i] = origin[i] + myDistance*nNew[i];
1001   }
1002   //
1003   vtkPlane *pPx=vtkPlane::New();
1004   pPx->SetNormal(aN2); 
1005   pPx->SetOrigin(oNew);
1006   //
1007   bool bFlag=IsValidPlane2Position(pPx, myBox);
1008   if (bFlag) {
1009     myPlane1->SetNormal(nNew);
1010     this->myPlane2->SetNormal(aN2); 
1011     this->myPlane2->SetOrigin(oNew);
1012   } 
1013   pPx->Delete();
1014   this->UpdateRepresentation();
1015 }
1016 //==================================================================
1017 // function: PushDistance
1018 // purpose :
1019 //==================================================================
1020 void VISU_PlanesWidget::PushDistance(double *p1, double *p2)
1021 {
1022   int i;
1023   vtkFloatingPointType v[3],  *anOrigin1, *aN1, *anOrigin2, *aN2, aD;
1024   //Get the motion vector
1025   for (i=0; i<3; ++i){ 
1026     v[i] = p2[i] - p1[i];
1027   }
1028   //
1029   anOrigin1 = myPlane1->GetOrigin();
1030   aN1 = myPlane1->GetNormal();
1031   anOrigin2 = myPlane2->GetOrigin();
1032   aN2 = myPlane2->GetNormal();
1033
1034   vtkMath::Normalize(aN1);
1035
1036   vtkFloatingPointType origin[3];
1037   double distance = vtkMath::Dot( v, aN2 );
1038   for(i=0; i<3; ++i) {
1039     origin[i] = anOrigin2[i] + distance * aN2[i];
1040   }
1041   vtkFloatingPointType d = DistanceToPlane(origin, aN1, anOrigin1);
1042   if( d <= 0.0 )
1043     return;
1044   //
1045   bool bFlag;
1046   vtkFloatingPointType aOr2[3], aNr2[3];
1047   vtkPlane *pPx;
1048   //
1049   myPlane2->GetOrigin(aOr2);
1050   myPlane2->GetNormal(aNr2);
1051   pPx=vtkPlane::New();
1052   pPx->SetNormal(aNr2);
1053   aD=vtkMath::Dot(v, aNr2);
1054   for (i=0; i < 3; ++i) {
1055     aOr2[i]=aOr2[i]+aD*aNr2[i];
1056   }
1057   pPx->SetOrigin(aOr2);
1058   bFlag=IsValidPlane2Position(pPx, myBox);
1059   if(bFlag) {
1060     myPlane2->SetOrigin(aOr2);
1061     myPlane2->Modified();
1062     aD=DistanceToPlane(aOr2, aN1, anOrigin1);
1063     //
1064     myDistance=aD;
1065   }
1066   pPx->Delete();
1067   this->UpdateRepresentation();
1068 }
1069
1070 //==================================================================
1071 // function: TranslatePlane
1072 // purpose : Loop through all points and translate them
1073 //==================================================================
1074 void VISU_PlanesWidget::TranslatePlane(double *p1, double *p2)
1075 {
1076   //Get the motion vector
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   //Translate the plane
1083   vtkFloatingPointType oNew[3];
1084   vtkFloatingPointType *origin = myPlane1->GetOrigin();
1085   oNew[0] = origin[0] + v[0];
1086   oNew[1] = origin[1] + v[1];
1087   oNew[2] = origin[2] + v[2];
1088   myPlane1->SetOrigin(oNew);
1089   
1090   origin = this->myPlane2->GetOrigin();
1091   oNew[0] = origin[0] + v[0];
1092   oNew[1] = origin[1] + v[1];
1093   oNew[2] = origin[2] + v[2];
1094   this->myPlane2->SetOrigin(oNew);
1095
1096   this->UpdateRepresentation();
1097 }
1098 //==================================================================
1099 // function: TranslateOutline
1100 // purpose :Loop through all points and translate them
1101 //==================================================================
1102 void VISU_PlanesWidget::TranslateOutline(double *p1, double *p2)
1103 {
1104   //Get the motion vector
1105   double v[3];
1106   v[0] = p2[0] - p1[0];
1107   v[1] = p2[1] - p1[1];
1108   v[2] = p2[2] - p1[2];
1109   
1110   //Translate the bounding box
1111   vtkFloatingPointType *origin = myBox->GetOrigin();
1112   vtkFloatingPointType oNew[3];
1113   oNew[0] = origin[0] + v[0];
1114   oNew[1] = origin[1] + v[1];
1115   oNew[2] = origin[2] + v[2];
1116   myBox->SetOrigin(oNew);
1117
1118   //Translate the plane
1119   origin = myPlane1->GetOrigin();
1120   oNew[0] = origin[0] + v[0];
1121   oNew[1] = origin[1] + v[1];
1122   oNew[2] = origin[2] + v[2];
1123   myPlane1->SetOrigin(oNew);
1124
1125   origin = this->myPlane2->GetOrigin();
1126   oNew[0] = origin[0] + v[0];
1127   oNew[1] = origin[1] + v[1];
1128   oNew[2] = origin[2] + v[2];
1129   this->myPlane2->SetOrigin(oNew);
1130
1131   this->UpdateRepresentation();
1132 }
1133
1134 //==================================================================
1135 // function: Scale
1136 // purpose :
1137 //==================================================================
1138 void VISU_PlanesWidget::Scale(double *p1, double *p2, 
1139                                         int vtkNotUsed(X), int Y)
1140 {
1141   //Get the motion vector
1142   double v[3];
1143   v[0] = p2[0] - p1[0];
1144   v[1] = p2[1] - p1[1];
1145   v[2] = p2[2] - p1[2];
1146
1147   //int res = this->PlaneSource->GetXResolution();
1148   vtkFloatingPointType *o = myPlane1->GetOrigin();
1149
1150   // Compute the scale factor
1151   vtkFloatingPointType sf = vtkMath::Norm(v) / this->myOutline->GetOutput()->GetLength();
1152   if ( Y > this->Interactor->GetLastEventPosition()[1] )    {
1153     sf = 1.0 + sf;
1154   }
1155   else    {
1156     sf = 1.0 - sf;
1157   }
1158   
1159   this->Transform->Identity();
1160   this->Transform->Translate(o[0],o[1],o[2]);
1161   this->Transform->Scale(sf,sf,sf);
1162   this->Transform->Translate(-o[0],-o[1],-o[2]);
1163
1164   vtkFloatingPointType *origin = myBox->GetOrigin();
1165   vtkFloatingPointType *spacing = myBox->GetSpacing();
1166   vtkFloatingPointType oNew[3], p[3], pNew[3];
1167   p[0] = origin[0] + spacing[0];
1168   p[1] = origin[1] + spacing[1];
1169   p[2] = origin[2] + spacing[2];
1170
1171   this->Transform->TransformPoint(origin,oNew);
1172   this->Transform->TransformPoint(p,pNew);
1173
1174   myBox->SetOrigin(oNew);
1175   myBox->SetSpacing( (pNew[0]-oNew[0]), (pNew[1]-oNew[1]), (pNew[2]-oNew[2]) );
1176
1177   this->UpdateRepresentation();
1178 }
1179
1180
1181
1182 //==================================================================
1183 // function: CreateDefaultProperties
1184 // purpose :
1185 //==================================================================
1186 void VISU_PlanesWidget::CreateDefaultProperties()
1187 {
1188   // Normal properties
1189   this->NormalProperty = vtkProperty::New();
1190   this->NormalProperty->SetColor(1,1,1);
1191   this->NormalProperty->SetLineWidth(2);
1192
1193   this->SelectedNormalProperty = vtkProperty::New();
1194   this->SelectedNormalProperty->SetColor(1,0,0);
1195   this->NormalProperty->SetLineWidth(2);
1196
1197   // Plane properties
1198   this->PlaneProperty = vtkProperty::New();
1199   this->PlaneProperty->SetAmbient(1.0);
1200   this->PlaneProperty->SetAmbientColor(1.0,1.0,1.0);
1201
1202   this->SelectedPlaneProperty = vtkProperty::New();
1203   this->SelectedPlaneProperty->SetAmbient(1.0);
1204   this->SelectedPlaneProperty->SetAmbientColor(0.0,1.0,0.0);
1205   this->SelectedPlaneProperty->SetOpacity(0.25);
1206
1207   // Outline properties
1208   this->OutlineProperty = vtkProperty::New();
1209   this->OutlineProperty->SetAmbient(1.0);
1210   this->OutlineProperty->SetAmbientColor(1.0,1.0,1.0);
1211
1212   this->SelectedOutlineProperty = vtkProperty::New();
1213   this->SelectedOutlineProperty->SetAmbient(1.0);
1214   this->SelectedOutlineProperty->SetAmbientColor(0.0,1.0,0.0);
1215
1216   // Edge property
1217   this->EdgesProperty = vtkProperty::New();
1218   this->EdgesProperty->SetAmbient(1.0);
1219   this->EdgesProperty->SetAmbientColor(1.0,1.0,1.0);
1220 }
1221 //==================================================================
1222 // function: InitialPlaceWidget
1223 // purpose :
1224 //==================================================================
1225 void VISU_PlanesWidget::InitialPlaceWidget(vtkFloatingPointType bds[6])
1226 {
1227   vtkFloatingPointType bounds[6], origin[3];
1228
1229   PlaceWidget(bds);
1230   //
1231   this->AdjustBounds(bds, bounds, origin);
1232   this->SetOrigin((bounds[1]+bounds[0])/2.0,
1233                   (bounds[3]+bounds[2])/2.0,
1234                   (bounds[5]+bounds[4])/2.0);
1235
1236   static vtkFloatingPointType DIST_COEFF = 0.1;
1237   SetDistance(this->InitialLength*DIST_COEFF);
1238   //
1239   this->UpdateRepresentation();
1240 }
1241 //==================================================================
1242 // function: PlaceWidget
1243 // purpose :
1244 //==================================================================
1245 void VISU_PlanesWidget::PlaceWidget(vtkFloatingPointType bds[6])
1246 {
1247   int i;
1248   vtkFloatingPointType bounds[6], origin[3];
1249
1250   this->AdjustBounds(bds, bounds, origin);
1251
1252   // Set up the bounding box
1253   myBox->SetOrigin(bounds[0],bounds[2],bounds[4]);
1254   myBox->SetSpacing((bounds[1]-bounds[0]),(bounds[3]-bounds[2]),
1255                         (bounds[5]-bounds[4]));
1256   this->myOutline->Update();
1257
1258   if (this->Input || this->Prop3D)    {
1259     this->LineSource->SetPoint1(myPlane1->GetOrigin());
1260     if ( this->NormalToYAxis )      {
1261       myPlane1->SetNormal(0,1,0);
1262       myPlane2->SetNormal(0,-1,0);
1263       this->LineSource->SetPoint2(0,1,0);
1264     }
1265     else if ( this->NormalToZAxis )      {
1266       myPlane1->SetNormal(0,0,1);
1267       myPlane2->SetNormal(0,0,-1);
1268       this->LineSource->SetPoint2(0,0,1);
1269     }
1270     else{ //default or x-normal
1271       myPlane1->SetNormal(1,0,0);
1272       myPlane2->SetNormal(-1,0,0);
1273       this->LineSource->SetPoint2(1,0,0);
1274     }
1275   }
1276   
1277   for (i=0; i<6; i++)    {
1278     this->InitialBounds[i] = bounds[i];
1279   }
1280
1281   this->InitialLength = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
1282                              (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
1283                              (bounds[5]-bounds[4])*(bounds[5]-bounds[4]));
1284
1285   this->UpdateRepresentation();
1286 }
1287 //==================================================================
1288 // function: SetOrigin
1289 // purpose :Set the origin of the plane.(for external calls)
1290 //==================================================================
1291 void VISU_PlanesWidget::SetOrigin(vtkFloatingPointType x, vtkFloatingPointType y, vtkFloatingPointType z) 
1292 {
1293   vtkFloatingPointType origin[3];
1294   origin[0] = x;
1295   origin[1] = y;
1296   origin[2] = z;
1297   this->SetOrigin(origin);
1298 }
1299 //==================================================================
1300 // function: SetOrigin 
1301 // purpose : Set the origin of the plane.(for external calls)
1302 //==================================================================
1303 void VISU_PlanesWidget::SetOrigin(vtkFloatingPointType x[3])
1304 {
1305   vtkFloatingPointType *bounds = this->myOutline->GetOutput()->GetBounds();
1306   for (int i=0; i<3; i++)    {
1307     if ( x[i] < bounds[2*i] )      {
1308       x[i] = bounds[2*i];
1309     }
1310     else if ( x[i] > bounds[2*i+1] )      {
1311       x[i] = bounds[2*i+1];
1312     }
1313   }
1314   myPlane1->SetOrigin(x);
1315   vtkFloatingPointType *origin, *normal, oNew[3];
1316   origin = myPlane1->GetOrigin();
1317   normal = myPlane1->GetNormal();
1318   vtkMath::Normalize(normal);
1319   oNew[0] = origin[0] + myDistance*normal[0];
1320   oNew[1] = origin[1] + myDistance*normal[1];
1321   oNew[2] = origin[2] + myDistance*normal[2];
1322   this->myPlane2->SetOrigin(oNew);
1323   this->UpdateRepresentation();
1324 }
1325 //==================================================================
1326 // function: GetOrigin
1327 // purpose :Get the origin of the plane.
1328 //==================================================================
1329 vtkFloatingPointType* VISU_PlanesWidget::GetOrigin() 
1330 {
1331   return myPlane1->GetOrigin();
1332 }
1333
1334 void VISU_PlanesWidget::GetOrigin(vtkFloatingPointType xyz[3]) 
1335 {
1336   myPlane1->GetOrigin(xyz);
1337 }
1338 //==================================================================
1339 // function: SetNormal
1340 // purpose :Set the normal to the plane.
1341 //==================================================================
1342 void VISU_PlanesWidget::SetNormal(vtkFloatingPointType x, vtkFloatingPointType y, vtkFloatingPointType z) 
1343 {
1344   vtkFloatingPointType n[3];
1345   n[0] = x;
1346   n[1] = y;
1347   n[2] = z;
1348   vtkMath::Normalize(n);
1349   myPlane1->SetNormal(n);
1350   n[0] =- x;
1351   n[1] =- y;
1352   n[2] =- z;
1353   this->myPlane2->SetNormal(n);
1354
1355   this->UpdateRepresentation();
1356 }
1357
1358 //==================================================================
1359 // function: SetNormal
1360 // purpose :Set the normal to the plane.
1361 //==================================================================
1362 void VISU_PlanesWidget::SetNormal(vtkFloatingPointType n[3]) 
1363 {
1364   this->SetNormal(n[0], n[1], n[2]);
1365 }
1366 //==================================================================
1367 // function: GetNormal
1368 // purpose :Get the normal to the plane.
1369 //==================================================================
1370 vtkFloatingPointType* VISU_PlanesWidget::GetNormal() 
1371 {
1372   return myPlane1->GetNormal();
1373 }
1374 //==================================================================
1375 // function: GetNormal
1376 // purpose :Get the normal to the plane.
1377 //==================================================================
1378 void VISU_PlanesWidget::GetNormal(vtkFloatingPointType xyz[3]) 
1379 {
1380   myPlane1->GetNormal(xyz);
1381 }
1382 //==================================================================
1383 // function: SetDrawPlane
1384 // purpose :
1385 //==================================================================
1386 void VISU_PlanesWidget::SetDrawPlane(int drawPlane)
1387 {
1388   if ( drawPlane == this->myDrawPlane )    {
1389     return;
1390   }
1391   
1392   this->Modified();
1393   this->myDrawPlane = drawPlane;
1394   if ( this->Enabled ) {
1395     if ( drawPlane ) {
1396       this->CurrentRenderer->AddActor(this->myCutActor1);
1397       this->CurrentRenderer->AddActor(myCutActor2);
1398     }
1399     else {
1400       this->CurrentRenderer->RemoveActor(this->myCutActor1);
1401       this->CurrentRenderer->RemoveActor(myCutActor2);
1402     }
1403     this->Interactor->Render();
1404   }
1405 }
1406 //==================================================================
1407 // function: SetNormalToXAxis
1408 // purpose :
1409 //==================================================================
1410 void VISU_PlanesWidget::SetNormalToXAxis (int var)
1411 {
1412   if (this->NormalToXAxis != var)    {
1413     this->NormalToXAxis = var;
1414     this->Modified();
1415   }
1416   if (var)    {
1417     this->NormalToYAxisOff();
1418     this->NormalToZAxisOff();
1419   }
1420 }
1421 //==================================================================
1422 // function: SetNormalToYAxis
1423 // purpose :
1424 //==================================================================
1425 void VISU_PlanesWidget::SetNormalToYAxis (int var)
1426 {
1427   if (this->NormalToYAxis != var)    {
1428     this->NormalToYAxis = var;
1429     this->Modified();
1430   }
1431   if (var)    {
1432     this->NormalToXAxisOff();
1433     this->NormalToZAxisOff();
1434   }
1435 }
1436 //==================================================================
1437 // function: SetNormalToZAxis
1438 // purpose :
1439 //==================================================================
1440 void VISU_PlanesWidget::SetNormalToZAxis (int var)
1441 {
1442   if (this->NormalToZAxis != var)    {
1443     this->NormalToZAxis = var;
1444     this->Modified();
1445   }
1446   if (var)    {
1447     this->NormalToXAxisOff();
1448     this->NormalToYAxisOff();
1449   }
1450 }
1451 //==================================================================
1452 // function: GetPolyData
1453 // purpose :
1454 //==================================================================
1455 void VISU_PlanesWidget::GetPolyData(vtkPolyData *pd)
1456
1457   pd->ShallowCopy(this->myCutter1->GetOutput()); 
1458 }
1459 //==================================================================
1460 // function: GetPolyDataSource
1461 // purpose :
1462 //==================================================================
1463 /*
1464 vtkPolyDataSource *VISU_PlanesWidget::GetPolyDataSource()
1465 {
1466   return this->myCutter1;
1467 }
1468 */
1469 //==================================================================
1470 // function:GetPlane
1471 // purpose :
1472 //==================================================================
1473 void VISU_PlanesWidget::GetPlane(vtkPlane *plane)
1474 {
1475   if ( plane == NULL )    {
1476     return;
1477   }
1478   
1479   plane->SetNormal(myPlane1->GetNormal());
1480   plane->SetOrigin(myPlane1->GetOrigin());
1481 }
1482 //==================================================================
1483 // function:UpdatePlacement
1484 // purpose :
1485 //==================================================================
1486 void VISU_PlanesWidget::UpdatePlacement(void)
1487 {
1488   this->myOutline->Update();
1489   this->myCutter1->Update();
1490   this->myEdges1->Update();
1491 }
1492 //==================================================================
1493 // function:UpdateRepresentation
1494 // purpose :
1495 //==================================================================
1496 void VISU_PlanesWidget::UpdateRepresentation()
1497 {
1498   if ( ! this->CurrentRenderer )    {
1499     return;
1500   }
1501
1502   vtkFloatingPointType *origin = myPlane1->GetOrigin();
1503   vtkFloatingPointType *normal = myPlane1->GetNormal();
1504   vtkFloatingPointType p2[3];
1505
1506   // Setup the plane normal
1507   vtkFloatingPointType d = this->myOutline->GetOutput()->GetLength();
1508
1509   p2[0] = origin[0] + 0.30 * d * normal[0];
1510   p2[1] = origin[1] + 0.30 * d * normal[1];
1511   p2[2] = origin[2] + 0.30 * d * normal[2];
1512
1513   this->LineSource->SetPoint1(origin);
1514   this->LineSource->SetPoint2(p2);
1515   this->ConeSource->SetCenter(p2);
1516   this->ConeSource->SetDirection(normal);
1517   ConeActor->SetCenter(p2);
1518
1519   p2[0] = origin[0] - 0.30 * d * normal[0];
1520   p2[1] = origin[1] - 0.30 * d * normal[1];
1521   p2[2] = origin[2] - 0.30 * d * normal[2];
1522
1523   this->LineSource2->SetPoint1(origin);
1524   this->LineSource2->SetPoint2(p2);
1525   this->ConeSource2->SetCenter(p2);
1526   this->ConeSource2->SetDirection(normal);
1527   ConeActor2->SetCenter(p2);
1528
1529   // Set up the position handle
1530   this->Sphere->SetCenter(origin);
1531   SphereActor->SetCenter(origin);
1532
1533   this->myEdgesMapper1->SetInput(this->myEdges1->GetOutput());
1534 }
1535
1536 //==================================================================
1537 // function:PrintSelf
1538 // purpose :
1539 //==================================================================
1540 void VISU_PlanesWidget::PrintSelf(ostream& os, vtkIndent indent)
1541 {
1542   this->Superclass::PrintSelf(os,indent);
1543 }
1544 //==================================================================
1545 // function: IsValidPlane2Position
1546 // purpose :
1547 //==================================================================
1548 bool IsValidPlane2Position(vtkPlane *pPx,
1549                            vtkDataSet *pDataSet,
1550                            vtkFloatingPointType aTol)
1551 {
1552   bool bRet;
1553   int i, iFound;
1554   vtkFloatingPointType aD, aDmax, aPnts[24], aDiagonal;
1555   vtkFloatingPointType aTol1, aOr[3], aN[3];
1556   //
1557   bRet=false;
1558   aDiagonal=pDataSet->GetLength();
1559   aTol1=aDiagonal*aTol;
1560   //
1561   GetBndPoints(pDataSet, aPnts);
1562   //
1563   pPx->GetOrigin(aOr);
1564   pPx->GetNormal(aN);
1565   vtkMath::Normalize(aN);
1566   //
1567   iFound=0;
1568   aDmax=0.;
1569   for (i=0; i<24; i+=3){
1570     aD=-DistanceToPlane(aPnts+i, aN, aOr);
1571     if (aD>aDmax){
1572             aDmax=aD;
1573             iFound=1;
1574     }
1575   }
1576   if (iFound && aDmax>aTol1) {
1577     bRet=!bRet;
1578   }
1579   return bRet;
1580 }
1581 //==================================================================
1582 // function: GetBndPoints
1583 // purpose :
1584 //==================================================================
1585 void 
1586 GetBndPoints(vtkDataSet *pDataSet, 
1587              vtkFloatingPointType aPnts[24])
1588 {
1589   int aIndx[24] = {
1590     0,2,4,1,2,4,1,3,4,0,3,4,
1591     0,2,5,1,2,5,1,3,5,0,3,5
1592   };
1593   int i;
1594   vtkFloatingPointType *pBounds=pDataSet->GetBounds();
1595   //
1596   for (i=0; i<24; ++i){
1597     aPnts[i]=pBounds[aIndx[i]];
1598   }
1599 }
1600 //==================================================================
1601 // function: DistanceToPlane
1602 // purpose :
1603 //==================================================================
1604 vtkFloatingPointType 
1605 DistanceToPlane(const vtkFloatingPointType x[3], 
1606                 const vtkFloatingPointType n[3], 
1607                 const vtkFloatingPointType p0[3])
1608 {
1609   return ((n[0]*(x[0]-p0[0]) + 
1610            n[1]*(x[1]-p0[1]) +  
1611            n[2]*(x[2]-p0[2])));
1612 }
1613 /*
1614 //==================================================================
1615 // function:SizeHandles
1616 // purpose :
1617 //==================================================================
1618 void VISU_PlanesWidget::SizeHandles()
1619 {
1620   //  vtkFloatingPointType radius = 
1621   this->vtk3DWidget::SizeHandles(1.35);
1622 }
1623 */