]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_Stream.cxx
Salome HOME
ec2b1cb9cb199810671025fe882878c7bbc95692
[modules/hydro.git] / src / HYDROData / HYDROData_Stream.cxx
1
2 #include "HYDROData_Stream.h"
3
4 #include "HYDROData_Document.h"
5 #include "HYDROData_PolylineXY.h"
6 #include "HYDROData_Profile.h"
7
8 #include <BRep_Builder.hxx>
9 #include <BRepBuilderAPI_MakeEdge.hxx>
10 #include <BRepBuilderAPI_MakeWire.hxx>
11 #include <BRepBuilderAPI_MakeFace.hxx>
12
13 #include <TDataStd_RealArray.hxx>
14
15 #include <TopoDS.hxx>
16 #include <TopoDS_Wire.hxx>
17 #include <TopoDS_Shell.hxx>
18 #include <TopoDS_Face.hxx>
19 #include <TopoDS_Edge.hxx>
20 #include <TopoDS_Vertex.hxx>
21 #include <TopExp.hxx>
22 #include <TopExp_Explorer.hxx>
23 #include <BRepProj_Projection.hxx>
24 #include <BRepExtrema_ExtCC.hxx>
25 #include <gp_Ax1.hxx>
26 #include <gp_Ax2.hxx>
27 #include <gp_Ax3.hxx>
28 #include <gp_Vec.hxx>
29 #include <gp_Pnt.hxx>
30 #include <gp_Pln.hxx>
31 #include <gp.hxx>
32 #include <Bnd_Box.hxx>
33 #include <BRepBndLib.hxx>
34 #include <TColStd_Array1OfReal.hxx>
35 #include <Precision.hxx>
36 #include <QStringList>
37
38 #include <NCollection_DataMap.hxx>
39 typedef NCollection_DataMap<Standard_Real, Handle(HYDROData_Profile)> HYDROData_DataMapOfRealOfHDProfile;
40 #include <TColStd_ListOfReal.hxx>
41 #include <TColStd_ListIteratorOfListOfReal.hxx>
42 #include <TCollection_CompareOfReal.hxx>
43 #include <SortTools_QuickSortOfReal.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TColgp_HArray1OfPnt.hxx>
46 #include <GeomAPI_Interpolate.hxx>
47 #include <Geom_BSplineCurve.hxx>
48 #include <TopTools_Array1OfShape.hxx>
49 #include <BRepCheck_Analyzer.hxx>
50
51 //#define DEB_STREAM 1
52 #ifdef DEB_STREAM
53 //#define DEB_HASINT 1
54 //#define DEB_UPDATE 1
55 #include <BRepTools.hxx>
56 #include <TCollection_AsciiString.hxx>
57 #endif
58
59 #define PYTHON_STREAM_ID "KIND_STREAM"
60
61 IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject)
62 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
63
64
65 HYDROData_Stream::HYDROData_Stream()
66 : HYDROData_NaturalObject()
67 {
68 }
69
70 HYDROData_Stream::~HYDROData_Stream()
71 {
72 }
73
74 QStringList HYDROData_Stream::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
75 {
76   QStringList aResList;
77
78   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
79   if ( aDocument.IsNull() )
80     return aResList;
81
82   QString aDocName = aDocument->GetDocPyName();
83   QString aStreamName = GetName();
84
85   aResList << QString( "%1 = %2.CreateObject( %3 );" )
86               .arg( aStreamName ).arg( aDocName ).arg( PYTHON_STREAM_ID );
87   aResList << QString( "%1.SetName( \"%2\" );" )
88               .arg( aStreamName ).arg( aStreamName );
89   aResList << QString( "" );
90
91   // TODO
92
93   return aResList;
94 }
95
96 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
97 {
98   HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
99
100   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
101   if ( !aHydAxis.IsNull() )
102     aResSeq.Append( aHydAxis );
103
104   HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
105   aResSeq.Append( aSeqOfProfiles );
106
107   return aResSeq;
108 }
109
110 TopoDS_Shape HYDROData_Stream::GetTopShape() const
111 {
112   return getTopShape();
113 }
114 TopoDS_Shape HYDROData_Stream::GetShape3D() const
115 {
116   return getShape3D();
117 }
118  Handle(Geom_BSplineCurve) HYDROData_Stream::buildInterpolationCurve(const   Handle(TColgp_HArray1OfPnt)& theArrayOfPnt)
119 {
120   Handle(Geom_BSplineCurve) aBSpline;
121   GeomAPI_Interpolate anInterpolator (theArrayOfPnt, Standard_False, 1.0e-5); 
122   anInterpolator.Perform() ;
123   if (anInterpolator.IsDone()) 
124         aBSpline = anInterpolator.Curve();
125   return aBSpline; 
126 }
127 void HYDROData_Stream::Update()
128 {
129   HYDROData_NaturalObject::Update();
130
131   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
132   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
133   if ( aHydAxis.IsNull() || aRefProfiles.IsEmpty() )
134     return; 
135  
136   bool anIsFirst = true;
137   gp_Pnt aPrevFirstPoint, aPrevLastPoint;
138   Handle(TColgp_HArray1OfPnt) anArrayOfFPnt    = new TColgp_HArray1OfPnt(1, aRefProfiles.Length());
139   Handle(TColgp_HArray1OfPnt) anArrayOfLPnt    = new TColgp_HArray1OfPnt(1, aRefProfiles.Length());  
140   TopTools_Array1OfShape anArrOfProfiles(1, aRefProfiles.Length());
141   TopTools_Array1OfShape anArrOf2DProfiles(1, aRefProfiles.Length());
142
143   // Pre-processing
144   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
145   for (int i=1 ; anIter.More(); anIter.Next(),i++ )
146   {
147     Handle(HYDROData_Profile) aProfile =
148       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
149     if ( aProfile.IsNull() )
150       continue; 
151         const TopoDS_Shape& aProf3d = aProfile->GetShape3D();
152     gp_XY aPnt1, aPnt2;
153     if ( !aProfile->GetFirstPoint( aPnt1 ) || !aProfile->GetLastPoint( aPnt2 ) )
154       continue;
155         anArrOfProfiles.SetValue(i,aProfile->GetShape3D());//aProfile->GetTopShape();
156         anArrOf2DProfiles.SetValue(i,aProfile->GetTopShape());
157
158     gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 ), aCurFP;
159     gp_Pnt aCurLastPoint(  aPnt2.X(), aPnt2.Y(), 0 ), aCurLP;
160         TopoDS_Vertex aV1, aV2;
161         TopExp::Vertices(TopoDS::Wire(aProf3d), aV1, aV2);
162         gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
163         if(aP1.X() == aPnt1.X() && aP1.Y() == aPnt1.Y())
164           aCurFP = aP1;
165         else
166           aCurLP = aP1;
167         aP1 = BRep_Tool::Pnt(aV2);
168         if(aP1.X() == aPnt2.X() && aP1.Y() == aPnt2.Y())
169           aCurLP = aP1;
170         else
171           aCurFP = aP1;
172         anArrayOfFPnt->SetValue(i,aCurFP);
173         anArrayOfLPnt->SetValue(i,aCurLP);
174   }
175
176
177   // Construct of the 3D presentation
178   Handle(Geom_BSplineCurve) aBSpline = buildInterpolationCurve (anArrayOfFPnt);
179   if(aBSpline.IsNull())
180           return;
181   TopoDS_Edge anEdgLeft, anEdgRight;
182   BRepBuilderAPI_MakeEdge aMakeEdge(aBSpline);
183   if(aMakeEdge.IsDone()) 
184           anEdgLeft = aMakeEdge.Edge();
185   if(anEdgLeft.IsNull())
186           return;
187   aBSpline.Nullify();
188   aBSpline = buildInterpolationCurve (anArrayOfLPnt);  
189   if(aBSpline.IsNull())
190     return; 
191   aMakeEdge.Init(aBSpline);
192   if(aMakeEdge.IsDone()) 
193           anEdgRight = aMakeEdge.Edge();
194   if(anEdgRight.IsNull())
195           return;
196   BRep_Builder aBB;
197   TopoDS_Compound aCmp;
198   aBB.MakeCompound(aCmp);
199   anIter.Init( aRefProfiles );
200   for (int i=1 ; i < anArrOfProfiles.Length() +1; i++ )  
201     aBB.Add(aCmp, anArrOfProfiles.Value(i));
202   aBB.Add(aCmp,anEdgLeft);
203   aBB.Add(aCmp,anEdgRight);
204   BRepCheck_Analyzer aCh(aCmp);
205   if(aCh.IsValid())
206     SetShape3D(aCmp);
207 #ifdef DEB_UPDATE
208   else {
209     BRepTools::Write(aCmp, "str3d.brep");
210         SetShape3D(aCmp);
211   }
212 #endif
213
214   // Construct the top presentation
215   for(int i=1;i<= anArrayOfLPnt->Length();i++) {
216           gp_Pnt aPnt = anArrayOfFPnt->Value(i);
217           aPnt.SetZ(.0); // make 2d
218           anArrayOfFPnt->SetValue(i, aPnt);
219       aPnt = anArrayOfLPnt->Value(i);
220           aPnt.SetZ(.0);
221           anArrayOfLPnt->SetValue(i, aPnt);
222   }
223   aBSpline.Nullify();
224   aBSpline = buildInterpolationCurve (anArrayOfFPnt);  
225   if(aBSpline.IsNull())
226     return; 
227   aMakeEdge.Init(aBSpline);
228   if(aMakeEdge.IsDone()) 
229           anEdgLeft = aMakeEdge.Edge();
230   aBSpline.Nullify();
231   aBSpline = buildInterpolationCurve (anArrayOfLPnt);  
232   if(aBSpline.IsNull())
233     return; 
234   aMakeEdge.Init(aBSpline);
235   if(aMakeEdge.IsDone()) 
236           anEdgRight = aMakeEdge.Edge();
237   if(anEdgRight.IsNull())
238           return;
239   BRepBuilderAPI_MakeEdge aMakeEdge2(anArrayOfFPnt->Value(1),anArrayOfLPnt->Value(1));
240   TopoDS_Edge aBotEdge, aTopEdge;
241   if(aMakeEdge2.IsDone()) 
242           aBotEdge = aMakeEdge2.Edge();
243   BRepBuilderAPI_MakeEdge aMakeEdge3(anArrayOfFPnt->Value(anArrayOfFPnt->Length()),anArrayOfLPnt->Value(anArrayOfLPnt->Length()));
244   if(aMakeEdge3.IsDone()) 
245           aTopEdge = aMakeEdge3.Edge();
246
247   BRepBuilderAPI_MakeWire aMakeWire( aBotEdge, anEdgLeft, aTopEdge,anEdgRight);
248   TopoDS_Wire aSectProfileWire;
249   if(aMakeWire.IsDone())
250   aSectProfileWire = aMakeWire.Wire();
251   BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
252   TopoDS_Face aFace;
253   aMakeFace.Build();
254   if( aMakeFace.IsDone() )
255         aFace = aMakeFace.Face();
256   aCmp.Nullify();
257   aBB.MakeCompound(aCmp);
258   aBB.Add(aCmp,aFace);
259   for(int i=1;i <= anArrOf2DProfiles.Length(); i++)
260           aBB.Add(aCmp,anArrOf2DProfiles.Value(i));
261    aCh.Init(aCmp);
262    if(aCh.IsValid())
263     SetTopShape(aCmp);
264 #ifdef DEB_UPDATE
265   else {
266     BRepTools::Write(aCmp, "str2d.brep");
267         SetTopShape(aCmp);
268   }
269 #endif 
270
271 }
272
273 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
274 {
275   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
276
277   if ( theAxis.IsNull() )
278   {
279     RemoveHydraulicAxis();
280     return !aPrevAxis.IsNull();
281   }
282
283   if ( IsEqual( aPrevAxis, theAxis ) )
284     return false;
285
286   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theAxis->GetShape() );
287   if ( aHydraulicWire.IsNull() )
288     return false; // The polyline must be a single wire
289
290   SetReferenceObject( theAxis, DataTag_HydraulicAxis );
291
292   // Update the order of profiles
293   updateProfilesOrder();
294
295   // Indicate model of the need to update the stream presentation
296   SetToUpdate( true );
297
298   return true;
299 }
300
301 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
302 {
303   return Handle(HYDROData_PolylineXY)::DownCast( 
304            GetReferenceObject( DataTag_HydraulicAxis ) );
305 }
306
307 void HYDROData_Stream::RemoveHydraulicAxis()
308 {
309   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
310   if ( aPrevAxis.IsNull() )
311     return;
312
313   ClearReferenceObjects( DataTag_HydraulicAxis );
314
315   // We remove the reference profiles
316   RemoveProfiles();
317
318   // Indicate model of the need to update the stream presentation
319   SetToUpdate( true );
320 }
321
322 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile, const TopoDS_Face& thePlane,
323                                                                            Standard_Real& outPar ) const
324 {
325   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
326   if ( theProfile.IsNull() || aHydAxis.IsNull() )
327     return false; 
328
329   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); //guide line
330   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
331   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
332     return false;
333
334   BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
335   if(!aProjector.IsDone())
336     return false;
337   TopoDS_Shape aPrjProfile = aProjector.Shape();
338   if(aPrjProfile.IsNull())
339     return false;
340   TopoDS_Vertex aV1, aV2;
341   if(aPrjProfile.ShapeType() == TopAbs_EDGE)
342           TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);          
343   else if(aPrjProfile.ShapeType() == TopAbs_WIRE)  
344           TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);          
345   else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
346     TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
347         if(anExp.More()) {
348                 TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);        
349         } else {
350           anExp.Init(aPrjProfile, TopAbs_EDGE);
351           if(anExp.More()) {
352                 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);        
353           }
354         }
355   }
356   if(aV1.IsNull() || aV2.IsNull())
357         return false;
358   gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
359   gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
360   aPnt1.SetZ(0.0);
361   aPnt2.SetZ(0.0);
362   BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2); 
363   if(!aMk.IsDone())
364     return false;
365   const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
366   Standard_Integer aNum(0);
367   
368   TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
369   for(;anExplo.More();anExplo.Next()) aNum++;
370   // check for self-intersection
371   const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
372   Standard_Boolean hasInt(false);
373   Standard_Real aSqDist(DBL_MAX);
374   Standard_Integer anIndx(0);
375   BRepExtrema_ExtCC aCC;
376   aCC.Initialize(anEdg2);
377   outPar = 0.0;
378   anExplo.Init(aHydraulicWire, TopAbs_EDGE);
379   for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
380         const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
381         if(anEdg1.IsNull())
382           continue;     
383         Standard_Boolean hasSol(false);
384         aCC.Perform(anEdg1);
385     if(aCC.IsDone()) {
386         // find minimal dist
387     for(Standard_Integer i=1; i<= aCC.NbExt();i++)
388       if(aCC.SquareDistance(i) < aSqDist) {
389         aSqDist = aCC.SquareDistance(i);
390         anIndx = i;
391                 hasSol = true;          
392           }  
393         }
394         if(hasSol) {   
395                 if(aSqDist <= SquareTolerance) { // hasInt
396         const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
397         if(aNum > 1) {
398           TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
399                   outPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
400             } else {
401           Standard_Real aPar = aCC.ParameterOnE1(anIndx);
402                   outPar = aPar;
403             }
404                 hasInt = true;
405             break;
406                 } else {
407                   // no ints-n
408         if(aNum > 1) {
409           TopExp::Vertices(anEdg1, aV1, aV2);
410               outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
411             }
412           }
413         } else if(aNum > 1) {
414           TopExp::Vertices(anEdg1, aV1, aV2);
415               outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
416         }
417   }
418   if(hasInt)
419     return true;
420   return false;
421 }
422
423
424 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
425 {
426   if ( theProfile.IsNull() )
427     return false;
428
429   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
430   if ( aHydAxis.IsNull() )
431     return false;
432
433   TopoDS_Face aPlane;
434   if(!BuildFace(aHydAxis, aPlane))
435     return false;
436
437   Standard_Real aPar(.0);
438   if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
439     return false; // Object is already in reference list or it has no intersection
440   
441   int aProfileIndex = insertParameter( aPar );
442   insertProfileInToOrder( theProfile, aProfileIndex );
443   
444   // Indicate model of the need to update the stream presentation
445   SetToUpdate( true );
446
447   return true;
448 }
449
450 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
451 {
452   return GetReferenceObjects( DataTag_Profile );
453 }
454
455 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
456 {
457   if ( theProfile.IsNull() )
458     return false;
459
460   int aProfileIndex = -1;
461
462   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
463   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
464   for ( int i = 0 ; anIter.More(); anIter.Next(), ++i )
465   {
466     Handle(HYDROData_Profile) aProfile =
467       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
468     if ( aProfile.IsNull() )
469       continue;
470
471     if ( IsEqual( theProfile, aProfile ) )
472     {
473       aProfileIndex = i;
474       break;
475     }
476   }
477
478   if ( aProfileIndex == -1 )
479     return false;
480
481   RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
482
483   // Remove parameter for removed profile
484   removeParameter( aProfileIndex );
485
486   // Indicate model of the need to update the stream presentation
487   SetToUpdate( true );
488
489   return true;
490 }
491
492 void HYDROData_Stream::RemoveProfiles()
493 {
494   bool anIsToUpdate = IsMustBeUpdated() || NbReferenceObjects( DataTag_Profile ) > 0;
495
496   ClearReferenceObjects( DataTag_Profile );
497
498   // Remove the parameters array
499   removeParametersArray();
500
501   // Indicate model of the need to update the stream presentation
502   SetToUpdate( anIsToUpdate );
503 }
504
505 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile,
506                                                const int                        theBeforeIndex )
507 {
508   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
509   if ( theProfile.IsNull() || aHydAxis.IsNull() )
510     return; 
511
512   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
513   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
514   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
515     return;
516
517   if ( theBeforeIndex == -1 )
518     AddReferenceObject( theProfile, DataTag_Profile );
519   else
520     InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex );
521 }
522
523 bool HYDROData_Stream::BuildFace( const Handle(HYDROData_PolylineXY)& theHydAxis, TopoDS_Face& thePlane) const
524 {
525   if ( theHydAxis.IsNull() ) return false;
526   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() );
527   if(aHydraulicWire.IsNull()) return false;
528   gp_Ax2 aX2(gp::XOY());
529   gp_Ax3 aX3(aX2);
530   gp_Pln aPln(aX3);   
531   Bnd_Box B;
532   BRepBndLib::Add(aHydraulicWire,B);
533   Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
534   B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
535   BRepBuilderAPI_MakeFace aMkr(aPln, axmin-500., axmax+500., aymin-500., aymax+500.); // to be tuned later according max/ Profile deviation
536   if(!aMkr.IsDone() || aMkr.Shape().IsNull()) return false;
537   thePlane = TopoDS::Face(aMkr.Shape());
538   return true;
539 }
540
541 void HYDROData_Stream::updateProfilesOrder()
542 {
543   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
544   if ( aRefProfiles.IsEmpty() )
545     return;
546
547   // At first we remove all profiles from order
548   RemoveProfiles();
549
550   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
551   if ( aHydAxis.IsNull() )
552     return; 
553
554   TopoDS_Face aPlane;
555   if ( !BuildFace( aHydAxis, aPlane ) )
556     return;
557
558   Standard_Real aPar( .0 );
559
560 #ifdef DEB_HASINT
561   BRep_Builder aBB;
562   TopoDS_Compound aCmp;
563   aBB.MakeCompound(aCmp);
564 #endif
565
566   HYDROData_DataMapOfRealOfHDProfile aDM;  
567   TColStd_ListOfReal aList;
568   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
569   for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
570   {
571     Handle(HYDROData_Profile) aProfile =
572       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
573 #ifdef DEB_HASINT
574   TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
575   aBB.Add( aCmp, aProfileWire ); 
576 #endif
577     if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
578       continue;
579         
580     aDM.Bind( aPar, aProfile );
581           aList.Append( aPar );
582   }
583   
584   if ( aList.IsEmpty() )
585     return;
586
587   TColStd_Array1OfReal anArr( 1, aList.Extent() );
588
589   TColStd_ListIteratorOfListOfReal it( aList );
590   for ( int j = 1; it.More(); it.Next(), j++ )
591     anArr( j ) = it.Value();
592
593   // sorting
594   if ( aList.Extent() > 1 )
595   {
596     TCollection_CompareOfReal Compar;
597     SortTools_QuickSortOfReal::Sort( anArr, Compar );
598
599     for (int j = 1; j <= anArr.Length(); j++) {
600       const Standard_Real aKey =  anArr(j);
601       const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
602       insertProfileInToOrder( aProfile );
603     }
604   } else if ( aList.Extent() == 1 ) {
605      const Standard_Real aKey = aList.Last();
606      const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
607      insertProfileInToOrder( aProfile );
608   } 
609
610   setParametersArray( anArr );
611
612 #ifdef DEB_HASINT
613   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
614   BRepTools::Write(aHydraulicWire, "Path.brep");
615   BRepTools::Write(aCmp, "Prof.brep");
616 #endif
617 }
618
619 void HYDROData_Stream::setParametersArray( const TColStd_Array1OfReal& theArray )
620 {
621   if ( theArray.Length() == 0 )
622   {
623     removeParametersArray();
624     return;
625   }
626
627   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray );
628   
629   Handle(TDataStd_RealArray) aParamsArray = 
630     TDataStd_RealArray::Set( aLabel, theArray.Lower(), theArray.Upper() );
631
632   for ( int i = theArray.Lower(), n = theArray.Upper(); i <= n; ++i )
633   {
634     const Standard_Real& aParam = theArray( i );
635     aParamsArray->SetValue( i, aParam );
636   }
637 }
638
639 TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const
640 {
641   TColStd_Array1OfReal* anArray = NULL;
642
643   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
644   if ( !aLabel.IsNull() )
645   {
646     Handle(TDataStd_RealArray) aParamsArray;
647     if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
648     {
649       anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() );
650       for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i )
651       {
652         const Standard_Real& aParam = aParamsArray->Value( i );
653         anArray->SetValue( i, aParam );
654       }
655     }
656   }
657
658   return anArray;
659 }
660
661 void HYDROData_Stream::removeParametersArray()
662 {
663   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
664   if ( !aLabel.IsNull() )
665     aLabel.ForgetAllAttributes();
666 }
667
668 int HYDROData_Stream::insertParameter( const Standard_Real& theParam )
669 {
670   int aResIndex = -1;
671
672   TColStd_Array1OfReal* anArr = getParametersArray();
673   if ( anArr )
674   {
675     aResIndex = 0;
676
677     TColStd_Array1OfReal aNewArr( anArr->Lower(), anArr->Upper() + 1 );
678
679     bool isInserted = false;
680     for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j )
681     {
682       const Standard_Real& aStoredParam = anArr->Value( i );
683       if ( !isInserted )
684       {
685         if ( theParam > aStoredParam )
686         {
687           aResIndex++;
688         }
689         else
690         {
691           aNewArr( j ) = theParam;
692           isInserted = true;
693           ++j;
694         }
695       }
696
697       aNewArr( j ) = aStoredParam;
698     }
699
700     if ( !isInserted )
701     {
702       aResIndex = -1;
703       aNewArr( aNewArr.Upper() ) = theParam;
704     }
705     
706     setParametersArray( aNewArr );
707     delete anArr;
708   }
709   else
710   {
711     TColStd_Array1OfReal aNewArr( 1, 1 );
712     aNewArr.SetValue( 1, theParam );
713     setParametersArray( aNewArr );
714   }
715
716   return aResIndex;
717 }
718
719 void HYDROData_Stream::removeParameter( const int& theIndex )
720 {
721   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
722   if ( aLabel.IsNull() )
723     return;
724
725   Handle(TDataStd_RealArray) aParamsArray;
726   if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
727     return;
728
729   TColStd_Array1OfReal aNewArr( aParamsArray->Lower(), aParamsArray->Upper() - 1 );
730
731   for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k )
732   {
733     const Standard_Real& aStoredParam = aParamsArray->Value( i );
734     if ( k == theIndex )
735       continue;
736
737     aNewArr.SetValue( j, aStoredParam );
738     ++j;
739   }
740
741   setParametersArray( aNewArr );
742 }