Salome HOME
220790056cd917e0ab50f1075a26aa4687d75218
[modules/hydro.git] / src / HYDROData / HYDROData_CalculationCase.cxx
1
2 #include "HYDROData_CalculationCase.h"
3
4 #include "HYDROData_ArtificialObject.h"
5 #include "HYDROData_Bathymetry.h"
6 #include "HYDROData_Document.h"
7 #include "HYDROData_EdgesGroup.h"
8 #include "HYDROData_Iterator.h"
9 #include "HYDROData_NaturalObject.h"
10 #include "HYDROData_PolylineXY.h"
11 #include "HYDROData_SplitToZonesTool.h"
12 #include "HYDROData_SplittedEdgesGroup.h"
13 #include "HYDROData_Region.h"
14 #include "HYDROData_Tool.h"
15 #include "HYDROData_Zone.h"
16
17 #include <TopoDS.hxx>
18 #include <TopoDS_Shell.hxx>
19 #include <TopoDS_Edge.hxx>
20
21 #include <BRep_Builder.hxx>
22 #include <BRepBuilderAPI_Sewing.hxx>
23 #include <BRepTopAdaptor_FClass2d.hxx>
24
25 #include <TopAbs.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <TopExp.hxx>
28 #include <TopTools_ListOfShape.hxx>
29 #include <TopTools_ListIteratorOfListOfShape.hxx>
30
31
32 #define CALCULATION_REGIONS_PREF GetName() + "_Reg"
33 #define CALCULATION_ZONES_PREF GetName() + "_Zone"
34
35 #define PYTHON_CALCULATION_ID "KIND_CALCULATION"
36
37 IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
38 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
39
40 HYDROData_CalculationCase::HYDROData_CalculationCase()
41 : HYDROData_Entity()
42 {
43 }
44
45 HYDROData_CalculationCase::~HYDROData_CalculationCase()
46 {
47 }
48
49 void HYDROData_CalculationCase::SetName( const QString& theName )
50 {
51   QString anOldCaseName = GetName();
52   if ( anOldCaseName != theName )
53   {
54     HYDROData_SequenceOfObjects aRegions = GetRegions();
55
56     HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
57     for ( ; anIter.More(); anIter.Next() )
58     {
59       Handle(HYDROData_Region) aRegion =
60         Handle(HYDROData_Region)::DownCast( anIter.Value() );
61       if ( aRegion.IsNull() )
62         continue;
63
64       QString aRegionName = aRegion->GetName();
65       if ( aRegionName.startsWith( anOldCaseName ) )
66       {
67         aRegionName.replace( anOldCaseName, theName );
68         aRegion->SetName( aRegionName );
69       }
70
71       HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
72       HYDROData_SequenceOfObjects::Iterator anIter( aZones );
73       for ( ; anIter.More(); anIter.Next() )
74       {
75         Handle(HYDROData_Zone) aRegZone =
76           Handle(HYDROData_Zone)::DownCast( anIter.Value() );
77         if ( aRegZone.IsNull() )
78           continue;
79
80         QString aRegionZoneName = aRegZone->GetName();
81         if ( aRegionZoneName.startsWith( anOldCaseName ) )
82         {
83           aRegionZoneName.replace( anOldCaseName, theName );
84           aRegZone->SetName( aRegionZoneName );
85         }
86       }
87     }
88   }
89
90   HYDROData_Entity::SetName( theName );
91 }
92
93 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
94 {
95   QStringList aResList;
96
97   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
98   if ( aDocument.IsNull() )
99     return aResList;
100                              
101   QString aDocName = aDocument->GetDocPyName();
102   QString aCalculName = GetName();
103
104   aResList << QString( "%1 = %2.CreateObject( %3 );" )
105               .arg( aCalculName ).arg( aDocName ).arg( PYTHON_CALCULATION_ID );
106   aResList << QString( "%1.SetName( \"%2\" );" )
107               .arg( aCalculName ).arg( aCalculName );
108   aResList << QString( "" );
109
110   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
111   HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
112   for ( ; anIter.More(); anIter.Next() )
113   {
114     Handle(HYDROData_Object) aRefGeomObj =
115       Handle(HYDROData_Object)::DownCast( anIter.Value() );
116     if ( !aRefGeomObj.IsNull() )
117       setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
118   }
119   aResList << QString( "" );
120
121   aResList << QString( "%1.SplitGeometryObjects();" ).arg( aCalculName );
122   aResList << QString( "" );
123
124   // Now we restore the regions and zones order
125   HYDROData_SequenceOfObjects aRegions = GetRegions();
126   anIter.Init( aRegions );
127   for ( ; anIter.More(); anIter.Next() )
128   {
129     Handle(HYDROData_Region) aRegion =
130       Handle(HYDROData_Region)::DownCast( anIter.Value() );
131     if ( aRegion.IsNull() )
132       continue;
133
134     QString aRegionName = aRegion->GetName();
135     // TODO
136   }
137
138   return aResList;
139 }
140
141 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetAllReferenceObjects() const
142 {
143   HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
144
145   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
146   if ( !aBoundaryPolyline.IsNull() )
147     aResSeq.Append( aBoundaryPolyline );
148
149   HYDROData_SequenceOfObjects aSeqOfRegions = GetRegions();
150   aResSeq.Append( aSeqOfRegions );
151
152   return aResSeq;
153 }
154
155 void HYDROData_CalculationCase::Update()
156 {
157   HYDROData_Entity::Update();
158
159   // At first we remove previously created objects
160   RemoveRegions();
161   RemoveSplittedGroups();
162
163   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
164   if ( aDocument.IsNull() )
165     return;
166
167   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
168   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
169   if ( aGeomObjects.IsEmpty() )
170     return;
171
172   HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
173
174   HYDROData_SplitToZonesTool::SplitDataList aSplitedObjects =
175     HYDROData_SplitToZonesTool::Split( aGeomObjects, aGeomGroups, aBoundaryPolyline );
176   if ( aSplitedObjects.isEmpty() )
177     return;
178
179   QString aRegsPref = CALCULATION_REGIONS_PREF;
180   QString aZonesPref = CALCULATION_ZONES_PREF;
181
182   QMap<QString,Handle(HYDROData_SplittedEdgesGroup)> aSplittedEdgesGroupsMap;
183
184   // Create result regions for case, by default one zone for one region
185   HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedObjects );
186   while( anIter.hasNext() )
187   {
188     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
189
190     if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone )
191     {
192       // Create new region
193       Handle(HYDROData_Region) aRegion = addNewRegion();
194
195       QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
196       aRegion->SetName( aRegionName );
197
198       // Add the zone for region
199       Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
200
201       QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
202       aRegionZone->SetName( aZoneName );
203
204       aRegionZone->SetShape( aSplitData.Face() );
205
206       // Add the reference object for zone
207       for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
208       {
209         const QString& anObjName = aSplitData.ObjectNames.at( i );
210         
211         Handle(HYDROData_Object) aRefObject = Handle(HYDROData_Object)::DownCast(
212           HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
213         if ( aRefObject.IsNull() )
214           continue;
215
216         aRegionZone->AddGeometryObject( aRefObject );
217       }
218     }
219     else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge )
220     {
221       // Create new edges group
222       if ( aSplitData.ObjectNames.isEmpty() || 
223            aSplitData.Shape.IsNull() || aSplitData.Shape.ShapeType() != TopAbs_EDGE )
224         continue;
225
226       QString anObjName = aSplitData.ObjectNames.first();
227       if ( anObjName.isEmpty() )
228         continue;
229
230       if ( !aSplittedEdgesGroupsMap.contains( anObjName ) )
231         aSplittedEdgesGroupsMap.insert( anObjName, addNewSplittedGroup() );
232
233       Handle(HYDROData_SplittedEdgesGroup) aSplittedGroup = aSplittedEdgesGroupsMap[ anObjName ];
234       if ( aSplittedGroup.IsNull() )
235         continue;
236
237       TopoDS_Edge anEdge = TopoDS::Edge( aSplitData.Shape );
238       aSplittedGroup->AddEdge( anEdge );
239     }
240   }
241 }
242
243 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
244 {
245   if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
246     return false; // Wrong type of object
247
248   if ( HasReference( theObject, DataTag_GeometryObject ) )
249     return false; // Object is already in reference list
250
251   AddReferenceObject( theObject, DataTag_GeometryObject );
252   
253   // Indicate model of the need to update splitting
254   SetToUpdate( true );
255
256   return true;
257 }
258
259 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
260 {
261   return GetReferenceObjects( DataTag_GeometryObject );
262 }
263
264 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
265 {
266   if ( theObject.IsNull() )
267     return;
268
269   RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
270
271   // Indicate model of the need to update splitting
272   SetToUpdate( true );
273 }
274
275 void HYDROData_CalculationCase::RemoveGeometryObjects()
276 {
277   ClearReferenceObjects( DataTag_GeometryObject );
278
279   // Indicate model of the need to update splitting
280   SetToUpdate( true );
281 }
282
283 bool HYDROData_CalculationCase::AddGeometryGroup( const Handle(HYDROData_EdgesGroup)& theGroup )
284 {
285   if ( theGroup.IsNull() )
286     return false;
287
288   if ( HasReference( theGroup, DataTag_GeometryGroup ) )
289     return false; // Object is already in reference list
290
291   AddReferenceObject( theGroup, DataTag_GeometryGroup );
292   
293   // Indicate model of the need to update splitting
294   SetToUpdate( true );
295
296   return true;
297 }
298
299 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryGroups() const
300 {
301   return GetReferenceObjects( DataTag_GeometryGroup );
302 }
303
304 void HYDROData_CalculationCase::RemoveGeometryGroup( const Handle(HYDROData_EdgesGroup)& theGroup )
305 {
306   if ( theGroup.IsNull() )
307     return;
308
309   RemoveReferenceObject( theGroup->Label(), DataTag_GeometryGroup );
310
311   // Indicate model of the need to update splitting
312   SetToUpdate( true );
313 }
314
315 void HYDROData_CalculationCase::RemoveGeometryGroups()
316 {
317   ClearReferenceObjects( DataTag_GeometryGroup );
318
319   // Indicate model of the need to update splitting
320   SetToUpdate( true );
321 }
322
323 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
324 {
325   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
326
327   SetReferenceObject( thePolyline, DataTag_Polyline );
328
329   // Indicate model of the need to update zones splitting
330   SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
331 }
332
333 Handle(HYDROData_PolylineXY) HYDROData_CalculationCase::GetBoundaryPolyline() const
334 {
335   return Handle(HYDROData_PolylineXY)::DownCast( 
336            GetReferenceObject( DataTag_Polyline ) );
337 }
338
339 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
340 {
341   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
342
343   ClearReferenceObjects( DataTag_Polyline );
344
345   // Indicate model of the need to update zones splitting
346   SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
347 }
348
349 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
350 {
351   Handle(HYDROData_Region) aNewRegion = addNewRegion();
352   if ( aNewRegion.IsNull() )
353     return aNewRegion;
354
355   // Generate new name for new region
356   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
357   if ( !aDocument.IsNull() )
358   {
359     QString aRegsPref = CALCULATION_REGIONS_PREF;
360
361     QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
362     aNewRegion->SetName( aNewRegionName );
363   }
364
365   aNewRegion->AddZone( theZone );
366
367   return aNewRegion;
368 }
369
370 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
371 {
372   if ( theRegion.IsNull() )
373     return false;
374   
375   if ( HasReference( theRegion, DataTag_Region ) )
376     return false; // Object is already in reference list
377
378   // Move the region from other calculation
379   Handle(HYDROData_CalculationCase) aFatherCalc = 
380     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
381   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
382   {
383     Handle(HYDROData_Region) aNewRegion = addNewRegion();
384     theRegion->CopyTo( aNewRegion );
385
386     aFatherCalc->RemoveRegion( theRegion );
387
388     theRegion->SetLabel( aNewRegion->Label() );
389   }
390   else
391   {
392     AddReferenceObject( theRegion, DataTag_Region );
393   }
394
395   return true;
396 }
397
398 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
399 {
400   return GetReferenceObjects( DataTag_Region );
401 }
402
403 void HYDROData_CalculationCase::UpdateRegionsOrder()
404 {
405   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
406   if ( aDocument.IsNull() )
407     return;
408
409   HYDROData_SequenceOfObjects aRegions = GetRegions();
410
411   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
412   for ( ; anIter.More(); anIter.Next() )
413   {
414     Handle(HYDROData_Region) aRegion =
415       Handle(HYDROData_Region)::DownCast( anIter.Value() );
416     if ( aRegion.IsNull() )
417       continue;
418
419     aRegion->SetName( "" );
420   }
421
422   QString aRegsPref = CALCULATION_REGIONS_PREF;
423
424   anIter.Init( aRegions );
425   for ( ; anIter.More(); anIter.Next() )
426   {
427     Handle(HYDROData_Region) aRegion =
428       Handle(HYDROData_Region)::DownCast( anIter.Value() );
429     if ( aRegion.IsNull() )
430       continue;
431
432     QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
433     aRegion->SetName( aRegionName );
434   }
435 }
436
437 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
438 {
439   if ( theRegion.IsNull() )
440     return;
441
442   RemoveReferenceObject( theRegion->Label(), DataTag_Region );
443
444   // Remove region from data model
445   Handle(HYDROData_CalculationCase) aFatherCalc = 
446     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
447   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
448     theRegion->Remove();
449 }
450
451 void HYDROData_CalculationCase::RemoveRegions()
452 {
453   myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes();
454 }
455
456 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetSplittedGroups() const
457 {
458   return GetReferenceObjects( DataTag_SplittedGroups );
459 }
460
461 void HYDROData_CalculationCase::RemoveSplittedGroups()
462 {
463   myLab.FindChild( DataTag_SplittedGroups ).ForgetAllAttributes();
464 }
465
466 TopoDS_Shell HYDROData_CalculationCase::GetShell()
467 {
468   TopoDS_Shell aShell;
469
470   TopTools_ListOfShape aFacesList;
471
472   // Make shell containing all region shapes
473   BRepBuilderAPI_Sewing aSewing( Precision::Confusion()*10.0 );
474
475   HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
476   HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
477   for ( ; aRegionIter.More(); aRegionIter.Next() ) {
478     Handle(HYDROData_Region) aRegion =
479       Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
480     if( aRegion.IsNull() ) {
481       continue;
482     }
483
484     TopoDS_Shape aRegionShape = aRegion->GetShape();
485     if( !aRegionShape.IsNull() ) {
486       if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
487         TopoDS_Face aFace = TopoDS::Face( aRegionShape );
488         if ( !aFace.IsNull() ) {
489           aFacesList.Append( aFace );
490           aSewing.Add( aFace );
491         }
492       } else {
493         TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
494         for ( ; anExp.More(); anExp.Next() ) {
495           TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
496           if ( !aFace.IsNull() ) {
497             aFacesList.Append( aFace );
498             aSewing.Add( aFace );
499           }
500         }
501       }
502     }
503   } // regions iterator
504   
505   aSewing.Perform();
506   TopoDS_Shape aSewedShape = aSewing.SewedShape();
507
508   if ( !aSewedShape.IsNull() )
509   {
510     if ( aSewedShape.ShapeType() == TopAbs_FACE && aCaseRegions.Length() ==1 ) {
511       // create shell from one face
512       BRep_Builder aBuilder;
513       aBuilder.MakeShell( aShell );
514       aBuilder.Add( aShell, aSewedShape);
515     } else {
516       TopExp_Explorer anExpShells( aSewedShape, TopAbs_SHELL );
517       Standard_Integer aNbOfShells = 0;
518       for ( ; anExpShells.More(); anExpShells.Next() ) {
519         aShell = TopoDS::Shell( anExpShells.Current() );
520         aNbOfShells++;
521       }
522
523       if ( aNbOfShells != 1 ) {
524         aShell.Nullify();
525         BRep_Builder aBuilder;
526         aBuilder.MakeShell( aShell );
527
528         TopExp_Explorer anExpFaces( aSewedShape, TopAbs_FACE );
529         for ( ; anExpFaces.More(); anExpFaces.Next() ) {
530           TopoDS_Face aFace = TopoDS::Face( anExpFaces.Current() );
531           if ( !aFace.IsNull() ) {
532             aBuilder.Add( aShell, aFace );
533           }
534         }
535       }
536     }
537   }
538
539   if ( !aShell.IsNull() ) {
540     TopTools_IndexedMapOfShape aMapOfFaces;
541     TopExp::MapShapes( aShell, TopAbs_FACE, aMapOfFaces );
542     if ( aMapOfFaces.Extent() != aFacesList.Extent() ) {
543       aShell.Nullify();
544       BRep_Builder aBuilder;
545       aBuilder.MakeShell( aShell );
546
547       TopTools_ListIteratorOfListOfShape anIter( aFacesList );
548       for ( ; anIter.More(); anIter.Next() ) {
549         TopoDS_Face aFace = TopoDS::Face( anIter.Value() );
550         aBuilder.Add( aShell, aFace );
551       }
552     }
553   }
554
555 /* TODO: old version
556   // Make shell
557   BRep_Builder aBuilder;
558   aBuilder.MakeShell( aShell );
559
560   // Make shell containing all region shapes
561   HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
562   HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
563   for ( ; aRegionIter.More(); aRegionIter.Next() ) {
564     Handle(HYDROData_Region) aRegion =
565       Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
566     if( aRegion.IsNull() ) {
567       continue;
568     }
569
570     TopoDS_Shape aRegionShape = aRegion->GetShape();
571
572     // Add shape (face or shell) corresponding to the region into the shell
573     if( !aRegionShape.IsNull() ) {
574       if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
575         aBuilder.Add( aShell, aRegionShape );
576       } else {
577         TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
578         for( ; anExp.More(); anExp.Next() ) {
579           TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
580           if( !aFace.IsNull() ) {
581             aBuilder.Add( aShell, aFace );
582           }
583         }
584       }
585     }
586   } // regions iterator
587 */
588
589   // Nullify shell if it is empty
590   if ( !aShell.IsNull() && !TopoDS_Iterator(aShell).More() ) {
591     aShell.Nullify();
592   }
593
594   return aShell;
595 }
596
597 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY& thePoint ) const
598 {
599   double aResAltitude = HYDROData_Bathymetry::GetInvalidAltitude();
600
601   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
602   if ( aZone.IsNull() )
603     return aResAltitude;
604
605   HYDROData_Zone::MergeBathymetriesType aZoneMergeType = aZone->GetMergeType();
606   if ( !aZone->IsMergingNeed() )
607   {
608     aZoneMergeType = HYDROData_Zone::Merge_UNKNOWN;
609   }
610   else if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
611   {
612     return aResAltitude;
613   }
614
615   if ( aZoneMergeType == HYDROData_Zone::Merge_Object )
616   {
617     Handle(HYDROData_Bathymetry) aMergeBathymetry = aZone->GetMergeBathymetry();
618     if ( !aMergeBathymetry.IsNull() )
619       aResAltitude = aMergeBathymetry->GetAltitudeForPoint( thePoint );
620   }
621   else
622   {
623     HYDROData_SequenceOfObjects aZoneObjects = aZone->GetGeometryObjects();
624     HYDROData_SequenceOfObjects::Iterator anIter( aZoneObjects );
625     for ( ; anIter.More(); anIter.Next() )
626     {
627       Handle(HYDROData_Object) aZoneObj =
628         Handle(HYDROData_Object)::DownCast( anIter.Value() );
629       if ( aZoneObj.IsNull() )
630         continue;
631
632       Handle(HYDROData_Bathymetry) anObjBathymetry = aZoneObj->GetBathymetry();
633       if ( anObjBathymetry.IsNull() )
634         continue;
635
636       double aPointAltitude = anObjBathymetry->GetAltitudeForPoint( thePoint );
637       if ( ValuesEquals( aPointAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) )
638         continue;
639
640       if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
641       {
642         aResAltitude = aPointAltitude;
643         break;
644       }
645       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMIN )
646       {
647         if ( ValuesEquals( aResAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) ||
648              aResAltitude > aPointAltitude )
649         {
650           aResAltitude = aPointAltitude;
651         }
652       }
653       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMAX )
654       {
655         if ( ValuesEquals( aResAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) ||
656              aResAltitude < aPointAltitude )
657         {
658           aResAltitude = aPointAltitude;
659         }
660       }
661     }
662   }
663
664   return aResAltitude;
665 }
666
667 Handle(HYDROData_Zone) HYDROData_CalculationCase::GetZoneFromPoint( const gp_XY& thePoint ) const
668 {
669   Handle(HYDROData_Zone) aResZone;
670
671   HYDROData_SequenceOfObjects aRegions = GetRegions();
672
673   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
674   for ( ; anIter.More() && aResZone.IsNull(); anIter.Next() )
675   {
676     Handle(HYDROData_Region) aRegion =
677       Handle(HYDROData_Region)::DownCast( anIter.Value() );
678     if ( aRegion.IsNull() )
679       continue;
680
681     HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
682     HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
683     for ( ; aZonesIter.More() && aResZone.IsNull(); aZonesIter.Next() )
684     {
685       Handle(HYDROData_Zone) aRegZone =
686         Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
687       if ( aRegZone.IsNull() )
688         continue;
689
690       PointClassification aPointRelation = GetPointClassification( thePoint, aRegZone );
691       if ( aPointRelation != POINT_OUT )
692         aResZone = aRegZone; // We found the desired zone
693     }
694   }
695
696   return aResZone;
697 }
698
699 HYDROData_CalculationCase::PointClassification HYDROData_CalculationCase::GetPointClassification(
700   const gp_XY&                  thePoint,
701   const Handle(HYDROData_Zone)& theZone ) const
702 {
703   PointClassification aRes = POINT_OUT;
704   if ( theZone.IsNull() )
705     return aRes;
706
707   TopoDS_Face aZoneFace = TopoDS::Face( theZone->GetShape() );
708   if ( aZoneFace.IsNull() )
709     return aRes;
710
711   BRepTopAdaptor_FClass2d aClassifier( aZoneFace, Precision::Confusion() );
712   TopAbs_State State = aClassifier.Perform( gp_Pnt2d(thePoint), Standard_False );
713   if (State == TopAbs_OUT)
714         aRes =  POINT_OUT;
715   else if(State == TopAbs_IN)
716     aRes =  POINT_IN;
717   else if(State == TopAbs_ON)
718     aRes =  POINT_ON;     
719   return aRes;
720 }
721
722 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
723 {
724   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
725
726   Handle(HYDROData_Region) aNewRegion =
727     Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
728   AddRegion( aNewRegion );
729
730   return aNewRegion;
731 }
732
733 Handle(HYDROData_SplittedEdgesGroup) HYDROData_CalculationCase::addNewSplittedGroup()
734 {
735   TDF_Label aNewLab = myLab.FindChild( DataTag_SplittedGroups ).NewChild();
736
737   Handle(HYDROData_SplittedEdgesGroup) aNewGroup =
738     Handle(HYDROData_SplittedEdgesGroup)::DownCast( 
739       HYDROData_Iterator::CreateObject( aNewLab, KIND_SPLITTED_GROUP ) );
740   AddReferenceObject( aNewGroup, DataTag_SplittedGroups );
741
742   return aNewGroup;
743 }
744
745