Salome HOME
PR: quadtree
[modules/hydro.git] / src / HYDROData / HYDROData_CalculationCase.cxx
1
2 #include "HYDROData_CalculationCase.h"
3
4 #include "HYDROData_ArtificialObject.h"
5 #include "HYDROData_IAltitudeObject.h"
6 #include "HYDROData_Document.h"
7 #include "HYDROData_ShapesGroup.h"
8 #include "HYDROData_Iterator.h"
9 #include "HYDROData_NaturalObject.h"
10 #include "HYDROData_PolylineXY.h"
11 #include "HYDROData_SplitToZonesTool.h"
12 #include "HYDROData_SplittedShapesGroup.h"
13 #include "HYDROData_Region.h"
14 #include "HYDROData_Tool.h"
15 #include "HYDROData_Zone.h"
16
17 #include <GEOMBase.h>
18
19 #include <QSet>
20
21 #include <TopoDS.hxx>
22 #include <TopoDS_Shell.hxx>
23 #include <TopoDS_Edge.hxx>
24
25 #include <BRep_Builder.hxx>
26 #include <BRepBuilderAPI_Sewing.hxx>
27 #include <BRepTopAdaptor_FClass2d.hxx>
28
29 #include <BRepTools.hxx>
30
31 #include <TopAbs.hxx>
32 #include <TopExp_Explorer.hxx>
33 #include <TopExp.hxx>
34 #include <TopTools_ListOfShape.hxx>
35 #include <TopTools_ListIteratorOfListOfShape.hxx>
36
37 //#define  DEB_CALCULATION 1
38 #ifdef DEB_CALCULATION
39 #include <BRepTools.hxx>
40 #include <TopLoc_Location.hxx>
41 #endif 
42 #define CALCULATION_REGIONS_PREF GetName() + "_Reg"
43 #define CALCULATION_ZONES_PREF GetName() + "_Zone"
44 #define CALCULATION_GROUPS_PREF GetName() + "_"
45 //#define DEB_CLASS2D 1
46 #ifdef DEB_CLASS2D
47 #include <BRepBuilderAPI_MakeVertex.hxx>
48 #endif
49
50 #define EXPORT_NAME "HYDRO_" + GetName()
51
52 #define _DEVDEBUG_
53 #include "HYDRO_trace.hxx"
54
55 IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
56 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
57
58 HYDROData_CalculationCase::HYDROData_CalculationCase()
59 : HYDROData_Entity()
60 {
61 }
62
63 HYDROData_CalculationCase::~HYDROData_CalculationCase()
64 {
65 }
66
67 void HYDROData_CalculationCase::SetName( const QString& theName )
68 {
69   QString anOldCaseName = GetName();
70   if ( anOldCaseName != theName )
71   {
72     HYDROData_SequenceOfObjects aRegions = GetRegions();
73
74     HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
75     for ( ; anIter.More(); anIter.Next() )
76     {
77       Handle(HYDROData_Region) aRegion =
78         Handle(HYDROData_Region)::DownCast( anIter.Value() );
79       if ( aRegion.IsNull() )
80         continue;
81
82       HYDROData_Tool::UpdateChildObjectName( anOldCaseName, theName, aRegion );
83
84       HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
85       HYDROData_SequenceOfObjects::Iterator anIter( aZones );
86       for ( ; anIter.More(); anIter.Next() )
87       {
88         Handle(HYDROData_Zone) aRegZone =
89           Handle(HYDROData_Zone)::DownCast( anIter.Value() );
90         if ( aRegZone.IsNull() )
91           continue;
92
93         HYDROData_Tool::UpdateChildObjectName( anOldCaseName, theName, aRegZone );
94       }
95     }
96
97     HYDROData_SequenceOfObjects aGroups = GetSplittedGroups();
98
99     anIter.Init( aGroups );
100     for ( ; anIter.More(); anIter.Next() )
101     {
102       Handle(HYDROData_SplittedShapesGroup) aGroup =
103         Handle(HYDROData_SplittedShapesGroup)::DownCast( anIter.Value() );
104       if ( aGroup.IsNull() )
105         continue;
106
107       HYDROData_Tool::UpdateChildObjectName( anOldCaseName, theName, aGroup );
108     }
109   }
110
111   HYDROData_Entity::SetName( theName );
112 }
113
114 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
115 {
116   QStringList aResList = dumpObjectCreation( theTreatedObjects );
117
118   QString aCalculName = GetObjPyName();
119
120   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
121   HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
122   for ( ; anIter.More(); anIter.Next() )
123   {
124     Handle(HYDROData_Object) aRefGeomObj =
125       Handle(HYDROData_Object)::DownCast( anIter.Value() );
126     setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
127   }
128   aResList << QString( "" );
129
130   QString aGroupName = HYDROData_Tool::GenerateNameForPython( theTreatedObjects, "case_geom_group" );
131
132   HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
133   anIter.Init( aGeomGroups );
134   for ( ; anIter.More(); anIter.Next() )
135   {
136     Handle(HYDROData_ShapesGroup) aGeomGroup =
137       Handle(HYDROData_ShapesGroup)::DownCast( anIter.Value() );
138     if ( aGeomGroup.IsNull() )
139       continue;
140
141     Handle(HYDROData_Object) aFatherGeom =
142       Handle(HYDROData_Object)::DownCast( aGeomGroup->GetFatherObject() );
143     if ( aFatherGeom.IsNull() )
144       continue;
145
146     int aGroupId = aFatherGeom->GetGroupId( aGeomGroup );
147     aResList << QString( "%1 = %2.GetGroup( %3 );" )
148               .arg( aGroupName ).arg( aFatherGeom->GetObjPyName() ).arg( aGroupId );
149
150     aResList << QString( "%1.AddGeometryGroup( %2 );" ).arg( aCalculName ).arg( aGroupName );
151   }
152   aResList << QString( "" );
153
154   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
155   setPythonReferenceObject( theTreatedObjects, aResList, aBoundaryPolyline, "SetBoundaryPolyline" );
156   aResList << QString( "" );
157
158   aResList << QString( "%1.Update();" ).arg( aCalculName );
159   aResList << QString( "" );
160
161   // Now we restore the regions and zones order
162   HYDROData_SequenceOfObjects aRegions = GetRegions();
163   anIter.Init( aRegions );
164   for ( ; anIter.More(); anIter.Next() )
165   {
166     Handle(HYDROData_Region) aRegion =
167       Handle(HYDROData_Region)::DownCast( anIter.Value() );
168     if ( aRegion.IsNull() )
169       continue;
170
171     QString aRegionName = aRegion->GetName();
172
173     HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
174     HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
175     for ( ; aZonesIter.More(); aZonesIter.Next() )
176     {
177       Handle(HYDROData_Zone) aRegZone =
178         Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
179       if ( aRegZone.IsNull() )
180         continue;
181
182       // TODO
183     }
184   }
185   aResList << QString( "" );
186
187   return aResList;
188 }
189
190 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetAllReferenceObjects() const
191 {
192   HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
193
194   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
195   if ( !aBoundaryPolyline.IsNull() )
196     aResSeq.Append( aBoundaryPolyline );
197
198   HYDROData_SequenceOfObjects aSeqOfRegions = GetRegions();
199   aResSeq.Append( aSeqOfRegions );
200
201   return aResSeq;
202 }
203
204 void HYDROData_CalculationCase::Update()
205 {
206   HYDROData_Entity::Update();
207
208   // At first we remove previously created objects
209   RemoveRegions();
210   RemoveSplittedGroups();
211
212   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
213   if ( aDocument.IsNull() )
214     return;
215
216   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
217   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
218   if ( aGeomObjects.IsEmpty() )
219     return;
220
221   HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
222
223   HYDROData_SplitToZonesTool::SplitDataList aSplitedObjects =
224     HYDROData_SplitToZonesTool::Split( aGeomObjects, aGeomGroups, aBoundaryPolyline );
225   if ( aSplitedObjects.isEmpty() )
226     return;
227
228   QString aRegsPref = CALCULATION_REGIONS_PREF;
229   QString aZonesPref = CALCULATION_ZONES_PREF;
230
231   QMap<QString,Handle(HYDROData_SplittedShapesGroup)> aSplittedEdgesGroupsMap;
232
233   // Create result regions for case, by default one zone for one region
234   HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedObjects );
235   while( anIter.hasNext() )
236   {
237     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
238
239     if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone )
240     {
241       // Create new region
242       Handle(HYDROData_Region) aRegion = addNewRegion();
243
244       QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
245       aRegion->SetName( aRegionName );
246
247       // Add the zone for region
248       Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
249
250       QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
251       aRegionZone->SetName( aZoneName );
252
253       aRegionZone->SetShape( aSplitData.Face() );
254
255       // Add the reference object for zone
256       for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
257       {
258         const QString& anObjName = aSplitData.ObjectNames.at( i );
259         
260         Handle(HYDROData_Object) aRefObject = 
261           Handle(HYDROData_Object)::DownCast( aDocument->FindObjectByName( anObjName ) );
262         if ( aRefObject.IsNull() )
263           continue;
264
265         aRegionZone->AddGeometryObject( aRefObject );
266       }
267     }
268     else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge )
269     {
270       // Create new edges group
271       if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
272         continue;
273
274       QString anObjName = aSplitData.ObjectNames.first();
275       if ( anObjName.isEmpty() )
276         continue;
277 #ifdef DEB_CALCULATION
278       QString aStr = aSplitData.ObjectNames.join(" "); 
279           cout << " CCase: Names = "<<aStr.toStdString() << " size = " <<aSplitData.ObjectNames.size() <<endl; 
280 #endif
281       Handle(HYDROData_SplittedShapesGroup) aSplittedGroup;
282       if ( !aSplittedEdgesGroupsMap.contains( anObjName ) )
283       {
284         aSplittedGroup = addNewSplittedGroup();
285
286         QString aCalcGroupName = CALCULATION_GROUPS_PREF + anObjName;
287         aSplittedGroup->SetName( aCalcGroupName );
288
289         aSplittedEdgesGroupsMap.insert( anObjName, aSplittedGroup );
290       }
291       else
292       {
293         aSplittedGroup = aSplittedEdgesGroupsMap[ anObjName ];
294       }
295
296       if ( aSplittedGroup.IsNull() )
297         continue;
298
299       aSplittedGroup->AddShape( aSplitData.Shape );
300     }
301   }
302 }
303
304 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
305 {
306   if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
307     return false; // Wrong type of object
308
309   if ( HasReference( theObject, DataTag_GeometryObject ) )
310     return false; // Object is already in reference list
311
312   AddReferenceObject( theObject, DataTag_GeometryObject );
313   
314   // Indicate model of the need to update splitting
315   SetToUpdate( true );
316
317   return true;
318 }
319
320 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
321 {
322   return GetReferenceObjects( DataTag_GeometryObject );
323 }
324
325 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
326 {
327   if ( theObject.IsNull() )
328     return;
329
330   RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
331
332   // Indicate model of the need to update splitting
333   SetToUpdate( true );
334 }
335
336 void HYDROData_CalculationCase::RemoveGeometryObjects()
337 {
338   ClearReferenceObjects( DataTag_GeometryObject );
339
340   // Indicate model of the need to update splitting
341   SetToUpdate( true );
342 }
343
344 bool HYDROData_CalculationCase::AddGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
345 {
346   if ( theGroup.IsNull() )
347     return false;
348
349   if ( HasReference( theGroup, DataTag_GeometryGroup ) )
350     return false; // Object is already in reference list
351
352   AddReferenceObject( theGroup, DataTag_GeometryGroup );
353   
354   // Indicate model of the need to update splitting
355   SetToUpdate( true );
356
357   return true;
358 }
359
360 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryGroups() const
361 {
362   return GetReferenceObjects( DataTag_GeometryGroup );
363 }
364
365 void HYDROData_CalculationCase::RemoveGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
366 {
367   if ( theGroup.IsNull() )
368     return;
369
370   RemoveReferenceObject( theGroup->Label(), DataTag_GeometryGroup );
371
372   // Indicate model of the need to update splitting
373   SetToUpdate( true );
374 }
375
376 void HYDROData_CalculationCase::RemoveGeometryGroups()
377 {
378   ClearReferenceObjects( DataTag_GeometryGroup );
379
380   // Indicate model of the need to update splitting
381   SetToUpdate( true );
382 }
383
384 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
385 {
386   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
387
388   SetReferenceObject( thePolyline, DataTag_Polyline );
389
390   // Indicate model of the need to update zones splitting
391   SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
392 }
393
394 Handle(HYDROData_PolylineXY) HYDROData_CalculationCase::GetBoundaryPolyline() const
395 {
396   return Handle(HYDROData_PolylineXY)::DownCast( 
397            GetReferenceObject( DataTag_Polyline ) );
398 }
399
400 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
401 {
402   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
403
404   ClearReferenceObjects( DataTag_Polyline );
405
406   // Indicate model of the need to update zones splitting
407   SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
408 }
409
410 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
411 {
412   Handle(HYDROData_Region) aNewRegion = addNewRegion();
413   if ( aNewRegion.IsNull() )
414     return aNewRegion;
415
416   // Generate new name for new region
417   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
418   if ( !aDocument.IsNull() )
419   {
420     QString aRegsPref = CALCULATION_REGIONS_PREF;
421
422     QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
423     aNewRegion->SetName( aNewRegionName );
424   }
425
426   aNewRegion->AddZone( theZone );
427
428   return aNewRegion;
429 }
430
431 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
432 {
433   if ( theRegion.IsNull() )
434     return false;
435   
436   if ( HasReference( theRegion, DataTag_Region ) )
437     return false; // Object is already in reference list
438
439   // Move the region from other calculation
440   Handle(HYDROData_CalculationCase) aFatherCalc = 
441     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
442   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
443   {
444     Handle(HYDROData_Region) aNewRegion = addNewRegion();
445     theRegion->CopyTo( aNewRegion );
446
447     aFatherCalc->RemoveRegion( theRegion );
448
449     theRegion->SetLabel( aNewRegion->Label() );
450   }
451   else
452   {
453     AddReferenceObject( theRegion, DataTag_Region );
454   }
455
456   return true;
457 }
458
459 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
460 {
461   return GetReferenceObjects( DataTag_Region );
462 }
463
464 void HYDROData_CalculationCase::UpdateRegionsOrder()
465 {
466   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
467   if ( aDocument.IsNull() )
468     return;
469
470   HYDROData_SequenceOfObjects aRegions = GetRegions();
471
472   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
473   for ( ; anIter.More(); anIter.Next() )
474   {
475     Handle(HYDROData_Region) aRegion =
476       Handle(HYDROData_Region)::DownCast( anIter.Value() );
477     if ( aRegion.IsNull() )
478       continue;
479
480     aRegion->SetName( "" );
481   }
482
483   QString aRegsPref = CALCULATION_REGIONS_PREF;
484
485   anIter.Init( aRegions );
486   for ( ; anIter.More(); anIter.Next() )
487   {
488     Handle(HYDROData_Region) aRegion =
489       Handle(HYDROData_Region)::DownCast( anIter.Value() );
490     if ( aRegion.IsNull() )
491       continue;
492
493     QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
494     aRegion->SetName( aRegionName );
495   }
496 }
497
498 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
499 {
500   if ( theRegion.IsNull() )
501     return;
502
503   RemoveReferenceObject( theRegion->Label(), DataTag_Region );
504
505   // Remove region from data model
506   Handle(HYDROData_CalculationCase) aFatherCalc = 
507     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
508   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
509     theRegion->Remove();
510 }
511
512 void HYDROData_CalculationCase::RemoveRegions()
513 {
514   myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes();
515 }
516
517 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetSplittedGroups() const
518 {
519   return GetReferenceObjects( DataTag_SplittedGroups );
520 }
521
522 void HYDROData_CalculationCase::RemoveSplittedGroups()
523 {
524   myLab.FindChild( DataTag_SplittedGroups ).ForgetAllAttributes();
525 }
526
527 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY& thePoint ) const
528 {
529   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
530   return GetAltitudeForPoint( thePoint, aZone );
531 }
532
533 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY&                    thePoint,
534                                                        const Handle(HYDROData_Region)& theRegion ) const
535 {
536   double aResAltitude = HYDROData_IAltitudeObject::GetInvalidAltitude();
537
538   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
539   if ( !aZone.IsNull() )
540   {
541     //DEBTRACE("GetAltitudeForPoint Region " << theRegion->GetName().toStdString() << " Zone " << aZone->GetName().toStdString());
542     Handle(HYDROData_Region) aRefRegion = Handle(HYDROData_Region)::DownCast( aZone->GetFatherObject() );
543     if ( IsEqual( aRefRegion, theRegion ) )
544       aResAltitude = GetAltitudeForPoint( thePoint, aZone );
545     else
546       {
547         DEBTRACE("GetAltitudeForPoint Region " << aRefRegion->GetName().toStdString() << " Zone " << aZone->GetName().toStdString() << " ---------------------------");
548         aResAltitude = GetAltitudeForPoint( thePoint, aZone );
549       }
550   }
551   else
552     {
553       DEBTRACE(" --- GetAltitudeForPoint No Zone ---");
554     }
555
556   return aResAltitude;
557 }
558
559 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY&                  thePoint,
560                                                        const Handle(HYDROData_Zone)& theZone ) const
561 {
562   //DEBTRACE("GetAltitudeForPoint Zone " << theZone->GetName().toStdString());
563   double aResAltitude = HYDROData_IAltitudeObject::GetInvalidAltitude();
564   if ( theZone.IsNull() )
565     return aResAltitude;
566
567   HYDROData_Zone::MergeAltitudesType aZoneMergeType = theZone->GetMergeType();
568   if ( !theZone->IsMergingNeed() )
569   {
570     aZoneMergeType = HYDROData_Zone::Merge_UNKNOWN;
571   }
572   else if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
573   {
574     return aResAltitude;
575   }
576
577   HYDROData_IInterpolator* aZoneInterpolator = theZone->GetInterpolator();
578   if ( aZoneMergeType == HYDROData_Zone::Merge_Object )
579   {
580     Handle(HYDROData_IAltitudeObject) aMergeAltitude = theZone->GetMergeAltitude();
581     if ( !aMergeAltitude.IsNull() )
582     {
583       if ( aZoneInterpolator != NULL )
584       {
585         aZoneInterpolator->SetAltitudeObject( aMergeAltitude );
586         aResAltitude = aZoneInterpolator->GetAltitudeForPoint( thePoint );
587       }
588       else
589         aResAltitude = aMergeAltitude->GetAltitudeForPoint( thePoint );
590     }
591   }
592   else
593   {
594     HYDROData_SequenceOfObjects aZoneObjects = theZone->GetGeometryObjects();
595     HYDROData_SequenceOfObjects::Iterator anIter( aZoneObjects );
596     for ( ; anIter.More(); anIter.Next() )
597     {
598       Handle(HYDROData_Object) aZoneObj =
599         Handle(HYDROData_Object)::DownCast( anIter.Value() );
600       if ( aZoneObj.IsNull() )
601         continue;
602
603       Handle(HYDROData_IAltitudeObject) anObjAltitude = aZoneObj->GetAltitudeObject();
604       if ( anObjAltitude.IsNull() )
605         continue;
606
607       double aPointAltitude = 0.0;
608       if ( aZoneInterpolator != NULL )
609       {
610         aZoneInterpolator->SetAltitudeObject( anObjAltitude );
611         aPointAltitude = aZoneInterpolator->GetAltitudeForPoint( thePoint );
612       }
613       else
614         aPointAltitude = anObjAltitude->GetAltitudeForPoint( thePoint );
615
616       if ( ValuesEquals( aPointAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) )
617         continue;
618
619       if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
620       {
621         aResAltitude = aPointAltitude;
622         break;
623       }
624       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMIN )
625       {
626         if ( ValuesEquals( aResAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) ||
627              aResAltitude > aPointAltitude )
628         {
629           aResAltitude = aPointAltitude;
630         }
631       }
632       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMAX )
633       {
634         if ( ValuesEquals( aResAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) ||
635              aResAltitude < aPointAltitude )
636         {
637           aResAltitude = aPointAltitude;
638         }
639       }
640     }
641   }
642
643   return aResAltitude;
644 }
645
646 NCollection_Sequence<double> HYDROData_CalculationCase::GetAltitudesForPoints( 
647   const NCollection_Sequence<gp_XY>& thePoints,
648   const Handle(HYDROData_Region)&    theRegion ) const
649 {
650   //DEBTRACE("HYDROData_CalculationCase::GetAltitudesForPoints " << theRegion->GetName().toStdString());
651   NCollection_Sequence<double> aResSeq;
652
653   for ( int i = 1, n = thePoints.Length(); i <= n; ++i )
654   {
655     const gp_XY& thePnt = thePoints.Value( i );
656     
657     double anAltitude = GetAltitudeForPoint( thePnt, theRegion );
658     aResSeq.Append( anAltitude );
659   }
660
661   return aResSeq;
662 }
663
664 NCollection_Sequence<double> HYDROData_CalculationCase::GetAltitudesForPoints( 
665   const NCollection_Sequence<gp_XY>& thePoints,
666   const Handle(HYDROData_Zone)&      theZone ) const
667 {
668   NCollection_Sequence<double> aResSeq;
669
670   for ( int i = 1, n = thePoints.Length(); i <= n; ++i )
671   {
672     const gp_XY& thePnt = thePoints.Value( i );
673     
674     double anAltitude = GetAltitudeForPoint( thePnt, theZone );
675     aResSeq.Append( anAltitude );
676   }
677
678   return aResSeq;
679 }
680
681 Handle(HYDROData_Region) HYDROData_CalculationCase::GetRegionFromPoint( const gp_XY& thePoint ) const
682 {
683   Handle(HYDROData_Region) aResRegion;
684
685   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
686   if ( !aZone.IsNull() )
687     aResRegion = Handle(HYDROData_Region)::DownCast( aZone->GetFatherObject() );
688
689   return aResRegion;
690 }
691
692 Handle(HYDROData_Zone) HYDROData_CalculationCase::GetZoneFromPoint( const gp_XY& thePoint ) const
693 {
694   Handle(HYDROData_Zone) aResZone;
695
696   HYDROData_SequenceOfObjects aRegions = GetRegions();
697
698   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
699   for ( ; anIter.More() && aResZone.IsNull(); anIter.Next() )
700   {
701     Handle(HYDROData_Region) aRegion =
702       Handle(HYDROData_Region)::DownCast( anIter.Value() );
703     if ( aRegion.IsNull() )
704       continue;
705
706     HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
707     HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
708     for ( ; aZonesIter.More() && aResZone.IsNull(); aZonesIter.Next() )
709     {
710       Handle(HYDROData_Zone) aRegZone =
711         Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
712       if ( aRegZone.IsNull() )
713         continue;
714
715       PointClassification aPointRelation = GetPointClassification( thePoint, aRegZone );
716       if ( aPointRelation != POINT_OUT )
717         aResZone = aRegZone; // We found the desired zone
718     }
719   }
720
721   return aResZone;
722 }
723
724 HYDROData_CalculationCase::PointClassification HYDROData_CalculationCase::GetPointClassification(
725   const gp_XY&                  thePoint,
726   const Handle(HYDROData_Zone)& theZone ) const
727 {
728   PointClassification aRes = POINT_OUT;
729   if ( theZone.IsNull() )
730     return aRes;
731
732   TopoDS_Face aZoneFace = TopoDS::Face( theZone->GetShape() );
733   if ( aZoneFace.IsNull() )
734     return aRes;
735 #ifdef DEB_CLASS2D      
736           TopoDS_Compound aCmp;
737       BRep_Builder aBB;
738       aBB.MakeCompound(aCmp);
739           aBB.Add(aCmp, aZoneFace);
740           gp_Pnt aPnt (thePoint.X(), thePoint.Y(), 0.);
741           BRepBuilderAPI_MakeVertex aMk(aPnt);
742           aBB.Add(aCmp, aMk.Vertex());
743           BRepTools::Write(aCmp, "FCL2d.brep");
744 #endif  
745   TopAbs_State State = HYDROData_Tool::ComputePointState(thePoint, aZoneFace);
746   if (State == TopAbs_OUT)
747     aRes =  POINT_OUT;
748   else if(State == TopAbs_IN)
749     aRes =  POINT_IN;
750   else if(State == TopAbs_ON)
751     aRes =  POINT_ON;
752   return aRes;
753 }
754
755 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
756 {
757   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
758
759   Handle(HYDROData_Region) aNewRegion =
760     Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
761   AddRegion( aNewRegion );
762
763   return aNewRegion;
764 }
765
766 Handle(HYDROData_SplittedShapesGroup) HYDROData_CalculationCase::addNewSplittedGroup()
767 {
768   TDF_Label aNewLab = myLab.FindChild( DataTag_SplittedGroups ).NewChild();
769
770   Handle(HYDROData_SplittedShapesGroup) aNewGroup =
771     Handle(HYDROData_SplittedShapesGroup)::DownCast( 
772       HYDROData_Iterator::CreateObject( aNewLab, KIND_SPLITTED_GROUP ) );
773   AddReferenceObject( aNewGroup, DataTag_SplittedGroups );
774
775   return aNewGroup;
776 }
777
778 bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var  theGeomEngine,
779                                         SALOMEDS::Study_ptr theStudy ) const
780 {
781   HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfGroupsDefs;
782
783   // Get groups definitions
784   HYDROData_SequenceOfObjects aSplittedGroups = GetSplittedGroups();
785
786   HYDROData_SequenceOfObjects::Iterator anIter( aSplittedGroups );
787   for ( ; anIter.More(); anIter.Next() )
788   {
789     // Get shapes group
790     Handle(HYDROData_ShapesGroup) aGroup =
791       Handle(HYDROData_ShapesGroup)::DownCast( anIter.Value() );
792     if ( aGroup.IsNull() )
793       continue;
794
795     HYDROData_ShapesGroup::GroupDefinition aGroupDef;
796
797     aGroupDef.Name = aGroup->GetName().toLatin1().constData();
798     aGroup->GetShapes( aGroupDef.Shapes );
799
800     aSeqOfGroupsDefs.Append( aGroupDef );
801   }
802   
803   // Get faces
804   TopTools_ListOfShape aFaces;
805   HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
806   HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
807   for ( ; aRegionIter.More(); aRegionIter.Next() )
808   {
809     Handle(HYDROData_Region) aRegion =
810       Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
811     if( aRegion.IsNull() )
812       continue;
813
814     TopoDS_Shape aRegionShape = aRegion->GetShape( &aSeqOfGroupsDefs );
815     aFaces.Append( aRegionShape );
816   }
817
818   return Export( theGeomEngine, theStudy, aFaces, aSeqOfGroupsDefs );
819 }
820
821 bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var                            theGeomEngine,
822                                         SALOMEDS::Study_ptr                           theStudy,
823                                         const TopTools_ListOfShape&                   theFaces,
824                                         const HYDROData_ShapesGroup::SeqOfGroupsDefs& theGroupsDefs ) const
825 {
826   // Sew faces
827   BRepBuilderAPI_Sewing aSewing( Precision::Confusion() * 10.0 );
828   aSewing.SetNonManifoldMode( Standard_False );
829 #ifdef DEB_CALCULATION
830   TCollection_AsciiString aNam("Sh_");
831   int i=1;
832 #endif
833   TopTools_ListIteratorOfListOfShape aFaceIter( theFaces );
834   for ( ; aFaceIter.More(); aFaceIter.Next() )
835   {
836     TopoDS_Shape aShape = aFaceIter.Value();
837     if ( aShape.IsNull() )
838       continue;
839
840     if ( aShape.ShapeType() == TopAbs_FACE )
841     {
842       aSewing.Add( aShape );
843 #ifdef DEB_CALCULATION
844       TCollection_AsciiString aName = aNam + ++i + ".brep";
845       BRepTools::Write(aShape ,aName.ToCString());
846 #endif
847     }
848     else
849     {
850 #ifdef DEB_CALCULATION
851       int j = 1;
852 #endif
853       TopExp_Explorer anExp( aShape, TopAbs_FACE );
854       for (; anExp.More(); anExp.Next() ) {
855         aSewing.Add( anExp.Current() );
856 #ifdef DEB_CALCULATION
857
858         TCollection_AsciiString aName = aNam + i + "_" + ++j + ".brep";
859         BRepTools::Write(anExp.Current() ,aName.ToCString());
860 #endif
861       }
862     }
863   } // faces iterator
864   
865   aSewing.Perform();
866   TopoDS_Shape aSewedShape = aSewing.SewedShape();
867
868   // If the sewed shape is empty - return false
869   if ( aSewedShape.IsNull() || !TopoDS_Iterator( aSewedShape ).More() )
870     return false;
871
872 #ifdef DEB_CALCULATION
873   BRepTools::Write(aSewedShape ,"Sew.brep");
874 #endif
875   // Publish the sewed shape
876   QString aName = EXPORT_NAME;
877   GEOM::GEOM_Object_ptr aMainShape = 
878     publishShapeInGEOM( theGeomEngine, theStudy, aSewedShape, aName );
879
880   if ( aMainShape->_is_nil() )  
881     return false;
882
883   if ( theGroupsDefs.IsEmpty() )
884     return true;
885
886   // Create groups
887   TopTools_IndexedMapOfShape aMapOfSubShapes;
888   TopExp::MapShapes( aSewedShape, aMapOfSubShapes );
889
890   NCollection_DataMap< TCollection_AsciiString, NCollection_Sequence<int> > aGroupsData;
891
892   for ( int aGrId = 1, nbGroups = theGroupsDefs.Length(); aGrId <= nbGroups; ++aGrId )
893   {
894     const HYDROData_ShapesGroup::GroupDefinition& aGroupDef = theGroupsDefs.Value( aGrId );
895
896     NCollection_Sequence<int> aGroupIndexes;
897     for( int i = 1, n = aGroupDef.Shapes.Length(); i <= n; i++ )
898     {
899       const TopoDS_Shape& aShape = aGroupDef.Shapes.Value( i );
900 #ifdef DEB_CALCULATION
901       cout << "\nOld shape(" << i << ") = " << aShape.TShape() <<endl;
902 #endif
903       
904       TopoDS_Shape aModifiedShape = aShape;
905       if ( aSewing.IsModified( aShape ) )
906         aModifiedShape = aSewing.Modified( aShape );
907       else if ( aSewing.IsModifiedSubShape( aShape ) )
908         aModifiedShape = aSewing.ModifiedSubShape( aShape );
909
910 #ifdef DEB_CALCULATION
911       const TopLoc_Location& aL1 = aShape.Location();
912       const TopLoc_Location& aL2 = aModifiedShape.Location();
913       cout << "\nNew shape(" << i << ") = " << aModifiedShape.TShape() << " Location is Equal = " << aL1.IsEqual(aL2)<<endl;
914 #endif
915
916       int anIndex = aMapOfSubShapes.FindIndex(aModifiedShape);
917       if ( anIndex > 0 ) {
918         aGroupIndexes.Append( anIndex );
919       } else {
920 #ifdef DEB_CALCULATION    
921         TCollection_AsciiString aNam("Lost_");
922         if(!aMapOfSubShapes.Contains(aModifiedShape)) {
923         for ( int anIndex = 1; anIndex <= aMapOfSubShapes.Extent(); anIndex++ )
924         {
925            const TopoDS_Shape& aS = aMapOfSubShapes.FindKey( anIndex );
926            if ( aModifiedShape.IsPartner( aS ) )
927            {
928              cout <<"\nIndex in Map = " << anIndex << "TShape = " << aS.TShape() <<endl;
929              TCollection_AsciiString aName = aNam + i + "_" + anIndex + ".brep";
930              BRepTools::Write(aS ,aName.ToCString());
931             break;
932            }
933          }
934         }
935 #endif
936       }
937     }
938     if ( !aGroupIndexes.IsEmpty() )
939       aGroupsData.Bind( aGroupDef.Name, aGroupIndexes );
940   }
941  
942   if ( !aGroupsData.IsEmpty() )
943   {
944     GEOM::GEOM_IGroupOperations_var aGroupOp = 
945       theGeomEngine->GetIGroupOperations( theStudy->StudyId() );  
946
947     NCollection_DataMap< TCollection_AsciiString, NCollection_Sequence<int> >::Iterator aMapIt( aGroupsData );
948     for ( ; aMapIt.More(); aMapIt.Next() )
949     {
950       const TCollection_AsciiString& aGroupName = aMapIt.Key(); 
951       const NCollection_Sequence<int>& aGroupIndexes = aMapIt.Value();
952
953       GEOM::GEOM_Object_var aGeomGroup = aGroupOp->CreateGroup( aMainShape, TopAbs_EDGE );
954       if ( CORBA::is_nil( aGeomGroup ) || !aGroupOp->IsDone() )
955         continue;
956
957       GEOM::ListOfLong_var aGeomIndexes = new GEOM::ListOfLong;
958       aGeomIndexes->length( aGroupIndexes.Length() );
959
960       for( int i = 1, n = aGroupIndexes.Length(); i <= n; i++ )
961         aGeomIndexes[ i - 1 ] = aGroupIndexes.Value( i );
962
963       aGroupOp->UnionIDs( aGeomGroup, aGeomIndexes );
964       if ( aGroupOp->IsDone() )
965       {
966         SALOMEDS::SObject_var aGroupSO = 
967           theGeomEngine->AddInStudy( theStudy, aGeomGroup, aGroupName.ToCString(), aMainShape );
968       }
969     }
970   }
971
972   return true;
973 }
974
975 GEOM::GEOM_Object_ptr HYDROData_CalculationCase::publishShapeInGEOM( 
976   GEOM::GEOM_Gen_var theGeomEngine, SALOMEDS::Study_ptr theStudy,
977   const TopoDS_Shape& theShape, const QString& theName ) const
978 {
979   GEOM::GEOM_Object_var aGeomObj;
980
981   if ( theGeomEngine->_is_nil() || theStudy->_is_nil() ||
982        theShape.IsNull() ) {
983     return aGeomObj._retn();
984   }
985
986   std::ostringstream aStreamShape;
987   // Write TopoDS_Shape in ASCII format to the stream
988   BRepTools::Write( theShape, aStreamShape );
989   // Returns the number of bytes that have been stored in the stream's buffer.
990   int aSize = aStreamShape.str().size();
991   // Allocate octect buffer of required size
992   CORBA::Octet* anOctetBuf = SALOMEDS::TMPFile::allocbuf( aSize );
993   // Copy ostrstream content to the octect buffer
994   memcpy( anOctetBuf, aStreamShape.str().c_str(), aSize );
995   // Create TMPFile
996   SALOMEDS::TMPFile_var aSeqFile = new SALOMEDS::TMPFile( aSize, aSize, anOctetBuf, 1 );
997
998   // Restore shape from the stream and get the GEOM object
999   GEOM::GEOM_IInsertOperations_var anInsOp = theGeomEngine->GetIInsertOperations( theStudy->StudyId() );
1000   aGeomObj = anInsOp->RestoreShape( aSeqFile );
1001   
1002   // Puplish the GEOM object
1003   if ( !aGeomObj->_is_nil() ) {
1004     QString aName = GEOMBase::GetDefaultName( theName );
1005
1006     SALOMEDS::SObject_var aResultSO = 
1007       theGeomEngine->PublishInStudy( theStudy, SALOMEDS::SObject::_nil(), 
1008                                      aGeomObj, qPrintable( aName ) );
1009     if ( aResultSO->_is_nil() ) {
1010       aGeomObj = GEOM::GEOM_Object::_nil();
1011     }
1012   }
1013
1014   return aGeomObj._retn();
1015  }