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