Salome HOME
patch for clear rules method
[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   TDF_Label aNewRuleLab = theRulesLabel.NewChild();
125
126   TDF_Label anObj1Lab = aNewRuleLab.FindChild( Object1_Tag );
127   Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set( anObj1Lab );
128   aRefs->Append( theObject1->Label() );
129   
130   TDF_Label aPriorityLab = aNewRuleLab.FindChild( Priority_Tag );
131   TDataStd_Integer::Set( aPriorityLab, thePriority );
132
133   TDF_Label anObj2Lab = aNewRuleLab.FindChild( Object2_Tag );
134   aRefs = TDataStd_ReferenceList::Set( anObj2Lab );
135   aRefs->Append( theObject2->Label() );
136
137   TDF_Label aMergeLab = aNewRuleLab.FindChild( Merge_Tag );
138   TDataStd_Integer::Set( aMergeLab, theMergeType );
139 }
140
141 HYDROData_ListOfRules HYDROData_PriorityQueue::GetRules( const TDF_Label& theRulesLabel )
142 {
143   HYDROData_ListOfRules aRules;
144
145   Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
146   Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
147
148   TDF_ChildIterator anIt( theRulesLabel );
149   for( ; anIt.More(); anIt.Next() )
150   {
151     TDF_Label aRuleLabel = anIt.Value();
152
153     bool isObj1OK = aRuleLabel.FindChild    ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
154     bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(),       aPriorityAttr );
155     bool isObj2OK = aRuleLabel.FindChild    ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
156     bool isMergeOK = aRuleLabel.FindChild   ( Merge_Tag ).   FindAttribute( TDataStd_Integer::GetID(),       aMergeAttr );
157
158     if( isObj1OK && isPriorityOK && isObj2OK && isMergeOK )
159     {
160       HYDROData_CustomRule aRule;
161       aRule.Object1 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs1->First() ) );
162       aRule.Priority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
163       aRule.Object2 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs2->First() ) );
164       aRule.MergeType = ( HYDROData_Zone::MergeAltitudesType ) aMergeAttr->Get();
165       aRules.append( aRule );
166     }
167   }
168
169   return aRules;
170 }
171
172 QString HYDROData_PriorityQueue::DumpRules( const TDF_Label& theRulesLab )
173 {
174   QString aDump = "Rules:\n";
175   HYDROData_ListOfRules aRules = GetRules( theRulesLab );
176   HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
177   for( ; anIt!=aLast; anIt++ )
178   {
179     QString aRule = anIt->Object1->GetName() + " ";
180     aRule += ( anIt->Priority == LESS ? "<" : ">" ) + QString( " " );
181     aRule += anIt->Object2->GetName() + " ";
182
183     switch( anIt->MergeType )
184     {
185     case HYDROData_Zone::Merge_UNKNOWN:
186       aRule += "unknown";
187       break;
188     case HYDROData_Zone::Merge_ZMIN:
189       aRule += "zmin";
190       break;
191     case HYDROData_Zone::Merge_ZMAX:
192       aRule += "zmax";
193       break;
194     case HYDROData_Zone::Merge_Object:
195       aRule += "object";
196       break;
197     }
198     aDump += aRule + "\n";
199   }
200   return aDump;
201 }
202
203 void HYDROData_PriorityQueue::DumpRulesToPython( const TDF_Label& theRulesLab,
204                                                  const QString& theCalcCaseName,
205                                                  QStringList& theScript )
206 {
207   HYDROData_ListOfRules aRules = GetRules( theRulesLab );
208   HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
209   for( ; anIt!=aLast; anIt++ )
210   {
211     QString anObj1 = anIt->Object1->GetObjPyName();
212     QString anObj2 = anIt->Object2->GetObjPyName();
213     QString aPriority = anIt->Priority == LESS ? "LESS" : "GREATER";
214     QString aMergeType;
215
216     switch( anIt->MergeType )
217     {
218     case HYDROData_Zone::Merge_UNKNOWN:
219       aMergeType = "HYDROData_Zone.Merge_UNKNOWN";
220       break;
221     case HYDROData_Zone::Merge_ZMIN:
222       aMergeType = "HYDROData_Zone.Merge_ZMIN";
223       break;
224     case HYDROData_Zone::Merge_ZMAX:
225       aMergeType = "HYDROData_Zone.Merge_ZMAX";
226       break;
227     case HYDROData_Zone::Merge_Object:
228       aMergeType = "HYDROData_Zone.Merge_Object";
229       break;
230     }
231
232     QString aRule = QString( "%0.AddRule( %1, %2, %3, %4 )" ).
233       arg( theCalcCaseName ).arg( anObj1 ).arg( aPriority ).arg( anObj2 ).arg( aMergeType );
234
235     theScript << aRule;
236   }
237 }
238
239 bool HYDROData_PriorityQueue::GetRule( const TDF_Label& theRulesLab,
240                                        int theIndex, 
241                                        Handle(HYDROData_Object)&           theObject1,
242                                        HYDROData_PriorityType&             thePriority,
243                                        Handle(HYDROData_Object)&           theObject2,
244                                        HYDROData_Zone::MergeAltitudesType& theMergeType )
245 {
246   TDF_Label aRuleLabel = theRulesLab.FindChild( theIndex );
247
248   Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
249   Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
250
251   bool isObj1OK = aRuleLabel.FindChild    ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
252   bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(),       aPriorityAttr );
253   bool isObj2OK = aRuleLabel.FindChild    ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
254   bool isMergeOK = aRuleLabel.FindChild   ( Merge_Tag ).   FindAttribute( TDataStd_Integer::GetID(),       aMergeAttr );
255
256   bool isOK = isObj1OK && isPriorityOK && isObj2OK && isMergeOK;
257   if( isOK )
258   {
259     theObject1   = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs1->First() ) );
260     thePriority  = ( HYDROData_PriorityType ) aPriorityAttr->Get();
261     theObject2   = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs2->First() ) );
262     theMergeType = ( HYDROData_Zone::MergeAltitudesType ) aMergeAttr->Get();
263   }
264   return isOK;
265 }