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