]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_CalculationCase.cxx
Salome HOME
Name for splitted zone (Feature #242).
[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       Handle(HYDROData_SplittedEdgesGroup) aSplittedGroup;
231       if ( !aSplittedEdgesGroupsMap.contains( anObjName ) )
232       {
233         aSplittedGroup = addNewSplittedGroup();
234
235         QString aCalcGroupName = GetName() + "_" + anObjName;
236         aSplittedGroup->SetName( aCalcGroupName );
237
238         aSplittedEdgesGroupsMap.insert( anObjName, aSplittedGroup );
239       }
240       else
241       {
242         aSplittedGroup = aSplittedEdgesGroupsMap[ anObjName ];
243       }
244
245       if ( aSplittedGroup.IsNull() )
246         continue;
247
248       TopoDS_Edge anEdge = TopoDS::Edge( aSplitData.Shape );
249       aSplittedGroup->AddEdge( anEdge );
250     }
251   }
252 }
253
254 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
255 {
256   if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
257     return false; // Wrong type of object
258
259   if ( HasReference( theObject, DataTag_GeometryObject ) )
260     return false; // Object is already in reference list
261
262   AddReferenceObject( theObject, DataTag_GeometryObject );
263   
264   // Indicate model of the need to update splitting
265   SetToUpdate( true );
266
267   return true;
268 }
269
270 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
271 {
272   return GetReferenceObjects( DataTag_GeometryObject );
273 }
274
275 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
276 {
277   if ( theObject.IsNull() )
278     return;
279
280   RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
281
282   // Indicate model of the need to update splitting
283   SetToUpdate( true );
284 }
285
286 void HYDROData_CalculationCase::RemoveGeometryObjects()
287 {
288   ClearReferenceObjects( DataTag_GeometryObject );
289
290   // Indicate model of the need to update splitting
291   SetToUpdate( true );
292 }
293
294 bool HYDROData_CalculationCase::AddGeometryGroup( const Handle(HYDROData_EdgesGroup)& theGroup )
295 {
296   if ( theGroup.IsNull() )
297     return false;
298
299   if ( HasReference( theGroup, DataTag_GeometryGroup ) )
300     return false; // Object is already in reference list
301
302   AddReferenceObject( theGroup, DataTag_GeometryGroup );
303   
304   // Indicate model of the need to update splitting
305   SetToUpdate( true );
306
307   return true;
308 }
309
310 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryGroups() const
311 {
312   return GetReferenceObjects( DataTag_GeometryGroup );
313 }
314
315 void HYDROData_CalculationCase::RemoveGeometryGroup( const Handle(HYDROData_EdgesGroup)& theGroup )
316 {
317   if ( theGroup.IsNull() )
318     return;
319
320   RemoveReferenceObject( theGroup->Label(), DataTag_GeometryGroup );
321
322   // Indicate model of the need to update splitting
323   SetToUpdate( true );
324 }
325
326 void HYDROData_CalculationCase::RemoveGeometryGroups()
327 {
328   ClearReferenceObjects( DataTag_GeometryGroup );
329
330   // Indicate model of the need to update splitting
331   SetToUpdate( true );
332 }
333
334 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
335 {
336   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
337
338   SetReferenceObject( thePolyline, DataTag_Polyline );
339
340   // Indicate model of the need to update zones splitting
341   SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
342 }
343
344 Handle(HYDROData_PolylineXY) HYDROData_CalculationCase::GetBoundaryPolyline() const
345 {
346   return Handle(HYDROData_PolylineXY)::DownCast( 
347            GetReferenceObject( DataTag_Polyline ) );
348 }
349
350 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
351 {
352   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
353
354   ClearReferenceObjects( DataTag_Polyline );
355
356   // Indicate model of the need to update zones splitting
357   SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
358 }
359
360 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
361 {
362   Handle(HYDROData_Region) aNewRegion = addNewRegion();
363   if ( aNewRegion.IsNull() )
364     return aNewRegion;
365
366   // Generate new name for new region
367   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
368   if ( !aDocument.IsNull() )
369   {
370     QString aRegsPref = CALCULATION_REGIONS_PREF;
371
372     QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
373     aNewRegion->SetName( aNewRegionName );
374   }
375
376   aNewRegion->AddZone( theZone );
377
378   return aNewRegion;
379 }
380
381 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
382 {
383   if ( theRegion.IsNull() )
384     return false;
385   
386   if ( HasReference( theRegion, DataTag_Region ) )
387     return false; // Object is already in reference list
388
389   // Move the region from other calculation
390   Handle(HYDROData_CalculationCase) aFatherCalc = 
391     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
392   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
393   {
394     Handle(HYDROData_Region) aNewRegion = addNewRegion();
395     theRegion->CopyTo( aNewRegion );
396
397     aFatherCalc->RemoveRegion( theRegion );
398
399     theRegion->SetLabel( aNewRegion->Label() );
400   }
401   else
402   {
403     AddReferenceObject( theRegion, DataTag_Region );
404   }
405
406   return true;
407 }
408
409 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
410 {
411   return GetReferenceObjects( DataTag_Region );
412 }
413
414 void HYDROData_CalculationCase::UpdateRegionsOrder()
415 {
416   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
417   if ( aDocument.IsNull() )
418     return;
419
420   HYDROData_SequenceOfObjects aRegions = GetRegions();
421
422   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
423   for ( ; anIter.More(); anIter.Next() )
424   {
425     Handle(HYDROData_Region) aRegion =
426       Handle(HYDROData_Region)::DownCast( anIter.Value() );
427     if ( aRegion.IsNull() )
428       continue;
429
430     aRegion->SetName( "" );
431   }
432
433   QString aRegsPref = CALCULATION_REGIONS_PREF;
434
435   anIter.Init( aRegions );
436   for ( ; anIter.More(); anIter.Next() )
437   {
438     Handle(HYDROData_Region) aRegion =
439       Handle(HYDROData_Region)::DownCast( anIter.Value() );
440     if ( aRegion.IsNull() )
441       continue;
442
443     QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
444     aRegion->SetName( aRegionName );
445   }
446 }
447
448 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
449 {
450   if ( theRegion.IsNull() )
451     return;
452
453   RemoveReferenceObject( theRegion->Label(), DataTag_Region );
454
455   // Remove region from data model
456   Handle(HYDROData_CalculationCase) aFatherCalc = 
457     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
458   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
459     theRegion->Remove();
460 }
461
462 void HYDROData_CalculationCase::RemoveRegions()
463 {
464   myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes();
465 }
466
467 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetSplittedGroups() const
468 {
469   return GetReferenceObjects( DataTag_SplittedGroups );
470 }
471
472 void HYDROData_CalculationCase::RemoveSplittedGroups()
473 {
474   myLab.FindChild( DataTag_SplittedGroups ).ForgetAllAttributes();
475 }
476
477 TopoDS_Shell HYDROData_CalculationCase::GetShell()
478 {
479   TopoDS_Shell aShell;
480
481   TopTools_ListOfShape aFacesList;
482
483   // Make shell containing all region shapes
484   BRepBuilderAPI_Sewing aSewing( Precision::Confusion()*10.0 );
485
486   HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
487   HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
488   for ( ; aRegionIter.More(); aRegionIter.Next() ) {
489     Handle(HYDROData_Region) aRegion =
490       Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
491     if( aRegion.IsNull() ) {
492       continue;
493     }
494
495     TopoDS_Shape aRegionShape = aRegion->GetShape();
496     if( !aRegionShape.IsNull() ) {
497       if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
498         TopoDS_Face aFace = TopoDS::Face( aRegionShape );
499         if ( !aFace.IsNull() ) {
500           aFacesList.Append( aFace );
501           aSewing.Add( aFace );
502         }
503       } else {
504         TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
505         for ( ; anExp.More(); anExp.Next() ) {
506           TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
507           if ( !aFace.IsNull() ) {
508             aFacesList.Append( aFace );
509             aSewing.Add( aFace );
510           }
511         }
512       }
513     }
514   } // regions iterator
515   
516   aSewing.Perform();
517   TopoDS_Shape aSewedShape = aSewing.SewedShape();
518
519   if ( !aSewedShape.IsNull() )
520   {
521     if ( aSewedShape.ShapeType() == TopAbs_FACE && aCaseRegions.Length() ==1 ) {
522       // create shell from one face
523       BRep_Builder aBuilder;
524       aBuilder.MakeShell( aShell );
525       aBuilder.Add( aShell, aSewedShape);
526     } else {
527       TopExp_Explorer anExpShells( aSewedShape, TopAbs_SHELL );
528       Standard_Integer aNbOfShells = 0;
529       for ( ; anExpShells.More(); anExpShells.Next() ) {
530         aShell = TopoDS::Shell( anExpShells.Current() );
531         aNbOfShells++;
532       }
533
534       if ( aNbOfShells != 1 ) {
535         aShell.Nullify();
536         BRep_Builder aBuilder;
537         aBuilder.MakeShell( aShell );
538
539         TopExp_Explorer anExpFaces( aSewedShape, TopAbs_FACE );
540         for ( ; anExpFaces.More(); anExpFaces.Next() ) {
541           TopoDS_Face aFace = TopoDS::Face( anExpFaces.Current() );
542           if ( !aFace.IsNull() ) {
543             aBuilder.Add( aShell, aFace );
544           }
545         }
546       }
547     }
548   }
549
550   if ( !aShell.IsNull() ) {
551     TopTools_IndexedMapOfShape aMapOfFaces;
552     TopExp::MapShapes( aShell, TopAbs_FACE, aMapOfFaces );
553     if ( aMapOfFaces.Extent() != aFacesList.Extent() ) {
554       aShell.Nullify();
555       BRep_Builder aBuilder;
556       aBuilder.MakeShell( aShell );
557
558       TopTools_ListIteratorOfListOfShape anIter( aFacesList );
559       for ( ; anIter.More(); anIter.Next() ) {
560         TopoDS_Face aFace = TopoDS::Face( anIter.Value() );
561         aBuilder.Add( aShell, aFace );
562       }
563     }
564   }
565
566 /* TODO: old version
567   // Make shell
568   BRep_Builder aBuilder;
569   aBuilder.MakeShell( aShell );
570
571   // Make shell containing all region shapes
572   HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
573   HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
574   for ( ; aRegionIter.More(); aRegionIter.Next() ) {
575     Handle(HYDROData_Region) aRegion =
576       Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
577     if( aRegion.IsNull() ) {
578       continue;
579     }
580
581     TopoDS_Shape aRegionShape = aRegion->GetShape();
582
583     // Add shape (face or shell) corresponding to the region into the shell
584     if( !aRegionShape.IsNull() ) {
585       if ( aRegionShape.ShapeType() == TopAbs_FACE ) {
586         aBuilder.Add( aShell, aRegionShape );
587       } else {
588         TopExp_Explorer anExp( aRegionShape, TopAbs_FACE );
589         for( ; anExp.More(); anExp.Next() ) {
590           TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
591           if( !aFace.IsNull() ) {
592             aBuilder.Add( aShell, aFace );
593           }
594         }
595       }
596     }
597   } // regions iterator
598 */
599
600   // Nullify shell if it is empty
601   if ( !aShell.IsNull() && !TopoDS_Iterator(aShell).More() ) {
602     aShell.Nullify();
603   }
604
605   return aShell;
606 }
607
608 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY& thePoint ) const
609 {
610   double aResAltitude = HYDROData_Bathymetry::GetInvalidAltitude();
611
612   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
613   if ( aZone.IsNull() )
614     return aResAltitude;
615
616   HYDROData_Zone::MergeBathymetriesType aZoneMergeType = aZone->GetMergeType();
617   if ( !aZone->IsMergingNeed() )
618   {
619     aZoneMergeType = HYDROData_Zone::Merge_UNKNOWN;
620   }
621   else if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
622   {
623     return aResAltitude;
624   }
625
626   if ( aZoneMergeType == HYDROData_Zone::Merge_Object )
627   {
628     Handle(HYDROData_Bathymetry) aMergeBathymetry = aZone->GetMergeBathymetry();
629     if ( !aMergeBathymetry.IsNull() )
630       aResAltitude = aMergeBathymetry->GetAltitudeForPoint( thePoint );
631   }
632   else
633   {
634     HYDROData_SequenceOfObjects aZoneObjects = aZone->GetGeometryObjects();
635     HYDROData_SequenceOfObjects::Iterator anIter( aZoneObjects );
636     for ( ; anIter.More(); anIter.Next() )
637     {
638       Handle(HYDROData_Object) aZoneObj =
639         Handle(HYDROData_Object)::DownCast( anIter.Value() );
640       if ( aZoneObj.IsNull() )
641         continue;
642
643       Handle(HYDROData_Bathymetry) anObjBathymetry = aZoneObj->GetBathymetry();
644       if ( anObjBathymetry.IsNull() )
645         continue;
646
647       double aPointAltitude = anObjBathymetry->GetAltitudeForPoint( thePoint );
648       if ( ValuesEquals( aPointAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) )
649         continue;
650
651       if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
652       {
653         aResAltitude = aPointAltitude;
654         break;
655       }
656       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMIN )
657       {
658         if ( ValuesEquals( aResAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) ||
659              aResAltitude > aPointAltitude )
660         {
661           aResAltitude = aPointAltitude;
662         }
663       }
664       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMAX )
665       {
666         if ( ValuesEquals( aResAltitude, HYDROData_Bathymetry::GetInvalidAltitude() ) ||
667              aResAltitude < aPointAltitude )
668         {
669           aResAltitude = aPointAltitude;
670         }
671       }
672     }
673   }
674
675   return aResAltitude;
676 }
677
678 Handle(HYDROData_Zone) HYDROData_CalculationCase::GetZoneFromPoint( const gp_XY& thePoint ) const
679 {
680   Handle(HYDROData_Zone) aResZone;
681
682   HYDROData_SequenceOfObjects aRegions = GetRegions();
683
684   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
685   for ( ; anIter.More() && aResZone.IsNull(); anIter.Next() )
686   {
687     Handle(HYDROData_Region) aRegion =
688       Handle(HYDROData_Region)::DownCast( anIter.Value() );
689     if ( aRegion.IsNull() )
690       continue;
691
692     HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
693     HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
694     for ( ; aZonesIter.More() && aResZone.IsNull(); aZonesIter.Next() )
695     {
696       Handle(HYDROData_Zone) aRegZone =
697         Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
698       if ( aRegZone.IsNull() )
699         continue;
700
701       PointClassification aPointRelation = GetPointClassification( thePoint, aRegZone );
702       if ( aPointRelation != POINT_OUT )
703         aResZone = aRegZone; // We found the desired zone
704     }
705   }
706
707   return aResZone;
708 }
709
710 HYDROData_CalculationCase::PointClassification HYDROData_CalculationCase::GetPointClassification(
711   const gp_XY&                  thePoint,
712   const Handle(HYDROData_Zone)& theZone ) const
713 {
714   PointClassification aRes = POINT_OUT;
715   if ( theZone.IsNull() )
716     return aRes;
717
718   TopoDS_Face aZoneFace = TopoDS::Face( theZone->GetShape() );
719   if ( aZoneFace.IsNull() )
720     return aRes;
721
722   BRepTopAdaptor_FClass2d aClassifier( aZoneFace, Precision::Confusion() );
723   TopAbs_State State = aClassifier.Perform( gp_Pnt2d(thePoint), Standard_False );
724   if (State == TopAbs_OUT)
725         aRes =  POINT_OUT;
726   else if(State == TopAbs_IN)
727     aRes =  POINT_IN;
728   else if(State == TopAbs_ON)
729     aRes =  POINT_ON;     
730   return aRes;
731 }
732
733 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
734 {
735   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
736
737   Handle(HYDROData_Region) aNewRegion =
738     Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
739   AddRegion( aNewRegion );
740
741   return aNewRegion;
742 }
743
744 Handle(HYDROData_SplittedEdgesGroup) HYDROData_CalculationCase::addNewSplittedGroup()
745 {
746   TDF_Label aNewLab = myLab.FindChild( DataTag_SplittedGroups ).NewChild();
747
748   Handle(HYDROData_SplittedEdgesGroup) aNewGroup =
749     Handle(HYDROData_SplittedEdgesGroup)::DownCast( 
750       HYDROData_Iterator::CreateObject( aNewLab, KIND_SPLITTED_GROUP ) );
751   AddReferenceObject( aNewGroup, DataTag_SplittedGroups );
752
753   return aNewGroup;
754 }
755
756