Salome HOME
Fix of Bug #39: Lambert93/Geodesic coordinates confusion
[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_SplitToZonesTool.h"
9 #include "HYDROData_Region.h"
10 #include "HYDROData_Tool.h"
11 #include "HYDROData_Zone.h"
12
13 #define PYTHON_CALCULATION_ID "KIND_CALCULATION"
14
15 IMPLEMENT_STANDARD_HANDLE(HYDROData_CalculationCase, HYDROData_Entity)
16 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_CalculationCase, HYDROData_Entity)
17
18 HYDROData_CalculationCase::HYDROData_CalculationCase()
19 : HYDROData_Entity()
20 {
21 }
22
23 HYDROData_CalculationCase::~HYDROData_CalculationCase()
24 {
25 }
26
27 QStringList HYDROData_CalculationCase::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
28 {
29   QStringList aResList;
30
31   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
32   if ( aDocument.IsNull() )
33     return aResList;
34                              
35   QString aDocName = aDocument->GetDocPyName();
36   QString aCalculName = GetName();
37
38   aResList << QString( "%1 = %2.CreateObject( %3 );" )
39               .arg( aCalculName ).arg( aDocName ).arg( PYTHON_CALCULATION_ID );
40   aResList << QString( "%1.SetName( \"%2\" );" )
41               .arg( aCalculName ).arg( aCalculName );
42   aResList << QString( "" );
43
44   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
45   HYDROData_SequenceOfObjects::Iterator anIter( aGeomObjects );
46   for ( ; anIter.More(); anIter.Next() )
47   {
48     Handle(HYDROData_Object) aRefGeomObj =
49       Handle(HYDROData_Object)::DownCast( anIter.Value() );
50     if ( !aRefGeomObj.IsNull() )
51       setPythonReferenceObject( theTreatedObjects, aResList, aRefGeomObj, "AddGeometryObject" );
52   }
53   aResList << QString( "" );
54
55   aResList << QString( "%1.SplitGeometryObjects();" ).arg( aCalculName );
56   aResList << QString( "" );
57
58   // Now we restore the regions and zones order
59   HYDROData_SequenceOfObjects aRegions = GetRegions();
60   anIter.Init( aRegions );
61   for ( ; anIter.More(); anIter.Next() )
62   {
63     Handle(HYDROData_Region) aRegion =
64       Handle(HYDROData_Region)::DownCast( anIter.Value() );
65     if ( aRegion.IsNull() )
66       continue;
67
68     QString aRegionName = aRegion->GetName();
69     // TODO
70   }
71
72   return aResList;
73 }
74
75 void HYDROData_CalculationCase::SplitGeometryObjects()
76 {
77   // At first we remove previously created regions
78   RemoveRegions();
79
80   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
81   if ( aDocument.IsNull() )
82     return;
83
84   HYDROData_SequenceOfObjects aGeomObjects = GetGeometryObjects();
85   if ( aGeomObjects.IsEmpty() )
86     return;
87
88   HYDROData_SplitToZonesTool::SplitDataList aSplitedZones =
89     HYDROData_SplitToZonesTool::SplitToZones( aGeomObjects );
90   if ( aSplitedZones.isEmpty() )
91     return;
92
93   // Create result regions for case, by default one zone for one region
94   HYDROData_SplitToZonesTool::SplitDataListIterator anIter( aSplitedZones );
95   while( anIter.hasNext() )
96   {
97     const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
98
99     // Create new region
100     Handle(HYDROData_Region) aRegion = addNewRegion();
101
102     QString aRegionName = HYDROData_Tool::GenerateObjectName( aDocument, "Region" );
103     aRegion->SetName( aRegionName );
104
105     // Add the zone for region
106     Handle(HYDROData_Zone) aRegionZone = aRegion->addNewZone();
107
108     QString aZoneName = HYDROData_Tool::GenerateObjectName( aDocument, "Zone" );
109     aRegionZone->SetName( aZoneName );
110
111     aRegionZone->SetShape( aSplitData.Face() );
112
113     // Add the reference object for zone
114     for ( int i = 0, n = aSplitData.ObjectNames.length(); i < n; ++i )
115     {
116       const QString& anObjName = aSplitData.ObjectNames.at( i );
117       
118       Handle(HYDROData_Object) aRefObject = Handle(HYDROData_Object)::DownCast(
119         HYDROData_Tool::FindObjectByName( aDocument, anObjName ) );
120       if ( aRefObject.IsNull() )
121         continue;
122
123       aRegionZone->AddGeometryObject( aRefObject );
124     }
125   }
126
127   // The splitted data is up to date
128   SetToUpdate( false );
129 }
130
131 bool HYDROData_CalculationCase::AddGeometryObject( const Handle(HYDROData_Object)& theObject )
132 {
133   if ( theObject.IsNull() )
134     return false;
135   
136   if ( !theObject->IsKind( STANDARD_TYPE(HYDROData_ArtificialObject) ) &&
137        !theObject->IsKind( STANDARD_TYPE(HYDROData_NaturalObject) ) )
138     return false; // Wrong type of object
139
140   if ( HasReference( theObject, DataTag_GeometryObject ) )
141     return false; // Object is already in reference list
142
143   AddReferenceObject( theObject, DataTag_GeometryObject );
144   
145   // Indicate model of the need to update zones splitting
146   SetToUpdate( true );
147
148   return true;
149 }
150
151 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetGeometryObjects() const
152 {
153   return GetReferenceObjects( DataTag_GeometryObject );
154 }
155
156 void HYDROData_CalculationCase::RemoveGeometryObject( const Handle(HYDROData_Object)& theObject )
157 {
158   if ( theObject.IsNull() )
159     return;
160
161   RemoveReferenceObject( theObject->Label(), DataTag_GeometryObject );
162
163   // Indicate model of the need to update zones splitting
164   SetToUpdate( true );
165 }
166
167 void HYDROData_CalculationCase::RemoveGeometryObjects()
168 {
169   ClearReferenceObjects( DataTag_GeometryObject );
170
171   // Indicate model of the need to update zones splitting
172   SetToUpdate( true );
173 }
174
175 Handle(HYDROData_Region) HYDROData_CalculationCase::AddNewRegion( const Handle(HYDROData_Zone)& theZone )
176 {
177   Handle(HYDROData_Region) aNewRegion = addNewRegion();
178   if ( aNewRegion.IsNull() )
179     return aNewRegion;
180
181   // Generate new name for new region
182   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
183   if ( !aDocument.IsNull() )
184   {
185     QString aNewRegionName = HYDROData_Tool::GenerateObjectName( aDocument, "Region" );
186     aNewRegion->SetName( aNewRegionName );
187   }
188
189   aNewRegion->AddZone( theZone );
190
191   return aNewRegion;
192 }
193
194 bool HYDROData_CalculationCase::AddRegion( const Handle(HYDROData_Region)& theRegion )
195 {
196   if ( theRegion.IsNull() )
197     return false;
198   
199   if ( HasReference( theRegion, DataTag_Region ) )
200     return false; // Object is already in reference list
201
202   // Move the region from other calculation
203   Handle(HYDROData_CalculationCase) aFatherCalc = 
204     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
205   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() != myLab )
206   {
207     Handle(HYDROData_Region) aNewRegion = addNewRegion();
208     theRegion->CopyTo( aNewRegion );
209
210     aFatherCalc->RemoveRegion( theRegion );
211
212     theRegion->SetLabel( aNewRegion->Label() );
213   }
214   else
215   {
216     AddReferenceObject( theRegion, DataTag_Region );
217   }
218
219   return true;
220 }
221
222 HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetRegions() const
223 {
224   return GetReferenceObjects( DataTag_Region );
225 }
226
227 void HYDROData_CalculationCase::RemoveRegion( const Handle(HYDROData_Region)& theRegion )
228 {
229   if ( theRegion.IsNull() )
230     return;
231
232   RemoveReferenceObject( theRegion->Label(), DataTag_Region );
233
234   // Remove region from data model
235   Handle(HYDROData_CalculationCase) aFatherCalc = 
236     Handle(HYDROData_CalculationCase)::DownCast( theRegion->GetFatherObject() );
237   if ( !aFatherCalc.IsNull() && aFatherCalc->Label() == myLab )
238     theRegion->Remove();
239 }
240
241 void HYDROData_CalculationCase::RemoveRegions()
242 {
243   ClearReferenceObjects( DataTag_Region );
244   myLab.FindChild( DataTag_ChildRegion ).ForgetAllAttributes( true );
245 }
246
247 Handle(HYDROData_Region) HYDROData_CalculationCase::addNewRegion()
248 {
249   TDF_Label aNewLab = myLab.FindChild( DataTag_ChildRegion ).NewChild();
250
251   Handle(HYDROData_Region) aNewRegion =
252     Handle(HYDROData_Region)::DownCast( HYDROData_Iterator::CreateObject( aNewLab, KIND_REGION ) );
253   AddRegion( aNewRegion );
254
255   return aNewRegion;
256 }
257