1 // Created by: DAUTRY Philippe
2 // Copyright (c) 1997-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
19 //Version Date Purpose
20 // 0.0 Mar 13 1997 Creation
24 #include <TDF_Tool.ixx>
26 #include <TDF_MapIteratorOfLabelMap.hxx>
27 #include <TDF_MapIteratorOfAttributeMap.hxx>
28 #include <TDF_AttributeIterator.hxx>
29 #include <TDF_AttributeIndexedMap.hxx>
30 #include <TDF_ChildIterator.hxx>
31 #include <TDF_DataSet.hxx>
32 #include <TDF_ListIteratorOfLabelList.hxx>
34 #include <TColStd_ListOfInteger.hxx>
35 #include <TColStd_ListIteratorOfListOfInteger.hxx>
37 #define TDF_TagSeparator ':'
39 static void TDF_Tool_ExtendedDeepDump(Standard_OStream& anOS,
40 const TDF_Label& aLabel,
41 const TDF_IDFilter& aFilter,
42 TDF_AttributeIndexedMap& aMap);
44 static Standard_Boolean TDF_Tool_DescendantRef(const TDF_Label& aRefLabel,
45 const TDF_Label& aLabel,
46 const TDF_IDFilter& aFilter,
47 const Handle(TDF_DataSet)& ds);
49 static void TDF_Tool_OutReferers(const TDF_Label& aRefLabel,
50 const TDF_Label& aLabel,
51 TDF_AttributeMap& atts,
52 const TDF_IDFilter& aFilterForReferers,
53 const TDF_IDFilter& aFilterForReferences,
54 const Handle(TDF_DataSet)& ds);
56 static void TDF_Tool_OutReferences(const TDF_Label& aRefLabel,
57 const TDF_Label& aLabel,
58 TDF_AttributeMap& atts,
59 const TDF_IDFilter& aFilterForReferers,
60 const TDF_IDFilter& aFilterForReferences,
61 const Handle(TDF_DataSet)& ds);
63 //=======================================================================
65 //purpose : Returns the numbers of labels of the tree.
66 //=======================================================================
68 Standard_Integer TDF_Tool::NbLabels(const TDF_Label& aLabel)
70 Standard_Integer n = 1;
71 for (TDF_ChildIterator itr(aLabel,Standard_True); itr.More(); itr.Next())
77 //=======================================================================
78 //function : NbAttributes
79 //purpose : Returns the number of attributes of the tree.
80 //=======================================================================
82 Standard_Integer TDF_Tool::NbAttributes(const TDF_Label& aLabel)
84 Standard_Integer n = aLabel.NbAttributes();
85 for (TDF_ChildIterator itr(aLabel,Standard_True); itr.More(); itr.Next())
86 n += itr.Value().NbAttributes();
91 //=======================================================================
92 //function : NbAttributes
93 //purpose : Returns the number of attributes of the tree,
94 // selected by an IDFilter.
95 //=======================================================================
97 Standard_Integer TDF_Tool::NbAttributes
98 (const TDF_Label& aLabel,
99 const TDF_IDFilter& aFilter)
101 Standard_Integer n = 0;
102 TDF_AttributeIterator it2;
103 for (it2.Initialize(aLabel,Standard_True);it2.More();it2.Next())
104 if (aFilter.IsKept(it2.Value())) ++n;
105 for (TDF_ChildIterator it1(aLabel,Standard_True); it1.More(); it1.Next())
106 for (it2.Initialize(it1.Value(),Standard_True);it2.More();it2.Next())
107 if (aFilter.IsKept(it2.Value())) ++n;
112 //=======================================================================
113 //function : IsSelfContained
115 //=======================================================================
117 Standard_Boolean TDF_Tool::IsSelfContained(const TDF_Label& aLabel)
119 TDF_IDFilter filter(Standard_False); // Keep all.
120 return IsSelfContained(aLabel,filter);
123 //=======================================================================
124 //function : IsSelfContained
126 //=======================================================================
128 Standard_Boolean TDF_Tool::IsSelfContained
129 (const TDF_Label& aLabel,
130 const TDF_IDFilter& aFilter)
132 Handle(TDF_DataSet) ds = new TDF_DataSet();
134 if (!TDF_Tool_DescendantRef(aLabel,aLabel,aFilter,ds))
135 return Standard_False;
137 for (TDF_ChildIterator itr(aLabel,Standard_True);
140 if (!TDF_Tool_DescendantRef(aLabel,itr.Value(),aFilter,ds))
141 return Standard_False;
143 return Standard_True;
147 //=======================================================================
148 //function : TDF_Tool_DescendantRef
150 //=======================================================================
152 static Standard_Boolean TDF_Tool_DescendantRef
153 (const TDF_Label& aRefLabel,
154 const TDF_Label& aLabel,
155 const TDF_IDFilter& aFilter,
156 const Handle(TDF_DataSet)& ds)
158 for (TDF_AttributeIterator itr(aLabel); itr.More(); itr.Next()) {
160 // const Handle(TDF_Attribute)& labAtt = itr.Value();
161 Handle(TDF_Attribute) labAtt = itr.Value();
163 if (aFilter.IsKept(labAtt)) {
164 labAtt->References(ds);
165 // First of all, the referenced labels.
166 const TDF_LabelMap& labMap = ds->Labels();
168 for (TDF_MapIteratorOfLabelMap labMItr(labMap);
169 labMItr.More(); labMItr.Next()) {
170 if (!labMItr.Key().IsDescendant(aRefLabel))
171 return Standard_False;
173 // Then the referenced attributes.
174 const TDF_AttributeMap& attMap = ds->Attributes();
175 for (TDF_MapIteratorOfAttributeMap attMItr(attMap);
176 attMItr.More(); attMItr.Next()) {
178 // const Handle(TDF_Attribute)& att = attMItr.Key();
179 Handle(TDF_Attribute) att = attMItr.Key();
180 if (!att.IsNull() && !att->Label().IsNull())
183 if (aFilter.IsKept(att) && !att->Label().IsDescendant(aRefLabel))
184 return Standard_False;
190 return Standard_True;
194 //=======================================================================
195 //function : OutReferers
197 //=======================================================================
199 void TDF_Tool::OutReferers(const TDF_Label& aLabel,
200 TDF_AttributeMap& atts)
202 TDF_IDFilter filter(Standard_False); // Keep all.
203 OutReferers(aLabel,filter,filter,atts);
207 //=======================================================================
208 //function : OutReferers
210 //=======================================================================
212 void TDF_Tool::OutReferers(const TDF_Label& aLabel,
213 const TDF_IDFilter& aFilterForReferers,
214 const TDF_IDFilter& aFilterForReferences,
215 TDF_AttributeMap& atts)
217 Handle(TDF_DataSet) ds = new TDF_DataSet();
218 TDF_Tool_OutReferers(aLabel,aLabel,atts,aFilterForReferers,aFilterForReferences,ds);
219 for (TDF_ChildIterator itr(aLabel,Standard_True);itr.More();itr.Next()) {
220 TDF_Tool_OutReferers(aLabel,itr.Value(),atts,aFilterForReferers,aFilterForReferences,ds);
225 //=======================================================================
226 //function : TDF_Tool_OutReferers
228 //=======================================================================
230 static void TDF_Tool_OutReferers(const TDF_Label& aRefLabel,
231 const TDF_Label& aLabel,
232 TDF_AttributeMap& atts,
233 const TDF_IDFilter& aFilterForReferers,
234 const TDF_IDFilter& aFilterForReferences,
235 const Handle(TDF_DataSet)& ds)
237 Standard_Boolean outRefFound = Standard_False;
239 for (TDF_AttributeIterator itr(aLabel); itr.More(); itr.Next()) {
241 if (!aFilterForReferers.IsKept(itr.Value())) continue;
242 itr.Value()->References(ds);
244 const TDF_AttributeMap& attMap = ds->Attributes();
245 for (TDF_MapIteratorOfAttributeMap attMItr(attMap);
246 attMItr.More(); attMItr.Next()) {
248 // const Handle(TDF_Attribute)& att = attMItr.Key();
249 Handle(TDF_Attribute) att = attMItr.Key();
251 if (aFilterForReferences.IsKept(att) && !att->Label().IsDescendant(aRefLabel)) {
252 atts.Add(itr.Value());
253 outRefFound = Standard_True;
259 const TDF_LabelMap& labMap = ds->Labels();
260 for (TDF_MapIteratorOfLabelMap labMItr(labMap);
261 labMItr.More(); labMItr.Next()) {
262 if (!labMItr.Key().IsDescendant(aRefLabel)) {
263 atts.Add(itr.Value());
269 outRefFound = Standard_False;
274 //=======================================================================
275 //function : OutReferences
277 //=======================================================================
279 void TDF_Tool::OutReferences(const TDF_Label& aLabel,
280 TDF_AttributeMap& atts)
282 TDF_IDFilter filter(Standard_False); // Keep all.
283 OutReferences(aLabel,filter,filter,atts);
286 //=======================================================================
287 //function : OutReferences
289 //=======================================================================
291 void TDF_Tool::OutReferences(const TDF_Label& aLabel,
292 const TDF_IDFilter& aFilterForReferers,
293 const TDF_IDFilter& aFilterForReferences,
294 TDF_AttributeMap& atts)
296 Handle(TDF_DataSet) ds = new TDF_DataSet();
297 TDF_Tool_OutReferences(aLabel,aLabel,atts,aFilterForReferers,aFilterForReferences,ds);
298 for (TDF_ChildIterator itr(aLabel,Standard_True);itr.More();itr.Next()) {
299 TDF_Tool_OutReferences(aLabel,itr.Value(),atts,aFilterForReferers,aFilterForReferences,ds);
303 //=======================================================================
304 //function : TDF_Tool_OutReferences
306 //=======================================================================
308 static void TDF_Tool_OutReferences(const TDF_Label& aRefLabel,
309 const TDF_Label& aLabel,
310 TDF_AttributeMap& atts,
311 const TDF_IDFilter& aFilterForReferers,
312 const TDF_IDFilter& aFilterForReferences,
313 const Handle(TDF_DataSet)& ds)
315 for (TDF_AttributeIterator itr(aLabel); itr.More(); itr.Next()) {
316 if (!aFilterForReferers.IsKept(itr.Value())) continue;
317 itr.Value()->References(ds);
318 const TDF_AttributeMap& attMap = ds->Attributes();
319 for (TDF_MapIteratorOfAttributeMap attMItr(attMap);attMItr.More();attMItr.Next()) {
320 Handle(TDF_Attribute) att = attMItr.Key();
321 if (aFilterForReferences.IsKept(att) && !att->Label().IsDescendant(aRefLabel)) {
325 const TDF_LabelMap& labMap = ds->Labels();
326 for (TDF_MapIteratorOfLabelMap labMItr(labMap);labMItr.More();labMItr.Next()) {
327 if (!labMItr.Key().IsDescendant(aRefLabel)) {
328 TDF_AttributeIterator itra(labMItr.Key());
329 for (; itra.More(); itra.Next()) {
330 if (aFilterForReferences.IsKept(itra.Value())) {
331 atts.Add(itra.Value());
340 //=======================================================================
341 //function : RelocateLabel
343 //=======================================================================
345 void TDF_Tool::RelocateLabel
346 (const TDF_Label& aSourceLabel,
347 const TDF_Label& fromRoot,
348 const TDF_Label& toRoot,
349 TDF_Label& aTargetLabel,
350 const Standard_Boolean create)
352 if (!aSourceLabel.IsDescendant(fromRoot)) return;
353 aTargetLabel.Nullify();
354 TColStd_ListOfInteger labelTags;
355 TDF_Tool::TagList(aSourceLabel,labelTags);
356 TColStd_ListOfInteger toTags;
357 TDF_Tool::TagList(toRoot,toTags);
358 for (Standard_Integer i = fromRoot.Depth(); i >= 0; --i)
359 labelTags.RemoveFirst();
360 labelTags.Prepend(toTags);
361 TDF_Tool::Label(toRoot.Data(),labelTags,aTargetLabel,create);
365 //=======================================================================
367 //purpose : Returns the entry as an ascii string.
368 //=======================================================================
371 (const TDF_Label& aLabel,
372 TCollection_AsciiString& anEntry)
375 if (!aLabel.IsNull()) {
376 TColStd_ListOfInteger Tags;
377 TDF_Tool::TagList(aLabel, Tags);
378 anEntry += TCollection_AsciiString(Tags.First());
380 if (Tags.IsEmpty()) {
381 anEntry += TDF_TagSeparator; // It must be the root label case.
384 while (!Tags.IsEmpty()) {
385 anEntry += TDF_TagSeparator;
386 anEntry += TCollection_AsciiString(Tags.First());
394 //=======================================================================
396 //purpose : Returns the entry of a label as a list of integers.
397 //=======================================================================
399 void TDF_Tool::TagList
400 (const TDF_Label& aLabel,
401 TColStd_ListOfInteger& aTagList)
404 if (!aLabel.IsNull()) {
405 TDF_Label Label = aLabel;
407 aTagList.Prepend(Label.Tag());
408 if (Label.IsRoot()) break;
409 Label = Label.Father();
415 //=======================================================================
417 //purpose : Returns the entry expressed as a string as a list of integers.
418 //=======================================================================
420 void TDF_Tool::TagList
421 (const TCollection_AsciiString& anEntry,
422 TColStd_ListOfInteger& aTagList)
424 char* cc = (char *)anEntry.ToCString();
425 Standard_Integer n = 0;
427 while (*cc != '\0') {
428 while ( *cc >= '0' && *cc <= '9') {
429 n = 10*n + (*cc - '0');
432 if (*cc == TDF_TagSeparator || *cc == '\0') {
435 if (*cc != '\0') ++cc;
437 else { // Not an entry!
445 //=======================================================================
447 //purpose : Returns the label expressed by <anEntry>.
448 //=======================================================================
451 (const Handle(TDF_Data)& aDF,
452 const TCollection_AsciiString& anEntry,
454 const Standard_Boolean create)
455 { TDF_Tool::Label(aDF,anEntry.ToCString(),aLabel,create); }
458 //=======================================================================
460 //purpose : Returns the label expressed by <anEntry>,
461 // and creates it if <create> is true.
462 //=======================================================================
465 (const Handle(TDF_Data)& aDF,
466 const Standard_CString anEntry,
468 const Standard_Boolean create)
470 TColStd_ListOfInteger tagList;
471 TDF_Tool::TagList(anEntry,tagList);
472 TDF_Tool::Label(aDF,tagList,aLabel,create);
476 //=======================================================================
478 //purpose : Returns the label expressed by <anEntry>,
479 // and creates it if <create> is true.
480 //=======================================================================
483 (const Handle(TDF_Data)& aDF,
484 const TColStd_ListOfInteger& aTagList,
486 const Standard_Boolean create)
488 if (aTagList.Extent() == 0) {
492 aLabel = aDF->Root();
493 if (aTagList.Extent() == 1 && aTagList.First() == 0) return;
495 TColStd_ListIteratorOfListOfInteger tagItr (aTagList);
496 tagItr.Next(); // Suppresses root tag.
497 for (; !aLabel.IsNull() && tagItr.More(); tagItr.Next()) {
498 aLabel = aLabel.FindChild(tagItr.Value(),create);
505 //=======================================================================
506 //function : CountLabels
508 //=======================================================================
510 void TDF_Tool::CountLabels
511 (TDF_LabelList& aLabelList,
512 TDF_LabelIntegerMap& aLabelMap)
514 if (aLabelList.IsEmpty()) return;
515 Standard_Boolean next = Standard_True;
516 TDF_ListIteratorOfLabelList itr(aLabelList);
518 const TDF_Label& lab = itr.Value();
519 if (aLabelMap.IsBound(lab)) {
521 aLabelList.Remove(itr);
522 next = Standard_False;
525 aLabelMap.Bind(lab,1);
528 if (next && !aLabelList.IsEmpty()) itr.Next();
533 //=======================================================================
534 //function : DeductLabels
536 //=======================================================================
538 void TDF_Tool::DeductLabels
539 (TDF_LabelList& aLabelList,
540 TDF_LabelIntegerMap& aLabelMap)
542 if (aLabelList.IsEmpty()) return;
543 Standard_Boolean next = Standard_True;
544 TDF_ListIteratorOfLabelList itr(aLabelList);
546 const TDF_Label& lab = itr.Value();
547 if (aLabelMap.IsBound(lab)) {
549 if (aLabelMap(lab) == 0) {
550 aLabelMap.UnBind(lab);
551 aLabelList.Remove(itr);
552 next = Standard_False;
555 else next = itr.More();
556 if (next && !aLabelList.IsEmpty()) itr.Next();
561 //=======================================================================
562 //function : DeepDump
563 //purpose : Deep dump of a DF.
564 //=======================================================================
566 void TDF_Tool::DeepDump
567 (Standard_OStream& anOS,
568 const Handle(TDF_Data)& aDF)
571 TDF_Tool::DeepDump(anOS,aDF->Root());
575 //=======================================================================
576 //function : ExtendedDeepDump
577 //purpose : Extended deep dump of a DF.
578 //=======================================================================
580 void TDF_Tool::ExtendedDeepDump
581 (Standard_OStream& anOS,
582 const Handle(TDF_Data)& aDF,
583 const TDF_IDFilter& aFilter)
586 TDF_Tool::ExtendedDeepDump(anOS,aDF->Root(),aFilter);
590 //=======================================================================
591 //function : DeepDump
592 //purpose : Deep dump of a label.
593 //=======================================================================
595 void TDF_Tool::DeepDump
596 (Standard_OStream& anOS,
597 const TDF_Label& aLabel)
602 for (TDF_ChildIterator ChildIt(aLabel); ChildIt.More (); ChildIt.Next ()) {
603 TDF_Tool::DeepDump(anOS,ChildIt.Value());
608 //=======================================================================
609 //function : ExtendedDeepDump
610 //purpose : Extended deep dump of a label.
611 //=======================================================================
613 void TDF_Tool::ExtendedDeepDump
614 (Standard_OStream& anOS,
615 const TDF_Label& aLabel,
616 const TDF_IDFilter& aFilter)
618 TDF_AttributeIndexedMap map;
619 TDF_Tool_ExtendedDeepDump(anOS,aLabel,aFilter,map);
621 anOS<<map.Extent()<<" attribute"; if (map.Extent()>1) anOS<<"s";
622 anOS<<" referenced by the label structure."<<endl;
624 anOS<<endl<<"Extended dump of filtered attribute(s):"<<endl;
625 Standard_Integer nba = 0;
626 TCollection_AsciiString entry;
628 for ( i = 1; i<= map.Extent(); ++i) {
629 const Handle(TDF_Attribute)& att = map.FindKey(i);
630 if (aFilter.IsKept(att)) {
633 if (att->Label().IsNull()) {
634 anOS<<" (no label)"<<endl;
637 TDF_Tool::Entry(att->Label(),entry);
638 anOS<<" (label: "<<entry<<")"<<endl;
640 att->ExtendedDump(anOS,aFilter,map); anOS<<endl;
643 anOS<<endl<<nba<<" attribute";
644 if (nba>1) anOS<<"s";
645 anOS<<" dumped between "<<--i<<endl;
649 //=======================================================================
650 //function : ExtendedDeepDump
651 //purpose : Internal method.
652 //=======================================================================
654 static void TDF_Tool_ExtendedDeepDump
655 (Standard_OStream& anOS,
656 const TDF_Label& aLabel,
657 const TDF_IDFilter& aFilter,
658 TDF_AttributeIndexedMap& aMap)
661 aLabel.ExtendedDump(anOS,aFilter,aMap);
663 for (TDF_ChildIterator ChildIt(aLabel); ChildIt.More (); ChildIt.Next ()) {
664 TDF_Tool_ExtendedDeepDump(anOS,ChildIt.Value(),aFilter,aMap);