Salome HOME
fix test on stream linear interpolation
[modules/hydro.git] / src / HYDROData / HYDROData_Channel.cxx
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.
6 //
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.
11 //
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
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROData_Channel.h"
20
21 #include "HYDROData_Document.h"
22 #include "HYDROData_Polyline3D.h"
23 #include "HYDROData_Profile.h"
24 #include "HYDROData_PolylineXY.h"
25 #include "HYDROData_Projection.h"
26 #include "HYDROData_ShapesGroup.h"
27 #include "HYDROData_ShapesTool.h"
28 #include "HYDROData_Stream.h"
29 #include "HYDROData_Tool.h"
30 #include "HYDROData_ChannelAltitude.h"
31
32 #include <BRepBuilderAPI_MakeWire.hxx>
33 #include <BRepLib_MakePolygon.hxx>
34
35 #include <BRepOffsetAPI_MakePipeShell.hxx>
36 #include <BRepOffsetAPI_MakePipe.hxx>
37 #include <BRepCheck_Analyzer.hxx>
38
39 #include <BRep_Tool.hxx>
40
41 #include <BRepBuilderAPI_Transform.hxx>
42
43 #include <BRepLib_MakeEdge.hxx>
44 #include <BRepLib_MakeWire.hxx>
45
46 #include <GeomAPI_ProjectPointOnCurve.hxx>
47
48 #include <gp_Ax1.hxx>
49
50 #include <TopExp.hxx>
51 #include <TopExp_Explorer.hxx>
52
53 #include <TColgp_HArray1OfPnt.hxx>
54 #include <TColgp_Array1OfDir.hxx>
55
56 #include <TColStd_Array1OfReal.hxx>
57
58 #include <TopTools_HArray1OfShape.hxx>
59 #include <TopTools_SequenceOfShape.hxx>
60
61 #include <TopoDS.hxx>
62 #include <TopoDS_Wire.hxx>
63 #include <TopoDS_Vertex.hxx>
64
65 #include <Quantity_Parameter.hxx>
66
67 #define DEB_CHANNEL 1
68 #ifdef DEB_CHANNEL
69 #include <BRepTools.hxx>
70 #endif
71
72 #include <QColor>
73 #include <QStringList>
74
75 //#define _DEVDEBUG_
76 #include "HYDRO_trace.hxx"
77
78 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Channel,HYDROData_ArtificialObject)
79
80
81 HYDROData_Channel::HYDROData_Channel()
82 : HYDROData_ArtificialObject( Geom_3d )
83 {
84 }
85
86 HYDROData_Channel::~HYDROData_Channel()
87 {
88 }
89
90 QStringList HYDROData_Channel::DumpToPython( const QString& thePyScriptPath,
91   MapOfTreatedObjects& theTreatedObjects ) const
92 {
93   QStringList aResList = dumpObjectCreation( theTreatedObjects );
94   QString aName = GetObjPyName();
95
96   Handle(HYDROData_Polyline3D) aRefGideLine = GetGuideLine();
97   setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefGideLine, "SetGuideLine" );
98
99   bool mode = GetProfileMode();
100   QString aMode = mode ? "True" : "False" ;
101   aResList << QString( "%1.SetProfileMode( %2 )" ).arg( aName ).arg( aMode );
102
103   if (mode)
104   {
105     Handle(HYDROData_Profile) aRefProfile = GetProfile();
106     setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefProfile, "SetProfile" );
107   }
108   else
109   {
110     QString aLC = QString::number( GetLCValue(), 'f', 3 );
111     QString aDeltaZ = QString::number( GetDeltaZValue(), 'f', 3 );
112     QString aCoteZ = QString::number( GetCoteZValue(), 'f', 3 );
113
114     aResList << QString( "%1.SetLCValue( %2 )" ).arg( aName ).arg( aLC );
115     aResList << QString( "%1.SetDeltaZValue( %2 )" ).arg( aName ).arg( aDeltaZ );
116     aResList << QString( "%1.SetCoteZValue( %2 )" ).arg( aName ).arg( aCoteZ );
117   }
118
119   aResList << QString( "%1.SetEquiDistance( %2 )" ).arg( aName ).arg( GetEquiDistance() );
120
121   aResList << QString( "" );
122   aResList << QString( "%1.Update()" ).arg( aName );
123   aResList << QString( "" );
124
125   return aResList;
126
127 }
128
129 HYDROData_SequenceOfObjects HYDROData_Channel::GetAllReferenceObjects() const
130 {
131   HYDROData_SequenceOfObjects aResSeq = HYDROData_ArtificialObject::GetAllReferenceObjects();
132
133   Handle(HYDROData_Polyline3D) aGuideLine = GetGuideLine();
134   if ( !aGuideLine.IsNull() )
135     aResSeq.Append( aGuideLine );
136
137   Handle(HYDROData_Profile) aProfile = GetProfile();
138   if ( !aProfile.IsNull() )
139     aResSeq.Append( aProfile );
140
141   return aResSeq;
142 }
143
144 bool HYDROData_Channel::CreatePresentations( const Handle(HYDROData_Polyline3D)& theGuideLine,
145                                              const Handle(HYDROData_Profile)&    theProfile,
146                                              PrsDefinition&                      thePrs,
147                                              double                              theEquiDistance,
148                                              bool                                ReverseXCoord)
149 {
150   return internalCreatePresentations( true, theGuideLine, theProfile, TopoDS_Wire(), gp_Pnt(), thePrs, theEquiDistance, ReverseXCoord);
151 }
152
153 bool HYDROData_Channel::CreatePresentations( const Handle(HYDROData_Polyline3D)& theGuideLine,
154                                              double                              LC,
155                                              double                              deltaZ,
156                                              double                              coteZ,
157                                              PrsDefinition&                      thePrs,
158                                              double                              theEquiDistance,
159                                              bool                                ReverseXCoord)
160 {
161   Handle(HYDROData_Profile) theProfile;
162   TopoDS_Wire W;
163   gp_Pnt MP;
164
165   gp_Pnt2d A1(-0.75*LC, coteZ-LC/2.0), A2(0.75*LC, coteZ -LC/2.0), B1(-LC/2.0, coteZ), B2(LC/2.0, coteZ), C(0, coteZ+deltaZ);
166   gp_Pnt A1_3d(A1.X(), 0, A1.Y()), A2_3d(A2.X(), 0, A2.Y()), B1_3d(B1.X(), 0, B1.Y()), B2_3d(B2.X(), 0, B2.Y()), C_3d(C.X(), 0, C.Y());
167   BRepLib_MakePolygon PM;
168   PM.Add(A1_3d);
169   PM.Add(B1_3d);
170   PM.Add(C_3d);
171   PM.Add(B2_3d);
172   PM.Add(A2_3d);
173   W = PM.Wire();
174   return internalCreatePresentations( false, theGuideLine, theProfile, W, MP, thePrs, theEquiDistance, ReverseXCoord);
175 }
176
177 bool HYDROData_Channel::internalCreatePresentations( bool mode,
178                                                      const Handle(HYDROData_Polyline3D)& theGuideLine,
179                                                      const Handle(HYDROData_Profile)&    theProfile,
180                                                      const TopoDS_Wire&                  theProfWire,
181                                                      const gp_Pnt&                       theMiddlePnt,
182                                                      PrsDefinition&                      thePrs,
183                                                      double                              theEquiDistance,
184                                                      bool                                ReverseXCoord)
185 {
186   // Check input parameters
187   if ( theGuideLine.IsNull() )
188   {
189     return false;
190   }
191   if (mode && theProfile.IsNull() || !mode && theProfWire.IsNull() )
192     return false;
193
194   TopoDS_Wire aPathWire = TopoDS::Wire( theGuideLine->GetShape3D() );
195   TopoDS_Wire aProfileWire = theProfWire;
196   //ignore ReverseXCoord if mode is false
197   if (mode)
198   {
199     if (!ReverseXCoord)
200       aProfileWire = TopoDS::Wire( theProfile->GetShape3D(false, false) ); //temp force rebuild
201     else
202       aProfileWire = TopoDS::Wire( theProfile->GetShape3D(true, true));
203   }
204   if ( aPathWire.IsNull() || aProfileWire.IsNull() ) {
205     return false;
206   }
207
208 #ifdef DEB_CHANNEL
209   std::string brepName = "guideline_";
210   brepName += theGuideLine->GetName().toStdString();
211   brepName += ".brep";
212   BRepTools::Write( aPathWire, brepName.c_str() );
213   brepName = "profile_";
214   brepName += theGuideLine->GetName().toStdString();
215   brepName += ".brep";
216   BRepTools::Write( aProfileWire, brepName.c_str() );
217 #endif
218
219   // Pre-processing
220   Handle(HYDROData_PolylineXY) aPolylineXY = theGuideLine->GetPolylineXY();
221   if ( aPolylineXY.IsNull() ) {
222     return false;
223   }
224
225   /*
226   HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 );
227   HYDROData_IPolyline::PointsList aPolylinePoints = aPolylineXY->GetPoints( 0 );
228   int aNbPoints = aPolylinePoints.Length();
229   */
230
231   HYDROData_Polyline3D::Polyline3DPoints aPolylinePoints3D = theGuideLine->GetPoints( theEquiDistance );
232   int aNbPoints = aPolylinePoints3D.Length();
233   if ( aNbPoints < 2 )
234     return false;
235   
236   // Get tangent in each point of the guide line ( 2D )
237   TColgp_Array1OfDir aTangents( 1, aNbPoints );
238
239   HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 );
240   
241   if( aSectionType == HYDROData_IPolyline::SECTION_POLYLINE )
242   {
243     for ( int i = 1; i <= aNbPoints; ++i ) {
244       gp_XYZ aPnt = aPolylinePoints3D.Value( i );
245       aPnt.SetZ( 0. );
246       gp_XYZ aPrevPnt;
247       if ( i > 1 ) {
248         aPrevPnt = aPolylinePoints3D.Value( i - 1 );
249         aPrevPnt.SetZ( 0. );
250       }
251
252       gp_Vec aDir;
253       if ( i < aNbPoints ) {
254         gp_XYZ aNextPnt = aPolylinePoints3D.Value( i + 1 );
255         aNextPnt.SetZ( 0. );
256
257         gp_Vec anEdgeVec( aPnt, aNextPnt );
258
259         if ( i == 1 ) {
260           aDir = anEdgeVec;
261         } else {
262           gp_Vec aPrevVec( aPrevPnt, aPnt );
263           aDir = aPrevVec.Normalized() + anEdgeVec.Normalized();
264         }
265       } else {
266         aDir = gp_Vec( aPrevPnt, aPnt );
267       }
268             
269       aTangents.SetValue( i, aDir );
270     }
271   } else {
272     // Get curve from the first edge ( 2D )
273     TopTools_SequenceOfShape anEdges;
274     HYDROData_ShapesTool::ExploreShapeToShapes( aPolylineXY->GetShape(), TopAbs_EDGE, anEdges );
275     Standard_Real aStart, anEnd;
276
277     Handle(Geom_Curve) aCurve = BRep_Tool::Curve( TopoDS::Edge( anEdges.First() ), aStart, anEnd );
278     GeomAPI_ProjectPointOnCurve aProject;
279
280     // Get tangents
281     for ( int i = 1; i <= aNbPoints; ++i ) {
282       gp_XYZ aPointToTest = aPolylinePoints3D.Value( i );
283       aPointToTest.SetZ( 0. );
284
285       aProject.Init( aPointToTest, aCurve );
286       Quantity_Parameter aParam = aProject.LowerDistanceParameter();
287       gp_Pnt aPnt;
288       gp_Vec aDir;
289       aCurve->D1( aParam, aPnt, aDir);
290
291       aTangents.SetValue( i, aDir );
292     }
293   }
294
295   // Get the profile middle point ( 3D )
296   gp_Pnt aMiddlePoint = theMiddlePnt;
297   if (mode)
298   {
299     aMiddlePoint = theProfile->GetMiddlePoint( true );
300   }
301
302   // Translate the profile to each point on the guide line ( 3D )
303   Handle(TColgp_HArray1OfPnt) anArrayOfFPnt = new TColgp_HArray1OfPnt(1, aNbPoints );
304   Handle(TColgp_HArray1OfPnt) anArrayOfLPnt = new TColgp_HArray1OfPnt(1, aNbPoints );  
305   Handle(TopTools_HArray1OfShape) anArrOfProfiles = new TopTools_HArray1OfShape( 1, aNbPoints );
306
307   for ( int i = 1; i <= aNbPoints; ++i ) {
308     // Get point on the guide line
309     gp_Pnt aPointOnGuide( aPolylinePoints3D.Value( i ) );
310
311     // Define translation and rotation:
312     gp_Trsf Translation, Rotation;
313
314     // Translation
315     Translation.SetTranslation( aMiddlePoint, aPointOnGuide );
316     TopoDS_Wire aTransformedProfile = 
317       TopoDS::Wire( BRepBuilderAPI_Transform( aProfileWire, Translation, Standard_True ) );
318
319     // Rotation
320     gp_Vec aVertical( 0., 0., 1. );
321     TopoDS_Vertex aLeftVertex, aRightVertex;
322     TopExp::Vertices( aTransformedProfile, aLeftVertex, aRightVertex );
323     gp_Pnt aLeftPoint  = BRep_Tool::Pnt( aLeftVertex );
324     gp_Pnt aRightPoint = BRep_Tool::Pnt( aRightVertex );
325     gp_Vec aLeftToRight( aLeftPoint, aRightPoint);
326     gp_Vec NormalToProfile = aVertical ^ aLeftToRight;
327
328     gp_Vec aDir = aTangents.Value( i );
329     gp_Vec AxisOfRotation = NormalToProfile ^ aDir;
330     if (AxisOfRotation.Magnitude() <= gp::Resolution()) {
331       if ( aVertical * aLeftToRight < 0. ) {
332         gp_Ax1 theVertical(aPointOnGuide, gp::DZ() );
333         Rotation.SetRotation(theVertical, M_PI);
334       }
335     } else {
336       gp_Ax1 theAxis(aPointOnGuide, AxisOfRotation);
337       Standard_Real theAngle = NormalToProfile.AngleWithRef(aDir, AxisOfRotation);
338       Rotation.SetRotation(theAxis, theAngle);
339     }
340
341     aTransformedProfile = TopoDS::Wire(BRepBuilderAPI_Transform( aTransformedProfile, Rotation, Standard_True) );
342
343     // Get the first and the last points of the transformed profile
344     TopoDS_Vertex V1, V2;
345     TopExp::Vertices( aTransformedProfile, V1, V2 );
346
347     // Fill the data
348     anArrayOfFPnt->SetValue( i, BRep_Tool::Pnt( V1 ) );
349     anArrayOfLPnt->SetValue( i, BRep_Tool::Pnt( V2 ) );
350        
351     anArrOfProfiles->SetValue( i, aTransformedProfile );
352   }
353
354   // Create presentation
355   HYDROData_Stream::PrsDefinition aPrs;
356   Handle(TopTools_HArray1OfShape) anArrOf2DProfiles; // we don't need 2D profiles for channel/digue presentation
357
358   HYDROData_Stream::CreatePresentations( anArrayOfFPnt, anArrayOfLPnt, anArrOfProfiles, aPrs );
359   thePrs.myInlet =  aPrs.myInlet;       
360   thePrs.myOutlet =  aPrs.myOutlet; 
361   thePrs.myLeftBank = aPrs.myLeftBank; 
362   thePrs.myRightBank = aPrs.myRightBank;
363   thePrs.myPrs2D = TopoDS::Face(aPrs.myPrs2D); 
364   thePrs.myPrs3D = aPrs.myPrs3D; 
365
366   //thePrs.myPrs2D = TopoDS::Face( aPrs.myPrs2D );
367   //BRepBuilderAPI_MakeWire aMakeWire( aPrs.myLeftBank ) ;
368   //thePrs.myLeftBank = aMakeWire.Wire();
369   //aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myRightBank );
370   //thePrs.myRightBank = aMakeWire.Wire();
371   //aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myInlet );
372   //thePrs.myInlet = aMakeWire.Wire();
373   //aMakeWire = BRepBuilderAPI_MakeWire( aPrs.myOutlet );
374   //thePrs.myOutlet = aMakeWire.Wire();
375
376   return true;
377 }
378
379 void HYDROData_Channel::Update()
380 {
381   HYDROData_ArtificialObject::Update();
382
383   Handle(HYDROData_Polyline3D) aGuideLine = GetGuideLine();
384
385   PrsDefinition aResultPrs;
386   double anEquiDistance = GetEquiDistance();
387
388   bool invDirection = false;
389   Handle(HYDROData_IAltitudeObject) anObjAltitude = GetAltitudeObject();
390   Handle(HYDROData_ChannelAltitude) aChannelAlt = Handle(HYDROData_ChannelAltitude)::DownCast(anObjAltitude);
391   if (!aChannelAlt.IsNull())
392     invDirection = aChannelAlt->GetInvertDirection();
393
394   if (GetProfileMode())
395   {
396     Handle(HYDROData_Profile) aProfile = GetProfile();
397     if ( !CreatePresentations( aGuideLine, aProfile, aResultPrs, anEquiDistance, invDirection ) )
398       return;
399   }
400   else
401   {
402     double lc = GetLCValue();
403     double deltaz = GetDeltaZValue();
404     double cotez = GetCoteZValue();
405     if ( !CreatePresentations( aGuideLine, lc, deltaz, cotez, aResultPrs, anEquiDistance, invDirection ) )
406       return;
407   }
408
409   SetShape3D( aResultPrs.myPrs3D );
410   SetTopShape( aResultPrs.myPrs2D );
411
412   // Create groups for channel
413   TopTools_SequenceOfShape aLeftBankEdges;
414   HYDROData_ShapesTool::ExploreShapeToShapes( aResultPrs.myLeftBank, TopAbs_EDGE, aLeftBankEdges );
415
416   TopTools_SequenceOfShape aRightBankEdges;
417   HYDROData_ShapesTool::ExploreShapeToShapes( aResultPrs.myRightBank, TopAbs_EDGE, aRightBankEdges );
418
419   TopTools_SequenceOfShape anInletEdges;
420   HYDROData_ShapesTool::ExploreShapeToShapes( aResultPrs.myInlet, TopAbs_EDGE, anInletEdges );
421
422   TopTools_SequenceOfShape anOutletEdges;
423   HYDROData_ShapesTool::ExploreShapeToShapes( aResultPrs.myOutlet, TopAbs_EDGE, anOutletEdges );
424     
425   RemoveGroupObjects();
426   QString aLeftGroupName = GetName() + "_Left_Bank";
427   Handle(HYDROData_ShapesGroup) aLeftGroup = createGroupObject();
428   aLeftGroup->SetName( aLeftGroupName );
429   aLeftGroup->SetShapes( aLeftBankEdges );
430
431   QString aRightGroupName = GetName() + "_Right_Bank";
432
433   Handle(HYDROData_ShapesGroup) aRightGroup = createGroupObject();
434   aRightGroup->SetName( aRightGroupName );
435   aRightGroup->SetShapes( aRightBankEdges );
436
437   QString anInGroupName = GetName() + "_Inlet";
438
439   Handle(HYDROData_ShapesGroup) anInGroup = createGroupObject();
440   anInGroup->SetName( anInGroupName );
441   anInGroup->SetShapes( anInletEdges );
442
443   QString anOutGroupName = GetName() + "_Outlet";
444
445   Handle(HYDROData_ShapesGroup) anOutGroup = createGroupObject();
446   anOutGroup->SetName( anOutGroupName );
447   anOutGroup->SetShapes( anOutletEdges );
448 }
449
450 bool HYDROData_Channel::IsHas2dPrs() const
451 {
452   return true;
453 }
454
455 QColor HYDROData_Channel::DefaultFillingColor() const
456 {
457   return QColor( Qt::blue );
458 }
459
460 QColor HYDROData_Channel::DefaultBorderColor() const
461 {
462   return QColor( Qt::transparent );
463 }
464
465 bool HYDROData_Channel::SetGuideLine( const Handle(HYDROData_Polyline3D)& theGuideLine )
466 {
467   Handle(HYDROData_Polyline3D) aPrevGuideLine = GetGuideLine();
468
469   if ( theGuideLine.IsNull() )
470   {
471     RemoveGuideLine();
472     return !aPrevGuideLine.IsNull();
473   }
474
475   if ( IsEqual( aPrevGuideLine, theGuideLine ) )
476     return false;
477
478   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theGuideLine->GetTopShape() );
479   if ( aHydraulicWire.IsNull() )
480     return false; // The polyline must be a single wire
481
482   SetReferenceObject( theGuideLine, DataTag_GuideLine );
483
484   // Indicate model of the need to update the chanel presentation
485   Changed( Geom_3d );
486
487   return true;
488 }
489
490 Handle(HYDROData_Polyline3D) HYDROData_Channel::GetGuideLine() const
491 {
492   return Handle(HYDROData_Polyline3D)::DownCast( 
493            GetReferenceObject( DataTag_GuideLine ) );
494 }
495
496 void HYDROData_Channel::RemoveGuideLine()
497 {
498   Handle(HYDROData_Polyline3D) aPrevGuideLine = GetGuideLine();
499   if ( aPrevGuideLine.IsNull() )
500     return;
501
502   ClearReferenceObjects( DataTag_GuideLine );
503
504   // Indicate model of the need to update the chanel presentation
505   Changed( Geom_3d );
506 }
507
508 bool HYDROData_Channel::SetProfile( const Handle(HYDROData_Profile)& theProfile )
509 {
510   Handle(HYDROData_Profile) aPrevProfile = GetProfile();
511
512   if ( theProfile.IsNull() )
513   {
514     RemoveProfile();
515     return !aPrevProfile.IsNull();
516   }
517
518   if ( IsEqual( aPrevProfile, theProfile ) )
519     return false;
520
521   SetReferenceObject( theProfile, DataTag_Profile );
522
523   // Indicate model of the need to update the chanel presentation
524   Changed( Geom_3d );
525
526   return true;
527 }
528
529 Handle(HYDROData_Profile) HYDROData_Channel::GetProfile() const
530 {
531   return Handle(HYDROData_Profile)::DownCast( 
532            GetReferenceObject( DataTag_Profile ) );
533 }
534
535 void HYDROData_Channel::RemoveProfile()
536 {
537   Handle(HYDROData_Profile) aPrevProfile = GetProfile();
538   if ( aPrevProfile.IsNull() )
539     return;
540
541   ClearReferenceObjects( DataTag_Profile );
542
543   // Indicate model of the need to update the chanel presentation
544   Changed( Geom_3d );
545 }
546
547 ObjectKind HYDROData_Channel::getAltitudeObjectType() const
548 {
549   //DEBTRACE("HYDROData_Channel::getAltitudeObjectType");
550   return KIND_CHANNEL_ALTITUDE;
551   //return KIND_STREAM_ALTITUDE;
552 }
553
554 TopoDS_Shape HYDROData_Channel::GetLeftShape() const
555 {
556   HYDROData_SequenceOfObjects aGroups = GetGroups();
557   return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 1);
558 }
559
560 TopoDS_Shape HYDROData_Channel::GetRightShape() const
561 {
562   HYDROData_SequenceOfObjects aGroups = GetGroups();
563   return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 2);
564 }
565
566 void HYDROData_Channel::SetEquiDistance( double theEquiDistance )
567 {
568   double anEquiDistance = theEquiDistance > 0 ? theEquiDistance : 1E-3;
569   SetDouble( DataTag_EquiDistance, theEquiDistance );
570 }
571
572 double HYDROData_Channel::GetEquiDistance() const
573 {
574   return GetDouble( DataTag_EquiDistance, 1.0 );
575 }
576
577 void HYDROData_Channel::SetLCValue( double val )
578 {
579   SetDouble( DataTag_LC, val );
580 }
581
582 double HYDROData_Channel::GetLCValue() const
583 {
584   return GetDouble( DataTag_LC, 1.0 );
585 }
586
587 void HYDROData_Channel::SetDeltaZValue( double val )
588 {
589   SetDouble( DataTag_DeltaZ, val );
590 }
591
592 double HYDROData_Channel::GetDeltaZValue() const
593 {
594   return GetDouble( DataTag_DeltaZ, 1.0 );
595 }
596
597 void HYDROData_Channel::SetCoteZValue( double val )
598 {
599   SetDouble( DataTag_CoteZ, val );
600 }
601
602 double HYDROData_Channel::GetCoteZValue() const
603 {
604   return GetDouble( DataTag_CoteZ, 1.0 );
605 }
606
607 void HYDROData_Channel::SetProfileMode( bool mode )
608 {
609   SetInteger( DataTag_ProfileMode, (bool)mode );
610 }
611
612 bool HYDROData_Channel::GetProfileMode() const
613 {
614   return (bool)GetInteger( DataTag_ProfileMode, 1 );
615 }