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