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