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