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 myGeomObjects = theCalcCase->GetGeometryObjects();
31 for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
33 Handle(HYDROData_Entity) anObj = myGeomObjects.Value( i );
36 QString anObjName = anObj->GetName();
37 myNames[anObjName] = anObj;
41 myRules = GetRules( theCalcCase->Label().FindChild( aTag ) );
44 HYDROData_PriorityQueue::~HYDROData_PriorityQueue()
48 Handle(HYDROData_Entity) HYDROData_PriorityQueue::GetMostPriorityObject( const QStringList& theZoneObjects,
49 HYDROData_Zone::MergeType& theMergeType ) const
51 QStringList aSortedZoneObjects;
52 for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
54 QString aName = myGeomObjects.Value( i )->GetName();
55 if( theZoneObjects.contains( aName ) )
56 aSortedZoneObjects.append( aName );
59 Handle(HYDROData_Entity) aMostPriorityObj;
60 theMergeType = HYDROData_Zone::Merge_UNKNOWN;
61 QStringList::const_iterator anIt = aSortedZoneObjects.begin(), aLast = aSortedZoneObjects.end();
62 for( ; anIt!=aLast; anIt++ )
64 HYDROData_Zone::MergeType aLocalMerge = HYDROData_Zone::Merge_UNKNOWN;
65 Handle(HYDROData_Entity) anObj = myNames[*anIt];
68 if( aMostPriorityObj.IsNull() )
70 aMostPriorityObj = anObj;
74 bool isMorePriority = IsMorePriority( anObj, aMostPriorityObj, aLocalMerge );
77 aMostPriorityObj = anObj;
79 if( aLocalMerge != HYDROData_Zone::Merge_UNKNOWN &&
80 ( theMergeType==HYDROData_Zone::Merge_UNKNOWN || isMorePriority ) )
81 theMergeType = aLocalMerge;
84 return aMostPriorityObj;
87 bool HYDROData_PriorityQueue::IsMorePriority( const Handle(HYDROData_Entity)& theObj1,
88 const Handle(HYDROData_Entity)& theObj2,
89 HYDROData_Zone::MergeType& theMergeType ) const
91 // 1. First we check custom rules
92 HYDROData_ListOfRules::const_iterator anIt = myRules.begin(), aLast = myRules.end();
93 for( ; anIt!=aLast; anIt++ )
95 if( anIt->Object1->Label()==theObj1->Label() && anIt->Object2->Label()==theObj2->Label() )
97 theMergeType = anIt->MergeType;
98 return anIt->Priority==GREATER;
100 if( anIt->Object1->Label()==theObj2->Label() && anIt->Object2->Label()==theObj1->Label() )
102 theMergeType = anIt->MergeType;
103 return anIt->Priority==LESS;
107 // 2. If no custom rule found, the standard ordering list is applied
108 for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
110 if( myGeomObjects.Value( i )->Label() == theObj1->Label() )
112 theMergeType = HYDROData_Zone::Merge_Object;
115 if( myGeomObjects.Value( i )->Label() == theObj2->Label() )
117 theMergeType = HYDROData_Zone::Merge_Object;
124 void HYDROData_PriorityQueue::ClearRules( TDF_Label& theRulesLabel )
126 theRulesLabel.ForgetAllAttributes( true );
129 enum HYDROData_PriorityQueueTag
137 void HYDROData_PriorityQueue::AddRule( TDF_Label& theRulesLabel,
138 const Handle(HYDROData_Entity)& theObject1,
139 HYDROData_PriorityType thePriority,
140 const Handle(HYDROData_Entity)& theObject2,
141 HYDROData_Zone::MergeType theMergeType )
143 // Get the last rule index
144 Standard_Integer aRuleIndex = 0;
145 Handle(TDataStd_Integer) anIntVal;
146 if ( theRulesLabel.FindAttribute( TDataStd_Integer::GetID(), anIntVal ) ) {
147 aRuleIndex = anIntVal->Get();
150 TDF_Label aNewRuleLab = theRulesLabel.FindChild( aRuleIndex );
152 TDF_Label anObj1Lab = aNewRuleLab.FindChild( Object1_Tag );
153 Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set( anObj1Lab );
154 aRefs->Append( theObject1->Label() );
156 TDF_Label aPriorityLab = aNewRuleLab.FindChild( Priority_Tag );
157 TDataStd_Integer::Set( aPriorityLab, thePriority );
159 TDF_Label anObj2Lab = aNewRuleLab.FindChild( Object2_Tag );
160 aRefs = TDataStd_ReferenceList::Set( anObj2Lab );
161 aRefs->Append( theObject2->Label() );
163 TDF_Label aMergeLab = aNewRuleLab.FindChild( Merge_Tag );
164 TDataStd_Integer::Set( aMergeLab, theMergeType );
166 // Increment the last rule index
167 TDataStd_Integer::Set( theRulesLabel, aRuleIndex + 1 );
170 HYDROData_ListOfRules HYDROData_PriorityQueue::GetRules( const TDF_Label& theRulesLabel )
172 HYDROData_ListOfRules aRules;
174 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
175 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
177 TDF_ChildIterator anIt( theRulesLabel );
178 for( ; anIt.More(); anIt.Next() )
180 TDF_Label aRuleLabel = anIt.Value();
182 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
183 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
184 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
185 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
187 if( isObj1OK && isPriorityOK && isObj2OK && isMergeOK )
189 HYDROData_CustomRule aRule;
190 aRule.Object1 = HYDROData_Iterator::Object( aRefs1->First() );
191 aRule.Priority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
192 aRule.Object2 = HYDROData_Iterator::Object( aRefs2->First() );
193 aRule.MergeType = ( HYDROData_Zone::MergeType ) aMergeAttr->Get();
194 aRules.append( aRule );
201 QString HYDROData_PriorityQueue::DumpRules( const TDF_Label& theRulesLab )
203 QString aDump = "Rules:\n";
204 HYDROData_ListOfRules aRules = GetRules( theRulesLab );
205 HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
206 for( ; anIt!=aLast; anIt++ )
208 QString aRule = anIt->Object1->GetName() + " ";
209 aRule += ( anIt->Priority == LESS ? "<" : ">" ) + QString( " " );
210 aRule += anIt->Object2->GetName() + " ";
212 switch( anIt->MergeType )
214 case HYDROData_Zone::Merge_UNKNOWN:
217 case HYDROData_Zone::Merge_ZMIN:
220 case HYDROData_Zone::Merge_ZMAX:
223 case HYDROData_Zone::Merge_Object:
227 aDump += aRule + "\n";
232 void HYDROData_PriorityQueue::DumpRulesToPython( const TDF_Label& theRulesLab,
233 const QString& theCalcCaseName,
234 QStringList& theScript )
236 HYDROData_ListOfRules aRules = GetRules( theRulesLab );
237 HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
238 for( ; anIt!=aLast; anIt++ )
240 QString anObj1 = anIt->Object1->GetObjPyName();
241 QString anObj2 = anIt->Object2->GetObjPyName();
242 QString aPriority = anIt->Priority == LESS ? "LESS" : "GREATER";
245 HYDROData_CalculationCase::DataTag aDataTag = HYDROData_CalculationCase::DataTag_CustomRules;
246 Handle(HYDROData_LandCover) aLandCover1 = Handle(HYDROData_LandCover)::DownCast( anIt->Object1 );
247 Handle(HYDROData_LandCover) aLandCover2 = Handle(HYDROData_LandCover)::DownCast( anIt->Object2 );
248 if ( !aLandCover1.IsNull() && !aLandCover2.IsNull() )
249 aDataTag = HYDROData_CalculationCase::DataTag_CustomLandCoverRules;
251 switch( anIt->MergeType )
253 case HYDROData_Zone::Merge_UNKNOWN:
254 aMergeType = "HYDROData_Zone.Merge_UNKNOWN";
256 case HYDROData_Zone::Merge_ZMIN:
257 aMergeType = "HYDROData_Zone.Merge_ZMIN";
259 case HYDROData_Zone::Merge_ZMAX:
260 aMergeType = "HYDROData_Zone.Merge_ZMAX";
262 case HYDROData_Zone::Merge_Object:
263 aMergeType = "HYDROData_Zone.Merge_Object";
267 QString aRule = QString( "%0.AddRule( %1, %2, %3, %4, %5 )" ).
268 arg( theCalcCaseName ).arg( anObj1 ).arg( aPriority ).arg( anObj2 ).arg( aMergeType ).arg( aDataTag );
274 bool HYDROData_PriorityQueue::GetRule( const TDF_Label& theRulesLab,
276 Handle(HYDROData_Entity)& theObject1,
277 HYDROData_PriorityType& thePriority,
278 Handle(HYDROData_Entity)& theObject2,
279 HYDROData_Zone::MergeType& theMergeType )
281 TDF_Label aRuleLabel = theRulesLab.FindChild( theIndex );
283 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
284 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
286 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
287 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
288 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
289 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
291 bool isOK = isObj1OK && isPriorityOK && isObj2OK && isMergeOK;
294 theObject1 = HYDROData_Iterator::Object( aRefs1->First() );
295 thePriority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
296 theObject2 = HYDROData_Iterator::Object( aRefs2->First() );
297 theMergeType = ( HYDROData_Zone::MergeType ) aMergeAttr->Get();