From b12e1c7ba215567716c6b85e78eeb73150fe6718 Mon Sep 17 00:00:00 2001 From: aba Date: Fri, 18 Dec 2015 10:17:18 +0300 Subject: [PATCH] 0025338: MFC standard samples: 3D selection rectangle blinking - 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 --- .../01_Geometry/src/GeometryView2D.cpp | 14 +- samples/mfc/standard/Common/OCC_2dView.cpp | 78 +--- samples/mfc/standard/Common/OCC_2dView.h | 21 +- samples/mfc/standard/Common/OCC_3dView.cpp | 94 +--- samples/mfc/standard/Common/OCC_3dView.h | 17 +- samples/mfc/standard/Common/OCC_BaseDoc.h | 2 - samples/mfc/standard/Common/OCC_BaseView.cpp | 69 ++- samples/mfc/standard/Common/OCC_BaseView.h | 26 ++ src/AIS/AIS_RubberBand.cxx | 417 ++++++++++++++++++ src/AIS/AIS_RubberBand.hxx | 148 +++++++ src/AIS/FILES | 2 + src/ViewerTest/ViewerTest_ViewerCommands.cxx | 84 ++-- 12 files changed, 751 insertions(+), 221 deletions(-) create mode 100644 src/AIS/AIS_RubberBand.cxx create mode 100644 src/AIS/AIS_RubberBand.hxx diff --git a/samples/mfc/standard/01_Geometry/src/GeometryView2D.cpp b/samples/mfc/standard/01_Geometry/src/GeometryView2D.cpp index a717f34196..feaa1e488e 100755 --- a/samples/mfc/standard/01_Geometry/src/GeometryView2D.cpp +++ b/samples/mfc/standard/01_Geometry/src/GeometryView2D.cpp @@ -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 +} diff --git a/samples/mfc/standard/Common/OCC_2dView.cpp b/samples/mfc/standard/Common/OCC_2dView.cpp index 8209ab828d..c8bf3516ab 100755 --- a/samples/mfc/standard/Common/OCC_2dView.cpp +++ b/samples/mfc/standard/Common/OCC_2dView.cpp @@ -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); -} - - - // ===================================================================== //----------------------------------------------------------------------------------------- diff --git a/samples/mfc/standard/Common/OCC_2dView.h b/samples/mfc/standard/Common/OCC_2dView.h index eaa03d6c94..5fe262073f 100755 --- a/samples/mfc/standard/Common/OCC_2dView.h +++ b/samples/mfc/standard/Common/OCC_2dView.h @@ -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 diff --git a/samples/mfc/standard/Common/OCC_3dView.cpp b/samples/mfc/standard/Common/OCC_3dView.cpp index 8c5c577e91..324919eb22 100755 --- a/samples/mfc/standard/Common/OCC_3dView.cpp +++ b/samples/mfc/standard/Common/OCC_3dView.cpp @@ -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); diff --git a/samples/mfc/standard/Common/OCC_3dView.h b/samples/mfc/standard/Common/OCC_3dView.h index dfe79291de..69a73f4c7c 100755 --- a/samples/mfc/standard/Common/OCC_3dView.h +++ b/samples/mfc/standard/Common/OCC_3dView.h @@ -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 diff --git a/samples/mfc/standard/Common/OCC_BaseDoc.h b/samples/mfc/standard/Common/OCC_BaseDoc.h index 0c8ad8ce67..e4897a471f 100755 --- a/samples/mfc/standard/Common/OCC_BaseDoc.h +++ b/samples/mfc/standard/Common/OCC_BaseDoc.h @@ -69,8 +69,6 @@ public: const Standard_Integer /*theMouseY*/, const Handle(V3d_View)& /*theView*/) {} -public: - void ResetDocumentViews (CDocTemplate* theTemplate); protected: diff --git a/samples/mfc/standard/Common/OCC_BaseView.cpp b/samples/mfc/standard/Common/OCC_BaseView.cpp index 2b0eb1cf5f..b03d65116c 100755 --- a/samples/mfc/standard/Common/OCC_BaseView.cpp +++ b/samples/mfc/standard/Common/OCC_BaseView.cpp @@ -5,16 +5,75 @@ #include #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(); +} + diff --git a/samples/mfc/standard/Common/OCC_BaseView.h b/samples/mfc/standard/Common/OCC_BaseView.h index 5351024dc1..c3bf793cbd 100755 --- a/samples/mfc/standard/Common/OCC_BaseView.h +++ b/samples/mfc/standard/Common/OCC_BaseView.h @@ -11,12 +11,38 @@ #include +#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 index 0000000000..2169e8d5fa --- /dev/null +++ b/src/AIS/AIS_RubberBand.cxx @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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& 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 index 0000000000..6cfd011c7f --- /dev/null +++ b/src/AIS/AIS_RubberBand.hxx @@ -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 +#include +#include +#include +#include + +//! 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& 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 myPoints; //!< Array of screen points + + Handle(Graphic3d_ArrayOfTriangles) myTriangles; //!< Triangles for rubber band filling + Handle(Graphic3d_ArrayOfPolylines) myBorders; //!< Polylines for rubber band borders +}; +#endif diff --git a/src/AIS/FILES b/src/AIS/FILES index ed1d9a5ef4..2882a7c425 100644 --- a/src/AIS/FILES +++ b/src/AIS/FILES @@ -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 diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 1c9b751c90..acc7fa6475 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -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); + X_Motion = LOWORD (lParam); + Y_Motion = HIWORD (lParam); - Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion ); - - SelectObject( hdc, anObj ); - - 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 {