0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TFunction / TFunction_Iterator.cxx
CommitLineData
b311480e 1// Created on: 2008-06-23
2// Created by: Vladislav ROMASHKO
973c2be1 3// Copyright (c) 2008-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
7fd59977 16
42cf5bc1 17#include <TColStd_MapIteratorOfMapOfInteger.hxx>
18#include <TDataStd_Name.hxx>
19#include <TDF_DataMapIteratorOfLabelIntegerMap.hxx>
20#include <TDF_Label.hxx>
21#include <TDF_LabelIntegerMap.hxx>
7fd59977 22#include <TDF_LabelMap.hxx>
7fd59977 23#include <TDF_ListIteratorOfLabelList.hxx>
42cf5bc1 24#include <TDF_MapIteratorOfLabelMap.hxx>
25#include <TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel.hxx>
26#include <TFunction_GraphNode.hxx>
27#include <TFunction_IFunction.hxx>
28#include <TFunction_Iterator.hxx>
29#include <TFunction_Scope.hxx>
7fd59977 30
31//=======================================================================
32//function : Create
33//purpose : Constructor
34//=======================================================================
7fd59977 35TFunction_Iterator::TFunction_Iterator():myUsageOfExecutionStatus(Standard_False)
36{
37
38}
39
40//=======================================================================
41//function : Create
42//purpose : Constructor
43//=======================================================================
44
45TFunction_Iterator::TFunction_Iterator(const TDF_Label& Access):myUsageOfExecutionStatus(Standard_False)
46{
47 Init(Access);
48}
49
50//=======================================================================
51//function : Init
52//purpose : Initializes the Iterator.
53//=======================================================================
54
55void TFunction_Iterator::Init(const TDF_Label& Access)
56{
57 myCurrent.Clear();
58 myPassedFunctions.Clear();
59
60 // Get the scope of functions
61 myScope = TFunction_Scope::Set(Access);
62
63 // Find the roots
64 TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(myScope->GetFunctions());
65 for (; itrm.More(); itrm.Next())
66 {
67 const TDF_Label& L = itrm.Key2();
68
69 TFunction_IFunction iFunction(L);
70 Handle(TFunction_GraphNode) graphNode = iFunction.GetGraphNode();
71 TFunction_ExecutionStatus status = graphNode->GetStatus();
72
73 // Check whether the function is a root function
74 if (!graphNode->GetPrevious().IsEmpty())
75 continue;
76
77 // In execution mode we consider only "not executed" functions.
78 if (myUsageOfExecutionStatus && status != TFunction_ES_NotExecuted)
79 continue;
80
81 myCurrent.Append(L);
82
83 // Register already passed functions
84 if (!myUsageOfExecutionStatus)
85 myPassedFunctions.Add(L);
86 }
87}
88
89//=======================================================================
90//function : SetUsageOfExecutionStatus
91//purpose : Defines usage of execution status
92//=======================================================================
93
94void TFunction_Iterator::SetUsageOfExecutionStatus(const Standard_Boolean usage)
95{
96 myUsageOfExecutionStatus = usage;
97}
98
99//=======================================================================
100//function : GetUsageOfExecutionStatus
101//purpose : Returns usage of execution status
102//=======================================================================
103
104Standard_Boolean TFunction_Iterator::GetUsageOfExecutionStatus() const
105{
106 return myUsageOfExecutionStatus;
107}
108
109//=======================================================================
110//function : GetMaxNbThreads
111//purpose : Defines the maximum number of threads
112//=======================================================================
113
114Standard_Integer TFunction_Iterator::GetMaxNbThreads() const
115{
116 int nb_threads = 0;
117 TFunction_Iterator fIterator;
118 fIterator.myUsageOfExecutionStatus = Standard_False;
119
120 // Start iteration from current functions
121 TDF_ListIteratorOfLabelList itrl(myCurrent);
122 for (; itrl.More(); itrl.Next())
123 {
124 fIterator.myCurrent.Append(itrl.Value());
125 }
126
127 // Check number of semultenious current functions
128 while (!fIterator.Current().IsEmpty())
129 {
130 const TDF_LabelList& current = fIterator.Current();
131 if (nb_threads < current.Extent())
132 nb_threads = current.Extent();
133 fIterator.Next();
134 }
135
136 return nb_threads;
137}
138
139//=======================================================================
140//function : Current
141//purpose : Returns the current list of functions
142//=======================================================================
143
144const TDF_LabelList& TFunction_Iterator::Current() const
145{
146 return myCurrent;
147}
148
149//=======================================================================
150//function : More
151//purpose : Returns true if the iteration is ended
152//=======================================================================
153
154Standard_Boolean TFunction_Iterator::More() const
155{
156 if (myUsageOfExecutionStatus)
157 {
158 TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(myScope->GetFunctions());
159 for (; itrm.More(); itrm.Next())
160 {
161 const TDF_Label& L = itrm.Key2();
162 if (GetStatus(L) == TFunction_ES_NotExecuted)
163 return Standard_True;
164 }
165 return Standard_False;
166 }
965681c5 167 return !myCurrent.IsEmpty();
7fd59977 168}
169
170//=======================================================================
171//function : Next
172//purpose : Switches the iterator to the next functions
173//=======================================================================
174
175void TFunction_Iterator::Next()
176{
177 TDF_LabelMap next_current;
178 TDF_ListIteratorOfLabelList itrl(myCurrent);
179 for (; itrl.More(); itrl.Next())
180 {
181 const TDF_Label& L = itrl.Value();
182 TFunction_IFunction iFunction(L);
183
184 Handle(TFunction_GraphNode) graphNode = iFunction.GetGraphNode();
7fd59977 185 const TColStd_MapOfInteger& next = graphNode->GetNext();
186 TFunction_ExecutionStatus status = graphNode->GetStatus();
187
188 // Consider the execution status
189 if (myUsageOfExecutionStatus)
190 {
191 if (status == TFunction_ES_NotExecuted || status == TFunction_ES_Executing)
192 {
193 next_current.Add(L);
194 continue;
195 }
196 else if (status == TFunction_ES_WrongDefinition || status == TFunction_ES_Failed)
197 {
198 continue;
199 }
200
201 // if "succeeded", we consider the next functions... see below.
202 }
203
204 // Add next functions
205 TColStd_MapIteratorOfMapOfInteger itrm(next);
206 for (; itrm.More(); itrm.Next())
207 {
208 const Standard_Integer IDnext = itrm.Key();
209 const TDF_Label& Lnext = myScope->GetFunctions().Find1(IDnext);
210
211 if (myUsageOfExecutionStatus)
212 {
213 // A previous function is "succeeded", check status of next functions and
214 // all other previous functions of the next functions.
215
216 // Check status, it should be "not executed"
217 TFunction_IFunction iNextFunction(Lnext);
218 Handle(TFunction_GraphNode) nextGraphNode = iNextFunction.GetGraphNode();
219 TFunction_ExecutionStatus next_status = nextGraphNode->GetStatus();
220 if (next_status != TFunction_ES_NotExecuted && next_status != TFunction_ES_Executing)
221 {
222 continue;
223 }
224
225 // Check all previous functions: all of them should be "succeeded"
226 Standard_Boolean is_prev_succeeded = Standard_True;
227 const TColStd_MapOfInteger& prevOfNext = nextGraphNode->GetPrevious();
228 TColStd_MapIteratorOfMapOfInteger itrp(prevOfNext);
229 for (; itrp.More(); itrp.Next())
230 {
231 const Standard_Integer IDprevOfNext = itrp.Key();
232 const TDF_Label& LprevOfNext = myScope->GetFunctions().Find1(IDprevOfNext);
233 Handle(TFunction_GraphNode) GprevOfNext;
234 LprevOfNext.FindAttribute(TFunction_GraphNode::GetID(), GprevOfNext);
235 TFunction_ExecutionStatus prev_status = GprevOfNext->GetStatus();
236 if (prev_status != TFunction_ES_Succeeded)
237 {
238 is_prev_succeeded = Standard_False;
239 break;
240 }
241 }
242 if (!is_prev_succeeded)
243 {
244 continue;
245 }
246 }
247
248 // Ignore already passed fucntions (for the mode of ignoring the execution status).
249 if (!myUsageOfExecutionStatus && myPassedFunctions.Contains(Lnext))
250 continue;
251
252 next_current.Add(Lnext);
253
254 // Register already passed functions
255 if (!myUsageOfExecutionStatus)
256 myPassedFunctions.Add(Lnext);
257 }
258 }
259
260 myCurrent.Clear();
261 TDF_MapIteratorOfLabelMap itrm(next_current);
262 for (; itrm.More(); itrm.Next())
263 {
264 myCurrent.Append(itrm.Key());
265 }
266}
267
268//=======================================================================
269//function : GetStatus
270//purpose : Returns the execution status of the function
271//=======================================================================
272
273TFunction_ExecutionStatus TFunction_Iterator::GetStatus(const TDF_Label& func) const
274{
275 TFunction_IFunction iFunction(func);
276 return iFunction.GetGraphNode()->GetStatus();
277}
278
279//=======================================================================
280//function : SetStatus
281//purpose : Defines an execution status for a function
282//=======================================================================
283
284void TFunction_Iterator::SetStatus(const TDF_Label& func,
285 const TFunction_ExecutionStatus status) const
286{
287 TFunction_IFunction iFunction(func);
288 iFunction.GetGraphNode()->SetStatus(status);
289}
290
291//=======================================================================
292//function : Dump
293//purpose :
294//=======================================================================
295Standard_OStream& TFunction_Iterator::Dump (Standard_OStream& anOS) const
296{
297 anOS << "Functions:" << endl ;
298
299 if (myCurrent.IsEmpty())
300 return anOS;
301
302 // Memorize the status of each function
303 // in order to recover it after iteration.
304 TDF_LabelIntegerMap saved_status;
305 Handle(TFunction_Scope) scope = TFunction_Scope::Set(myCurrent.First());
306 TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrd(scope->GetFunctions());
307 for (; itrd.More(); itrd.Next())
308 {
309 const TDF_Label& L = itrd.Key2();
310 Handle(TFunction_GraphNode) G;
311 if (L.FindAttribute(TFunction_GraphNode::GetID(), G))
312 {
313 saved_status.Bind(L, (Standard_Integer) G->GetStatus());
314 G->SetStatus(TFunction_ES_NotExecuted);
315 }
316 }
317
318 TFunction_Iterator fIterator(myCurrent.First());
319 fIterator.myUsageOfExecutionStatus = Standard_True;
320
321 while (fIterator.More())
322 {
323 const TDF_LabelList& current = fIterator.Current();
324
325 TDF_ListIteratorOfLabelList itrl(current);
326 for (; itrl.More(); itrl.Next())
327 {
328
329 const TDF_Label& L = itrl.Value();
330
331 Handle(TDataStd_Name) N;
332 if (L.FindAttribute(TDataStd_Name::GetID(), N))
333 {
334 anOS << TCollection_AsciiString(N->Get()).ToCString() ;
335 }
336
337 Handle(TFunction_GraphNode) G;
338 if (L.FindAttribute(TFunction_GraphNode::GetID(), G))
339 {
340 G->SetStatus(TFunction_ES_Succeeded);
341 }
342
343 anOS << "\t" ;
344 }
345
346 fIterator.Next();
347
348 anOS << endl;
349 }
350
351 // Recover the status of functions
352 TDF_DataMapIteratorOfLabelIntegerMap itrm(saved_status);
353 for (; itrm.More(); itrm.Next())
354 {
355 const TDF_Label& L = itrm.Key();
356 TFunction_ExecutionStatus status = (TFunction_ExecutionStatus) itrm.Value();
357
358 Handle(TFunction_GraphNode) G;
359 if (L.FindAttribute(TFunction_GraphNode::GetID(), G))
360 {
361 G->SetStatus(status);
362 }
363 }
364
365 return anOS;
366}