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