0032308: Configuration - make Xlib dependency optional
[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 #ifdef _WIN32
17   #include <windows.h>
18   #include <WNT_WClass.hxx>
19   #include <WNT_Window.hxx>
20 #endif
21
22 #include <Draw.hxx>
23 #include <Draw_Interpretor.hxx>
24 #include <Draw_PluginMacro.hxx>
25 #include <TCollection_AsciiString.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRepTools.hxx>
29 #include <DBRep.hxx>
30 #include <NCollection_DoubleMap.hxx>
31 #include <NCollection_List.hxx>
32 #include <NCollection_DataMap.hxx>
33 #include <TopTools_DataMapOfIntegerShape.hxx>
34 #include <OpenGl_GraphicDriver.hxx>
35 #include <V3d.hxx>
36 #include <V3d_TypeOfOrientation.hxx>
37 #include <Aspect_DisplayConnection.hxx>
38
39 #include <IVtk_Types.hxx>
40 #include <IVtkVTK_ShapeData.hxx>
41 #include <IVtkOCC_Shape.hxx>
42 #include <IVtkOCC_ShapeMesher.hxx>
43 #include <IVtkTools_ShapeDataSource.hxx>
44 #include <IVtkTools_ShapeObject.hxx>
45 #include <IVtkTools_SubPolyDataFilter.hxx>
46 #include <IVtkTools_DisplayModeFilter.hxx>
47 #include <IVtkTools_ShapePicker.hxx>
48
49 #include <IVtkDraw.hxx>
50 #include <IVtkDraw_HighlightAndSelectionPipeline.hxx>
51 #include <IVtkDraw_Interactor.hxx>
52
53 // prevent disabling some MSVC warning messages by VTK headers 
54 #include <Standard_WarningsDisable.hxx>
55 #include <vtkAlgorithmOutput.h>
56 #include <vtkAppendPolyData.h>
57 #include <vtkBMPWriter.h>
58 #include <vtkCamera.h>
59 #include <vtkCellData.h>
60 #include <vtkCommand.h>
61 #include <vtkGeometryFilter.h>
62 #include <vtkIdTypeArray.h>
63 #include <vtkImageResize.h>
64 #include <vtkImageWriter.h>
65 #include <vtkInteractorStyleTrackballCamera.h>
66 #include <vtkJPEGWriter.h>
67 #include <vtkPNGWriter.h>
68 #include <vtkPNMWriter.h>
69 #include <vtkPolyDataMapper.h>
70 #include <vtkProperty.h>
71 #include <vtkRenderWindow.h>
72 #include <vtkRenderer.h>
73 #include <vtkRenderWindowInteractor.h>
74 #include <vtkSmartPointer.h>
75 #include <vtkTIFFWriter.h>
76 #include <vtkWindowToImageFilter.h>
77 #ifndef _WIN32
78   #include <X11/X.h>
79   #include <X11/Shell.h>
80   #include <X11/Xlib.h>
81   #include <X11/Xutil.h>
82   #include <GL/glx.h>
83   #include <Xw_Window.hxx>
84   #include <vtkXRenderWindowInteractor.h>
85   #include <vtkXOpenGLRenderWindow.h>
86 #endif
87 #include <Standard_WarningsRestore.hxx>
88
89 #if (VTK_MAJOR_VERSION > 8) || (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1)
90   #define HAVE_VTK_SRGB
91 #endif
92
93 //================================================================
94 // TYPE DEFINITIONS
95 //================================================================
96
97 typedef NCollection_DoubleMap<TopoDS_Shape, TCollection_AsciiString> DoubleMapOfShapesAndNames;
98 typedef NCollection_DoubleMap<vtkSmartPointer<vtkActor>, TCollection_AsciiString> DoubleMapOfActorsAndNames;
99
100 typedef IVtkDraw_HighlightAndSelectionPipeline PipelinePtr;
101
102 //================================================================
103 // GLOBAL VARIABLES
104 //================================================================
105
106 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
107
108 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
109 {
110   static Handle(Aspect_DisplayConnection) aDisplayConnection;
111   return aDisplayConnection;
112 }
113
114 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
115 {
116   GetDisplayConnection() = theDisplayConnection;
117 }
118
119 static DoubleMapOfShapesAndNames& GetMapOfShapes()
120 {
121   static DoubleMapOfShapesAndNames aMap;
122   return aMap;
123 }
124
125 static DoubleMapOfActorsAndNames& GetMapOfActors()
126 {
127   static DoubleMapOfActorsAndNames aMap;
128   return aMap;
129 }
130
131 static vtkSmartPointer<vtkRenderer>& GetRenderer()
132 {
133   static vtkSmartPointer<vtkRenderer> aRenderer;
134   return aRenderer;
135 }
136
137 static Handle(ShapePipelineMap)& GetPipelines()
138 {
139   static Handle(ShapePipelineMap) aPLMap;
140   if (aPLMap.IsNull())
141   {
142     aPLMap = new ShapePipelineMap();
143   }
144
145   return aPLMap;
146 }
147
148 static Handle(PipelinePtr) GetPipeline (const IVtk_IdType& theShapeID)
149 {
150   Handle(PipelinePtr) aPtr;
151   GetPipelines()->Find (theShapeID, aPtr);
152   return aPtr;
153 }
154
155 //! Get VTK render pipeline with shape ID got from actor.
156 static Handle(PipelinePtr) PipelineByActor (const vtkSmartPointer<vtkActor>& theActor)
157 {
158   IVtk_IdType aShapeID = IVtkTools_ShapeObject::GetShapeSource (theActor)->GetShape()->GetId();
159   return GetPipeline (aShapeID);
160 }
161
162 //! Get VTK render pipeline with actor that has the input name.
163 static Handle(PipelinePtr) PipelineByActorName (const TCollection_AsciiString& theName)
164 {
165   const vtkSmartPointer<vtkActor>& anActor = GetMapOfActors().Find2 (theName);
166   return PipelineByActor (anActor);
167 }
168
169 //! Create global presentation attributes.
170 static Handle(Prs3d_Drawer) createDefaultDrawer()
171 {
172   Handle(Prs3d_Drawer) aGlobalDrawer = new Prs3d_Drawer();
173   aGlobalDrawer->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
174   aGlobalDrawer->SetDeviationCoefficient (0.0001);
175   return aGlobalDrawer;
176 }
177
178 //! Get global presentation attributes (analog of AIS_InteractiveContext::DefaultDrawer()).
179 static const Handle(Prs3d_Drawer)& GetDefaultDrawer()
180 {
181   static Handle(Prs3d_Drawer) aGlobalDrawer = createDefaultDrawer();
182   return aGlobalDrawer;
183 }
184
185 #ifdef _WIN32
186
187 static Handle(WNT_Window)& GetWindow()
188 {
189   static Handle(WNT_Window) aWindow;
190   return aWindow;
191 }
192
193 #else
194
195 static Handle(Xw_Window)& GetWindow()
196 {
197   static Handle(Xw_Window) aXWWin;
198   return aXWWin;
199 }
200
201 #endif
202
203 static vtkSmartPointer<IVtkDraw_Interactor>& GetInteractor()
204 {
205   static vtkSmartPointer<IVtkDraw_Interactor> anInteractor;
206   return anInteractor;
207 }
208
209 static vtkSmartPointer<IVtkTools_ShapePicker>& GetPicker()
210 {
211   static vtkSmartPointer<IVtkTools_ShapePicker> aPicker;
212   return aPicker;
213 }
214
215 //! Generate identical number for shape
216 Standard_Integer GenerateId()
217 {
218   static unsigned int aShapesCounter = (unsigned int )-1;
219   return (Standard_Integer )++aShapesCounter;
220 }
221
222 //=========================================================
223 // Function : WClass
224 // Purpose  :
225 //=========================================================
226 const Handle(WNT_WClass)& IVtkDraw::WClass()
227 {
228   static Handle(WNT_WClass) aWindowClass;
229 #ifdef _WIN32
230   if (aWindowClass.IsNull())
231   {
232     aWindowClass = new WNT_WClass ("GWVTK_Class", NULL,
233                                    CS_VREDRAW | CS_HREDRAW, 0, 0,
234                                    ::LoadCursorW (NULL, IDC_ARROW));
235   }
236 #endif
237   return aWindowClass;
238 }
239
240 //==============================================================
241 // Function : ViewerInit
242 // Purpose  :
243 //==============================================================
244 void IVtkDraw::ViewerInit (const IVtkWinParams& theParams)
245 {
246   Standard_Integer aPxLeft  =   0, aPxTop    = 460;
247   Standard_Integer aPxWidth = 409, aPxHeight = 409;
248   if (theParams.TopLeft.x() != 0)
249   {
250     aPxLeft = theParams.TopLeft.x();
251   }
252   if (theParams.TopLeft.y() != 0)
253   {
254     aPxTop = theParams.TopLeft.y();
255   }
256   if (theParams.Size.x() != 0)
257   {
258     aPxWidth = theParams.Size.x();
259   }
260   if (theParams.Size.y() != 0)
261   {
262     aPxHeight = theParams.Size.y();
263   }
264
265   if (!GetRenderer())
266   {
267     SetDisplayConnection (new Aspect_DisplayConnection ());
268 #ifdef _WIN32
269     if (GetWindow().IsNull())
270     {
271       GetWindow() = new WNT_Window ("IVtkTest", WClass(),
272                                     WS_OVERLAPPEDWINDOW,
273                                     aPxLeft, aPxTop,
274                                     aPxWidth, aPxHeight,
275                                     Quantity_NOC_BLACK);
276       GetWindow()->SetVirtual (Draw_VirtualWindows);
277     }
278 #else
279
280     if (GetWindow().IsNull())
281     {
282       GetWindow() = new Xw_Window (GetDisplayConnection(),
283                                    "IVtkTest",
284                                    aPxLeft, aPxTop,
285                                    aPxWidth, aPxHeight);
286       GetWindow()->SetVirtual (Draw_VirtualWindows);
287     }
288 #endif
289     // Init pipeline
290     GetRenderer() = vtkSmartPointer<vtkRenderer>::New();
291
292     vtkSmartPointer<vtkRenderWindow> aRenWin = vtkSmartPointer<vtkRenderWindow>::New();
293     aRenWin->AddRenderer (GetRenderer());
294     GetRenderer()->GetActiveCamera()->ParallelProjectionOn();
295     aRenWin->SetSize (aPxWidth, aPxHeight);
296
297     aRenWin->SetMultiSamples (theParams.NbMsaaSample);
298     aRenWin->SetAlphaBitPlanes (1);
299   #ifdef HAVE_VTK_SRGB
300     aRenWin->SetUseSRGBColorSpace (theParams.UseSRGBColorSpace);
301   #else
302     if (theParams.UseSRGBColorSpace)
303     {
304       Message::SendWarning() << "Warning: skipped option -srgb unsupported by old VTK";
305     }
306   #endif
307
308 #ifdef _WIN32
309     aRenWin->SetWindowId((void*)GetWindow()->HWindow());
310 #else
311     Window aWindowId = GetWindow()->XWindow();
312     aRenWin->SetWindowId ((void*)aWindowId);
313     Display* aDisplayId = (Display* )GetDisplayConnection()->GetDisplayAspect();
314     aRenWin->SetDisplayId (aDisplayId);
315
316     // Setup XWindow
317     XSynchronize (aDisplayId, 1);
318     GetWindow()->Map();
319
320     // X11 : For keyboard on SUN
321     XWMHints wmhints;
322     wmhints.flags = InputHint;
323     wmhints.input = 1;
324
325     XSetWMHints (aDisplayId, aWindowId, &wmhints);
326
327     XSelectInput (aDisplayId, aWindowId,  ExposureMask | KeyPressMask |
328       ButtonPressMask | ButtonReleaseMask |
329       StructureNotifyMask |
330       PointerMotionMask |
331       Button1MotionMask | Button2MotionMask |
332       Button3MotionMask
333       );
334
335     XSynchronize (aDisplayId, 0);
336
337 #endif
338
339     // Init interactor
340     GetInteractor() = vtkSmartPointer<IVtkDraw_Interactor>::New();
341     GetInteractor()->SetRenderWindow (aRenWin);
342     GetInteractor()->SetOCCWindow (GetWindow());
343
344     vtkSmartPointer<vtkInteractorStyleTrackballCamera>
345       aStyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
346     GetInteractor()->SetInteractorStyle (aStyle);
347
348     // Init picker
349     GetPicker() = vtkSmartPointer<IVtkTools_ShapePicker>::New();
350     GetPicker()->SetTolerance (0.025f);
351     GetPicker()->SetRenderer (GetRenderer());
352
353     GetInteractor()->SetShapePicker (GetPicker());
354     GetInteractor()->SetPipelines (GetPipelines());
355     GetInteractor()->Initialize();
356
357     aRenWin->SetOffScreenRendering(Draw_VirtualWindows);
358     aRenWin->Render();
359   }
360
361   GetWindow()->Map();
362 }
363
364 //================================================================
365 // Function : VtkInit
366 // Purpose  : 
367 //================================================================
368 static Standard_Integer VtkInit (Draw_Interpretor& ,
369                                  Standard_Integer theNbArgs,
370                                  const char** theArgVec)
371 {
372   bool hasSize = false;
373   IVtkDraw::IVtkWinParams aParams;
374   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
375   {
376     TCollection_AsciiString anArg (theArgVec[anArgIter]);
377     anArg.LowerCase();
378     if (anArg == "-msaa"
379      && anArgIter + 1 < theNbArgs)
380     {
381       aParams.NbMsaaSample = Draw::Atoi (theArgVec[++anArgIter]);
382     }
383     else if (anArg == "-srgb")
384     {
385       aParams.UseSRGBColorSpace = true;
386       if (anArgIter + 1 < theNbArgs
387        && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.UseSRGBColorSpace))
388       {
389         ++anArgIter;
390       }
391     }
392     else if (!hasSize
393           && anArgIter + 3 < theNbArgs)
394     {
395       aParams.TopLeft.SetValues (Draw::Atoi (theArgVec[anArgIter + 0]),
396                                  Draw::Atoi (theArgVec[anArgIter + 1]));
397       aParams.Size   .SetValues (Draw::Atoi (theArgVec[anArgIter + 2]),
398                                  Draw::Atoi (theArgVec[anArgIter + 3]));
399     }
400     else
401     {
402       Message::SendFail() << "Syntax error at '" << anArg << "'";
403       return 1;
404     }
405   }
406
407   IVtkDraw::ViewerInit (aParams);
408   return 0;
409 }
410
411 //================================================================
412 // Function : VtkClose
413 // Purpose  :
414 //================================================================
415 static Standard_Integer VtkClose (Draw_Interpretor& ,
416                                   Standard_Integer theNbArgs,
417                                   const char** )
418 {
419   if (theNbArgs > 1)
420   {
421     Message::SendFail() << "Syntax error: wrong number of arguments";
422     return 1;
423   }
424
425   if (GetWindow())
426   {
427     GetWindow()->Unmap();
428   }
429
430   GetWindow().Nullify();
431   if (GetInteractor())
432   {
433     GetInteractor()->GetRenderWindow()->Finalize();
434     //GetInteractor()->SetRenderWindow (NULL);
435     GetInteractor()->TerminateApp();
436   }
437
438   GetInteractor() = NULL;
439   GetRenderer() = NULL;
440   GetPicker() = NULL;
441   return 0;
442 }
443
444 //================================================================
445 // Function : VtkRenderParams
446 // Purpose  :
447 //================================================================
448 static Standard_Integer VtkRenderParams (Draw_Interpretor& ,
449                                          Standard_Integer theNbArgs,
450                                          const char** theArgVec)
451 {
452   if (!GetInteractor()
453    || !GetInteractor()->IsEnabled())
454   {
455     Message::SendFail() << "Syntax error: call ivtkinit before";
456     return 1;
457   }
458   else if (theNbArgs <= 1)
459   {
460     Message::SendFail() << "Syntax error: wrong number of arguments";
461     return 1;
462   }
463
464   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
465   {
466     TCollection_AsciiString anArg (theArgVec[anArgIter]);
467     anArg.LowerCase();
468     if (anArg == "-depthpeeling"
469      && anArgIter + 1 < theNbArgs)
470     {
471       Standard_Integer aNbLayers = Draw::Atoi (theArgVec[++anArgIter]);
472       GetRenderer()->SetUseDepthPeeling (aNbLayers > 0);
473       GetRenderer()->SetMaximumNumberOfPeels (aNbLayers);
474     }
475     else if (anArg == "-shadows")
476     {
477       bool toUseShadows = true;
478       if (anArgIter + 1 < theNbArgs
479        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toUseShadows))
480       {
481         ++anArgIter;
482       }
483     #if (VTK_MAJOR_VERSION >= 7)
484       GetRenderer()->SetUseShadows (toUseShadows);
485     #else
486       Message::SendWarning() << "Warning: skipped option -shadows unsupported by old VTK";
487     #endif
488     }
489     else
490     {
491       Message::SendFail() << "Syntax error at '" << anArg << "'";
492       return 1;
493     }
494   }
495
496   GetInteractor()->GetRenderWindow()->Render();
497   return 0;
498 }
499
500
501 //================================================================
502 // Function : CreateActor
503 // Purpose  : 
504 //================================================================
505 vtkActor* CreateActor (const Standard_Integer theId,
506                        const TopoDS_Shape& theShape)
507 {
508   if ( theShape.IsNull() )
509   {
510     return NULL;
511   }
512
513   Handle(PipelinePtr) aPL = new PipelinePtr (theShape, theId, GetDefaultDrawer());
514   GetPipelines()->Bind (theId, aPL);
515
516   aPL->Actor()->GetProperty()->SetInterpolationToPhong();
517   return aPL->Actor();
518 }
519
520
521 //===============================================================================================
522 //function : VtkDefaults
523 //purpose  :
524 //===============================================================================================
525 static int VtkDefaults (Draw_Interpretor& theDi,
526                         Standard_Integer  theArgsNb,
527                         const char**      theArgVec)
528 {
529   const Handle(Prs3d_Drawer)& aDefParams = GetDefaultDrawer();
530   if (theArgsNb < 2)
531   {
532     if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
533     {
534       theDi << "DeflType:           relative\n"
535             << "DeviationCoeff:     " << aDefParams->DeviationCoefficient() << "\n";
536     }
537     else
538     {
539       theDi << "DeflType:           absolute\n"
540             << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
541     }
542     theDi << "AngularDeflection:  " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
543     theDi << "AutoTriangulation:  " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
544     return 0;
545   }
546
547   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
548   {
549     TCollection_AsciiString anArg (theArgVec[anArgIter]);
550     anArg.UpperCase();
551     if (anArg == "-ABSDEFL"
552      || anArg == "-ABSOLUTEDEFLECTION"
553      || anArg == "-DEFL"
554      || anArg == "-DEFLECTION")
555     {
556       if (++anArgIter >= theArgsNb)
557       {
558         theDi << "Syntax error at " << anArg;
559         return 1;
560       }
561       aDefParams->SetTypeOfDeflection         (Aspect_TOD_ABSOLUTE);
562       aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
563     }
564     else if (anArg == "-RELDEFL"
565           || anArg == "-RELATIVEDEFLECTION"
566           || anArg == "-DEVCOEFF"
567           || anArg == "-DEVIATIONCOEFF"
568           || anArg == "-DEVIATIONCOEFFICIENT")
569     {
570       if (++anArgIter >= theArgsNb)
571       {
572         theDi << "Syntax error at " << anArg;
573         return 1;
574       }
575       aDefParams->SetTypeOfDeflection     (Aspect_TOD_RELATIVE);
576       aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
577     }
578     else if (anArg == "-ANGDEFL"
579           || anArg == "-ANGULARDEFL"
580           || anArg == "-ANGULARDEFLECTION")
581     {
582       if (++anArgIter >= theArgsNb)
583       {
584         theDi << "Syntax error at " << anArg;
585         return 1;
586       }
587       aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
588     }
589     else if (anArg == "-AUTOTR"
590           || anArg == "-AUTOTRIANG"
591           || anArg == "-AUTOTRIANGULATION")
592     {
593       ++anArgIter;
594       bool toTurnOn = true;
595       if (anArgIter >= theArgsNb
596       || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
597       {
598         theDi << "Syntax error at '" << anArg << "'";
599         return 1;
600       }
601       aDefParams->SetAutoTriangulation (toTurnOn);
602     }
603     else
604     {
605       theDi << "Syntax error: unknown argument '" << anArg << "'";
606       return 1;
607     }
608   }
609
610   return 0;
611 }
612
613 //================================================================
614 // Function : VtkDisplay
615 // Purpose  : 
616 //================================================================
617
618 static Standard_Integer VtkDisplay (Draw_Interpretor& ,
619                                     Standard_Integer theArgNum,
620                                     const char** theArgs)
621 {
622   if (!GetInteractor()
623    || !GetInteractor()->IsEnabled())
624   {
625     Message::SendFail() << "Error : call ivtkinit before";
626     return 1;
627   }
628   if (theArgNum < 2)
629   {
630     Message::SendFail() << "Error : expects at least 1 argument\n";
631     return 1;
632   }
633
634   TCollection_AsciiString aName;
635   TopoDS_Shape anOldShape, aNewShape;
636   vtkSmartPointer<vtkRenderer>& aRenderer = GetRenderer();
637   for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
638   {
639     // Get name of shape
640     aName = theArgs[anIndex];
641     // Get shape from DRAW
642     aNewShape = DBRep::Get (theArgs[anIndex]);
643
644     // The shape is already in the map
645     if (GetMapOfShapes().IsBound2 (aName))
646     {
647       // Get shape from map
648       anOldShape = GetMapOfShapes().Find2 (aName);
649       // Equal shapes
650       if (anOldShape.IsEqual (aNewShape))
651       {
652         // Get actor from map and display it
653         PipelineByActorName (aName)->AddToRenderer (aRenderer);
654       }
655       // Different shapes
656       else
657       {
658         if (aNewShape.IsNull()) continue;
659         // Create actor from DRAW shape
660         vtkActor* anActor = CreateActor (GenerateId(), aNewShape);
661         // Remove old actor from render
662         PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
663         // Update maps
664         GetMapOfShapes().UnBind2 (aName);
665         GetMapOfShapes().Bind (aNewShape, aName);
666         GetMapOfActors().UnBind2 (aName);
667         GetMapOfActors().Bind (anActor, aName);
668         // Display new actor
669         PipelineByActorName (aName)->AddToRenderer (aRenderer);
670         // Compute selection for displayed actors
671         GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
672       }
673     }
674     // There is no shape with given name in map
675     else
676     {
677       if (aNewShape.IsNull()) continue;
678       // Create actor from DRAW shape
679       Standard_Integer anId = GenerateId();
680       vtkSmartPointer<vtkActor> anActor = CreateActor (anId, aNewShape);
681       // Update maps
682       GetMapOfShapes().Bind (aNewShape, aName);
683       GetMapOfActors().Bind (anActor, aName);
684       // Display actor
685       GetPipeline(anId)->AddToRenderer(aRenderer);
686
687       // Compute selection for displayed actors
688       GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
689     }
690   }
691
692   // Redraw window
693   aRenderer->ResetCamera();
694   GetInteractor()->GetRenderWindow()->Render();
695
696   return 0;
697 }
698
699 //================================================================
700 // Function : VtkErase
701 // Purpose  : 
702 //================================================================
703 static Standard_Integer VtkErase (Draw_Interpretor& ,
704                                   Standard_Integer theArgNum,
705                                   const char** theArgs)
706 {
707   if (!GetInteractor()
708    || !GetInteractor()->IsEnabled())
709   {
710     Message::SendFail() << "Error: call ivtkinit before";
711     return 1;
712   }
713
714   vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
715   if (theArgNum == 1)
716   {
717     // Erase all objects
718     DoubleMapOfActorsAndNames::Iterator anIterator (GetMapOfActors());
719     while (anIterator.More())
720     {
721       PipelineByActor (anIterator.Key1())->RemoveFromRenderer (aRenderer);
722       anIterator.Next();
723     }
724   }
725   else
726   {
727     // Erase named objects
728     for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
729     {
730       TCollection_AsciiString aName = theArgs[anIndex];
731       vtkSmartPointer<vtkActor> anActor;
732       if (!GetMapOfActors().Find2 (aName, anActor))
733       {
734         Message::SendFail() << "Syntax error: object '" << aName << "' not found";
735         return 1;
736       }
737
738       PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
739     }
740   }
741
742   // Redraw window
743   aRenderer->ResetCamera();
744   GetInteractor()->GetRenderWindow()->Render();
745   return 0;
746 }
747
748 //================================================================
749 // Function : VtkRemove
750 // Purpose  : Remove the actor from memory.
751 //================================================================
752 static Standard_Integer VtkRemove (Draw_Interpretor& ,
753                                    Standard_Integer theArgNum,
754                                    const char** theArgs)
755 {
756   if (!GetInteractor()
757    || !GetInteractor()->IsEnabled())
758   {
759     Message::SendFail() << "Error: call ivtkinit before";
760     return 1;
761   }
762
763   vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
764   if (theArgNum == 1)
765   {
766     // Remove all actors from the renderer
767     DoubleMapOfActorsAndNames::Iterator anIterator(GetMapOfActors());
768     while (anIterator.More())
769     {
770       vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc = IVtkTools_ShapeObject::GetShapeSource (anIterator.Key1());
771       if (aSrc.GetPointer() != NULL && !aSrc->GetShape().IsNull())
772       {
773         GetPicker()->RemoveSelectableObject(aSrc->GetShape());
774       }
775       else
776       {
777         aRenderer->RemoveActor(anIterator.Key1());
778       }
779       anIterator.Next();
780     }
781     // Remove all pipelines from the renderer
782     for (ShapePipelineMap::Iterator anIt(*GetPipelines()); anIt.More(); anIt.Next())
783     {
784       anIt.Value()->RemoveFromRenderer(aRenderer);
785     }
786     // Clear maps and remove all TopoDS_Shapes, actors and pipelines
787     GetMapOfShapes().Clear();
788     GetMapOfActors().Clear();
789     GetPipelines()->Clear();
790   }
791   else
792   {
793     // Remove named objects
794     for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
795     {
796       TCollection_AsciiString aName = theArgs[anIndex];
797       vtkSmartPointer<vtkActor> anActor;
798       if (!GetMapOfActors().Find2 (aName, anActor))
799       {
800         Message::SendFail() << "Syntax error: object '" << aName << "' not found";
801         return 1;
802       }
803
804       // Remove the actor and its pipeline (if found) from the renderer
805       vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
806       if (aSrc.GetPointer() != NULL && !aSrc->GetShape().IsNull())
807       {
808         IVtk_IdType aShapeID = aSrc->GetShape()->GetId();
809         GetPicker()->RemoveSelectableObject (aSrc->GetShape());
810         GetPipeline (aSrc->GetShape()->GetId())->RemoveFromRenderer (aRenderer);
811         GetPipelines()->UnBind (aShapeID); // Remove a pipeline
812       }
813       else
814       {
815         aRenderer->RemoveActor (anActor);
816       }
817       // Remove the TopoDS_Shape and the actor
818       GetMapOfShapes().UnBind2 (aName); // Remove a TopoDS shape
819       GetMapOfActors().UnBind2 (aName); // Remove an actor
820     }
821   }
822
823   // Redraw window
824   aRenderer->ResetCamera();
825   GetInteractor()->GetRenderWindow()->Render();
826   return 0;
827 }
828
829 //================================================================
830 // Function  : VtkSetDisplayMode
831 // Purpose   :
832 //================================================================
833 static Standard_Integer VtkSetDisplayMode (Draw_Interpretor& theDI,
834                                            Standard_Integer theArgNum,
835                                            const char** theArgs)
836 {
837   if (!GetInteractor()
838    || !GetInteractor()->IsEnabled())
839   {
840     theDI << "Error: call ivtkinit before";
841     return 1;
842   }
843
844   Standard_Integer aDispMode = -1;
845   Standard_Integer isFaceBoundaryDraw = -1, isSmoothShading = -1;
846   Graphic3d_TypeOfShadingModel aShadingModel = Graphic3d_TOSM_DEFAULT;
847   NCollection_Sequence< vtkSmartPointer<vtkActor> > anActors;
848   for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
849   {
850     TCollection_AsciiString anArgCase (theArgs[anArgIter]);
851     anArgCase.LowerCase();
852     if (anArgCase == "-faceboundarydraw"
853      || anArgCase == "-drawfaceboundary"
854      || anArgCase == "-faceboundary")
855     {
856       bool toDraw = Draw::ParseOnOffNoIterator (theArgNum, theArgs, anArgIter);
857       isFaceBoundaryDraw = toDraw ? 1 : 0;
858     }
859     else if (anArgCase == "-smoothshading"
860           || anArgCase == "-smooth")
861     {
862       bool toEnable = Draw::ParseOnOffNoIterator (theArgNum, theArgs, anArgIter);
863       isSmoothShading = toEnable ? 1 : 0;
864     }
865     else if (anArgIter + 1 < theArgNum
866           && (anArgCase == "-shadingmodel"))
867     {
868       TCollection_AsciiString aModelName (theArgs[++anArgIter]);
869       aModelName.LowerCase();
870       if (aModelName == "fragment"
871        || aModelName == "frag"
872        || aModelName == "phong")
873       {
874         aShadingModel = Graphic3d_TOSM_FRAGMENT;
875       }
876       else if (aModelName == "vertex"
877             || aModelName == "vert"
878             || aModelName == "gouraud")
879       {
880         aShadingModel = Graphic3d_TOSM_VERTEX;
881       }
882       else if (aModelName == "facet"
883             || aModelName == "flat")
884       {
885         aShadingModel = Graphic3d_TOSM_FACET;
886       }
887       else
888       {
889         theDI << "Syntax error: unknown shading model '" << theArgs[anArgIter] << "'";
890         return 1;
891       }
892     }
893     else if (aDispMode == -1
894           && (anArgCase == "0"
895            || anArgCase == "1"))
896     {
897       aDispMode = Draw::Atoi (theArgs[anArgIter]);
898     }
899     else if (aDispMode == -1
900           && (anArgCase == "-shaded"
901            || anArgCase == "-shading"))
902     {
903       aDispMode = DM_Shading;
904     }
905     else if (aDispMode == -1
906           && anArgCase == "-wireframe")
907     {
908       aDispMode = DM_Wireframe;
909     }
910     else
911     {
912       TCollection_AsciiString aName = theArgs[anArgIter];
913       vtkSmartPointer<vtkActor> anActor;
914       if (!GetMapOfActors().Find2 (aName, anActor))
915       {
916         theDI << "Syntax error: object '" << aName << "' not found";
917         return 1;
918       }
919       anActors.Append (anActor);
920     }
921   }
922   if (aDispMode == -1)
923   {
924     theDI << "Syntax error: wrong number of arguments";
925     return 1;
926   }
927
928   if (anActors.IsEmpty())
929   {
930     // update all objects
931     for (DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors()); anIter.More(); anIter.Next())
932     {
933       anActors.Append (anIter.Key1());
934     }
935   }
936
937   for (NCollection_Sequence< vtkSmartPointer<vtkActor> >::Iterator anActorIter (anActors); anActorIter.More(); anActorIter.Next())
938   {
939     vtkSmartPointer<vtkActor> anActor = anActorIter.Value();
940     IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
941     if (aSrc == NULL)
942     {
943       continue;
944     }
945
946     IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
947     if (!anOccShape.IsNull())
948     {
949       IVtkTools_DisplayModeFilter* aFilter = GetPipeline ( anOccShape->GetId() )->GetDisplayModeFilter();
950       aFilter->SetDisplayMode ((IVtk_DisplayMode)aDispMode);
951       if (isFaceBoundaryDraw != -1)
952       {
953         // Set Red color for boundary edges
954         vtkLookupTable* aTable = (vtkLookupTable*)anActor->GetMapper()->GetLookupTable();
955         IVtkTools::SetLookupTableColor (aTable, MT_SharedEdge, 1., 0., 0., 1.);
956         aFilter->SetFaceBoundaryDraw (isFaceBoundaryDraw == 1);
957       }
958       if (isSmoothShading != -1)
959       {
960         aFilter->SetSmoothShading (isSmoothShading == 1);
961       }
962       switch (aShadingModel)
963       {
964         case Graphic3d_TOSM_FACET:
965         {
966           anActor->GetProperty()->SetInterpolationToFlat();
967           break;
968         }
969         case Graphic3d_TOSM_VERTEX:
970         {
971           anActor->GetProperty()->SetInterpolationToGouraud();
972           break;
973         }
974         case Graphic3d_TOSM_FRAGMENT:
975         {
976           anActor->GetProperty()->SetInterpolationToPhong();
977           break;
978         }
979         default: break;
980       }
981
982       aFilter->Modified();
983       aFilter->Update();
984     }
985   }
986
987   // Redraw window
988   GetInteractor()->Render();
989   return 0;
990 }
991
992 //================================================================
993 // Function  : VtkSetSelectionMode
994 // Purpose   :
995 //================================================================
996 static Standard_Integer VtkSetSelectionMode (Draw_Interpretor& ,
997                                              Standard_Integer theArgNum,
998                                              const char** theArgs)
999 {
1000   if (!GetInteractor()
1001    || !GetInteractor()->IsEnabled())
1002   {
1003     Message::SendFail() << "Error: call ivtkinit before";
1004     return 1;
1005   }
1006   else if (theArgNum != 3 && theArgNum != 4)
1007   {
1008     Message::SendFail() << "Syntax error: expects 2 or 3 arguments";
1009     return 1;
1010   }
1011
1012   if (theArgNum == 3)
1013   {
1014     // Set sel mode for all objects
1015     const Standard_Integer aMode = Draw::Atoi (theArgs[1]);
1016     Standard_Boolean isTurnOn = true;
1017     if (aMode < 0 || aMode > 8 || !Draw::ParseOnOff (theArgs[2], isTurnOn))
1018     {
1019       Message::SendFail() << "Syntax error: only 0-8 selection modes are supported";
1020       return 1;
1021     }
1022     DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
1023     while (anIter.More())
1024     {
1025       vtkSmartPointer<vtkActor> anActor = anIter.Key1();
1026       if (aMode == SM_Shape && isTurnOn)
1027       {
1028         IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
1029         IVtk_SelectionModeList::Iterator anIt (aList);
1030         // Turn off all sel modes differed from SM_Shape
1031         while (anIt.More())
1032         {
1033           IVtk_SelectionMode aCurMode = anIt.Value();
1034           if (SM_Shape != aCurMode)
1035           {
1036             GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
1037           }
1038           anIt.Next();
1039         }
1040         GetPicker()->SetSelectionMode (anActor, SM_Shape);
1041       }
1042
1043       if (aMode != SM_Shape)
1044       {
1045         if (isTurnOn)
1046         {
1047           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
1048           GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
1049           if (aMode == SM_Vertex)
1050           {
1051             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
1052           }
1053         }
1054         else
1055         {
1056           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
1057           IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
1058           if (!aList.Size())
1059           {
1060             GetPicker()->SetSelectionMode(anActor, SM_Shape);
1061           }
1062           if (aMode == SM_Vertex)
1063           {
1064             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
1065           }
1066         }
1067       }
1068       anIter.Next();
1069     }
1070   }
1071
1072   if (theArgNum == 4)
1073   {
1074     // Set sel mode for named object
1075     const Standard_Integer aMode = Draw::Atoi (theArgs[2]);
1076     Standard_Boolean isTurnOn = true;
1077     if (aMode < 0 || aMode > 8 || !Draw::ParseOnOff (theArgs[3], isTurnOn))
1078     {
1079       Message::SendFail() << "Syntax error: only 0-8 selection modes are supported";
1080       return 1;
1081     }
1082
1083     TCollection_AsciiString aName = theArgs[1];
1084     if (GetMapOfActors().IsBound2 (aName))
1085     {
1086       vtkSmartPointer<vtkActor> anActor = GetMapOfActors().Find2 (aName);
1087       if (aMode == SM_Shape && isTurnOn)
1088       {
1089         IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
1090         IVtk_SelectionModeList::Iterator anIt (aList);
1091         // Turn off all sel modes differed from SM_Shape
1092         while (anIt.More())
1093         {
1094           IVtk_SelectionMode aCurMode = anIt.Value();
1095           if (SM_Shape != aCurMode)
1096           {
1097             GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
1098           }
1099           anIt.Next();
1100         }
1101         GetPicker()->SetSelectionMode (anActor, SM_Shape);
1102       }
1103
1104       if (aMode != SM_Shape)
1105       {
1106         if (isTurnOn)
1107         {
1108           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
1109           GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
1110           if (aMode == SM_Vertex)
1111           {
1112             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
1113           }
1114         }
1115         else
1116         {
1117           GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
1118           IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
1119           if (!aList.Size())
1120           {
1121             GetPicker()->SetSelectionMode(anActor, SM_Shape);
1122           }
1123           if (aMode == SM_Vertex)
1124           {
1125             GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
1126           }
1127         }
1128       }
1129     }
1130   }
1131
1132   // Redraw window
1133   GetInteractor()->Render();
1134   return 0;
1135 }
1136
1137 //================================================================
1138 // Function  : VtkSetColor
1139 // Purpose   :
1140 //================================================================
1141 static Standard_Integer VtkSetColor (Draw_Interpretor& ,
1142                                      Standard_Integer theArgNb,
1143                                      const char** theArgVec)
1144 {
1145   if (!GetInteractor()
1146    || !GetInteractor()->IsEnabled())
1147   {
1148     Message::SendFail() << "Error: call ivtkinit before\n";
1149     return 1;
1150   }
1151
1152   NCollection_Sequence< vtkSmartPointer<vtkActor> > anActorSeq;
1153   Quantity_Color aQColor;
1154   bool hasColor = false;
1155   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
1156   {
1157     TCollection_AsciiString anArg (theArgVec[anArgIter]);
1158     vtkSmartPointer<vtkActor> anActor;
1159     if (hasColor)
1160     {
1161       Message::SendFail() << "Syntax error at '" << anArg << "'";
1162       return 1;
1163     }
1164     else if (GetMapOfActors().Find2 (anArg, anActor))
1165     {
1166       anActorSeq.Append (anActor);
1167     }
1168     else
1169     {
1170       Standard_Integer aNbParsed = Draw::ParseColor (theArgNb  - anArgIter,
1171                                                      theArgVec + anArgIter,
1172                                                      aQColor);
1173       if (aNbParsed == 0)
1174       {
1175         Message::SendFail() << "Syntax error at '" << anArg << "'";
1176         return 1;
1177       }
1178       anArgIter += aNbParsed - 1;
1179       hasColor = true;
1180     }
1181   }
1182   if (!hasColor || anActorSeq.IsEmpty())
1183   {
1184     Message::SendFail() << "Syntax error: wrong number of arguments";
1185     return 1;
1186   }
1187
1188   bool isSRGBAware = false;
1189 #ifdef HAVE_VTK_SRGB
1190   isSRGBAware = GetRenderer()->GetRenderWindow()->GetUseSRGBColorSpace();
1191 #endif
1192   const Graphic3d_Vec3 aColor = isSRGBAware ? (Graphic3d_Vec3 )aQColor : Quantity_Color::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec3 )aQColor);
1193   for (NCollection_Sequence< vtkSmartPointer<vtkActor> >::Iterator anActorIter (anActorSeq); anActorIter.More(); anActorIter.Next())
1194   {
1195     const vtkSmartPointer<vtkActor>& anActor = anActorIter.Value();
1196     vtkLookupTable* aTable = (vtkLookupTable* )anActor->GetMapper()->GetLookupTable();
1197     IVtkTools::SetLookupTableColor (aTable, MT_ShadedFace, aColor.r(), aColor.g(), aColor.b(), 1.0);
1198   }
1199
1200   GetInteractor()->Render();
1201   return 0;
1202 }
1203
1204 //================================================================
1205 // Function  : VtkSetTransparency
1206 // Purpose   :
1207 //================================================================
1208 static Standard_Integer VtkSetTransparency (Draw_Interpretor& ,
1209                                             Standard_Integer theArgNb,
1210                                             const char** theArgVec)
1211 {
1212   if (!GetInteractor()
1213    || !GetInteractor()->IsEnabled())
1214   {
1215     Message::SendFail() << "Error: call ivtkinit before\n";
1216     return 1;
1217   }
1218
1219   NCollection_Sequence< vtkSmartPointer<vtkActor> > anActorSeq;
1220   Standard_Real aTransparency = -1.0;
1221   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
1222   {
1223     TCollection_AsciiString anArg (theArgVec[anArgIter]);
1224     vtkSmartPointer<vtkActor> anActor;
1225     if (aTransparency >= 0.0)
1226     {
1227       Message::SendFail() << "Syntax error at '" << anArg << "'";
1228       return 1;
1229     }
1230     else if (GetMapOfActors().Find2 (anArg, anActor))
1231     {
1232       anActorSeq.Append (anActor);
1233     }
1234     else if (!Draw::ParseReal (theArgVec[anArgIter], aTransparency)
1235            || aTransparency < 0.0
1236            || aTransparency >= 1.0)
1237     {
1238       Message::SendFail() << "Syntax error at '" << anArg << "'";
1239       return 1;
1240     }
1241   }
1242   if (aTransparency < 0.0 || aTransparency >= 1)
1243   {
1244     Message::SendFail() << "Syntax error: wrong number of arguments";
1245     return 1;
1246   }
1247
1248   for (NCollection_Sequence< vtkSmartPointer<vtkActor> >::Iterator anActorIter (anActorSeq); anActorIter.More(); anActorIter.Next())
1249   {
1250     const vtkSmartPointer<vtkActor>& anActor = anActorIter.Value();
1251     anActor->GetProperty()->SetOpacity (1.0 - aTransparency);
1252   }
1253
1254   GetInteractor()->Render();
1255   return 0;
1256 }
1257
1258 //================================================================
1259 // Function  : VtkMoveTo
1260 // Purpose   : 
1261 // Draw args : ivtkmoveto x y
1262 //================================================================
1263 static Standard_Integer VtkMoveTo(Draw_Interpretor& theDI,
1264                                   Standard_Integer theArgNum,
1265                                   const char** theArgs)
1266 {
1267   if (!GetInteractor()
1268    || !GetInteractor()->IsEnabled())
1269   {
1270     Message::SendFail() << "Error: call ivtkinit before";
1271     return 1;
1272   }
1273   else if (theArgNum != 3)
1274   {
1275     Message::SendFail() << "Syntax error: expects 2 arguments";
1276     return 1;
1277   }
1278
1279   Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[2]) - 1;
1280   GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
1281
1282   gp_XYZ aPickPnt;
1283   GetInteractor()->Selector()->GetPickPosition (aPickPnt.ChangeData());
1284   theDI << aPickPnt.X() << " " << aPickPnt.Y() << " " << aPickPnt.Z();
1285   return 0;
1286 }
1287
1288 //================================================================
1289 // Function  : VtkSelect
1290 // Purpose   :
1291 //================================================================
1292 static Standard_Integer VtkSelect (Draw_Interpretor& ,
1293                                    Standard_Integer theArgNum,
1294                                    const char** theArgs)
1295 {
1296   if (!GetInteractor()
1297    || !GetInteractor()->IsEnabled())
1298   {
1299     Message::SendFail() << "Error: call ivtkinit before";
1300     return 1;
1301   }
1302   else if (theArgNum != 3)
1303   {
1304     Message::SendFail() << "Syntax error: expects 3 arguments";
1305     return 1;
1306   }
1307
1308   Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[2]) - 1;
1309   GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
1310   GetInteractor()->OnSelection();
1311   return 0;
1312
1313 }
1314
1315 //===================================================================
1316 // Fubction  : VtkViewProj
1317 // Purpose   :
1318 //===================================================================
1319 static Standard_Integer VtkViewProj (Draw_Interpretor& ,
1320                                      Standard_Integer theNbArgs,
1321                                      const char** theArgVec)
1322 {
1323   if (!GetInteractor()
1324    || !GetInteractor()->IsEnabled())
1325   {
1326     Message::SendFail() << "Error: call ivtkinit before";
1327     return 1;
1328   }
1329   else if (theNbArgs != 1)
1330   {
1331     Message::SendFail() << "Syntax error: wrong number of arguments";
1332     return 1;
1333   }
1334
1335   TCollection_AsciiString aCmd (theArgVec[0]);
1336   aCmd.LowerCase();
1337
1338   V3d_TypeOfOrientation aProj = V3d_Xpos;
1339   bool hasProjDir = false;
1340   if (aCmd == "ivtkaxo")
1341   {
1342     hasProjDir = true;
1343     aProj = V3d_TypeOfOrientation_Zup_AxoRight;
1344   }
1345   else if (aCmd == "ivtktop")
1346   {
1347     hasProjDir = true;
1348     aProj = V3d_TypeOfOrientation_Zup_Top;
1349   }
1350   else if (aCmd == "ivtkbottom")
1351   {
1352     hasProjDir = true;
1353     aProj = V3d_TypeOfOrientation_Zup_Bottom;
1354   }
1355   else if (aCmd == "ivtkfront")
1356   {
1357     hasProjDir = true;
1358     aProj = V3d_TypeOfOrientation_Zup_Front;
1359   }
1360   else if (aCmd == "ivtkback")
1361   {
1362     hasProjDir = true;
1363     aProj = V3d_TypeOfOrientation_Zup_Back;
1364   }
1365   else if (aCmd == "ivtkleft")
1366   {
1367     hasProjDir = true;
1368     aProj = V3d_TypeOfOrientation_Zup_Left;
1369   }
1370   else if (aCmd == "ivtkright")
1371   {
1372     hasProjDir = true;
1373     aProj = V3d_TypeOfOrientation_Zup_Right;
1374   }
1375
1376   if (hasProjDir)
1377   {
1378     const gp_Dir aBck = V3d::GetProjAxis (aProj);
1379     Graphic3d_Vec3d anUp (0.0, 0.0, 1.0);
1380     if (aProj == V3d_Zpos)
1381     {
1382       anUp.SetValues (0.0, 1.0, 0.0);
1383     }
1384     else if (aProj == V3d_Zneg)
1385     {
1386       anUp.SetValues (0.0, -1.0, 0.0);
1387     }
1388
1389     vtkCamera* aCam = GetRenderer()->GetActiveCamera();
1390     const double aDist = aCam->GetDistance();
1391
1392     Graphic3d_Vec3d aNewEye = Graphic3d_Vec3d (aBck.X(), aBck.Y(), aBck.Z()) * aDist;
1393     aCam->SetPosition (aNewEye.x(), aNewEye.y(), aNewEye.z());
1394     aCam->SetFocalPoint (0.0, 0.0, 0.0);
1395     aCam->SetViewUp (anUp.x(), anUp.y(), anUp.z());
1396     aCam->OrthogonalizeViewUp();
1397   }
1398
1399   GetRenderer()->ResetCamera();
1400   GetInteractor()->Render();
1401   return 0;
1402 }
1403
1404 //===================================================================
1405 // Fubction  : VtkDump
1406 // Purpose   :
1407 //===================================================================
1408 static Standard_Integer VtkDump (Draw_Interpretor& ,
1409                                  Standard_Integer theArgNum,
1410                                  const char** theArgs)
1411 {
1412   if (!GetInteractor()
1413    || !GetInteractor()->IsEnabled())
1414   {
1415     Message::SendFail() << "Error : call ivtkinit before";
1416     return 1;
1417   }
1418   else if (theArgNum < 2)
1419   {
1420     Message::SendFail() << "Syntax error: wrong number of parameters";
1421     return 1;
1422   }
1423
1424   vtkSmartPointer<vtkWindowToImageFilter> anImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
1425   anImageFilter->SetInput (GetInteractor()->GetRenderWindow());
1426   // Set custom buffer type
1427   if (theArgNum > 2)
1428   {
1429     TCollection_AsciiString aBufferType (theArgs[2]);
1430     aBufferType.LowerCase();
1431     if (aBufferType.IsEqual ("rgb"))
1432     {
1433       anImageFilter->SetInputBufferTypeToRGB();
1434     }
1435     else if (aBufferType.IsEqual ("rgba"))
1436     {
1437       anImageFilter->SetInputBufferTypeToRGBA();
1438     }
1439     else if (aBufferType.IsEqual ("depth"))
1440     {
1441       anImageFilter->SetInputBufferTypeToZBuffer();
1442     }
1443   }
1444   anImageFilter->Update();
1445
1446   // Set custom stereo projection options
1447   if (theArgNum > 5 && GetRenderer()->GetRenderWindow()->GetStereoRender())
1448   {
1449     Standard_CString aStereoProjStr = theArgs[5];
1450
1451     Standard_Integer aStereoType =  GetRenderer()->GetRenderWindow()->GetStereoType();
1452     if (strcasecmp (aStereoProjStr, "L"))
1453     {
1454       GetRenderer()->GetRenderWindow()->SetStereoTypeToLeft();
1455       GetRenderer()->GetRenderWindow()->StereoUpdate();
1456       anImageFilter->Update();
1457       GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
1458     }
1459     else if (strcasecmp (aStereoProjStr, "R"))
1460     {
1461       GetRenderer()->GetRenderWindow()->SetStereoTypeToRight();
1462       GetRenderer()->GetRenderWindow()->StereoUpdate();
1463       anImageFilter->Update();
1464       GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
1465     }
1466     else
1467     {
1468       Message::SendFail() << "Syntax error: unknown value for stereo projection";
1469       return 1;
1470     }
1471   }
1472
1473   // Set parameters for image writer
1474   vtkSmartPointer<vtkImageWriter> anImageWriter;
1475   TCollection_AsciiString aFilename (theArgs[1]);
1476   Standard_Integer anExtStart = aFilename.SearchFromEnd (TCollection_AsciiString("."));
1477   TCollection_AsciiString aFormat = (anExtStart == -1) ? TCollection_AsciiString("")
1478                                     : aFilename.SubString (anExtStart + 1, aFilename.Length());
1479   aFormat.LowerCase();
1480
1481   if (aFormat.IsEqual ("png"))
1482   {
1483     anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
1484   }
1485   else if (aFormat.IsEqual ("bmp"))
1486   {
1487     anImageWriter = vtkSmartPointer<vtkBMPWriter>::New();
1488   }
1489   else if (aFormat.IsEqual ("jpeg"))
1490   {
1491     anImageWriter = vtkSmartPointer<vtkJPEGWriter>::New();
1492   }
1493   else if (aFormat.IsEqual ("tiff"))
1494   {
1495     anImageWriter = vtkSmartPointer<vtkTIFFWriter>::New();
1496   }
1497   else if (aFormat.IsEqual ("pnm"))
1498   {
1499     anImageWriter = vtkSmartPointer<vtkPNMWriter>::New();
1500   }
1501   else // aFormat is unsupported or not set.
1502   {
1503     if (aFormat.IsEmpty())
1504     {
1505       Message::SendWarning() << "Warning: the image format is not set.\n"
1506             << "The image will be saved into PNG format.";
1507       anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
1508       aFormat = TCollection_AsciiString ("png");
1509       if (anExtStart != -1)
1510       {
1511         aFilename.Split (anExtStart);
1512       }
1513       else
1514       {
1515         aFilename += ".";
1516       }
1517       aFilename += aFormat;
1518     }
1519     else
1520     {
1521       Message::SendFail() << "Error: the image format " << aFormat << " is not supported";
1522       return 1;
1523     }
1524
1525   }
1526
1527   anImageWriter->SetFileName (aFilename.ToCString());
1528
1529   Standard_Integer aWidth = (theArgNum > 3) ? atoi (theArgs[3]) : 0;
1530   Standard_Integer aHeight = (theArgNum > 4) ? atoi (theArgs[4]) : 0;
1531   if (aWidth >= 0 || aHeight >= 0)
1532   {
1533     // Scale image
1534     vtkSmartPointer<vtkImageResize> anImageResize = vtkSmartPointer<vtkImageResize>::New();
1535 #if VTK_MAJOR_VERSION <= 5
1536     anImageResize->SetInput (anImageFilter->GetOutput());
1537 #else
1538     anImageResize->SetInputData (anImageFilter->GetOutput());
1539 #endif
1540
1541     anImageResize->SetOutputDimensions (aWidth, aHeight, 1);
1542     anImageResize->Update();
1543     anImageWriter->SetInputConnection (anImageResize->GetOutputPort());
1544   }
1545   else
1546   {
1547     anImageWriter->SetInputConnection (anImageFilter->GetOutputPort());
1548   }
1549   anImageWriter->Write();
1550   return 0;
1551 }
1552
1553 //===================================================================
1554 // Fubction  : VtkBackgroundColor
1555 // Purpose   :
1556 //===================================================================
1557 static Standard_Integer VtkBackgroundColor (Draw_Interpretor& ,
1558                                             Standard_Integer theArgNum,
1559                                             const char** theArgs)
1560 {
1561   if (!GetInteractor()
1562    || !GetInteractor()->IsEnabled())
1563   {
1564     Message::SendFail() << "Error: call ivtkinit before";
1565     return 1;
1566   }
1567
1568   Quantity_Color aQColor1;
1569   const Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNum - 1, theArgs + 1, aQColor1);
1570   if (aNbParsed1 == 0)
1571   {
1572     Message::SendFail() << "Syntax error: wrong number of parameters";
1573     return 1;
1574   }
1575
1576   bool isSRGBAware = false;
1577 #ifdef HAVE_VTK_SRGB
1578   isSRGBAware = GetRenderer()->GetRenderWindow()->GetUseSRGBColorSpace();
1579 #endif
1580   const Graphic3d_Vec3 aColor1 = isSRGBAware ? (Graphic3d_Vec3 )aQColor1 : Quantity_Color::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec3 )aQColor1);
1581   GetRenderer()->SetGradientBackground(false);
1582   GetRenderer()->SetBackground (aColor1.r(), aColor1.g(), aColor1.b());
1583   if (theArgNum - 1 > aNbParsed1)
1584   {
1585     Quantity_Color aQColor2;
1586     const Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNum - 1 - aNbParsed1, theArgs + 1 + aNbParsed1, aQColor2);
1587     if (aNbParsed2 == 0)
1588     {
1589       Message::SendFail() << "Syntax error: wrong number of parameters";
1590       return 1;
1591     }
1592
1593     const Graphic3d_Vec3 aColor2 = isSRGBAware ? (Graphic3d_Vec3 )aQColor2 : Quantity_Color::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec3 )aQColor2);
1594     GetRenderer()->SetBackground2 (aColor2.r(), aColor2.g(), aColor2.b());
1595     GetRenderer()->SetGradientBackground (true);
1596   }
1597
1598   GetInteractor()->Render();
1599   return 0;
1600 }
1601
1602 //================================================================
1603 // Function : Commands
1604 // Purpose  : 
1605 //================================================================
1606 void IVtkDraw::Commands (Draw_Interpretor& theCommands)
1607 {
1608   const char *group = "VtkViewer";
1609
1610   theCommands.Add("ivtkinit",
1611               "ivtkinit [leftPx topPx widthPx heightPx] [-srgb {on|off}] [-msaa NbSamples]"
1612       "\n\t\t: Creates the Vtk window."
1613       "\n\t\t:  -srgb Enable/disable sRGB colorspace; OFF by default."
1614       "\n\t\t:  -msaa Requests desired number of samples for multisampling buffer;"
1615       "\n\t\t:        0 by default meaning no MSAA.",
1616     __FILE__, VtkInit, group);
1617
1618   theCommands.Add("ivtkclose",
1619               "ivtkclose : Closes the Vtk window.",
1620     __FILE__, VtkClose, group);
1621
1622   theCommands.Add("ivtkdefaults",
1623                "ivtkdefaults [-absDefl value]"
1624        "\n\t\t:              [-devCoeff value]"
1625        "\n\t\t:              [-angDefl value]"
1626        "\n\t\t:              [-autoTriang {off/on | 0/1}]"
1627        "\n\t\t: Sets default VTK meshing parameters."
1628     , __FILE__, VtkDefaults, group);
1629
1630   theCommands.Add("ivtkrenderparams",
1631               "ivtkrenderparams [-depthPeeling NbLayers] [-shadows {on|off}]"
1632       "\n\t\t: Sets Vtk rendering parameters."
1633       "\n\t\t:  -shadows      Turn shadows on/off; OFF by default."
1634       "\n\t\t:  -depthPeeling Enable/disable depth peeling for rendering transparent objects"
1635       "\n\t\t:                with specified number of layers;"
1636       "\n\t\t:                0 by default meaning order-dependent transparency without depth peeling.",
1637     __FILE__, VtkRenderParams, group);
1638
1639   theCommands.Add("ivtkdisplay",
1640               "ivtkdisplay name1 [name2 ...]"
1641       "\n\t\t: Displays named objects in Vtk view.",
1642     __FILE__, VtkDisplay, group);
1643
1644   theCommands.Add("ivtkerase",
1645               "ivtkerase [name1 name2 ...]"
1646       "\n\t\t: Hides in Vtk renderer named objects or all objects.",
1647     __FILE__, VtkErase, group);
1648
1649   theCommands.Add("ivtkremove",
1650               "ivtkremove name1 [name2 ...]"
1651       "\n\t\t: Removes from Vtk renderer named objects.",
1652     __FILE__, VtkRemove, group);
1653
1654   theCommands.Add("ivtkclear",
1655               "ivtkclear : Removes all objects from Vtk renderer.",
1656     __FILE__, VtkRemove, group);
1657
1658   theCommands.Add("ivtksetdispmode",
1659               "ivtksetdispmode [name] mode={0|1} [-faceBoundaryDraw {0|1}] [-smoothShading {0|1}]"
1660       "\n\t\t:                                   [-shadingModel {phong|gouraud|flat}]"
1661       "\n\t\t: Sets or unsets display mode to the object with the given name or to all objects."
1662       "\n\t\t:   -faceBoundaryDraw show/hide boundaries within shading display mode"
1663       "\n\t\t:   -smoothShading    enable/disable vertex normals for smooth shading"
1664       "\n\t\t:   -shadingModel     sets specified shading model",
1665     __FILE__, VtkSetDisplayMode, group);
1666
1667   theCommands.Add("ivtksetselmode",
1668               "ivtksetselmode [name] mode {on|off}"
1669       "\n\t\t: Sets or unsets selection mode 'mode' to the object with name 'name'"
1670       "\n\t\t: or to the all displayed objects.",
1671     __FILE__, VtkSetSelectionMode, group);
1672
1673   theCommands.Add("ivtkmoveto",
1674               "ivtkmoveto x y"
1675       "\n\t\t: Moves position to the pixel with coordinates (x,y). The object on this position is highlighted.",
1676     __FILE__, VtkMoveTo, group);
1677
1678   theCommands.Add("ivtkselect",
1679               "ivtkselect x y"
1680       "\n\t\t: Selects object which correspond to the pixel with input coordinates (x,y).",
1681     __FILE__, VtkSelect, group);
1682
1683   theCommands.Add("ivtkfit",
1684               "ivtkfit : Fits all displayed objects into Vtk view.",
1685     __FILE__, VtkViewProj, group);
1686
1687   theCommands.Add("ivtkaxo",
1688               "ivtkaxo : Resets Vtk view orientation to axo",
1689     __FILE__, VtkViewProj, group);
1690
1691   theCommands.Add("ivtkfront",
1692               "ivtkfront : Resets Vtk view orientation to front",
1693     __FILE__, VtkViewProj, group);
1694
1695   theCommands.Add("ivtkback",
1696               "ivtkback : Resets Vtk view orientation to back",
1697     __FILE__, VtkViewProj, group);
1698
1699   theCommands.Add("ivtktop",
1700               "ivtktop : Resets Vtk view orientation to top",
1701     __FILE__, VtkViewProj, group);
1702
1703   theCommands.Add("ivtkbottom",
1704               "ivtkbottom : Resets Vtk view orientation to bottom",
1705     __FILE__, VtkViewProj, group);
1706
1707   theCommands.Add("ivtkleft",
1708               "ivtkleft : Resets Vtk view orientation to left",
1709     __FILE__, VtkViewProj, group);
1710
1711   theCommands.Add("ivtkright",
1712               "ivtkright : Resets Vtk view orientation to right",
1713     __FILE__, VtkViewProj, group);
1714
1715   theCommands.Add("ivtkdump",
1716               "ivtkdump <FullFilename>.{png|bmp|jpeg|tiff|pnm} [buffer={rgb|rgba|depth}]"
1717       "\n\t\t:          [width height] [stereoproj={L|R}]"
1718       "\n\t\t: Dumps contents of viewer window to PNG, BMP, JPEG, TIFF or PNM file.",
1719     __FILE__, VtkDump, group);
1720
1721   theCommands.Add("ivtkbgcolor",
1722               "ivtkbgcolor Color1 [Color2]"
1723       "\n\t\t: Sets uniform background color or gradient one if second triple of parameters is set.",
1724     __FILE__, VtkBackgroundColor, group);
1725
1726   theCommands.Add("ivtksetcolor",
1727               "ivtksetcolor name {ColorName|R G B}"
1728       "\n\t\t: Sets color to the object with name 'name'.",
1729     __FILE__, VtkSetColor, group);
1730
1731   theCommands.Add("ivtksettransparency",
1732               "ivtksettransparency name 0..1"
1733       "\n\t\t: Sets transparency to the object with name 'name'.",
1734     __FILE__, VtkSetTransparency, group);
1735 }
1736
1737 //================================================================
1738 // Function : Factory
1739 // Purpose  : 
1740 //================================================================
1741 void IVtkDraw::Factory (Draw_Interpretor& theDI)
1742 {
1743   // definition of Viewer Commands
1744   IVtkDraw::Commands (theDI);
1745 }
1746
1747 // Declare entry point PLUGINFACTORY
1748 DPLUGIN(IVtkDraw)