Salome HOME
46cf97ba08a52f3f79aa81cc35b0f1048e0a43d8
[modules/hydro.git] / src / HYDROData / HYDROData_CalculationCase.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROData_CalculationCase.h"
20 #include "HYDROData_ArtificialObject.h"
21 #include "HYDROData_IAltitudeObject.h"
22 #include "HYDROData_Document.h"
23 #include "HYDROData_ShapesGroup.h"
24 #include "HYDROData_Iterator.h"
25 #include "HYDROData_NaturalObject.h"
26 #include "HYDROData_PolylineXY.h"
27 #include "HYDROData_StricklerTable.h"
28 #include "HYDROData_SplittedShapesGroup.h"
29 #include "HYDROData_Region.h"
30 #include "HYDROData_Tool.h"
31 #include "HYDROData_GeomTool.h"
32
33 #ifdef WIN32
34   #pragma warning ( disable: 4251 )
35 #endif
36
37 #ifndef LIGHT_MODE
38 #include <GEOMBase.h>
39 #endif
40
41 #ifdef WIN32
42   #pragma warning ( default: 4251 )
43 #endif
44
45 #include <QSet>
46
47 #include <TopoDS.hxx>
48 #include <TopoDS_Shell.hxx>
49 #include <TopoDS_Edge.hxx>
50
51 #include <BRep_Builder.hxx>
52 #include <BRepBuilderAPI_Sewing.hxx>
53 #include <BRepTopAdaptor_FClass2d.hxx>
54
55 #include <BRepTools.hxx>
56
57 #include <TopAbs.hxx>
58 #include <TopExp_Explorer.hxx>
59 #include <TopExp.hxx>
60 #include <TopTools_ListOfShape.hxx>
61 #include <TopTools_ListIteratorOfListOfShape.hxx>
62 #include <TDataStd_Integer.hxx>
63
64 //#define  DEB_CALCULATION 1
65 #ifdef DEB_CALCULATION
66 #include <BRepTools.hxx>
67 #include <TopLoc_Location.hxx>
68 #endif 
69 #define CALCULATION_REGIONS_PREF GetName() + "_Reg"
70 #define CALCULATION_ZONES_PREF GetName() + "_Zone"
71 #define CALCULATION_GROUPS_PREF GetName() + "_"
72 //#define DEB_CLASS2D 1
73 #ifdef DEB_CLASS2D
74 #include <BRepBuilderAPI_MakeVertex.hxx>
75 #endif
76
77 #define EXPORT_NAME "HYDRO_" + GetName()
78
79 IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
80 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
81
82 HYDROData_CalculationCase::HYDROData_CalculationCase()
83 : HYDROData_Entity( Geom_2d_and_groups )
84 {
85 }
86
87 HYDROData_CalculationCase::~HYDROData_CalculationCase()
88 {
89 }
90
91 void HYDROData_CalculationCase::SetName( const QString& theName )
92 {
93   QString anOldCaseName = GetName();
94   if ( anOldCaseName != theName )
95   {
96     // Update names of regions and its zones
97     UpdateRegionsNames( GetRegions(), anOldCaseName, theName );
98
99     HYDROData_SequenceOfObjects aGroups = GetSplittedGroups();
100
101     HYDROData_SequenceOfObjects::Iterator anIter;
102     anIter.Init( aGroups );
103     for ( ; anIter.More(); anIter.Next() )
104     {
105       Handle(HYDROData_SplittedShapesGroup) aGroup =
106         Handle(HYDROData_SplittedShapesGroup)::DownCast( anIter.Value() );
107       if ( aGroup.IsNull() )
108         continue;
109
110       HYDROData_Tool::UpdateChildObjectName( anOldCaseName, theName, aGroup );
111     }
112   }
113
114   HYDROData_Entity::SetName( theName );
115 }
116
117 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
118 {
119   QStringList aResList = dumpObjectCreation( theTreatedObjects );
120   aResList.prepend( "# Calculation case" );
121
122   QString aCalculName = GetObjPyName();
123
124   AssignmentMode aMode = GetAssignmentMode();  
125   QString aModeStr = aMode==MANUAL ? "HYDROData_CalculationCase.MANUAL" : "HYDROData_CalculationCase.AUTOMATIC";
126   aResList << QString( "%0.SetAssignmentMode( %1 )" ).arg( aCalculName ).arg( aModeStr );
127
128   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
129   HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
130   for ( ; anIter.More(); anIter.Next() )
131   {
132     Handle(HYDROData_Object) aRefGeomObj =
133       Handle(HYDROData_Object)::DownCast( anIter.Value() );
134     setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
135   }
136   aResList << QString( "" );
137
138   QString aGroupName = HYDROData_Tool::GenerateNameForPython( theTreatedObjects, "case_geom_group" );
139
140   HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
141   anIter.Init( aGeomGroups );
142   for ( ; anIter.More(); anIter.Next() )
143   {
144     Handle(HYDROData_ShapesGroup) aGeomGroup =
145       Handle(HYDROData_ShapesGroup)::DownCast( anIter.Value() );
146     if ( aGeomGroup.IsNull() )
147       continue;
148
149     Handle(HYDROData_Object) aFatherGeom =
150       Handle(HYDROData_Object)::DownCast( aGeomGroup->GetFatherObject() );
151     if ( aFatherGeom.IsNull() )
152       continue;
153
154     int aGroupId = aFatherGeom->GetGroupId( aGeomGroup );
155     aResList << QString( "%1 = %2.GetGroup( %3 );" )
156               .arg( aGroupName ).arg( aFatherGeom->GetObjPyName() ).arg( aGroupId );
157
158     aResList << QString( "%1.AddGeometryGroup( %2 );" ).arg( aCalculName ).arg( aGroupName );
159   }
160
161   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
162   setPythonReferenceObject( theTreatedObjects, aResList, aBoundaryPolyline, "SetBoundaryPolyline" );
163
164   if( aMode==AUTOMATIC )
165     DumpRulesToPython( aCalculName, aResList );
166
167   aResList << QString( "" );
168   aResList << "# Start the algorithm of the partition and assignment";
169   aResList << QString( "%1.Update();" ).arg( aCalculName );
170
171   if( aMode==MANUAL )
172   {
173     // Now we restore the
174     // - regions and zones order
175     DumpRegionsToPython( aResList, theTreatedObjects, GetRegions() );   
176   }
177
178   // Export calculation case
179   aResList << QString( "" );
180   aResList << "# Export of the calculation case";
181   QString aStudyName = "theStudy";
182   QString anEntryVar = aCalculName + "_entry";
183   aResList << QString( "%1 = %2.Export( %3._get_StudyId() )" ).arg( anEntryVar ).arg( aCalculName ).arg( aStudyName );
184
185   // Get geometry object and print debug information
186   aResList << "";
187   aResList << "# Get geometry shape and print debug information";
188   aResList << "import GEOM";
189   aResList << QString( "print \"Entry:\", %1" ).arg( anEntryVar );
190   QString aGeomShapeName = aCalculName + "_geom";
191   aResList << QString( "%1 = salome.IDToObject( str( %2 ) )" ).arg( aGeomShapeName ).arg( anEntryVar );
192   aResList << QString( "print \"Geom shape:\", %1" ).arg( aGeomShapeName );
193   aResList << QString( "print \"Geom shape name:\", %1.GetName()" ).arg( aGeomShapeName );
194
195   DumpSampleMeshing( aResList, aStudyName, aGeomShapeName, aCalculName+"_mesh" );
196
197   aResList << QString( "" );
198   return aResList;
199 }
200
201 void HYDROData_CalculationCase::DumpSampleMeshing( QStringList& theResList,
202                                                    const QString& theStudyName,
203                                                    const QString& theGeomShapeName,
204                                                    const QString& theMeshName ) const
205 {
206   theResList << "";
207   theResList << "# Meshing";
208   theResList << "import SMESH, SALOMEDS";
209   theResList << "from salome.smesh import smeshBuilder";
210   theResList << "from salome.geom import geomBuilder";
211
212   theResList << QString( "smesh = smeshBuilder.New( %1 )" ).arg( theStudyName );
213   theResList << QString( "%1 = smesh.Mesh( %2 )" ).arg( theMeshName ).arg( theGeomShapeName );
214   theResList << QString( "MEFISTO_2D = %1.Triangle( algo=smeshBuilder.MEFISTO )" ).arg( theMeshName );
215   theResList << "Max_Element_Area_1 = MEFISTO_2D.MaxElementArea( 10 )";
216   theResList << QString( "Regular_1D = %1.Segment()" ).arg( theMeshName );
217   theResList << "Max_Size_1 = Regular_1D.MaxSize(10)";
218   theResList << QString( "isDone = %1.Compute()" ).arg( theMeshName );
219
220   theResList << "";
221   theResList << "# Set names of Mesh objects";
222   theResList << "smesh.SetName( MEFISTO_2D.GetAlgorithm(), 'MEFISTO_2D' )";
223   theResList << "smesh.SetName( Regular_1D.GetAlgorithm(), 'Regular_1D' )";
224   theResList << "smesh.SetName( Max_Size_1, 'Max Size_1' )";
225   theResList << "smesh.SetName( Max_Element_Area_1, 'Max. Element Area_1' )";
226   theResList << QString( "smesh.SetName( %1.GetMesh(), '%1' )" ).arg( theMeshName );
227
228   theResList << "";
229   theResList << "# Greate SMESH groups";
230   theResList << QString( "geompy = geomBuilder.New( %1 )" ).arg( theStudyName );
231   theResList << QString( "geom_groups = geompy.GetGroups( %1 )" ).arg( theGeomShapeName );
232   theResList << QString( "for group in geom_groups:" );
233   theResList << QString( "    smesh_group = %1.GroupOnGeom(group, group.GetName(), SMESH.EDGE)" )
234                 .arg( theMeshName );
235   theResList << QString( "    smesh.SetName(smesh_group, group.GetName())" );
236   theResList << QString( "    print \"SMESH group '%s': %s\" % (smesh_group.GetName(), smesh_group)" );
237 }
238
239 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetAllReferenceObjects() const
240 {
241   HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
242
243   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
244   if ( !aBoundaryPolyline.IsNull() )
245     aResSeq.Append( aBoundaryPolyline );
246
247   HYDROData_SequenceOfObjects aSeqOfGeomObjs = GetGeometryObjects();
248   aResSeq.Append( aSeqOfGeomObjs );
249
250   // Regions
251   HYDROData_SequenceOfObjects aSeqOfRegions = GetRegions();
252   aResSeq.Append( aSeqOfRegions );
253
254   return aResSeq;
255 }
256
257 void HYDROData_CalculationCase::Update()
258 {
259   HYDROData_Entity::Update();
260   SetWarning();
261
262   // At first we remove previously created objects
263   RemoveRegions();
264   RemoveSplittedGroups();
265
266   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
267   if ( aDocument.IsNull() )
268     return;
269
270   // Split to zones
271   HYDROData_SplitToZonesTool::SplitDataList aZonesList, anEdgesList;
272
273   Handle(HYDROData_PolylineXY) aBoundaryPolyline = GetBoundaryPolyline();
274   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
275   if ( !aGeomObjects.IsEmpty() ) {
276     HYDROData_SequenceOfObjects aGeomGroups = GetGeometryGroups();
277
278     HYDROData_SplitToZonesTool::SplitDataList aSplitObjects =
279       HYDROData_SplitToZonesTool::Split( aGeomObjects, aGeomGroups, aBoundaryPolyline );
280     if ( !aSplitObjects.isEmpty() ) {
281       HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitObjects );
282       while( anIter.hasNext() ) {
283         const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
284         if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Zone )
285           aZonesList.append( aSplitData );
286         else if ( aSplitData.Type == HYDROData_SplitToZonesTool::SplitData::Data_Edge )
287           anEdgesList.append( aSplitData );
288       }
289     }
290   }
291
292   switch( GetAssignmentMode() )
293   {
294   case MANUAL:
295     CreateRegionsDef( aDocument, aZonesList );    
296     break;
297   case AUTOMATIC:
298     CreateRegionsAuto( aDocument, aZonesList );    
299     break;
300   }
301
302   CreateEdgeGroupsDef( aDocument, anEdgesList );
303 }
304
305 void HYDROData_CalculationCase::CreateRegionsDef( const Handle(HYDROData_Document)& theDoc,
306                                                   const HYDROData_SplitToZonesTool::SplitDataList& theZones )
307 {
308   // Create result regions for case, by default one zone for one region
309   QString aRegsPref = CALCULATION_REGIONS_PREF;
310   QString aZonesPref = CALCULATION_ZONES_PREF;
311
312   HYDROData_SplitToZonesTool::SplitDataListIterator anIter( theZones );
313   while( anIter.hasNext() )
314   {
315     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
316     // Create new region
317     Handle(HYDROData_Region) aRegion = addNewRegion( theDoc, aRegsPref );
318
319     // Add the zone for region
320     Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone( theDoc, aZonesPref, aSplitData.Face(), aSplitData.ObjectNames );
321   }
322 }
323
324 void HYDROData_CalculationCase::CreateRegionsAuto( const Handle(HYDROData_Document)& theDoc,
325                                                    const HYDROData_SplitToZonesTool::SplitDataList& theZones )
326 {
327   QMap<QString, Handle(HYDROData_Region)> aRegionsMap; //object name to region
328   QMap<QString, QString> aRegionNameToObjNameMap;
329   QString aZonesPref = CALCULATION_ZONES_PREF;
330   HYDROData_PriorityQueue aPr( this, DataTag_CustomRules );
331
332   // 1. First we create a default region for each object included into the calculation case
333   HYDROData_SequenceOfObjects anObjects = GetGeometryObjects();
334   for( int i = anObjects.Lower(), n = anObjects.Upper(); i<=n; i++ )
335   {
336     Handle(HYDROData_Entity) anObj = anObjects.Value( i );
337     if( anObj.IsNull() )
338       continue;
339     QString anObjName = anObj->GetName();
340     QString aRegName = anObjName + "_reg";
341     Handle(HYDROData_Region) aRegion = addNewRegion( theDoc, aRegName, false );
342     aRegionsMap.insert( anObjName, aRegion );
343     aRegionNameToObjNameMap.insert( aRegName, anObjName );
344   }
345
346   // 2. Now for each zone it is necessary to determine the most priority object
347   //    and assign to zone to corresponding region
348   HYDROData_SplitToZonesTool::SplitDataListIterator anIter( theZones );
349   while( anIter.hasNext() )
350   {
351     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
352     HYDROData_Zone::MergeType aMergeType;
353     Handle(HYDROData_Entity) aRegObj = aPr.GetMostPriorityObject( aSplitData.ObjectNames, aMergeType );
354     if( aRegObj.IsNull() )
355       continue;
356     Handle(HYDROData_Region) aRegion = aRegionsMap[aRegObj->GetName()];
357     if( aRegion.IsNull() )
358       continue;
359     Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone( theDoc, aZonesPref, aSplitData.Face(), aSplitData.ObjectNames );
360
361     if( aSplitData.ObjectNames.count() > 1 && aMergeType==HYDROData_Zone::Merge_UNKNOWN )
362     {
363       qDebug( "Error in algorithm: unresolved conflicts" );
364     }
365
366     Handle(HYDROData_Entity) aMergeEntity = aRegObj;
367     Handle(HYDROData_Object) aMergeObject = Handle(HYDROData_Object)::DownCast( aMergeEntity );
368     if ( !aMergeObject.IsNull() ) {
369       aMergeEntity = aMergeObject->GetAltitudeObject();
370     }
371
372     switch( aMergeType )
373     {
374     case HYDROData_Zone::Merge_ZMIN:
375     case HYDROData_Zone::Merge_ZMAX:
376       aRegionZone->SetMergeType( aMergeType );
377       break;
378     case HYDROData_Zone::Merge_Object:
379       aRegionZone->SetMergeType( aMergeType );
380       aRegionZone->RemoveMergeObject();
381       aRegionZone->SetMergeObject( aMergeEntity );
382       break;
383     }
384   }
385
386   QStringList anObjectsWithEmptyRegions;
387   QMap<QString, Handle(HYDROData_Region)>::const_iterator
388     anIt = aRegionsMap.begin(), aLast = aRegionsMap.end();
389   for( ; anIt!=aLast; anIt++ )
390   {
391     Handle(HYDROData_Region) aRegion = anIt.value();
392     if( aRegion->GetZones().IsEmpty() )
393     {
394       QString aRegName = aRegion->GetName();
395       QString anObjName = aRegionNameToObjNameMap[aRegName];
396       anObjectsWithEmptyRegions.append( anObjName );
397     }
398   }
399   
400   if( !anObjectsWithEmptyRegions.empty() )
401   {
402     QString aData = anObjectsWithEmptyRegions.join( ", " );
403     SetWarning( WARN_EMPTY_REGIONS, aData );
404   }
405 }
406
407 void HYDROData_CalculationCase::CreateEdgeGroupsDef( const Handle(HYDROData_Document)& theDoc,
408                                                      const HYDROData_SplitToZonesTool::SplitDataList& theEdges )
409 {
410   QMap<QString,Handle(HYDROData_SplittedShapesGroup)> aSplittedEdgesGroupsMap;
411
412   HYDROData_SplitToZonesTool::SplitDataListIterator anIter( theEdges );
413   while( anIter.hasNext() )
414   {
415     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
416     // Create new edges group
417     if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
418       continue;
419
420     QString anObjName = aSplitData.ObjectNames.first();
421     if ( anObjName.isEmpty() )
422       continue;
423 #ifdef DEB_CALCULATION
424     QString aStr = aSplitData.ObjectNames.join(" "); 
425           cout << " CCase: Names = "<<aStr.toStdString() << " size = " <<aSplitData.ObjectNames.size() <<endl; 
426 #endif
427     Handle(HYDROData_SplittedShapesGroup) aSplittedGroup;
428     if ( !aSplittedEdgesGroupsMap.contains( anObjName ) )
429     {
430       aSplittedGroup = addNewSplittedGroup( CALCULATION_GROUPS_PREF + anObjName );
431       aSplittedEdgesGroupsMap.insert( anObjName, aSplittedGroup );
432     }
433     else
434     {
435       aSplittedGroup = aSplittedEdgesGroupsMap[ anObjName ];
436     }
437     if ( aSplittedGroup.IsNull() )
438       continue;
439
440     aSplittedGroup->AddShape( aSplitData.Shape );
441   }
442 }
443
444 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
445 {
446   if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
447     return false; // Wrong type of object
448
449   if ( HasReference( theObject, DataTag_GeometryObject ) )
450     return false; // Object is already in reference list
451
452   AddReferenceObject( theObject, DataTag_GeometryObject );
453   
454   // Indicate model of the need to update splitting
455   Changed( Geom_2d );
456
457   return true;
458 }
459
460 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
461 {
462   return GetReferenceObjects( DataTag_GeometryObject );
463 }
464
465 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
466 {
467   if ( theObject.IsNull() )
468     return;
469
470   RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
471
472   // Indicate model of the need to update splitting
473   Changed( Geom_2d );
474 }
475
476 void HYDROData_CalculationCase::RemoveGeometryObjects()
477 {
478   ClearReferenceObjects( DataTag_GeometryObject );
479
480   // Indicate model of the need to update splitting
481   Changed( Geom_2d );
482 }
483
484 bool HYDROData_CalculationCase::AddGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
485 {
486   if ( theGroup.IsNull() )
487     return false;
488
489   if ( HasReference( theGroup, DataTag_GeometryGroup ) )
490     return false; // Object is already in reference list
491
492   AddReferenceObject( theGroup, DataTag_GeometryGroup );
493   
494   // Indicate model of the need to update splitting
495   Changed( Geom_Groups );
496
497   return true;
498 }
499
500 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryGroups() const
501 {
502   return GetReferenceObjects( DataTag_GeometryGroup );
503 }
504
505 void HYDROData_CalculationCase::RemoveGeometryGroup( const Handle(HYDROData_ShapesGroup)& theGroup )
506 {
507   if ( theGroup.IsNull() )
508     return;
509
510   RemoveReferenceObject( theGroup->Label(), DataTag_GeometryGroup );
511
512   // Indicate model of the need to update splitting
513   Changed( Geom_Groups );
514 }
515
516 void HYDROData_CalculationCase::RemoveGeometryGroups()
517 {
518   ClearReferenceObjects( DataTag_GeometryGroup );
519
520   // Indicate model of the need to update splitting
521   Changed( Geom_Groups );
522 }
523
524 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
525 {
526   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
527
528   SetReferenceObject( thePolyline, DataTag_Polyline );
529
530   // Indicate model of the need to update zones splitting
531   if( !IsEqual( aPrevPolyline, thePolyline ) )
532     Changed( Geom_2d );
533 }
534
535 Handle(HYDROData_PolylineXY) HYDROData_CalculationCase::GetBoundaryPolyline() const
536 {
537   return Handle(HYDROData_PolylineXY)::DownCast( 
538            GetReferenceObject( DataTag_Polyline ) );
539 }
540
541 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
542 {
543   Handle(HYDROData_PolylineXY) aPrevPolyline = GetBoundaryPolyline();
544
545   ClearReferenceObjects( DataTag_Polyline );
546
547   // Indicate model of the need to update zones splitting
548   Changed( Geom_2d );
549 }
550
551 void HYDROData_CalculationCase::SetStricklerTable( const Handle(HYDROData_StricklerTable)& theStricklerTable )
552 {
553   Handle(HYDROData_StricklerTable) aPrevStricklerTable = GetStricklerTable();
554
555   SetReferenceObject( theStricklerTable, DataTag_StricklerTable );
556
557   // Indicate model of the need to update land covers partition
558   if( !IsEqual( aPrevStricklerTable, theStricklerTable ) )
559     Changed( Geom_No );
560 }
561
562 Handle(HYDROData_StricklerTable) HYDROData_CalculationCase::GetStricklerTable() const
563 {
564   return Handle(HYDROData_StricklerTable)::DownCast( 
565            GetReferenceObject( DataTag_StricklerTable ) );
566 }
567
568 void HYDROData_CalculationCase::RemoveStricklerTable()
569 {
570   Handle(HYDROData_StricklerTable) aPrevStricklerTable = GetStricklerTable();
571
572   ClearReferenceObjects( DataTag_StricklerTable );
573
574   // Indicate model of the need to update land covers partition
575   Changed( Geom_No );
576 }
577
578 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
579 {
580   Changed( Geom_No );
581   Changed( Geom_No );
582   Changed( Geom_No );
583   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
584   Handle(HYDROData_Region) aNewRegion = addNewRegion( aDocument, CALCULATION_REGIONS_PREF );
585   if ( aNewRegion.IsNull() )
586     return aNewRegion;
587
588   aNewRegion->AddZone( theZone );
589
590   return aNewRegion;
591 }
592
593 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
594 {
595   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
596
597   if ( theRegion.IsNull() )
598     return false;
599   
600   HYDROData_CalculationCase::DataTag aDataTag = DataTag_Region;
601
602   if ( HasReference( theRegion, aDataTag ) )
603     return false; // Object is already in reference list
604
605   // Move the region from other calculation
606   Handle(HYDROData_CalculationCase) aFatherCalc = 
607     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
608   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
609   {
610     Handle(HYDROData_Region) aNewRegion = addNewRegion( aDocument, CALCULATION_REGIONS_PREF );
611     theRegion->CopyTo( aNewRegion, true );
612
613     aFatherCalc->RemoveRegion( theRegion );
614
615     theRegion->SetLabel( aNewRegion->Label() );
616   }
617   else
618   {
619     AddReferenceObject( theRegion, aDataTag );
620   }
621
622   return true;
623 }
624
625 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
626 {
627   return GetReferenceObjects( DataTag_Region );
628 }
629
630 void HYDROData_CalculationCase::UpdateRegionsOrder()
631 {
632   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
633   if ( aDocument.IsNull() )
634     return;
635
636   HYDROData_SequenceOfObjects aRegions = GetRegions();
637   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
638   for ( ; anIter.More(); anIter.Next() )
639   {
640     Handle(HYDROData_Region) aRegion =
641       Handle(HYDROData_Region)::DownCast( anIter.Value() );
642     if ( aRegion.IsNull() )
643       continue;
644
645     aRegion->SetName( "" );
646   }
647
648   QString aRegsPref = CALCULATION_REGIONS_PREF;
649
650   anIter.Init( aRegions );
651   for ( ; anIter.More(); anIter.Next() )
652   {
653     Handle(HYDROData_Region) aRegion =
654       Handle(HYDROData_Region)::DownCast( anIter.Value() );
655     if ( aRegion.IsNull() )
656       continue;
657
658     QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
659     aRegion->SetName( aRegionName );
660   }
661 }
662
663 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
664 {
665   if ( theRegion.IsNull() )
666     return;
667
668   HYDROData_CalculationCase::DataTag aDataTag = DataTag_Region;
669   RemoveReferenceObject( theRegion->Label(), aDataTag );
670
671   // Remove region from data model
672   Handle(HYDROData_CalculationCase) aFatherCalc = 
673     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
674   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
675     theRegion->Remove();
676 }
677
678 void HYDROData_CalculationCase::RemoveRegions()
679 {
680   myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes();
681 }
682
683 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetSplittedGroups() const
684 {
685   return GetReferenceObjects( DataTag_SplittedGroups );
686 }
687
688 void HYDROData_CalculationCase::RemoveSplittedGroups()
689 {
690   myLab.FindChild( DataTag_SplittedGroups ).ForgetAllAttributes();
691 }
692
693 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY& thePoint ) const
694 {
695   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
696   return GetAltitudeForPoint( thePoint, aZone );
697 }
698
699 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY&                    thePoint,
700                                                        const Handle(HYDROData_Region)& theRegion ) const
701 {
702   double aResAltitude = HYDROData_IAltitudeObject::GetInvalidAltitude();
703
704   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
705   if ( !aZone.IsNull() )
706   {
707     Handle(HYDROData_Region) aRefRegion = Handle(HYDROData_Region)::DownCast( aZone->GetFatherObject() );
708     if ( IsEqual( aRefRegion, theRegion ) )
709       aResAltitude = GetAltitudeForPoint( thePoint, aZone );
710   }
711
712   return aResAltitude;
713 }
714
715 double HYDROData_CalculationCase::GetAltitudeForPoint( const gp_XY&                  thePoint,
716                                                        const Handle(HYDROData_Zone)& theZone ) const
717 {
718   double aResAltitude = HYDROData_IAltitudeObject::GetInvalidAltitude();
719   if ( theZone.IsNull() )
720     return aResAltitude;
721
722   HYDROData_Zone::MergeType aZoneMergeType = theZone->GetMergeType();
723   if ( !theZone->IsMergingNeed() )
724   {
725     aZoneMergeType = HYDROData_Zone::Merge_UNKNOWN;
726   }
727   else if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
728   {
729     return aResAltitude;
730   }
731
732   HYDROData_IInterpolator* aZoneInterpolator = theZone->GetInterpolator();
733   if ( aZoneMergeType == HYDROData_Zone::Merge_Object )
734   {
735     Handle(HYDROData_IAltitudeObject) aMergeAltitude = 
736       Handle(HYDROData_IAltitudeObject)::DownCast( theZone->GetMergeObject() );
737     if ( !aMergeAltitude.IsNull() )
738     {
739       if ( aZoneInterpolator != NULL )
740       {
741         aZoneInterpolator->SetAltitudeObject( aMergeAltitude );
742         aResAltitude = aZoneInterpolator->GetAltitudeForPoint( thePoint );
743       }
744       else
745         aResAltitude = aMergeAltitude->GetAltitudeForPoint( thePoint );
746     }
747   }
748   else
749   {
750     HYDROData_SequenceOfObjects aZoneObjects = theZone->GetObjects();
751     HYDROData_SequenceOfObjects::Iterator anIter( aZoneObjects );
752     for ( ; anIter.More(); anIter.Next() )
753     {
754       Handle(HYDROData_Object) aZoneObj =
755         Handle(HYDROData_Object)::DownCast( anIter.Value() );
756       if ( aZoneObj.IsNull() )
757         continue;
758
759       Handle(HYDROData_IAltitudeObject) anObjAltitude = aZoneObj->GetAltitudeObject();
760       if ( anObjAltitude.IsNull() )
761         continue;
762
763       double aPointAltitude = 0.0;
764       if ( aZoneInterpolator != NULL )
765       {
766         aZoneInterpolator->SetAltitudeObject( anObjAltitude );
767         aPointAltitude = aZoneInterpolator->GetAltitudeForPoint( thePoint );
768       }
769       else
770         aPointAltitude = anObjAltitude->GetAltitudeForPoint( thePoint );
771
772       if ( ValuesEquals( aPointAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) )
773         continue;
774
775       if ( aZoneMergeType == HYDROData_Zone::Merge_UNKNOWN )
776       {
777         aResAltitude = aPointAltitude;
778         break;
779       }
780       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMIN )
781       {
782         if ( ValuesEquals( aResAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) ||
783              aResAltitude > aPointAltitude )
784         {
785           aResAltitude = aPointAltitude;
786         }
787       }
788       else if ( aZoneMergeType == HYDROData_Zone::Merge_ZMAX )
789       {
790         if ( ValuesEquals( aResAltitude, HYDROData_IAltitudeObject::GetInvalidAltitude() ) ||
791              aResAltitude < aPointAltitude )
792         {
793           aResAltitude = aPointAltitude;
794         }
795       }
796     }
797   }
798
799   return aResAltitude;
800 }
801
802 NCollection_Sequence<double> HYDROData_CalculationCase::GetAltitudesForPoints( 
803   const NCollection_Sequence<gp_XY>& thePoints,
804   const Handle(HYDROData_Region)&    theRegion ) const
805 {
806   NCollection_Sequence<double> aResSeq;
807
808   for ( int i = 1, n = thePoints.Length(); i <= n; ++i )
809   {
810     const gp_XY& thePnt = thePoints.Value( i );
811     
812     double anAltitude = GetAltitudeForPoint( thePnt, theRegion );
813     aResSeq.Append( anAltitude );
814   }
815
816   return aResSeq;
817 }
818
819 NCollection_Sequence<double> HYDROData_CalculationCase::GetAltitudesForPoints( 
820   const NCollection_Sequence<gp_XY>& thePoints,
821   const Handle(HYDROData_Zone)&      theZone ) const
822 {
823   NCollection_Sequence<double> aResSeq;
824
825   for ( int i = 1, n = thePoints.Length(); i <= n; ++i )
826   {
827     const gp_XY& thePnt = thePoints.Value( i );
828     
829     double anAltitude = GetAltitudeForPoint( thePnt, theZone );
830     aResSeq.Append( anAltitude );
831   }
832
833   return aResSeq;
834 }
835
836 double HYDROData_CalculationCase::GetStricklerCoefficientForPoint( const gp_XY& thePoint ) const
837 {
838   //TODO: #652
839   return 0.0;
840 }
841
842 Handle(HYDROData_Region) HYDROData_CalculationCase::GetRegionFromPoint( const gp_XY& thePoint ) const
843 {
844   Handle(HYDROData_Region) aResRegion;
845
846   Handle(HYDROData_Zone) aZone = GetZoneFromPoint( thePoint );
847   if ( !aZone.IsNull() )
848     aResRegion = Handle(HYDROData_Region)::DownCast( aZone->GetFatherObject() );
849
850   return aResRegion;
851 }
852
853 Handle(HYDROData_Zone) HYDROData_CalculationCase::GetZoneFromPoint( const gp_XY& thePoint ) const
854 {
855   Handle(HYDROData_Zone) aResZone;
856
857   HYDROData_SequenceOfObjects aRegions = GetRegions();
858
859   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
860   for ( ; anIter.More() && aResZone.IsNull(); anIter.Next() )
861   {
862     Handle(HYDROData_Region) aRegion =
863       Handle(HYDROData_Region)::DownCast( anIter.Value() );
864     if ( aRegion.IsNull() )
865       continue;
866
867     HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
868     HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
869     for ( ; aZonesIter.More() && aResZone.IsNull(); aZonesIter.Next() )
870     {
871       Handle(HYDROData_Zone) aRegZone =
872         Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
873       if ( aRegZone.IsNull() )
874         continue;
875
876       PointClassification aPointRelation = GetPointClassification( thePoint, aRegZone );
877       if ( aPointRelation != POINT_OUT )
878         aResZone = aRegZone; // We found the desired zone
879     }
880   }
881
882   return aResZone;
883 }
884
885 HYDROData_CalculationCase::PointClassification HYDROData_CalculationCase::GetPointClassification(
886   const gp_XY&                  thePoint,
887   const Handle(HYDROData_Zone)& theZone ) const
888 {
889   PointClassification aRes = POINT_OUT;
890   if ( theZone.IsNull() )
891     return aRes;
892
893   TopoDS_Face aZoneFace = TopoDS::Face( theZone->GetShape() );
894   if ( aZoneFace.IsNull() )
895     return aRes;
896 #ifdef DEB_CLASS2D      
897           TopoDS_Compound aCmp;
898       BRep_Builder aBB;
899       aBB.MakeCompound(aCmp);
900           aBB.Add(aCmp, aZoneFace);
901           gp_Pnt aPnt (thePoint.X(), thePoint.Y(), 0.);
902           BRepBuilderAPI_MakeVertex aMk(aPnt);
903           aBB.Add(aCmp, aMk.Vertex());
904           BRepTools::Write(aCmp, "FCL2d.brep");
905 #endif  
906   TopAbs_State State = HYDROData_Tool::ComputePointState(thePoint, aZoneFace);
907   if (State == TopAbs_OUT)
908     aRes =  POINT_OUT;
909   else if(State == TopAbs_IN)
910     aRes =  POINT_IN;
911   else if(State == TopAbs_ON)
912     aRes =  POINT_ON;
913   return aRes;
914 }
915
916 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion( const Handle(HYDROData_Document)& theDoc,
917                                                                   const QString& thePrefixOrName,
918                                                                   bool isPrefix )
919 {
920   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
921   int aTag = aNewLab.Tag();
922
923   Handle(HYDROData_Region) aNewRegion =
924     Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
925   AddRegion( aNewRegion );
926
927   QString aRegionName = isPrefix ? HYDROData_Tool::GenerateObjectName( theDoc, thePrefixOrName ) : thePrefixOrName;
928   aNewRegion->SetName( aRegionName );
929
930   return aNewRegion;
931 }
932
933 Handle(HYDROData_SplittedShapesGroup) HYDROData_CalculationCase::addNewSplittedGroup( const QString& theName )
934 {
935   TDF_Label aNewLab = myLab.FindChild( DataTag_SplittedGroups ).NewChild();
936
937   Handle(HYDROData_SplittedShapesGroup) aNewGroup =
938     Handle(HYDROData_SplittedShapesGroup)::DownCast( 
939       HYDROData_Iterator::CreateObject( aNewLab, KIND_SPLITTED_GROUP ) );
940   AddReferenceObject( aNewGroup, DataTag_SplittedGroups );
941
942   aNewGroup->SetName( theName );
943
944   return aNewGroup;
945 }
946
947 QString HYDROData_CalculationCase::Export( int theStudyId ) const
948 {
949 #ifdef LIGHT_MODE
950   return "";
951 #else
952   GEOM::GEOM_Gen_var aGEOMEngine = HYDROData_GeomTool::GetGeomGen();
953   SALOMEDS::Study_var aDSStudy = HYDROData_GeomTool::GetStudyByID( theStudyId );
954   
955   QString aGeomObjEntry, anErrorMsg;
956   bool isOK = Export( aGEOMEngine, aDSStudy, aGeomObjEntry, anErrorMsg );
957   return isOK ? aGeomObjEntry : QString();
958 #endif
959 }
960
961 #ifndef LIGHT_MODE
962 bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var  theGeomEngine,
963                                         SALOMEDS::Study_ptr theStudy,
964                                         QString& theGeomObjEntry,
965                                         QString& theErrorMsg ) const
966 {
967   HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfGroupsDefs;
968
969   // Get groups definitions
970   HYDROData_SequenceOfObjects aSplittedGroups = GetSplittedGroups();
971
972   HYDROData_SequenceOfObjects::Iterator anIter( aSplittedGroups );
973   for ( ; anIter.More(); anIter.Next() )
974   {
975     // Get shapes group
976     Handle(HYDROData_ShapesGroup) aGroup =
977       Handle(HYDROData_ShapesGroup)::DownCast( anIter.Value() );
978     if ( aGroup.IsNull() )
979       continue;
980
981     HYDROData_ShapesGroup::GroupDefinition aGroupDef;
982
983     aGroupDef.Name = aGroup->GetName().toLatin1().constData();
984     aGroup->GetShapes( aGroupDef.Shapes );
985
986     aSeqOfGroupsDefs.Append( aGroupDef );
987   }
988   
989   // Get faces
990   bool isAllNotSubmersible = true;
991   TopTools_ListOfShape aFaces;
992   HYDROData_SequenceOfObjects aCaseRegions = GetRegions();
993   HYDROData_SequenceOfObjects::Iterator aRegionIter( aCaseRegions );
994   for ( ; aRegionIter.More(); aRegionIter.Next() )
995   {
996     Handle(HYDROData_Region) aRegion =
997       Handle(HYDROData_Region)::DownCast( aRegionIter.Value() );
998     if( aRegion.IsNull() || !aRegion->IsSubmersible() )
999       continue;
1000     
1001     if ( isAllNotSubmersible )
1002       isAllNotSubmersible = false;
1003
1004     TopoDS_Shape aRegionShape = aRegion->GetShape( &aSeqOfGroupsDefs );
1005     aFaces.Append( aRegionShape );
1006   }
1007
1008   bool aRes = false;
1009
1010   if ( aCaseRegions.IsEmpty() ) {
1011     theErrorMsg = QString("the list of regions is empty.");
1012   } else if ( isAllNotSubmersible ) {
1013     theErrorMsg = QString("there are no submersible regions.");
1014   } else {
1015     aRes = Export( theGeomEngine, theStudy, aFaces, aSeqOfGroupsDefs, theGeomObjEntry );;
1016   }
1017
1018   return aRes;
1019 }
1020
1021 bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var                            theGeomEngine,
1022                                         SALOMEDS::Study_ptr                           theStudy,
1023                                         const TopTools_ListOfShape&                   theFaces,
1024                                         const HYDROData_ShapesGroup::SeqOfGroupsDefs& theGroupsDefs,
1025                                         QString& theGeomObjEntry ) const
1026 {
1027   // Sew faces
1028   BRepBuilderAPI_Sewing aSewing( Precision::Confusion() * 10.0 );
1029   aSewing.SetNonManifoldMode( Standard_False );
1030 #ifdef DEB_CALCULATION
1031   TCollection_AsciiString aNam("Sh_");
1032   int i=1;
1033 #endif
1034   TopTools_ListIteratorOfListOfShape aFaceIter( theFaces );
1035   for ( ; aFaceIter.More(); aFaceIter.Next() )
1036   {
1037     TopoDS_Shape aShape = aFaceIter.Value();
1038     if ( aShape.IsNull() )
1039       continue;
1040
1041     if ( aShape.ShapeType() == TopAbs_FACE )
1042     {
1043       aSewing.Add( aShape );
1044 #ifdef DEB_CALCULATION
1045       TCollection_AsciiString aName = aNam + ++i + ".brep";
1046       BRepTools::Write(aShape ,aName.ToCString());
1047 #endif
1048     }
1049     else
1050     {
1051 #ifdef DEB_CALCULATION
1052       int j = 1;
1053 #endif
1054       TopExp_Explorer anExp( aShape, TopAbs_FACE );
1055       for (; anExp.More(); anExp.Next() ) {
1056         aSewing.Add( anExp.Current() );
1057 #ifdef DEB_CALCULATION
1058
1059         TCollection_AsciiString aName = aNam + i + "_" + ++j + ".brep";
1060         BRepTools::Write(anExp.Current() ,aName.ToCString());
1061 #endif
1062       }
1063     }
1064   } // faces iterator
1065   
1066   aSewing.Perform();
1067   TopoDS_Shape aSewedShape = aSewing.SewedShape();
1068
1069   // If the sewed shape is empty - return false
1070   if ( aSewedShape.IsNull() || !TopoDS_Iterator( aSewedShape ).More() )
1071     return false;
1072
1073 #ifdef DEB_CALCULATION
1074   BRepTools::Write(aSewedShape ,"Sew.brep");
1075 #endif
1076   // Publish the sewed shape
1077   QString aName = EXPORT_NAME;
1078   GEOM::GEOM_Object_ptr aMainShape = 
1079     HYDROData_GeomTool::publishShapeInGEOM( theGeomEngine, theStudy, aSewedShape, aName, theGeomObjEntry );
1080
1081   if ( aMainShape->_is_nil() )  
1082     return false;
1083
1084   if ( theGroupsDefs.IsEmpty() )
1085     return true;
1086
1087   // Create groups
1088   TopTools_IndexedMapOfShape aMapOfSubShapes;
1089   TopExp::MapShapes( aSewedShape, aMapOfSubShapes );
1090
1091   NCollection_DataMap< TCollection_AsciiString, NCollection_Sequence<int> > aGroupsData;
1092
1093   for ( int aGrId = 1, nbGroups = theGroupsDefs.Length(); aGrId <= nbGroups; ++aGrId )
1094   {
1095     const HYDROData_ShapesGroup::GroupDefinition& aGroupDef = theGroupsDefs.Value( aGrId );
1096
1097     NCollection_Sequence<int> aGroupIndexes;
1098     for( int i = 1, n = aGroupDef.Shapes.Length(); i <= n; i++ )
1099     {
1100       const TopoDS_Shape& aShape = aGroupDef.Shapes.Value( i );
1101 #ifdef DEB_CALCULATION
1102       cout << "\nOld shape(" << i << ") = " << aShape.TShape() <<endl;
1103 #endif
1104       
1105       TopoDS_Shape aModifiedShape = aShape;
1106       if ( aSewing.IsModified( aShape ) )
1107         aModifiedShape = aSewing.Modified( aShape );
1108       else if ( aSewing.IsModifiedSubShape( aShape ) )
1109         aModifiedShape = aSewing.ModifiedSubShape( aShape );
1110
1111 #ifdef DEB_CALCULATION
1112       const TopLoc_Location& aL1 = aShape.Location();
1113       const TopLoc_Location& aL2 = aModifiedShape.Location();
1114       cout << "\nNew shape(" << i << ") = " << aModifiedShape.TShape() << " Location is Equal = " << aL1.IsEqual(aL2)<<endl;
1115 #endif
1116
1117       int anIndex = aMapOfSubShapes.FindIndex(aModifiedShape);
1118       if ( anIndex > 0 ) {
1119         aGroupIndexes.Append( anIndex );
1120       } else {
1121 #ifdef DEB_CALCULATION    
1122         TCollection_AsciiString aNam("Lost_");
1123         if(!aMapOfSubShapes.Contains(aModifiedShape)) {
1124         for ( int anIndex = 1; anIndex <= aMapOfSubShapes.Extent(); anIndex++ )
1125         {
1126            const TopoDS_Shape& aS = aMapOfSubShapes.FindKey( anIndex );
1127            if ( aModifiedShape.IsPartner( aS ) )
1128            {
1129              cout <<"\nIndex in Map = " << anIndex << "TShape = " << aS.TShape() <<endl;
1130              TCollection_AsciiString aName = aNam + i + "_" + anIndex + ".brep";
1131              BRepTools::Write(aS ,aName.ToCString());
1132             break;
1133            }
1134          }
1135         }
1136 #endif
1137       }
1138     }
1139     if ( !aGroupIndexes.IsEmpty() )
1140       aGroupsData.Bind( aGroupDef.Name, aGroupIndexes );
1141   }
1142  
1143   if ( !aGroupsData.IsEmpty() )
1144   {
1145     GEOM::GEOM_IGroupOperations_var aGroupOp = 
1146       theGeomEngine->GetIGroupOperations( theStudy->StudyId() );  
1147
1148     NCollection_DataMap< TCollection_AsciiString, NCollection_Sequence<int> >::Iterator aMapIt( aGroupsData );
1149     for ( ; aMapIt.More(); aMapIt.Next() )
1150     {
1151       const TCollection_AsciiString& aGroupName = aMapIt.Key(); 
1152       const NCollection_Sequence<int>& aGroupIndexes = aMapIt.Value();
1153
1154       GEOM::GEOM_Object_var aGeomGroup = aGroupOp->CreateGroup( aMainShape, TopAbs_EDGE );
1155       if ( CORBA::is_nil( aGeomGroup ) || !aGroupOp->IsDone() )
1156         continue;
1157
1158       GEOM::ListOfLong_var aGeomIndexes = new GEOM::ListOfLong;
1159       aGeomIndexes->length( aGroupIndexes.Length() );
1160
1161       for( int i = 1, n = aGroupIndexes.Length(); i <= n; i++ )
1162         aGeomIndexes[ i - 1 ] = aGroupIndexes.Value( i );
1163
1164       aGroupOp->UnionIDs( aGeomGroup, aGeomIndexes );
1165       if ( aGroupOp->IsDone() )
1166       {
1167         SALOMEDS::SObject_var aGroupSO = 
1168           theGeomEngine->AddInStudy( theStudy, aGeomGroup, aGroupName.ToCString(), aMainShape );
1169       }
1170     }
1171   }
1172
1173   return true;
1174 }
1175 #endif
1176
1177 void HYDROData_CalculationCase::ClearRules( HYDROData_CalculationCase::DataTag theDataTag,
1178                                             const bool theIsSetToUpdate )
1179 {
1180   TDF_Label aRulesLab = myLab.FindChild( theDataTag );
1181   HYDROData_PriorityQueue::ClearRules( aRulesLab );
1182
1183   // Indicate model of the need to update splitting
1184   if ( theIsSetToUpdate ) {
1185     Changed( Geom_2d );
1186   }
1187 }
1188
1189 void HYDROData_CalculationCase::AddRule( const Handle(HYDROData_Entity)&    theObject1,
1190                                          HYDROData_PriorityType             thePriority,
1191                                          const Handle(HYDROData_Entity)&    theObject2,
1192                                          HYDROData_Zone::MergeType          theMergeType,
1193                                          HYDROData_CalculationCase::DataTag theDataTag )
1194 {
1195   TDF_Label aRulesLab = myLab.FindChild( theDataTag );
1196   HYDROData_PriorityQueue::AddRule( aRulesLab, theObject1, thePriority, theObject2, theMergeType );
1197
1198   // Indicate model of the need to update splitting
1199   Changed( Geom_2d );
1200 }
1201
1202 QString HYDROData_CalculationCase::DumpRules() const
1203 {
1204   TDF_Label aRulesLab = myLab.FindChild( DataTag_CustomRules );
1205   return HYDROData_PriorityQueue::DumpRules( aRulesLab );
1206 }
1207
1208 void HYDROData_CalculationCase::SetAssignmentMode( AssignmentMode theMode )
1209 {
1210   TDF_Label aModeLab = myLab.FindChild( DataTag_AssignmentMode );
1211   TDataStd_Integer::Set( aModeLab, ( int ) theMode );
1212
1213   // Indicate model of the need to update splitting
1214   Changed( Geom_2d );
1215 }
1216
1217 HYDROData_CalculationCase::AssignmentMode HYDROData_CalculationCase::GetAssignmentMode() const
1218 {
1219   Handle(TDataStd_Integer) aModeAttr;
1220   bool isOK = myLab.FindChild( DataTag_AssignmentMode ).FindAttribute( TDataStd_Integer::GetID(), aModeAttr );
1221   if( isOK )
1222     return ( AssignmentMode ) aModeAttr->Get();
1223   else
1224     return MANUAL;
1225 }
1226
1227 void HYDROData_CalculationCase::DumpRulesToPython( const QString& theCalcCaseName,
1228                                                    QStringList& theScript ) const
1229 {
1230   TDF_Label aRulesLab = myLab.FindChild( DataTag_CustomRules );
1231   HYDROData_PriorityQueue::DumpRulesToPython( aRulesLab, theCalcCaseName, theScript );
1232 }
1233
1234 HYDROData_Warning HYDROData_CalculationCase::GetLastWarning() const
1235 {
1236   return myLastWarning;
1237 }
1238
1239 void HYDROData_CalculationCase::SetWarning( HYDROData_WarningType theType, const QString& theData )
1240 {
1241   myLastWarning.Type = theType;
1242   myLastWarning.Data = theData;
1243 }
1244
1245 void HYDROData_CalculationCase::UpdateRegionsNames( const HYDROData_SequenceOfObjects& theRegions,
1246                                                     const QString& theOldCaseName,
1247                                                     const QString& theName )
1248 {
1249   HYDROData_SequenceOfObjects::Iterator anIter( theRegions );
1250   for ( ; anIter.More(); anIter.Next() )
1251   {
1252     Handle(HYDROData_Region) aRegion =
1253       Handle(HYDROData_Region)::DownCast( anIter.Value() );
1254     if ( aRegion.IsNull() )
1255       continue;
1256
1257     HYDROData_Tool::UpdateChildObjectName( theOldCaseName, theName, aRegion );
1258
1259     HYDROData_SequenceOfObjects aZones = aRegion->GetZones();
1260     HYDROData_SequenceOfObjects::Iterator anIter( aZones );
1261     for ( ; anIter.More(); anIter.Next() )
1262     {
1263       Handle(HYDROData_Zone) aRegZone =
1264         Handle(HYDROData_Zone)::DownCast( anIter.Value() );
1265       if ( aRegZone.IsNull() )
1266         continue;
1267
1268       HYDROData_Tool::UpdateChildObjectName( theOldCaseName, theName, aRegZone );
1269     }
1270   }
1271 }
1272
1273 void HYDROData_CalculationCase::DumpRegionsToPython( QStringList& theResList,
1274                                                      MapOfTreatedObjects& theTreatedObjects,
1275                                                      const HYDROData_SequenceOfObjects& theRegions ) const
1276 {
1277   HYDROData_SequenceOfObjects::Iterator anIter;
1278   anIter.Init( theRegions );
1279   for ( ; anIter.More(); anIter.Next() )
1280   {
1281     Handle(HYDROData_Region) aRegion =
1282       Handle(HYDROData_Region)::DownCast( anIter.Value() );
1283     if ( aRegion.IsNull() )
1284       continue;
1285
1286     theTreatedObjects.insert( aRegion->GetName(), aRegion );
1287     QStringList aRegDump = aRegion->DumpToPython( theTreatedObjects );
1288     theResList << aRegDump;
1289   }
1290 }
1291
1292 bool HYDROData_CalculationCase::GetRule( int theIndex, 
1293                                          Handle(HYDROData_Entity)&           theObject1,
1294                                          HYDROData_PriorityType&             thePriority,
1295                                          Handle(HYDROData_Entity)&           theObject2,
1296                                          HYDROData_Zone::MergeType&          theMergeType,
1297                                          HYDROData_CalculationCase::DataTag& theDataTag) const
1298 {
1299   TDF_Label aRulesLab = myLab.FindChild( theDataTag );
1300   return HYDROData_PriorityQueue::GetRule( aRulesLab, theIndex,
1301     theObject1, thePriority, theObject2, theMergeType );
1302 }