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