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