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 )
28 myGeomObjects = theCalcCase->GetGeometryObjects();
29 for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
31 Handle(HYDROData_Object) anObj = Handle(HYDROData_Object)::DownCast( myGeomObjects.Value( i ) );
34 QString anObjName = anObj->GetName();
35 myNames[anObjName] = anObj;
39 myRules = GetRules( theCalcCase->Label().FindChild( HYDROData_CalculationCase::DataTag_CustomRules ) );
42 HYDROData_PriorityQueue::~HYDROData_PriorityQueue()
46 Handle(HYDROData_Object) HYDROData_PriorityQueue::GetMostPriorityObject( const QStringList& theZoneObjects,
47 HYDROData_Zone::MergeAltitudesType& theMergeType ) const
49 QStringList aSortedZoneObjects;
50 for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
52 QString aName = myGeomObjects.Value( i )->GetName();
53 if( theZoneObjects.contains( aName ) )
54 aSortedZoneObjects.append( aName );
57 Handle(HYDROData_Object) aMostPriorityObj;
58 theMergeType = HYDROData_Zone::Merge_UNKNOWN;
59 QStringList::const_iterator anIt = aSortedZoneObjects.begin(), aLast = aSortedZoneObjects.end();
60 for( ; anIt!=aLast; anIt++ )
62 HYDROData_Zone::MergeAltitudesType aLocalMerge = HYDROData_Zone::Merge_UNKNOWN;
63 Handle(HYDROData_Object) anObj = myNames[*anIt];
66 if( aMostPriorityObj.IsNull() )
68 aMostPriorityObj = anObj;
72 bool isMorePriority = IsMorePriority( anObj, aMostPriorityObj, aLocalMerge );
75 aMostPriorityObj = anObj;
77 if( aLocalMerge != HYDROData_Zone::Merge_UNKNOWN &&
78 ( theMergeType==HYDROData_Zone::Merge_UNKNOWN || isMorePriority ) )
79 theMergeType = aLocalMerge;
82 return aMostPriorityObj;
85 bool HYDROData_PriorityQueue::IsMorePriority( const Handle(HYDROData_Object)& theObj1,
86 const Handle(HYDROData_Object)& theObj2,
87 HYDROData_Zone::MergeAltitudesType& theMergeType ) const
89 // 1. First we check custom rules
90 HYDROData_ListOfRules::const_iterator anIt = myRules.begin(), aLast = myRules.end();
91 for( ; anIt!=aLast; anIt++ )
93 if( anIt->Object1->Label()==theObj1->Label() && anIt->Object2->Label()==theObj2->Label() )
95 theMergeType = anIt->MergeType;
96 return anIt->Priority==GREATER;
98 if( anIt->Object1->Label()==theObj2->Label() && anIt->Object2->Label()==theObj1->Label() )
100 theMergeType = anIt->MergeType;
101 return anIt->Priority==LESS;
105 // 2. If no custom rule found, the standard ordering list is applied
106 for( int i=myGeomObjects.Lower(), n=myGeomObjects.Upper(); i<=n; i++ )
108 if( myGeomObjects.Value( i )->Label() == theObj1->Label() )
110 theMergeType = HYDROData_Zone::Merge_Object;
113 if( myGeomObjects.Value( i )->Label() == theObj2->Label() )
115 theMergeType = HYDROData_Zone::Merge_Object;
122 void HYDROData_PriorityQueue::ClearRules( TDF_Label& theRulesLabel )
124 theRulesLabel.ForgetAllAttributes( true );
127 enum HYDROData_PriorityQueueTag
135 void HYDROData_PriorityQueue::AddRule( TDF_Label& theRulesLabel,
136 const Handle(HYDROData_Object)& theObject1,
137 HYDROData_PriorityType thePriority,
138 const Handle(HYDROData_Object)& theObject2,
139 HYDROData_Zone::MergeAltitudesType theMergeType )
141 // Get the last rule index
142 Standard_Integer aRuleIndex = 0;
143 Handle(TDataStd_Integer) anIntVal;
144 if ( theRulesLabel.FindAttribute( TDataStd_Integer::GetID(), anIntVal ) ) {
145 aRuleIndex = anIntVal->Get();
148 TDF_Label aNewRuleLab = theRulesLabel.FindChild( aRuleIndex );
150 TDF_Label anObj1Lab = aNewRuleLab.FindChild( Object1_Tag );
151 Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set( anObj1Lab );
152 aRefs->Append( theObject1->Label() );
154 TDF_Label aPriorityLab = aNewRuleLab.FindChild( Priority_Tag );
155 TDataStd_Integer::Set( aPriorityLab, thePriority );
157 TDF_Label anObj2Lab = aNewRuleLab.FindChild( Object2_Tag );
158 aRefs = TDataStd_ReferenceList::Set( anObj2Lab );
159 aRefs->Append( theObject2->Label() );
161 TDF_Label aMergeLab = aNewRuleLab.FindChild( Merge_Tag );
162 TDataStd_Integer::Set( aMergeLab, theMergeType );
164 // Increment the last rule index
165 TDataStd_Integer::Set( theRulesLabel, aRuleIndex + 1 );
168 HYDROData_ListOfRules HYDROData_PriorityQueue::GetRules( const TDF_Label& theRulesLabel )
170 HYDROData_ListOfRules aRules;
172 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
173 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
175 TDF_ChildIterator anIt( theRulesLabel );
176 for( ; anIt.More(); anIt.Next() )
178 TDF_Label aRuleLabel = anIt.Value();
180 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
181 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
182 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
183 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
185 if( isObj1OK && isPriorityOK && isObj2OK && isMergeOK )
187 HYDROData_CustomRule aRule;
188 aRule.Object1 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs1->First() ) );
189 aRule.Priority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
190 aRule.Object2 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs2->First() ) );
191 aRule.MergeType = ( HYDROData_Zone::MergeAltitudesType ) aMergeAttr->Get();
192 aRules.append( aRule );
199 QString HYDROData_PriorityQueue::DumpRules( const TDF_Label& theRulesLab )
201 QString aDump = "Rules:\n";
202 HYDROData_ListOfRules aRules = GetRules( theRulesLab );
203 HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
204 for( ; anIt!=aLast; anIt++ )
206 QString aRule = anIt->Object1->GetName() + " ";
207 aRule += ( anIt->Priority == LESS ? "<" : ">" ) + QString( " " );
208 aRule += anIt->Object2->GetName() + " ";
210 switch( anIt->MergeType )
212 case HYDROData_Zone::Merge_UNKNOWN:
215 case HYDROData_Zone::Merge_ZMIN:
218 case HYDROData_Zone::Merge_ZMAX:
221 case HYDROData_Zone::Merge_Object:
225 aDump += aRule + "\n";
230 void HYDROData_PriorityQueue::DumpRulesToPython( const TDF_Label& theRulesLab,
231 const QString& theCalcCaseName,
232 QStringList& theScript )
234 HYDROData_ListOfRules aRules = GetRules( theRulesLab );
235 HYDROData_ListOfRules::const_iterator anIt = aRules.begin(), aLast = aRules.end();
236 for( ; anIt!=aLast; anIt++ )
238 QString anObj1 = anIt->Object1->GetObjPyName();
239 QString anObj2 = anIt->Object2->GetObjPyName();
240 QString aPriority = anIt->Priority == LESS ? "LESS" : "GREATER";
243 switch( anIt->MergeType )
245 case HYDROData_Zone::Merge_UNKNOWN:
246 aMergeType = "HYDROData_Zone.Merge_UNKNOWN";
248 case HYDROData_Zone::Merge_ZMIN:
249 aMergeType = "HYDROData_Zone.Merge_ZMIN";
251 case HYDROData_Zone::Merge_ZMAX:
252 aMergeType = "HYDROData_Zone.Merge_ZMAX";
254 case HYDROData_Zone::Merge_Object:
255 aMergeType = "HYDROData_Zone.Merge_Object";
259 QString aRule = QString( "%0.AddRule( %1, %2, %3, %4 )" ).
260 arg( theCalcCaseName ).arg( anObj1 ).arg( aPriority ).arg( anObj2 ).arg( aMergeType );
266 bool HYDROData_PriorityQueue::GetRule( const TDF_Label& theRulesLab,
268 Handle(HYDROData_Object)& theObject1,
269 HYDROData_PriorityType& thePriority,
270 Handle(HYDROData_Object)& theObject2,
271 HYDROData_Zone::MergeAltitudesType& theMergeType )
273 TDF_Label aRuleLabel = theRulesLab.FindChild( theIndex );
275 Handle(TDataStd_ReferenceList) aRefs1, aRefs2;
276 Handle(TDataStd_Integer) aPriorityAttr, aMergeAttr;
278 bool isObj1OK = aRuleLabel.FindChild ( Object1_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs1 );
279 bool isPriorityOK = aRuleLabel.FindChild( Priority_Tag ).FindAttribute( TDataStd_Integer::GetID(), aPriorityAttr );
280 bool isObj2OK = aRuleLabel.FindChild ( Object2_Tag ). FindAttribute( TDataStd_ReferenceList::GetID(), aRefs2 );
281 bool isMergeOK = aRuleLabel.FindChild ( Merge_Tag ). FindAttribute( TDataStd_Integer::GetID(), aMergeAttr );
283 bool isOK = isObj1OK && isPriorityOK && isObj2OK && isMergeOK;
286 theObject1 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs1->First() ) );
287 thePriority = ( HYDROData_PriorityType ) aPriorityAttr->Get();
288 theObject2 = Handle_HYDROData_Object::DownCast( HYDROData_Iterator::Object( aRefs2->First() ) );
289 theMergeType = ( HYDROData_Zone::MergeAltitudesType ) aMergeAttr->Get();