0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / TNaming / TNaming_NamedShape.cxx
1 // Created on: 1996-12-18
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <TNaming_NamedShape.ixx>
18 #include <TNaming_Builder.ixx>
19
20 #include <TDF_Label.hxx>
21 #include <TDF_Data.hxx>
22 #include <TDF_DeltaOnAddition.hxx>
23 #include <TDF_AttributeIterator.hxx>
24 #include <TNaming_PtrNode.hxx>
25 #include <TNaming_PtrRefShape.hxx>
26 #include <TNaming_RefShape.hxx>
27 #include <TNaming_PtrDataMapOfShapePtrRefShape.hxx>
28 #include <TNaming_UsedShapes.hxx>
29 #include <TNaming_Tool.hxx>
30 #include <TNaming_Iterator.hxx>
31 #include <TNaming_NewShapeIterator.hxx>
32 #include <TNaming_OldShapeIterator.hxx>
33 #include <TNaming_SameShapeIterator.hxx>
34
35 #include <TNaming_DeltaOnModification.hxx>
36 #include <TNaming_DeltaOnRemoval.hxx>
37 #include <Standard_NoMoreObject.hxx>
38 #include <Standard_NoSuchObject.hxx>
39 #include <Standard_ConstructionError.hxx>
40 #include <Standard_NullObject.hxx>
41
42 #include <gp_Pnt.hxx>
43 #include <BRepBuilderAPI_MakeVertex.hxx>
44 #include <TopoDS_Vertex.hxx>
45
46 // Defines the nodes classes
47
48 #include <Standard.hxx>
49 #include <TNaming_CopyShape.hxx>
50
51 #define BUC60921   //SRN 15/05/01 : Fixes the memory leak due to pointer to RefShape is not deleted
52 //#define MDTV_DEB_HASL
53 //=======================================================================
54 //function : GetID
55 //purpose  : 
56 //=======================================================================
57
58 const Standard_GUID& TNaming_NamedShape::GetID() 
59 {
60   static Standard_GUID TNaming_NamedShapeID("c4ef4200-568f-11d1-8940-080009dc3333");
61   return TNaming_NamedShapeID;
62 }
63
64 //=======================================================================
65 //class: TNaming_Node
66 //=======================================================================
67
68 class TNaming_Node {
69 public:
70   TNaming_Node(TNaming_PtrRefShape        Old,
71                TNaming_PtrRefShape        New)
72     : myOld(Old),myNew(New),
73   myAtt(0L),
74   nextSameAttribute(0L), nextSameOld(0L),nextSameNew(0L)
75   {}
76   
77   //Label : Donne le Label
78   TDF_Label Label();
79
80   // NextSameShape
81   TNaming_Node* NextSameShape(TNaming_RefShape* prs);
82
83   // Test si l evolution est valide dans la transaction Trans
84   // ie : Trans n est pas anterieure a sa creation
85   //      et Trans n est pas posterieure a son BackUp
86   Standard_Boolean IsValidInTrans(Standard_Integer Trans);
87
88   // Memory management
89   DEFINE_STANDARD_ALLOC
90   
91   TNaming_PtrRefShape  myOld;
92   TNaming_PtrRefShape  myNew;
93   TNaming_NamedShape*  myAtt;
94   TNaming_PtrNode      nextSameAttribute;
95   TNaming_PtrNode      nextSameOld;
96   TNaming_PtrNode      nextSameNew;
97 };
98
99 //=======================================================================
100 //function : NextSameShape
101 //purpose  : 
102 //=======================================================================
103
104 TNaming_Node* TNaming_Node::NextSameShape(TNaming_RefShape* prs)
105 {
106   if (myOld == prs) return nextSameOld;
107   if (myNew == prs) return nextSameNew;
108   return nextSameNew;
109 }  
110
111 //=======================================================================
112 //function : Label
113 //purpose  : 
114 //=======================================================================
115
116 TDF_Label TNaming_Node::Label() 
117
118   return myAtt->Label();
119 }
120
121 //=======================================================================
122 //function : IsValidInTrans
123 //purpose  : 
124 //=======================================================================
125
126 Standard_Boolean TNaming_Node::IsValidInTrans(Standard_Integer Trans)
127 {
128   if (myAtt->Transaction() <= Trans && Trans <= myAtt->UntilTransaction()) {
129     return 1;
130   }
131   return 0;
132 }
133
134 //**********************************************************************
135 // Methods of TNaming_NamedShape
136 //**********************************************************************
137
138 //=======================================================================
139 //function : TNaming_NamedShape
140 //purpose  : 
141 //=======================================================================
142
143 TNaming_NamedShape::TNaming_NamedShape()
144
145   myNode    = 0L;
146   myVersion = 0;
147 }
148
149 //=======================================================================
150 //function : IsEmpty
151 //purpose  : 
152 //=======================================================================
153
154 Standard_Boolean  TNaming_NamedShape::IsEmpty () const
155 {  
156   TNaming_Iterator it (this);
157   return !it.More();
158 }
159
160
161 //=======================================================================
162 //function : Get
163 //purpose  : 
164 //=======================================================================
165
166 TopoDS_Shape TNaming_NamedShape::Get () const
167 {  
168   return TNaming_Tool::GetShape (this);
169 }
170
171
172
173
174 //=======================================================================
175 //function : RemoveNode
176 //purpose  : 
177 //=======================================================================
178
179 static void RemoveNode(Standard_Boolean                   MapExist ,
180                        TNaming_DataMapOfShapePtrRefShape& M, 
181                        TNaming_Node*&                     N) 
182 {
183   TNaming_RefShape* pos  = N->myOld;  
184   if (pos != 0L) {
185     if (pos->FirstUse() == N) {
186       TNaming_Node*  nextOld = N->nextSameOld;
187       if (nextOld != 0L) 
188         pos->FirstUse(nextOld);
189       else {
190         // le shape disparait
191         if (MapExist)
192           M.UnBind(pos->Shape());
193         //#ifdef BUC60921
194         N->myOld = 0L;
195         if(pos != N->myNew)
196         {
197           delete pos;
198           pos = 0L;
199         }
200         //#endif 
201       }
202     }
203     else {
204       TNaming_Node* pdn = pos->FirstUse();
205       while (pdn != 0L) {
206         
207         if (pdn->NextSameShape(pos) == N) {
208           if (pdn->myOld == pos) pdn->nextSameOld =  N->nextSameOld;
209           else                   pdn->nextSameNew =  N->nextSameOld;
210           break;
211         }
212         pdn = pdn->NextSameShape(pos);
213       }
214     }
215   }
216
217   TNaming_RefShape* pns  = N->myNew;  
218   if (pns != 0L) {
219     if (pns->FirstUse() == N) {
220       TNaming_Node*  nextNew = N->nextSameNew;
221       if (nextNew != 0L) 
222         pns->FirstUse(nextNew);
223       else 
224       {
225         // le shape disparait
226         if (MapExist) 
227           M.UnBind(pns->Shape());
228       
229         pns->FirstUse(0L);
230         delete pns;
231         pns = 0L;
232
233         N->myNew = 0L;
234       
235       }
236     }
237     else {
238       TNaming_Node* pdn = pns->FirstUse();
239       while (pdn != 0L) {
240         if (pdn->NextSameShape(pns) == N) {
241           if (pdn->myOld == pns) pdn->nextSameOld =  N->nextSameNew;
242           else                   pdn->nextSameNew =  N->nextSameNew;
243           break;
244         }
245         pdn = pdn->NextSameShape(pns);
246       }
247     }
248   }
249 }
250
251 //=======================================================================
252 //function : Clear
253 //purpose  : 
254 //=======================================================================
255
256 void TNaming_NamedShape::Clear()
257 {
258   if (Label().IsNull()) {
259 #ifdef DEB_BUILDER
260     cout << "attention etat fantomatique" << endl;
261 #endif
262     return;
263   }
264
265   Handle(TNaming_UsedShapes) US;
266     
267   TNaming_DataMapOfShapePtrRefShape* M=NULL;
268     
269   // Recuperation de la map si celle-ci n est pas deja detruite.
270   //Standard_Boolean MapExist = Ins.FindInRoot(TNaming_UsedShapes::GetID(),US);
271
272   Standard_Boolean MapExist = Label().Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
273   if (MapExist) M = &(US->Map());
274     
275   TNaming_Node* p = myNode;
276   while (p != 0L) {
277     RemoveNode (MapExist,*M,p);
278     p = p->nextSameAttribute;
279   }
280     
281   p = myNode;
282   TNaming_Node* q;
283   while (p != 0L) {
284     q = p;
285     p = p->nextSameAttribute;
286     if( q !=0L)
287     {
288       delete q;
289       q = 0L;
290     }
291   }
292     
293   myNode = 0L;
294 }
295
296 //=======================================================================
297 //function : BeforeRemoval
298 //purpose  : 
299 //=======================================================================
300
301 void TNaming_NamedShape::BeforeRemoval()
302 {
303   Clear();
304 }
305
306
307 //=======================================================================
308 //function : BeforeUndo
309 //purpose  : before application of a TDF_Delta.
310 //=======================================================================
311
312 Standard_Boolean TNaming_NamedShape::BeforeUndo
313   (const Handle(TDF_AttributeDelta)& /*anAttDelta*/,
314    const Standard_Boolean /*forceIt*/)
315 {
316 //  if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition))) {
317 //    anAttDelta->Attribute()->BeforeRemoval();
318 //  }
319   return Standard_True;
320 }
321
322 //=======================================================================
323 //function : AfterUndo 
324 //purpose  : After application of a TDF_Delta.
325 //=======================================================================
326
327 Standard_Boolean TNaming_NamedShape::AfterUndo
328   (const Handle(TDF_AttributeDelta)& anAttDelta,
329    const Standard_Boolean /*forceIt*/)
330 {
331   if (anAttDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition))) {
332     Handle(TNaming_UsedShapes) US;
333
334     TNaming_DataMapOfShapePtrRefShape* M=NULL;
335
336   // Recuperation de la map si celle-ci n est pas deja detruite.
337     //Standard_Boolean MapExist = Ins.FindInRoot(TNaming_UsedShapes::GetID(),US);
338     
339     Standard_Boolean MapExist = anAttDelta->Label().Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
340
341     if (MapExist) M = &(US->Map());
342     
343     TNaming_Node* p = myNode;
344     while (p != 0L) {
345       RemoveNode (MapExist,*M,p);
346       p = p->nextSameAttribute;
347     }
348     
349     p = myNode;
350     TNaming_Node* q;
351     while (p != 0L) {
352       q = p;
353       p = p->nextSameAttribute;
354       if(q != 0L)
355       {
356         delete q;
357         q = 0L;
358       }
359     }
360
361     myNode = 0L;
362   }
363   return Standard_True;
364 }
365
366
367 //=======================================================================
368 //function : BackupCopy
369 //purpose  : 
370 //=======================================================================
371
372 Handle(TDF_Attribute) TNaming_NamedShape::BackupCopy() const
373 {
374   // Remarque dans le copy il est important de reporter le noeud de l attribut
375   // pour ne pas casser le chemin nextSameShape.
376
377   Handle(TNaming_NamedShape) Cop = new TNaming_NamedShape();
378   Cop->myNode      = myNode;
379   Cop->myEvolution = myEvolution;
380   Cop->myVersion   = myVersion;
381
382   // Mise a jour de myAtt sur les noeuds dans l attribut.
383   TNaming_Node*  CN = Cop->myNode;
384
385   Handle(TNaming_NamedShape) A = this;
386   A->myNode = 0L;
387
388   while (CN != 0L) {
389     CN->myAtt = Cop.operator->();
390     CN        = CN->nextSameAttribute;
391   }
392   return Cop;
393 }
394
395
396 //=======================================================================
397 //function : Restore
398 //purpose  : 
399 //=======================================================================
400
401 void TNaming_NamedShape::Restore(const Handle(TDF_Attribute)& anAttribute) 
402 {
403   Clear();
404
405   TNaming_NamedShape* PAtt  = (TNaming_NamedShape*)anAttribute.operator->();
406   myNode                   = PAtt->myNode;
407   myEvolution              = PAtt->myEvolution;
408   myVersion                = PAtt->myVersion;
409   
410   // Mise a jour de myAtt sur les noeuds dans l attribut.
411   TNaming_Node*  CN = myNode;
412   while (CN != 0L) {
413     CN->myAtt = this;
414     CN        = CN->nextSameAttribute;
415   }
416   PAtt->myNode = 0L; //un noeud est dans un seul attribut.
417 }
418
419
420 //=======================================================================
421 //function : DeltaOnModification
422 //purpose  : 
423 //=======================================================================
424
425 Handle(TDF_DeltaOnModification) TNaming_NamedShape::DeltaOnModification
426 (const Handle(TDF_Attribute)& anOldAttribute) const
427 {
428   
429   return new TNaming_DeltaOnModification(*((Handle(TNaming_NamedShape)*)&anOldAttribute));
430 }
431
432 //=======================================================================
433 //function : DeltaOnModification
434 //purpose  : 
435 //=======================================================================
436
437 void TNaming_NamedShape::DeltaOnModification(const Handle(TDF_DeltaOnModification)& aDelta) 
438 {
439   aDelta->Apply();
440 }
441
442 //=======================================================================
443 //function : DeltaOnRemoval
444 //purpose  : 
445 //=======================================================================
446
447 Handle(TDF_DeltaOnRemoval) TNaming_NamedShape::DeltaOnRemoval() const
448 {
449   return new TNaming_DeltaOnRemoval(this);
450 }
451
452 //=======================================================================
453 //function : NewEmpty
454 //purpose  : 
455 //=======================================================================
456
457 Handle(TDF_Attribute) TNaming_NamedShape::NewEmpty () const
458 {
459   return new TNaming_NamedShape();
460 }
461
462 //=======================================================================
463 //function : Paste
464 //purpose  : 
465 //=======================================================================
466
467 void TNaming_NamedShape::Paste(const Handle(TDF_Attribute)&       into,
468                                const Handle(TDF_RelocationTable)& Tab) 
469 const
470
471   TDF_Label        Lab = into->Label();
472   if (Lab.IsNull()) {
473     Standard_NullObject::Raise("TNaming_NamedShape::Paste");
474   }
475   TNaming_Builder B(Lab);
476
477   TNaming_Iterator It (this);
478   for ( ;It.More() ; It.Next()) {
479     const TopoDS_Shape& OS     = It.OldShape();
480     const TopoDS_Shape& NS     = It.NewShape();
481     TNaming_Evolution   Status = It.Evolution();
482
483 // Modification_1 24.06.99 (szy)  
484     TopoDS_Shape copOS, copNS;
485     if(Status != TNaming_PRIMITIVE)
486       TNaming_CopyShape::CopyTool(OS, Tab->TransientTable(), copOS);
487     else copOS.Nullify();    
488     if(Status != TNaming_DELETE )
489       TNaming_CopyShape::CopyTool(NS, Tab->TransientTable(), copNS);
490     else copNS.Nullify();
491     
492     switch (Status) {
493     case TNaming_PRIMITIVE :
494       {
495         B.Generated(copNS);
496         break;
497       }
498     case TNaming_GENERATED :
499       {
500         B.Generated(copOS, copNS);
501         break;
502       }
503     case TNaming_MODIFY : 
504       {
505         B.Modify(copOS, copNS);
506         break;
507       }
508     case TNaming_DELETE : 
509       {
510         B.Delete (copOS);
511         break;
512       }
513     case TNaming_SELECTED :
514       {
515         B.Select(copNS,copOS);
516         break;
517       }
518
519     default:
520         break;
521     }
522   }
523 }
524
525 //=======================================================================
526 //function : References
527 //purpose  : 
528 //=======================================================================
529
530 void TNaming_NamedShape::References(const Handle(TDF_DataSet)& aDataSet) const
531 {
532   // Recherche des dependances.
533   // Pour chaque OldShape de l attribut on ajoute au dataSet son label d origine.
534   TNaming_Node* Current = myNode;
535   while (Current != NULL) {
536     if (Current->myOld != NULL) {
537       TNaming_RefShape* prs = Current->myOld;
538       TNaming_Node*     pdn = prs->FirstUse();
539       
540       while (pdn != NULL) {
541         if (pdn->myNew == prs && pdn->myAtt->Evolution() != TNaming_SELECTED) {
542           aDataSet->AddLabel(pdn->Label());
543         }
544         pdn = pdn->NextSameShape(prs);
545       }
546     }
547     Current = Current->nextSameAttribute;
548   }
549 }
550
551
552 //=======================================================================
553 //function : Add
554 //purpose  : 
555 //=======================================================================
556
557 void TNaming_NamedShape::Add(TNaming_Node*& pdn )
558
559   pdn->myAtt             = this;
560   if (myNode != 0L){
561     pdn->nextSameAttribute = myNode;
562   }
563   myNode = pdn;
564 }
565
566 //=======================================================================
567 //function : Dump
568 //purpose  : 
569 //=======================================================================
570
571 Standard_OStream& TNaming_NamedShape::Dump(Standard_OStream& anOS) const
572 {
573   return anOS;
574 }
575
576 //***************************************
577 //       Fin Class Named_Shape.
578 //***************************************
579
580
581 //**********************************************************************
582 // Methods of the TNaming_Builder class
583 //**********************************************************************
584
585 ///=======================================================================
586 //function : TNaming_Builder
587 //purpose  : 
588 //=======================================================================
589
590 TNaming_Builder::TNaming_Builder (const TDF_Label& L)
591 {
592   // Find or Build Map;
593   const TDF_Label& root = L.Root();
594   if (!root.FindAttribute(TNaming_UsedShapes::GetID(),myShapes)) {
595     myShapes = new TNaming_UsedShapes();
596     root.AddAttribute (myShapes);
597   }
598   
599   //Find Or Build Attribute in LIns.
600   if (!L.FindAttribute(TNaming_NamedShape::GetID(),myAtt)) {
601     myAtt = new TNaming_NamedShape();  
602     L.AddAttribute(myAtt);
603   }
604   else {
605     myAtt->Backup();
606     myAtt->Clear();  
607     myAtt->myVersion++;
608   }
609 }
610
611 //=======================================================================
612 //function : TNaming_Builder
613 //purpose  : 
614 //=======================================================================
615
616 Handle(TNaming_NamedShape) TNaming_Builder::NamedShape() const
617 {
618   return myAtt;
619 }
620
621 //=======================================================================
622 //function : UpdateNextSameShape
623 //purpose  : 
624 //=======================================================================
625
626 static void UpdateFirstUseOrNextSameShape(TNaming_RefShape*& prs,
627                                           TNaming_Node*& pdn)
628 {  
629   TNaming_Node* ldn = prs->FirstUse();
630   if (ldn == 0L) {
631     prs->FirstUse(pdn);
632   }
633   else {
634     TNaming_Node* cdn = ldn;
635     while (cdn != 0L) {
636       ldn = cdn;
637       cdn = cdn->NextSameShape(prs);
638       if (ldn == cdn) {
639         Standard_ConstructionError::Raise("UpdateFirstUseOrNextSameShape");
640         break;
641       }
642     }
643     // boucle interdite et inutile.
644     if (ldn != pdn) {
645       if (ldn->myOld == prs) ldn->nextSameOld = pdn;
646       if (ldn->myNew == prs) ldn->nextSameNew = pdn;
647     }
648   }
649 }
650
651 //=======================================================================
652 //function : Generate
653 //purpose  : 
654 //=======================================================================
655
656 void TNaming_Builder::Generated(const TopoDS_Shape& newShape) 
657 {
658   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_PRIMITIVE;
659   else {
660     if (myAtt->myEvolution != TNaming_PRIMITIVE)
661       Standard_ConstructionError::Raise("TNaming_Builder : not same evolution");
662   }
663
664   TNaming_RefShape* pos = 0L;
665   TNaming_RefShape* pns;
666   
667   if (myShapes->myMap.IsBound(newShape)) {
668 #ifdef DEB_BUILDER
669     cout <<"TNaming_Builder::Generate : the shape is already in the attribute"<<endl;
670 #endif
671     pns = myShapes->myMap.ChangeFind(newShape);
672     if (pns->FirstUse()->myAtt  == myAtt.operator->()) {
673       Standard_ConstructionError::Raise("TNaming_Builder::Generate");
674     }
675     TNaming_Node* pdn = new TNaming_Node(pos,pns);
676     myAtt->Add(pdn);
677     UpdateFirstUseOrNextSameShape (pns,pdn);
678   }
679   else {
680     pns = new TNaming_RefShape(newShape);    
681     TNaming_Node*     pdn = new TNaming_Node(pos,pns); 
682     pns  ->FirstUse(pdn);
683     myShapes->myMap.Bind (newShape , pns);
684     myAtt->Add(pdn);
685   }
686 }
687
688
689
690 //=======================================================================
691 //function : Delete
692 //purpose  : 
693 //=======================================================================
694
695 void TNaming_Builder::Delete(const TopoDS_Shape& oldShape) 
696 {  
697   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_DELETE;
698   else {
699     if (myAtt->myEvolution != TNaming_DELETE)
700       Standard_ConstructionError::Raise("TNaming_Builder : not same evolution");
701   }
702
703   TNaming_RefShape* pns = 0L;
704   TNaming_RefShape* pos;
705
706   if (myShapes->myMap.IsBound(oldShape)) 
707     pos = myShapes->myMap.ChangeFind(oldShape); 
708   else {
709 #ifdef DEB_BUILDER
710     cout <<"TNaming_Builder::Delete : the shape is not in the data"<<endl;
711 #endif
712     pos = new TNaming_RefShape(oldShape);  
713     myShapes->myMap.Bind(oldShape, pos);
714   }
715   TNaming_Node*     pdn = new TNaming_Node(pos,pns);   
716   myAtt->Add(pdn);
717   UpdateFirstUseOrNextSameShape (pos,pdn);
718 }
719
720 //=======================================================================
721 //function : Generate
722 //purpose  : 
723 //=======================================================================
724
725 void TNaming_Builder::Generated(const TopoDS_Shape& oldShape,
726                                 const TopoDS_Shape& newShape) 
727 {  
728   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_GENERATED;
729   else {
730     if (myAtt->myEvolution != TNaming_GENERATED)
731       Standard_ConstructionError::Raise("TNaming_Builder : not same evolution");
732   }
733
734   if (oldShape.IsSame(newShape)) {
735 #ifdef DEB_BUILDER
736     cout <<"TNaming_Builder::Generate : oldShape IsSame newShape"<<endl;
737 #endif
738     return;
739   }
740   TNaming_RefShape* pos;
741   if (!myShapes->myMap.IsBound(oldShape)) {
742     pos = new TNaming_RefShape(oldShape);
743     myShapes->myMap.Bind(oldShape,pos);
744   }
745   else
746     pos = myShapes->myMap.ChangeFind(oldShape);
747   
748   TNaming_RefShape* pns;
749   if (!myShapes->myMap.IsBound(newShape)) {
750     pns = new TNaming_RefShape(newShape);
751     myShapes->myMap.Bind(newShape,pns);
752   }
753   else
754     pns = myShapes->myMap.ChangeFind(newShape);
755   
756   TNaming_Node* pdn = new TNaming_Node(pos,pns);
757   myAtt->Add(pdn);
758   UpdateFirstUseOrNextSameShape (pos,pdn);
759   UpdateFirstUseOrNextSameShape (pns,pdn);
760 }
761
762
763 //=======================================================================
764 //function : Modify
765 //purpose  : 
766 //=======================================================================
767
768 void TNaming_Builder::Modify(const TopoDS_Shape& oldShape,
769                               const TopoDS_Shape& newShape) 
770
771   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_MODIFY;
772   else {
773     if (myAtt->myEvolution != TNaming_MODIFY)
774       Standard_ConstructionError::Raise("TNaming_Builder : not same evolution");
775   }
776
777   if (oldShape.IsSame(newShape)) {
778 #ifdef DEB_BUILDER
779     cout <<"TNaming_Builder::Modify : oldShape IsSame newShape"<<endl;
780 #endif
781     return;
782   }
783   TNaming_RefShape* pos;
784   if (!myShapes->myMap.IsBound(oldShape)) {
785     pos = new TNaming_RefShape(oldShape);
786     myShapes->myMap.Bind(oldShape,pos);
787   }
788   else
789     pos = myShapes->myMap.ChangeFind(oldShape);
790   
791   TNaming_RefShape* pns;
792   if (!myShapes->myMap.IsBound(newShape)) {
793     pns = new TNaming_RefShape(newShape);
794     myShapes->myMap.Bind(newShape,pns);
795   }
796   else
797     pns = myShapes->myMap.ChangeFind(newShape);
798   
799   TNaming_Node* pdn = new TNaming_Node(pos,pns);
800   myAtt->Add(pdn);
801   UpdateFirstUseOrNextSameShape (pos,pdn);
802   UpdateFirstUseOrNextSameShape (pns,pdn);
803   
804 }
805
806 //=======================================================================
807 //function : Select
808 //purpose  : 
809 //=======================================================================
810 void TNaming_Builder::Select (const TopoDS_Shape& S,
811                               const TopoDS_Shape& InS)
812 {  
813   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_SELECTED;
814   else {
815     if (myAtt->myEvolution != TNaming_SELECTED)
816       Standard_ConstructionError::Raise("TNaming_Builder : not same evolution");
817   }
818
819   TNaming_RefShape* pos;  
820   if (!myShapes->myMap.IsBound(InS)) {
821     pos = new TNaming_RefShape(InS);
822     myShapes->myMap.Bind(InS,pos);
823   }
824   else
825     pos = myShapes->myMap.ChangeFind(InS);
826
827   TNaming_RefShape* pns;
828   if (!myShapes->myMap.IsBound(S)) {
829     pns = new TNaming_RefShape(S);
830     myShapes->myMap.Bind(S,pns);
831   }
832   else
833     pns = myShapes->myMap.ChangeFind(S);  
834
835   TNaming_Node* pdn = new TNaming_Node(pos,pns);
836   myAtt->Add(pdn);
837   UpdateFirstUseOrNextSameShape (pos,pdn);
838   UpdateFirstUseOrNextSameShape (pns,pdn);
839 }
840
841 //**********************************************************************
842 //Methods of the TNaming_Iterator class
843 //**********************************************************************
844
845 //=======================================================================
846 //function : TNaming_Iterator
847 //purpose  : 
848 //=======================================================================
849
850 TNaming_Iterator::TNaming_Iterator(const Handle(TNaming_NamedShape)& Att)
851 :myTrans(-1)
852 {
853   myNode  = Att->myNode; 
854 }
855
856 //=======================================================================
857 //function : TNaming_Iterator
858 //purpose  : 
859 //=======================================================================
860
861 TNaming_Iterator::TNaming_Iterator(const TDF_Label& Lab)
862 :myTrans(-1)
863 {
864   Handle(TNaming_NamedShape) Att;
865   if (Lab.FindAttribute(TNaming_NamedShape::GetID(),Att)) {
866     myNode = Att->myNode;
867   }
868   else {
869     myNode = 0L; 
870   }
871 }
872
873 //=====================================================================
874 //function : TNaming_Iterator
875 //purpose  : 
876 //=======================================================================
877
878 TNaming_Iterator::TNaming_Iterator(const TDF_Label&       Lab,
879                                    const Standard_Integer Trans)
880 :myTrans(Trans)
881 {
882   Handle(TNaming_NamedShape) Att;
883   if (Lab.FindAttribute(TNaming_NamedShape::GetID(),Trans,Att)) {
884     myNode = Att->myNode;
885   }
886   else {
887     myNode = 0L;
888 #ifdef TNAMING_DEB
889     cout <<"TNaming_Iterator : No Shape for this label"<<endl;
890 #endif
891   }
892 }
893
894 //=======================================================================
895 //function : Next
896 //purpose  : 
897 //=======================================================================
898
899 void TNaming_Iterator::Next() 
900 {
901   Standard_NoMoreObject_Raise_if(myNode == 0L,
902                                  "TNaming_Iterator::Next");
903   myNode = myNode->nextSameAttribute;   
904 }
905
906 //=======================================================================
907 //function : OldShape
908 //purpose  : 
909 //=======================================================================
910
911 const TopoDS_Shape& TNaming_Iterator::OldShape() const 
912 {  
913   Standard_NoSuchObject_Raise_if(myNode == 0L,
914                                  "TNaming_Iterator::OldShape");
915   if (myNode->myOld == 0L) {
916     static TopoDS_Shape NullShape;
917     return NullShape;
918   }
919   return myNode->myOld->Shape();
920 }
921
922 //=======================================================================
923 //function : NewShape
924 //purpose  : 
925 //=======================================================================
926
927 const TopoDS_Shape& TNaming_Iterator::NewShape() const 
928 {
929   Standard_NoSuchObject_Raise_if(myNode == 0L,
930                                  "TNaming_Iterator::NewShape");
931   if (myNode->myNew == 0L) {
932     static TopoDS_Shape NullShape;
933     return NullShape;
934   }
935   return myNode->myNew->Shape();
936 }
937
938
939 //=======================================================================
940 //function : IsModification
941 //purpose  : 
942 //=======================================================================
943
944 Standard_Boolean TNaming_Iterator::IsModification() const
945 {
946   Standard_NoSuchObject_Raise_if(myNode == 0L,
947                                  "TNaming_Iterator::IsModification");
948   return (myNode->myAtt->myEvolution == TNaming_MODIFY || 
949           myNode->myAtt->myEvolution == TNaming_DELETE );
950 }
951
952 //=======================================================================
953 //function : Evolution
954 //purpose  : 
955 //=======================================================================
956
957 TNaming_Evolution  TNaming_Iterator::Evolution() const
958 {
959   Standard_NoSuchObject_Raise_if(myNode == 0L,
960                                  "TNaming_Iterator::IsModification");
961   return myNode->myAtt->myEvolution;
962 }
963
964
965
966 //**********************************************************************
967 //Methods of the TNaming_NewShapeIterator class
968 //**********************************************************************
969
970 //=======================================================================
971 //function : SelectSameShape
972 //purpose  : Selectionne le prochain noeud ou le shape est le meme que celui
973 //           de RS. Old = 0 si il doit etre new dans le noeud a chercher.
974 //           selection dans la transaction valide.
975 //           On saute aussi les noeud ou OS = NS;
976 //=======================================================================
977
978 static void SelectSameShape (TNaming_Node*&          myNode,
979                              Standard_Boolean        Old,
980                              TNaming_RefShape*&      RS,
981                              const Standard_Integer& Trans)
982 {
983   TNaming_Node* pdn = myNode;
984   
985   while (pdn != 0L) {
986     Standard_Boolean Valid;
987     if (Trans < 0) Valid = pdn->myAtt->IsValid(); 
988     else Valid = pdn->IsValidInTrans(Trans);
989
990     if (Valid)
991     {
992       if (Old) {
993         if( pdn->myOld == RS && pdn->myNew != 0L && pdn->myNew != RS) {
994           break;
995         }  
996       }
997       else {
998         if( pdn->myNew == RS && pdn->myOld != 0L && pdn->myOld != RS) {
999           break;
1000         }
1001       }
1002     }
1003     pdn = pdn->NextSameShape(RS);
1004   }
1005   myNode = pdn;
1006 }  
1007
1008 //=======================================================================
1009 //function : TNaming_NewShapeIterator
1010 //purpose  : 
1011 //=======================================================================
1012
1013 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1014 (const TopoDS_Shape&               aShape,
1015  const Standard_Integer            Trans,
1016  const Handle(TNaming_UsedShapes)& Shapes)
1017 :myTrans(Trans)
1018 {
1019   Standard_Boolean  Old = Standard_True;  
1020   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1021   myNode = RS->FirstUse();
1022   SelectSameShape(myNode,Old,RS,myTrans);
1023 }
1024
1025 //=======================================================================
1026 //function : TNaming_NewShapeIterator
1027 //purpose  : 
1028 //=======================================================================
1029
1030 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1031 (const TopoDS_Shape&               aShape,
1032  const Standard_Integer            Trans,
1033  const TDF_Label&                  access)
1034 :myTrans(Trans)
1035 {  
1036   Handle(TNaming_UsedShapes) Shapes;
1037   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {
1038     Standard_Boolean  Old = Standard_True;  
1039     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1040     myNode = RS->FirstUse();
1041     SelectSameShape(myNode,Old,RS,myTrans);
1042   }
1043 }
1044
1045 //=======================================================================
1046 //function : TNaming_NewShapeIterator
1047 //purpose  : 
1048 //=======================================================================
1049
1050 TNaming_NewShapeIterator::TNaming_NewShapeIterator (const TNaming_Iterator& anIterator)
1051 :myTrans(anIterator.myTrans)
1052 {
1053   Standard_Boolean Old = Standard_True;  
1054   myNode = anIterator.myNode;
1055   TNaming_RefShape* RS = myNode->myNew;
1056   if (RS == 0L) 
1057     myNode = 0L;  // No descendant
1058   else {    
1059     // il faut repartir de la premiere utilisation.
1060     myNode = RS->FirstUse();
1061     SelectSameShape(myNode,Old,RS,myTrans);
1062   }
1063 }
1064
1065 //=======================================================================
1066 //function : TNaming_NewShapeIterator
1067 //purpose  : 
1068 //=======================================================================
1069
1070 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1071 (const TopoDS_Shape&               aShape,
1072  const Handle(TNaming_UsedShapes)& Shapes)
1073 :myTrans(-1)
1074 {
1075   Standard_Boolean  Old = Standard_True;  
1076   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1077   myNode = RS->FirstUse();
1078   SelectSameShape(myNode,Old,RS,myTrans);
1079 }
1080
1081 //=======================================================================
1082 //function : TNaming_NewShapeIterator
1083 //purpose  : 
1084 //=======================================================================
1085
1086 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1087 (const TopoDS_Shape& aShape,
1088  const TDF_Label&    access)
1089 :myTrans(-1)
1090 {
1091   Handle(TNaming_UsedShapes) Shapes;
1092   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {
1093     Standard_Boolean  Old = Standard_True;  
1094     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1095     myNode = RS->FirstUse();
1096     SelectSameShape(myNode,Old,RS,myTrans);
1097   }
1098 }
1099
1100 //=======================================================================
1101 //function : TNaming_NewShapeIterator
1102 //purpose  : 
1103 //=======================================================================
1104
1105 TNaming_NewShapeIterator::TNaming_NewShapeIterator(const TNaming_NewShapeIterator& anIterator)
1106 :myTrans(anIterator.myTrans)
1107 {
1108   Standard_Boolean Old = Standard_True;
1109   myNode = anIterator.myNode;
1110   TNaming_RefShape* RS = myNode->myNew;
1111   if (RS == 0L) 
1112     myNode = 0L;  // No descendant
1113   else  {
1114     // il faut repartir de la premiere utilisation.
1115     myNode = RS->FirstUse();
1116     SelectSameShape(myNode,Old,RS,myTrans);
1117   }
1118 }
1119
1120 //=======================================================================
1121 //function : Next
1122 //purpose  : 
1123 //=======================================================================
1124
1125 void TNaming_NewShapeIterator::Next() 
1126 {
1127   Standard_Boolean  Old = Standard_True;
1128   TNaming_RefShape* RS  = myNode->myOld;
1129   myNode = myNode->NextSameShape(RS);
1130   SelectSameShape(myNode,Old,RS,myTrans);
1131 }
1132
1133 //=======================================================================
1134 //function : Label
1135 //purpose  : 
1136 //=======================================================================
1137
1138 TDF_Label TNaming_NewShapeIterator::Label() const
1139 {  
1140   Standard_NoSuchObject_Raise_if(myNode == 0L,
1141                                  "TNaming_NewShapeIterator::Label");
1142   return myNode->Label();
1143 }
1144
1145 //=======================================================================
1146 //function : NamedShape
1147 //purpose  : 
1148 //=======================================================================
1149
1150 Handle(TNaming_NamedShape) TNaming_NewShapeIterator::NamedShape() const
1151 {  
1152   Standard_NoSuchObject_Raise_if(myNode == 0L,
1153                                  "TNaming_NewShapeIterator::Label");
1154   return myNode->myAtt;
1155 }
1156
1157 //=======================================================================
1158 //function : Shape
1159 //purpose  : 
1160 //=======================================================================
1161
1162 const TopoDS_Shape& TNaming_NewShapeIterator::Shape() const
1163 {
1164   Standard_NoSuchObject_Raise_if(myNode == 0L,
1165                                  "TNaming_NewShapeIterator::Shape"); 
1166   return myNode->myNew->Shape();
1167 }
1168
1169 //=======================================================================
1170 //function : IsModification
1171 //purpose  : 
1172 //=======================================================================
1173
1174 Standard_Boolean TNaming_NewShapeIterator::IsModification() const
1175 {  
1176   Standard_NoSuchObject_Raise_if(myNode == 0L,
1177                                  "TNaming_NewShapeIterator::IsModification");
1178
1179   return (myNode->myAtt->myEvolution == TNaming_MODIFY || 
1180           myNode->myAtt->myEvolution == TNaming_DELETE );
1181 }
1182
1183 //**********************************************************************
1184 //Methods of the TNaming_OldShapeIterator class
1185 //**********************************************************************
1186 //=======================================================================
1187 //function : TNaming_OldShapeIterator
1188 //purpose  : 
1189 //=======================================================================
1190
1191 TNaming_OldShapeIterator::TNaming_OldShapeIterator
1192 (const TopoDS_Shape&               aShape,
1193  const Standard_Integer            Trans,
1194  const Handle(TNaming_UsedShapes)& Shapes)
1195 :myTrans(Trans)
1196 {
1197   Standard_Boolean  Old = Standard_False;
1198   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1199   myNode = RS->FirstUse();
1200   SelectSameShape(myNode,Old,RS,myTrans);
1201 }
1202
1203 //=======================================================================
1204 //function : TNaming_OldShapeIterator
1205 //purpose  : 
1206 //=======================================================================
1207
1208 TNaming_OldShapeIterator::TNaming_OldShapeIterator 
1209 (const TopoDS_Shape& aShape,
1210  const Standard_Integer Trans,
1211  const TDF_Label& access)
1212 :myTrans(Trans)
1213 {
1214   Handle(TNaming_UsedShapes) Shapes;
1215   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {
1216     Standard_Boolean  Old = Standard_False;
1217     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1218     myNode = RS->FirstUse();
1219     SelectSameShape(myNode,Old,RS,myTrans);
1220   }
1221 }
1222 //=======================================================================
1223 //function : TNaming_OldShapeIterator
1224 //purpose  : 
1225 //=======================================================================
1226
1227 TNaming_OldShapeIterator::TNaming_OldShapeIterator
1228 (const TopoDS_Shape&               aShape,
1229  const Handle(TNaming_UsedShapes)& Shapes)
1230 :myTrans(-1)
1231 {  
1232   Standard_Boolean  Old = Standard_False;
1233   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1234   myNode = RS->FirstUse();
1235   SelectSameShape(myNode,Old,RS,myTrans);
1236 }
1237
1238 //=======================================================================
1239 //function : TNaming_OldShapeIterator
1240 //purpose  : 
1241 //=======================================================================
1242
1243 TNaming_OldShapeIterator::TNaming_OldShapeIterator
1244 (const TopoDS_Shape& aShape,
1245  const TDF_Label& access)
1246 :myTrans(-1)
1247 {  
1248   Handle(TNaming_UsedShapes) Shapes;
1249   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {  
1250     Standard_Boolean  Old = Standard_False;
1251     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1252     myNode = RS->FirstUse();
1253     SelectSameShape(myNode,Old,RS,myTrans);
1254   }
1255 }
1256
1257 //=======================================================================
1258 //function : TNaming_OldShapeIterator
1259 //purpose  : 
1260 //=======================================================================
1261
1262 TNaming_OldShapeIterator::TNaming_OldShapeIterator (const TNaming_Iterator& anIterator)
1263 :myTrans(anIterator.myTrans)
1264 {
1265   Standard_Boolean Old = Standard_False;  
1266   myNode = anIterator.myNode;
1267   TNaming_RefShape* RS = myNode->myNew;
1268   if (RS == 0L) 
1269     myNode = 0L;  // No descendant
1270   else {    
1271     // il faut repartir de la premiere utilisation.
1272     myNode = RS->FirstUse();
1273     SelectSameShape(myNode,Old,RS,myTrans);
1274   }
1275 }
1276
1277 //=======================================================================
1278 //function : TNaming_OldShapeIterator
1279 //purpose  : 
1280 //=======================================================================
1281
1282 TNaming_OldShapeIterator::TNaming_OldShapeIterator(const TNaming_OldShapeIterator& anIterator)
1283 :myTrans(anIterator.myTrans)
1284 {
1285   Standard_Boolean Old = Standard_False;  
1286   myNode = anIterator.myNode;
1287   TNaming_RefShape* RS = myNode->myOld;
1288   if (RS == 0L) 
1289     myNode = 0L;  // No descendant
1290   else  {
1291     // il faut repartir de la premiere utilisation.
1292     myNode = RS->FirstUse();
1293     SelectSameShape(myNode,Old,RS,myTrans);
1294   }
1295 }
1296
1297 //=======================================================================
1298 //function : Next
1299 //purpose  : 
1300 //=======================================================================
1301
1302 void TNaming_OldShapeIterator::Next() 
1303 {
1304   Standard_Boolean  Old = Standard_False;  
1305   TNaming_RefShape* RS  = myNode->myNew;
1306   myNode = myNode->NextSameShape(RS);
1307   SelectSameShape(myNode,Old,RS,myTrans);
1308 }
1309
1310 //=======================================================================
1311 //function : Label
1312 //purpose  : 
1313 //=======================================================================
1314
1315 TDF_Label TNaming_OldShapeIterator::Label() const
1316 {  
1317   if (myNode == 0L) Standard_NoSuchObject::Raise("TNaming_OldShapeIterator::Label");
1318   return myNode->Label();
1319   
1320 }
1321
1322 //=======================================================================
1323 //function : NamedShape
1324 //purpose  : 
1325 //=======================================================================
1326
1327 Handle(TNaming_NamedShape) TNaming_OldShapeIterator::NamedShape() const
1328 {  
1329   if (myNode == 0L) Standard_NoSuchObject::Raise("TNaming_OldShapeIterator::Label");
1330   return myNode->myAtt;
1331 }
1332 //=======================================================================
1333 //function : Shape
1334 //purpose  : 
1335 //=======================================================================
1336
1337 const TopoDS_Shape& TNaming_OldShapeIterator::Shape() const
1338 {   
1339   if(myNode == 0L) Standard_NoSuchObject::Raise("TNaming_OldShapeIterator::Shape"); 
1340   return myNode->myOld->Shape();
1341 }
1342
1343 //=======================================================================
1344 //function : IsModification
1345 //purpose  : 
1346 //=======================================================================
1347
1348 Standard_Boolean TNaming_OldShapeIterator::IsModification() const
1349 {  
1350   Standard_NoSuchObject_Raise_if(myNode == 0L,
1351                                  "TNaming_OldShapeIterator::IsModification");  
1352   return (myNode->myAtt->myEvolution == TNaming_MODIFY || 
1353           myNode->myAtt->myEvolution == TNaming_DELETE );
1354 }
1355
1356
1357 //**********************************************************************
1358 //Methods of the SameShapeIterator
1359 //**********************************************************************
1360
1361 //=======================================================================
1362 //function : 
1363 //purpose  : 
1364 //=======================================================================
1365
1366 TNaming_SameShapeIterator::TNaming_SameShapeIterator
1367 (const TopoDS_Shape& aShape,
1368  const Handle(TNaming_UsedShapes)& Shapes)
1369 {
1370   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1371   myNode  = RS->FirstUse();
1372   myIsNew = (myNode->myNew == RS);
1373 }
1374
1375
1376 //=======================================================================
1377 //function : TNaming_SameShapeIterator
1378 //purpose  : 
1379 //=======================================================================
1380
1381 TNaming_SameShapeIterator::TNaming_SameShapeIterator
1382 (const TopoDS_Shape& aShape,
1383  const TDF_Label& access)
1384 {  
1385   Handle(TNaming_UsedShapes) Shapes;
1386   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) { 
1387     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1388     myNode  = RS->FirstUse();
1389     myIsNew = (myNode->myNew == RS);
1390   }
1391 }
1392
1393 //=======================================================================
1394 //function : Next
1395 //purpose  : 
1396 //=======================================================================
1397
1398 void TNaming_SameShapeIterator::Next() 
1399 {
1400   TNaming_RefShape* prs;
1401   if (myIsNew) prs = myNode->myNew; else prs = myNode->myOld;
1402   
1403   myNode = myNode->NextSameShape(prs);
1404   if (myNode != 0L) myIsNew = (myNode->myNew == prs);
1405 }
1406
1407 //=======================================================================
1408 //function : Label
1409 //purpose  : 
1410 //=======================================================================
1411
1412 TDF_Label TNaming_SameShapeIterator::Label() const
1413 {  
1414   Standard_NoSuchObject_Raise_if(myNode == 0L,
1415                                  "TNaming_SameShapeIterator::Label");
1416   return myNode->Label();
1417 }
1418
1419
1420 //**********************************************************************
1421 //Methods of the TNaming_RefShape
1422 //**********************************************************************
1423 //=======================================================================
1424 //function : Label
1425 //purpose  : 
1426 //=======================================================================
1427
1428 TDF_Label TNaming_RefShape::Label() const
1429 {
1430   return myFirstUse->myAtt->Label();
1431 }
1432
1433 //=======================================================================
1434 //function : NamedShape
1435 //purpose  : 
1436 //=======================================================================
1437
1438 Handle(TNaming_NamedShape) TNaming_RefShape::NamedShape() const
1439 {
1440   return myFirstUse->myAtt;
1441 }
1442
1443
1444 //**********************************************************************
1445 //Methods of the TNaming_Tool class
1446 //**********************************************************************
1447
1448 //=======================================================================
1449 //function : HasLabel
1450 //purpose  : 
1451 //=======================================================================
1452
1453 Standard_Boolean TNaming_Tool::HasLabel (const TDF_Label&    access,
1454                                          const TopoDS_Shape& S)
1455 {
1456   Handle(TNaming_UsedShapes) US;
1457   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),US)) {
1458     return (US->Map().IsBound(S));
1459   }
1460 #ifdef MDTV_DEB_HASL
1461   cout << "##==> Sub-Shape has no Label!" <<endl;
1462 #endif
1463   return Standard_False;
1464 }
1465
1466
1467 //=======================================================================
1468 //function : Label
1469 //purpose  : 
1470 //=======================================================================
1471
1472 TDF_Label TNaming_Tool::Label(const TDF_Label&    access,
1473                               const TopoDS_Shape& S,
1474                               Standard_Integer&   Trans)
1475
1476   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(access,S),"TNaming_Tool::Label"); 
1477   Handle(TNaming_UsedShapes) US;
1478   access.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
1479   return TNaming_Tool::Label(US,S,Trans);
1480 }
1481
1482
1483 //=======================================================================
1484 //function : IsValidInTrans
1485 //purpose  : un shape est valid tant que l attribut ou il est cree est valid 
1486 //=======================================================================
1487
1488 Standard_Integer TNaming_Tool::ValidUntil (const TDF_Label& access, const TopoDS_Shape& S)
1489 {  
1490   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(access,S),"TNaming_Tool::ValidUntil"); 
1491   Handle(TNaming_UsedShapes) US;
1492   access.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
1493   return TNaming_Tool::ValidUntil(S,US);
1494 }
1495  
1496
1497 //=======================================================================
1498 //function : HasLabel
1499 //purpose  : 
1500 //=======================================================================
1501
1502 Standard_Boolean TNaming_Tool::HasLabel(const Handle(TNaming_UsedShapes)& Shapes,
1503                                         const TopoDS_Shape&               S)
1504 {
1505   return (Shapes->Map().IsBound(S));
1506 }
1507
1508
1509 //=======================================================================
1510 //function : Label
1511 //purpose  : 
1512 //=======================================================================
1513
1514 TDF_Label TNaming_Tool::Label(const Handle(TNaming_UsedShapes)& Shapes,
1515                               const TopoDS_Shape&               S,
1516                               Standard_Integer&                 Trans)
1517 {
1518   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(Shapes,S),"TNaming_Tool::Label");
1519   TNaming_RefShape* prs = Shapes->Map().Find(S);
1520   TNaming_Node*     pdn = prs->FirstUse();
1521
1522   while (pdn != 0L && !(pdn->myNew == prs && pdn->myAtt->Evolution() != TNaming_SELECTED)){
1523     pdn = pdn->NextSameShape(prs);
1524   }
1525   if (pdn == 0L) pdn = prs->FirstUse();
1526
1527   TDF_Label      L   = pdn->Label();
1528   Trans = pdn->myAtt->Transaction();
1529   return L;
1530 }
1531 //=======================================================================
1532 //function : NamedShape
1533 //purpose  : 
1534 //=======================================================================
1535 Handle(TNaming_NamedShape) TNaming_Tool::NamedShape(const TopoDS_Shape& S,
1536                                                     const TDF_Label&    Acces) 
1537
1538   Handle(TNaming_UsedShapes) US;
1539   Acces.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
1540   Handle(TNaming_NamedShape) NS;
1541   
1542   if(!TNaming_Tool::HasLabel(US,S)) {
1543     return NS;
1544   }
1545   
1546   TNaming_RefShape* prs = US->Map().Find(S);
1547   TNaming_Node*     pdn = prs->FirstUse();
1548   TNaming_Node*     res = 0L;
1549
1550   while (pdn != 0L) {
1551     if (pdn->myNew == prs && pdn->myAtt->Evolution() != TNaming_SELECTED) {
1552       res = pdn;
1553       if (pdn->myAtt->Evolution() != TNaming_GENERATED) {
1554         // Les modifications sont privilegiees par rapport au generation.
1555         // Dans le cas des shapes qui sont a la fois des modifications et des generations
1556         // faces tangentes.
1557         break;
1558       }
1559     }
1560     pdn = pdn->NextSameShape(prs);
1561   }
1562   
1563   if (res == 0L) return NS;
1564
1565   // VERUE EN ATTENDANT DE REVOIR ABORT 03/11/98
1566   // Protection pour eviter de renvoyer un attribut backuped
1567   TDF_Label Lab = res->Label();
1568   Lab.FindAttribute(TNaming_NamedShape::GetID(),NS);
1569   return NS;
1570   //  return res->myAtt;
1571
1572
1573 //=======================================================================
1574 //function : IsValidInTrans
1575 //purpose  : un shape est valid tant que l attribut ou il est cree est valid 
1576 //=======================================================================
1577
1578 Standard_Integer TNaming_Tool::ValidUntil (const TopoDS_Shape&               S,
1579                                            const Handle(TNaming_UsedShapes)& US)
1580 {  
1581   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(US,S),"TNaming_Tool::ValidUntil"); 
1582   
1583   TNaming_RefShape* RS  = US->Map().ChangeFind(S);
1584   Standard_Integer  Cur;
1585   Standard_Integer  Until  = 0;  
1586   TNaming_Node*     Node   = RS->FirstUse();
1587
1588   while (Node != 0L) {
1589     if (Node->myNew != 0L && Node->myNew == RS) {
1590       Cur    = Node->myAtt->UntilTransaction();
1591       if (Cur > Until) Until = Cur;
1592     }
1593     Node = Node->NextSameShape(RS);
1594   }
1595   return Until;
1596 }