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