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 <TDataStd_ReferenceList.hxx>
23 #include <TDataStd_Integer.hxx>
24 #include <TDF_ChildIterator.hxx>
26 HYDROData_PriorityQueue::HYDROData_PriorityQueue( HYDROData_CalculationCase* theCalcCase,
27 Standard_Integer aTag )
29 myObjects = theCalcCase->GetGeometryObjects();
30 for( int i=myObjects.Lower(), n=myObjects.Upper(); i<=n; i++ )
32 Handle(HYDROData_Entity) anObj = myObjects.Value( i );
35 QString anObjName = anObj->GetName();
36 myNames[anObjName] = anObj;
40 myRules = GetRules( theCalcCase->Label().FindChild( aTag ) );
43 HYDROData_PriorityQueue::~HYDROData_PriorityQueue()
47 Handle(HYDROData_Entity) HYDROData_PriorityQueue::GetMostPriorityObject( const QStringList& theZoneObjects,
48 HYDROData_Zone::MergeType& theMergeType ) const
50 QStringList aSortedZoneObjects;
51 for( int i=myObjects.Lower(), n=myObjects.Upper(); i<=n; i++ )
53 QString aName = myObjects.Value( i )->GetName();
54 if( theZoneObjects.contains( aName ) )
55 aSortedZoneObjects.append( aName );
58 Handle(HYDROData_Entity) aMostPriorityObj;
59 theMergeType = HYDROData_Zone::Merge_UNKNOWN;
60 QStringList::const_iterator anIt = aSortedZoneObjects.begin(), aLast = aSortedZoneObjects.end();
61 for( ; anIt!=aLast; anIt++ )
63 HYDROData_Zone::MergeType aLocalMerge = HYDROData_Zone::Merge_UNKNOWN;
64 Handle(HYDROData_Entity) anObj = myNames[*anIt];
67 if( aMostPriorityObj.IsNull() )
69 aMostPriorityObj = anObj;
73 bool isMorePriority = IsMorePriority( anObj, aMostPriorityObj, aLocalMerge );
76 aMostPriorityObj = anObj;
78 if( aLocalMerge != HYDROData_Zone::Merge_UNKNOWN &&
79 ( theMergeType==HYDROData_Zone::Merge_UNKNOWN || isMorePriority ) )
80 theMergeType = aLocalMerge;
83 return aMostPriorityObj;
86 bool HYDROData_PriorityQueue::IsMorePriority( const Handle(HYDROData_Entity)& theObj1,
87 const Handle(HYDROData_Entity)& theObj2,
88 HYDROData_Zone::MergeType& theMergeType ) const
90 // 1. First we check custom rules
91 HYDROData_ListOfRules::const_iterator anIt = myRules.begin(), aLast = myRules.end();
92 for( ; anIt!=aLast; anIt++ )
94 if( anIt->Object1->Label()==theObj1->Label() && anIt->Object2->Label()==theObj2->Label() )
96 theMergeType = anIt->MergeType;
97 return anIt->Priority==GREATER;
99 if( anIt->Object1->Label()==theObj2->Label() && anIt->Object2->Label()==theObj1->Label() )
101 theMergeType = anIt->MergeType;
102 return anIt->Priority==LESS;
106 // 2. If no custom rule found, the standard ordering list is applied
107 for( int i=myObjects.Lower(), n=myObjects.Upper(); i<=n; i++ )
109 if( myObjects.Value( i )->Label() == theObj1->Label() )
111 theMergeType = HYDROData_Zone::Merge_Object;
114 if( myObjects.Value( i )->Label() == theObj2->Label() )
116 theMergeType = HYDROData_Zone::Merge_Object;
123 void HYDROData_PriorityQueue::ClearRules( TDF_Label& theRulesLabel )
125 theRulesLabel.ForgetAllAttributes( true );
128 enum HYDROData_PriorityQueueTag
136 void HYDROData_PriorityQueue::AddRule( TDF_Label& theRulesLabel,
137 const Handle(HYDROData_Entity)& theObject1,
138 HYDROData_PriorityType thePriority,
139 const Handle(HYDROData_Entity)& theObject2,
140 HYDROData_Zone::MergeType theMergeType )
142 // Get the last rule index
143 Standard_Integer aRuleIndex = 0;
144 Handle(TDataStd_Integer) anIntVal;
145 if ( theRulesLabel.FindAttribute( TDataStd_Integer::GetID(), anIntVal ) ) {
146 aRuleIndex = anIntVal->Get();
149 TDF_Label aNewRuleLab = theRulesLabel.FindChild( aRuleIndex );
151 TDF_Label anObj1Lab = aNewRuleLab.FindChild( Object1_Tag );
152 Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set( anObj1Lab );
153 aRefs->Append( theObject1->Label() );
155 TDF_Label aPriorityLab = aNewRuleLab.FindChild( Priority_Tag );
156 TDataStd_Integer::Set( aPriorityLab, thePriority );
158 TDF_Label anObj2Lab = aNewRuleLab.FindChild( Object2_Tag );
159 aRefs = TDataStd_ReferenceList::Set( anObj2Lab );
160 aRefs->Append( theObject2->Label() );
162 TDF_Label aMergeLab = aNewRuleLab.FindChild( Merge_Tag );
163 TDataStd_Integer::Set( aMergeLab, theMergeType );
165 // Increment the last rule index
166 TDataStd_Integer::Set( theRulesLabel, aRuleIndex + 1 );
169 HYDROData_ListOfRules HYDROData_PriorityQueue::GetRules( const TDF_Label& theRulesLabel )
171 HYDROData_ListOfRules aRules;
173 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
174 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
176 TDF_ChildIterator anIt( theRulesLabel );
177 for( ; anIt.More(); anIt.Next() )
179 TDF_Label aRuleLabel = anIt.Value();
181 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
182 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
183 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
184 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
186 if( isObj1OK && isPriorityOK && isObj2OK && isMergeOK )
188 HYDROData_CustomRule aRule;
189 aRule.Object1 = HYDROData_Iterator::Object( aRefs1->First() );
190 aRule.Priority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
191 aRule.Object2 = HYDROData_Iterator::Object( aRefs2->First() );
192 aRule.MergeType = ( HYDROData_Zone::MergeType ) aMergeAttr->Get();
193 aRules.append( aRule );
200 QString HYDROData_PriorityQueue::DumpRules( const TDF_Label& theRulesLab )
202 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;
247 switch( anIt->MergeType )
249 case HYDROData_Zone::Merge_UNKNOWN:
250 aMergeType = "HYDROData_Zone.Merge_UNKNOWN";
252 case HYDROData_Zone::Merge_ZMIN:
253 aMergeType = "HYDROData_Zone.Merge_ZMIN";
255 case HYDROData_Zone::Merge_ZMAX:
256 aMergeType = "HYDROData_Zone.Merge_ZMAX";
258 case HYDROData_Zone::Merge_Object:
259 aMergeType = "HYDROData_Zone.Merge_Object";
263 QString aRule = QString( "%0.AddRule( %1, %2, %3, %4, %5 )" ).
264 arg( theCalcCaseName ).arg( anObj1 ).arg( aPriority ).arg( anObj2 ).arg( aMergeType ).arg( aDataTag );
270 bool HYDROData_PriorityQueue::GetRule( const TDF_Label& theRulesLab,
272 Handle(HYDROData_Entity)& theObject1,
273 HYDROData_PriorityType& thePriority,
274 Handle(HYDROData_Entity)& theObject2,
275 HYDROData_Zone::MergeType& theMergeType )
277 TDF_Label aRuleLabel = theRulesLab.FindChild( theIndex );
279 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
280 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
282 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
283 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
284 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
285 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
287 bool isOK = isObj1OK && isPriorityOK && isObj2OK && isMergeOK;
290 theObject1 = HYDROData_Iterator::Object( aRefs1->First() );
291 thePriority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
292 theObject2 = HYDROData_Iterator::Object( aRefs2->First() );
293 theMergeType = ( HYDROData_Zone::MergeType ) aMergeAttr->Get();