Salome HOME
Bug on dragging rectangle in overview: Fatal error "ZFar should be greater than ZNear...
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Overview.cxx
index 7a6c18976b5204579269d04823784ddec152f60c..f1075782abd5986c35147eeedfb1bf45a6c55bf3 100644 (file)
 #include <HYDROGUI_Overview.h>
 #include <OCCViewer_ViewPort3d.h>
 #include <OCCViewer_ViewFrame.h>
+#include <OCCViewer_ViewModel.h>
+#include <OCCViewer_ViewManager.h>
 #include <QtxRubberBand.h>
 #include <QApplication>
 #include <QPainter>
 #include <QMouseEvent>
 #include <QLayout>
 
+//#define _DEVDEBUG_
+#include "HYDRO_trace.hxx"
+
 class HYDROGUI_OverviewBand : public QtxPolyRubberBand
 {
 public:
@@ -119,6 +124,7 @@ QPoint HYDROGUI_OverviewBand::center() const
 
 void HYDROGUI_OverviewBand::drag( const QPoint& thePoint, bool isStart )
 {
+  DEBTRACE("drag");
   if( myIsDrag==isStart )
     return;
 
@@ -146,6 +152,7 @@ bool HYDROGUI_OverviewBand::isDrag() const
 
 void HYDROGUI_OverviewBand::dragging( const QPoint& thePoint )
 {
+  DEBTRACE("dragging");
   int n = myPoints.size();
   QPoint delta = thePoint - myStartPnt;
   for( int i=0; i<n; i++ )
@@ -190,13 +197,14 @@ void HYDROGUI_OverviewBand::update( bool isFromMain )
     QPoint c = center();
     double x1, y1, z1, x2, y2, z2;
     main->getView()->Convert( main->width()/2, main->height()/2, x1, y1, z1 );
-
+    DEBTRACE("x1, y1, z1 " << x1 << " " << y1 << " " << z1);
     // Patch for OCCT 6.9.1, on 7.0.0 the moving of point to plane XY is not necessary
-    gp_Dir dm = main->getView()->Camera()->Direction();
-    double t1 = -z1/dm.Z();
-    x1 += dm.X()*t1;
-    y1 += dm.Y()*t1;
-    z1 += dm.Z()*t1;
+//    gp_Dir dm = main->getView()->Camera()->Direction();
+//    double t1 = -z1/dm.Z();
+//    x1 += dm.X()*t1;
+//    y1 += dm.Y()*t1;
+//    z1 += dm.Z()*t1;
+//    DEBTRACE("x1, y1, z1 " << x1 << " " << y1 << " " << z1);
 
     overview->getView()->Convert( c.x(), c.y(), x2, y2, z2 );
     gp_Dir dov = overview->getView()->Camera()->Direction();
@@ -204,27 +212,37 @@ void HYDROGUI_OverviewBand::update( bool isFromMain )
     x2 += dov.X()*t2;
     y2 += dov.Y()*t2;
     z2 += dov.Z()*t2;
+    DEBTRACE("x2, y2, z2 " << x2 << " " << y2 << " " << z2);
 
     gp_Trsf aTrsf;
     aTrsf.SetTranslation( gp_Pnt( x1, y1, z1 ), gp_Pnt( x2, y2, z2 ) );
 
     // Temporary patch for bug in OCCT 6.9.1
-    Handle(Graphic3d_Camera) cam = main->getView()->Camera();
-    gp_Dir u = cam->Up(), nu = u.Transformed (aTrsf);
-    gp_Pnt e = cam->Eye(), ne = e.Transformed (aTrsf);
-    gp_Pnt cen = cam->Center(), ncen = cen.Transformed (aTrsf);
-
-    if (!nu.IsEqual (u, 0.0))
-      cam->SetUp(nu);
-
-    if (!ne.IsEqual (e, 0.0))
-      cam->SetEye(ne);
-
-    if (!ncen.IsEqual(cen, 0.0))
-      cam->SetCenter (ncen);
+//    Handle(Graphic3d_Camera) cam = main->getView()->Camera();
+//    gp_Dir u = cam->Up(), nu = u.Transformed (aTrsf);
+//    gp_Pnt e = cam->Eye(), ne = e.Transformed (aTrsf);
+//    gp_Pnt cen = cam->Center(), ncen = cen.Transformed (aTrsf);
+//
+//    if (!nu.IsEqual (u, 0.0))
+//    {
+//      cam->SetUp(nu);
+//      DEBTRACE("nu " << nu.X() << " "  << nu.Y() << " "  << nu.Z());
+//    }
+//
+//    if (!ne.IsEqual (e, 0.0))
+//    {
+//      cam->SetEye(ne);
+//      DEBTRACE("ne " << ne.X() << " "  << ne.Y() << " "  << ne.Z())
+//    }
+//
+//    if (!ncen.IsEqual(cen, 0.0))
+//    {
+//      cam->SetCenter (ncen);
+//      DEBTRACE("ncen " << ncen.X() << " "  << ncen.Y() << " "  << ncen.Z())
+//    }
 
     //version for new OCCT:
-    //main->getView()->Camera()->Transform( aTrsf );
+    main->getView()->Camera()->Transform( aTrsf );
     main->repaint();
   }
 }
@@ -242,10 +260,7 @@ void HYDROGUI_OverviewBand::paintEvent( QPaintEvent* thePaintEvent )
   painter.drawPolygon( myPoints );
 }
 
-
-
-
-
+//////////////
 
 HYDROGUI_Overview::HYDROGUI_Overview( const QString& theTitle, int theMargin, QWidget* theParent )
   : QFrame( theParent ), myMargin( theMargin ),
@@ -261,6 +276,7 @@ HYDROGUI_Overview::HYDROGUI_Overview( const QString& theTitle, int theMargin, QW
 
 HYDROGUI_Overview::~HYDROGUI_Overview()
 {
+  //delete myViewPort;
 }
 
 QImage HYDROGUI_Overview::dump() const
@@ -276,12 +292,25 @@ QImage HYDROGUI_Overview::dump() const
   int aHeight = myViewPort->height();
 
   Image_PixMap aPix;
-  view->ToPixMap( aPix,aWidth, aHeight,Graphic3d_BT_RGBA );
 
+#if OCC_VERSION_LARGE >= 0x07020000
+  view->ToPixMap( aPix,aWidth, aHeight,Graphic3d_BT_RGBA );
   QImage anImage( aPix.Data(), aWidth, aHeight, QImage::Format_ARGB32 );
   anImage = anImage.mirrored();
   anImage = anImage.rgbSwapped();
-
+#else
+  view->ToPixMap(aPix, aWidth, aHeight, Graphic3d_BT_RGB);
+  QImage anImage( aWidth, aHeight, QImage::Format_ARGB32 );
+  for ( int i = 0; i < aWidth; i++ ) {
+    for ( int j = 0; j < aHeight; j++ ) {
+      Quantity_Color pixel = aPix.PixelColor( i, j ).GetRGB();
+      QColor color = QColor::fromRgbF( pixel.Red(), pixel.Green(), pixel.Blue() );
+      anImage.setPixelColor( i, j, color );
+    }
+  }
+  if ( aPix.IsTopDown() )
+    anImage = anImage.mirrored();
+#endif
   if( myBand && myBand->isVisible() )
   {
     QPixmap aPixmap = QPixmap::fromImage( anImage );
@@ -289,13 +318,20 @@ QImage HYDROGUI_Overview::dump() const
     myBand->render( &aPixmap, p );
     anImage = aPixmap.toImage();
   }
-
   return anImage;
 }
 
 OCCViewer_ViewPort3d* HYDROGUI_Overview::getViewPort( bool isMain ) const
 {
-  return isMain ? myMainView->getViewPort() : myViewPort;
+  if ( isMain) 
+  {
+    if (myMainView!=NULL)
+      return myMainView->getViewPort();
+    else
+      return NULL;
+  }
+  else
+    return myViewPort;
 }
 
 void HYDROGUI_Overview::setMainView( OCCViewer_ViewFrame* theMainView )
@@ -310,7 +346,9 @@ void HYDROGUI_Overview::setMainView( OCCViewer_ViewFrame* theMainView )
   connect( aMainView->getViewPort(), SIGNAL( vpResizeEvent( QResizeEvent* ) ),
            this,       SLOT( OnResizeEvent( QResizeEvent* ) ) );
   connect( aMainView->getViewPort(), SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ),
-           this,       SLOT( OnTransformation() ) );
+           this,       SLOT( OnTransformation() ) ); 
+
+  connect( myMainView, SIGNAL(destroyed()),  this,  SLOT( onMainViewDestr() ) );
 
   if( !myViewPort )
   {
@@ -320,6 +358,7 @@ void HYDROGUI_Overview::setMainView( OCCViewer_ViewFrame* theMainView )
     {
       myViewPort->setBackgroundColor( myMainView->getViewPort()->backgroundColor() );
 
+      connect( myViewPort, SIGNAL(destroyed()),  this,  SLOT( onViewPortDestr() ) );
       connect( myViewPort, SIGNAL( vpMouseEvent( QMouseEvent* ) ), 
               this,       SLOT( OnMouseEvent( QMouseEvent* ) ) );
       connect( myViewPort, SIGNAL( vpResizeEvent( QResizeEvent* ) ),
@@ -372,6 +411,10 @@ void HYDROGUI_Overview::OnTransformationAfterOp( OCCViewer_ViewWindow::Operation
   {
     myViewPort->fitAll();
   }
+  if( theOp==OCCViewer_ViewWindow::FITSELECTION )
+  {
+    CustomFitSelection();
+  }
   OnTransformation();
 }
 
@@ -383,7 +426,7 @@ void HYDROGUI_Overview::OnTransformation()
 
 QPoint HYDROGUI_Overview::fromMain( int xp, int yp ) const
 {
-  if( !myMainView || !myViewPort )
+  if( !myMainView || !myViewPort || !myViewPort->isVisible() )
     return QPoint();
 
   const double EPS = 1E-2;
@@ -458,3 +501,134 @@ void HYDROGUI_Overview::OnResizeEvent( QResizeEvent* )
   if( myBand )
     myBand->update( true );
 }
+
+
+void HYDROGUI_Overview::onMainViewDestr()
+{
+  myMainView = NULL;
+  if (myViewPort == NULL)
+    return;
+  Handle(V3d_View) ov = myViewPort->getView();
+  ov->View()->Deactivate();
+  delete myViewPort; //this will delete myBand
+  myViewPort = NULL;
+  myBand = NULL;
+}
+
+void HYDROGUI_Overview::onViewPortDestr()
+{
+  myViewPort = NULL;
+}
+
+
+void HYDROGUI_Overview::CustomFitSelection() const
+{
+  DEBTRACE("CustomFitSelection");
+  OCCViewer_ViewPort3d* main = getViewPort( true );
+  if( !main )
+    return;
+
+  int w = main->width();
+  int h = main->height();
+
+  Bnd_Box bounding = BoundingForSelection();
+  if( bounding.IsVoid() )
+    return;
+
+  Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
+  bounding.Get( xmin, ymin, zmin, xmax, ymax, zmax );
+
+  QList<QPoint> points;
+  Standard_Integer xp, yp;
+  main->getView()->Convert( xmin, ymin, zmin, xp, yp ); points.append( QPoint( xp, yp ) );
+  main->getView()->Convert( xmax, ymin, zmin, xp, yp ); points.append( QPoint( xp, yp ) );
+  main->getView()->Convert( xmin, ymax, zmin, xp, yp ); points.append( QPoint( xp, yp ) );
+  main->getView()->Convert( xmax, ymax, zmin, xp, yp ); points.append( QPoint( xp, yp ) );
+  main->getView()->Convert( xmin, ymin, zmax, xp, yp ); points.append( QPoint( xp, yp ) );
+  main->getView()->Convert( xmax, ymin, zmax, xp, yp ); points.append( QPoint( xp, yp ) );
+  main->getView()->Convert( xmin, ymax, zmax, xp, yp ); points.append( QPoint( xp, yp ) );
+  main->getView()->Convert( xmax, ymax, zmax, xp, yp ); points.append( QPoint( xp, yp ) );
+
+  int xpmin, ypmin, xpmax, ypmax;
+  bool isFirst = true;
+  foreach( QPoint p, points )
+  {
+    int x = p.x(), y = p.y();
+    if( isFirst || x<xpmin )
+      xpmin = x;
+    if( isFirst || x>xpmax )
+      xpmax = x;
+    if( isFirst || y<ypmin )
+      ypmin = y;
+    if( isFirst || y>ypmax )
+      ypmax = y;
+
+    isFirst = false;
+  }
+
+  const int margin = 5;
+  QRect r( xpmin-margin, ypmin-margin, xpmax-xpmin+2*margin, ypmax-ypmin+2*margin );
+  main->fitRect( r );
+}
+
+Handle(AIS_InteractiveContext) HYDROGUI_Overview::context() const
+{
+  if( myMainView )
+  {
+    SUIT_ViewModel* vm = myMainView->getViewManager()->getViewModel();
+    OCCViewer_Viewer* viewer = dynamic_cast<OCCViewer_Viewer*>( vm );
+    if( viewer )
+      return viewer->getAISContext();
+  }
+  return Handle(AIS_InteractiveContext)();
+}
+
+typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_IndexedMapOfOwner)> AIS_MapOfObjectOwners1;
+  typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_IndexedMapOfOwner)>::Iterator AIS_MapIteratorOfMapOfObjectOwners1;
+Bnd_Box HYDROGUI_Overview::BoundingForSelection() const
+{
+  DEBTRACE("BoundingForSelection");
+  Handle(AIS_InteractiveContext) c = context();
+
+  Bnd_Box aBndSelected;
+
+  AIS_MapOfObjectOwners1 anObjectOwnerMap;
+  for (c->InitSelected(); c->MoreSelected(); c->NextSelected())
+  {
+    const Handle(SelectMgr_EntityOwner)& anOwner = c->SelectedOwner();
+    Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
+    if (anObj->IsInfinite())
+    {
+      continue;
+    }
+
+    if (anOwner == anObj->GlobalSelOwner())
+    {
+      Bnd_Box aTmpBnd;
+      anObj->BoundingBox (aTmpBnd);
+      aBndSelected.Add (aTmpBnd);
+    }
+    else
+    {
+      Handle(SelectMgr_IndexedMapOfOwner) anOwnerMap;
+      if (!anObjectOwnerMap.Find (anOwner->Selectable(), anOwnerMap))
+      {
+        anOwnerMap = new SelectMgr_IndexedMapOfOwner();
+        anObjectOwnerMap.Bind (anOwner->Selectable(), anOwnerMap);
+      }
+
+      anOwnerMap->Add (anOwner);
+    }
+  }
+
+  for (AIS_MapIteratorOfMapOfObjectOwners1 anIter (anObjectOwnerMap); anIter.More(); anIter.Next())
+  {
+    const Handle(SelectMgr_SelectableObject) anObject = anIter.Key();
+    Bnd_Box aTmpBox = anObject->BndBoxOfSelected (anIter.ChangeValue());
+    aBndSelected.Add (aTmpBox);
+  }
+
+  anObjectOwnerMap.Clear();
+
+  return aBndSelected;
+}