1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROData_ProfileUZ.h"
21 #include "HYDROData_Tool.h"
24 #include <gp_Pnt2d.hxx>
26 #include <TColStd_ListIteratorOfListOfReal.hxx>
28 #include <TDataStd_BooleanList.hxx>
29 #include <TDataStd_ExtStringList.hxx>
30 #include <TDataStd_IntegerList.hxx>
31 #include <TDataStd_RealList.hxx>
33 #include <TopoDS_Shape.hxx>
35 #include <HYDROData_Profile.h>
36 #include <HYDROData_PolylineXY.h>
39 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ProfileUZ, HYDROData_IPolyline)
41 HYDROData_ProfileUZ::HYDROData_ProfileUZ()
42 : HYDROData_IPolyline()
46 HYDROData_ProfileUZ::~HYDROData_ProfileUZ()
50 TopoDS_Shape HYDROData_ProfileUZ::GetShape() const
52 return TopoDS_Shape();
55 double HYDROData_ProfileUZ::GetDepthFromDistance( const PointsList& thePoints,
56 const double& theDistance )
58 double aResDepth = 0.0;
60 int aNbPoints = thePoints.Size();
64 double aCompDist = 0.0;
65 HYDROData_IPolyline::Point aPrevPoint = thePoints.First();
66 for ( int i = 2; i <= aNbPoints; ++i )
68 const Point& aCurPoint = thePoints.Value( i );
70 double aPntDist = gp_Pnt2d( aPrevPoint.X(), 0 ).Distance( gp_Pnt2d( aCurPoint.X(), 0 ) );
72 aCompDist += aPntDist;
74 if ( theDistance < aCompDist )
76 double aComPntDist = gp_Pnt2d( thePoints.First().X(), 0 ).Distance( gp_Pnt2d( aPrevPoint.X(), 0 ) );
78 double aFindDist = theDistance - aComPntDist;
79 double aRatio = aFindDist / ( aPntDist - aFindDist );
81 aResDepth = ( aPrevPoint.Y() + aRatio * aCurPoint.Y() ) / ( 1 + aRatio );
84 else aResDepth = aCurPoint.Y(); // TODO: workaround for normalized flat altitudes
86 aPrevPoint = aCurPoint;
92 int HYDROData_ProfileUZ::NbSections() const
97 void HYDROData_ProfileUZ::AddSection( const TCollection_AsciiString& /*theSectName*/,
98 const SectionType /*theSectionType*/,
99 const bool /*theIsClosed*/ )
103 TCollection_AsciiString HYDROData_ProfileUZ::GetSectionName( const int /*theSectionIndex*/ ) const
108 void HYDROData_ProfileUZ::SetSectionName( const int /*theSectionIndex*/,
109 const TCollection_AsciiString& /*theSectionName*/ )
113 HYDROData_ProfileUZ::SectionType HYDROData_ProfileUZ::GetSectionType( const int /*theSectionIndex*/ ) const
115 Handle(TDataStd_ExtStringList) aNamesList;
116 Handle(TDataStd_IntegerList) aTypesList;
117 Handle(TDataStd_BooleanList) aClosuresList;
118 getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
119 if ( aTypesList.IsNull() || aTypesList->IsEmpty() )
120 return SECTION_POLYLINE;
122 return (SectionType)aTypesList->First();
125 void HYDROData_ProfileUZ::SetSectionType( const int /*theSectionIndex*/,
126 const SectionType theSectionType )
128 Handle(TDataStd_ExtStringList) aNamesList;
129 Handle(TDataStd_IntegerList) aTypesList;
130 Handle(TDataStd_BooleanList) aClosuresList;
131 getSectionsLists( aNamesList, aTypesList, aClosuresList );
132 if ( aTypesList.IsNull() )
135 // Refill the existing list
137 aTypesList->Append( theSectionType );
140 bool HYDROData_ProfileUZ::IsClosedSection( const int /*theSectionIndex*/ ) const
145 void HYDROData_ProfileUZ::SetSectionClosed( const int /*theSectionIndex*/,
146 const bool /*theIsClosed*/ )
150 void HYDROData_ProfileUZ::RemoveSection( const int /*theSectionIndex*/ )
155 void HYDROData_ProfileUZ::RemoveSections()
157 removePointsLists( 0 );
160 void HYDROData_ProfileUZ::AddPoint( const int /*theSectionIndex*/,
161 const Point& thePoint,
162 const int thePointIndex )
164 double aNewCoordU = thePoint.X();
165 double aNewCoordZ = thePoint.Y();
167 Handle(TDataStd_RealList) aListU, aListZ;
168 getPointsLists( 0, aListU, aListZ );
170 if ( aListU->IsEmpty() || aNewCoordU > aListU->Last() )
172 aListU->Append( aNewCoordU );
173 aListZ->Append( aNewCoordZ );
176 else if ( aNewCoordU < aListU->First() )
178 aListU->Prepend( aNewCoordU );
179 aListZ->Prepend( aNewCoordZ );
183 TColStd_ListOfReal anOldListU;
184 anOldListU = aListU->List();
186 TColStd_ListOfReal anOldListZ;
187 anOldListZ = aListZ->List();
190 removePointsLists( 0 );
191 getPointsLists( 0, aListU, aListZ );
193 bool anIsInserted = false;
194 TColStd_ListIteratorOfListOfReal anIterU( anOldListU );
195 TColStd_ListIteratorOfListOfReal anIterZ( anOldListZ );
196 for ( ; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next() )
198 double aCoordU = anIterU.Value();
199 double aCoordZ = anIterZ.Value();
203 if ( ValuesEquals( aNewCoordU, aCoordU ) )
205 // Just update Z value
206 aCoordZ = aNewCoordZ;
209 else if ( aNewCoordU < aCoordU )
212 aListU->Append( aNewCoordU );
213 aListZ->Append( aNewCoordZ );
218 aListU->Append( aCoordU );
219 aListZ->Append( aCoordZ );
223 void HYDROData_ProfileUZ::SetPoint( const int theSectionIndex,
224 const Point& thePoint,
225 const int /*thePointIndex*/ )
227 AddPoint( theSectionIndex, thePoint );
230 void HYDROData_ProfileUZ::RemovePoint( const int /*theSectionIndex*/,
231 const int thePointIndex )
233 Handle(TDataStd_RealList) aListU, aListZ;
234 getPointsLists( 0, aListU, aListZ, false );
235 if ( aListU.IsNull() || aListZ.IsNull() || aListU->IsEmpty() )
238 TColStd_ListOfReal anOldListU;
239 anOldListU = aListU->List();
241 TColStd_ListOfReal anOldListZ;
242 anOldListZ = aListZ->List();
245 removePointsLists( 0 );
246 getPointsLists( 0, aListU, aListZ );
248 bool anIsInserted = false;
249 TColStd_ListIteratorOfListOfReal anIterU( anOldListU );
250 TColStd_ListIteratorOfListOfReal anIterZ( anOldListZ );
251 for ( int i = 0; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next(), ++i )
253 if ( i == thePointIndex )
254 continue; // skip index to remove
256 aListU->Append( anIterU.Value() );
257 aListZ->Append( anIterZ.Value() );
261 HYDROData_ProfileUZ::PointsList HYDROData_ProfileUZ::GetPoints( const int /*theSectionIndex*/, bool /*IsConvertToGlobal*/ ) const
265 Handle(TDataStd_RealList) aListU, aListZ;
266 getPointsLists( 0, aListU, aListZ, false );
267 if ( aListU.IsNull() || aListZ.IsNull() )
270 TColStd_ListIteratorOfListOfReal anIterU( aListU->List() );
271 TColStd_ListIteratorOfListOfReal anIterZ( aListZ->List() );
272 for ( ; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next() )
274 Point aPoint( anIterU.Value(), anIterZ.Value() );
275 aResList.Append( aPoint );
281 void HYDROData_ProfileUZ::CalculateAndAddPoints(const NCollection_Sequence<gp_XYZ>& theXYZPoints, Handle(HYDROData_PolylineXY)& thePolylineXY)
284 for ( int i = 1; i <= theXYZPoints.Size(); i++ ) {
285 const HYDROData_Profile::ProfilePoint& aBottomPoint = theXYZPoints.Value( i );
286 thePolylineXY->AddPoint( 0, HYDROData_PolylineXY::Point( aBottomPoint.X(), aBottomPoint.Y() ) );
289 // Calculate profile UZ points
292 const HYDROData_Profile::ProfilePoint& aFirstBottomPoint = theXYZPoints.First();
293 AddPoint( 0, HYDROData_ProfileUZ::Point( 0, aFirstBottomPoint.Z() ) );
295 // Intermediate points
296 double aPolylineCommonDist = thePolylineXY->GetDistance( 0, thePolylineXY->NbPoints( 0 ) - 1 );
298 for ( int i = 2, aNbPoints = theXYZPoints.Size(); i < aNbPoints; i++ ) {
299 const HYDROData_Profile::ProfilePoint& aBottomPoint = theXYZPoints.Value( i );
301 double aDistance = thePolylineXY->GetDistance( 0, i - 1 );
303 Standard_Real anU = aDistance; // = ( aDistance / aPolylineCommonDist ) * aPolylineCommonDist;
304 AddPoint( 0, HYDROData_ProfileUZ::Point( anU, aBottomPoint.Z() ) );
308 const HYDROData_Profile::ProfilePoint& aLastBottomPoint = theXYZPoints.Last();
309 AddPoint( 0, HYDROData_ProfileUZ::Point( aPolylineCommonDist, aLastBottomPoint.Z() ) );