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