Salome HOME
Update names of regions in calculation case if its order has been changed (Bug #47).
[modules/hydro.git] / src / HYDROData / HYDROData_CalculationCase.cxx
1
2 #include "HYDROData_CalculationCase.h"
3
4 #include "HYDROData_ArtificialObject.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_Iterator.h"
7 #include "HYDROData_NaturalObject.h"
8 #include "HYDROData_Polyline.h"
9 #include "HYDROData_SplitToZonesTool.h"
10 #include "HYDROData_Region.h"
11 #include "HYDROData_Tool.h"
12 #include "HYDROData_Zone.h"
13
14 #define CALCULATION_REGIONS_PREF GetName() + "_Reg"
15 #define CALCULATION_ZONES_PREF GetName() + "_Zone"
16
17 #define PYTHON_CALCULATION_ID "KIND_CALCULATION"
18
19 IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
20 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
21
22 HYDROData_CalculationCase::HYDROData_CalculationCase()
23 : HYDROData_Entity()
24 {
25 }
26
27 HYDROData_CalculationCase::~HYDROData_CalculationCase()
28 {
29 }
30
31 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
32 {
33   QStringList aResList;
34
35   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
36   if ( aDocument.IsNull() )
37     return aResList;
38                              
39   QString aDocName = aDocument->GetDocPyName();
40   QString aCalculName = GetName();
41
42   aResList << QString( "%1 = %2.CreateObject( %3 );" )
43               .arg( aCalculName ).arg( aDocName ).arg( PYTHON_CALCULATION_ID );
44   aResList << QString( "%1.SetName( \"%2\" );" )
45               .arg( aCalculName ).arg( aCalculName );
46   aResList << QString( "" );
47
48   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
49   HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
50   for ( ; anIter.More(); anIter.Next() )
51   {
52     Handle(HYDROData_Object) aRefGeomObj =
53       Handle(HYDROData_Object)::DownCast( anIter.Value() );
54     if ( !aRefGeomObj.IsNull() )
55       setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
56   }
57   aResList << QString( "" );
58
59   aResList << QString( "%1.SplitGeometryObjects();" ).arg( aCalculName );
60   aResList << QString( "" );
61
62   // Now we restore the regions and zones order
63   HYDROData_SequenceOfObjects aRegions = GetRegions();
64   anIter.Init( aRegions );
65   for ( ; anIter.More(); anIter.Next() )
66   {
67     Handle(HYDROData_Region) aRegion =
68       Handle(HYDROData_Region)::DownCast( anIter.Value() );
69     if ( aRegion.IsNull() )
70       continue;
71
72     QString aRegionName = aRegion->GetName();
73     // TODO
74   }
75
76   return aResList;
77 }
78
79 void HYDROData_CalculationCase::SplitGeometryObjects()
80 {
81   // At first we remove previously created regions
82   RemoveRegions();
83
84   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
85   if ( aDocument.IsNull() )
86     return;
87
88   Handle(HYDROData_Polyline) aBoundaryPolyline = GetBoundaryPolyline();
89   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
90   if ( aGeomObjects.IsEmpty() )
91     return;
92
93   HYDROData_SplitToZonesTool::SplitDataList aSplitedZones =
94     HYDROData_SplitToZonesTool::SplitToZones( aGeomObjects, aBoundaryPolyline );
95   if ( aSplitedZones.isEmpty() )
96     return;
97
98   QString aRegsPref = CALCULATION_REGIONS_PREF;
99   QString aZonesPref = CALCULATION_ZONES_PREF;
100
101   // Create result regions for case, by default one zone for one region
102   HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedZones );
103   while( anIter.hasNext() )
104   {
105     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
106
107     // Create new region
108     Handle(HYDROData_Region) aRegion = addNewRegion();
109
110     QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
111     aRegion->SetName( aRegionName );
112
113     // Add the zone for region
114     Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
115
116     QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, aZonesPref );
117     aRegionZone->SetName( aZoneName );
118
119     aRegionZone->SetShape( aSplitData.Face() );
120
121     // Add the reference object for zone
122     for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
123     {
124       const QString& anObjName = aSplitData.ObjectNames.at( i );
125       
126       Handle(HYDROData_Object) aRefObject = Handle(HYDROData_Object)::DownCast(
127         HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
128       if ( aRefObject.IsNull() )
129         continue;
130
131       aRegionZone->AddGeometryObject( aRefObject );
132     }
133   }
134
135   // The splitted data is up to date
136   SetToUpdate( false );
137 }
138
139 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
140 {
141   if ( !HYDROData_Tool::IsGeometryObject( theObject ) )
142     return false; // Wrong type of object
143
144   if ( HasReference( theObject, DataTag_GeometryObject ) )
145     return false; // Object is already in reference list
146
147   AddReferenceObject( theObject, DataTag_GeometryObject );
148   
149   // Indicate model of the need to update zones splitting
150   SetToUpdate( true );
151
152   return true;
153 }
154
155 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
156 {
157   return GetReferenceObjects( DataTag_GeometryObject );
158 }
159
160 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
161 {
162   if ( theObject.IsNull() )
163     return;
164
165   RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
166
167   // Indicate model of the need to update zones splitting
168   SetToUpdate( true );
169 }
170
171 void HYDROData_CalculationCase::RemoveGeometryObjects()
172 {
173   ClearReferenceObjects( DataTag_GeometryObject );
174
175   // Indicate model of the need to update zones splitting
176   SetToUpdate( true );
177 }
178
179 void HYDROData_CalculationCase::SetBoundaryPolyline( const Handle(HYDROData_Polyline)& thePolyline )
180 {
181   Handle(HYDROData_Polyline) aPrevPolyline = GetBoundaryPolyline();
182
183   SetReferenceObject( thePolyline, DataTag_Polyline );
184
185   // Indicate model of the need to update zones splitting
186   SetToUpdate( !IsEqual( aPrevPolyline, thePolyline ) || IsMustBeUpdated() );
187 }
188
189 Handle(HYDROData_Polyline) HYDROData_CalculationCase::GetBoundaryPolyline() const
190 {
191   return Handle(HYDROData_Polyline)::DownCast( 
192            GetReferenceObject( DataTag_Polyline ) );
193 }
194
195 void HYDROData_CalculationCase::RemoveBoundaryPolyline()
196 {
197   Handle(HYDROData_Polyline) aPrevPolyline = GetBoundaryPolyline();
198
199   ClearReferenceObjects( DataTag_Polyline );
200
201   // Indicate model of the need to update zones splitting
202   SetToUpdate( !aPrevPolyline.IsNull() || IsMustBeUpdated() );
203 }
204
205 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
206 {
207   Handle(HYDROData_Region) aNewRegion = addNewRegion();
208   if ( aNewRegion.IsNull() )
209     return aNewRegion;
210
211   // Generate new name for new region
212   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
213   if ( !aDocument.IsNull() )
214   {
215     QString aRegsPref = CALCULATION_REGIONS_PREF;
216
217     QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
218     aNewRegion->SetName( aNewRegionName );
219   }
220
221   aNewRegion->AddZone( theZone );
222
223   return aNewRegion;
224 }
225
226 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
227 {
228   if ( theRegion.IsNull() )
229     return false;
230   
231   if ( HasReference( theRegion, DataTag_Region ) )
232     return false; // Object is already in reference list
233
234   // Move the region from other calculation
235   Handle(HYDROData_CalculationCase) aFatherCalc = 
236     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
237   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
238   {
239     Handle(HYDROData_Region) aNewRegion = addNewRegion();
240     theRegion->CopyTo( aNewRegion );
241
242     aFatherCalc->RemoveRegion( theRegion );
243
244     theRegion->SetLabel( aNewRegion->Label() );
245   }
246   else
247   {
248     AddReferenceObject( theRegion, DataTag_Region );
249   }
250
251   return true;
252 }
253
254 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
255 {
256   return GetReferenceObjects( DataTag_Region );
257 }
258
259 void HYDROData_CalculationCase::UpdateRegionsOrder()
260 {
261   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
262   if ( aDocument.IsNull() )
263     return;
264
265   HYDROData_SequenceOfObjects aRegions = GetRegions();
266
267   HYDROData_SequenceOfObjects::Iterator anIter( aRegions );
268   for ( ; anIter.More(); anIter.Next() )
269   {
270     Handle(HYDROData_Region) aRegion =
271       Handle(HYDROData_Region)::DownCast( anIter.Value() );
272     if ( aRegion.IsNull() )
273       continue;
274
275     aRegion->SetName( "" );
276   }
277
278   QString aRegsPref = CALCULATION_REGIONS_PREF;
279
280   anIter.Init( aRegions );
281   for ( ; anIter.More(); anIter.Next() )
282   {
283     Handle(HYDROData_Region) aRegion =
284       Handle(HYDROData_Region)::DownCast( anIter.Value() );
285     if ( aRegion.IsNull() )
286       continue;
287
288     QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, aRegsPref );
289     aRegion->SetName( aRegionName );
290   }
291 }
292
293 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
294 {
295   if ( theRegion.IsNull() )
296     return;
297
298   RemoveReferenceObject( theRegion->Label(), DataTag_Region );
299
300   // Remove region from data model
301   Handle(HYDROData_CalculationCase) aFatherCalc = 
302     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
303   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
304     theRegion->Remove();
305 }
306
307 void HYDROData_CalculationCase::RemoveRegions()
308 {
309   ClearReferenceObjects( DataTag_Region );
310   myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes( true );
311 }
312
313 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
314 {
315   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
316
317   Handle(HYDROData_Region) aNewRegion =
318     Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
319   AddRegion( aNewRegion );
320
321   return aNewRegion;
322 }
323