1 // Created by: DAUTRY Philippe
2 // Copyright (c) 1997-1999 Matra Datavision
3 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
23 //Version Date Purpose
24 // 0.0 Mar 13 1997 Creation
28 #include <TDF_Tool.ixx>
30 #include <TDF_MapIteratorOfLabelMap.hxx>
31 #include <TDF_MapIteratorOfAttributeMap.hxx>
32 #include <TDF_AttributeIterator.hxx>
33 #include <TDF_AttributeIndexedMap.hxx>
34 #include <TDF_ChildIterator.hxx>
35 #include <TDF_DataSet.hxx>
36 #include <TDF_ListIteratorOfLabelList.hxx>
38 #include <TColStd_ListOfInteger.hxx>
39 #include <TColStd_ListIteratorOfListOfInteger.hxx>
41 #define TDF_TagSeparator ':'
43 static void TDF_Tool_ExtendedDeepDump(Standard_OStream& anOS,
44 const TDF_Label& aLabel,
45 const TDF_IDFilter& aFilter,
46 TDF_AttributeIndexedMap& aMap);
48 static Standard_Boolean TDF_Tool_DescendantRef(const TDF_Label& aRefLabel,
49 const TDF_Label& aLabel,
50 const TDF_IDFilter& aFilter,
51 const Handle(TDF_DataSet)& ds);
53 static void TDF_Tool_OutReferers(const TDF_Label& aRefLabel,
54 const TDF_Label& aLabel,
55 TDF_AttributeMap& atts,
56 const TDF_IDFilter& aFilterForReferers,
57 const TDF_IDFilter& aFilterForReferences,
58 const Handle(TDF_DataSet)& ds);
60 static void TDF_Tool_OutReferences(const TDF_Label& aRefLabel,
61 const TDF_Label& aLabel,
62 TDF_AttributeMap& atts,
63 const TDF_IDFilter& aFilterForReferers,
64 const TDF_IDFilter& aFilterForReferences,
65 const Handle(TDF_DataSet)& ds);
67 //=======================================================================
69 //purpose : Returns the numbers of labels of the tree.
70 //=======================================================================
72 Standard_Integer TDF_Tool::NbLabels(const TDF_Label& aLabel)
74 Standard_Integer n = 1;
75 for (TDF_ChildIterator itr(aLabel,Standard_True); itr.More(); itr.Next())
81 //=======================================================================
82 //function : NbAttributes
83 //purpose : Returns the number of attributes of the tree.
84 //=======================================================================
86 Standard_Integer TDF_Tool::NbAttributes(const TDF_Label& aLabel)
88 Standard_Integer n = aLabel.NbAttributes();
89 for (TDF_ChildIterator itr(aLabel,Standard_True); itr.More(); itr.Next())
90 n += itr.Value().NbAttributes();
95 //=======================================================================
96 //function : NbAttributes
97 //purpose : Returns the number of attributes of the tree,
98 // selected by an IDFilter.
99 //=======================================================================
101 Standard_Integer TDF_Tool::NbAttributes
102 (const TDF_Label& aLabel,
103 const TDF_IDFilter& aFilter)
105 Standard_Integer n = 0;
106 TDF_AttributeIterator it2;
107 for (it2.Initialize(aLabel,Standard_True);it2.More();it2.Next())
108 if (aFilter.IsKept(it2.Value())) ++n;
109 for (TDF_ChildIterator it1(aLabel,Standard_True); it1.More(); it1.Next())
110 for (it2.Initialize(it1.Value(),Standard_True);it2.More();it2.Next())
111 if (aFilter.IsKept(it2.Value())) ++n;
116 //=======================================================================
117 //function : IsSelfContained
119 //=======================================================================
121 Standard_Boolean TDF_Tool::IsSelfContained(const TDF_Label& aLabel)
123 TDF_IDFilter filter(Standard_False); // Keep all.
124 return IsSelfContained(aLabel,filter);
127 //=======================================================================
128 //function : IsSelfContained
130 //=======================================================================
132 Standard_Boolean TDF_Tool::IsSelfContained
133 (const TDF_Label& aLabel,
134 const TDF_IDFilter& aFilter)
136 Handle(TDF_DataSet) ds = new TDF_DataSet();
138 if (!TDF_Tool_DescendantRef(aLabel,aLabel,aFilter,ds))
139 return Standard_False;
141 for (TDF_ChildIterator itr(aLabel,Standard_True);
144 if (!TDF_Tool_DescendantRef(aLabel,itr.Value(),aFilter,ds))
145 return Standard_False;
147 return Standard_True;
151 //=======================================================================
152 //function : TDF_Tool_DescendantRef
154 //=======================================================================
156 static Standard_Boolean TDF_Tool_DescendantRef
157 (const TDF_Label& aRefLabel,
158 const TDF_Label& aLabel,
159 const TDF_IDFilter& aFilter,
160 const Handle(TDF_DataSet)& ds)
162 for (TDF_AttributeIterator itr(aLabel); itr.More(); itr.Next()) {
164 // const Handle(TDF_Attribute)& labAtt = itr.Value();
165 Handle(TDF_Attribute) labAtt = itr.Value();
167 if (aFilter.IsKept(labAtt)) {
168 labAtt->References(ds);
169 // First of all, the referenced labels.
170 const TDF_LabelMap& labMap = ds->Labels();
172 for (TDF_MapIteratorOfLabelMap labMItr(labMap);
173 labMItr.More(); labMItr.Next()) {
174 if (!labMItr.Key().IsDescendant(aRefLabel))
175 return Standard_False;
177 // Then the referenced attributes.
178 const TDF_AttributeMap& attMap = ds->Attributes();
179 for (TDF_MapIteratorOfAttributeMap attMItr(attMap);
180 attMItr.More(); attMItr.Next()) {
182 // const Handle(TDF_Attribute)& att = attMItr.Key();
183 Handle(TDF_Attribute) att = attMItr.Key();
184 if (!att.IsNull() && !att->Label().IsNull())
187 if (aFilter.IsKept(att) && !att->Label().IsDescendant(aRefLabel))
188 return Standard_False;
194 return Standard_True;
198 //=======================================================================
199 //function : OutReferers
201 //=======================================================================
203 void TDF_Tool::OutReferers(const TDF_Label& aLabel,
204 TDF_AttributeMap& atts)
206 TDF_IDFilter filter(Standard_False); // Keep all.
207 OutReferers(aLabel,filter,filter,atts);
211 //=======================================================================
212 //function : OutReferers
214 //=======================================================================
216 void TDF_Tool::OutReferers(const TDF_Label& aLabel,
217 const TDF_IDFilter& aFilterForReferers,
218 const TDF_IDFilter& aFilterForReferences,
219 TDF_AttributeMap& atts)
221 Handle(TDF_DataSet) ds = new TDF_DataSet();
222 TDF_Tool_OutReferers(aLabel,aLabel,atts,aFilterForReferers,aFilterForReferences,ds);
223 for (TDF_ChildIterator itr(aLabel,Standard_True);itr.More();itr.Next()) {
224 TDF_Tool_OutReferers(aLabel,itr.Value(),atts,aFilterForReferers,aFilterForReferences,ds);
229 //=======================================================================
230 //function : TDF_Tool_OutReferers
232 //=======================================================================
234 static void TDF_Tool_OutReferers(const TDF_Label& aRefLabel,
235 const TDF_Label& aLabel,
236 TDF_AttributeMap& atts,
237 const TDF_IDFilter& aFilterForReferers,
238 const TDF_IDFilter& aFilterForReferences,
239 const Handle(TDF_DataSet)& ds)
241 Standard_Boolean outRefFound = Standard_False;
243 for (TDF_AttributeIterator itr(aLabel); itr.More(); itr.Next()) {
245 if (!aFilterForReferers.IsKept(itr.Value())) continue;
246 itr.Value()->References(ds);
248 const TDF_AttributeMap& attMap = ds->Attributes();
249 for (TDF_MapIteratorOfAttributeMap attMItr(attMap);
250 attMItr.More(); attMItr.Next()) {
252 // const Handle(TDF_Attribute)& att = attMItr.Key();
253 Handle(TDF_Attribute) att = attMItr.Key();
255 if (aFilterForReferences.IsKept(att) && !att->Label().IsDescendant(aRefLabel)) {
256 atts.Add(itr.Value());
257 outRefFound = Standard_True;
263 const TDF_LabelMap& labMap = ds->Labels();
264 for (TDF_MapIteratorOfLabelMap labMItr(labMap);
265 labMItr.More(); labMItr.Next()) {
266 if (!labMItr.Key().IsDescendant(aRefLabel)) {
267 atts.Add(itr.Value());
273 outRefFound = Standard_False;
278 //=======================================================================
279 //function : OutReferences
281 //=======================================================================
283 void TDF_Tool::OutReferences(const TDF_Label& aLabel,
284 TDF_AttributeMap& atts)
286 TDF_IDFilter filter(Standard_False); // Keep all.
287 OutReferences(aLabel,filter,filter,atts);
290 //=======================================================================
291 //function : OutReferences
293 //=======================================================================
295 void TDF_Tool::OutReferences(const TDF_Label& aLabel,
296 const TDF_IDFilter& aFilterForReferers,
297 const TDF_IDFilter& aFilterForReferences,
298 TDF_AttributeMap& atts)
300 Handle(TDF_DataSet) ds = new TDF_DataSet();
301 TDF_Tool_OutReferences(aLabel,aLabel,atts,aFilterForReferers,aFilterForReferences,ds);
302 for (TDF_ChildIterator itr(aLabel,Standard_True);itr.More();itr.Next()) {
303 TDF_Tool_OutReferences(aLabel,itr.Value(),atts,aFilterForReferers,aFilterForReferences,ds);
307 //=======================================================================
308 //function : TDF_Tool_OutReferences
310 //=======================================================================
312 static void TDF_Tool_OutReferences(const TDF_Label& aRefLabel,
313 const TDF_Label& aLabel,
314 TDF_AttributeMap& atts,
315 const TDF_IDFilter& aFilterForReferers,
316 const TDF_IDFilter& aFilterForReferences,
317 const Handle(TDF_DataSet)& ds)
319 for (TDF_AttributeIterator itr(aLabel); itr.More(); itr.Next()) {
320 if (!aFilterForReferers.IsKept(itr.Value())) continue;
321 itr.Value()->References(ds);
322 const TDF_AttributeMap& attMap = ds->Attributes();
323 for (TDF_MapIteratorOfAttributeMap attMItr(attMap);attMItr.More();attMItr.Next()) {
324 Handle(TDF_Attribute) att = attMItr.Key();
325 if (aFilterForReferences.IsKept(att) && !att->Label().IsDescendant(aRefLabel)) {
329 const TDF_LabelMap& labMap = ds->Labels();
330 for (TDF_MapIteratorOfLabelMap labMItr(labMap);labMItr.More();labMItr.Next()) {
331 if (!labMItr.Key().IsDescendant(aRefLabel)) {
332 TDF_AttributeIterator itra(labMItr.Key());
333 for (; itra.More(); itra.Next()) {
334 if (aFilterForReferences.IsKept(itra.Value())) {
335 atts.Add(itra.Value());
344 //=======================================================================
345 //function : RelocateLabel
347 //=======================================================================
349 void TDF_Tool::RelocateLabel
350 (const TDF_Label& aSourceLabel,
351 const TDF_Label& fromRoot,
352 const TDF_Label& toRoot,
353 TDF_Label& aTargetLabel,
354 const Standard_Boolean create)
356 if (!aSourceLabel.IsDescendant(fromRoot)) return;
357 aTargetLabel.Nullify();
358 TColStd_ListOfInteger labelTags;
359 TDF_Tool::TagList(aSourceLabel,labelTags);
360 TColStd_ListOfInteger toTags;
361 TDF_Tool::TagList(toRoot,toTags);
362 for (Standard_Integer i = fromRoot.Depth(); i >= 0; --i)
363 labelTags.RemoveFirst();
364 labelTags.Prepend(toTags);
365 TDF_Tool::Label(toRoot.Data(),labelTags,aTargetLabel,create);
369 //=======================================================================
371 //purpose : Returns the entry as an ascii string.
372 //=======================================================================
375 (const TDF_Label& aLabel,
376 TCollection_AsciiString& anEntry)
379 if (!aLabel.IsNull()) {
380 TColStd_ListOfInteger Tags;
381 TDF_Tool::TagList(aLabel, Tags);
382 anEntry += TCollection_AsciiString(Tags.First());
384 if (Tags.IsEmpty()) {
385 anEntry += TDF_TagSeparator; // It must be the root label case.
388 while (!Tags.IsEmpty()) {
389 anEntry += TDF_TagSeparator;
390 anEntry += TCollection_AsciiString(Tags.First());
398 //=======================================================================
400 //purpose : Returns the entry of a label as a list of integers.
401 //=======================================================================
403 void TDF_Tool::TagList
404 (const TDF_Label& aLabel,
405 TColStd_ListOfInteger& aTagList)
408 if (!aLabel.IsNull()) {
409 TDF_Label Label = aLabel;
411 aTagList.Prepend(Label.Tag());
412 if (Label.IsRoot()) break;
413 Label = Label.Father();
419 //=======================================================================
421 //purpose : Returns the entry expressed as a string as a list of integers.
422 //=======================================================================
424 void TDF_Tool::TagList
425 (const TCollection_AsciiString& anEntry,
426 TColStd_ListOfInteger& aTagList)
428 char* cc = (char *)anEntry.ToCString();
429 Standard_Integer n = 0;
431 while (*cc != '\0') {
432 while ( *cc >= '0' && *cc <= '9') {
433 n = 10*n + (*cc - '0');
436 if (*cc == TDF_TagSeparator || *cc == '\0') {
439 if (*cc != '\0') ++cc;
441 else { // Not an entry!
449 //=======================================================================
451 //purpose : Returns the label expressed by <anEntry>.
452 //=======================================================================
455 (const Handle(TDF_Data)& aDF,
456 const TCollection_AsciiString& anEntry,
458 const Standard_Boolean create)
459 { TDF_Tool::Label(aDF,anEntry.ToCString(),aLabel,create); }
462 //=======================================================================
464 //purpose : Returns the label expressed by <anEntry>,
465 // and creates it if <create> is true.
466 //=======================================================================
469 (const Handle(TDF_Data)& aDF,
470 const Standard_CString anEntry,
472 const Standard_Boolean create)
474 TColStd_ListOfInteger tagList;
475 TDF_Tool::TagList(anEntry,tagList);
476 TDF_Tool::Label(aDF,tagList,aLabel,create);
480 //=======================================================================
482 //purpose : Returns the label expressed by <anEntry>,
483 // and creates it if <create> is true.
484 //=======================================================================
487 (const Handle(TDF_Data)& aDF,
488 const TColStd_ListOfInteger& aTagList,
490 const Standard_Boolean create)
492 if (aTagList.Extent() == 0) {
496 aLabel = aDF->Root();
497 if (aTagList.Extent() == 1 && aTagList.First() == 0) return;
499 TColStd_ListIteratorOfListOfInteger tagItr (aTagList);
500 tagItr.Next(); // Suppresses root tag.
501 for (; !aLabel.IsNull() && tagItr.More(); tagItr.Next()) {
502 aLabel = aLabel.FindChild(tagItr.Value(),create);
509 //=======================================================================
510 //function : CountLabels
512 //=======================================================================
514 void TDF_Tool::CountLabels
515 (TDF_LabelList& aLabelList,
516 TDF_LabelIntegerMap& aLabelMap)
518 if (aLabelList.IsEmpty()) return;
519 Standard_Boolean next = Standard_True;
520 TDF_ListIteratorOfLabelList itr(aLabelList);
522 const TDF_Label& lab = itr.Value();
523 if (aLabelMap.IsBound(lab)) {
525 aLabelList.Remove(itr);
526 next = Standard_False;
529 aLabelMap.Bind(lab,1);
532 if (next && !aLabelList.IsEmpty()) itr.Next();
537 //=======================================================================
538 //function : DeductLabels
540 //=======================================================================
542 void TDF_Tool::DeductLabels
543 (TDF_LabelList& aLabelList,
544 TDF_LabelIntegerMap& aLabelMap)
546 if (aLabelList.IsEmpty()) return;
547 Standard_Boolean next = Standard_True;
548 TDF_ListIteratorOfLabelList itr(aLabelList);
550 const TDF_Label& lab = itr.Value();
551 if (aLabelMap.IsBound(lab)) {
553 if (aLabelMap(lab) == 0) {
554 aLabelMap.UnBind(lab);
555 aLabelList.Remove(itr);
556 next = Standard_False;
559 else next = itr.More();
560 if (next && !aLabelList.IsEmpty()) itr.Next();
565 //=======================================================================
566 //function : DeepDump
567 //purpose : Deep dump of a DF.
568 //=======================================================================
570 void TDF_Tool::DeepDump
571 (Standard_OStream& anOS,
572 const Handle(TDF_Data)& aDF)
575 TDF_Tool::DeepDump(anOS,aDF->Root());
579 //=======================================================================
580 //function : ExtendedDeepDump
581 //purpose : Extended deep dump of a DF.
582 //=======================================================================
584 void TDF_Tool::ExtendedDeepDump
585 (Standard_OStream& anOS,
586 const Handle(TDF_Data)& aDF,
587 const TDF_IDFilter& aFilter)
590 TDF_Tool::ExtendedDeepDump(anOS,aDF->Root(),aFilter);
594 //=======================================================================
595 //function : DeepDump
596 //purpose : Deep dump of a label.
597 //=======================================================================
599 void TDF_Tool::DeepDump
600 (Standard_OStream& anOS,
601 const TDF_Label& aLabel)
606 for (TDF_ChildIterator ChildIt(aLabel); ChildIt.More (); ChildIt.Next ()) {
607 TDF_Tool::DeepDump(anOS,ChildIt.Value());
612 //=======================================================================
613 //function : ExtendedDeepDump
614 //purpose : Extended deep dump of a label.
615 //=======================================================================
617 void TDF_Tool::ExtendedDeepDump
618 (Standard_OStream& anOS,
619 const TDF_Label& aLabel,
620 const TDF_IDFilter& aFilter)
622 TDF_AttributeIndexedMap map;
623 TDF_Tool_ExtendedDeepDump(anOS,aLabel,aFilter,map);
625 anOS<<map.Extent()<<" attribute"; if (map.Extent()>1) anOS<<"s";
626 anOS<<" referenced by the label structure."<<endl;
628 anOS<<endl<<"Extended dump of filtered attribute(s):"<<endl;
629 Standard_Integer nba = 0;
630 TCollection_AsciiString entry;
632 for ( i = 1; i<= map.Extent(); ++i) {
633 const Handle(TDF_Attribute)& att = map.FindKey(i);
634 if (aFilter.IsKept(att)) {
637 if (att->Label().IsNull()) {
638 anOS<<" (no label)"<<endl;
641 TDF_Tool::Entry(att->Label(),entry);
642 anOS<<" (label: "<<entry<<")"<<endl;
644 att->ExtendedDump(anOS,aFilter,map); anOS<<endl;
647 anOS<<endl<<nba<<" attribute";
648 if (nba>1) anOS<<"s";
649 anOS<<" dumped between "<<--i<<endl;
653 //=======================================================================
654 //function : ExtendedDeepDump
655 //purpose : Internal method.
656 //=======================================================================
658 static void TDF_Tool_ExtendedDeepDump
659 (Standard_OStream& anOS,
660 const TDF_Label& aLabel,
661 const TDF_IDFilter& aFilter,
662 TDF_AttributeIndexedMap& aMap)
665 aLabel.ExtendedDump(anOS,aFilter,aMap);
667 for (TDF_ChildIterator ChildIt(aLabel); ChildIt.More (); ChildIt.Next ()) {
668 TDF_Tool_ExtendedDeepDump(anOS,ChildIt.Value(),aFilter,aMap);