X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_Polyline3D.cxx;h=15959d971f698ca5499aa347c7d7f3dc604470af;hb=6bcda532ec67940d5c53e70df3b7912a09208c1c;hp=8bff09cb3301cb587b4de1b9c4e6dc684104e9d7;hpb=2d99821157e770385d7af917b2d22d6aa3cacb7e;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_Polyline3D.cxx b/src/HYDROData/HYDROData_Polyline3D.cxx index 8bff09cb..15959d97 100644 --- a/src/HYDROData/HYDROData_Polyline3D.cxx +++ b/src/HYDROData/HYDROData_Polyline3D.cxx @@ -1,28 +1,66 @@ +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "HYDROData_Polyline3D.h" +#include "HYDROData_IAltitudeObject.h" #include "HYDROData_Document.h" #include "HYDROData_PolylineXY.h" +#include "HYDROData_Profile.h" #include "HYDROData_ProfileUZ.h" +#include "HYDROData_ShapesTool.h" +#include "HYDROData_Tool.h" + +#include + +#include +#include +#include +#include #include #include #include +#include + #include +#include +#include #include +#include + +#include + +#include + +#define _DEVDEBUG_ +#include "HYDRO_trace.hxx" + #include #include -#define PYTHON_POLYLINE_ID "KIND_POLYLINE" - -IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline3D,HYDROData_Object) IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline3D,HYDROData_Object) HYDROData_Polyline3D::HYDROData_Polyline3D() -: HYDROData_Object() +: HYDROData_Object( Geom_3d ) { } @@ -30,23 +68,58 @@ HYDROData_Polyline3D::~HYDROData_Polyline3D() { } -QStringList HYDROData_Polyline3D::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const +QStringList HYDROData_Polyline3D::DumpToPython( const QString& thePyScriptPath, + MapOfTreatedObjects& theTreatedObjects ) const { - QStringList aResList; + QStringList aResList = dumpObjectCreation( theTreatedObjects ); + QString aPolylineName = GetObjPyName(); - Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab ); - if ( aDocument.IsNull() ) - return aResList; + Handle(HYDROData_PolylineXY) aRefPolyline = GetPolylineXY(); + setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefPolyline, "SetPolylineXY" ); - QString aDocName = aDocument->GetDocPyName(); - QString aPolylineName = GetName(); + Handle(HYDROData_ProfileUZ) aRefProfileUZ = GetProfileUZ(); + if ( !aRefProfileUZ.IsNull() ) + { + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( aRefProfileUZ->GetFatherObject() ); + if ( checkObjectPythonDefinition( thePyScriptPath, theTreatedObjects, aResList, aProfile ) ) + { + QString aProfileName = aProfile->GetObjPyName(); + if ( !aProfileName.isEmpty() ) + { + aResList << QString( "%1.SetProfileUZ( %2.GetProfileUZ() )" ) + .arg( aPolylineName ).arg( aProfileName ); + } + } + } + else + { + Handle(HYDROData_IAltitudeObject) aRefBathymetry = GetAltitudeObject(); + if ( !aRefBathymetry.IsNull() ) + { + Handle(HYDROData_ProfileUZ) aChildProfileUZ = GetChildProfileUZ(); + if ( !aChildProfileUZ.IsNull() ) + { + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( aChildProfileUZ->GetFatherObject() ); + if ( checkObjectPythonDefinition( thePyScriptPath, theTreatedObjects, aResList, aProfile ) ) + { + QString aProfileName = aProfile->GetObjPyName(); + if ( !aProfileName.isEmpty() ) + { + aResList << QString( "%1.SetChildProfileUZ( %2.GetProfileUZ() )" ) + .arg( aPolylineName ).arg( aProfileName ); + } + } + } + + setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefBathymetry, "SetAltitudeObject" ); + } + } - aResList << QString( "%1 = %2.CreateObject( %3 );" ) - .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID ); - aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName ); aResList << QString( "" ); - - // TODO + aResList << QString( "%1.Update()" ).arg( aPolylineName ); + aResList << QString( "" ); return aResList; } @@ -63,17 +136,11 @@ HYDROData_SequenceOfObjects HYDROData_Polyline3D::GetAllReferenceObjects() const if ( !aProfileUZ.IsNull() ) aResSeq.Append( aProfileUZ ); - return aResSeq; -} - -TopoDS_Shape HYDROData_Polyline3D::GetTopShape() const -{ - return getTopShape(); -} + Handle(HYDROData_ProfileUZ) aChildProfileUZ = GetChildProfileUZ( false ); + if ( !aChildProfileUZ.IsNull() ) + aResSeq.Append( aChildProfileUZ ); -TopoDS_Shape HYDROData_Polyline3D::GetShape3D() const -{ - return getShape3D(); + return aResSeq; } void HYDROData_Polyline3D::Update() @@ -81,15 +148,26 @@ void HYDROData_Polyline3D::Update() HYDROData_Object::Update(); Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY(); - Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ(); - if ( aPolylineXY.IsNull() || aProfileUZ.IsNull() ) + if ( aPolylineXY.IsNull() ) return; bool anIsSectionClosed = aPolylineXY->IsClosedSection( 0 ); HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 ); HYDROData_IPolyline::PointsList aPolylinePoints = aPolylineXY->GetPoints( 0 ); + if ( aPolylinePoints.IsEmpty() ) + return; + + Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ(); + + Handle(HYDROData_IAltitudeObject) anAltitude = GetAltitudeObject(); + if ( !anAltitude.IsNull() ) + aProfileUZ = GetChildProfileUZ(); + + if ( aProfileUZ.IsNull() ) + return; + HYDROData_IPolyline::PointsList aProfilePoints = aProfileUZ->GetPoints(); - if ( aPolylinePoints.IsEmpty() || aProfilePoints.IsEmpty() ) + if ( aProfilePoints.IsEmpty() ) return; const HYDROData_IPolyline::Point& aFirstPoint = aPolylinePoints.First(); @@ -113,7 +191,7 @@ void HYDROData_Polyline3D::Update() double aDistance = aPolylineXY->GetDistance( 0, i - 1 ); double aParLen = ( aDistance / aPolylineCommonDist ) * aParCommonDist; - double aDepth = aProfileUZ->GetDepthFromDistance( aParLen ); + double aDepth = HYDROData_ProfileUZ::GetDepthFromDistance( aProfilePoints, aParLen ); Polyline3DPoint aCompPoint( aPolylinePoint.X(), aPolylinePoint.Y(), aDepth ); aResPoints.Append( aCompPoint ); @@ -127,27 +205,18 @@ void HYDROData_Polyline3D::Update() SetShape3D( aResWire ); } -QColor HYDROData_Polyline3D::DefaultFillingColor() +QColor HYDROData_Polyline3D::DefaultFillingColor() const { return QColor( Qt::transparent ); } -QColor HYDROData_Polyline3D::DefaultBorderColor() +QColor HYDROData_Polyline3D::DefaultBorderColor() const { return QColor( Qt::red ); } -QColor HYDROData_Polyline3D::getDefaultFillingColor() const -{ - return DefaultFillingColor(); -} - -QColor HYDROData_Polyline3D::getDefaultBorderColor() const -{ - return DefaultBorderColor(); -} - -bool HYDROData_Polyline3D::SetPolylineXY( const Handle(HYDROData_PolylineXY)& thePolyline ) +bool HYDROData_Polyline3D::SetPolylineXY( const Handle(HYDROData_PolylineXY)& thePolyline, + const bool theIsUpdateProfile ) { if ( thePolyline.IsNull() ) return false; @@ -158,8 +227,12 @@ bool HYDROData_Polyline3D::SetPolylineXY( const Handle(HYDROData_PolylineXY)& th SetReferenceObject( thePolyline, DataTag_PolylineXY ); + // Update the child profile object + if ( theIsUpdateProfile ) + updateChildProfilePoints(); + // Indicate model of the need to update the polyline presentation - SetToUpdate( true ); + Changed( Geom_2d ); return true; } @@ -179,7 +252,7 @@ void HYDROData_Polyline3D::RemovePolylineXY() ClearReferenceObjects( DataTag_PolylineXY ); // Indicate model of the need to update the polyline presentation - SetToUpdate( true ); + Changed( Geom_2d ); } bool HYDROData_Polyline3D::SetProfileUZ( const Handle(HYDROData_ProfileUZ)& theProfile ) @@ -193,8 +266,11 @@ bool HYDROData_Polyline3D::SetProfileUZ( const Handle(HYDROData_ProfileUZ)& theP SetReferenceObject( theProfile, DataTag_ProfileUZ ); + // Remove the bathymetry, because one altitude object can be presented at time + RemoveAltitudeObject(); + // Indicate model of the need to update the polyline presentation - SetToUpdate( true ); + Changed( Geom_Z ); return true; } @@ -214,6 +290,230 @@ void HYDROData_Polyline3D::RemoveProfileUZ() ClearReferenceObjects( DataTag_ProfileUZ ); // Indicate model of the need to update the polyline presentation - SetToUpdate( true ); + Changed( Geom_Z ); +} + +bool HYDROData_Polyline3D::SetAltitudeObject( + const Handle(HYDROData_IAltitudeObject)& theAltitude ) +{ + Handle(HYDROData_IAltitudeObject) aPrevAltitude = GetAltitudeObject(); + + if ( !HYDROData_Object::SetAltitudeObject( theAltitude ) ) + return false; + + if ( IsEqual( aPrevAltitude, theAltitude ) ) + return true; + + // Remove the u,z profile, because one altitude object can be presented at time + RemoveProfileUZ(); + + // Create the child profile object + updateChildProfilePoints(); + + return true; +} + + +void HYDROData_Polyline3D::RemoveAltitudeObject() +{ + HYDROData_Object::RemoveAltitudeObject(); + + // Remove the child profile object + removeChildProfileUZ(); +} + +Handle(HYDROData_ProfileUZ) HYDROData_Polyline3D::GetChildProfileUZ( const bool theIsCreate ) const +{ + Handle(HYDROData_ProfileUZ) aProfileUZ = + Handle(HYDROData_ProfileUZ)::DownCast( GetReferenceObject( DataTag_ChildProfileUZ ) ); + if ( !theIsCreate || !aProfileUZ.IsNull() ) + return aProfileUZ; + + Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab ); + if ( aDocument.IsNull() ) + return aProfileUZ; + + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) ); + + QString aProfilePref = GetName() + "_Profile"; + QString aProfileName = HYDROData_Tool::GenerateObjectName( aDocument, aProfilePref ); + + aProfile->SetName( aProfileName ); + + aProfileUZ = aProfile->GetProfileUZ(); + + HYDROData_Polyline3D* me = const_cast( this ); // Temporary to be revised + me->SetChildProfileUZ( aProfileUZ ); + + return aProfileUZ; +} + +void HYDROData_Polyline3D::SetChildProfileUZ( const Handle(HYDROData_ProfileUZ)& theProfile ) +{ + SetReferenceObject( theProfile, DataTag_ChildProfileUZ ); +} + +HYDROData_IPolyline::PointsList generateProfileUZPoints( + const Handle(HYDROData_PolylineXY)& thePolyline, + const Handle(HYDROData_IAltitudeObject)& theAltitude ) +{ + HYDROData_IPolyline::PointsList aPointsList; + if ( thePolyline.IsNull() || theAltitude.IsNull() ) + return aPointsList; + + bool anIsSectionClosed = thePolyline->IsClosedSection( 0 ); + HYDROData_IPolyline::SectionType aSectionType = thePolyline->GetSectionType( 0 ); + HYDROData_IPolyline::PointsList aPolylinePoints = thePolyline->GetPoints( 0 ); + if ( aPolylinePoints.IsEmpty() ) + return aPointsList; + + for ( int i = 1, aNbPoints = aPolylinePoints.Size(); i <= aNbPoints; ++i ) + { + const HYDROData_PolylineXY::Point& aSectPoint = aPolylinePoints.Value( i ); + + double aPointDistance = thePolyline->GetDistance( 0, i - 1 ); + double aPointDepth = theAltitude->GetAltitudeForPoint( aSectPoint ); + if( aPointDepth == theAltitude->GetInvalidAltitude() ) + aPointDepth = 0.0; + + HYDROData_IPolyline::Point anAltitudePoint( aPointDistance, aPointDepth ); + aPointsList.Append( anAltitudePoint ); + } + + return aPointsList; +} + +void HYDROData_Polyline3D::updateChildProfilePoints() +{ + Handle(HYDROData_IAltitudeObject) anAltitude = GetAltitudeObject(); + if ( anAltitude.IsNull() ) + return; + + Handle(HYDROData_ProfileUZ) aChildProfileUZ = GetChildProfileUZ(); + if ( aChildProfileUZ.IsNull() ) + return; + + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( aChildProfileUZ->GetFatherObject() ); + if ( aProfile.IsNull() ) + return; + + HYDROData_IPolyline::PointsList aProfilePoints = + generateProfileUZPoints( GetPolylineXY(), anAltitude ); + aProfile->SetParametricPoints( aProfilePoints ); + + aProfile->Update(); +} + +void HYDROData_Polyline3D::removeChildProfileUZ() +{ + Handle(HYDROData_ProfileUZ) aChildProfileUZ = GetChildProfileUZ( false ); + if ( aChildProfileUZ.IsNull() ) + return; + + ClearReferenceObjects( DataTag_ChildProfileUZ ); + + /* Uncomment if removing is requested + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( aChildProfileUZ->GetFatherObject() ); + if ( !aProfile.IsNull() ) + aProfile->Remove(); + */ +} + +HYDROData_Polyline3D::Polyline3DPoints HYDROData_Polyline3D::GetPoints( double theEqDistance ) const +{ + Polyline3DPoints aPoints; + + Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY(); + TopoDS_Wire aWire = TopoDS::Wire( GetShape3D() ); + if ( aPolylineXY.IsNull() || aWire.IsNull() ) { + return aPoints; + } + + // Explode polyline on edges + TopTools_SequenceOfShape anEdges; + HYDROData_ShapesTool::ExploreShapeToShapes( aWire, TopAbs_EDGE, anEdges ); + + // Get points + if ( !anEdges.IsEmpty() ) { + HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 ); + + if ( aSectionType == HYDROData_IPolyline::SECTION_POLYLINE ) { + // Get points from wire + /* Seems that intermediate vertices are duplicated + TopExp_Explorer anExp( aWire, TopAbs_VERTEX ); + for ( ; anExp.More(); anExp.Next() ) { + TopoDS_Vertex aVertex = TopoDS::Vertex( anExp.Current() ); + if ( !aVertex.IsNull() ) { + gp_Pnt aPnt = BRep_Tool::Pnt( aVertex ); + aPoints.Append( aPnt.XYZ() ); + } + } + */ + TopExp_Explorer anExp( aWire, TopAbs_EDGE ); + bool isFirst = true; + for ( ; anExp.More(); anExp.Next() ) { + TopoDS_Edge anEdge = TopoDS::Edge( anExp.Current() ); + if ( !anEdge.IsNull() ) { + TopoDS_Vertex aV1, aV2; + TopExp::Vertices( anEdge, aV1, aV2 ); + if ( isFirst ) { + gp_Pnt aPnt1 = BRep_Tool::Pnt( aV1 ); + aPoints.Append( aPnt1.XYZ() ); + } + + gp_Pnt aPnt2 = BRep_Tool::Pnt( aV2 ); + aPoints.Append( aPnt2.XYZ() ); + + isFirst = false; + } + } + } else { + // Get points from spline curve + Standard_Real aStart, anEnd; + TopoDS_Edge anEdge = TopoDS::Edge( anEdges.First() ); + Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aStart, anEnd ); + + if( theEqDistance > 0 ) + { + GeomAdaptor_Curve anAdaptorCurve( aCurve ); + double aLength = GCPnts_AbscissaPoint::Length( anAdaptorCurve ); + int aNbPoints = ceil( aLength / theEqDistance ); + GCPnts_QuasiUniformAbscissa aDist( anAdaptorCurve, aNbPoints ); + if( aDist.IsDone() ) + { + aNbPoints = aDist.NbPoints(); + for( int i=1; i<=aNbPoints; i++ ) + { + double p = aDist.Parameter( i ); + gp_Pnt aPnt; + aCurve->D0( p, aPnt ); + aPoints.Append( aPnt.XYZ() ); + } + return aPoints; + } + } + + Handle(Geom_BSplineCurve) aGeomSpline = Handle(Geom_BSplineCurve)::DownCast( aCurve ); + + if ( !aGeomSpline.IsNull() ) { + int aNbKnots = aGeomSpline->NbKnots(); + + TColStd_Array1OfReal aSplineKnots( 1, aNbKnots ); + aGeomSpline->Knots( aSplineKnots ); + + for ( int i = 1; i <= aNbKnots; ++i ) { + const Standard_Real& aKnot = aSplineKnots.Value( i ); + gp_Pnt aPnt; + aGeomSpline->D0( aKnot, aPnt ); + aPoints.Append( aPnt.XYZ() ); + } + } + } + } + + return aPoints; }