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