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