1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include <HYDROData_PriorityQueue.h>
20 #include <HYDROData_CalculationCase.h>
21 #include <HYDROData_Iterator.h>
22 #include <HYDROData_LandCover.h>
23 #include <TDataStd_ReferenceList.hxx>
24 #include <TDataStd_Integer.hxx>
25 #include <TDF_ChildIterator.hxx>
27 HYDROData_PriorityQueue::HYDROData_PriorityQueue( HYDROData_CalculationCase* theCalcCase,
28 Standard_Integer aTag )
30 bool isLandCover = aTag == HYDROData_CalculationCase::DataTag_CustomLandCoverRules;
31 myObjects = isLandCover ? theCalcCase->GetLandCovers() : theCalcCase->GetGeometryObjects();
32 for( int i=myObjects.Lower(), n=myObjects.Upper(); i<=n; i++ )
34 Handle(HYDROData_Entity) anObj = myObjects.Value( i );
37 QString anObjName = anObj->GetName();
38 myNames[anObjName] = anObj;
42 myRules = GetRules( theCalcCase->Label().FindChild( aTag ) );
45 HYDROData_PriorityQueue::~HYDROData_PriorityQueue()
49 Handle(HYDROData_Entity) HYDROData_PriorityQueue::GetMostPriorityObject( const QStringList& theZoneObjects,
50 HYDROData_Zone::MergeType& theMergeType ) const
52 QStringList aSortedZoneObjects;
53 for( int i=myObjects.Lower(), n=myObjects.Upper(); i<=n; i++ )
55 QString aName = myObjects.Value( i )->GetName();
56 if( theZoneObjects.contains( aName ) )
57 aSortedZoneObjects.append( aName );
60 Handle(HYDROData_Entity) aMostPriorityObj;
61 theMergeType = HYDROData_Zone::Merge_UNKNOWN;
62 QStringList::const_iterator anIt = aSortedZoneObjects.begin(), aLast = aSortedZoneObjects.end();
63 for( ; anIt!=aLast; anIt++ )
65 HYDROData_Zone::MergeType aLocalMerge = HYDROData_Zone::Merge_UNKNOWN;
66 Handle(HYDROData_Entity) anObj = myNames[*anIt];
69 if( aMostPriorityObj.IsNull() )
71 aMostPriorityObj = anObj;
75 bool isMorePriority = IsMorePriority( anObj, aMostPriorityObj, aLocalMerge );
78 aMostPriorityObj = anObj;
80 if( aLocalMerge != HYDROData_Zone::Merge_UNKNOWN &&
81 ( theMergeType==HYDROData_Zone::Merge_UNKNOWN || isMorePriority ) )
82 theMergeType = aLocalMerge;
85 return aMostPriorityObj;
88 bool HYDROData_PriorityQueue::IsMorePriority( const Handle(HYDROData_Entity)& theObj1,
89 const Handle(HYDROData_Entity)& theObj2,
90 HYDROData_Zone::MergeType& theMergeType ) const
92 // 1. First we check custom rules
93 HYDROData_ListOfRules::const_iterator anIt = myRules.begin(), aLast = myRules.end();
94 for( ; anIt!=aLast; anIt++ )
96 if( anIt->Object1->Label()==theObj1->Label() && anIt->Object2->Label()==theObj2->Label() )
98 theMergeType = anIt->MergeType;
99 return anIt->Priority==GREATER;
101 if( anIt->Object1->Label()==theObj2->Label() && anIt->Object2->Label()==theObj1->Label() )
103 theMergeType = anIt->MergeType;
104 return anIt->Priority==LESS;
108 // 2. If no custom rule found, the standard ordering list is applied
109 for( int i=myObjects.Lower(), n=myObjects.Upper(); i<=n; i++ )
111 if( myObjects.Value( i )->Label() == theObj1->Label() )
113 theMergeType = HYDROData_Zone::Merge_Object;
116 if( myObjects.Value( i )->Label() == theObj2->Label() )
118 theMergeType = HYDROData_Zone::Merge_Object;
125 void HYDROData_PriorityQueue::ClearRules( TDF_Label& theRulesLabel )
127 theRulesLabel.ForgetAllAttributes( true );
130 enum HYDROData_PriorityQueueTag
138 void HYDROData_PriorityQueue::AddRule( TDF_Label& theRulesLabel,
139 const Handle(HYDROData_Entity)& theObject1,
140 HYDROData_PriorityType thePriority,
141 const Handle(HYDROData_Entity)& theObject2,
142 HYDROData_Zone::MergeType theMergeType )
144 // Get the last rule index
145 Standard_Integer aRuleIndex = 0;
146 Handle(TDataStd_Integer) anIntVal;
147 if ( theRulesLabel.FindAttribute( TDataStd_Integer::GetID(), anIntVal ) ) {
148 aRuleIndex = anIntVal->Get();
151 TDF_Label aNewRuleLab = theRulesLabel.FindChild( aRuleIndex );
153 TDF_Label anObj1Lab = aNewRuleLab.FindChild( Object1_Tag );
154 Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set( anObj1Lab );
155 aRefs->Append( theObject1->Label() );
157 TDF_Label aPriorityLab = aNewRuleLab.FindChild( Priority_Tag );
158 TDataStd_Integer::Set( aPriorityLab, thePriority );
160 TDF_Label anObj2Lab = aNewRuleLab.FindChild( Object2_Tag );
161 aRefs = TDataStd_ReferenceList::Set( anObj2Lab );
162 aRefs->Append( theObject2->Label() );
164 TDF_Label aMergeLab = aNewRuleLab.FindChild( Merge_Tag );
165 TDataStd_Integer::Set( aMergeLab, theMergeType );
167 // Increment the last rule index
168 TDataStd_Integer::Set( theRulesLabel, aRuleIndex + 1 );
171 HYDROData_ListOfRules HYDROData_PriorityQueue::GetRules( const TDF_Label& theRulesLabel )
173 HYDROData_ListOfRules aRules;
175 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
176 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
178 TDF_ChildIterator anIt( theRulesLabel );
179 for( ; anIt.More(); anIt.Next() )
181 TDF_Label aRuleLabel = anIt.Value();
183 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
184 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
185 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
186 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
188 if( isObj1OK && isPriorityOK && isObj2OK && isMergeOK )
190 HYDROData_CustomRule aRule;
191 aRule.Object1 = HYDROData_Iterator::Object( aRefs1->First() );
192 aRule.Priority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
193 aRule.Object2 = HYDROData_Iterator::Object( aRefs2->First() );
194 aRule.MergeType = ( HYDROData_Zone::MergeType ) aMergeAttr->Get();
195 aRules.append( aRule );
202 QString HYDROData_PriorityQueue::DumpRules( const TDF_Label& theRulesLab )
204 bool isLandCover = theRulesLab.Tag() == HYDROData_CalculationCase::DataTag_CustomLandCoverRules;
205 QString aDump = isLandCover ? "Land Cover rules:\n" : "Rules:\n";
207 HYDROData_ListOfRules aRules = GetRules( theRulesLab );
208 HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
209 for( ; anIt!=aLast; anIt++ )
211 QString aRule = anIt->Object1->GetName() + " ";
212 aRule += ( anIt->Priority == LESS ? "<" : ">" ) + QString( " " );
213 aRule += anIt->Object2->GetName() + " ";
215 switch( anIt->MergeType )
217 case HYDROData_Zone::Merge_UNKNOWN:
220 case HYDROData_Zone::Merge_ZMIN:
223 case HYDROData_Zone::Merge_ZMAX:
226 case HYDROData_Zone::Merge_Object:
230 aDump += aRule + "\n";
235 void HYDROData_PriorityQueue::DumpRulesToPython( const TDF_Label& theRulesLab,
236 const QString& theCalcCaseName,
237 QStringList& theScript )
239 HYDROData_ListOfRules aRules = GetRules( theRulesLab );
240 HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
241 for( ; anIt!=aLast; anIt++ )
243 QString anObj1 = anIt->Object1->GetObjPyName();
244 QString anObj2 = anIt->Object2->GetObjPyName();
245 QString aPriority = anIt->Priority == LESS ? "LESS" : "GREATER";
248 HYDROData_CalculationCase::DataTag aDataTag = HYDROData_CalculationCase::DataTag_CustomRules;
249 Handle(HYDROData_LandCover) aLandCover1 = Handle(HYDROData_LandCover)::DownCast( anIt->Object1 );
250 Handle(HYDROData_LandCover) aLandCover2 = Handle(HYDROData_LandCover)::DownCast( anIt->Object2 );
251 if ( !aLandCover1.IsNull() && !aLandCover2.IsNull() )
252 aDataTag = HYDROData_CalculationCase::DataTag_CustomLandCoverRules;
254 switch( anIt->MergeType )
256 case HYDROData_Zone::Merge_UNKNOWN:
257 aMergeType = "HYDROData_Zone.Merge_UNKNOWN";
259 case HYDROData_Zone::Merge_ZMIN:
260 aMergeType = "HYDROData_Zone.Merge_ZMIN";
262 case HYDROData_Zone::Merge_ZMAX:
263 aMergeType = "HYDROData_Zone.Merge_ZMAX";
265 case HYDROData_Zone::Merge_Object:
266 aMergeType = "HYDROData_Zone.Merge_Object";
270 QString aRule = QString( "%0.AddRule( %1, %2, %3, %4, %5 )" ).
271 arg( theCalcCaseName ).arg( anObj1 ).arg( aPriority ).arg( anObj2 ).arg( aMergeType ).arg( aDataTag );
277 bool HYDROData_PriorityQueue::GetRule( const TDF_Label& theRulesLab,
279 Handle(HYDROData_Entity)& theObject1,
280 HYDROData_PriorityType& thePriority,
281 Handle(HYDROData_Entity)& theObject2,
282 HYDROData_Zone::MergeType& theMergeType )
284 TDF_Label aRuleLabel = theRulesLab.FindChild( theIndex );
286 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
287 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
289 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
290 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
291 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
292 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
294 bool isOK = isObj1OK && isPriorityOK && isObj2OK && isMergeOK;
297 theObject1 = HYDROData_Iterator::Object( aRefs1->First() );
298 thePriority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
299 theObject2 = HYDROData_Iterator::Object( aRefs2->First() );
300 theMergeType = ( HYDROData_Zone::MergeType ) aMergeAttr->Get();