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