Salome HOME
1d76a26aaf8755d38ebd5d5941e309423a29980e
[modules/hydro.git] / src / HYDROData / HYDROData_Stream.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_Stream.h"
20
21 #include "HYDROData_Document.h"
22 #include "HYDROData_PolylineXY.h"
23 #include "HYDROData_Polyline3D.h"
24 #include "HYDROData_Profile.h"
25 #include "HYDROData_ShapesGroup.h"
26 #include "HYDROData_ShapesTool.h"
27 #include "HYDROData_IAltitudeObject.h"
28 #include "HYDROData_IProfilesInterpolator.h"
29 #include "HYDROData_Tool.h"
30 #include "HYDROData_DTM.h"
31
32 #include <TDataStd_RealArray.hxx>
33
34 #include <Precision.hxx>
35
36 #include <NCollection_DataMap.hxx>
37
38 #include <TColStd_Array1OfReal.hxx>
39 #include <TColStd_ListOfReal.hxx>
40 #include <TColStd_ListIteratorOfListOfReal.hxx>
41 #include <TCollection_CompareOfReal.hxx>
42 #include <TColgp_Array1OfPnt.hxx>
43 #include <TColgp_HArray1OfPnt.hxx>
44
45 #include <TopoDS.hxx>
46 #include <TopoDS_Wire.hxx>
47 #include <TopoDS_Shell.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Vertex.hxx>
51 #include <TopExp.hxx>
52 #include <TopExp_Explorer.hxx>
53
54 #include <Bnd_Box.hxx>
55
56 #include <BRep_Builder.hxx>
57 #include <BRepBuilderAPI_MakeEdge.hxx>
58 #include <BRepBuilderAPI_MakeWire.hxx>
59 #include <BRepBuilderAPI_MakeFace.hxx>
60
61 #include <BRepBndLib.hxx>
62 #include <BRepProj_Projection.hxx>
63 #include <BRepExtrema_ExtCC.hxx>
64 #include <BRepCheck_Analyzer.hxx>
65
66 #include <gp.hxx>
67 #include <gp_Ax1.hxx>
68 #include <gp_Ax2.hxx>
69 #include <gp_Ax3.hxx>
70 #include <gp_Vec.hxx>
71 #include <gp_Pnt.hxx>
72 #include <gp_Pln.hxx>
73
74 #include <GeomAPI_Interpolate.hxx>
75 #include <Geom_BSplineCurve.hxx>
76
77 #include <TopTools_HArray1OfShape.hxx>
78
79 #include <SortTools_QuickSortOfReal.hxx>
80
81 #include <QColor>
82 #include <QStringList>
83
84 //#define DEB_STREAM 1
85 #ifdef DEB_STREAM
86 //#define DEB_HASINT 1
87 //#define DEB_UPDATE 1
88 #include <BRepTools.hxx>
89 #include <TCollection_AsciiString.hxx>
90 #endif
91
92 typedef NCollection_DataMap<Standard_Real, Handle(HYDROData_Profile)> HYDROData_DataMapOfRealOfHDProfile;
93
94 IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject)
95 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
96
97
98 HYDROData_Stream::HYDROData_Stream()
99 : HYDROData_NaturalObject( Geom_3d )
100 {
101 }
102
103 HYDROData_Stream::~HYDROData_Stream()
104 {
105 }
106
107 QStringList HYDROData_Stream::DumpToPython( const QString&       thePyScriptPath,
108                                             MapOfTreatedObjects& theTreatedObjects ) const
109 {
110   QStringList aResList = dumpObjectCreation( theTreatedObjects );
111   QString aName = GetObjPyName();
112
113   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
114   setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aHydAxis, "SetHydraulicAxis" );
115
116   HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
117   for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; ++i )
118   {
119     const Handle(HYDROData_Entity) aProfile = aSeqOfProfiles.Value( i );
120     setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aProfile, "AddProfile" );
121   }
122
123   // Set bottom polyline if exists
124   const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
125   if ( !aBottomPolyline.IsNull() ) {
126     setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aBottomPolyline, "SetBottomPolyline" );
127   }
128
129   QString aDDZs = QString::number( GetDDZ(), 'f', 3 );
130   QString aSSteps = QString::number( GetSpatialStep(), 'f', 3 );
131   aResList << QString( "%1.SetDDZ( %2 )" ).arg( aName ).arg( aDDZs );
132   aResList << QString( "%1.SetSpatialStep( %2 )" ).arg( aName ).arg( aSSteps );
133
134   aResList << QString( "" );
135   aResList << QString( "%1.Update()" ).arg( aName );
136   aResList << QString( "" );
137
138   return aResList;
139 }
140
141 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
142 {
143   HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
144
145   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
146   if ( !aHydAxis.IsNull() )
147     aResSeq.Append( aHydAxis );
148
149   HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
150   aResSeq.Append( aSeqOfProfiles );
151
152   return aResSeq;
153 }
154
155 Handle(Geom_BSplineCurve) HYDROData_Stream::buildInterpolationCurve( 
156   const Handle(TColgp_HArray1OfPnt)& theArrayOfPnt )
157 {
158   Handle(Geom_BSplineCurve) aBSpline;
159   GeomAPI_Interpolate anInterpolator (theArrayOfPnt, Standard_False, 1.0e-5); 
160   anInterpolator.Perform() ;
161   if (anInterpolator.IsDone()) 
162     aBSpline = anInterpolator.Curve();
163   return aBSpline; 
164 }
165
166 void HYDROData_Stream::Update()
167 {
168   updateProfilesOrder();
169
170   // Update bottom polyline if exists
171   const Handle(HYDROData_Polyline3D) aBottomPolyline = GetBottomPolyline();
172   if ( !aBottomPolyline.IsNull() ) {
173     if ( GenerateBottomPolyline() ) {
174       Handle(HYDROData_PolylineXY) aPolylineXY = aBottomPolyline->GetPolylineXY();
175       if ( !aPolylineXY.IsNull() ) {
176         aPolylineXY->Update();
177       }
178       aBottomPolyline->Update();
179     }
180   }
181
182   Handle_HYDROData_DTM dtm = DTM();
183   dtm->Update();
184   UpdatePrs( dtm );
185 }
186
187 bool HYDROData_Stream::IsHas2dPrs() const
188 {
189   return true;
190 }
191
192 bool HYDROData_Stream::CreatePresentations( const Handle_HYDROData_DTM& theDTM,
193                                             PrsDefinition&              thePrs )
194 {
195   if ( theDTM.IsNull() )
196     return false;
197
198   HYDROData_SequenceOfObjects profiles = theDTM->GetProfiles();
199   if( profiles.Length() < 2 )
200     return false;
201
202   TopTools_ListOfShape profiles3d;
203
204   // Pre-processing
205   HYDROData_SequenceOfObjects::Iterator anIter( profiles );
206   for (int i=1 ; anIter.More(); anIter.Next(),i++ )
207   {
208     Handle(HYDROData_Profile) aProfile =
209       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
210
211     if ( aProfile.IsNull() )
212       continue;
213
214     const TopoDS_Shape& aProfileShape = aProfile->GetShape3D();
215     profiles3d.Append( aProfileShape );
216   }
217
218   TopoDS_Edge aLeftBank, aRightBank;
219   theDTM->CreateBankShapes( aLeftBank, aRightBank );
220   return CreatePresentations( aLeftBank, aRightBank, profiles3d, thePrs );
221 }
222
223 void HYDROData_Stream::UpdatePrs( const Handle_HYDROData_DTM& theDTM )
224 {
225   HYDROData_NaturalObject::Update();
226   
227   PrsDefinition aResultPrs;
228   if ( !CreatePresentations( theDTM, aResultPrs ) )
229     return;
230
231   SetShape3D( aResultPrs.myPrs3D );
232   SetTopShape( aResultPrs.myPrs2D );
233
234   // Create the stream groups
235   QString aLeftGroupName = GetName() + "_Left_Bank";
236
237   Handle(HYDROData_ShapesGroup) aLeftGroup = createGroupObject();
238   aLeftGroup->SetName( aLeftGroupName );
239   aLeftGroup->AddShape( aResultPrs.myLeftBank );
240
241   QString aRightGroupName = GetName() + "_Right_Bank";
242
243   Handle(HYDROData_ShapesGroup) aRightGroup = createGroupObject();
244   aRightGroup->SetName( aRightGroupName );
245   aRightGroup->AddShape( aResultPrs.myRightBank );
246
247   QString anInGroupName = GetName() + "_Inlet";
248
249   Handle(HYDROData_ShapesGroup) anInGroup = createGroupObject();
250   anInGroup->SetName( anInGroupName );
251   anInGroup->AddShape( aResultPrs.myInlet );
252
253   QString anOutGroupName = GetName() + "_Outlet";
254   
255   Handle(HYDROData_ShapesGroup) anOutGroup = createGroupObject();
256   anOutGroup->SetName( anOutGroupName );
257   anOutGroup->AddShape( aResultPrs.myOutlet );
258 }
259
260 QColor HYDROData_Stream::DefaultFillingColor() const
261 {
262   return QColor( Qt::green );
263 }
264
265 QColor HYDROData_Stream::DefaultBorderColor() const
266 {
267   return QColor( Qt::transparent );
268 }
269
270 bool HYDROData_Stream::IsValidAsAxis( const Handle(HYDROData_PolylineXY)& theHydAxis )
271 {
272   if ( theHydAxis.IsNull() )
273     return false;
274
275   TopoDS_Shape aHydraulicShape = theHydAxis->GetShape();
276   if ( aHydraulicShape.IsNull() || 
277        aHydraulicShape.ShapeType() != TopAbs_WIRE ||
278        BRep_Tool::IsClosed( aHydraulicShape ) )
279     return false; // The polyline must be a single not closed wire
280
281   return true;
282 }
283
284 TopoDS_Shape HYDROData_Stream::GetLeftShape() const
285 {
286   HYDROData_SequenceOfObjects aGroups = GetGroups();
287   return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 1);
288 }
289
290 TopoDS_Shape HYDROData_Stream::GetRightShape() const
291 {
292   HYDROData_SequenceOfObjects aGroups = GetGroups();
293   return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 2);
294 }
295
296 TopoDS_Shape HYDROData_Stream::GetInletShape() const
297 {
298   HYDROData_SequenceOfObjects aGroups = GetGroups();
299   return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 3);
300 }
301
302 TopoDS_Shape HYDROData_Stream::GetOutletShape() const
303 {
304   HYDROData_SequenceOfObjects aGroups = GetGroups();
305   return HYDROData_Tool::getFirstShapeFromGroup( aGroups, 4);
306 }
307
308 Handle_HYDROData_DTM HYDROData_Stream::DTM() const
309 {
310   const_cast<HYDROData_Stream*>( this )->checkAndSetAltitudeObject();
311   return Handle(HYDROData_DTM)::DownCast( GetAltitudeObject() );
312 }
313
314 double HYDROData_Stream::GetDDZ() const
315 {
316   return DTM()->GetDDZ();
317 }
318
319 void HYDROData_Stream::SetDDZ( double theDDZ )
320 {
321   DTM()->SetDDZ( theDDZ );
322 }
323   
324 double HYDROData_Stream::GetSpatialStep() const
325 {
326   return DTM()->GetSpatialStep();
327 }
328
329 void HYDROData_Stream::SetSpatialStep( double theSpatialStep )
330 {
331   DTM()->SetSpatialStep( theSpatialStep );
332 }
333
334 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
335 {
336   if ( !IsValidAsAxis( theAxis ) )
337     return false;
338
339   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
340   if ( IsEqual( aPrevAxis, theAxis ) )
341     return true;
342
343   SetReferenceObject( theAxis, DataTag_HydraulicAxis );
344
345   // Update the order of profiles
346   updateProfilesOrder();
347
348   // Indicate model of the need to update the stream presentation
349   Changed( Geom_3d );
350
351   return true;
352 }
353
354 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
355 {
356   return Handle(HYDROData_PolylineXY)::DownCast( 
357            GetReferenceObject( DataTag_HydraulicAxis ) );
358 }
359
360 void HYDROData_Stream::RemoveHydraulicAxis()
361 {
362   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
363   if ( aPrevAxis.IsNull() )
364     return;
365
366   ClearReferenceObjects( DataTag_HydraulicAxis );
367
368   // We remove the reference profiles
369   RemoveProfiles();
370
371   // Indicate model of the need to update the stream presentation
372   Changed( Geom_3d );
373 }
374
375 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile,
376                                         const TopoDS_Face&               thePlane,
377                                         Standard_Real&                   theOutPar ) const
378 {
379   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
380   return HasIntersection( aHydAxis, theProfile, thePlane, theOutPar );
381 }
382
383 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_PolylineXY)& theHydAxis, 
384                                         const Handle(HYDROData_Profile)&    theProfile, 
385                                         const TopoDS_Face&                  thePlane,
386                                         Standard_Real&                      theOutPar )
387 {
388   if ( theProfile.IsNull() || !IsValidAsAxis( theHydAxis ) )
389     return false; 
390
391   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() ); //guide line
392   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
393   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
394     return false;
395
396   BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
397   if(!aProjector.IsDone())
398     return false;
399   TopoDS_Shape aPrjProfile = aProjector.Shape();
400   if(aPrjProfile.IsNull())
401     return false;
402   TopoDS_Vertex aV1, aV2;
403   if(aPrjProfile.ShapeType() == TopAbs_EDGE)
404     TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
405   else if(aPrjProfile.ShapeType() == TopAbs_WIRE)  
406     TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
407   else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
408     TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
409     if(anExp.More()) {
410       TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
411     } else {
412       anExp.Init(aPrjProfile, TopAbs_EDGE);
413       if(anExp.More()) {
414         TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
415       }
416     }
417   }
418   if(aV1.IsNull() || aV2.IsNull())
419     return false;
420   gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
421   gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
422   aPnt1.SetZ(0.0);
423   aPnt2.SetZ(0.0);
424   BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2); 
425   if(!aMk.IsDone())
426     return false;
427   const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
428   Standard_Integer aNum(0);
429   
430   TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
431   for(;anExplo.More();anExplo.Next()) aNum++;
432   // check for self-intersection
433   const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
434   Standard_Boolean hasInt(false);
435   Standard_Real aSqDist(DBL_MAX);
436   Standard_Integer anIndx(0);
437   BRepExtrema_ExtCC aCC;
438   aCC.Initialize(anEdg2);
439   theOutPar = 0.0;
440   anExplo.Init(aHydraulicWire, TopAbs_EDGE);
441   for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
442     const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
443     if(anEdg1.IsNull())
444       continue;
445     Standard_Boolean hasSol(false);
446     aCC.Perform(anEdg1);
447     if(aCC.IsDone()) {
448     // find minimal dist
449     for(Standard_Integer i=1; i<= aCC.NbExt();i++)
450       if(aCC.SquareDistance(i) < aSqDist) {
451         aSqDist = aCC.SquareDistance(i);
452         anIndx = i;
453         hasSol = true;
454       }  
455     }
456     if(hasSol) {
457       if(aSqDist <= SquareTolerance) { // hasInt
458         const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
459         if(aNum > 1) {
460           TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
461           theOutPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
462         } else {
463           Standard_Real aPar = aCC.ParameterOnE1(anIndx);
464           theOutPar = aPar;
465         }
466         hasInt = true;
467         break;
468       } else {
469           // no ints-n
470         if(aNum > 1) {
471           TopExp::Vertices(anEdg1, aV1, aV2);
472           theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
473         }
474       }
475     } else if(aNum > 1) {
476       TopExp::Vertices(anEdg1, aV1, aV2);
477       theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
478     }
479   }
480   if(hasInt)
481     return true;
482   return false;
483 }
484
485 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
486 {
487   if ( theProfile.IsNull() )
488     return false;
489
490   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
491   if ( aHydAxis.IsNull() )
492     return false;
493
494   TopoDS_Face aPlane;
495   if(!BuildFace(aHydAxis, aPlane))
496     return false;
497
498   Standard_Real aPar(.0);
499   if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) )
500     return false; // Object is already in reference list or it has no intersection
501   
502   int aProfileIndex = insertParameter( aPar );
503   insertProfileInToOrder( theProfile, aProfileIndex );
504   
505   // Indicate model of the need to update the stream presentation
506   Changed( Geom_3d );
507
508   return true;
509 }
510
511 bool HYDROData_Stream::SetProfiles( const HYDROData_SequenceOfObjects& theProfiles,
512                                     const bool&                        theIsToOrder )
513 {
514   if ( theIsToOrder )
515   {
516     for ( int i = 1; i <= theProfiles.Length(); ++i )
517     {
518       Handle(HYDROData_Profile) aProfile = 
519         Handle(HYDROData_Profile)::DownCast( theProfiles.Value( i ) );
520       if ( aProfile.IsNull() )
521         continue;
522
523       if ( !AddProfile( aProfile ) )
524       {
525         DTM()->SetProfiles( HYDROData_SequenceOfObjects() );
526         return false;
527       }
528     }
529   }
530   else // Just store the sequence of objects as is
531   {
532     bool anIsToUpdate = true;
533
534     HYDROData_SequenceOfObjects anOldProfiles = GetProfiles();
535     if ( anOldProfiles.Length() == theProfiles.Length() )
536     {
537       anIsToUpdate = false;
538
539       for ( int i = 1; i <= theProfiles.Length(); ++i )
540       {
541         Handle(HYDROData_Entity) anOldProfile = anOldProfiles.Value( i );
542         Handle(HYDROData_Entity) aNewProfile = theProfiles.Value( i );
543         if ( !IsEqual( anOldProfile, aNewProfile ) )
544         {
545           anIsToUpdate = true;
546           break;
547         }
548       }
549     }
550     
551     SetReferenceObjects( theProfiles, DataTag_Profile );
552
553     if ( anIsToUpdate )
554       Changed( Geom_3d );
555   }
556
557   DTM()->SetProfiles( GetProfiles() );
558   return true;
559 }
560
561 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
562 {
563   return GetReferenceObjects( DataTag_Profile );
564 }
565
566 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
567 {
568   if ( theProfile.IsNull() )
569     return false;
570
571   int aProfileIndex = -1;
572
573   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
574   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
575   for ( int i = 0 ; anIter.More(); anIter.Next(), ++i )
576   {
577     Handle(HYDROData_Profile) aProfile =
578       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
579     if ( aProfile.IsNull() )
580       continue;
581
582     if ( IsEqual( theProfile, aProfile ) )
583     {
584       aProfileIndex = i;
585       break;
586     }
587   }
588
589   if ( aProfileIndex == -1 )
590     return false;
591
592   RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
593
594   // Remove parameter for removed profile
595   removeParameter( aProfileIndex );
596
597   // Indicate model of the need to update the stream presentation
598   Changed( Geom_3d );
599
600   return true;
601 }
602
603 void HYDROData_Stream::RemoveProfiles()
604 {
605   ClearReferenceObjects( DataTag_Profile );
606
607   // Remove the parameters array
608   removeParametersArray();
609
610   // Indicate model of the need to update the stream presentation
611   Changed( Geom_3d );
612 }
613
614 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile,
615                                                const int                        theBeforeIndex )
616 {
617   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
618   if ( theProfile.IsNull() || aHydAxis.IsNull() )
619     return; 
620
621   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
622   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
623   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
624     return;
625
626   if ( theBeforeIndex == -1 )
627     AddReferenceObject( theProfile, DataTag_Profile );
628   else
629     InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex );
630 }
631
632 bool HYDROData_Stream::BuildFace( const Handle(HYDROData_PolylineXY)& theHydAxis,
633                                   TopoDS_Face&                        thePlane )
634 {
635   if ( !IsValidAsAxis( theHydAxis ) )
636     return false;
637
638   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() );
639
640   gp_Ax2 aX2(gp::XOY());
641   gp_Ax3 aX3(aX2);
642   gp_Pln aPln(aX3);   
643   Bnd_Box B;
644   BRepBndLib::Add(aHydraulicWire,B);
645   Standard_Real axmin,aymin,azmin,axmax,aymax,azmax;
646   B.Get(axmin,aymin,azmin,axmax,aymax,azmax);
647   BRepBuilderAPI_MakeFace aMkr(aPln, axmin-500., axmax+500., aymin-500., aymax+500.); // to be tuned later according max/ Profile deviation
648   if(!aMkr.IsDone() || aMkr.Shape().IsNull()) return false;
649   thePlane = TopoDS::Face(aMkr.Shape());
650   return true;
651 }
652
653 void HYDROData_Stream::updateProfilesOrder()
654 {
655   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
656   if ( aRefProfiles.IsEmpty() )
657     return;
658
659   // At first we remove all profiles from order
660   RemoveProfiles();
661
662   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
663   if ( aHydAxis.IsNull() )
664     return; 
665
666   TopoDS_Face aPlane;
667   if ( !BuildFace( aHydAxis, aPlane ) )
668     return;
669
670   Standard_Real aPar( .0 );
671
672 #ifdef DEB_HASINT
673   BRep_Builder aBB;
674   TopoDS_Compound aCmp;
675   aBB.MakeCompound(aCmp);
676 #endif
677
678   HYDROData_DataMapOfRealOfHDProfile aDM;  
679   TColStd_ListOfReal aList;
680   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
681   for (int i = 1 ; anIter.More(); anIter.Next(), i++ )
682   {
683     Handle(HYDROData_Profile) aProfile =
684       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
685 #ifdef DEB_HASINT
686   TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() );
687   aBB.Add( aCmp, aProfileWire ); 
688 #endif
689     if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) )
690       continue;
691     
692     aDM.Bind( aPar, aProfile );
693     aList.Append( aPar );
694   }
695   
696   if ( aList.IsEmpty() )
697     return;
698
699   TColStd_Array1OfReal anArr( 1, aList.Extent() );
700
701   TColStd_ListIteratorOfListOfReal it( aList );
702   for ( int j = 1; it.More(); it.Next(), j++ )
703     anArr( j ) = it.Value();
704
705   // sorting
706   if ( aList.Extent() > 1 )
707   {
708     TCollection_CompareOfReal Compar;
709     SortTools_QuickSortOfReal::Sort( anArr, Compar );
710
711     for (int j = 1; j <= anArr.Length(); j++) {
712       const Standard_Real aKey =  anArr(j);
713       const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
714       insertProfileInToOrder( aProfile );
715     }
716   } else if ( aList.Extent() == 1 ) {
717      const Standard_Real aKey = aList.Last();
718      const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey);
719      insertProfileInToOrder( aProfile );
720   } 
721
722   setParametersArray( anArr );
723
724 #ifdef DEB_HASINT
725   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
726   BRepTools::Write(aHydraulicWire, "Path.brep");
727   BRepTools::Write(aCmp, "Prof.brep");
728 #endif
729 }
730
731 ObjectKind HYDROData_Stream::getAltitudeObjectType() const
732 {
733   return KIND_DTM;
734 }
735
736 void HYDROData_Stream::setParametersArray( const TColStd_Array1OfReal& theArray )
737 {
738   if ( theArray.Length() == 0 )
739   {
740     removeParametersArray();
741     return;
742   }
743
744   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray );
745   
746   Handle(TDataStd_RealArray) aParamsArray = 
747     TDataStd_RealArray::Set( aLabel, theArray.Lower(), theArray.Upper() );
748
749   for ( int i = theArray.Lower(), n = theArray.Upper(); i <= n; ++i )
750   {
751     const Standard_Real& aParam = theArray( i );
752     aParamsArray->SetValue( i, aParam );
753   }
754 }
755
756 TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const
757 {
758   TColStd_Array1OfReal* anArray = NULL;
759
760   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
761   if ( !aLabel.IsNull() )
762   {
763     Handle(TDataStd_RealArray) aParamsArray;
764     if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
765     {
766       anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() );
767       for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i )
768       {
769         const Standard_Real& aParam = aParamsArray->Value( i );
770         anArray->SetValue( i, aParam );
771       }
772     }
773   }
774
775   return anArray;
776 }
777
778 void HYDROData_Stream::removeParametersArray()
779 {
780   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
781   if ( !aLabel.IsNull() )
782     aLabel.ForgetAllAttributes();
783 }
784
785 int HYDROData_Stream::insertParameter( const Standard_Real& theParam )
786 {
787   int aResIndex = -1;
788
789   TColStd_Array1OfReal* anArr = getParametersArray();
790   if ( anArr )
791   {
792     aResIndex = 0;
793
794     TColStd_Array1OfReal aNewArr( anArr->Lower(), anArr->Upper() + 1 );
795
796     bool isInserted = false;
797     for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j )
798     {
799       const Standard_Real& aStoredParam = anArr->Value( i );
800       if ( !isInserted )
801       {
802         if ( theParam > aStoredParam )
803         {
804           aResIndex++;
805         }
806         else
807         {
808           aNewArr( j ) = theParam;
809           isInserted = true;
810           ++j;
811         }
812       }
813
814       aNewArr( j ) = aStoredParam;
815     }
816
817     if ( !isInserted )
818     {
819       aResIndex = -1;
820       aNewArr( aNewArr.Upper() ) = theParam;
821     }
822     
823     setParametersArray( aNewArr );
824     delete anArr;
825   }
826   else
827   {
828     TColStd_Array1OfReal aNewArr( 1, 1 );
829     aNewArr.SetValue( 1, theParam );
830     setParametersArray( aNewArr );
831   }
832
833   return aResIndex;
834 }
835
836 void HYDROData_Stream::removeParameter( const int& theIndex )
837 {
838   TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false );
839   if ( aLabel.IsNull() )
840     return;
841
842   Handle(TDataStd_RealArray) aParamsArray;
843   if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) )
844     return;
845
846   if ( aParamsArray->Length() == 1 )
847   {
848     removeParametersArray();
849     return;
850   }
851
852   TColStd_Array1OfReal aNewArr( aParamsArray->Lower(), aParamsArray->Upper() - 1 );
853
854   for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k )
855   {
856     const Standard_Real& aStoredParam = aParamsArray->Value( i );
857     if ( k == theIndex )
858       continue;
859
860     aNewArr.SetValue( j, aStoredParam );
861     ++j;
862   }
863
864   setParametersArray( aNewArr );
865 }
866
867 bool HYDROData_Stream::GenerateBottomPolyline()
868 {
869   // Get the document
870   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
871   if ( aDocument.IsNull() ) {
872     return false;
873   }
874
875   // Collect bottom points ( one bottom point from each profile of the stream )
876   HYDROData_Profile::ProfilePoints aBottomPoints;
877   
878   HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
879   for ( int i = 1, aNb = aSeqOfProfiles.Size(); i <= aNb; i++ ) {
880     const Handle(HYDROData_Profile) aProfile = 
881       Handle(HYDROData_Profile)::DownCast( aSeqOfProfiles.Value( i ) );
882     if ( aProfile.IsNull() ) {
883       continue;
884     }
885     
886     aBottomPoints.Append( aProfile->GetBottomPoint() );
887   }
888
889   int aNbBottomPoints = aBottomPoints.Size();
890
891   if ( aNbBottomPoints < 2 ) {
892     return false;
893   }
894
895   // Create bottom polyline object if the stream doesn't contain it yet
896   Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
897   if ( aBottom.IsNull() ) {
898     aBottom = Handle(HYDROData_Polyline3D)::DownCast( aDocument->CreateObject( KIND_POLYLINE ) );  
899     QString aBaseName = GetName() + "_bottom";
900     QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
901     aBottom->SetName( aName );
902
903     SetReferenceObject( aBottom, DataTag_BottomPolyline );
904   }
905   
906   // Create 2D polyline if the bottom polyline doesn't contain it yet
907   Handle(HYDROData_PolylineXY) aPolylineXY = aBottom->GetPolylineXY();
908   if ( aPolylineXY.IsNull() ) {
909     aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( aDocument->CreateObject( KIND_POLYLINEXY ) );
910     QString aBaseName = GetName() + "_bottom_2d";
911     QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
912     aPolylineXY->SetName( aName );
913     aBottom->SetPolylineXY( aPolylineXY, false );
914   }
915
916   aPolylineXY->RemoveSections();
917   aPolylineXY->AddSection( "", HYDROData_PolylineXY::SECTION_SPLINE, false );
918   
919   // Create profile if the bottom polyline doesn't contain it yet
920   Handle(HYDROData_ProfileUZ) aProfileUZ = aBottom->GetProfileUZ();
921   if ( aProfileUZ.IsNull() ) {
922     Handle(HYDROData_Profile) aProfile = 
923       Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
924     QString aBaseName = GetName() + "_bottom_profile";
925     QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName, QStringList(), true );
926     aProfile->SetName( aName );
927     aProfileUZ = aProfile->GetProfileUZ( true );
928     aBottom->SetProfileUZ( aProfileUZ );
929   }
930   
931   aProfileUZ->RemoveSection( 0 );
932
933   aProfileUZ->CalculateAndAddPoints(aBottomPoints, aPolylineXY);
934   
935   return true;
936 }
937
938 Handle(HYDROData_Polyline3D) HYDROData_Stream::GetBottomPolyline() const
939 {
940   return Handle(HYDROData_Polyline3D)::DownCast( 
941            GetReferenceObject( DataTag_BottomPolyline ) );
942 }
943
944 bool HYDROData_Stream::SetBottomPolyline( const Handle(HYDROData_Polyline3D)& theBottom )
945 {
946   if ( theBottom.IsNull() ) {
947     return false;
948   }
949
950   SetReferenceObject( theBottom, DataTag_BottomPolyline );
951
952   return true;
953 }
954
955 bool HYDROData_Stream::Interpolate( HYDROData_IProfilesInterpolator* theInterpolator )
956 {
957   // Get the document
958   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
959   if ( aDocument.IsNull() ) {
960     return false;
961   }
962   
963   if ( theInterpolator->GetCalculatedProfilesNumber() < 1 ) {
964     theInterpolator->Calculate();
965   }
966
967   if ( theInterpolator->GetErrorCode() != OK ) {
968     return false;
969   }
970
971   bool isOK = true;
972
973   for ( int aProfileInd = 0; aProfileInd < theInterpolator->GetCalculatedProfilesNumber(); aProfileInd++ ) {
974     // Get calculated point coordinates
975     HYDROData_Profile::ProfilePoints aResultPoints = theInterpolator->GetResultProfilePoints( aProfileInd );
976     if ( aResultPoints.IsEmpty() ) {
977       isOK = false;
978       continue;
979     }
980         
981     // Create profile object
982     Handle(HYDROData_Profile) aProfile = 
983       Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
984     QString aBaseName = GetName() + "_interp_profile";
985     QString aName = HYDROData_Tool::GenerateObjectName( aDocument, aBaseName );
986     aProfile->SetName( aName );
987
988     // Fill the profile with points
989     aProfile->SetProfilePoints( aResultPoints );
990
991     // Add profile to the stream
992     bool isAdded = AddProfile( aProfile );
993     if ( !isAdded ) {
994       aProfile->Remove();
995     }
996     else
997       aProfile->Update();
998   }
999
1000   if ( isOK )
1001     Update();
1002
1003   return isOK;
1004 }
1005
1006 void HYDROData_Stream::CopyTo( const Handle(HYDROData_Entity)& theDestination,
1007                                bool isGenerateNewName ) const
1008 {
1009   // Get the document
1010   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
1011   if ( aDocument.IsNull() ) {
1012     return;
1013   }
1014
1015   // Call base method
1016   HYDROData_Entity::CopyTo( theDestination, isGenerateNewName );
1017
1018   Handle(HYDROData_Stream) aStreamCopy = 
1019     Handle(HYDROData_Stream)::DownCast( theDestination );
1020
1021   // Copy bottom polyline if exists
1022   if ( !aStreamCopy.IsNull() ) {
1023     const Handle(HYDROData_Polyline3D) aBottom = GetBottomPolyline();
1024     if ( !aBottom.IsNull() ) {
1025       aStreamCopy->ClearReferenceObjects( DataTag_BottomPolyline );
1026       aStreamCopy->GenerateBottomPolyline();
1027       const Handle(HYDROData_Polyline3D) aBottomCopy = aStreamCopy->GetBottomPolyline();
1028       if ( !aBottomCopy.IsNull() && !aBottomCopy->GetPolylineXY().IsNull() ) {
1029         aBottomCopy->GetPolylineXY()->Update();
1030         aBottomCopy->Update();
1031       }
1032     }
1033   }
1034 }
1035 #include <GeomProjLib.hxx>
1036 #include <Geom_TrimmedCurve.hxx>
1037 #include <Geom_Plane.hxx>
1038 #include <BRepTools.hxx>
1039 static void ProjEdgeOnPlane(const TopoDS_Edge& inpEdge, const Handle_Geom_Plane& RefPlane, TopoDS_Edge& outSh, TopoDS_Vertex V1, TopoDS_Vertex V2)
1040 {
1041   double f, l;
1042   Handle(Geom_Curve) C3d = BRep_Tool::Curve(inpEdge, f, l);
1043   Handle(Geom_Curve) ProjectedCurve = GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d, f, l), RefPlane, RefPlane->Position().Direction(), Standard_True);
1044   if (V1.IsNull() || V2.IsNull())
1045     outSh = BRepLib_MakeEdge(ProjectedCurve); //create new vertices
1046   else
1047     outSh = BRepLib_MakeEdge(ProjectedCurve, V1, V2);
1048 }
1049
1050
1051 bool HYDROData_Stream::CreatePresentations( const TopoDS_Edge&          theLeftBank,
1052                                             const TopoDS_Edge&          theRightBank,
1053                                             const std::vector<TopoDS_Edge>& theProfiles3d,
1054                                             PrsDefinition&              thePrs )
1055 {
1056   thePrs.myLeftBank = theLeftBank;
1057   thePrs.myRightBank = theRightBank;
1058
1059   BRep_Builder aBB;
1060   TopoDS_Compound aCmp;
1061   aBB.MakeCompound(aCmp);
1062   for (size_t i = 0; i < theProfiles3d.size(); i++ )  
1063     aBB.Add(aCmp, theProfiles3d[i]);
1064
1065   aBB.Add(aCmp, theLeftBank);
1066   aBB.Add(aCmp, theRightBank);
1067
1068   thePrs.myPrs3D = aCmp; //3d pres
1069   
1070
1071   Handle_Geom_Plane RefPlane = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1));
1072   std::vector<TopoDS_Edge> internProf;
1073   internProf.reserve(theProfiles3d.size() - 2);
1074   
1075   //project internal edges/profiles
1076   for (size_t i = 1; i < theProfiles3d.size() - 1; i++ )  
1077   {
1078     TopoDS_Edge ProjEdge;
1079     ProjEdgeOnPlane(theProfiles3d[i], RefPlane, ProjEdge, TopoDS_Vertex(), TopoDS_Vertex());
1080     internProf.push_back (TopoDS::Edge(ProjEdge.Oriented(TopAbs_INTERNAL)));
1081   }
1082  
1083   TopoDS_Edge ProjEdgeIn, ProjEdgeOut;
1084   TopoDS_Vertex V1In, V2In, V1Out, V2Out;
1085
1086   ProjEdgeOnPlane(theProfiles3d.front(), RefPlane, ProjEdgeIn, TopoDS_Vertex(), TopoDS_Vertex());
1087   TopExp::Vertices(ProjEdgeIn, V1In, V2In);
1088
1089   ProjEdgeOnPlane(theProfiles3d.back(), RefPlane, ProjEdgeOut, TopoDS_Vertex(), TopoDS_Vertex());
1090   TopExp::Vertices(ProjEdgeOut, V1Out, V2Out);
1091
1092   TopoDS_Edge ProjEdgeLeftB, ProjEdgeRightB;
1093   ProjEdgeOnPlane(theLeftBank, RefPlane, ProjEdgeLeftB, V1In, V1Out);
1094   ProjEdgeOnPlane(theRightBank, RefPlane, ProjEdgeRightB, V2In, V2Out);
1095
1096   BRepLib_MakeWire WM(ProjEdgeIn, ProjEdgeOut, ProjEdgeLeftB, ProjEdgeRightB);
1097   for (size_t i = 0; i < internProf.size(); i++ ) 
1098     WM.Add(internProf[i]);
1099
1100   TopoDS_Face outF = BRepLib_MakeFace(RefPlane, WM.Wire()).Face();
1101   thePrs.myPrs2D = outF;
1102
1103   return true;
1104   /*if ( theArrayOfFPnt.IsNull() || theArrayOfLPnt.IsNull() || theArrOfProfiles.IsNull() ) {
1105     return false;
1106   }
1107
1108   if ( theArrayOfFPnt->Length() != theArrayOfLPnt->Length() ) {
1109     return false;
1110   }
1111   
1112   // Construct of the 3D presentation
1113   Handle(Geom_BSplineCurve) aBSpline = buildInterpolationCurve (theArrayOfFPnt);
1114   if(aBSpline.IsNull())
1115     return false;
1116
1117   TopoDS_Edge anEdgLeft, anEdgRight;
1118   
1119   BRepBuilderAPI_MakeEdge aMakeEdge(aBSpline);
1120   if(aMakeEdge.IsDone()) 
1121     anEdgLeft = aMakeEdge.Edge();
1122
1123   if(anEdgLeft.IsNull())
1124     return false;
1125
1126   aBSpline.Nullify();
1127   aBSpline = buildInterpolationCurve (theArrayOfLPnt);  
1128   if(aBSpline.IsNull())
1129     return false;
1130
1131   aMakeEdge.Init(aBSpline);
1132   if(aMakeEdge.IsDone()) 
1133     anEdgRight = aMakeEdge.Edge();
1134
1135   if(anEdgRight.IsNull())
1136     return false;
1137
1138   BRep_Builder aBB;
1139   TopoDS_Compound aCmp;
1140   aBB.MakeCompound(aCmp);
1141   for (int i=1 ; i < theArrOfProfiles->Length() +1; i++ )  
1142     aBB.Add(aCmp, theArrOfProfiles->Value(i));
1143
1144   aBB.Add(aCmp,anEdgLeft);
1145   aBB.Add(aCmp,anEdgRight);
1146   BRepCheck_Analyzer aCh(aCmp);
1147   if(aCh.IsValid())
1148     thePrs.myPrs3D = aCmp;
1149 #ifdef DEB_UPDATE
1150   else {
1151     BRepTools::Write(aCmp, "str3d.brep");
1152     thePrs.myPrs3D = aCmp;
1153   }
1154 #endif
1155
1156   // Construct the top presentation
1157   int aNbPoints = theArrayOfFPnt->Length();
1158   Handle(TColgp_HArray1OfPnt) anArrayOfFPnt = new TColgp_HArray1OfPnt(1, aNbPoints);
1159   Handle(TColgp_HArray1OfPnt) anArrayOfLPnt = new TColgp_HArray1OfPnt(1, aNbPoints);  
1160   for( int i=1; i <= aNbPoints; i++ ) {
1161       gp_Pnt aPnt = theArrayOfFPnt->Value(i);
1162       aPnt.SetZ(.0); // make 2d
1163       anArrayOfFPnt->SetValue(i, aPnt);
1164       aPnt = theArrayOfLPnt->Value(i);
1165       aPnt.SetZ(.0);
1166       anArrayOfLPnt->SetValue(i, aPnt);
1167   }
1168
1169   aBSpline.Nullify();
1170   aBSpline = buildInterpolationCurve (anArrayOfFPnt);  
1171   if(aBSpline.IsNull())
1172     return false; 
1173
1174   aMakeEdge.Init(aBSpline);
1175   if(aMakeEdge.IsDone()) 
1176       anEdgLeft = aMakeEdge.Edge();
1177
1178   aBSpline.Nullify();
1179   aBSpline = buildInterpolationCurve (anArrayOfLPnt);  
1180   if(aBSpline.IsNull())
1181     return false; 
1182
1183   aMakeEdge.Init(aBSpline);
1184   if(aMakeEdge.IsDone()) 
1185     anEdgRight = aMakeEdge.Edge();
1186   if(anEdgRight.IsNull())
1187     return false;
1188
1189   BRepBuilderAPI_MakeEdge aMakeEdge2(anArrayOfFPnt->Value(1),anArrayOfLPnt->Value(1));
1190   TopoDS_Edge aBotEdge, aTopEdge;
1191   if(aMakeEdge2.IsDone()) 
1192     aBotEdge = aMakeEdge2.Edge();
1193
1194   BRepBuilderAPI_MakeEdge aMakeEdge3(anArrayOfFPnt->Value(anArrayOfFPnt->Length()),anArrayOfLPnt->Value(anArrayOfLPnt->Length()));
1195   if(aMakeEdge3.IsDone()) 
1196     aTopEdge = aMakeEdge3.Edge();
1197
1198   // Make wire for 2D presentation with updating of corresponding edges
1199   BRepBuilderAPI_MakeWire aMakeWire;
1200   
1201   aMakeWire.Add( aBotEdge );
1202   thePrs.myInlet = aMakeWire.Edge();
1203
1204   aMakeWire.Add( anEdgLeft );
1205   thePrs.myLeftBank = aMakeWire.Edge();
1206
1207   aMakeWire.Add( aTopEdge );
1208   thePrs.myOutlet = aMakeWire.Edge();
1209
1210   aMakeWire.Add( anEdgRight );
1211   thePrs.myRightBank = aMakeWire.Edge();
1212
1213   TopoDS_Wire aSectProfileWire;
1214   if(aMakeWire.IsDone())
1215     aSectProfileWire = aMakeWire.Wire();
1216
1217   BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
1218   TopoDS_Face aFace;
1219   aMakeFace.Build();
1220   if( aMakeFace.IsDone() )
1221     aFace = aMakeFace.Face();
1222
1223   TopoDS_Shape aPrs2D;
1224
1225   if ( !theArrOf2DProfiles.IsNull() ) {
1226     aCmp.Nullify();
1227     aBB.MakeCompound(aCmp);
1228     aBB.Add(aCmp,aFace);
1229     for(int i=1;i <= theArrOf2DProfiles->Length(); i++)
1230       aBB.Add(aCmp, theArrOf2DProfiles->Value(i));
1231
1232     aPrs2D = aCmp;
1233   } else {
1234     aPrs2D = aFace;
1235   }
1236
1237   aCh.Init(aPrs2D);
1238   if(aCh.IsValid())
1239    thePrs.myPrs2D = aPrs2D;
1240 #ifdef DEB_UPDATE
1241   else {
1242     BRepTools::Write(aPrs2D, "str2d.brep");
1243     thePrs.myPrs2D = aPrs2D;
1244   }
1245 #endif
1246
1247   return true;*/
1248 }