-// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015 EDF-R&D
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
//
#include <HYDROGUI_ShapeBathymetry.h>
+#include <HYDROGUI_OCCDisplayer.h>
+#include <HYDROGUI_BathymetryPrs.h>
#include <HYDROData_Bathymetry.h>
+#include <HYDROGUI_Tool.h>
#include <AIS_InteractiveContext.hxx>
-#include <AIS_PointCloud.hxx>
-#include <AIS_Drawer.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( const Handle(AIS_InteractiveContext)& theContext,
- const Handle_HYDROData_Bathymetry& theBathymetry,
+HYDROGUI_ShapeBathymetry::HYDROGUI_ShapeBathymetry( HYDROGUI_OCCDisplayer* theDisplayer,
+ const Handle(AIS_InteractiveContext)& theContext,
+ const Handle(HYDROData_Bathymetry)& theBathymetry,
const int theZLayer )
-: HYDROGUI_Shape( theContext, theBathymetry, theZLayer )
+: HYDROGUI_Shape( theContext, theBathymetry, theZLayer ),
+ myDisplayer( theDisplayer ),
+ myMin( 0 ),
+ myMax( 0 ),
+ myRangeInitialized( false )
{
+ setDisplayMode( AIS_PointCloud::DM_Points );
}
HYDROGUI_ShapeBathymetry::~HYDROGUI_ShapeBathymetry()
{
+ setToUpdateColorScale( true );
}
void HYDROGUI_ShapeBathymetry::update( bool theIsUpdateViewer, bool isDeactivateSelection )
Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( getObject() );
- if ( !aBath.IsNull() )
+ if ( !aBath.IsNull() && !aBath->GetAltitudePoints().empty())
{
buildShape();
updateShape( false, false );
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 AIS_PointCloud();
- aPntCloud->Attributes()->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_WHITE, 1.0));
+ 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 )
+{
+ if( getAISObjects().isEmpty() )
+ return;
+
+ bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
+ bool isChanged = ( isShown != theState );
+ HYDROGUI_Shape::setVisible( theState, theIsUpdateViewer );
+ setToUpdateColorScale( isChanged );
+}
+
+void HYDROGUI_ShapeBathymetry::displayShape( const bool theIsUpdateViewer )
+{
+ if( getAISObjects().isEmpty() )
+ return;
+
+ bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
+ bool isChanged = ( !isShown );
+ HYDROGUI_Shape::displayShape( theIsUpdateViewer );
+ setToUpdateColorScale( isChanged );
+}
+
+void HYDROGUI_ShapeBathymetry::display( const bool theIsUpdateViewer )
+{
+ if( getAISObjects().isEmpty() )
+ return;
+
+ bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
+ bool isChanged = ( !isShown );
+ HYDROGUI_Shape::display( theIsUpdateViewer );
+ setToUpdateColorScale( isChanged );
+}
+
+void HYDROGUI_ShapeBathymetry::erase( const bool theIsUpdateViewer )
+{
+ if( getAISObjects().isEmpty() )
+ return;
+
+ bool isShown = getContext()->IsDisplayed( getAISObjects()[0] );
+ bool isChanged = ( isShown );
+ HYDROGUI_Shape::erase( theIsUpdateViewer );
+ 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();
+}