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_HANDLE(HYDROData_ProfileUZ, HYDROData_IPolyline)
40 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ProfileUZ, HYDROData_IPolyline)
42 HYDROData_ProfileUZ::HYDROData_ProfileUZ()
43 : HYDROData_IPolyline()
47 HYDROData_ProfileUZ::~HYDROData_ProfileUZ()
51 TopoDS_Shape HYDROData_ProfileUZ::GetShape() const
53 return TopoDS_Shape();
56 double HYDROData_ProfileUZ::GetDepthFromDistance( const PointsList& thePoints,
57 const double& theDistance )
59 double aResDepth = 0.0;
61 int aNbPoints = thePoints.Size();
65 double aCompDist = 0.0;
66 HYDROData_IPolyline::Point aPrevPoint = thePoints.First();
67 for ( int i = 2; i <= aNbPoints; ++i )
69 const Point& aCurPoint = thePoints.Value( i );
71 double aPntDist = gp_Pnt2d( aPrevPoint.X(), 0 ).Distance( gp_Pnt2d( aCurPoint.X(), 0 ) );
73 aCompDist += aPntDist;
75 if ( theDistance < aCompDist )
77 double aComPntDist = gp_Pnt2d( thePoints.First().X(), 0 ).Distance( gp_Pnt2d( aPrevPoint.X(), 0 ) );
79 double aFindDist = theDistance - aComPntDist;
80 double aRatio = aFindDist / ( aPntDist - aFindDist );
82 aResDepth = ( aPrevPoint.Y() + aRatio * aCurPoint.Y() ) / ( 1 + aRatio );
85 else aResDepth = aCurPoint.Y(); // TODO: workaround for normalized flat altitudes
87 aPrevPoint = aCurPoint;
93 int HYDROData_ProfileUZ::NbSections() const
98 void HYDROData_ProfileUZ::AddSection( const TCollection_AsciiString& /*theSectName*/,
99 const SectionType /*theSectionType*/,
100 const bool /*theIsClosed*/ )
104 TCollection_AsciiString HYDROData_ProfileUZ::GetSectionName( const int /*theSectionIndex*/ ) const
109 void HYDROData_ProfileUZ::SetSectionName( const int /*theSectionIndex*/,
110 const TCollection_AsciiString& /*theSectionName*/ )
114 HYDROData_ProfileUZ::SectionType HYDROData_ProfileUZ::GetSectionType( const int /*theSectionIndex*/ ) const
116 Handle(TDataStd_ExtStringList) aNamesList;
117 Handle(TDataStd_IntegerList) aTypesList;
118 Handle(TDataStd_BooleanList) aClosuresList;
119 getSectionsLists( aNamesList, aTypesList, aClosuresList, false );
120 if ( aTypesList.IsNull() || aTypesList->IsEmpty() )
121 return SECTION_POLYLINE;
123 return (SectionType)aTypesList->First();
126 void HYDROData_ProfileUZ::SetSectionType( const int /*theSectionIndex*/,
127 const SectionType theSectionType )
129 Handle(TDataStd_ExtStringList) aNamesList;
130 Handle(TDataStd_IntegerList) aTypesList;
131 Handle(TDataStd_BooleanList) aClosuresList;
132 getSectionsLists( aNamesList, aTypesList, aClosuresList );
133 if ( aTypesList.IsNull() )
136 // Refill the existing list
138 aTypesList->Append( theSectionType );
141 bool HYDROData_ProfileUZ::IsClosedSection( const int /*theSectionIndex*/ ) const
146 void HYDROData_ProfileUZ::SetSectionClosed( const int /*theSectionIndex*/,
147 const bool /*theIsClosed*/ )
151 void HYDROData_ProfileUZ::RemoveSection( const int /*theSectionIndex*/ )
156 void HYDROData_ProfileUZ::RemoveSections()
158 removePointsLists( 0 );
161 void HYDROData_ProfileUZ::AddPoint( const int /*theSectionIndex*/,
162 const Point& thePoint,
163 const int thePointIndex )
165 double aNewCoordU = thePoint.X();
166 double aNewCoordZ = thePoint.Y();
168 Handle(TDataStd_RealList) aListU, aListZ;
169 getPointsLists( 0, aListU, aListZ );
171 if ( aListU->IsEmpty() || aNewCoordU > aListU->Last() )
173 aListU->Append( aNewCoordU );
174 aListZ->Append( aNewCoordZ );
177 else if ( aNewCoordU < aListU->First() )
179 aListU->Prepend( aNewCoordU );
180 aListZ->Prepend( aNewCoordZ );
184 TColStd_ListOfReal anOldListU;
185 anOldListU = aListU->List();
187 TColStd_ListOfReal anOldListZ;
188 anOldListZ = aListZ->List();
191 removePointsLists( 0 );
192 getPointsLists( 0, aListU, aListZ );
194 bool anIsInserted = false;
195 TColStd_ListIteratorOfListOfReal anIterU( anOldListU );
196 TColStd_ListIteratorOfListOfReal anIterZ( anOldListZ );
197 for ( ; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next() )
199 double aCoordU = anIterU.Value();
200 double aCoordZ = anIterZ.Value();
204 if ( ValuesEquals( aNewCoordU, aCoordU ) )
206 // Just update Z value
207 aCoordZ = aNewCoordZ;
210 else if ( aNewCoordU < aCoordU )
213 aListU->Append( aNewCoordU );
214 aListZ->Append( aNewCoordZ );
219 aListU->Append( aCoordU );
220 aListZ->Append( aCoordZ );
224 void HYDROData_ProfileUZ::SetPoint( const int theSectionIndex,
225 const Point& thePoint,
226 const int /*thePointIndex*/ )
228 AddPoint( theSectionIndex, thePoint );
231 void HYDROData_ProfileUZ::RemovePoint( const int /*theSectionIndex*/,
232 const int thePointIndex )
234 Handle(TDataStd_RealList) aListU, aListZ;
235 getPointsLists( 0, aListU, aListZ, false );
236 if ( aListU.IsNull() || aListZ.IsNull() || aListU->IsEmpty() )
239 TColStd_ListOfReal anOldListU;
240 anOldListU = aListU->List();
242 TColStd_ListOfReal anOldListZ;
243 anOldListZ = aListZ->List();
246 removePointsLists( 0 );
247 getPointsLists( 0, aListU, aListZ );
249 bool anIsInserted = false;
250 TColStd_ListIteratorOfListOfReal anIterU( anOldListU );
251 TColStd_ListIteratorOfListOfReal anIterZ( anOldListZ );
252 for ( int i = 0; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next(), ++i )
254 if ( i == thePointIndex )
255 continue; // skip index to remove
257 aListU->Append( anIterU.Value() );
258 aListZ->Append( anIterZ.Value() );
262 HYDROData_ProfileUZ::PointsList HYDROData_ProfileUZ::GetPoints( const int /*theSectionIndex*/, bool /*IsConvertToGlobal*/ ) const
266 Handle(TDataStd_RealList) aListU, aListZ;
267 getPointsLists( 0, aListU, aListZ, false );
268 if ( aListU.IsNull() || aListZ.IsNull() )
271 TColStd_ListIteratorOfListOfReal anIterU( aListU->List() );
272 TColStd_ListIteratorOfListOfReal anIterZ( aListZ->List() );
273 for ( ; anIterU.More() && anIterZ.More(); anIterU.Next(), anIterZ.Next() )
275 Point aPoint( anIterU.Value(), anIterZ.Value() );
276 aResList.Append( aPoint );
282 void HYDROData_ProfileUZ::CalculateAndAddPoints(const NCollection_Sequence<gp_XYZ>& theXYZPoints, Handle_HYDROData_PolylineXY& thePolylineXY)
285 for ( int i = 1; i <= theXYZPoints.Size(); i++ ) {
286 const HYDROData_Profile::ProfilePoint& aBottomPoint = theXYZPoints.Value( i );
287 thePolylineXY->AddPoint( 0, HYDROData_PolylineXY::Point( aBottomPoint.X(), aBottomPoint.Y() ) );
290 // Calculate profile UZ points
293 const HYDROData_Profile::ProfilePoint& aFirstBottomPoint = theXYZPoints.First();
294 AddPoint( 0, HYDROData_ProfileUZ::Point( 0, aFirstBottomPoint.Z() ) );
296 // Intermediate points
297 double aPolylineCommonDist = thePolylineXY->GetDistance( 0, thePolylineXY->NbPoints( 0 ) - 1 );
299 for ( int i = 2, aNbPoints = theXYZPoints.Size(); i < aNbPoints; i++ ) {
300 const HYDROData_Profile::ProfilePoint& aBottomPoint = theXYZPoints.Value( i );
302 double aDistance = thePolylineXY->GetDistance( 0, i - 1 );
304 Standard_Real anU = aDistance; // = ( aDistance / aPolylineCommonDist ) * aPolylineCommonDist;
305 AddPoint( 0, HYDROData_ProfileUZ::Point( anU, aBottomPoint.Z() ) );
309 const HYDROData_Profile::ProfilePoint& aLastBottomPoint = theXYZPoints.Last();
310 AddPoint( 0, HYDROData_ProfileUZ::Point( aPolylineCommonDist, aLastBottomPoint.Z() ) );