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