0022877: Implementation of DRAW commands for non-regression testing:
authoraba <aba@opencascade.com>
Thu, 11 Sep 2014 09:37:09 +0000 (13:37 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 11 Sep 2014 09:39:44 +0000 (13:39 +0400)
- TKIVtkDraw toolkit provides IVtk packages functionality in DRAW.

- it allows to create VTK interactive view in regular or virtual mode (virtual windows),
  display OCC objects and dump them.

- TKIVtkDraw provides also test commands: ivtlinit, ivtkdisplay, ivtkerase, ivtksetdispmode,
   ivtksetselmode, ivtkmoveto, ivtkselect, ivtkfit, ivtkdump, ivtkbgcolor.

Corrected offscreen rendering mode.

Moved vinit command from /v3d/begin script to avoid unused occ view in ivtk tests.

39 files changed:
adm/UDLIST
src/DrawResources/DrawPlugin
src/IVtkDraw/EXTERNLIB [new file with mode: 0644]
src/IVtkDraw/FILES [new file with mode: 0644]
src/IVtkDraw/IVtkDraw.cxx [new file with mode: 0644]
src/IVtkDraw/IVtkDraw.hxx [new file with mode: 0644]
src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.cxx [new file with mode: 0644]
src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.hxx [new file with mode: 0644]
src/IVtkDraw/IVtkDraw_Interactor.cxx [new file with mode: 0644]
src/IVtkDraw/IVtkDraw_Interactor.hxx [new file with mode: 0644]
src/OS/Draw.tcl
src/TKIVtkDraw/EXTERNLIB [new file with mode: 0644]
src/TKIVtkDraw/FILES [new file with mode: 0644]
src/TKIVtkDraw/PACKAGES [new file with mode: 0644]
tests/v3d/begin
tests/v3d/edge/begin
tests/v3d/edge_face/begin
tests/v3d/edge_solid/begin
tests/v3d/end
tests/v3d/face/begin
tests/v3d/glsl/begin [new file with mode: 0644]
tests/v3d/grids.list
tests/v3d/ivtk/begin [new file with mode: 0644]
tests/v3d/ivtk/bgcolor [new file with mode: 0644]
tests/v3d/ivtk/detect [new file with mode: 0644]
tests/v3d/ivtk/display_mode [new file with mode: 0644]
tests/v3d/ivtk/erase [new file with mode: 0644]
tests/v3d/ivtk/select [new file with mode: 0644]
tests/v3d/ivtk/selection_mode [new file with mode: 0644]
tests/v3d/materials/begin [new file with mode: 0644]
tests/v3d/raytrace/begin [new file with mode: 0644]
tests/v3d/vertex/begin
tests/v3d/vertex_edge/begin
tests/v3d/vertex_face/begin
tests/v3d/vertex_solid/begin
tests/v3d/vertex_wire/begin
tests/v3d/voxel/begin [new file with mode: 0644]
tests/v3d/wire/begin
tests/v3d/wire_solid/begin

index d0943c0..c0ca732 100644 (file)
@@ -480,3 +480,5 @@ p IVtkOCC
 p IVtkVTK
 p IVtkTools
 t TKIVtk
+p IVtkDraw
+t TKIVtkDraw
\ No newline at end of file
index 2660d47..dc17bad 100755 (executable)
@@ -48,3 +48,4 @@ XDEDRAW            : TKXDEDRAW
 TOBJ               : TKTObjDRAW
 DFBROWSER          : TKDFBrowser
 QAcommands         : TKQADraw
+VIS                : TKIVtkDraw
diff --git a/src/IVtkDraw/EXTERNLIB b/src/IVtkDraw/EXTERNLIB
new file mode 100644 (file)
index 0000000..72e05d5
--- /dev/null
@@ -0,0 +1 @@
+CSF_VTK
\ No newline at end of file
diff --git a/src/IVtkDraw/FILES b/src/IVtkDraw/FILES
new file mode 100644 (file)
index 0000000..2e5104a
--- /dev/null
@@ -0,0 +1,7 @@
+EXTERNLIB
+IVtkDraw.hxx
+IVtkDraw.cxx
+IVtkDraw_HighlightAndSelectionPipeline.hxx
+IVtkDraw_HighlightAndSelectionPipeline.cxx
+IVtkDraw_Interactor.hxx
+IVtkDraw_Interactor.cxx
diff --git a/src/IVtkDraw/IVtkDraw.cxx b/src/IVtkDraw/IVtkDraw.cxx
new file mode 100644 (file)
index 0000000..3310415
--- /dev/null
@@ -0,0 +1,1159 @@
+// Created on: 2012-02-03 
+// 
+// Copyright (c) 2012-2014 OPEN CASCADE SAS 
+// 
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#ifdef NOMINMAX
+#undef NOMINMAX    /* avoid #define min() and max() */
+#endif
+#ifdef NOMSG
+#undef NOMSG       /* avoid #define SendMessage etc. */
+#endif
+#ifdef NODRAWTEXT
+#undef NODRAWTEXT  /* avoid #define DrawText etc. */
+#endif
+#ifdef NONLS
+#undef NONLS       /* avoid #define CompareString etc. */
+#endif
+#ifdef NOGDI
+#undef NOGDI       /* avoid #define SetPrinter (winspool.h) etc. */
+#endif
+#ifdef NOSERVICE
+#undef NOSERVICE    
+#endif
+#ifdef NOKERNEL
+#undef NOKERNEL 
+#endif
+#ifdef NOUSER
+#undef NOUSER 
+#endif
+#ifdef NOMCX
+#undef NOMCX 
+#endif
+#ifdef NOIME
+#undef NOIME 
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#ifdef _WIN32
+#define _WIN32_WINNT 0x0400  // for TrackMouseEvent support requires Win95 with IE 3.0 or greater.
+#include <windows.h>
+#include <WNT_WClass.hxx>
+#include <WNT_Window.hxx>
+#endif
+
+#include <Draw.hxx>
+#include <Draw_Interpretor.hxx>
+#include <Draw_PluginMacro.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TopoDS_Shape.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepTools.hxx>
+#include <DBRep.hxx>
+#include <NCollection_DoubleMap.hxx>
+#include <NCollection_List.hxx>
+#include <NCollection_DataMap.hxx>
+#include <TopTools_DataMapOfIntegerShape.hxx>
+#include <OpenGl_GraphicDriver.hxx>
+#include <Aspect_DisplayConnection.hxx>
+
+#include <IVtk_Types.hxx>
+#include <IVtkVTK_ShapeData.hxx>
+#include <IVtkOCC_Shape.hxx>
+#include <IVtkOCC_ShapeMesher.hxx>
+#include <IVtkTools_ShapeDataSource.hxx>
+#include <IVtkTools_ShapeObject.hxx>
+#include <IVtkTools_SubPolyDataFilter.hxx>
+#include <IVtkTools_DisplayModeFilter.hxx>
+#include <IVtkTools_ShapePicker.hxx>
+
+#include <IVtkDraw.hxx>
+#include <IVtkDraw_HighlightAndSelectionPipeline.hxx>
+#include <IVtkDraw_Interactor.hxx>
+
+#include <vtkAlgorithmOutput.h>
+#include <vtkAppendPolyData.h>
+#include <vtkBMPWriter.h>
+#include <vtkCamera.h>
+#include <vtkCellData.h>
+#include <vtkCommand.h>
+#include <vtkGeometryFilter.h>
+#include <vtkIdTypeArray.h>
+#include <vtkImageResize.h>
+#include <vtkImageWriter.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include <vtkJPEGWriter.h>
+#include <vtkPNGWriter.h>
+#include <vtkPNMWriter.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkProperty.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkSmartPointer.h>
+#include <vtkTIFFWriter.h>
+#include <vtkWindowToImageFilter.h>
+
+#ifndef _WIN32
+#include <X11/X.h>
+#include <X11/Shell.h>
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include <Xw_Window.hxx>
+#include <vtkXRenderWindowInteractor.h>
+#include <vtkXOpenGLRenderWindow.h>
+#include <X11/Xutil.h>
+#include <tk.h>
+#endif
+
+// workaround name conflicts with OCCT methods (in class TopoDS_Shape for example)
+#ifdef Convex
+  #undef Convex
+#endif
+#ifdef Status
+  #undef Status
+#endif
+
+//================================================================
+// TYPE DEFINITIONS
+//================================================================
+
+typedef NCollection_DoubleMap<TopoDS_Shape, TCollection_AsciiString> DoubleMapOfShapesAndNames;
+typedef NCollection_DoubleMap<vtkSmartPointer<vtkActor>, TCollection_AsciiString> DoubleMapOfActorsAndNames;
+
+typedef IVtkDraw_HighlightAndSelectionPipeline PipelinePtr;
+typedef Handle(IVtkDraw_HighlightAndSelectionPipeline) Handle(PipelinePtr);
+
+//================================================================
+// GLOBAL VARIABLES
+//================================================================
+
+Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
+
+static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
+{
+  static Handle(Aspect_DisplayConnection) aDisplayConnection;
+  return aDisplayConnection;
+}
+
+static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
+{
+  GetDisplayConnection() = theDisplayConnection;
+}
+
+static DoubleMapOfShapesAndNames& GetMapOfShapes()
+{
+  static DoubleMapOfShapesAndNames aMap;
+  return aMap;
+}
+
+static DoubleMapOfActorsAndNames& GetMapOfActors()
+{
+  static DoubleMapOfActorsAndNames aMap;
+  return aMap;
+}
+
+static vtkSmartPointer<vtkRenderer>& GetRenderer()
+{
+  static vtkSmartPointer<vtkRenderer> aRenderer;
+  return aRenderer;
+}
+
+static Handle(ShapePipelineMap)& GetPipelines()
+{
+  static Handle(ShapePipelineMap) aPLMap;
+  if (aPLMap.IsNull())
+  {
+    aPLMap = new ShapePipelineMap();
+  }
+
+  return aPLMap;
+}
+
+static Handle(PipelinePtr) GetPipeline (const IVtk_IdType& theShapeID)
+{
+  Handle(PipelinePtr) aPtr;
+  GetPipelines()->Find (theShapeID, aPtr);
+  return aPtr;
+}
+
+//! Get VTK render pipeline with shape ID got from actor.
+static Handle(PipelinePtr) PipelineByActor (const vtkSmartPointer<vtkActor>& theActor)
+{
+  IVtk_IdType aShapeID = IVtkTools_ShapeObject::GetShapeSource (theActor)->GetShape()->GetId();
+  return GetPipeline (aShapeID);
+}
+
+//! Get VTK render pipeline with actor that has the input name.
+static Handle(PipelinePtr) PipelineByActorName (const TCollection_AsciiString& theName)
+{
+  const vtkSmartPointer<vtkActor>& anActor = GetMapOfActors().Find2 (theName);
+  return PipelineByActor (anActor);
+}
+
+static Standard_Boolean IsEqual (const TopoDS_Shape& theLeft,
+                                 const TopoDS_Shape& theRight)
+{
+  return theLeft.IsEqual (theRight);
+}
+
+#ifdef _WIN32
+
+static Handle(WNT_Window)& GetWindow()
+{
+  static Handle(WNT_Window) aWindow;
+  return aWindow;
+}
+
+#else
+
+static Handle(Xw_Window)& GetWindow()
+{
+  static Handle(Xw_Window) aXWWin;
+  return aXWWin;
+}
+
+#endif
+
+static vtkSmartPointer<IVtkDraw_Interactor>& GetInteractor()
+{
+  static vtkSmartPointer<IVtkDraw_Interactor> anInteractor;
+  return anInteractor;
+}
+
+static vtkSmartPointer<IVtkTools_ShapePicker>& GetPicker()
+{
+  static vtkSmartPointer<IVtkTools_ShapePicker> aPicker;
+  return aPicker;
+}
+
+//! Generate identical number for shape
+Standard_Integer GenerateId()
+{
+  static unsigned int aShapesCounter = (unsigned int )-1;
+  return (Standard_Integer )++aShapesCounter;
+}
+
+//=========================================================
+// Function : WClass
+// Purpose  :
+//=========================================================
+const Handle(MMgt_TShared)& IVtkDraw::WClass()
+{
+  static Handle(MMgt_TShared) aWindowClass;
+#ifdef WNT
+  if (aWindowClass.IsNull())
+  {
+    aWindowClass = new WNT_WClass ("GWVTK_Class", DefWindowProc,
+                                   CS_VREDRAW | CS_HREDRAW, 0, 0,
+                                   ::LoadCursor (NULL, IDC_ARROW));
+  }
+#endif
+  return aWindowClass;
+}
+
+//==============================================================
+// Function : ViewerInit
+// Purpose  : 
+//==============================================================
+void IVtkDraw::ViewerInit (Standard_Integer thePxLeft,
+                           Standard_Integer thePxTop,
+                           Standard_Integer thePxWidth,
+                           Standard_Integer thePxHeight)
+{
+  static Standard_Boolean isFirst = Standard_True;
+
+  Standard_Integer aPxLeft   = 0;
+  Standard_Integer aPxTop    = 460;
+  Standard_Integer aPxWidth  = 409;
+  Standard_Integer aPxHeight = 409;
+
+  if (thePxLeft != 0)
+  {
+    aPxLeft = thePxLeft;
+  }
+  if (thePxTop != 0)
+  {
+    aPxTop = thePxTop;
+  }
+  if (thePxWidth != 0)
+  {
+    aPxWidth = thePxWidth;
+  }
+  if (thePxHeight != 0)
+  {
+    aPxHeight = thePxHeight;
+  }
+  
+  if (isFirst)
+  {
+    SetDisplayConnection (new Aspect_DisplayConnection ());
+#ifdef WNT
+    if (GetWindow().IsNull())
+    {
+      GetWindow() = new WNT_Window ("IVtkTest",
+                                    Handle(WNT_WClass)::DownCast (WClass()),
+                                    WS_OVERLAPPEDWINDOW,
+                                    aPxLeft, aPxTop,
+                                    aPxWidth, aPxHeight,
+                                    Quantity_NOC_BLACK);
+      GetWindow()->SetVirtual (Draw_VirtualWindows);
+    }
+#else
+
+    if (GetWindow().IsNull())
+    {
+      GetWindow() = new Xw_Window (GetDisplayConnection(),
+                                   "IVtkTest",
+                                   aPxLeft, aPxTop,
+                                   aPxWidth, aPxHeight);
+      GetWindow()->SetVirtual (Draw_VirtualWindows);
+    }
+#endif
+    // Init pipeline
+    GetRenderer() = vtkSmartPointer<vtkRenderer>::New();
+
+    vtkSmartPointer<vtkRenderWindow> aRenWin = vtkSmartPointer<vtkRenderWindow>::New();
+    aRenWin->AddRenderer (GetRenderer());
+    GetRenderer()->GetActiveCamera()->ParallelProjectionOn();
+    aRenWin->SetSize (aPxWidth, aPxHeight);
+
+#ifdef WNT
+    aRenWin->SetWindowId((void*)GetWindow()->HWindow());
+#else
+    Window aWindowId = GetWindow()->XWindow();
+    aRenWin->SetWindowId ((void*)aWindowId);
+    Display *aDisplayId = GetDisplayConnection()->GetDisplay();
+    aRenWin->SetDisplayId (aDisplayId);
+
+    // Setup XWindow
+    XSynchronize (aDisplayId, 1);
+    GetWindow()->Map();
+
+    // X11 : For keyboard on SUN
+    XWMHints wmhints;
+    wmhints.flags = InputHint;
+    wmhints.input = 1;
+
+    XSetWMHints (aDisplayId, aWindowId, &wmhints);
+
+    XSelectInput (aDisplayId, aWindowId,  ExposureMask | KeyPressMask |
+      ButtonPressMask | ButtonReleaseMask |
+      StructureNotifyMask |
+      PointerMotionMask |
+      Button1MotionMask | Button2MotionMask |
+      Button3MotionMask
+      );
+
+    XSynchronize (aDisplayId, 0);
+
+#endif
+
+    // Init interactor
+    GetInteractor() = vtkSmartPointer<IVtkDraw_Interactor>::New();
+    GetInteractor()->SetRenderWindow (aRenWin);
+    GetInteractor()->SetOCCWindow (GetWindow());
+
+    vtkSmartPointer<vtkInteractorStyleTrackballCamera>
+      aStyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
+    GetInteractor()->SetInteractorStyle (aStyle);
+
+    // Init picker
+    GetPicker() = vtkSmartPointer<IVtkTools_ShapePicker>::New();
+    GetPicker()->SetTolerance (0.025);
+    GetPicker()->SetRenderer (GetRenderer());
+
+    GetInteractor()->SetShapePicker (GetPicker());
+    GetInteractor()->SetPipelines (GetPipelines());
+    GetInteractor()->Initialize();
+
+    aRenWin->SetOffScreenRendering(Draw_VirtualWindows);
+    aRenWin->Render();
+
+    isFirst = Standard_False;
+  }
+
+  GetWindow()->Map();
+}
+
+//================================================================
+// Function : VtkInit
+// Purpose  : 
+//================================================================
+static Standard_Integer VtkInit (Draw_Interpretor& ,
+                                 Standard_Integer theArgNum,
+                                 const char** theArgs)
+{
+  Standard_Integer aPxLeft   = (theArgNum > 1) ? atoi(theArgs[1]) : 0;
+  Standard_Integer aPxTop    = (theArgNum > 2) ? atoi(theArgs[2]) : 0;
+  Standard_Integer aPxWidth  = (theArgNum > 3) ? atoi(theArgs[3]) : 0;
+  Standard_Integer aPxHeight = (theArgNum > 4) ? atoi(theArgs[4]) : 0;
+
+  IVtkDraw::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight);
+  return 0;
+}
+
+
+//================================================================
+// Function : CreateActor
+// Purpose  : 
+//================================================================
+vtkActor* CreateActor (const Standard_Integer theId,
+                       const TopoDS_Shape& theShape)
+{
+  if ( theShape.IsNull() )
+  {
+    return NULL;
+  }
+
+  Handle(PipelinePtr) aPL = new PipelinePtr (theShape, theId);
+  GetPipelines()->Bind (theId, aPL);
+
+  return aPL->Actor();
+}
+
+//================================================================
+// Function : VtkDisplay
+// Purpose  : 
+//================================================================
+
+static Standard_Integer VtkDisplay (Draw_Interpretor& theDI,
+                                    Standard_Integer theArgNum,
+                                    const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    theDI << theArgs[0] << " error : call ivtkinit before\n";
+    return 1; // TCL_ERROR
+  }
+
+  // Check arguments
+  if (theArgNum < 2)
+  {
+    theDI << theArgs[0] << " error : expects at least 1 argument\n";
+    return 1; // TCL_ERROR
+  }
+
+  TCollection_AsciiString aName;
+  TopoDS_Shape anOldShape, aNewShape;
+  vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
+  for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
+  {
+    // Get name of shape
+    aName = theArgs[anIndex];
+    // Get shape from DRAW
+    aNewShape = DBRep::Get (theArgs[anIndex]);
+
+    // The shape is already in the map
+    if (GetMapOfShapes().IsBound2 (aName))
+    {
+      // Get shape from map
+      anOldShape = GetMapOfShapes().Find2 (aName);
+      // Equal shapes
+      if (anOldShape.IsEqual (aNewShape))
+      {
+        // Get actor from map and display it
+        PipelineByActorName (aName)->AddToRenderer (aRenderer);
+      }
+      // Different shapes
+      else
+      {
+        if (aNewShape.IsNull()) continue;
+        // Create actor from DRAW shape
+        vtkActor* anActor = CreateActor (GenerateId(), aNewShape);
+        // Remove old actor from render
+        PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
+        // Update maps
+        GetMapOfShapes().UnBind2 (aName);
+        GetMapOfShapes().Bind (aNewShape, aName);
+        GetMapOfActors().UnBind2 (aName);
+        GetMapOfActors().Bind (anActor, aName);
+        // Display new actor
+        PipelineByActorName (aName)->AddToRenderer (aRenderer);
+        // Compute selection for displayed actors
+        GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
+      }
+    }
+    // There is no shape with given name in map
+    else
+    {
+      if (aNewShape.IsNull()) continue;
+      // Create actor from DRAW shape
+      vtkActor* anActor = CreateActor (GenerateId(), aNewShape);
+      // Update maps
+      GetMapOfShapes().Bind (aNewShape, aName);
+      GetMapOfActors().Bind (anActor, aName);
+      // Display actor
+      PipelineByActorName (aName)->AddToRenderer (aRenderer);
+
+      // Compute selection for displayed actors
+      GetPicker()->SetSelectionMode (SM_Shape, Standard_True);
+    }
+  }
+
+  // Redraw window
+  aRenderer->ResetCamera();
+  GetInteractor()->GetRenderWindow()->Render();
+
+  return 0;
+}
+
+//================================================================
+// Function : VtkErase
+// Purpose  : 
+//================================================================
+static Standard_Integer VtkErase (Draw_Interpretor& theDI,
+                                  Standard_Integer theArgNum,
+                                  const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    theDI << theArgs[0] << " error : call ivtkinit before\n";
+    return 1; // TCL_ERROR
+  }
+
+  vtkSmartPointer<vtkRenderer> aRenderer = GetRenderer();
+  // Erase all objects
+  if (theArgNum == 1)
+  {
+    DoubleMapOfActorsAndNames::Iterator anIterator (GetMapOfActors());
+    while (anIterator.More())
+    {
+      PipelineByActor (anIterator.Key1())->RemoveFromRenderer (aRenderer);
+      anIterator.Next();
+    }
+  }
+  // Erase named objects
+  else
+  {
+    TCollection_AsciiString aName;
+    for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex)
+    {
+      aName = theArgs[anIndex];
+      if (GetMapOfActors().IsBound2 (aName))
+      {
+        PipelineByActorName (aName)->RemoveFromRenderer (aRenderer);
+      }
+    }
+  }
+
+  // Redraw window
+  aRenderer->ResetCamera();
+  GetInteractor()->GetRenderWindow()->Render();
+  return 0;
+}
+
+//================================================================
+// Function  : VtkSetDisplayMode
+// Purpose   : 
+// Draw args : ivtksetdispmode [name] mode(0,1)
+//================================================================
+static Standard_Integer VtkSetDisplayMode (Draw_Interpretor& theDI,
+                                           Standard_Integer theArgNum,
+                                           const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    theDI << theArgs[0] << " error: call ivtkinit before\n";
+    return 1; // TCL_ERROR
+  }
+
+  // Check arguments
+  if (theArgNum != 2 && theArgNum != 3)
+  {
+    theDI << theArgs[0] << " error: expects 1 or 2 arguments\n";
+    return 1; // TCL_ERROR
+  }
+
+  vtkSmartPointer<vtkActor> anActor;
+  // Set disp mode for all objects
+  if (theArgNum == 2)
+  {
+    // Get mode
+    Standard_Integer aMode =  Draw::Atoi (theArgs[1]);
+    DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
+    while (anIter.More())
+    {
+      anActor = anIter.Key1();
+      IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
+      if (aSrc)
+      {
+        IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
+        if (!anOccShape.IsNull())
+        {
+          IVtkTools_DisplayModeFilter* aFilter = GetPipeline ( anOccShape->GetId() )->GetDisplayModeFilter();
+          aFilter->SetDisplayMode((IVtk_DisplayMode)aMode);
+          aFilter->Modified();
+          aFilter->Update();
+        }
+      }
+      anIter.Next();
+    }
+  }
+  // Set disp mode for named object
+  else 
+  {
+    Standard_Integer aMode = atoi(theArgs[2]);
+    TCollection_AsciiString aName = theArgs[1];
+    if (GetMapOfActors().IsBound2 (aName))
+    {
+      anActor = GetMapOfActors().Find2 (aName);
+      vtkSmartPointer<IVtkTools_ShapeDataSource> aSrc = IVtkTools_ShapeObject::GetShapeSource (anActor);
+      if (aSrc)
+      {
+        IVtkOCC_Shape::Handle anOccShape = aSrc->GetShape();
+        if (!anOccShape.IsNull())
+        {
+          IVtkTools_DisplayModeFilter* aFilter = GetPipeline (anOccShape->GetId())->GetDisplayModeFilter();
+          aFilter->SetDisplayMode ((IVtk_DisplayMode)aMode);
+          aFilter->Modified();
+          aFilter->Update();
+        }
+      }
+    }
+  }
+
+  // Redraw window
+  GetInteractor()->Render();
+  return 0;
+}
+
+//================================================================
+// Function  : VtkSetSelectionMode
+// Purpose   : 
+// Draw args : ivtksetselmode [name] mode on/off(0,1)
+//================================================================
+static Standard_Integer VtkSetSelectionMode (Draw_Interpretor& theDI,
+                                             Standard_Integer theArgNum,
+                                             const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    theDI << theArgs[0] << " error: call ivtkinit before\n";
+    return 1; // TCL_ERROR
+  }
+
+  // Check arguments
+  if (theArgNum != 3 && theArgNum != 4)
+  {
+    theDI << theArgs[0] << " error: expects 2 or 3 arguments\n";
+    return 1; // TCL_ERROR
+  }
+
+  vtkSmartPointer<vtkActor> anActor;
+  Standard_Integer aMode;
+  Standard_Boolean isTurnOn;
+  // Set sel mode for all objects
+  if (theArgNum == 3)
+  {
+    aMode = atoi (theArgs[1]);
+    isTurnOn = atoi (theArgs[2]);
+    if (aMode < 0 || aMode > 8)
+    {
+      theDI << theArgs[0] << " error: only 0-8 selection modes are supported\n";
+      return 1; // TCL_ERROR
+    }
+    DoubleMapOfActorsAndNames::Iterator anIter (GetMapOfActors());
+    while (anIter.More())
+    {
+      anActor = anIter.Key1();
+
+      if (aMode == SM_Shape && isTurnOn)
+      {
+        IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
+        IVtk_SelectionModeList::Iterator anIt (aList);
+        // Turn off all sel modes differed from SM_Shape
+        while (anIt.More())
+        {
+          IVtk_SelectionMode aCurMode = anIt.Value();
+          if (SM_Shape != aCurMode)
+          {
+            GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
+          }
+          anIt.Next();
+        }
+        GetPicker()->SetSelectionMode (anActor, SM_Shape);
+      }
+
+      if (aMode != SM_Shape)
+      {
+        if (isTurnOn)
+        {
+          GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
+          GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
+          if (aMode == SM_Vertex)
+          {
+            GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
+          }
+        }
+        else
+        {
+          GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
+          IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
+          if (!aList.Size())
+          {
+            GetPicker()->SetSelectionMode(anActor, SM_Shape);
+          }
+          if (aMode == SM_Vertex)
+          {
+            GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
+          }
+        }
+      }
+      anIter.Next();
+    }
+  }
+
+  // Set sel mode for named object
+  if (theArgNum == 4)
+  {
+    aMode = atoi (theArgs[2]);
+    isTurnOn = atoi (theArgs[3]);
+
+    if (aMode < 0 || aMode > 8)
+    {
+      theDI << theArgs[0] << " error: only 0-8 selection modes are supported\n";
+      return 1; // TCL_ERROR
+    }
+
+    TCollection_AsciiString aName = theArgs[1];
+    if (GetMapOfActors().IsBound2 (aName))
+    {
+      anActor = GetMapOfActors().Find2 (aName);
+
+      if (aMode == SM_Shape && isTurnOn)
+      {
+        IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
+        IVtk_SelectionModeList::Iterator anIt (aList);
+        // Turn off all sel modes differed from SM_Shape
+        while (anIt.More())
+        {
+          IVtk_SelectionMode aCurMode = anIt.Value();
+          if (SM_Shape != aCurMode)
+          {
+            GetPicker()->SetSelectionMode (anActor, aCurMode, Standard_False);
+          }
+          anIt.Next();
+        }
+        GetPicker()->SetSelectionMode (anActor, SM_Shape);
+      }
+
+      if (aMode != SM_Shape)
+      {
+        if (isTurnOn)
+        {
+          GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode);
+          GetPicker()->SetSelectionMode (anActor, SM_Shape, Standard_False);
+          if (aMode == SM_Vertex)
+          {
+            GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOn();
+          }
+        }
+        else
+        {
+          GetPicker()->SetSelectionMode (anActor, (IVtk_SelectionMode)aMode, Standard_False);
+          IVtk_SelectionModeList aList = GetPicker()->GetSelectionModes (anActor);
+          if (!aList.Size())
+          {
+            GetPicker()->SetSelectionMode(anActor, SM_Shape);
+          }
+          if (aMode == SM_Vertex)
+          {
+            GetPipeline( IVtkTools_ShapeObject::GetShapeSource(anActor)->GetShape()->GetId() )->SharedVerticesSelectionOff();
+          }
+        }
+      }
+    }
+  }
+
+  // Redraw window
+  GetInteractor()->Render();
+
+  return 0;
+}
+
+//================================================================
+// Function  : VtkMoveTo
+// Purpose   : 
+// Draw args : ivtkmoveto x y
+//================================================================
+static Standard_Integer VtkMoveTo(Draw_Interpretor& theDI,
+                                  Standard_Integer theArgNum,
+                                  const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    theDI << theArgs[0] << " error: call ivtkinit before\n";
+    return 1; // TCL_ERROR
+  }
+
+  // Check args
+  if (theArgNum != 3)
+  {
+    theDI << theArgs[0] << " error: expects 2 arguments\n";
+    return 1; // TCL_ERROR
+  }
+
+  Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[2]) - 1;
+  GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
+  return 0;
+}
+
+//================================================================
+// Function  : VtkSelect
+// Purpose   : 
+// Draw args : ivtkselect x y
+//================================================================
+static Standard_Integer VtkSelect (Draw_Interpretor& theDI,
+                                   Standard_Integer theArgNum,
+                                   const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    theDI << theArgs[0] << " error: call ivtkinit before\n";
+    return 1; // TCL_ERROR
+  }
+
+  // Check args
+  if (theArgNum != 3)
+  {
+    theDI << theArgs[0] << " error: expects 3 arguments\n";
+    return 1; // TCL_ERROR
+  }
+
+  Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[1]) - 1;
+  GetInteractor()->MoveTo (atoi (theArgs[1]), anY);
+  GetInteractor()->OnSelection();
+  return 0;
+
+}
+
+//===================================================================
+// Fubction  : VtkFit
+// Purpose   :
+// Draw args : ivtkfit
+//===================================================================
+
+static Standard_Integer VtkFit (Draw_Interpretor& theDI,
+                                Standard_Integer,
+                                const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    theDI << theArgs[0] << " error : call ivtkinit before \n";
+    return 1; //TCL_ERROR
+  }
+
+  GetRenderer()->ResetCamera();
+  GetInteractor()->Render();
+  return 0;
+}
+
+//===================================================================
+// Fubction  : VtkDump
+// Purpose   :
+// Draw args : ivtkdump FullFilename.{png|bmp|jpeg|tiff|pnm} 
+//                      [buffer={rgb|rgba|depth}] [width height]
+//                      [stereoproj={L|R}]
+//===================================================================
+static Standard_Integer VtkDump (Draw_Interpretor& theDI,
+                                 Standard_Integer theArgNum,
+                                 const char** theArgs)
+{
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    std::cout << theArgs[0] << " error : call ivtkinit before \n";
+    return 1;
+  }
+
+  if (theArgNum < 2)
+  {
+    theDI << theArgs[0] << " error : wrong number of parameters. Type 'help"
+          << theArgs[0] << "' for more information.\n";
+  }
+  vtkSmartPointer<vtkWindowToImageFilter> anImageFilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
+
+  anImageFilter->SetInput (GetInteractor()->GetRenderWindow());
+  // Set custom buffer type
+  if (theArgNum > 2)
+  {
+    TCollection_AsciiString aBufferType (theArgs[2]);
+    aBufferType.LowerCase();
+    if (aBufferType.IsEqual ("rgb"))
+    {
+      anImageFilter->SetInputBufferTypeToRGB();
+    }
+    else if (aBufferType.IsEqual ("rgba"))
+    {
+      anImageFilter->SetInputBufferTypeToRGBA();
+    }
+    else if (aBufferType.IsEqual ("depth"))
+    {
+      anImageFilter->SetInputBufferTypeToZBuffer();
+    }
+  }
+  anImageFilter->Update();
+
+  // Set custom stereo projection options
+  if (theArgNum > 5 && GetRenderer()->GetRenderWindow()->GetStereoRender())
+  {
+    Standard_CString aStereoProjStr = theArgs[5];
+
+    Standard_Integer aStereoType =  GetRenderer()->GetRenderWindow()->GetStereoType();
+    if (strcasecmp (aStereoProjStr, "L"))
+    {
+      GetRenderer()->GetRenderWindow()->SetStereoTypeToLeft();
+      GetRenderer()->GetRenderWindow()->StereoUpdate();
+      anImageFilter->Update();
+      GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
+    }
+    else if (strcasecmp (aStereoProjStr, "R"))
+    {
+      GetRenderer()->GetRenderWindow()->SetStereoTypeToRight();
+      GetRenderer()->GetRenderWindow()->StereoUpdate();
+      anImageFilter->Update();
+      GetRenderer()->GetRenderWindow()->SetStereoType (aStereoType);
+    }
+    else
+    {
+      theDI << theArgs[0] << " error: unknown value for stereo projection.\n";
+      return 1;
+    }
+  }
+
+  // Set parameters for image writer
+  vtkSmartPointer<vtkImageWriter> anImageWriter;
+  TCollection_AsciiString aFilename (theArgs[1]);
+  Standard_Integer anExtStart = aFilename.SearchFromEnd (TCollection_AsciiString("."));
+  TCollection_AsciiString aFormat = (anExtStart == -1) ? TCollection_AsciiString("")
+                                    : aFilename.SubString (anExtStart + 1, aFilename.Length());
+  aFormat.LowerCase();
+
+  if (aFormat.IsEqual ("png"))
+  {
+    anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
+  }
+  else if (aFormat.IsEqual ("bmp"))
+  {
+    anImageWriter = vtkSmartPointer<vtkBMPWriter>::New();
+  }
+  else if (aFormat.IsEqual ("jpeg"))
+  {
+    anImageWriter = vtkSmartPointer<vtkJPEGWriter>::New();
+  }
+  else if (aFormat.IsEqual ("tiff"))
+  {
+    anImageWriter = vtkSmartPointer<vtkTIFFWriter>::New();
+  }
+  else if (aFormat.IsEqual ("pnm"))
+  {
+    anImageWriter = vtkSmartPointer<vtkPNMWriter>::New();
+  }
+  else // aFormat is unsupported or not set.
+  {
+    if (aFormat.IsEmpty())
+    {
+      theDI << theArgs[0] << " warning: the image format is not set.\n"
+            << "The image will be saved into PNG format.\n";
+      anImageWriter = vtkSmartPointer<vtkPNGWriter>::New();
+      aFormat = TCollection_AsciiString ("png");
+      if (anExtStart != -1)
+      {
+        aFilename.Split (anExtStart);
+      }
+      else
+      {
+        aFilename += ".";
+      }
+      aFilename += aFormat;
+    }
+    else
+    {
+      theDI << theArgs[0] << " error: the image format "
+            << aFormat.ToCString() <<" is not supported.\n";
+      return 1;
+    }
+
+  }
+
+  anImageWriter->SetFileName (aFilename.ToCString());
+
+  Standard_Integer aWidth = (theArgNum > 3) ? atoi (theArgs[3]) : 0;
+  Standard_Integer aHeight = (theArgNum > 4) ? atoi (theArgs[4]) : 0;
+  if (aWidth >= 0 || aHeight >= 0)
+  {
+    // Scale image
+    vtkSmartPointer<vtkImageResize> anImageResize = vtkSmartPointer<vtkImageResize>::New();
+#if VTK_MAJOR_VERSION <= 5
+    anImageResize->SetInput (anImageFilter->GetOutput());
+#else
+    anImageResize->SetInputData (anImageFilter->GetOutput());
+#endif
+
+    anImageResize->SetOutputDimensions (aWidth, aHeight, 1);
+    anImageResize->Update();
+    anImageWriter->SetInputConnection (anImageResize->GetOutputPort());
+  }
+  else
+  {
+    anImageWriter->SetInputConnection (anImageFilter->GetOutputPort());
+  }
+  anImageWriter->Write();
+
+  return 0;
+}
+
+//===================================================================
+// Fubction  : VtkBackgroundColor
+// Purpose   :
+// Draw args : ivtkbgcolor r g b
+//             r,g,b = [0..255]
+//===================================================================
+static Standard_Integer VtkBackgroundColor (Draw_Interpretor& theDI,
+                                            Standard_Integer theArgNum,
+                                            const char** theArgs)
+{
+  if (theArgNum != 4 && theArgNum != 7)
+  {
+    theDI << theArgs[0] << " error : wrong number of parameters.\n"
+          << "Type 'help " << theArgs[0] << "' for more information.\n";
+    return 1;
+  }
+
+  // Check viewer
+  if (!GetInteractor()->IsEnabled())
+  {
+    std::cout << theArgs[0] << " error : call ivtkinit before \n";
+    return 1;
+  }
+
+  Standard_Real aR = Draw::Atof(theArgs[1])/255.0;
+  Standard_Real aG = Draw::Atof(theArgs[2])/255.0;
+  Standard_Real aB = Draw::Atof(theArgs[3])/255.0;
+
+  GetRenderer()->SetGradientBackground(false);
+  GetRenderer()->SetBackground (aR, aG, aB);
+
+  if (theArgNum == 7)
+  {
+    Standard_Real aR2 = Draw::Atof(theArgs[4])/255.0;
+    Standard_Real aG2 = Draw::Atof(theArgs[5])/255.0;
+    Standard_Real aB2 = Draw::Atof(theArgs[6])/255.0;
+
+    GetRenderer()->SetBackground2(aR2, aG2, aB2);
+    GetRenderer()->SetGradientBackground(true);
+  }
+
+  GetInteractor()->Render();
+
+  return 0;
+}
+
+//================================================================
+// Function : Commands
+// Purpose  : 
+//================================================================
+void IVtkDraw::Commands (Draw_Interpretor& theCommands)
+{
+  const char *group = "VtkViewer";
+  
+  theCommands.Add("ivtkinit",
+    "ivtkinit usage:\n"
+    "ivtkinit [leftPx topPx widthPx heightPx]"
+    "\n\t\t: Creates the Vtk window",
+    __FILE__, VtkInit, group);
+
+  theCommands.Add("ivtkdisplay",
+    "ivtkdisplay usage:\n"
+    "ivtkdisplay name1 name2 ..."
+    "\n\t\t: Displayes named objects in current view.",
+    __FILE__, VtkDisplay, group);
+
+  theCommands.Add("ivtkerase",
+    "ivtkerase usage:\n"
+    "ivtkerase [name1 name2 ...]"
+    "\n\t\t: Removes from renderer named objects or all objects.",
+    __FILE__, VtkErase, group);
+
+  theCommands.Add("ivtksetdispmode",
+    "ivtksetdispmode usage:\n"
+    "ivtksetdispmode [name] mode (0,1)"
+    "\n\t\t: Sets or unsets display mode 'mode' to the object with name 'name' or to all objects"
+    "if name is not defined.",
+    __FILE__, VtkSetDisplayMode, group);
+
+  theCommands.Add("ivtksetselmode",
+    "ivtksetselmode usage:\n"
+    " ivtksetselmode [name] mode on/off(0,1)"
+    "\n\t\t: Sets or unsets selection mode 'mode' to the object with name 'name' or to the all displayed objects.",
+    __FILE__, VtkSetSelectionMode, group);
+
+  theCommands.Add("ivtkmoveto",
+    "ivtkmoveto usage:\n"
+    "ivtkmoveto x y"
+    "\n\t\t: Moves position to the pixel with coordinates (x,y). The object on this position is highlighted.",
+    __FILE__, VtkMoveTo, group);
+
+  theCommands.Add("ivtkselect",
+    "ivtkselect usage:\n"
+    "ivtkselect x y"
+    "\n\t\t: Selects object which correspond to the pixel with input coordinates (x,y).",
+    __FILE__, VtkSelect, group);
+
+  theCommands.Add("ivtkfit",
+    "ivtkfit usage:\n"
+    "ivtkfit"
+    "\n\t\t: Fits view according all displayed objects.",
+    __FILE__, VtkFit, group);
+
+  theCommands.Add("ivtkdump",
+    "ivtkdump usage:\n"
+    "ivtkdump <FullFilename>.{png|bmp|jpeg|tiff|pnm} [buffer={rgb|rgba|depth}] [width height] [stereoproj={L|R}]"
+    "\n\t\t: Dumps contents of viewer window to PNG, BMP, JPEG, TIFF or PNM file",
+    __FILE__, VtkDump, group);
+
+  theCommands.Add("ivtkbgcolor",
+    "ivtkbgcolor usage:\n"
+    "ivtkbgcolor r g b [r2 g2 b2]\n"
+    "\n\t\t: Sets uniform  background color or gradient one if second triple of paramers is set."
+    "Color parameters r,g,b = [0..255].",
+    __FILE__, VtkBackgroundColor, group);
+}
+
+
+//================================================================
+// Function : Factory
+// Purpose  : 
+//================================================================
+void IVtkDraw::Factory (Draw_Interpretor& theDI)
+{
+  // definition of Viewer Commands
+  IVtkDraw::Commands (theDI);
+}
+
+// Declare entry point PLUGINFACTORY
+DPLUGIN(IVtkDraw)
+
diff --git a/src/IVtkDraw/IVtkDraw.hxx b/src/IVtkDraw/IVtkDraw.hxx
new file mode 100644 (file)
index 0000000..a564db9
--- /dev/null
@@ -0,0 +1,45 @@
+// Created on: 2012-02-03 
+// 
+// Copyright (c) 2012-2014 OPEN CASCADE SAS 
+// 
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IVtkDraw_HeaderFile
+#define _IVtkDraw_HeaderFile
+
+#include <MMgt_TShared.hxx>
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+
+class Draw_Interpretor;
+class MMgt_TShared;
+
+class IVtkDraw
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  Standard_EXPORT   static  void ViewerInit (Standard_Integer thePxLeft,
+                                             Standard_Integer thePxTop,
+                                             Standard_Integer thePxWidth,
+                                             Standard_Integer thePxHeight);
+
+  Standard_EXPORT   static  void Factory (Draw_Interpretor& theDI);
+  Standard_EXPORT   static  void Commands (Draw_Interpretor& theCommands);
+
+private:
+  Standard_EXPORT   static const Handle_MMgt_TShared& WClass();
+};
+
+#endif
+
diff --git a/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.cxx b/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.cxx
new file mode 100644 (file)
index 0000000..474d6cc
--- /dev/null
@@ -0,0 +1,244 @@
+// Created on: 2012-04-02 
+
+// Copyright (c) 2012-2014 OPEN CASCADE SAS 
+// 
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <IVtkDraw_HighlightAndSelectionPipeline.hxx>
+
+#include <vtkRenderer.h>
+#include <vtkActor.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkPolyData.h>
+#include <vtkAppendPolyData.h>
+#include <vtkProperty.h>
+
+#include <IVtkOCC_Shape.hxx>
+#include <IVtkTools_DisplayModeFilter.hxx>
+#include <IVtkTools_ShapeDataSource.hxx>
+#include <IVtkTools_ShapeObject.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(IVtkDraw_HighlightAndSelectionPipeline, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(IVtkDraw_HighlightAndSelectionPipeline, Standard_Transient)
+
+//===========================================================
+// Function : Constructor
+// Purpose  :
+//===========================================================
+
+IVtkDraw_HighlightAndSelectionPipeline::IVtkDraw_HighlightAndSelectionPipeline (const TopoDS_Shape& theShape,
+                                                                                const Standard_Integer theShapeID)
+: Standard_Transient()
+{
+  /* ===========================
+   *  Allocate involved filters
+   * =========================== */
+
+  myFilterMap.Bind (Filter_DM_Shape, vtkSmartPointer<IVtkTools_DisplayModeFilter>::New());
+  myFilterMap.Bind (Filter_DM_Hili,  vtkSmartPointer<IVtkTools_DisplayModeFilter>::New());
+  myFilterMap.Bind (Filter_DM_Sel,   vtkSmartPointer<IVtkTools_DisplayModeFilter>::New());
+  myFilterMap.Bind (Filter_SUB_Hili, vtkSmartPointer<IVtkTools_SubPolyDataFilter>::New());
+  myFilterMap.Bind (Filter_SUB_Sel,  vtkSmartPointer<IVtkTools_SubPolyDataFilter>::New());
+
+  /* ========================
+   *  Build primary pipeline
+   * ======================== */
+
+  myActor = vtkSmartPointer<vtkActor>::New();
+  IVtkOCC_Shape::Handle anIVtkShape = new IVtkOCC_Shape (theShape);
+  anIVtkShape->SetId (theShapeID);
+  vtkSmartPointer<IVtkTools_ShapeDataSource> aDataSource = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
+  aDataSource->SetShape (IVtkOCC_Shape::Handle::DownCast (anIVtkShape) );
+
+  IVtkTools_DisplayModeFilter*
+    aDMFilter = IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find(Filter_DM_Shape));
+
+  aDMFilter->AddInputConnection (aDataSource->GetOutputPort());
+  aDMFilter->SetDisplayMode (DM_Wireframe);
+
+  myMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+  myMapper->AddInputConnection (aDMFilter->GetOutputPort());
+  myActor->SetMapper (myMapper);
+  IVtkTools_ShapeObject::SetShapeSource (aDataSource, myActor);
+
+  myMapper->ScalarVisibilityOn();
+  myMapper->SetScalarModeToUseCellFieldData();
+  IVtkTools::InitShapeMapper (myMapper);
+  myMapper->Update();
+
+  /* =================================
+   *  Build pipeline for highlighting
+   * ================================= */
+
+  IVtkTools_DisplayModeFilter*
+    aDMFilterH = IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find(Filter_DM_Hili) );
+  IVtkTools_SubPolyDataFilter*
+    aSUBFilterH = IVtkTools_SubPolyDataFilter::SafeDownCast (myFilterMap.Find(Filter_SUB_Hili) );
+
+  // No highligthing exists initially
+  aSUBFilterH->SetInputConnection (aDataSource->GetOutputPort() );
+  aDMFilterH->SetInputConnection (aSUBFilterH->GetOutputPort() );
+
+  myHiliMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+  myHiliMapper->SetInputConnection (aDMFilterH->GetOutputPort() );
+
+  // Create non-pickable actor
+  myHiliActor = vtkSmartPointer<vtkActor>::New();
+  myHiliActor->SetPickable(0);
+  myHiliActor->SetVisibility(1);
+  myHiliActor->GetProperty()->SetColor(0, 1, 1);
+  myHiliActor->GetProperty()->SetOpacity(1);
+  myHiliActor->GetProperty()->SetPointSize (myHiliActor->GetProperty()->GetPointSize() + 4 );
+  myHiliActor->GetProperty()->SetLineWidth (myHiliActor->GetProperty()->GetLineWidth() + 2 );
+
+  // Set maper for actor
+  myHiliActor->SetMapper (myHiliMapper);
+  myHiliMapper->ScalarVisibilityOff();
+
+  /* ==============================
+   *  Build pipeline for selection
+   * ============================== */
+
+  IVtkTools_DisplayModeFilter*
+    aDMFilterS = IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find(Filter_DM_Sel) );
+  IVtkTools_SubPolyDataFilter*
+    aSUBFilterS = IVtkTools_SubPolyDataFilter::SafeDownCast (myFilterMap.Find(Filter_SUB_Sel) );
+
+  // No highligthing exists initially
+  aSUBFilterS->SetInputConnection (aDataSource->GetOutputPort() );
+  aDMFilterS->SetInputConnection (aSUBFilterS->GetOutputPort() );
+
+  mySelMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+  mySelMapper->SetInputConnection (aDMFilterS->GetOutputPort() );
+
+  // Create non-pickable actor
+  mySelActor = vtkSmartPointer<vtkActor>::New();
+  mySelActor->SetPickable (0);
+  mySelActor->SetVisibility (1);
+  mySelActor->GetProperty()->SetColor (1, 1, 1);
+  mySelActor->GetProperty()->SetOpacity (1);
+  mySelActor->GetProperty()->SetPointSize (myHiliActor->GetProperty()->GetPointSize() + 4 );
+  mySelActor->GetProperty()->SetLineWidth (myHiliActor->GetProperty()->GetLineWidth() + 2 );
+
+  // Set maper for actor
+  mySelActor->SetMapper (mySelMapper);
+  mySelMapper->ScalarVisibilityOff();
+}
+
+//===========================================================
+// Function : AddToRenderer
+// Purpose  :
+//===========================================================
+void IVtkDraw_HighlightAndSelectionPipeline::AddToRenderer (vtkRenderer* theRenderer)
+{
+  theRenderer->AddActor (myActor);
+  theRenderer->AddActor (myHiliActor);
+  theRenderer->AddActor (mySelActor);
+}
+
+//===========================================================
+// Function : RemoveFromRenderer
+// Purpose  :
+//===========================================================
+void IVtkDraw_HighlightAndSelectionPipeline::RemoveFromRenderer (vtkRenderer* theRenderer)
+{
+  theRenderer->RemoveActor (myActor);
+  theRenderer->RemoveActor (myHiliActor);
+  theRenderer->RemoveActor (mySelActor);
+}
+
+//===========================================================
+// Function : ClearHighlightFilters
+// Purpose  :
+//===========================================================
+void IVtkDraw_HighlightAndSelectionPipeline::ClearHighlightFilters()
+{
+  this->GetHighlightFilter()->Clear();
+  this->GetHighlightFilter()->SetDoFiltering (true);
+  this->GetHighlightFilter()->Modified();
+}
+
+//===========================================================
+// Function : ClearSelectionFilters
+// Purpose  :
+//===========================================================
+void IVtkDraw_HighlightAndSelectionPipeline::ClearSelectionFilters()
+{
+  this->GetSelectionFilter()->Clear();
+  this->GetSelectionFilter()->SetDoFiltering (true);
+  this->GetSelectionFilter()->Modified();
+}
+
+//===========================================================
+// Function : GetDisplayModeFilter
+// Purpose  :
+//===========================================================
+IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetDisplayModeFilter()
+{
+  return IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find(Filter_DM_Shape) );
+}
+
+//===========================================================
+// Function : GetHighlightFilter
+// Purpose  :
+//===========================================================
+IVtkTools_SubPolyDataFilter* IVtkDraw_HighlightAndSelectionPipeline::GetHighlightFilter()
+{
+  return IVtkTools_SubPolyDataFilter::SafeDownCast (myFilterMap.Find (Filter_SUB_Hili) );
+}
+
+//===========================================================
+// Function : GetSelectionFilter
+// Purpose  :
+//===========================================================
+IVtkTools_SubPolyDataFilter* IVtkDraw_HighlightAndSelectionPipeline::GetSelectionFilter()
+{
+  return IVtkTools_SubPolyDataFilter::SafeDownCast (myFilterMap.Find (Filter_SUB_Sel) );
+}
+
+//===========================================================
+// Function : GetHighlightDMFilter
+// Purpose  :
+//===========================================================
+IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetHighlightDMFilter()
+{
+  return IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find (Filter_DM_Hili) );
+}
+
+//===========================================================
+// Function : GetSelectionDMFilter
+// Purpose  :
+//===========================================================
+IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetSelectionDMFilter()
+{
+  return IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find(Filter_DM_Sel));
+}
+
+//===========================================================
+// Function : SharedVerticesSelectionOn
+// Purpose  :
+//===========================================================
+void IVtkDraw_HighlightAndSelectionPipeline::SharedVerticesSelectionOn()
+{
+  this->GetHighlightDMFilter()->SetDisplaySharedVertices (Standard_True);
+  this->GetSelectionDMFilter()->SetDisplaySharedVertices (Standard_True);
+}
+
+//===========================================================
+// Function : SharedVerticesSelectionOff
+// Purpose  :
+//===========================================================
+void IVtkDraw_HighlightAndSelectionPipeline::SharedVerticesSelectionOff()
+{
+  this->GetHighlightDMFilter()->SetDisplaySharedVertices (Standard_False);
+  this->GetSelectionDMFilter()->SetDisplaySharedVertices (Standard_False);
+}
diff --git a/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.hxx b/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.hxx
new file mode 100644 (file)
index 0000000..3c5050b
--- /dev/null
@@ -0,0 +1,128 @@
+// Created on: 2012-04-02 
+
+// Copyright (c) 2012-2014 OPEN CASCADE SAS 
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IVtkDraw_HighlightAndSelectionPipeline_HeaderFile
+#define _IVtkDraw_HighlightAndSelectionPipeline_HeaderFile
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+#ifndef _Handle_MMgt_TShared_HeaderFile
+#include <Handle_MMgt_TShared.hxx>
+#endif
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Handle.hxx>
+#include <Standard_Transient.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <vtkActor.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkRenderer.h>
+#include <vtkSmartPointer.h>
+
+#include <IVtk_Types.hxx>
+#include <IVtkTools_DisplayModeFilter.hxx>
+#include <IVtkTools_SubPolyDataFilter.hxx>
+
+typedef NCollection_DataMap <IVtk_IdType, vtkSmartPointer<IVtkTools_DisplayModeFilter> > DisplayModeFiltersMap;
+typedef NCollection_DataMap <IVtk_IdType, vtkSmartPointer<IVtkTools_SubPolyDataFilter> > SubShapesFiltersMap;
+
+DEFINE_STANDARD_HANDLE(IVtkDraw_HighlightAndSelectionPipeline, Standard_Transient)
+
+class IVtkDraw_HighlightAndSelectionPipeline : public Standard_Transient
+{
+public:
+
+  DEFINE_STANDARD_RTTI(IVtkDraw_HighlightAndSelectionPipeline)
+
+public:
+
+  //! Filters comprising the pipeline.
+  enum FilterId
+  {
+    Filter_DM_Shape = 1, //!< Display Mode filter for shape.
+    Filter_DM_Hili,      //!< Display Mode filter for highlighting.
+    Filter_DM_Sel,       //!< Display Mode filter for selection.
+    Filter_SUB_Hili,     //!< Sub-shapes filter for highlighting.
+    Filter_SUB_Sel       //!< Sub-shapes filter for selection.
+  };
+
+public:
+
+  IVtkDraw_HighlightAndSelectionPipeline (const TopoDS_Shape& theShape,
+                                          const Standard_Integer theShapeID);
+  ~IVtkDraw_HighlightAndSelectionPipeline() {}
+
+public:
+
+  void AddToRenderer (vtkRenderer* theRenderer);
+  void RemoveFromRenderer (vtkRenderer* theRenderer);
+
+  inline vtkActor* Actor() { return myActor; }
+  inline vtkMapper* Mapper() { return myMapper; }
+
+  void ClearHighlightFilters();
+  void ClearSelectionFilters();
+
+  IVtkTools_DisplayModeFilter* GetDisplayModeFilter();
+  IVtkTools_SubPolyDataFilter* GetHighlightFilter();
+  IVtkTools_SubPolyDataFilter* GetSelectionFilter();
+  IVtkTools_DisplayModeFilter* GetHighlightDMFilter();
+  IVtkTools_DisplayModeFilter* GetSelectionDMFilter();
+
+  void SharedVerticesSelectionOn();
+  void SharedVerticesSelectionOff();
+
+private:
+
+  //! Auxiliary map of internal filters by their correspondent IDs.
+  typedef NCollection_DataMap <FilterId, vtkSmartPointer<vtkAlgorithm> > FilterMap;
+
+private:
+
+  //! Actor.
+  vtkSmartPointer<vtkActor> myActor;
+
+  //! Polygonal mapper.
+  vtkSmartPointer<vtkPolyDataMapper> myMapper;
+
+  //! Actor for highlighting.
+  vtkSmartPointer<vtkActor> myHiliActor;
+
+  //! Polygonal mapper for highlighting.
+  vtkSmartPointer<vtkPolyDataMapper> myHiliMapper;
+
+  //! Actor for selection.
+  vtkSmartPointer<vtkActor> mySelActor;
+
+  //! Polygonal mapper for selection.
+  vtkSmartPointer<vtkPolyDataMapper> mySelMapper;
+
+  //! Map of involved VTK filters.
+  FilterMap myFilterMap;
+
+};
+
+//! Mapping between OCCT topological shape IDs and their correspondent
+//! visualization pipelines.
+typedef NCollection_DataMap<IVtk_IdType, Handle(IVtkDraw_HighlightAndSelectionPipeline)> ShapePipelineMap;
+typedef NCollection_Handle<ShapePipelineMap> Handle(ShapePipelineMap);
+
+#endif
diff --git a/src/IVtkDraw/IVtkDraw_Interactor.cxx b/src/IVtkDraw/IVtkDraw_Interactor.cxx
new file mode 100644 (file)
index 0000000..79c7854
--- /dev/null
@@ -0,0 +1,1014 @@
+// Created on: 2012-05-28 
+// 
+// Copyright (c) 2011-2014 OPEN CASCADE SAS 
+// 
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifdef _WIN32
+#define _WIN32_WINNT 0x0400  // for trackmouseevent support  requires Win95 with IE 3.0 or greater.
+#include <windows.h>
+#include <vtkWin32RenderWindowInteractor.h>
+#include <vtkWin32OpenGLRenderWindow.h>
+#endif
+
+#include <IVtkTools_ShapePicker.hxx>
+#include <IVtkTools_SubPolyDataFilter.hxx>
+#include <IVtkTools_DisplayModeFilter.hxx>
+#include <IVtkTools_ShapeObject.hxx>
+#include <IVtkTools_ShapeDataSource.hxx>
+#include <IVtkDraw_Interactor.hxx>
+
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+
+#include <vtkActor.h>
+#include <vtkActorCollection.h>
+#include <vtkCommand.h>
+#include <vtkObjectFactory.h>
+#include <vtkSmartPointer.h>
+
+#ifndef _WIN32
+#include <X11/X.h>
+#include <X11/Shell.h>
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include <vtkXRenderWindowInteractor.h>
+#include <vtkXOpenGLRenderWindow.h>
+#include <X11/Xutil.h>
+#include <tk.h>
+#endif
+
+//===========================================================
+// Function : ClearHighlightAndSelection
+// Purpose  :
+//===========================================================
+static void ClearHighlightAndSelection (const Handle(ShapePipelineMap)& theMap,
+                                         const Standard_Boolean doHighlighting,
+                                         const Standard_Boolean doSelection)
+{
+  if (!doHighlighting && !doSelection)
+  {
+    return;
+  }
+
+  for (ShapePipelineMap::Iterator anIt (*theMap); anIt.More(); anIt.Next())
+  {
+    const Handle(IVtkDraw_HighlightAndSelectionPipeline)& aPL = anIt.Value();
+
+    if (doHighlighting)
+    {
+      aPL->ClearHighlightFilters();
+    }
+
+    if (doSelection)
+    {
+      aPL->ClearSelectionFilters();
+    }
+  }
+}
+
+vtkStandardNewMacro(IVtkDraw_Interactor);
+
+//===========================================================
+// Function : Constructor
+// Purpose  :
+//===========================================================
+IVtkDraw_Interactor::IVtkDraw_Interactor()
+:
+#ifdef _WIN32
+  myWindowId (NULL),
+  myMouseInWindow (0)
+#else
+  myIsLeftButtonPressed (Standard_False)
+#endif
+{ }
+
+//===========================================================
+// Function : Destructor
+// Purpose  :
+//===========================================================
+IVtkDraw_Interactor::~IVtkDraw_Interactor()
+{
+}
+
+//===========================================================
+// Function : Copy constructor
+// Purpose  :
+//===========================================================
+IVtkDraw_Interactor::IVtkDraw_Interactor (const IVtkDraw_Interactor& )
+{
+}
+
+//===========================================================
+// Function : SetShapePicker
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::SetShapePicker (const PSelector& theSelector)
+{
+  mySelector = theSelector;
+}
+
+//===========================================================
+// Function : SetPipelines
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::SetPipelines (const Handle(ShapePipelineMap)& thePipelines)
+{
+  myPipelines = thePipelines;
+}
+
+//===========================================================
+// Function : SetOCCWindow
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::SetOCCWindow (const Handle(Aspect_Window)& theWindow)
+{
+  myWindow = theWindow;
+}
+
+//===========================================================
+// Function : GetOCCWindow
+// Purpose  :
+//===========================================================
+const Handle(Aspect_Window)& IVtkDraw_Interactor::GetOCCWindow() const
+{
+  return myWindow;
+}
+
+//===========================================================
+// Function : IsEnabled
+// Purpose  :
+//===========================================================
+Standard_Boolean IVtkDraw_Interactor::IsEnabled() const
+{
+  return Enabled;
+}
+
+//===========================================================
+// Function : Initialize
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::Initialize()
+{
+  // Make sure we have a RenderWindow and camera
+  if (!this->RenderWindow)
+  {
+    vtkErrorMacro(<<"No renderer defined!");
+    return;
+  }
+
+  if (this->Initialized)
+  {
+    return;
+  }
+
+  this->Initialized = 1;
+  
+  // Get the info we need from the RenderingWindow
+  Standard_Integer *aSize;
+#ifdef _WIN32
+  vtkWin32OpenGLRenderWindow *aRenWin;
+  aRenWin = (vtkWin32OpenGLRenderWindow *)(this->RenderWindow);
+  aRenWin->Start();
+  aSize = aRenWin->GetSize();
+  aRenWin->GetPosition();
+  this->myWindowId = aRenWin->GetWindowId();
+#else
+  vtkXOpenGLRenderWindow *aRenWin;
+  aRenWin = static_cast<vtkXOpenGLRenderWindow *>(this->RenderWindow);
+  this->myDisplayId = aRenWin->GetDisplayId();
+  this->myWindowId = aRenWin->GetWindowId();
+  aSize = aRenWin->GetSize();
+  aRenWin->Start();
+#endif
+
+  this->Enable();
+  this->Size[0] = aSize[0];
+  this->Size[1] = aSize[1];
+}
+
+//===========================================================
+// Function : Enable
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::Enable()
+{
+  if (this->Enabled)
+  {
+    return;
+  }
+
+  // Add event handlers
+#ifdef _WIN32
+  SetWindowLongPtr(this->myWindowId, GWLP_USERDATA, (LONG_PTR)this);
+  SetWindowLongPtr(this->myWindowId, GWLP_WNDPROC, (LONG_PTR)WndProc);
+#else
+  #if TCL_MAJOR_VERSION  < 8
+    Tk_CreateFileHandler((void*)ConnectionNumber(this->myDisplayId),
+      TK_READABLE, ProcessEvents, (ClientData) this);
+  #else
+    Tk_CreateFileHandler(ConnectionNumber(this->myDisplayId),
+      TK_READABLE, ProcessEvents, (ClientData) this);
+  #endif
+#endif
+
+  this->Enabled = 1;
+  this->Modified();
+}
+
+//===========================================================
+// Function : MoveTo
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::MoveTo (Standard_Integer theX, Standard_Integer theY)
+{
+  // Processing highlighting
+  mySelector->Pick (theX, theY, 0.0);
+  vtkActorCollection* anActorCollection = mySelector->GetPickedActors();
+
+  if (anActorCollection)
+  {
+    // Highlight picked subshapes
+    ClearHighlightAndSelection (myPipelines, Standard_True, Standard_False);
+    anActorCollection->InitTraversal();
+    while (vtkActor* anActor = anActorCollection->GetNextActor())
+    {
+      IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource (anActor);
+      if (!aDataSource)
+      {
+        continue;
+      }
+
+      IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
+      if (anOccShape.IsNull())
+      {
+        continue;
+      }
+
+      IVtk_IdType aShapeID = anOccShape->GetId();
+      Handle(Message_Messenger) anOutput = Message::DefaultMessenger();
+      if (!myPipelines->IsBound(aShapeID))
+      {
+        anOutput << "Warning: there is no VTK pipeline registered for highlighted shape" << endl;
+        continue;
+      }
+
+      const Handle(IVtkDraw_HighlightAndSelectionPipeline)& aPL = myPipelines->Find (aShapeID);
+
+      // Add a subpolydata filter to the highlight pipeline for the shape data source.
+      IVtkTools_SubPolyDataFilter* aFilter = aPL->GetHighlightFilter();
+
+      // Set the selected sub-shapes ids to subpolydata filter.
+      IVtk_ShapeIdList aSubShapeIds = mySelector->GetPickedSubShapesIds(aShapeID);
+
+      // Get ids of cells for picked subshapes.
+      IVtk_ShapeIdList aSubIds;
+      IVtk_ShapeIdList::Iterator aMetaIds (aSubShapeIds);
+      for (; aMetaIds.More(); aMetaIds.Next())
+      {
+        IVtk_ShapeIdList aSubSubIds = anOccShape->GetSubIds (aMetaIds.Value());
+        aSubIds.Append (aSubSubIds);
+      }
+
+      aFilter->SetDoFiltering (!aSubIds.IsEmpty());
+      aFilter->SetData (aSubIds);
+      if (!aFilter->GetInput())
+      {
+        aFilter->SetInputConnection (aDataSource->GetOutputPort());
+      }
+      aFilter->Modified();
+    }
+  }
+  this->Render();
+}
+
+//===========================================================
+// Function : OnSelection
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnSelection()
+{
+  // Processing selection
+  vtkActorCollection* anActorCollection = mySelector->GetPickedActors();
+
+  if (anActorCollection)
+  {
+    // Highlight picked subshapes.
+    ClearHighlightAndSelection (myPipelines, Standard_False, Standard_True);
+    anActorCollection->InitTraversal();
+    while (vtkActor* anActor = anActorCollection->GetNextActor())
+    {
+      IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource (anActor);
+      if (!aDataSource)
+      {
+        continue;
+      }
+
+      IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
+      if (anOccShape.IsNull())
+      {
+        continue;
+      }
+
+      IVtk_IdType aShapeID = anOccShape->GetId();
+      Handle(Message_Messenger) anOutput = Message::DefaultMessenger();
+      if (!myPipelines->IsBound (aShapeID))
+      {
+        anOutput << "Warning: there is no VTK pipeline registered for picked shape" << endl;
+        continue;
+      }
+
+      const Handle(IVtkDraw_HighlightAndSelectionPipeline)& aPL = myPipelines->Find (aShapeID);
+
+      // Add a subpolydata filter to the selection pipeline for the shape data source.
+      IVtkTools_SubPolyDataFilter* aFilter = aPL->GetSelectionFilter();
+
+      // Set the selected sub-shapes ids to subpolydata filter.
+      IVtk_ShapeIdList aSubShapeIds = mySelector->GetPickedSubShapesIds(aShapeID);
+
+      // Get ids of cells for picked subshapes.
+      IVtk_ShapeIdList aSubIds;
+      IVtk_ShapeIdList::Iterator aMetaIds (aSubShapeIds);
+      for (; aMetaIds.More(); aMetaIds.Next())
+      {
+        IVtk_ShapeIdList aSubSubIds = anOccShape->GetSubIds (aMetaIds.Value());
+        aSubIds.Append (aSubSubIds);
+      }
+
+      aFilter->SetDoFiltering (!aSubIds.IsEmpty());
+      aFilter->SetData (aSubIds);
+      if (!aFilter->GetInput())
+      {
+        aFilter->SetInputConnection (aDataSource->GetOutputPort());
+      }
+      aFilter->Modified();
+    }
+  }
+  this->Render();
+}
+
+#ifdef _WIN32
+
+//===========================================================
+// Function : OnMouseMove
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnMouseMove (HWND theHWnd, UINT theNFlags,
+                                       Standard_Integer theX,
+                                       Standard_Integer theY)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT);
+  this->SetAltKey(GetKeyState(VK_MENU) & (~1));
+  if (!this->myMouseInWindow && 
+      (theX >= 0 && theX < this->Size[0] && theY >= 0 && theY < this->Size[1]))
+  {
+    this->InvokeEvent (vtkCommand::EnterEvent, NULL);
+    this->myMouseInWindow = 1;
+    // request WM_MOUSELEAVE generation
+    TRACKMOUSEEVENT aTme;
+    aTme.cbSize = sizeof (TRACKMOUSEEVENT);
+    aTme.dwFlags = TME_LEAVE;
+    aTme.hwndTrack = theHWnd;
+    TrackMouseEvent (&aTme);
+  }
+
+  if (!(theNFlags & MK_LBUTTON))
+    this->MoveTo (theX, this->Size[1] - theY - 1);
+
+  this->InvokeEvent (vtkCommand::MouseMoveEvent, NULL);
+}
+
+//===========================================================
+// Function : OnMouseWheelForward
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnMouseWheelForward (HWND, UINT theNFlags,
+                                               Standard_Integer theX,
+                                               Standard_Integer theY)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT);
+
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+  this->InvokeEvent (vtkCommand::MouseWheelForwardEvent, NULL);
+}
+
+//===========================================================
+// Function : OnMouseWheelBackward
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnMouseWheelBackward (HWND, UINT theNFlags,
+                                                Standard_Integer theX,
+                                                Standard_Integer theY)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT);
+
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+  this->InvokeEvent (vtkCommand::MouseWheelBackwardEvent, NULL);
+}
+
+//===========================================================
+// Function : OnLButtonDown
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnLButtonDown (HWND theHWnd, UINT theNFlags,
+                                         Standard_Integer theX,
+                                         Standard_Integer theY,
+                                         Standard_Integer theRepeat)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+  SetFocus (theHWnd);
+  SetCapture (theHWnd);
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT,
+                                  0, theRepeat);
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+
+  OnSelection ();
+
+  this->InvokeEvent (vtkCommand::LeftButtonPressEvent, NULL);
+}
+
+//===========================================================
+// Function : OnLButtonUp
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnLButtonUp (HWND, UINT theNFlags,
+                                       Standard_Integer theX,
+                                       Standard_Integer theY)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT);
+
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+  this->InvokeEvent (vtkCommand::LeftButtonReleaseEvent, NULL);
+  ReleaseCapture();
+}
+
+//===========================================================
+// Function : OnMButtonDown
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnMButtonDown (HWND theHWnd, UINT theNFlags,
+                                         Standard_Integer theX,
+                                         Standard_Integer theY,
+                                         Standard_Integer theRepeat)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+
+  SetFocus (theHWnd);
+  SetCapture (theHWnd);
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT,
+                                  0, theRepeat);
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+  this->InvokeEvent (vtkCommand::MiddleButtonPressEvent, NULL);
+}
+
+//===========================================================
+// Function : OnMButtonUp
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnMButtonUp (HWND, UINT theNFlags,
+                                       Standard_Integer theX,
+                                       Standard_Integer theY)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT);
+
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+  this->InvokeEvent (vtkCommand::MiddleButtonReleaseEvent, NULL);
+  ReleaseCapture();
+}
+
+//===========================================================
+// Function : OnRButtonDown
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnRButtonDown (HWND theHWnd, UINT theNFlags,
+                                         Standard_Integer theX,
+                                         Standard_Integer theY,
+                                         Standard_Integer theRepeat)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+
+  SetFocus(theHWnd);
+  SetCapture(theHWnd);
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT,
+                                  0, theRepeat);
+
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+  this->InvokeEvent (vtkCommand::RightButtonPressEvent, NULL);
+}
+
+//===========================================================
+// Function : OnRButtonUp
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnRButtonUp (HWND, UINT theNFlags,
+                                       Standard_Integer theX,
+                                       Standard_Integer theY)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+  this->SetEventInformationFlipY (theX,
+                                  theY,
+                                  theNFlags & MK_CONTROL,
+                                  theNFlags & MK_SHIFT);
+
+  this->SetAltKey (GetKeyState(VK_MENU) & (~1));
+  this->InvokeEvent (vtkCommand::RightButtonReleaseEvent, NULL);
+  ReleaseCapture();
+}
+
+//===========================================================
+// Function : OnSize
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnSize (HWND, UINT,
+                                  Standard_Integer theX,
+                                  Standard_Integer theY)
+{
+  this->UpdateSize (theX, theY);
+  if (this->Enabled)
+  {
+    this->InvokeEvent (vtkCommand::ConfigureEvent, NULL);
+  }
+}
+
+//===========================================================
+// Function : OnTimer
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::OnTimer (HWND, UINT theTimerId)
+{
+  if (!this->Enabled)
+  {
+    return;
+  }
+
+  Standard_Integer aTid = static_cast<Standard_Integer>(theTimerId);
+  this->InvokeEvent (vtkCommand::TimerEvent, (void*)&aTid);
+
+  // Here we deal with one-shot versus repeating timers
+  if (this->IsOneShotTimer(aTid))
+  {
+    KillTimer (this->myWindowId, aTid); //'cause windows timers are always repeating
+  }
+}
+
+//===========================================================
+// Function : WndProc
+// Purpose  :
+//===========================================================
+LRESULT CALLBACK WndProc (HWND theHWnd,UINT theUMsg,
+                          WPARAM theWParam,
+                          LPARAM theLParam)
+{
+  LRESULT aRes = 0;
+  IVtkDraw_Interactor *anInteractor = 0;
+
+  anInteractor = (IVtkDraw_Interactor *)GetWindowLongPtr (theHWnd, GWLP_USERDATA);
+
+  if (anInteractor && anInteractor->GetReferenceCount() > 0)
+  {
+    anInteractor->Register (anInteractor);
+    aRes = ViewerWindowProc (theHWnd, theUMsg, theWParam, theLParam, anInteractor);
+    anInteractor->UnRegister (anInteractor);
+  }
+
+  return aRes;
+}
+
+//===========================================================
+// Function : ViewerWindowProc
+// Purpose  :
+//===========================================================
+LRESULT CALLBACK ViewerWindowProc (HWND theHWnd,
+                                   UINT theMsg,
+                                   WPARAM theWParam,
+                                   LPARAM theLParam,
+                                   IVtkDraw_Interactor *theInteractor)
+{
+  switch (theMsg)
+  {
+  case WM_CLOSE:
+    theInteractor->GetOCCWindow ()->Unmap ();
+    return 0;
+  case WM_PAINT:
+    theInteractor->Render();
+    break;
+  case WM_SIZE:
+    theInteractor->OnSize (theHWnd, theWParam, LOWORD(theLParam), HIWORD(theLParam));
+    break;
+  case WM_LBUTTONDBLCLK:
+    theInteractor->OnLButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 1);
+    break;
+  case WM_LBUTTONDOWN:
+    theInteractor->OnLButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 0);
+    break;
+  case WM_LBUTTONUP:
+    theInteractor->OnLButtonUp (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
+    break;
+  case WM_MBUTTONDBLCLK:
+    theInteractor->OnMButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 1);
+    break;
+  case WM_MBUTTONDOWN:
+    theInteractor->OnMButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 0);
+    break;
+  case WM_MBUTTONUP:
+    theInteractor->OnMButtonUp (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
+    break;
+  case WM_RBUTTONDBLCLK:
+    theInteractor->OnRButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 1);
+    break;
+  case WM_RBUTTONDOWN:
+    theInteractor->OnRButtonDown (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y, 0);
+    break;
+  case WM_RBUTTONUP:
+    theInteractor->OnRButtonUp (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
+    break;
+  case WM_MOUSELEAVE:
+    {
+      theInteractor->InvokeEvent (vtkCommand::LeaveEvent, NULL);
+      theInteractor->myMouseInWindow = 0;
+    }
+    break;
+  case WM_MOUSEMOVE:
+    theInteractor->OnMouseMove (theHWnd, theWParam, MAKEPOINTS(theLParam).x, MAKEPOINTS(theLParam).y);
+    break;
+  case WM_MOUSEWHEEL:
+    {
+      POINT pt;
+      pt.x = MAKEPOINTS(theLParam).x;
+      pt.y = MAKEPOINTS(theLParam).y;
+      ::ScreenToClient(theHWnd, &pt);
+      if( GET_WHEEL_DELTA_WPARAM(theWParam) > 0)
+      {
+        theInteractor->OnMouseWheelForward (theHWnd, theWParam, pt.x, pt.y);
+      }
+      else
+      {
+        theInteractor->OnMouseWheelBackward (theHWnd, theWParam, pt.x, pt.y);
+      }
+    }
+    break;
+  case WM_TIMER:
+    theInteractor->OnTimer (theHWnd, theWParam);
+    break;
+  }
+  return DefWindowProc(theHWnd, theMsg, theWParam, theLParam);
+}
+
+#else
+
+//===========================================================
+// Function : GetDisplayId
+// Purpose  :
+//===========================================================
+Display* IVtkDraw_Interactor::GetDisplayId() const
+{
+  return myDisplayId;
+}
+
+//===========================================================
+// Function : GetMousePosition
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::GetMousePosition (Standard_Integer *theX,
+                                            Standard_Integer *theY)
+{
+  Window aRoot, aChild;
+  Standard_Integer aRoot_x, aRoot_y;
+  unsigned int aKeys;
+
+  XQueryPointer (this->myDisplayId, this->myWindowId,
+                 &aRoot, &aChild, &aRoot_x, &aRoot_y, theX, theY, &aKeys);
+
+}
+
+//===========================================================
+// Function : ViewerMainLoop
+// Purpose  :
+//===========================================================
+Standard_Integer IVtkDraw_Interactor::ViewerMainLoop (Standard_Integer theArgNum, const char** /*theArgs*/)
+{
+  Standard_Integer aXp, aYp;
+  Standard_Boolean aPick = theArgNum > 0;
+
+  static XEvent anEvent;
+  XNextEvent (myDisplayId, &anEvent);
+
+  switch (anEvent.type)
+  {
+  case Expose:
+    {
+      if (!this->Enabled)
+      {
+        return aPick;
+      }
+      XEvent aResult;
+      while (XCheckTypedWindowEvent (this->myDisplayId,
+                                     this->myWindowId,
+                                     Expose,
+                                     &aResult))
+      {
+        // just getting the expose configure event
+        anEvent = aResult;
+      }
+
+      this->SetEventSize (anEvent.xexpose.width, anEvent.xexpose.height);
+
+
+      aXp = anEvent.xexpose.x;
+      aYp = this->Size[1] - anEvent.xexpose.y - 1;
+      this->SetEventPosition (aXp, aYp);
+      
+      // only render if we are currently accepting events
+      if (this->Enabled)
+      {
+        this->InvokeEvent(vtkCommand::ExposeEvent,NULL);
+        this->Render();
+      }
+    }
+    break;
+
+  case MapNotify:
+    {
+      // only render if we are currently accepting events
+      if (this->Enabled && this->GetRenderWindow()->GetNeverRendered())
+      {
+        this->Render();
+      }
+    }
+    break;
+
+  case ConfigureNotify:
+    {
+      XEvent aResult;
+      while (XCheckTypedWindowEvent(this->myDisplayId,
+                                    this->myWindowId,
+                                    ConfigureNotify,
+                                    &aResult))
+      {
+        // just getting the last configure event
+        anEvent = aResult;
+      }
+      Standard_Integer aWidth = anEvent.xconfigure.width;
+      Standard_Integer aHeight = anEvent.xconfigure.height;
+      if (aWidth != this->Size[0] || aHeight != this->Size[1])
+      {
+        Standard_Boolean toResizeSmaller = aWidth <= this->Size[0] && aHeight <= this->Size[1];
+        this->UpdateSize (aWidth, aHeight);
+        aXp = anEvent.xbutton.x;
+        aYp = anEvent.xbutton.y;
+
+        SetEventPosition (aXp, this->Size[1] - aYp - 1);
+
+        // only render if we are currently accepting events
+        if (Enabled)
+        {
+          this->InvokeEvent(vtkCommand::ConfigureEvent,NULL);
+          if (toResizeSmaller)
+          {
+            // Don't call Render when the window is resized to be larger:
+            //
+            // - if the window is resized to be larger, an Expose event will
+            // be trigged by the X server which will trigger a call to
+            // Render().
+            // - if the window is resized to be smaller, no Expose event will
+            // be trigged by the X server, as no new area become visible.
+            // only in this case, we need to explicitly call Render()
+            // in ConfigureNotify.
+            this->Render();
+          }
+        }
+      }
+    }
+    break;
+
+  case ButtonPress:
+    {
+      if (!this->Enabled)
+      {
+        return aPick;
+      }
+      
+      Standard_Integer aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
+      Standard_Integer aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
+      Standard_Integer anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
+      aXp = anEvent.xbutton.x;
+      aYp = anEvent.xbutton.y;
+
+      // check for double click
+      static Standard_Integer aMousePressTime = 0;
+      Standard_Integer aRepeat = 0;
+      // 400 ms threshold by default is probably good to start
+      Standard_Integer anEventTime = static_cast<int>(anEvent.xbutton.time);
+      if ((anEventTime - aMousePressTime) < 400)
+      {
+        aMousePressTime -= 2000;  // no double click next time
+        aRepeat = 1;
+      }
+      else
+      {
+        aMousePressTime = anEventTime;
+      }
+
+      this->SetEventInformationFlipY (aXp, aYp, aCtrl, aShift, 0, aRepeat);
+      this->SetAltKey (anAlt);
+
+      switch (anEvent.xbutton.button)
+      {
+        case Button1:
+          this->OnSelection ();
+          this->myIsLeftButtonPressed = 1;
+          this->InvokeEvent (vtkCommand::LeftButtonPressEvent,NULL);
+          break;
+        case Button2:
+          this->InvokeEvent (vtkCommand::MiddleButtonPressEvent,NULL);
+          break;
+        case Button3:
+          this->InvokeEvent (vtkCommand::RightButtonPressEvent,NULL);
+          break;
+        case Button4:
+          this->InvokeEvent (vtkCommand::MouseWheelForwardEvent,NULL);
+          break;
+        case Button5:
+          this->InvokeEvent (vtkCommand::MouseWheelBackwardEvent,NULL);
+          break;
+      }
+      this->Render();
+    }
+    break;
+
+  case ButtonRelease:
+    {
+      if (!this->Enabled)
+      {
+        return aPick;
+      }
+      Standard_Integer aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
+      Standard_Integer aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
+      Standard_Integer anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
+      aXp = anEvent.xbutton.x;
+      aYp = anEvent.xbutton.y;
+      
+      this->SetEventInformationFlipY (aXp, aYp, aCtrl, aShift);
+      this->SetAltKey (anAlt);
+      switch (anEvent.xbutton.button)
+      {
+        case Button1:
+          this->InvokeEvent (vtkCommand::LeftButtonReleaseEvent,NULL);
+          this->myIsLeftButtonPressed = False;
+          break;
+        case Button2:
+          this->InvokeEvent (vtkCommand::MiddleButtonReleaseEvent,NULL);
+          break;
+        case Button3:
+          this->InvokeEvent (vtkCommand::RightButtonReleaseEvent,NULL);
+          break;
+      }
+      this->Render();
+    }
+    break;
+
+  case EnterNotify:
+    {
+      if (this->Enabled)
+      {
+        XEnterWindowEvent *anEnterEvent = reinterpret_cast<XEnterWindowEvent *>(&anEvent);
+        this->SetEventInformationFlipY (anEnterEvent->x,
+                                        anEnterEvent->y,
+                                        (anEnterEvent->state & ControlMask) != 0,
+                                        (anEnterEvent->state & ShiftMask) != 0);
+                                        
+        this->SetAltKey (anEvent.xbutton.state & Mod1Mask ? 1 : 0);
+        this->InvokeEvent (vtkCommand::EnterEvent, NULL);
+      }
+      this->Render();
+    }
+    break;
+
+  case LeaveNotify:
+    {
+      if (this->Enabled)
+      {
+        XLeaveWindowEvent *aLeaveEvent = reinterpret_cast<XLeaveWindowEvent *>(&anEvent);
+        this->SetEventInformationFlipY (aLeaveEvent->x,
+                                        aLeaveEvent->y,
+                                        (aLeaveEvent->state & ControlMask) != 0,
+                                        (aLeaveEvent->state & ShiftMask) != 0);
+                                        
+        this->SetAltKey (anEvent.xbutton.state & Mod1Mask ? 1 : 0);
+        this->InvokeEvent(vtkCommand::LeaveEvent, NULL);
+      }
+      this->Render();
+    }
+    break;
+
+  case MotionNotify:
+    {
+      if (!this->Enabled)
+      {
+        return aPick;
+      }
+      
+      Standard_Integer aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
+      Standard_Integer aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
+      Standard_Integer anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
+
+      // Note that even though the (x,y) location of the pointer is event structure,
+      // we must call XQueryPointer for the hints (motion event compression) to
+      // work properly.
+      this->GetMousePosition (&aXp, &aYp);
+      this->SetEventInformationFlipY (aXp, aYp, aCtrl, aShift);
+      this->SetAltKey (anAlt);
+      if (!myIsLeftButtonPressed)
+        MoveTo (aXp, this->Size[1]- aYp - 1); 
+      this->InvokeEvent (vtkCommand::MouseMoveEvent, NULL);
+    }
+    break;
+  }
+
+  return aPick;
+}
+
+//===========================================================
+// Function : ProcessEvents
+// Purpose  :
+//===========================================================
+void IVtkDraw_Interactor::ProcessEvents (ClientData theData, int)
+{
+  IVtkDraw_Interactor *anInteractor = (IVtkDraw_Interactor *)theData;
+  // test for X Event
+  while (XPending(anInteractor->GetDisplayId()))
+  {
+    anInteractor->ViewerMainLoop (0, NULL);
+  }
+}
+
+#endif
diff --git a/src/IVtkDraw/IVtkDraw_Interactor.hxx b/src/IVtkDraw/IVtkDraw_Interactor.hxx
new file mode 100644 (file)
index 0000000..499feb8
--- /dev/null
@@ -0,0 +1,118 @@
+// Created on: 2012-05-28 
+// 
+// Copyright (c) 2012-2014 OPEN CASCADE SAS 
+// 
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IVtkDraw_Interactor_HeaderFile
+#define _IVtkDraw_Interactor_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <MMgt_TShared.hxx>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Shell.h>
+#include <X11/Xutil.h>
+#include <tk.h>
+#endif
+
+#include <vtkRenderWindowInteractor.h>
+#include <vtkSmartPointer.h>
+#include <IVtkTools_ShapePicker.hxx>
+#include <IVtkDraw_HighlightAndSelectionPipeline.hxx>
+#include <Aspect_Window.hxx>
+
+class vtkWin32RenderWindowInteractor;
+typedef vtkSmartPointer<IVtkTools_ShapePicker> PSelector;
+
+class IVtkDraw_Interactor : public vtkRenderWindowInteractor
+{
+public:
+  static IVtkDraw_Interactor *New();
+  vtkTypeMacro (IVtkDraw_Interactor, vtkRenderWindowInteractor);
+
+  virtual void Initialize();
+  virtual void Enable();
+  virtual void Start() { }
+
+  void SetShapePicker (const PSelector& theSelector);
+  void SetPipelines (const Handle(ShapePipelineMap)& thePipelines);
+  void SetOCCWindow (const Handle(Aspect_Window)& theWindow);
+  const Handle(Aspect_Window)& GetOCCWindow() const;
+
+  //! Process highlighting
+  void MoveTo (Standard_Integer theX, Standard_Integer theY);
+
+  //! Process selection
+  void OnSelection();
+
+  Standard_Boolean IsEnabled() const;
+
+#ifndef _WIN32
+  Display* GetDisplayId() const;
+  Standard_Integer ViewerMainLoop (Standard_Integer theArgNum, const char** theArgs);
+#endif
+
+protected:
+  IVtkDraw_Interactor();
+  IVtkDraw_Interactor (const IVtkDraw_Interactor& );
+  ~IVtkDraw_Interactor();
+
+
+#ifdef _WIN32
+  friend LRESULT CALLBACK WndProc (HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
+  friend LRESULT CALLBACK ViewerWindowProc (HWND hwnd,
+                                            UINT Msg,
+                                            WPARAM wParam,
+                                            LPARAM lParam,
+                                            IVtkDraw_Interactor *theInteractor);
+
+  void OnMouseMove (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y);
+  void OnRButtonDown (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y, Standard_Integer repeat=0);
+  void OnRButtonUp (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y);
+  void OnMButtonDown (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y, Standard_Integer repeat=0);
+  void OnMButtonUp (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y);
+  void OnLButtonDown (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y, Standard_Integer repeat=0);
+  void OnLButtonUp (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y);
+  void OnSize (HWND wnd, UINT nType,  Standard_Integer X, Standard_Integer Y);
+  void OnTimer (HWND wnd, UINT nIDEvent);
+  void OnMouseWheelForward (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y);
+  void OnMouseWheelBackward (HWND wnd, UINT nFlags, Standard_Integer X, Standard_Integer Y);
+#else
+  static void ProcessEvents (ClientData theData, int);
+  void GetMousePosition (Standard_Integer *theX, Standard_Integer *theY);
+#endif
+
+
+private:
+
+#ifdef _WIN32
+  HWND                     myWindowId;
+  Standard_Integer         myMouseInWindow;
+#else
+  Window                   myWindowId;
+  Display                 *myDisplayId;
+  Standard_Boolean         myIsLeftButtonPressed;
+#endif
+
+  PSelector                mySelector;
+  Handle(ShapePipelineMap) myPipelines;
+  Handle(Aspect_Window)    myWindow;
+
+};
+
+#endif
index e48cb7b..967f97f 100644 (file)
 ;# Liste des toolkits WOK sous forme de full path
 ;# 
 proc Draw:toolkits { } {
-    return [list TKDraw TKTopTest TKViewerTest TKXSDRAW TKDCAF TKXDEDRAW TKTObjDRAW TKQADraw]
+    set aResult [list TKDraw TKTopTest TKViewerTest TKXSDRAW TKDCAF TKXDEDRAW TKTObjDRAW TKQADraw]
+
+    if { $::env(HAVE_VTK) == "true" } {
+      lappend aResult "TKIVtkDraw"
+    }
+
+    return $aResult
 }
+
 ;#
 ;# Autres UDs a prendre. Listes de triplets
 ;# { ar typ UD str } Tous les types de UD vont dans un sous directory nomme root/str
diff --git a/src/TKIVtkDraw/EXTERNLIB b/src/TKIVtkDraw/EXTERNLIB
new file mode 100644 (file)
index 0000000..fc1f509
--- /dev/null
@@ -0,0 +1,18 @@
+CSF_VTK
+CSF_TclLibs
+CSF_TclTkLibs
+TKernel
+TKBRep
+TKDraw
+TKG2d
+TKG3d
+TKGeomAlgo
+TKGeomBase
+TKMath
+TKMesh
+TKService
+TKTopAlgo
+TKV3d
+TKOpenGl
+TKIVtk
+
diff --git a/src/TKIVtkDraw/FILES b/src/TKIVtkDraw/FILES
new file mode 100644 (file)
index 0000000..a8d3702
--- /dev/null
@@ -0,0 +1,2 @@
+PACKAGES
+EXTERNLIB
\ No newline at end of file
diff --git a/src/TKIVtkDraw/PACKAGES b/src/TKIVtkDraw/PACKAGES
new file mode 100644 (file)
index 0000000..66e2f72
--- /dev/null
@@ -0,0 +1 @@
+IVtkDraw
\ No newline at end of file
index 785f553..d6a4e9a 100755 (executable)
@@ -2,7 +2,6 @@ cpulimit 300
 set group "v3d"
 
 pload VISUALIZATION
-vinit View1
 pload TOPTEST
 
 if { [info exists imagedir] == 0 } {
index 378cff4..a07094a 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "edge"
index 9bd57b6..427b54c 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "edge_face"
index 81da205..dac621c 100644 (file)
@@ -1,3 +1,4 @@
+vinit View1
 set subgroup "edge_solid"
 
 
index 1d492e6..c7941ec 100755 (executable)
@@ -1,5 +1,5 @@
 catch { vfit }
-if { [ catch { vdump $imagedir/${test_image}.png } catch_result ] } {
+if { ![info exists to_dump_screen] && [ catch { vdump $imagedir/${test_image}.png } catch_result ] } {
   puts $catch_result
 }
 catch { vglinfo }
index 556a14f..3e56bf5 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "face"
diff --git a/tests/v3d/glsl/begin b/tests/v3d/glsl/begin
new file mode 100644 (file)
index 0000000..6cabd38
--- /dev/null
@@ -0,0 +1 @@
+vinit View1
\ No newline at end of file
index 1e5671d..7be59dc 100644 (file)
@@ -13,3 +13,4 @@
 013 glsl
 014 raytrace
 015 materials
+016 ivtk
diff --git a/tests/v3d/ivtk/begin b/tests/v3d/ivtk/begin
new file mode 100644 (file)
index 0000000..b0f7620
--- /dev/null
@@ -0,0 +1,5 @@
+pload VIS
+
+set to_dump_screen 1
+
+set subgroup ivtk
diff --git a/tests/v3d/ivtk/bgcolor b/tests/v3d/ivtk/bgcolor
new file mode 100644 (file)
index 0000000..3635a25
--- /dev/null
@@ -0,0 +1,18 @@
+puts "============"
+puts "bgcolor"
+puts "============"
+puts ""
+#######################################################
+#  Tests changing of background color in the IVtk view
+#######################################################
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+
+ivtkinit
+ivtkbgcolor 200 220 250
+ivtkdump $anImage1
+
+ivtkbgcolor 10 30 80 255 255 255
+ivtkdump $anImage2
+
diff --git a/tests/v3d/ivtk/detect b/tests/v3d/ivtk/detect
new file mode 100644 (file)
index 0000000..7763008
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============"
+puts "detect"
+puts "============"
+puts ""
+#######################################################
+#  Tests detection of shapes in the IVtk view
+#######################################################
+
+set anImage $imagedir/${casename}.png
+ivtkinit
+box b 1 1 1
+ivtkdisplay b
+ivtkmoveto 100 100
+
+ivtkdump $anImage
diff --git a/tests/v3d/ivtk/display_mode b/tests/v3d/ivtk/display_mode
new file mode 100644 (file)
index 0000000..3cf0131
--- /dev/null
@@ -0,0 +1,19 @@
+puts "============"
+puts "display_mode"
+puts "============"
+puts ""
+#######################################################
+#  Tests display modes changing in the IVtk view
+#######################################################
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+
+ivtkinit
+box b 1 1 1
+ivtkdisplay b
+ivtksetdispmode 1
+ivtkdump $anImage1
+
+ivtksetdispmode 0
+ivtkdump $anImage2
diff --git a/tests/v3d/ivtk/erase b/tests/v3d/ivtk/erase
new file mode 100644 (file)
index 0000000..09e5a57
--- /dev/null
@@ -0,0 +1,24 @@
+puts "============"
+puts "erase"
+puts "============"
+puts ""
+#######################################################
+#  Tests erasing of shapes in the IVtk view
+#######################################################
+
+set anImage1 $imagedir/${casename}_before.png
+set anImage2 $imagedir/${casename}_oneErased.png
+set anImage3 $imagedir/${casename}_allErased.png
+
+ivtkinit
+box b1 1 1 1
+box b2 3 3 3 1 1 1
+ivtkdisplay b1 b2 
+ivtkdump $anImage1
+
+ivtkerase b1
+ivtkdump $anImage2
+
+ivtkdisplay b1
+ivtkerase
+ivtkdump $anImage3
diff --git a/tests/v3d/ivtk/select b/tests/v3d/ivtk/select
new file mode 100644 (file)
index 0000000..5007fc6
--- /dev/null
@@ -0,0 +1,15 @@
+puts "============"
+puts "select"
+puts "============"
+puts ""
+#######################################################
+#  Tests selection of shapes in the IVtk view
+#######################################################
+
+set anImage $imagedir/${casename}.png
+ivtkinit
+box b 1 1 1
+ivtkdisplay b
+ivtkselect 100 100
+
+ivtkdump $anImage
diff --git a/tests/v3d/ivtk/selection_mode b/tests/v3d/ivtk/selection_mode
new file mode 100644 (file)
index 0000000..0503b43
--- /dev/null
@@ -0,0 +1,16 @@
+puts "============"
+puts "selection_mode"
+puts "============"
+puts ""
+#######################################################
+#  Tests selection modes changing in the IVtk view
+#######################################################
+
+set anImage $imagedir/${casename}.png
+ivtkinit
+box b 1 1 1
+ivtkdisplay b
+ivtksetselmode 2 1
+ivtkselect 86 117
+
+ivtkdump $anImage
diff --git a/tests/v3d/materials/begin b/tests/v3d/materials/begin
new file mode 100644 (file)
index 0000000..6cabd38
--- /dev/null
@@ -0,0 +1 @@
+vinit View1
\ No newline at end of file
diff --git a/tests/v3d/raytrace/begin b/tests/v3d/raytrace/begin
new file mode 100644 (file)
index 0000000..6cabd38
--- /dev/null
@@ -0,0 +1 @@
+vinit View1
\ No newline at end of file
index 2fa482e..5225a65 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "vertex"
index 96bcffe..9d2b7c2 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "vertex_edge"
index 9985ca3..64ad201 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "vertex_face"
index ff74724..d0a29e9 100644 (file)
@@ -1,2 +1,3 @@
+vinit View1
 set subgroup "vertex_solid"
 
index d07586a..16acd7f 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "vertex_wire"
diff --git a/tests/v3d/voxel/begin b/tests/v3d/voxel/begin
new file mode 100644 (file)
index 0000000..6cabd38
--- /dev/null
@@ -0,0 +1 @@
+vinit View1
\ No newline at end of file
index 9d2f0f3..ce5b265 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "wire"
index f164540..f8926ad 100644 (file)
@@ -1 +1,2 @@
+vinit View1
 set subgroup "wire_solid"