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