Salome HOME
Bug #490: batch mode error.
[modules/hydro.git] / src / HYDROData / HYDROData_PriorityQueue.cxx
1
2 #include <HYDROData_PriorityQueue.h>
3 #include <HYDROData_CalculationCase.h>
4 #include <HYDROData_Iterator.h>
5 #include <TDataStd_ReferenceList.hxx>
6 #include <TDataStd_Integer.hxx>
7 #include <TDF_ChildIterator.hxx>
8
9 HYDROData_PriorityQueue::HYDROData_PriorityQueue( HYDROData_CalculationCase* theCalcCase )
10 {
11   myGeomObjects = theCalcCase->GetGeometryObjects();
12   for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
13   {
14     Handle(HYDROData_Object) anObj = Handle(HYDROData_Object)::DownCast( myGeomObjects.Value( i ) );
15     if( !anObj.IsNull() )
16     {
17       QString anObjName = anObj->GetName();
18       myNames[anObjName] = anObj;
19     }
20   }
21
22   myRules = GetRules( theCalcCase->Label().FindChild( HYDROData_CalculationCase::DataTag_CustomRules ) );
23 }
24
25 HYDROData_PriorityQueue::~HYDROData_PriorityQueue()
26 {
27 }
28
29 Handle(HYDROData_Object) HYDROData_PriorityQueue::GetMostPriorityObject( const QStringList& theZoneObjects,
30                                                                          HYDROData_Zone::MergeAltitudesType& theMergeType ) const
31 {
32   QStringList aSortedZoneObjects;
33   for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
34   {
35     QString aName = myGeomObjects.Value( i )->GetName();
36     if( theZoneObjects.contains( aName ) )
37       aSortedZoneObjects.append( aName );
38   }
39
40   Handle(HYDROData_Object) aMostPriorityObj;
41   theMergeType = HYDROData_Zone::Merge_UNKNOWN;
42   QStringList::const_iterator anIt = aSortedZoneObjects.begin(), aLast = aSortedZoneObjects.end();
43   for( ; anIt!=aLast; anIt++ )
44   {
45     HYDROData_Zone::MergeAltitudesType aLocalMerge = HYDROData_Zone::Merge_UNKNOWN;
46     Handle(HYDROData_Object) anObj = myNames[*anIt];
47     if( !anObj.IsNull() )
48     {
49       if( aMostPriorityObj.IsNull() )
50       {
51         aMostPriorityObj = anObj;
52         continue;
53       }
54
55       bool isMorePriority = IsMorePriority( anObj, aMostPriorityObj, aLocalMerge );
56
57       if( isMorePriority )
58         aMostPriorityObj = anObj;
59
60       if( aLocalMerge != HYDROData_Zone::Merge_UNKNOWN && 
61           ( theMergeType==HYDROData_Zone::Merge_UNKNOWN || isMorePriority ) )
62         theMergeType = aLocalMerge;
63     }
64   }
65   return aMostPriorityObj;
66 }
67
68 bool HYDROData_PriorityQueue::IsMorePriority( const Handle(HYDROData_Object)& theObj1,
69                                               const Handle(HYDROData_Object)& theObj2,
70                                               HYDROData_Zone::MergeAltitudesType& theMergeType ) const
71 {
72   // 1. First we check custom rules
73   HYDROData_ListOfRules::const_iterator anIt = myRules.begin(), aLast = myRules.end();
74   for( ; anIt!=aLast; anIt++ )
75   {
76     if( anIt->Object1->Label()==theObj1->Label() && anIt->Object2->Label()==theObj2->Label() )
77     {
78       theMergeType = anIt->MergeType;
79       return anIt->Priority==GREATER;
80     }
81     if( anIt->Object1->Label()==theObj2->Label() && anIt->Object2->Label()==theObj1->Label() )
82     {
83       theMergeType = anIt->MergeType;
84       return anIt->Priority==LESS;
85     }
86   }
87
88   // 2. If no custom rule found, the standard ordering list is applied
89   for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
90   {
91     if( myGeomObjects.Value( i )->Label() == theObj1->Label() )
92     {
93       theMergeType = HYDROData_Zone::Merge_Object;
94       return true;
95     }
96     if( myGeomObjects.Value( i )->Label() == theObj2->Label() )
97     {
98       theMergeType = HYDROData_Zone::Merge_Object;
99       return false;
100     }
101   }
102   return false;
103 }
104
105 void HYDROData_PriorityQueue::ClearRules( TDF_Label& theRulesLabel )
106 {
107   theRulesLabel.ForgetAllAttributes( true );
108 }
109
110 enum HYDROData_PriorityQueueTag
111 {
112   Object1_Tag,
113   Priority_Tag,
114   Object2_Tag,
115   Merge_Tag,
116 };
117
118 void HYDROData_PriorityQueue::AddRule( TDF_Label&                         theRulesLabel,
119                                        const Handle(HYDROData_Object)&    theObject1,
120                                        HYDROData_PriorityType             thePriority,
121                                        const Handle(HYDROData_Object)&    theObject2,
122                                        HYDROData_Zone::MergeAltitudesType theMergeType )
123 {
124   // Get the last rule index
125   Standard_Integer aRuleIndex = 0;
126   Handle(TDataStd_Integer) anIntVal;
127   if ( theRulesLabel.FindAttribute( TDataStd_Integer::GetID(), anIntVal ) ) {
128     aRuleIndex = anIntVal->Get();
129   }
130
131   TDF_Label aNewRuleLab = theRulesLabel.FindChild( aRuleIndex );
132
133   TDF_Label anObj1Lab = aNewRuleLab.FindChild( Object1_Tag );
134   Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set( anObj1Lab );
135   aRefs->Append( theObject1->Label() );
136   
137   TDF_Label aPriorityLab = aNewRuleLab.FindChild( Priority_Tag );
138   TDataStd_Integer::Set( aPriorityLab, thePriority );
139
140   TDF_Label anObj2Lab = aNewRuleLab.FindChild( Object2_Tag );
141   aRefs = TDataStd_ReferenceList::Set( anObj2Lab );
142   aRefs->Append( theObject2->Label() );
143
144   TDF_Label aMergeLab = aNewRuleLab.FindChild( Merge_Tag );
145   TDataStd_Integer::Set( aMergeLab, theMergeType );
146
147   // Increment the last rule index
148   TDataStd_Integer::Set( theRulesLabel, aRuleIndex + 1 );
149 }
150
151 HYDROData_ListOfRules HYDROData_PriorityQueue::GetRules( const TDF_Label& theRulesLabel )
152 {
153   HYDROData_ListOfRules aRules;
154
155   Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
156   Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
157
158   TDF_ChildIterator anIt( theRulesLabel );
159   for( ; anIt.More(); anIt.Next() )
160   {
161     TDF_Label aRuleLabel = anIt.Value();
162
163     bool isObj1OK = aRuleLabel.FindChild    ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
164     bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(),       aPriorityAttr );
165     bool isObj2OK = aRuleLabel.FindChild    ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
166     bool isMergeOK = aRuleLabel.FindChild   ( Merge_Tag ).   FindAttribute( TDataStd_Integer::GetID(),       aMergeAttr );
167
168     if( isObj1OK && isPriorityOK && isObj2OK && isMergeOK )
169     {
170       HYDROData_CustomRule aRule;
171       aRule.Object1 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs1->First() ) );
172       aRule.Priority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
173       aRule.Object2 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs2->First() ) );
174       aRule.MergeType = ( HYDROData_Zone::MergeAltitudesType ) aMergeAttr->Get();
175       aRules.append( aRule );
176     }
177   }
178
179   return aRules;
180 }
181
182 QString HYDROData_PriorityQueue::DumpRules( const TDF_Label& theRulesLab )
183 {
184   QString aDump = "Rules:\n";
185   HYDROData_ListOfRules aRules = GetRules( theRulesLab );
186   HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
187   for( ; anIt!=aLast; anIt++ )
188   {
189     QString aRule = anIt->Object1->GetName() + " ";
190     aRule += ( anIt->Priority == LESS ? "<" : ">" ) + QString( " " );
191     aRule += anIt->Object2->GetName() + " ";
192
193     switch( anIt->MergeType )
194     {
195     case HYDROData_Zone::Merge_UNKNOWN:
196       aRule += "unknown";
197       break;
198     case HYDROData_Zone::Merge_ZMIN:
199       aRule += "zmin";
200       break;
201     case HYDROData_Zone::Merge_ZMAX:
202       aRule += "zmax";
203       break;
204     case HYDROData_Zone::Merge_Object:
205       aRule += "object";
206       break;
207     }
208     aDump += aRule + "\n";
209   }
210   return aDump;
211 }
212
213 void HYDROData_PriorityQueue::DumpRulesToPython( const TDF_Label& theRulesLab,
214                                                  const QString& theCalcCaseName,
215                                                  QStringList& theScript )
216 {
217   HYDROData_ListOfRules aRules = GetRules( theRulesLab );
218   HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
219   for( ; anIt!=aLast; anIt++ )
220   {
221     QString anObj1 = anIt->Object1->GetObjPyName();
222     QString anObj2 = anIt->Object2->GetObjPyName();
223     QString aPriority = anIt->Priority == LESS ? "LESS" : "GREATER";
224     QString aMergeType;
225
226     switch( anIt->MergeType )
227     {
228     case HYDROData_Zone::Merge_UNKNOWN:
229       aMergeType = "HYDROData_Zone.Merge_UNKNOWN";
230       break;
231     case HYDROData_Zone::Merge_ZMIN:
232       aMergeType = "HYDROData_Zone.Merge_ZMIN";
233       break;
234     case HYDROData_Zone::Merge_ZMAX:
235       aMergeType = "HYDROData_Zone.Merge_ZMAX";
236       break;
237     case HYDROData_Zone::Merge_Object:
238       aMergeType = "HYDROData_Zone.Merge_Object";
239       break;
240     }
241
242     QString aRule = QString( "%0.AddRule( %1, %2, %3, %4 )" ).
243       arg( theCalcCaseName ).arg( anObj1 ).arg( aPriority ).arg( anObj2 ).arg( aMergeType );
244
245     theScript << aRule;
246   }
247 }
248
249 bool HYDROData_PriorityQueue::GetRule( const TDF_Label& theRulesLab,
250                                        int theIndex, 
251                                        Handle(HYDROData_Object)&           theObject1,
252                                        HYDROData_PriorityType&             thePriority,
253                                        Handle(HYDROData_Object)&           theObject2,
254                                        HYDROData_Zone::MergeAltitudesType& theMergeType )
255 {
256   TDF_Label aRuleLabel = theRulesLab.FindChild( theIndex );
257
258   Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
259   Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
260
261   bool isObj1OK = aRuleLabel.FindChild    ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
262   bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(),       aPriorityAttr );
263   bool isObj2OK = aRuleLabel.FindChild    ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
264   bool isMergeOK = aRuleLabel.FindChild   ( Merge_Tag ).   FindAttribute( TDataStd_Integer::GetID(),       aMergeAttr );
265
266   bool isOK = isObj1OK && isPriorityOK && isObj2OK && isMergeOK;
267   if( isOK )
268   {
269     theObject1   = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs1->First() ) );
270     thePriority  = ( HYDROData_PriorityType ) aPriorityAttr->Get();
271     theObject2   = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs2->First() ) );
272     theMergeType = ( HYDROData_Zone::MergeAltitudesType ) aMergeAttr->Get();
273   }
274   return isOK;
275 }