0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / IVtkDraw / IVtkDraw.cxx
1 // Created on: 2012-02-03 
2 // 
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS 
4 // 
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #ifdef NOMINMAX
18 #undef NOMINMAX    /* avoid #define min() and max() */
19 #endif
20 #ifdef NOMSG
21 #undef NOMSG       /* avoid #define SendMessage etc. */
22 #endif
23 #ifdef NODRAWTEXT
24 #undef NODRAWTEXT  /* avoid #define DrawText etc. */
25 #endif
26 #ifdef NONLS
27 #undef NONLS       /* avoid #define CompareString etc. */
28 #endif
29 #ifdef NOGDI
30 #undef NOGDI       /* avoid #define SetPrinter (winspool.h) etc. */
31 #endif
32 #ifdef NOSERVICE
33 #undef NOSERVICE    
34 #endif
35 #ifdef NOKERNEL
36 #undef NOKERNEL 
37 #endif
38 #ifdef NOUSER
39 #undef NOUSER 
40 #endif
41 #ifdef NOMCX
42 #undef NOMCX 
43 #endif
44 #ifdef NOIME
45 #undef NOIME 
46 #endif
47
48 #include <stdio.h>
49 #ifdef HAVE_STRINGS_H
50 # include <strings.h>
51 #endif
52
53 #ifdef _WIN32
54 #define _WIN32_WINNT 0x0400  // for TrackMouseEvent support requires Win95 with IE 3.0 or greater.
55 #include <windows.h>
56 #include <WNT_WClass.hxx>
57 #include <WNT_Window.hxx>
58 #endif
59
60 #include <Draw.hxx>
61 #include <Draw_Interpretor.hxx>
62 #include <Draw_PluginMacro.hxx>
63 #include <TCollection_AsciiString.hxx>
64 #include <TopoDS_Shape.hxx>
65 #include <BRep_Builder.hxx>
66 #include <BRepTools.hxx>
67 #include <DBRep.hxx>
68 #include <NCollection_DoubleMap.hxx>
69 #include <NCollection_List.hxx>
70 #include <NCollection_DataMap.hxx>
71 #include <TopTools_DataMapOfIntegerShape.hxx>
72 #include <OpenGl_GraphicDriver.hxx>
73 #include <Aspect_DisplayConnection.hxx>
74
75 #include <IVtk_Types.hxx>
76 #include <IVtkVTK_ShapeData.hxx>
77 #include <IVtkOCC_Shape.hxx>
78 #include <IVtkOCC_ShapeMesher.hxx>
79 #include <IVtkTools_ShapeDataSource.hxx>
80 #include <IVtkTools_ShapeObject.hxx>
81 #include <IVtkTools_SubPolyDataFilter.hxx>
82 #include <IVtkTools_DisplayModeFilter.hxx>
83 #include <IVtkTools_ShapePicker.hxx>
84
85 #include <IVtkDraw.hxx>
86 #include <IVtkDraw_HighlightAndSelectionPipeline.hxx>
87 #include <IVtkDraw_Interactor.hxx>
88
89 #include <vtkAlgorithmOutput.h>
90 #include <vtkAppendPolyData.h>
91 #include <vtkBMPWriter.h>
92 #include <vtkCamera.h>
93 #include <vtkCellData.h>
94 #include <vtkCommand.h>
95 #include <vtkGeometryFilter.h>
96 #include <vtkIdTypeArray.h>
97 #include <vtkImageResize.h>
98 #include <vtkImageWriter.h>
99 #include <vtkInteractorStyleTrackballCamera.h>
100 #include <vtkJPEGWriter.h>
101 #include <vtkPNGWriter.h>
102 #include <vtkPNMWriter.h>
103 #include <vtkPolyDataMapper.h>
104 #include <vtkProperty.h>
105 #include <vtkRenderWindow.h>
106 #include <vtkRenderer.h>
107 #include <vtkRenderWindowInteractor.h>
108 #include <vtkSmartPointer.h>
109 #include <vtkTIFFWriter.h>
110 #include <vtkWindowToImageFilter.h>
111
112 #ifndef _WIN32
113 #include <X11/X.h>
114 #include <X11/Shell.h>
115 #include <X11/Xlib.h>
116 #include <GL/glx.h>
117 #include <Xw_Window.hxx>
118 #include <vtkXRenderWindowInteractor.h>
119 #include <vtkXOpenGLRenderWindow.h>
120 #include <X11/Xutil.h>
121 #include <tk.h>
122 #endif
123
124 // workaround name conflicts with OCCT methods (in class TopoDS_Shape for example)
125 #ifdef Convex
126   #undef Convex
127 #endif
128 #ifdef Status
129   #undef Status
130 #endif
131
132 //================================================================
133 // TYPE DEFINITIONS
134 //================================================================
135
136 typedef NCollection_DoubleMap<TopoDS_Shape, TCollection_AsciiString> DoubleMapOfShapesAndNames;
137 typedef NCollection_DoubleMap<vtkSmartPointer<vtkActor>, TCollection_AsciiString> DoubleMapOfActorsAndNames;
138
139 typedef IVtkDraw_HighlightAndSelectionPipeline PipelinePtr;
140
141 //================================================================
142 // GLOBAL VARIABLES
143 //================================================================
144
145 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
146
147 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
148 {
149   static Handle(Aspect_DisplayConnection) aDisplayConnection;
150   return aDisplayConnection;
151 }
152
153 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
154 {
155   GetDisplayConnection() = theDisplayConnection;
156 }
157
158 static DoubleMapOfShapesAndNames& GetMapOfShapes()
159 {
160   static DoubleMapOfShapesAndNames aMap;
161   return aMap;
162 }
163
164 static DoubleMapOfActorsAndNames& GetMapOfActors()
165 {
166   static DoubleMapOfActorsAndNames aMap;
167   return aMap;
168 }
169
170 static vtkSmartPointer<vtkRenderer>& GetRenderer()
171 {
172   static vtkSmartPointer<vtkRenderer> aRenderer;
173   return aRenderer;
174 }
175
176 static Handle(ShapePipelineMap)& GetPipelines()
177 {
178   static Handle(ShapePipelineMap) aPLMap;
179   if (aPLMap.IsNull())
180   {
181     aPLMap = new ShapePipelineMap();
182   }
183
184   return aPLMap;
185 }
186
187 static Handle(PipelinePtr) GetPipeline (const IVtk_IdType& theShapeID)
188 {
189   Handle(PipelinePtr) aPtr;
190   GetPipelines()->Find (theShapeID, aPtr);
191   return aPtr;
192 }
193
194 //! Get VTK render pipeline with shape ID got from actor.
195 static Handle(PipelinePtr) PipelineByActor (const vtkSmartPointer<vtkActor>& theActor)
196 {
197   IVtk_IdType aShapeID = IVtkTools_ShapeObject::GetShapeSource (theActor)->GetShape()->GetId();
198   return GetPipeline (aShapeID);
199 }
200
201 //! Get VTK render pipeline with actor that has the input name.
202 static Handle(PipelinePtr) PipelineByActorName (const TCollection_AsciiString& theName)
203 {
204   const vtkSmartPointer<vtkActor>& anActor = GetMapOfActors().Find2 (theName);
205   return PipelineByActor (anActor);
206 }
207
208 static Standard_Boolean IsEqual (const TopoDS_Shape& theLeft,
209                                  const TopoDS_Shape& theRight)
210 {
211   return theLeft.IsEqual (theRight);
212 }
213
214 #ifdef _WIN32
215
216 static Handle(WNT_Window)& GetWindow()
217 {
218   static Handle(WNT_Window) aWindow;
219   return aWindow;
220 }
221
222 #else
223
224 static Handle(Xw_Window)& GetWindow()
225 {
226   static Handle(Xw_Window) aXWWin;
227   return aXWWin;
228 }
229
230 #endif
231
232 static vtkSmartPointer<IVtkDraw_Interactor>& GetInteractor()
233 {
234   static vtkSmartPointer<IVtkDraw_Interactor> anInteractor;
235   return anInteractor;
236 }
237
238 static vtkSmartPointer<IVtkTools_ShapePicker>& GetPicker()
239 {
240   static vtkSmartPointer<IVtkTools_ShapePicker> aPicker;
241   return aPicker;
242 }
243
244 //! Generate identical number for shape
245 Standard_Integer GenerateId()
246 {
247   static unsigned int aShapesCounter = (unsigned int )-1;
248   return (Standard_Integer )++aShapesCounter;
249 }
250
251 //=========================================================
252 // Function : WClass
253 // Purpose  :
254 //=========================================================
255 const Handle(MMgt_TShared)& IVtkDraw::WClass()
256 {
257   static Handle(MMgt_TShared) aWindowClass;
258 #ifdef _WIN32
259   if (aWindowClass.IsNull())
260   {
261     aWindowClass = new WNT_WClass ("GWVTK_Class", DefWindowProc,
262                                    CS_VREDRAW | CS_HREDRAW, 0, 0,
263                                    ::LoadCursor (NULL, IDC_ARROW));
264   }
265 #endif
266   return aWindowClass;
267 }
268
269 //==============================================================
270 // Function : ViewerInit
271 // Purpose  : 
272 //==============================================================
273 void IVtkDraw::ViewerInit (Standard_Integer thePxLeft,
274                            Standard_Integer thePxTop,
275                            Standard_Integer thePxWidth,
276                            Standard_Integer thePxHeight)
277 {
278   static Standard_Boolean isFirst = Standard_True;
279
280   Standard_Integer aPxLeft   = 0;
281   Standard_Integer aPxTop    = 460;
282   Standard_Integer aPxWidth  = 409;
283   Standard_Integer aPxHeight = 409;
284
285   if (thePxLeft != 0)
286   {
287     aPxLeft = thePxLeft;
288   }
289   if (thePxTop != 0)
290   {
291     aPxTop = thePxTop;
292   }
293   if (thePxWidth != 0)
294   {
295     aPxWidth = thePxWidth;
296   }
297   if (thePxHeight != 0)
298   {
299     aPxHeight = thePxHeight;
300   }
301   
302   if (isFirst)
303   {
304     SetDisplayConnection (new Aspect_DisplayConnection ());
305 #ifdef _WIN32
306     if (GetWindow().IsNull())
307     {
308       GetWindow() = new WNT_Window ("IVtkTest",
309                                     Handle(WNT_WClass)::DownCast (WClass()),
310                                     WS_OVERLAPPEDWINDOW,
311                                     aPxLeft, aPxTop,
312                                     aPxWidth, aPxHeight,
313                                     Quantity_NOC_BLACK);
314       GetWindow()->SetVirtual (Draw_VirtualWindows);
315     }
316 #else
317
318     if (GetWindow().IsNull())
319     {
320       GetWindow() = new Xw_Window (GetDisplayConnection(),
321                                    "IVtkTest",
322                                    aPxLeft, aPxTop,
323                                    aPxWidth, aPxHeight);
324       GetWindow()->SetVirtual (Draw_VirtualWindows);
325     }
326 #endif
327     // Init pipeline
328     GetRenderer() = vtkSmartPointer<vtkRenderer>::New();
329
330     vtkSmartPointer<vtkRenderWindow> aRenWin = vtkSmartPointer<vtkRenderWindow>::New();
331     aRenWin->AddRenderer (GetRenderer());
332     GetRenderer()->GetActiveCamera()->ParallelProjectionOn();
333     aRenWin->SetSize (aPxWidth, aPxHeight);
334
335 #ifdef _WIN32
336     aRenWin->SetWindowId((void*)GetWindow()->HWindow());
337 #else
338     Window aWindowId = GetWindow()->XWindow();
339     aRenWin->SetWindowId ((void*)aWindowId);
340     Display *aDisplayId = GetDisplayConnection()->GetDisplay();
341     aRenWin->SetDisplayId (aDisplayId);
342
343     // Setup XWindow
344     XSynchronize (aDisplayId, 1);
345     GetWindow()->Map();
346
347     // X11 : For keyboard on SUN
348     XWMHints wmhints;
349     wmhints.flags = InputHint;
350     wmhints.input = 1;
351
352     XSetWMHints (aDisplayId, aWindowId, &wmhints);
353
354     XSelectInput (aDisplayId, aWindowId,  ExposureMask | KeyPressMask |
355       ButtonPressMask | ButtonReleaseMask |
356       StructureNotifyMask |
357       PointerMotionMask |
358       Button1MotionMask | Button2MotionMask |
359       Button3MotionMask
360       );
361
362     XSynchronize (aDisplayId, 0);
363
364 #endif
365
366     // Init interactor
367     GetInteractor() = vtkSmartPointer<IVtkDraw_Interactor>::New();
368     GetInteractor()->SetRenderWindow (aRenWin);
369     GetInteractor()->SetOCCWindow (GetWindow());
370
371     vtkSmartPointer<vtkInteractorStyleTrackballCamera>
372       aStyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
373     GetInteractor()->SetInteractorStyle (aStyle);
374
375     // Init picker
376     GetPicker() = vtkSmartPointer<IVtkTools_ShapePicker>::New();
377     GetPicker()->SetTolerance (0.025);
378     GetPicker()->SetRenderer (GetRenderer());
379
380     GetInteractor()->SetShapePicker (GetPicker());
381     GetInteractor()->SetPipelines (GetPipelines());
382     GetInteractor()->Initialize();
383
384     aRenWin->SetOffScreenRendering(Draw_VirtualWindows);
385     aRenWin->Render();
386
387     isFirst = Standard_False;
388   }
389
390   GetWindow()->Map();
391 }
392
393 //================================================================
394 // Function : VtkInit
395 // Purpose  : 
396 //================================================================
397 static Standard_Integer VtkInit (Draw_Interpretor& ,
398                                  Standard_Integer theArgNum,
399                                  const char** theArgs)
400 {
401   Standard_Integer aPxLeft   = (theArgNum > 1) ? atoi(theArgs[1]) : 0;
402   Standard_Integer aPxTop    = (theArgNum > 2) ? atoi(theArgs[2]) : 0;
403   Standard_Integer aPxWidth  = (theArgNum > 3) ? atoi(theArgs[3]) : 0;
404   Standard_Integer aPxHeight = (theArgNum > 4) ? atoi(theArgs[4]) : 0;
405
406   IVtkDraw::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight);
407   return 0;
408 }
409
410
411 //================================================================
412 // Function : CreateActor
413 // Purpose  : 
414 //================================================================
415 vtkActor* CreateActor (const Standard_Integer theId,
416                        const TopoDS_Shape& theShape)
417 {
418   if ( theShape.IsNull() )
419   {
420     return NULL;
421   }
422
423   Handle(PipelinePtr) aPL = new PipelinePtr (theShape, theId);
424   GetPipelines()->Bind (theId, aPL);
425
426   return aPL->Actor();
427 }
428
429 //================================================================
430 // Function : VtkDisplay
431 // Purpose  : 
432 //================================================================
433
434 static Standard_Integer VtkDisplay (Draw_Interpretor& theDI,
435                                     Standard_Integer theArgNum,
436                                     const char** theArgs)
437 {
438   // Check viewer
439   if (!GetInteractor()->IsEnabled())
440   {
441     theDI << theArgs[0] << " error : call ivtkinit before\n";
442     return 1; // TCL_ERROR
443   }
444
445   // Check arguments
446   if (theArgNum < 2)
447   {
448     theDI << theArgs[0] << " error : expects at least 1 argument\n";
449     return 1; // TCL_ERROR
450   }
451
452   TCollection_AsciiString aName;
453   TopoDS_Shape anOldShape, aNewShape;
454   vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
455   for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
456   {
457     // Get name of shape
458     aName = theArgs[anIndex];
459     // Get shape from DRAW
460     aNewShape = DBRep::Get (theArgs[anIndex]);
461
462     // The shape is already in the map
463     if (GetMapOfShapes().IsBound2 (aName))
464     {
465       // Get shape from map
466       anOldShape = GetMapOfShapes().Find2 (aName);
467       // Equal shapes
468       if (anOldShape.IsEqual (aNewShape))
469       {
470         // Get actor from map and display it
471         PipelineByActorName (aName)->AddToRenderer (aRenderer);
472       }
473       // Different shapes
474       else
475       {
476         if (aNewShape.IsNull()) continue;
477         // Create actor from DRAW shape
478         vtkActor* anActor = CreateActor (GenerateId(), aNewShape);
479         // Remove old actor from render
480         PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
481         // Update maps
482         GetMapOfShapes().UnBind2 (aName);
483         GetMapOfShapes().Bind (aNewShape, aName);
484         GetMapOfActors().UnBind2 (aName);
485         GetMapOfActors().Bind (anActor, aName);
486         // Display new actor
487         PipelineByActorName (aName)->AddToRenderer (aRenderer);
488         // Compute selection for displayed actors
489         GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
490       }
491     }
492     // There is no shape with given name in map
493     else
494     {
495       if (aNewShape.IsNull()) continue;
496       // Create actor from DRAW shape
497       vtkActor* anActor = CreateActor (GenerateId(), aNewShape);
498       // Update maps
499       GetMapOfShapes().Bind (aNewShape, aName);
500       GetMapOfActors().Bind (anActor, aName);
501       // Display actor
502       PipelineByActorName (aName)->AddToRenderer (aRenderer);
503
504       // Compute selection for displayed actors
505       GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
506     }
507   }
508
509   // Redraw window
510   aRenderer->ResetCamera();
511   GetInteractor()->GetRenderWindow()->Render();
512
513   return 0;
514 }
515
516 //================================================================
517 // Function : VtkErase
518 // Purpose  : 
519 //================================================================
520 static Standard_Integer VtkErase (Draw_Interpretor& theDI,
521                                   Standard_Integer theArgNum,
522                                   const char** theArgs)
523 {
524   // Check viewer
525   if (!GetInteractor()->IsEnabled())
526   {
527     theDI << theArgs[0] << " error : call ivtkinit before\n";
528     return 1; // TCL_ERROR
529   }
530
531   vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
532   // Erase all objects
533   if (theArgNum == 1)
534   {
535     DoubleMapOfActorsAndNames::Iterator anIterator (GetMapOfActors());
536     while (anIterator.More())
537     {
538       PipelineByActor (anIterator.Key1())->RemoveFromRenderer (aRenderer);
539       anIterator.Next();
540     }
541   }
542   // Erase named objects
543   else
544   {
545     TCollection_AsciiString aName;
546     for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
547     {
548       aName = theArgs[anIndex];
549       if (GetMapOfActors().IsBound2 (aName))
550       {
551         PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
552       }
553     }
554   }
555
556   // Redraw window
557   aRenderer->ResetCamera();
558   GetInteractor()->GetRenderWindow()->Render();
559   return 0;
560 }
561
562 //================================================================
563 // Function  : VtkSetDisplayMode
564 // Purpose   : 
565 // Draw args : ivtksetdispmode [name] mode(0,1)
566 //================================================================
567 static Standard_Integer VtkSetDisplayMode (Draw_Interpretor& theDI,
568                                            Standard_Integer theArgNum,
569                                            const char** theArgs)
570 {
571   // Check viewer
572   if (!GetInteractor()->IsEnabled())
573   {
574     theDI << theArgs[0] << " error: call ivtkinit before\n";
575     return 1; // TCL_ERROR
576   }
577
578   // Check arguments
579   if (theArgNum != 2 && theArgNum != 3)
580   {
581     theDI << theArgs[0] << " error: expects 1 or 2 arguments\n";
582     return 1; // TCL_ERROR
583   }
584
585   vtkSmartPointer<vtkActor> anActor;
586   // Set disp mode for all objects
587   if (theArgNum == 2)
588   {
589     // Get mode
590     Standard_Integer aMode =  Draw::Atoi (theArgs[1]);
591     DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
592     while (anIter.More())
593     {
594       anActor = anIter.Key1();
595       IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
596       if (aSrc)
597       {
598         IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
599         if (!anOccShape.IsNull())
600         {
601           IVtkTools_DisplayModeFilter* aFilter = GetPipeline ( anOccShape->GetId() )->GetDisplayModeFilter();
602           aFilter->SetDisplayMode((IVtk_DisplayMode)aMode);
603           aFilter->Modified();
604           aFilter->Update();
605         }
606       }
607       anIter.Next();
608     }
609   }
610   // Set disp mode for named object
611   else 
612   {
613     Standard_Integer aMode = atoi(theArgs[2]);
614     TCollection_AsciiString aName = theArgs[1];
615     if (GetMapOfActors().IsBound2 (aName))
616     {
617       anActor = GetMapOfActors().Find2 (aName);
618       vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
619       if (aSrc)
620       {
621         IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
622         if (!anOccShape.IsNull())
623         {
624           IVtkTools_DisplayModeFilter* aFilter = GetPipeline (anOccShape->GetId())->GetDisplayModeFilter();
625           aFilter->SetDisplayMode ((IVtk_DisplayMode)aMode);
626           aFilter->Modified();
627           aFilter->Update();
628         }
629       }
630     }
631   }
632
633   // Redraw window
634   GetInteractor()->Render();
635   return 0;
636 }
637
638 //================================================================
639 // Function  : VtkSetSelectionMode
640 // Purpose   : 
641 // Draw args : ivtksetselmode [name] mode on/off(0,1)
642 //================================================================
643 static Standard_Integer VtkSetSelectionMode (Draw_Interpretor& theDI,
644                                              Standard_Integer theArgNum,
645                                              const char** theArgs)
646 {
647   // Check viewer
648   if (!GetInteractor()->IsEnabled())
649   {
650     theDI << theArgs[0] << " error: call ivtkinit before\n";
651     return 1; // TCL_ERROR
652   }
653
654   // Check arguments
655   if (theArgNum != 3 && theArgNum != 4)
656   {
657     theDI << theArgs[0] << " error: expects 2 or 3 arguments\n";
658     return 1; // TCL_ERROR
659   }
660
661   vtkSmartPointer<vtkActor> anActor;
662   Standard_Integer aMode;
663   Standard_Boolean isTurnOn;
664   // Set sel mode for all objects
665   if (theArgNum == 3)
666   {
667     aMode = atoi (theArgs[1]);
668     isTurnOn = (atoi (theArgs[2]) != 0);
669     if (aMode < 0 || aMode > 8)
670     {
671       theDI << theArgs[0] << " error: only 0-8 selection modes are supported\n";
672       return 1; // TCL_ERROR
673     }
674     DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
675     while (anIter.More())
676     {
677       anActor = anIter.Key1();
678
679       if (aMode == SM_Shape && isTurnOn)
680       {
681         IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
682         IVtk_SelectionModeList::Iterator anIt (aList);
683         // Turn off all sel modes differed from SM_Shape
684         while (anIt.More())
685         {
686           IVtk_SelectionMode aCurMode = anIt.Value();
687           if (SM_Shape != aCurMode)
688           {
689             GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
690           }
691           anIt.Next();
692         }
693         GetPicker()->SetSelectionMode (anActor, SM_Shape);
694       }
695
696       if (aMode != SM_Shape)
697       {
698         if (isTurnOn)
699         {
700           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
701           GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
702           if (aMode == SM_Vertex)
703           {
704             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
705           }
706         }
707         else
708         {
709           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
710           IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
711           if (!aList.Size())
712           {
713             GetPicker()->SetSelectionMode(anActor, SM_Shape);
714           }
715           if (aMode == SM_Vertex)
716           {
717             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
718           }
719         }
720       }
721       anIter.Next();
722     }
723   }
724
725   // Set sel mode for named object
726   if (theArgNum == 4)
727   {
728     aMode = atoi (theArgs[2]);
729     isTurnOn = (atoi (theArgs[3]) != 0);
730
731     if (aMode < 0 || aMode > 8)
732     {
733       theDI << theArgs[0] << " error: only 0-8 selection modes are supported\n";
734       return 1; // TCL_ERROR
735     }
736
737     TCollection_AsciiString aName = theArgs[1];
738     if (GetMapOfActors().IsBound2 (aName))
739     {
740       anActor = GetMapOfActors().Find2 (aName);
741
742       if (aMode == SM_Shape && isTurnOn)
743       {
744         IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
745         IVtk_SelectionModeList::Iterator anIt (aList);
746         // Turn off all sel modes differed from SM_Shape
747         while (anIt.More())
748         {
749           IVtk_SelectionMode aCurMode = anIt.Value();
750           if (SM_Shape != aCurMode)
751           {
752             GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
753           }
754           anIt.Next();
755         }
756         GetPicker()->SetSelectionMode (anActor, SM_Shape);
757       }
758
759       if (aMode != SM_Shape)
760       {
761         if (isTurnOn)
762         {
763           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
764           GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
765           if (aMode == SM_Vertex)
766           {
767             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
768           }
769         }
770         else
771         {
772           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
773           IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
774           if (!aList.Size())
775           {
776             GetPicker()->SetSelectionMode(anActor, SM_Shape);
777           }
778           if (aMode == SM_Vertex)
779           {
780             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
781           }
782         }
783       }
784     }
785   }
786
787   // Redraw window
788   GetInteractor()->Render();
789
790   return 0;
791 }
792
793 //================================================================
794 // Function  : VtkMoveTo
795 // Purpose   : 
796 // Draw args : ivtkmoveto x y
797 //================================================================
798 static Standard_Integer VtkMoveTo(Draw_Interpretor& theDI,
799                                   Standard_Integer theArgNum,
800                                   const char** theArgs)
801 {
802   // Check viewer
803   if (!GetInteractor()->IsEnabled())
804   {
805     theDI << theArgs[0] << " error: call ivtkinit before\n";
806     return 1; // TCL_ERROR
807   }
808
809   // Check args
810   if (theArgNum != 3)
811   {
812     theDI << theArgs[0] << " error: expects 2 arguments\n";
813     return 1; // TCL_ERROR
814   }
815
816   Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[2]) - 1;
817   GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
818   return 0;
819 }
820
821 //================================================================
822 // Function  : VtkSelect
823 // Purpose   : 
824 // Draw args : ivtkselect x y
825 //================================================================
826 static Standard_Integer VtkSelect (Draw_Interpretor& theDI,
827                                    Standard_Integer theArgNum,
828                                    const char** theArgs)
829 {
830   // Check viewer
831   if (!GetInteractor()->IsEnabled())
832   {
833     theDI << theArgs[0] << " error: call ivtkinit before\n";
834     return 1; // TCL_ERROR
835   }
836
837   // Check args
838   if (theArgNum != 3)
839   {
840     theDI << theArgs[0] << " error: expects 3 arguments\n";
841     return 1; // TCL_ERROR
842   }
843
844   Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[1]) - 1;
845   GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
846   GetInteractor()->OnSelection();
847   return 0;
848
849 }
850
851 //===================================================================
852 // Fubction  : VtkFit
853 // Purpose   :
854 // Draw args : ivtkfit
855 //===================================================================
856
857 static Standard_Integer VtkFit (Draw_Interpretor& theDI,
858                                 Standard_Integer,
859                                 const char** theArgs)
860 {
861   // Check viewer
862   if (!GetInteractor()->IsEnabled())
863   {
864     theDI << theArgs[0] << " error : call ivtkinit before \n";
865     return 1; //TCL_ERROR
866   }
867
868   GetRenderer()->ResetCamera();
869   GetInteractor()->Render();
870   return 0;
871 }
872
873 //===================================================================
874 // Fubction  : VtkDump
875 // Purpose   :
876 // Draw args : ivtkdump FullFilename.{png|bmp|jpeg|tiff|pnm} 
877 //                      [buffer={rgb|rgba|depth}] [width height]
878 //                      [stereoproj={L|R}]
879 //===================================================================
880 static Standard_Integer VtkDump (Draw_Interpretor& theDI,
881                                  Standard_Integer theArgNum,
882                                  const char** theArgs)
883 {
884   // Check viewer
885   if (!GetInteractor()->IsEnabled())
886   {
887     std::cout << theArgs[0] << " error : call ivtkinit before \n";
888     return 1;
889   }
890
891   if (theArgNum < 2)
892   {
893     theDI << theArgs[0] << " error : wrong number of parameters. Type 'help"
894           << theArgs[0] << "' for more information.\n";
895   }
896   vtkSmartPointer<vtkWindowToImageFilter> anImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
897
898   anImageFilter->SetInput (GetInteractor()->GetRenderWindow());
899   // Set custom buffer type
900   if (theArgNum > 2)
901   {
902     TCollection_AsciiString aBufferType (theArgs[2]);
903     aBufferType.LowerCase();
904     if (aBufferType.IsEqual ("rgb"))
905     {
906       anImageFilter->SetInputBufferTypeToRGB();
907     }
908     else if (aBufferType.IsEqual ("rgba"))
909     {
910       anImageFilter->SetInputBufferTypeToRGBA();
911     }
912     else if (aBufferType.IsEqual ("depth"))
913     {
914       anImageFilter->SetInputBufferTypeToZBuffer();
915     }
916   }
917   anImageFilter->Update();
918
919   // Set custom stereo projection options
920   if (theArgNum > 5 && GetRenderer()->GetRenderWindow()->GetStereoRender())
921   {
922     Standard_CString aStereoProjStr = theArgs[5];
923
924     Standard_Integer aStereoType =  GetRenderer()->GetRenderWindow()->GetStereoType();
925     if (strcasecmp (aStereoProjStr, "L"))
926     {
927       GetRenderer()->GetRenderWindow()->SetStereoTypeToLeft();
928       GetRenderer()->GetRenderWindow()->StereoUpdate();
929       anImageFilter->Update();
930       GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
931     }
932     else if (strcasecmp (aStereoProjStr, "R"))
933     {
934       GetRenderer()->GetRenderWindow()->SetStereoTypeToRight();
935       GetRenderer()->GetRenderWindow()->StereoUpdate();
936       anImageFilter->Update();
937       GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
938     }
939     else
940     {
941       theDI << theArgs[0] << " error: unknown value for stereo projection.\n";
942       return 1;
943     }
944   }
945
946   // Set parameters for image writer
947   vtkSmartPointer<vtkImageWriter> anImageWriter;
948   TCollection_AsciiString aFilename (theArgs[1]);
949   Standard_Integer anExtStart = aFilename.SearchFromEnd (TCollection_AsciiString("."));
950   TCollection_AsciiString aFormat = (anExtStart == -1) ? TCollection_AsciiString("")
951                                     : aFilename.SubString (anExtStart + 1, aFilename.Length());
952   aFormat.LowerCase();
953
954   if (aFormat.IsEqual ("png"))
955   {
956     anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
957   }
958   else if (aFormat.IsEqual ("bmp"))
959   {
960     anImageWriter = vtkSmartPointer<vtkBMPWriter>::New();
961   }
962   else if (aFormat.IsEqual ("jpeg"))
963   {
964     anImageWriter = vtkSmartPointer<vtkJPEGWriter>::New();
965   }
966   else if (aFormat.IsEqual ("tiff"))
967   {
968     anImageWriter = vtkSmartPointer<vtkTIFFWriter>::New();
969   }
970   else if (aFormat.IsEqual ("pnm"))
971   {
972     anImageWriter = vtkSmartPointer<vtkPNMWriter>::New();
973   }
974   else // aFormat is unsupported or not set.
975   {
976     if (aFormat.IsEmpty())
977     {
978       theDI << theArgs[0] << " warning: the image format is not set.\n"
979             << "The image will be saved into PNG format.\n";
980       anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
981       aFormat = TCollection_AsciiString ("png");
982       if (anExtStart != -1)
983       {
984         aFilename.Split (anExtStart);
985       }
986       else
987       {
988         aFilename += ".";
989       }
990       aFilename += aFormat;
991     }
992     else
993     {
994       theDI << theArgs[0] << " error: the image format "
995             << aFormat.ToCString() <<" is not supported.\n";
996       return 1;
997     }
998
999   }
1000
1001   anImageWriter->SetFileName (aFilename.ToCString());
1002
1003   Standard_Integer aWidth = (theArgNum > 3) ? atoi (theArgs[3]) : 0;
1004   Standard_Integer aHeight = (theArgNum > 4) ? atoi (theArgs[4]) : 0;
1005   if (aWidth >= 0 || aHeight >= 0)
1006   {
1007     // Scale image
1008     vtkSmartPointer<vtkImageResize> anImageResize = vtkSmartPointer<vtkImageResize>::New();
1009 #if VTK_MAJOR_VERSION <= 5
1010     anImageResize->SetInput (anImageFilter->GetOutput());
1011 #else
1012     anImageResize->SetInputData (anImageFilter->GetOutput());
1013 #endif
1014
1015     anImageResize->SetOutputDimensions (aWidth, aHeight, 1);
1016     anImageResize->Update();
1017     anImageWriter->SetInputConnection (anImageResize->GetOutputPort());
1018   }
1019   else
1020   {
1021     anImageWriter->SetInputConnection (anImageFilter->GetOutputPort());
1022   }
1023   anImageWriter->Write();
1024
1025   return 0;
1026 }
1027
1028 //===================================================================
1029 // Fubction  : VtkBackgroundColor
1030 // Purpose   :
1031 // Draw args : ivtkbgcolor r g b
1032 //             r,g,b = [0..255]
1033 //===================================================================
1034 static Standard_Integer VtkBackgroundColor (Draw_Interpretor& theDI,
1035                                             Standard_Integer theArgNum,
1036                                             const char** theArgs)
1037 {
1038   if (theArgNum != 4 && theArgNum != 7)
1039   {
1040     theDI << theArgs[0] << " error : wrong number of parameters.\n"
1041           << "Type 'help " << theArgs[0] << "' for more information.\n";
1042     return 1;
1043   }
1044
1045   // Check viewer
1046   if (!GetInteractor()->IsEnabled())
1047   {
1048     std::cout << theArgs[0] << " error : call ivtkinit before \n";
1049     return 1;
1050   }
1051
1052   Standard_Real aR = Draw::Atof(theArgs[1])/255.0;
1053   Standard_Real aG = Draw::Atof(theArgs[2])/255.0;
1054   Standard_Real aB = Draw::Atof(theArgs[3])/255.0;
1055
1056   GetRenderer()->SetGradientBackground(false);
1057   GetRenderer()->SetBackground (aR, aG, aB);
1058
1059   if (theArgNum == 7)
1060   {
1061     Standard_Real aR2 = Draw::Atof(theArgs[4])/255.0;
1062     Standard_Real aG2 = Draw::Atof(theArgs[5])/255.0;
1063     Standard_Real aB2 = Draw::Atof(theArgs[6])/255.0;
1064
1065     GetRenderer()->SetBackground2(aR2, aG2, aB2);
1066     GetRenderer()->SetGradientBackground(true);
1067   }
1068
1069   GetInteractor()->Render();
1070
1071   return 0;
1072 }
1073
1074 //================================================================
1075 // Function : Commands
1076 // Purpose  : 
1077 //================================================================
1078 void IVtkDraw::Commands (Draw_Interpretor& theCommands)
1079 {
1080   const char *group = "VtkViewer";
1081   
1082   theCommands.Add("ivtkinit",
1083     "ivtkinit usage:\n"
1084     "ivtkinit [leftPx topPx widthPx heightPx]"
1085     "\n\t\t: Creates the Vtk window",
1086     __FILE__, VtkInit, group);
1087
1088   theCommands.Add("ivtkdisplay",
1089     "ivtkdisplay usage:\n"
1090     "ivtkdisplay name1 name2 ..."
1091     "\n\t\t: Displayes named objects in current view.",
1092     __FILE__, VtkDisplay, group);
1093
1094   theCommands.Add("ivtkerase",
1095     "ivtkerase usage:\n"
1096     "ivtkerase [name1 name2 ...]"
1097     "\n\t\t: Removes from renderer named objects or all objects.",
1098     __FILE__, VtkErase, group);
1099
1100   theCommands.Add("ivtksetdispmode",
1101     "ivtksetdispmode usage:\n"
1102     "ivtksetdispmode [name] mode (0,1)"
1103     "\n\t\t: Sets or unsets display mode 'mode' to the object with name 'name' or to all objects"
1104     "if name is not defined.",
1105     __FILE__, VtkSetDisplayMode, group);
1106
1107   theCommands.Add("ivtksetselmode",
1108     "ivtksetselmode usage:\n"
1109     " ivtksetselmode [name] mode on/off(0,1)"
1110     "\n\t\t: Sets or unsets selection mode 'mode' to the object with name 'name' or to the all displayed objects.",
1111     __FILE__, VtkSetSelectionMode, group);
1112
1113   theCommands.Add("ivtkmoveto",
1114     "ivtkmoveto usage:\n"
1115     "ivtkmoveto x y"
1116     "\n\t\t: Moves position to the pixel with coordinates (x,y). The object on this position is highlighted.",
1117     __FILE__, VtkMoveTo, group);
1118
1119   theCommands.Add("ivtkselect",
1120     "ivtkselect usage:\n"
1121     "ivtkselect x y"
1122     "\n\t\t: Selects object which correspond to the pixel with input coordinates (x,y).",
1123     __FILE__, VtkSelect, group);
1124
1125   theCommands.Add("ivtkfit",
1126     "ivtkfit usage:\n"
1127     "ivtkfit"
1128     "\n\t\t: Fits view according all displayed objects.",
1129     __FILE__, VtkFit, group);
1130
1131   theCommands.Add("ivtkdump",
1132     "ivtkdump usage:\n"
1133     "ivtkdump <FullFilename>.{png|bmp|jpeg|tiff|pnm} [buffer={rgb|rgba|depth}] [width height] [stereoproj={L|R}]"
1134     "\n\t\t: Dumps contents of viewer window to PNG, BMP, JPEG, TIFF or PNM file",
1135     __FILE__, VtkDump, group);
1136
1137   theCommands.Add("ivtkbgcolor",
1138     "ivtkbgcolor usage:\n"
1139     "ivtkbgcolor r g b [r2 g2 b2]\n"
1140     "\n\t\t: Sets uniform  background color or gradient one if second triple of paramers is set."
1141     "Color parameters r,g,b = [0..255].",
1142     __FILE__, VtkBackgroundColor, group);
1143 }
1144
1145
1146 //================================================================
1147 // Function : Factory
1148 // Purpose  : 
1149 //================================================================
1150 void IVtkDraw::Factory (Draw_Interpretor& theDI)
1151 {
1152   // definition of Viewer Commands
1153   IVtkDraw::Commands (theDI);
1154 }
1155
1156 // Declare entry point PLUGINFACTORY
1157 DPLUGIN(IVtkDraw)
1158