Salome HOME
cleaning some comments
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ShapeBathymetry.cxx
index fd8158e539b1f4d8bc143b1ce0b7000bb0b1dda1..a6de2d915509941d23825af2618fac74c0cf06e5 100644 (file)
 #include <HYDROGUI_OCCDisplayer.h>
 #include <HYDROGUI_BathymetryPrs.h>
 #include <HYDROData_Bathymetry.h>
+#include <HYDROGUI_Tool.h>
 
 #include <AIS_InteractiveContext.hxx>
-#include <Aspect_ColorScale.hxx>
+#include <AIS_ColorScale.hxx>
 #include <Prs3d_PointAspect.hxx>
+#include <OCCViewer_ViewWindow.h>
+#include <OCCViewer_ViewPort3d.h>
+#include <V3d_View.hxx>
+#include <QTime>
+#include <utilities.h>
+
+//#define _DEVDEBUG_
+#include "HYDRO_trace.hxx"
 
 HYDROGUI_ShapeBathymetry::HYDROGUI_ShapeBathymetry( HYDROGUI_OCCDisplayer*                theDisplayer,
                                                     const Handle(AIS_InteractiveContext)& theContext,
-                                                    const Handle_HYDROData_Bathymetry&    theBathymetry,
+                                                    const Handle(HYDROData_Bathymetry)&   theBathymetry,
                                                     const int                             theZLayer )
 : HYDROGUI_Shape( theContext, theBathymetry, theZLayer ),
-  myDisplayer( theDisplayer )
+  myDisplayer( theDisplayer ),
+  myMin( 0 ),
+  myMax( 0 ),
+  myRangeInitialized( false )
 {
   setDisplayMode( AIS_PointCloud::DM_Points );
 }
 
 HYDROGUI_ShapeBathymetry::~HYDROGUI_ShapeBathymetry()
 {
-  myDisplayer->SetToUpdateColorScale();
+  setToUpdateColorScale( true );
 }
 
 void HYDROGUI_ShapeBathymetry::update( bool theIsUpdateViewer, bool isDeactivateSelection )
@@ -48,7 +60,7 @@ void HYDROGUI_ShapeBathymetry::update( bool theIsUpdateViewer, bool isDeactivate
 
   Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( getObject() );
 
-  if ( !aBath.IsNull() )
+  if ( !aBath.IsNull() && !aBath->GetAltitudePoints().empty())
   {
     buildShape();
     updateShape( false, false );
@@ -57,98 +69,253 @@ void HYDROGUI_ShapeBathymetry::update( bool theIsUpdateViewer, bool isDeactivate
   HYDROGUI_Shape::update( theIsUpdateViewer, isDeactivateSelection );
 }
 
-
-Handle_AIS_InteractiveObject HYDROGUI_ShapeBathymetry::createShape() const
+QList<Handle(AIS_InteractiveObject)> HYDROGUI_ShapeBathymetry::createShape() const
 {
-  Handle_HYDROData_Bathymetry aBath = Handle_HYDROData_Bathymetry::DownCast( getObject() );
+  DEBTRACE("createShape");
+  QList<Handle(AIS_InteractiveObject)> shapes;
+
+  Handle(AIS_InteractiveObject) aPntCloud;
+
+  Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( getObject() );
   if( !aBath.IsNull() )
   {
-    Handle_AIS_PointCloud aPntCloud = new HYDROGUI_BathymetryPrs();
-    aPntCloud->SetHilightMode( AIS_PointCloud::DM_BndBox );
+    aPntCloud = new HYDROGUI_BathymetryPrs( this );
+    //aPntCloud->SetHilightMode( AIS_PointCloud::DM_BndBox );
     aPntCloud->Attributes()->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_WHITE, 2.0));
 
     const HYDROData_Bathymetry::AltitudePoints& aBathPoints = aBath->GetAltitudePoints();
-    int aLower = aBathPoints.Lower();
-    int anUpper = aBathPoints.Upper();
+    int aLower = 0;
+    int anUpper = (int)aBathPoints.size()-1;
 
     HYDROGUI_ShapeBathymetry* aThat = const_cast<HYDROGUI_ShapeBathymetry*>( this );
     aThat->myCoords = new TColgp_HArray1OfPnt( aLower, anUpper );
     aThat->myColors = new Quantity_HArray1OfColor( aLower, anUpper );
     for( int i=aLower; i<=anUpper; i++ )
-      aThat->myCoords->SetValue( i, aBathPoints.Value( i ) );
+      aThat->myCoords->SetValue( i, gp_Pnt( aBathPoints[i].X, aBathPoints[i].Y, aBathPoints[i].Z ) );
 
-    return aPntCloud;
+    shapes.append( aPntCloud );
   }
-  else
-    return Handle_AIS_InteractiveObject();
+
+  return shapes;
 }
 
-void HYDROGUI_ShapeBathymetry::GetRange( double& theMin, double& theMax ) const
+void HYDROGUI_ShapeBathymetry::UpdateWithColorScale( const Handle(AIS_ColorScale)& theColorScale )
 {
-  theMin = 0;
-  theMax = 0;
-  if( myCoords.IsNull() )
+  DEBTRACE("UpdateWithColorScale");
+  if (!myCoords || getAISObjects().isEmpty())
     return;
 
-  bool isFirst = true;
-  for( int i=myCoords->Lower(), n=myCoords->Upper(); i<=n; i++ )
-  {
-    double aValue = myCoords->Value( i ).Z();
-    if( isFirst || aValue < theMin )
-      theMin = aValue;
-    if( isFirst || aValue > theMax )
-      theMax = aValue;
-    isFirst = false;
-  }
-}
-
-void HYDROGUI_ShapeBathymetry::UpdateWithColorScale( const Handle(Aspect_ColorScale)& theColorScale )
-{
   for( int i=myCoords->Lower(), n=myCoords->Upper(); i<=n; i++ )
   {
     double z = myCoords->Value( i ).Z();
+    if( z<myMin )
+      z = myMin;
+    if( z>myMax )
+      z = myMax;
     Quantity_Color aColor;
     theColorScale->FindColor( z, aColor );
     myColors->SetValue( i, aColor );
   }
-  Handle_AIS_PointCloud aPntCloud = Handle_AIS_PointCloud::DownCast( getAISObject() );
+  Handle(HYDROGUI_BathymetryPrs) aPntCloud = Handle(HYDROGUI_BathymetryPrs)::DownCast( getAISObjects()[0] );
   aPntCloud->SetPoints( myCoords, myColors );
-  getContext()->Redisplay( aPntCloud, Standard_False );
+  getContext()->RecomputePrsOnly( aPntCloud, Standard_True );
+  getContext()->RecomputeSelectionOnly( aPntCloud );
 }
 
 void HYDROGUI_ShapeBathymetry::setVisible( const bool theState,
                                            const bool theIsUpdateViewer )
 {
-  bool isShown = getContext()->IsDisplayed( getAISObject() );
+  if( getAISObjects().isEmpty() )
+    return;
+
+  bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
   bool isChanged = ( isShown != theState );
   HYDROGUI_Shape::setVisible( theState, theIsUpdateViewer );
-  if( isChanged )
-    myDisplayer->SetToUpdateColorScale();
+  setToUpdateColorScale( isChanged );
 }
 
 void HYDROGUI_ShapeBathymetry::displayShape( const bool theIsUpdateViewer )
 {
-  bool isShown = getContext()->IsDisplayed( getAISObject() );
+  if( getAISObjects().isEmpty() )
+    return;
+
+  bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
   bool isChanged = ( !isShown  );
   HYDROGUI_Shape::displayShape( theIsUpdateViewer );
-  if( isChanged )
-    myDisplayer->SetToUpdateColorScale();
+  setToUpdateColorScale( isChanged );
 }
 
 void HYDROGUI_ShapeBathymetry::display( const bool theIsUpdateViewer )
 {
-  bool isShown = getContext()->IsDisplayed( getAISObject() );
+  if( getAISObjects().isEmpty() )
+    return;
+
+  bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
   bool isChanged = ( !isShown  );
   HYDROGUI_Shape::display( theIsUpdateViewer );
-  if( isChanged )
-    myDisplayer->SetToUpdateColorScale();
+  setToUpdateColorScale( isChanged );
 }
 
 void HYDROGUI_ShapeBathymetry::erase( const bool theIsUpdateViewer )
 {
-  bool isShown = getContext()->IsDisplayed( getAISObject() );
+  if( getAISObjects().isEmpty() )
+    return;
+
+  bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
   bool isChanged = ( isShown  );
   HYDROGUI_Shape::erase( theIsUpdateViewer );
-  if( isChanged )
+  setToUpdateColorScale( isChanged );
+}
+
+void HYDROGUI_ShapeBathymetry::setToUpdateColorScale( bool isChanged )
+{
+#ifndef LIGHT_MODE
+  if( isChanged && myDisplayer )
     myDisplayer->SetToUpdateColorScale();
+#endif
+}
+
+void HYDROGUI_ShapeBathymetry::GetRange( double& theMin, double& theMax ) const
+{
+  if( !myRangeInitialized )
+  {
+    HYDROGUI_ShapeBathymetry* that =
+      const_cast<HYDROGUI_ShapeBathymetry*>( this );
+    that->RescaleDefault();
+    that->myRangeInitialized = true;
+  }
+
+  theMin = myMin;
+  theMax = myMax;
+}
+
+void HYDROGUI_ShapeBathymetry::RescaleByVisible( OCCViewer_ViewWindow* theWindow )
+{
+  QVector<int> visible;
+  visible.reserve( myCoords->Size() );
+
+  OCCViewer_ViewPort3d* vp = theWindow->getViewPort();
+  Handle(V3d_View) v = vp->getView();
+
+  int xp, yp;
+  int w = vp->width();
+  int h = vp->height();
+  int n = myCoords->Upper();
+  bool isVisible;
+
+#ifdef _DEBUG
+  MESSAGE("RescaleByVisible: " << n);
+  QTime t1;
+  t1.start();
+#endif
+
+  for( int i=myCoords->Lower(); i<=n; i++ )
+  {
+    gp_Pnt p = myCoords->Value( i );
+    v->Convert( p.X(), p.Y(), p.Z(), xp, yp );
+    isVisible = ( xp>=0 && yp>=0 && xp<w && yp<h );
+    if( isVisible )
+      visible.append( i );
+  }
+
+#ifdef _DEBUG
+  MESSAGE("Time after visibles search:" << t1.elapsed());
+#endif
+
+  //TODO: question: empty visible part produce empty bathymetry or complete bathymetry?
+  // For now "complete" is implemented
+  Rescale( visible, visible.isEmpty() );
+
+#ifdef _DEBUG
+  MESSAGE("Time after rescale:" << t1.elapsed());
+#endif
+}
+
+QVector<int> HYDROGUI_ShapeBathymetry::selected() const
+{
+  DEBTRACE("selected");
+  QVector<int> selected;
+
+  // HYDROGUI_BathymetryPrs::ClearSelected() called before: Nothing left...
+
+  Handle(HYDROGUI_BathymetryPrs) aPntCloud = Handle(HYDROGUI_BathymetryPrs)::DownCast( getAISObjects()[0] );
+  if (!aPntCloud.IsNull())
+    selected = aPntCloud->getSelectedPoints();
+  DEBTRACE("selected " << selected.size());
+  return selected;
+}
+
+void HYDROGUI_ShapeBathymetry::RescaleBySelection()
+{
+  QVector<int> selection = selected();
+
+  //TODO: question: empty selection produce empty bathymetry or complete bathymetry?
+  // For now "complete" is implemented
+  Rescale( selection, selection.isEmpty() );
+}
+
+void HYDROGUI_ShapeBathymetry::Rescale( double theMin, double theMax )
+{
+  getContext()->ClearSelected(true);
+  myMin = qMin( theMin, theMax );
+  myMax = qMax( theMin, theMax );
+  setToUpdateColorScale( true );
+
+  if( !getAISObjects().isEmpty() )
+  {
+    getContext()->RecomputePrsOnly( getAISObjects()[0], true );
+  }
+}
+
+void HYDROGUI_ShapeBathymetry::RescaleDefault()
+{
+  Rescale( QVector<int>(), true );
+}
+
+void HYDROGUI_ShapeBathymetry::Rescale( const QVector<int>& theIndices, bool isForcedAll )
+{
+  double aMin = 0, aMax = 0;
+  if( !myCoords.IsNull() )
+  {
+    bool isFirst = true;
+    int n = isForcedAll ? myCoords->Size() : theIndices.size();
+    for( int i=0; i<n; i++ )
+    {
+      int index = isForcedAll ? myCoords->Lower() + i : theIndices[i];
+
+      double aValue = myCoords->Value( index ).Z();
+      if( isFirst || aValue < aMin )
+        aMin = aValue;
+      if( isFirst || aValue > aMax )
+        aMax = aValue;
+      isFirst = false;
+    }
+  }
+  Rescale( aMin, aMax );
+}
+
+void HYDROGUI_ShapeBathymetry::Build()
+{
+  buildShape();
+}
+
+void HYDROGUI_ShapeBathymetry::TextLabels( bool isOn, bool isUpdateCurrentViewer )
+{
+  DEBTRACE("TextLabels " << isOn << " " << isUpdateCurrentViewer);
+  if( getAISObjects().isEmpty() )
+    return;
+
+  Handle(HYDROGUI_BathymetryPrs) prs = Handle(HYDROGUI_BathymetryPrs)::DownCast( getAISObjects()[0] );
+  if( prs.IsNull() )
+    return;
+
+  QVector<int> selection;
+  if( isOn )
+    selection = selected();
+
+
+  prs->SetTextLabels( selection );
+  getContext()->RecomputePrsOnly( prs, Standard_False, Standard_False );
+  if( isUpdateCurrentViewer )
+  getContext()->UpdateCurrentViewer();
 }