0025338: MFC standard samples: 3D selection rectangle blinking
authoraba <aba@opencascade.com>
Fri, 18 Dec 2015 07:17:18 +0000 (10:17 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 22 Dec 2015 11:18:23 +0000 (14:18 +0300)
- Added new interactive object AIS_RubberBand to draw rubber rectangle or polygon
- Added using of AIS_RubberBand in DRAW view for rectangular selection
- Added using of AIS_RubberBand in MFC samples for rectangular selection

12 files changed:
samples/mfc/standard/01_Geometry/src/GeometryView2D.cpp
samples/mfc/standard/Common/OCC_2dView.cpp
samples/mfc/standard/Common/OCC_2dView.h
samples/mfc/standard/Common/OCC_3dView.cpp
samples/mfc/standard/Common/OCC_3dView.h
samples/mfc/standard/Common/OCC_BaseDoc.h
samples/mfc/standard/Common/OCC_BaseView.cpp
samples/mfc/standard/Common/OCC_BaseView.h
src/AIS/AIS_RubberBand.cxx [new file with mode: 0644]
src/AIS/AIS_RubberBand.hxx [new file with mode: 0644]
src/AIS/FILES
src/ViewerTest/ViewerTest_ViewerCommands.cxx

index a717f34..feaa1e4 100755 (executable)
@@ -117,6 +117,7 @@ void CGeometryView2D::OnLButtonUp(UINT nFlags, CPoint point)
   }
   else // if ( Ctrl )
   {
+    const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetISessionContext();
     switch (myCurrentMode)
     {
     case CurAction2d_Nothing :
@@ -130,7 +131,7 @@ void CGeometryView2D::OnLButtonUp(UINT nFlags, CPoint point)
           GetDocument()->InputEvent2D     (point.x,point.y,myV2dView);
       } else
       {
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
+        drawRectangle (myXmin,myYmin,myXmax,myYmax,aContext,Standard_False);
         myXmax=point.x;  
         myYmax=point.y;
         if (nFlags & MK_SHIFT)
@@ -145,7 +146,7 @@ void CGeometryView2D::OnLButtonUp(UINT nFlags, CPoint point)
       break;
     case CurAction2d_WindowZooming :
       myXmax=point.x;         myYmax=point.y;
-      DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
+      drawRectangle (myXmin,myYmin,myXmax,myYmax,aContext,Standard_False);
       if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
         // Test if the zoom window is greater than a minimale window.
       {
@@ -221,14 +222,14 @@ void CGeometryView2D::OnMouseMove(UINT nFlags, CPoint point)
     }
     else // if ( Ctrl )
     {
+      const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetISessionContext();
       switch (myCurrentMode)
       {
       case CurAction2d_Nothing :
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
         myXmax = point.x; 
         myYmax = point.y;      
         GetDocument()->DragEvent2D(myXmax,myYmax,0,myV2dView);
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True);
+        drawRectangle (myXmin,myYmin,myXmax,myYmax, aContext);
         break;
       case CurAction2d_DynamicZooming :
         myV2dView->Zoom(myXmax,myYmax,point.x,point.y); 
@@ -237,8 +238,7 @@ void CGeometryView2D::OnMouseMove(UINT nFlags, CPoint point)
         break;
       case CurAction2d_WindowZooming :
         myXmax = point.x; myYmax = point.y;    
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
+        drawRectangle (myXmin,myYmin,myXmax,myYmax, aContext);
         break;
       case CurAction2d_DynamicPanning :
         myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
@@ -305,4 +305,4 @@ void CGeometryView2D::OnInitialUpdate()
   /* Matrox                               */
   /* I suspect another problem elsewhere  */
   ::PostMessage ( GetSafeHwnd () , WM_SIZE , SIZE_RESTORED , w + h*65536 ) ;
-}
\ No newline at end of file
+}
index 8209ab8..c8bf351 100755 (executable)
@@ -67,16 +67,13 @@ END_MESSAGE_MAP()
 // OCC_2dView construction/destruction
 
 OCC_2dView::OCC_2dView()
+: myCurrentMode (CurAction2d_Nothing)
 {
-  // TODO: add construction code here
-  myCurrentMode = CurAction2d_Nothing;
-  m_Pen = NULL;
 }
 
 OCC_2dView::~OCC_2dView()
 {
   myV2dView->Remove();
-  if (m_Pen) delete m_Pen;
 }
 
 BOOL OCC_2dView::PreCreateWindow(CREATESTRUCT& cs)
@@ -154,7 +151,7 @@ void OCC_2dView::OnBUTTONGridRectLines()
   aViewer->SetRectangularGridGraphicValues(aWidth,aHeight,anOffset);
   aViewer->ActivateGrid(Aspect_GT_Rectangular, Aspect_GDM_Lines);
   FitAll();
-  
+
   if (TheCircularGridDialog.IsWindowVisible())
   {
     TheCircularGridDialog.ShowWindow(SW_HIDE);
@@ -302,6 +299,7 @@ void OCC_2dView::OnLButtonUp(UINT nFlags, CPoint point)
   }
   else // if ( Ctrl )
   {
+    const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetAISContext();
     switch (myCurrentMode)
     {
     case CurAction2d_Nothing :
@@ -315,7 +313,7 @@ void OCC_2dView::OnLButtonUp(UINT nFlags, CPoint point)
           InputEvent2D     (point.x,point.y);
       } else
       {
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext, Standard_False);
         myXmax=point.x;  
         myYmax=point.y;
         if (nFlags & MULTISELECTIONKEY)
@@ -330,7 +328,7 @@ void OCC_2dView::OnLButtonUp(UINT nFlags, CPoint point)
       break;
     case CurAction2d_WindowZooming :
       myXmax=point.x;     myYmax=point.y;
-      DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
+      drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext, Standard_False);
       if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
         // Test if the zoom window is greater than a minimale window.
       {
@@ -410,13 +408,13 @@ void OCC_2dView::OnMouseMove(UINT nFlags, CPoint point)
     }
     else // if ( CASCADESHORTCUTKEY )
     {
+      const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetAISContext();
       switch (myCurrentMode)
       {
       case CurAction2d_Nothing :
         myXmax = point.x;     myYmax = point.y;        
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False);
         DragEvent2D(myXmax,myYmax,0);  
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True);
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext);
         break;
       case CurAction2d_DynamicZooming :
         myV2dView->Zoom(myXmax,myYmax,point.x,point.y);
@@ -424,15 +422,15 @@ void OCC_2dView::OnMouseMove(UINT nFlags, CPoint point)
         myXmax=point.x;  myYmax=point.y;
         break;
       case CurAction2d_WindowZooming :
-        myXmax = point.x; myYmax = point.y;    
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
-        DrawRectangle2D(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
+        myXmax = point.x;
+        myYmax = point.y;
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext);
         break;
       case CurAction2d_DynamicPanning :
         myV2dView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
         myXmax = point.x; myYmax = point.y;    
         break;
-      case CurAction2d_GlobalPanning : // nothing           
+      case CurAction2d_GlobalPanning : // nothing
         break;
       default :
         Standard_Failure::Raise(" incompatible Current Mode ");
@@ -558,60 +556,6 @@ void OCC_2dView::OnUpdateBUTTON2DZoomWin(CCmdUI* pCmdUI)
   pCmdUI->Enable   (myCurrentMode != CurAction2d_WindowZooming);               
 }
 
-
-void OCC_2dView::DrawRectangle2D(const Standard_Integer  MinX,
-                              const Standard_Integer  MinY,
-                              const Standard_Integer  MaxX,
-                              const Standard_Integer  MaxY,
-                              const Standard_Boolean  Draw, 
-                              const LineStyle aLineStyle)
-{
-  static int m_DrawMode;
-  if  (!m_Pen && aLineStyle ==Solid )
-  {m_Pen = new CPen(PS_SOLID, 1, RGB(0,0,0)); m_DrawMode = R2_MERGEPENNOT;}
-  else if (!m_Pen && aLineStyle ==Dot )
-  {m_Pen = new CPen(PS_DOT, 1, RGB(0,0,0));   m_DrawMode = R2_XORPEN;}
-  else if (!m_Pen && aLineStyle == ShortDash)
-  {m_Pen = new CPen(PS_DASH, 1, RGB(255,0,0)); m_DrawMode = R2_XORPEN;}
-  else if (!m_Pen && aLineStyle == LongDash)
-  {m_Pen = new CPen(PS_DASH, 1, RGB(0,0,0));   m_DrawMode = R2_NOTXORPEN;}
-  else if (aLineStyle == Default) 
-  { m_Pen = NULL;      m_DrawMode = R2_MERGEPENNOT;}
-
-  CPen* aOldPen = NULL;
-  CClientDC clientDC(this);
-  if (m_Pen) aOldPen = clientDC.SelectObject(m_Pen);
-  clientDC.SetROP2(m_DrawMode);
-
-  static               Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
-  static               Standard_Boolean m_IsVisible;
-
-  if ( m_IsVisible && !Draw) // move or up  : erase at the old position 
-  {
-    clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
-    clientDC.LineTo(StoredMaxX,StoredMaxY); 
-    clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
-    m_IsVisible = false;
-  }
-
-  StoredMinX = Min ( MinX, MaxX );
-  StoredMinY = Min ( MinY, MaxY );
-  StoredMaxX = Max ( MinX, MaxX );
-  StoredMaxY = Max ( MinY, MaxY);
-
-  if (Draw) // move : draw
-  {
-    clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
-    clientDC.LineTo(StoredMaxX,StoredMaxY); 
-    clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
-    m_IsVisible = true;
-  }
-
-  if (m_Pen) clientDC.SelectObject(aOldPen);
-}
-
-
-
 // =====================================================================
 
 //-----------------------------------------------------------------------------------------
index eaa03d6..5fe2620 100755 (executable)
@@ -93,24 +93,6 @@ protected:
 
 protected:
 
-  CurrentAction2d myCurrentMode;
-  Standard_Integer myXmin;
-  Standard_Integer myYmin;
-  Standard_Integer myXmax;
-  Standard_Integer myYmax;
-  Quantity_Factor myCurZoom;
-
-  enum LineStyle { Solid, Dot, ShortDash, LongDash, Default };
-
-  CPen* m_Pen;
-
-  virtual void DrawRectangle2D (const Standard_Integer MinX,
-                                const Standard_Integer MinY,
-                                const Standard_Integer MaxX,
-                                const Standard_Integer MaxY,
-                                const Standard_Boolean Draw,
-                                const LineStyle aLineStyle = Default);
-
     virtual void DragEvent2D (const Standard_Integer x,
                               const Standard_Integer y,
                               const Standard_Integer TheState);
@@ -136,9 +118,10 @@ protected:
 
 protected:
 
+  Handle(V3d_View) myV2dView;
+  CurrentAction2d  myCurrentMode;
   CRectangularGrid TheRectangularGridDialog;
   CCircularGrid    TheCircularGridDialog;
-  Handle(V3d_View) myV2dView;
 };
 
 #ifndef _DEBUG  // debug version in 2DDisplayView.cpp
index 8c5c577..324919e 100755 (executable)
@@ -62,15 +62,9 @@ END_MESSAGE_MAP()
 
 OCC_3dView::OCC_3dView()
 : myCurrentMode (CurAction3d_Nothing),
-  myXmin (0),
-  myYmin (0),
-  myXmax (0),
-  myYmax (0),
-  myCurZoom (0.0),
   myWidth  (0),
   myHeight (0),
-  myHlrModeIsOn (Standard_False),
-  m_Pen (NULL)
+  myHlrModeIsOn (Standard_False)
 {
   // TODO: add construction code here
 }
@@ -83,7 +77,6 @@ OCC_3dView::~OCC_3dView()
   }
 
   delete m_pStereoDlg;
-  delete m_Pen;
 }
 
 BOOL OCC_3dView::PreCreateWindow(CREATESTRUCT& cs)
@@ -135,7 +128,7 @@ void OCC_3dView::OnDraw(CDC* /*pDC*/)
   if(myWidth != aRect.Width() || myHeight != aRect.Height()) {
     myWidth = aRect.Width();
     myHeight = aRect.Height();
-    ::PostMessage ( GetSafeHwnd () , WM_SIZE , SW_SHOW , myWidth + myHeight*65536 );
+    ::PostMessage ( GetSafeHwnd() , WM_SIZE , SW_SHOW , myWidth + myHeight*65536 );
   }
   myView->Redraw();
 }
@@ -321,6 +314,7 @@ void OCC_3dView::OnLButtonUp(UINT nFlags, CPoint point)
   }
   else // if ( Ctrl )
   {
+    const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetAISContext();
     switch (myCurrentMode)
     {
     case CurAction3d_Nothing :
@@ -335,7 +329,7 @@ void OCC_3dView::OnLButtonUp(UINT nFlags, CPoint point)
       } else
       {
         myXmax=point.x;    myYmax=point.y;
-        DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext, Standard_False);
         if (nFlags & MK_SHIFT)
           GetDocument()->ShiftDragEvent(point.x,point.y,1,myView);
         else
@@ -347,7 +341,7 @@ void OCC_3dView::OnLButtonUp(UINT nFlags, CPoint point)
       break;
     case CurAction3d_WindowZooming :
       myXmax=point.x;        myYmax=point.y;
-      DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
+      drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext, Standard_False);
       if ((abs(myXmin-myXmax)>ValZWMin) || (abs(myYmin-myYmax)>ValZWMin))
         // Test if the zoom window is greater than a minimale window.
       {
@@ -432,17 +426,17 @@ void OCC_3dView::OnMouseMove(UINT nFlags, CPoint point)
     {
       // move with MB1 and Control : on the dynamic zooming  
       // Do the zoom in function of mouse's coordinates  
-      myView->Zoom(myXmax,myYmax,point.x,point.y); 
+      myView->Zoom (myXmax,myYmax,point.x,point.y); 
       // save the current mouse coordinate in min 
       myXmax = point.x; 
       myYmax = point.y;        
     }
     else // if ( Ctrl )
     {
+      const Handle(AIS_InteractiveContext)& aContext = GetDocument()->GetAISContext();
       switch (myCurrentMode)
       {
       case CurAction3d_Nothing :
-        DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False);
         myXmax = point.x;
         myYmax = point.y;
 
@@ -450,18 +444,20 @@ void OCC_3dView::OnMouseMove(UINT nFlags, CPoint point)
           GetDocument()->ShiftDragEvent(myXmax,myYmax,0,myView);
         else
           GetDocument()->DragEvent(myXmax,myYmax,0,myView);
-        DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True);
+
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext);
 
         break;
       case CurAction3d_DynamicZooming :
         myView->Zoom(myXmax,myYmax,point.x,point.y); 
         // save the current mouse coordinate in min \n";
-        myXmax=point.x;  myYmax=point.y;
+        myXmax = point.x;
+        myYmax = point.y;
         break;
       case CurAction3d_WindowZooming :
-        myXmax = point.x; myYmax = point.y;    
-        DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_False,LongDash);
-        DrawRectangle(myXmin,myYmin,myXmax,myYmax,Standard_True,LongDash);
+        myXmax = point.x;
+        myYmax = point.y;
+        drawRectangle (myXmin, myYmin, myXmax, myYmax, aContext);
         break;
       case CurAction3d_DynamicPanning :
         myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
@@ -484,8 +480,8 @@ void OCC_3dView::OnMouseMove(UINT nFlags, CPoint point)
     if ( nFlags & MK_CONTROL ) 
     {
       myView->Pan(point.x-myXmax,myYmax-point.y); // Realize the panning
-      myXmax = point.x; myYmax = point.y;      
-
+      myXmax = point.x;
+      myYmax = point.y;
     }
   } 
   else if ( nFlags & MK_RBUTTON)
@@ -496,8 +492,9 @@ void OCC_3dView::OnMouseMove(UINT nFlags, CPoint point)
     }
   }
   else 
-  {  // No buttons 
-    myXmax = point.x; myYmax = point.y;        
+  {  // No buttons
+    myXmax = point.x;
+    myYmax = point.y;
     if (nFlags & MK_SHIFT)
       GetDocument()->ShiftMoveEvent(point.x,point.y,myView);
     else
@@ -505,59 +502,6 @@ void OCC_3dView::OnMouseMove(UINT nFlags, CPoint point)
   }
 }
 
-void OCC_3dView::DrawRectangle(const Standard_Integer  MinX    ,
-                                                           const Standard_Integer  MinY    ,
-                                        const Standard_Integer  MaxX ,
-                                                           const Standard_Integer  MaxY ,
-                                                           const Standard_Boolean  Draw , 
-                                        const LineStyle aLineStyle)
-{
-    static int m_DrawMode;
-    if  (!m_Pen && aLineStyle ==Solid )
-        {m_Pen = new CPen(PS_SOLID, 1, RGB(0,0,0)); m_DrawMode = R2_MERGEPENNOT;}
-    else if (!m_Pen && aLineStyle ==Dot )
-        {m_Pen = new CPen(PS_DOT, 1, RGB(0,0,0));   m_DrawMode = R2_XORPEN;}
-    else if (!m_Pen && aLineStyle == ShortDash)
-        {m_Pen = new CPen(PS_DASH, 1, RGB(255,0,0));   m_DrawMode = R2_XORPEN;}
-    else if (!m_Pen && aLineStyle == LongDash)
-        {m_Pen = new CPen(PS_DASH, 1, RGB(0,0,0));     m_DrawMode = R2_NOTXORPEN;}
-    else if (aLineStyle == Default) 
-        { m_Pen = NULL;        m_DrawMode = R2_MERGEPENNOT;}
-
-    CPen* aOldPen = NULL;
-    CClientDC clientDC(this);
-    if (m_Pen) aOldPen = clientDC.SelectObject(m_Pen);
-    clientDC.SetROP2(m_DrawMode);
-
-    static             Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
-    static             Standard_Boolean m_IsVisible;
-
-    if ( m_IsVisible && !Draw) // move or up  : erase at the old position 
-    {
-     clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
-     clientDC.LineTo(StoredMaxX,StoredMaxY); 
-        clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
-     m_IsVisible = false;
-    }
-
-    StoredMinX = Min ( MinX, MaxX );
-    StoredMinY = Min ( MinY, MaxY );
-    StoredMaxX = Max ( MinX, MaxX );
-    StoredMaxY = Max ( MinY, MaxY);
-
-    if (Draw) // move : draw
-    {
-     clientDC.MoveTo(StoredMinX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMaxY); 
-     clientDC.LineTo(StoredMaxX,StoredMaxY); 
-        clientDC.LineTo(StoredMaxX,StoredMinY); clientDC.LineTo(StoredMinX,StoredMinY);
-     m_IsVisible = true;
-   }
-
-    if (m_Pen) clientDC.SelectObject(aOldPen);
-}
-
-
-
 void OCC_3dView::OnUpdateBUTTONHlrOff(CCmdUI* pCmdUI) 
 {
   pCmdUI->SetCheck (!myHlrModeIsOn);
index dfe7929..69a73f4 100755 (executable)
@@ -94,27 +94,12 @@ protected:
 
 protected:
 
-  Handle(V3d_View)  myView;
+  Handle(V3d_View) myView;
   CurAction3d      myCurrentMode;
-  Standard_Integer myXmin;
-  Standard_Integer myYmin;
-  Standard_Integer myXmax;
-  Standard_Integer myYmax;
-  Quantity_Factor  myCurZoom;
   Standard_Integer myWidth;
   Standard_Integer myHeight;
   Standard_Boolean myHlrModeIsOn;
 
-       enum LineStyle { Solid, Dot, ShortDash, LongDash, Default };
-       CPen*  m_Pen;
-
-    virtual void DrawRectangle (const Standard_Integer  MinX  ,
-                                               const Standard_Integer  MinY  ,
-                                const Standard_Integer  MaxX  ,
-                                               const Standard_Integer  MaxY  ,
-                                                   const Standard_Boolean  Draw  ,
-                                const LineStyle aLineStyle = Default  );
-
 private:
 
   //! Persistent non blocking stereo configuration dialog
index 0c8ad8c..e4897a4 100755 (executable)
@@ -69,8 +69,6 @@ public:
                       const Standard_Integer /*theMouseY*/,
                       const Handle(V3d_View)& /*theView*/) {}
 
-public:
-
   void ResetDocumentViews (CDocTemplate* theTemplate);
 
 protected:
index 2b0eb1c..b03d651 100755 (executable)
@@ -5,16 +5,75 @@
 #include <stdafx.h>
 #include "OCC_BaseView.h"
 
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
 OCC_BaseView::OCC_BaseView()
+  : myXmin (0),
+    myYmin (0),
+    myXmax (0),
+    myYmax (0),
+    myCurZoom (0.0),
+    myRect (new AIS_RubberBand (Quantity_Color(Quantity_NOC_WHITE), Aspect_TOL_SOLID, 1.0) )
 {
-
+  myRect->SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0));
+  if (myRect->ZLayer() != Graphic3d_ZLayerId_TopOSD)
+  {
+    myRect->SetZLayer (Graphic3d_ZLayerId_TopOSD);
+  }
+  
 }
 
+//=======================================================================
+//function : Destructor
+//purpose  :
+//=======================================================================
 OCC_BaseView::~OCC_BaseView()
 {
 
 }
+
+//=======================================================================
+//function : GetDocument
+//purpose  :
+//=======================================================================
+OCC_BaseDoc* OCC_BaseView::GetDocument() // non-debug version is inline
+{
+       return (OCC_BaseDoc*)m_pDocument;
+}
+
+//=======================================================================
+//function : drawRectangle
+//purpose  :
+//=======================================================================
+void OCC_BaseView::drawRectangle (const Standard_Integer theMinX,
+                                  const Standard_Integer theMinY,
+                                  const Standard_Integer theMaxX,
+                                  const Standard_Integer theMaxY,
+                                  const Handle(AIS_InteractiveContext)& theContext,
+                                  const Standard_Boolean toDraw)
+{
+  if (toDraw)
+  {
+    CRect aRect;
+    GetWindowRect(aRect);
+    myRect->SetRectangle (theMinX, aRect.Height() - theMinY, theMaxX, aRect.Height() - theMaxY);
+
+    if (!theContext->IsDisplayed (myRect))
+    {
+      theContext->Display (myRect, Standard_False);
+    }
+    else
+    {
+      theContext->Redisplay (myRect, Standard_False);
+    }
+  }
+  else
+  {
+    theContext->Remove (myRect, Standard_False);
+  }
+
+  theContext->CurrentViewer()->RedrawImmediate();
+}
+
index 5351024..c3bf793 100755 (executable)
 
 #include <stdafx.h>
 
+#include "OCC_BaseDoc.h"
+#include "AIS_RubberBand.hxx"
+
 class AFX_EXT_CLASS OCC_BaseView  : public CView
 {
+  
 public:
+  
        OCC_BaseView();
        virtual ~OCC_BaseView();
+  
+  OCC_BaseDoc* GetDocument();
+
+protected:
+  
+  virtual void drawRectangle (const Standard_Integer theMinX,
+                              const Standard_Integer theMinY,
+                              const Standard_Integer theMaxX,
+                              const Standard_Integer theMaxY,
+                              const Handle(AIS_InteractiveContext)& theContext,
+                              const Standard_Boolean toDraw = Standard_True);
+
+
+protected:
+
+  Quantity_Factor  myCurZoom;
+  Standard_Integer myXmin;
+  Standard_Integer myYmin;
+  Standard_Integer myXmax;
+  Standard_Integer myYmax;
 
+  Handle(AIS_RubberBand) myRect; //!< Rubber rectangle for selection
 };
 
 #endif // !defined(AFX_OCC_BASEVIEW_H__2E048CCA_38F9_11D7_8611_0060B0EE281E__INCLUDED_)
diff --git a/src/AIS/AIS_RubberBand.cxx b/src/AIS/AIS_RubberBand.cxx
new file mode 100644 (file)
index 0000000..2169e8d
--- /dev/null
@@ -0,0 +1,417 @@
+// Created on: 2015-11-23
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2015 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 <AIS_RubberBand.hxx>
+#include <BRepMesh_DataStructureOfDelaun.hxx>
+#include <BRepMesh_Delaun.hxx>
+#include <Graphic3d_ArrayOfPolygons.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_GraphicDriver.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_TransModeFlags.hxx>
+#include <Graphic3d_ZLayerId.hxx>
+#include <Prs3d_LineAspect.hxx>
+#include <Prs3d_Root.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <V3d_Viewer.hxx>
+#include <V3d_View.hxx>
+
+
+#define MEMORY_BLOCK_SIZE 512 * 7
+
+IMPLEMENT_STANDARD_RTTIEXT(AIS_RubberBand, AIS_InteractiveObject)
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_RubberBand::AIS_RubberBand()
+{
+  myDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0));
+  myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+  myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_EMPTY);
+  myDrawer->ShadingAspect()->SetTransparency (1.0);
+  myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
+
+  SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0));
+  SetZLayer (Graphic3d_ZLayerId_TopOSD);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_RubberBand::AIS_RubberBand (const Quantity_Color& theLineColor,
+                                const Aspect_TypeOfLine theLineType,
+                                const Standard_Real theWidth)
+{
+  myDrawer->SetLineAspect (new Prs3d_LineAspect (theLineColor, theLineType, theWidth));
+  myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+  myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_EMPTY);
+  myDrawer->ShadingAspect()->SetTransparency (1.0);
+  myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
+
+  SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0));
+  SetZLayer (Graphic3d_ZLayerId_TopOSD);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+AIS_RubberBand::AIS_RubberBand (const Quantity_Color& theLineColor,
+                                const Aspect_TypeOfLine theLineType,
+                                const Quantity_Color theFillColor,
+                                const Standard_Real theTransparency,
+                                const Standard_Real theLineWidth)
+{
+  myDrawer->SetLineAspect (new Prs3d_LineAspect (theLineColor, theLineType, theLineWidth));
+  myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
+  myDrawer->ShadingAspect()->SetColor (theFillColor);
+  myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
+  myDrawer->ShadingAspect()->SetTransparency (theTransparency);
+
+  SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0));
+  SetZLayer (Graphic3d_ZLayerId_TopOSD);
+}
+
+//=======================================================================
+//function : Destructor
+//purpose  :
+//=======================================================================
+AIS_RubberBand::~AIS_RubberBand()
+{
+  myPoints.Clear();
+  myTriangles.Nullify();
+  myBorders.Nullify();
+}
+
+//=======================================================================
+//function : SetRectangle
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetRectangle (const Standard_Integer theMinX, const Standard_Integer theMinY,
+                                   const Standard_Integer theMaxX, const Standard_Integer theMaxY)
+{
+  myPoints.Clear();
+  myPoints.Append (Graphic3d_Vec2i (theMinX, theMinY));
+  myPoints.Append (Graphic3d_Vec2i (theMinX, theMaxY));
+  myPoints.Append (Graphic3d_Vec2i (theMaxX, theMaxY));
+  myPoints.Append (Graphic3d_Vec2i (theMaxX, theMinY));
+}
+
+//=======================================================================
+//function : AddPoint
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::AddPoint (const Graphic3d_Vec2i& thePoint)
+{
+  myPoints.Append (thePoint);
+}
+
+//=======================================================================
+//function : AddPoint
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::RemoveLastPoint()
+{
+  myPoints.Remove (myPoints.Length());
+}
+
+//=======================================================================
+//function : GetPoints
+//purpose  :
+//=======================================================================
+const NCollection_Sequence<Graphic3d_Vec2i>& AIS_RubberBand::Points() const
+{
+  return myPoints;
+}
+
+//=======================================================================
+//function : LineColor
+//purpose  :
+//=======================================================================
+Quantity_Color AIS_RubberBand::LineColor() const
+{
+  Quantity_Color aColor;
+  Standard_Real aWidth;
+  Aspect_TypeOfLine aTOL;
+  myDrawer->LineAspect()->Aspect()->Values (aColor, aTOL, aWidth);
+  return aColor;
+}
+
+//=======================================================================
+//function : SetLineColor
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetLineColor (const Quantity_Color& theColor)
+{
+  myDrawer->LineAspect()->SetColor (theColor);
+}
+
+//=======================================================================
+//function : FillColor
+//purpose  :
+//=======================================================================
+Quantity_Color AIS_RubberBand::FillColor() const
+{
+  return myDrawer->ShadingAspect()->Color();
+}
+
+//=======================================================================
+//function : SetFillColor
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetFillColor (const Quantity_Color& theColor)
+{
+  myDrawer->ShadingAspect()->SetColor (theColor);
+}
+
+//=======================================================================
+//function : SetLineWidth
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetLineWidth (const Standard_Real theWidth) const
+{
+  myDrawer->LineAspect()->SetWidth (theWidth);
+}
+
+//=======================================================================
+//function : SetLineWidth
+//purpose  :
+//=======================================================================
+Standard_Real AIS_RubberBand::LineWidth() const
+{
+  Quantity_Color aColor;
+  Standard_Real aWidth;
+  Aspect_TypeOfLine aTOL;
+  myDrawer->LineAspect()->Aspect()->Values (aColor, aTOL, aWidth);
+  return aWidth;
+}
+
+//=======================================================================
+//function : SetLineType
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetLineType (const Aspect_TypeOfLine theType)
+{
+  myDrawer->LineAspect()->SetTypeOfLine (theType);
+}
+
+//=======================================================================
+//function : LineType
+//purpose  :
+//=======================================================================
+Aspect_TypeOfLine AIS_RubberBand::LineType() const
+{
+  Quantity_Color aColor;
+  Standard_Real aWidth;
+  Aspect_TypeOfLine aTOL;
+  myDrawer->LineAspect()->Aspect()->Values (aColor, aTOL, aWidth);
+  return aTOL;
+}
+
+//=======================================================================
+//function : SetFillTransparency
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetFillTransparency (const Standard_Real theValue) const
+{
+  myDrawer->ShadingAspect()->SetTransparency (theValue);
+}
+
+//=======================================================================
+//function : SetFillTransparency
+//purpose  :
+//=======================================================================
+Standard_Real AIS_RubberBand::FillTransparency() const
+{
+  return myDrawer->ShadingAspect()->Transparency();
+}
+
+//=======================================================================
+//function : SetFilling
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetFilling (const Standard_Boolean theIsFilling)
+{
+  myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (theIsFilling ? Aspect_IS_SOLID : Aspect_IS_EMPTY);
+}
+
+//=======================================================================
+//function : SetFilling
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::SetFilling (const Quantity_Color theColor, const Standard_Real theTransparency)
+{
+  SetFilling (Standard_True);
+  SetFillTransparency (theTransparency);
+  SetFillColor (theColor);
+}
+
+//=======================================================================
+//function : IsFilling
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_RubberBand::IsFilling() const
+{
+  Aspect_InteriorStyle aStyle;
+  Quantity_Color anIntColor, anEdgeColor;
+  Aspect_TypeOfLine aTOL;
+  Standard_Real aWidth;
+  myDrawer->ShadingAspect()->Aspect()->Values (aStyle, anIntColor, anEdgeColor, aTOL, aWidth);
+  return aStyle != Aspect_IS_EMPTY;
+}
+
+//=======================================================================
+//function : fillTriangles
+//purpose  :
+//=======================================================================
+Standard_Boolean AIS_RubberBand::fillTriangles()
+{
+  Handle(NCollection_IncAllocator) anAllocator = new NCollection_IncAllocator (MEMORY_BLOCK_SIZE);
+  Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
+  Standard_Integer aPtsLower = myPoints.Lower();
+  Standard_Integer aPtsUpper = myPoints.Upper();
+  BRepMesh::Array1OfInteger anIndexes (0, myPoints.Length() - 1);
+  for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
+  {
+    gp_XY aP ((Standard_Real)myPoints.Value (aPtIdx).x(),
+              (Standard_Real)myPoints.Value (aPtIdx).y());
+    BRepMesh_Vertex aVertex (aP, aPtIdx, BRepMesh_Frontier);
+    anIndexes.ChangeValue (aPtIdx - aPtsLower) = aMeshStructure->AddNode (aVertex);
+  }
+
+  Standard_Real aPtSum = 0;
+  for (Standard_Integer aIdx = aPtsLower; aIdx <= aPtsUpper; ++aIdx)
+  {
+    Standard_Integer aNextIdx = (aIdx % myPoints.Length()) + 1;
+    aPtSum += (Standard_Real)(myPoints.Value (aNextIdx).x() - myPoints.Value (aIdx).x())
+             * (Standard_Real)(myPoints.Value (aNextIdx).y() + myPoints.Value (aIdx).y());
+  }
+  Standard_Boolean isClockwiseOrdered = aPtSum < 0;
+
+  for (Standard_Integer aIdx = 0; aIdx < anIndexes.Length(); ++aIdx)
+  {
+    Standard_Integer aPtIdx = isClockwiseOrdered ? aIdx : (aIdx + 1) % anIndexes.Length();
+    Standard_Integer aNextPtIdx = isClockwiseOrdered ? (aIdx + 1) % anIndexes.Length() : aIdx;
+    BRepMesh_Edge anEdge (anIndexes.Value (aPtIdx),
+                          anIndexes.Value (aNextPtIdx),
+                          BRepMesh_Frontier);
+    aMeshStructure->AddLink (anEdge);
+  }
+
+  BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes);
+  const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
+  if (aTriangles.Extent() < 1)
+    return Standard_False;
+
+
+  Standard_Boolean toFill = Standard_False;
+  if (myTriangles.IsNull() || myTriangles->VertexNumber() != myPoints.Length() + 1)
+  {
+    toFill = Standard_True;
+    myTriangles = new Graphic3d_ArrayOfTriangles (aTriangles.Extent() * 3);
+  }
+
+  Standard_Integer aVertexIndex = 1;
+  BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles);
+  for (; aTriangleIt.More(); aTriangleIt.Next())
+  {
+    const Standard_Integer aTriangleId = aTriangleIt.Key();
+    const BRepMesh_Triangle& aCurrentTriangle = aMeshStructure->GetElement (aTriangleId);
+
+    if (aCurrentTriangle.Movability() == BRepMesh_Deleted)
+      continue;
+
+    Standard_Integer aTriangleVerts[3];
+    aMeshStructure->ElementNodes (aCurrentTriangle, aTriangleVerts);
+
+    gp_Pnt2d aPts[3];
+    for (Standard_Integer aVertIdx = 0; aVertIdx < 3; ++aVertIdx)
+    {
+      const BRepMesh_Vertex& aVertex = aMeshStructure->GetNode (aTriangleVerts[aVertIdx]);
+      aPts[aVertIdx] = aVertex.Coord();
+    }
+
+    if (toFill)
+    {
+      for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
+      {
+        myTriangles->AddVertex (aPts[anIt].X(), aPts[anIt].Y(), 0.0);
+      }
+    }
+    else
+    {
+      for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
+      {
+        myTriangles->SetVertice (aVertexIndex++, (Standard_ShortReal)aPts[anIt].X(), (Standard_ShortReal)aPts[anIt].Y(), 0.0f);
+      }
+    }
+  }
+
+  aMeshStructure.Nullify();
+  anAllocator.Nullify();
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Compute
+//purpose  :
+//=======================================================================
+void AIS_RubberBand::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
+                              const Handle(Prs3d_Presentation)& thePresentation,
+                              const Standard_Integer /*theMode*/)
+{
+  Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
+
+  // Draw filling
+  if (IsFilling() && fillTriangles())
+  {
+    aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
+    aGroup->AddPrimitiveArray (myTriangles);
+  }
+
+  // Draw frame
+  if (myBorders.IsNull() || myBorders->VertexNumber() != myPoints.Length() + 1)
+  {
+     myBorders = new Graphic3d_ArrayOfPolylines (myPoints.Length() + 1);
+     for (Standard_Integer anIt = 1; anIt <= myPoints.Length(); anIt++)
+     {
+       myBorders->AddVertex ((Standard_Real)myPoints.Value (anIt).x(),
+                             (Standard_Real)myPoints.Value (anIt).y(), 0.0);
+     }
+
+     myBorders->AddVertex ((Standard_Real)myPoints.Value(1).x(),
+                           (Standard_Real)myPoints.Value(1).y(), 0.0);
+
+  }
+  else
+  {
+    for (Standard_Integer anIt = 1; anIt <= myPoints.Length(); anIt++)
+    {
+          myBorders->SetVertice (anIt, (Standard_ShortReal)myPoints.Value (anIt).x(),
+                                 (Standard_ShortReal)myPoints.Value (anIt).y(), 0.0f);
+    }
+
+    myBorders->SetVertice (myPoints.Length() + 1, (Standard_ShortReal)myPoints.Value(1).x(),
+                           (Standard_ShortReal)myPoints.Value(1).y(), 0.0f);
+  }
+
+  aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
+  aGroup->AddPrimitiveArray (myBorders);
+}
diff --git a/src/AIS/AIS_RubberBand.hxx b/src/AIS/AIS_RubberBand.hxx
new file mode 100644 (file)
index 0000000..6cfd011
--- /dev/null
@@ -0,0 +1,148 @@
+// Created on: 2015-11-23
+// Created by: Anastasia BORISOVA
+// Copyright (c) 2015 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 _AIS_RubberBand_HeaderFile
+#define _AIS_RubberBand_HeaderFile
+
+#include <AIS_InteractiveObject.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_Vec2.hxx>
+#include <NCollection_Sequence.hxx>
+
+//! Presentation for drawing rubber band selection.
+//! It supports rectangle and polygonal selection.
+//! It is constructed in 2d overlay.
+//! Default configaration is built without filling.
+//! For rectangle selection use SetRectangle() method.
+//! For polygonal selection use AddPoint() and GetPoints() methods.
+class AIS_RubberBand : public AIS_InteractiveObject
+{
+public:
+
+  DEFINE_STANDARD_RTTIEXT(AIS_RubberBand, AIS_InteractiveObject)
+
+  //! Constructs rubber band with default configuration: empty filling and white solid lines.
+  //! @warning It binds this object with Graphic3d_ZLayerId_TopOSD layer.
+  Standard_EXPORT AIS_RubberBand();
+
+  //! Consructs the rubber band with empty filling and defined line style.
+  //! @param theLineColor [in] color of rubber band lines
+  //! @param theType [in] type of rubber band lines
+  //! @param theLineWidth [in] width of rubber band line. By default it is 1.
+  //! @warning It binds this object with Graphic3d_ZLayerId_TopOSD layer.
+  Standard_EXPORT AIS_RubberBand (const Quantity_Color& theLineColor,
+                                  const Aspect_TypeOfLine theType,
+                                  const Standard_Real theLineWidth = 1.0);
+
+  //! Constructs the rubber band with defined filling and line parameters.
+  //! @param theLineColor [in] color of rubber band lines
+  //! @param theType [in] type of rubber band lines
+  //! @param theFillColor [in] color of rubber band filling
+  //! @param theTransparency [in] transparency of the filling. 0 is for opaque filling. By default it is transparent.
+  //! @param theLineWidth [in] width of rubber band line. By default it is 1.
+  //! @warning It binds this object with Graphic3d_ZLayerId_TopOSD layer.
+  Standard_EXPORT AIS_RubberBand (const Quantity_Color& theLineColor,
+                                  const Aspect_TypeOfLine theType,
+                                  const Quantity_Color theFillColor,
+                                  const Standard_Real theTransparency = 1.0,
+                                  const Standard_Real theLineWidth = 1.0);
+
+  Standard_EXPORT virtual ~AIS_RubberBand();
+
+  //! Sets rectangle bounds.
+  Standard_EXPORT void SetRectangle (const Standard_Integer theMinX, const Standard_Integer theMinY,
+                                     const Standard_Integer theMaxX, const Standard_Integer theMaxY);
+
+  //! Adds last point to the list of points. They are used to build polygon for rubber band.
+  //! @sa RemoveLastPoint(), GetPoints()
+  Standard_EXPORT void AddPoint (const Graphic3d_Vec2i& thePoint);
+
+  //! Remove last point from the list of points for the rubber band polygon.
+  //! @sa AddPoint(), GetPoints()
+  Standard_EXPORT void RemoveLastPoint();
+
+  //! @return points for the rubber band polygon.
+  Standard_EXPORT const NCollection_Sequence<Graphic3d_Vec2i>& Points() const;
+
+  //! Remove all points for the rubber band polygon.
+  void ClearPoints() { myPoints.Clear(); }
+
+  //! @return the Color attributes.
+  Standard_EXPORT Quantity_Color LineColor() const;
+
+  //! Sets color of lines for rubber band presentation.
+  Standard_EXPORT void SetLineColor (const Quantity_Color& theColor);
+
+  //! @return the color of rubber band filling.
+  Standard_EXPORT Quantity_Color FillColor() const;
+
+  //! Sets color of rubber band filling.
+  Standard_EXPORT void SetFillColor (const Quantity_Color& theColor);
+
+  //! Sets wodth of line for rubber band presentation.
+  Standard_EXPORT void SetLineWidth (const Standard_Real theWidth) const;
+
+  //! @return width of lines.
+  Standard_EXPORT Standard_Real LineWidth() const;
+
+  //! Sets type of line for rubber band presentation.
+  Standard_EXPORT void SetLineType (const Aspect_TypeOfLine theType);
+
+  //! @return type of lines.
+  Standard_EXPORT Aspect_TypeOfLine LineType() const;
+
+  //! Sets fill transparency.
+  //! @param theValue [in] the transparency value. 1.0 is for transparent background
+  Standard_EXPORT void SetFillTransparency (const Standard_Real theValue) const;
+
+  //! @return fill transparency.
+  Standard_EXPORT Standard_Real FillTransparency() const;
+
+  //! Enable or disable filling of rubber band.
+  Standard_EXPORT void SetFilling (const Standard_Boolean theIsFilling);
+
+  //! Enable filling of rubber band with defined parameters.
+  //! @param theColor [in] color of filling
+  //! @param theTransparency [in] transparency of the filling. 0 is for opaque filling.
+  Standard_EXPORT void SetFilling (const Quantity_Color theColor, const Standard_Real theTransparency);
+
+  //! @return true if filling of rubber band is enabled.
+  Standard_EXPORT Standard_Boolean IsFilling() const;
+
+protected:
+
+  //! Computes presentation of rubber band.
+  Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
+                                        const Handle(Prs3d_Presentation)& thePresentation,
+                                        const Standard_Integer theMode) Standard_OVERRIDE;
+
+  //! Does not fill selection primitives for rubber band.
+  void virtual ComputeSelection (const Handle(SelectMgr_Selection)& /*aSelection*/,
+                                         const Standard_Integer /*aMode*/) Standard_OVERRIDE { };
+
+  //! Fills triangles primitive array for rubber band filling.
+  //! It uses Delaunay triangulation.
+  //! @return true if array of triangles is successfully filled.
+  Standard_EXPORT Standard_Boolean fillTriangles();
+
+protected:
+
+  NCollection_Sequence<Graphic3d_Vec2i> myPoints; //!< Array of screen points
+
+  Handle(Graphic3d_ArrayOfTriangles) myTriangles; //!< Triangles for rubber band filling
+  Handle(Graphic3d_ArrayOfPolylines) myBorders; //!< Polylines for rubber band borders
+};
+#endif
index ed1d9a5..2882a7c 100644 (file)
@@ -139,6 +139,8 @@ AIS_RadiusDimension.hxx
 AIS_Relation.cxx
 AIS_Relation.hxx
 AIS_Relation.lxx
+AIS_RubberBand.hxx
+AIS_RubberBand.cxx
 AIS_Selection.cxx
 AIS_Selection.hxx
 AIS_Selection.lxx
index 1c9b751..acc7fa6 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <OpenGl_GlCore20.hxx>
 #include <AIS_ColorScale.hxx>
+#include <AIS_RubberBand.hxx>
 #include <AIS_Shape.hxx>
 #include <AIS_InteractiveObject.hxx>
 #include <AIS_ListOfInteractive.hxx>
@@ -194,6 +195,17 @@ int Y_ButtonPress = 0;
 Standard_Boolean IsDragged = Standard_False;
 Standard_Boolean DragFirst = Standard_False;
 
+
+Standard_EXPORT const Handle(AIS_RubberBand)& GetRubberBand()
+{
+  static Handle(AIS_RubberBand) aBand;
+  if (aBand.IsNull())
+  {
+    aBand = new AIS_RubberBand();
+  }
+  return aBand;
+}
+
 //==============================================================================
 
 #ifdef _WIN32
@@ -1902,11 +1914,12 @@ static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
     case WM_LBUTTONUP:
       if (!DragFirst)
       {
-        HDC hdc = GetDC( hwnd );
-        SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
-        SetROP2( hdc, R2_NOT );
-        Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
-        ReleaseDC( hwnd, hdc );
+        if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
+        {
+          ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
+          ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
+        }
+
         VT_ProcessButton1Release (fwKeys & MK_SHIFT);
       }
       IsDragged = Standard_False;
@@ -1925,26 +1938,26 @@ static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
       break;
 
     case WM_MOUSEMOVE:
-      if( IsDragged )
+      if (IsDragged)
       {
-        HDC hdc = GetDC( hwnd );
-
-        HGDIOBJ anObj = SelectObject( hdc, GetStockObject( WHITE_PEN ) );
-        SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
-        SetROP2( hdc, R2_NOT );
-
-        if( !DragFirst )
-          Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
+        if (!DragFirst && ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
+        {
+          ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
+          ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
+        }
 
         DragFirst = Standard_False;
-        X_Motion = LOWORD(lParam);
-        Y_Motion = HIWORD(lParam);
-
-        Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
-
-        SelectObject( hdc, anObj );
+        X_Motion = LOWORD (lParam);
+        Y_Motion = HIWORD (lParam);
 
-        ReleaseDC( hwnd, hdc );
+        RECT aRect;
+        if (GetClientRect (hwnd, &aRect))
+        {
+          int aHeight = aRect.bottom - aRect.top;
+          GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
+          ViewerTest::GetAISContext()->Display (GetRubberBand(), Standard_False);
+          ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
+        }
       }
       else
         return ViewerWindowProc( hwnd, Msg, wParam, lParam );
@@ -2297,9 +2310,11 @@ int ViewerMainLoop(Standard_Integer argc, const char** argv)
           {
             if( !DragFirst )
             {
-              Aspect_Handle aWindow = VT_GetWindow()->XWindow();
-              GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
-              XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
+              if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
+              {
+                ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
+                ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
+              }
             }
 
             Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
@@ -2350,18 +2365,27 @@ int ViewerMainLoop(Standard_Integer argc, const char** argv)
           }
           if( IsDragged )
           {
-            Aspect_Handle aWindow = VT_GetWindow()->XWindow();
-            GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
-            XSetFunction( aDisplay, gc, GXinvert );
-
             if( !DragFirst )
-              XDrawRectangle(aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
+            {
+              if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
+              {
+                ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
+                ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
+              }
+            }
 
             X_Motion = aReport.xmotion.x;
             Y_Motion = aReport.xmotion.y;
             DragFirst = Standard_False;
 
-            XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
+            Window aWindow = GetWindowHandle(VT_GetWindow());
+            Window aRoot;
+            int anX, anY;
+            unsigned int aWidth, aHeight, aBorderWidth, aDepth;
+            XGetGeometry (aDisplay, aWindow, &aRoot, &anX, &anY, &aWidth, &aHeight, &aBorderWidth, &aDepth);
+            GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
+            ViewerTest::GetAISContext()->Display (GetRubberBand(), Standard_False);
+            ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
           }
           else
           {