Warnings on vc14 were eliminated
[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   Status = It.Evolution();
484
485 // Modification_1 24.06.99 (szy)  
486     TopoDS_Shape copOS, copNS;
487     if(Status != TNaming_PRIMITIVE)
488       TNaming_CopyShape::CopyTool(OS, Tab->TransientTable(), copOS);
489     else copOS.Nullify();    
490     if(Status != TNaming_DELETE )
491       TNaming_CopyShape::CopyTool(NS, Tab->TransientTable(), copNS);
492     else copNS.Nullify();
493     
494     switch (Status) {
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 = 0L;
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   TNaming_Node*     pdn = new TNaming_Node(pos,pns);   
718   myAtt->Add(pdn);
719   UpdateFirstUseOrNextSameShape (pos,pdn);
720 }
721
722 //=======================================================================
723 //function : Generate
724 //purpose  : 
725 //=======================================================================
726
727 void TNaming_Builder::Generated(const TopoDS_Shape& oldShape,
728                                 const TopoDS_Shape& newShape) 
729 {  
730   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_GENERATED;
731   else {
732     if (myAtt->myEvolution != TNaming_GENERATED)
733       throw Standard_ConstructionError("TNaming_Builder : not same evolution");
734   }
735
736   if (oldShape.IsSame(newShape)) {
737 #ifdef OCCT_DEBUG_BUILDER
738     cout <<"TNaming_Builder::Generate : oldShape IsSame newShape"<<endl;
739 #endif
740     return;
741   }
742   TNaming_RefShape* pos;
743   if (!myShapes->myMap.IsBound(oldShape)) {
744     pos = new TNaming_RefShape(oldShape);
745     myShapes->myMap.Bind(oldShape,pos);
746   }
747   else
748     pos = myShapes->myMap.ChangeFind(oldShape);
749   
750   TNaming_RefShape* pns;
751   if (!myShapes->myMap.IsBound(newShape)) {
752     pns = new TNaming_RefShape(newShape);
753     myShapes->myMap.Bind(newShape,pns);
754   }
755   else
756     pns = myShapes->myMap.ChangeFind(newShape);
757   
758   TNaming_Node* pdn = new TNaming_Node(pos,pns);
759   myAtt->Add(pdn);
760   UpdateFirstUseOrNextSameShape (pos,pdn);
761   UpdateFirstUseOrNextSameShape (pns,pdn);
762 }
763
764
765 //=======================================================================
766 //function : Modify
767 //purpose  : 
768 //=======================================================================
769
770 void TNaming_Builder::Modify(const TopoDS_Shape& oldShape,
771                               const TopoDS_Shape& newShape) 
772
773   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_MODIFY;
774   else {
775     if (myAtt->myEvolution != TNaming_MODIFY)
776       throw Standard_ConstructionError("TNaming_Builder : not same evolution");
777   }
778
779   if (oldShape.IsSame(newShape)) {
780 #ifdef OCCT_DEBUG_BUILDER
781     cout <<"TNaming_Builder::Modify : oldShape IsSame newShape"<<endl;
782 #endif
783     return;
784   }
785   TNaming_RefShape* pos;
786   if (!myShapes->myMap.IsBound(oldShape)) {
787     pos = new TNaming_RefShape(oldShape);
788     myShapes->myMap.Bind(oldShape,pos);
789   }
790   else
791     pos = myShapes->myMap.ChangeFind(oldShape);
792   
793   TNaming_RefShape* pns;
794   if (!myShapes->myMap.IsBound(newShape)) {
795     pns = new TNaming_RefShape(newShape);
796     myShapes->myMap.Bind(newShape,pns);
797   }
798   else
799     pns = myShapes->myMap.ChangeFind(newShape);
800   
801   TNaming_Node* pdn = new TNaming_Node(pos,pns);
802   myAtt->Add(pdn);
803   UpdateFirstUseOrNextSameShape (pos,pdn);
804   UpdateFirstUseOrNextSameShape (pns,pdn);
805   
806 }
807
808 //=======================================================================
809 //function : Select
810 //purpose  : 
811 //=======================================================================
812 void TNaming_Builder::Select (const TopoDS_Shape& S,
813                               const TopoDS_Shape& InS)
814 {  
815   if (myAtt->myNode == 0L) myAtt->myEvolution = TNaming_SELECTED;
816   else {
817     if (myAtt->myEvolution != TNaming_SELECTED)
818       throw Standard_ConstructionError("TNaming_Builder : not same evolution");
819   }
820
821   TNaming_RefShape* pos;  
822   if (!myShapes->myMap.IsBound(InS)) {
823     pos = new TNaming_RefShape(InS);
824     myShapes->myMap.Bind(InS,pos);
825   }
826   else
827     pos = myShapes->myMap.ChangeFind(InS);
828
829   TNaming_RefShape* pns;
830   if (!myShapes->myMap.IsBound(S)) {
831     pns = new TNaming_RefShape(S);
832     myShapes->myMap.Bind(S,pns);
833   }
834   else
835     pns = myShapes->myMap.ChangeFind(S);  
836
837   TNaming_Node* pdn = new TNaming_Node(pos,pns);
838   myAtt->Add(pdn);
839   UpdateFirstUseOrNextSameShape (pos,pdn);
840   UpdateFirstUseOrNextSameShape (pns,pdn);
841 }
842
843 //**********************************************************************
844 //Methods of the TNaming_Iterator class
845 //**********************************************************************
846
847 //=======================================================================
848 //function : TNaming_Iterator
849 //purpose  : 
850 //=======================================================================
851
852 TNaming_Iterator::TNaming_Iterator(const Handle(TNaming_NamedShape)& Att)
853 :myTrans(-1)
854 {
855   myNode  = Att->myNode; 
856 }
857
858 //=======================================================================
859 //function : TNaming_Iterator
860 //purpose  : 
861 //=======================================================================
862
863 TNaming_Iterator::TNaming_Iterator(const TDF_Label& Lab)
864 :myTrans(-1)
865 {
866   Handle(TNaming_NamedShape) Att;
867   if (Lab.FindAttribute(TNaming_NamedShape::GetID(),Att)) {
868     myNode = Att->myNode;
869   }
870   else {
871     myNode = 0L; 
872   }
873 }
874
875 //=====================================================================
876 //function : TNaming_Iterator
877 //purpose  : 
878 //=======================================================================
879
880 TNaming_Iterator::TNaming_Iterator(const TDF_Label&       Lab,
881                                    const Standard_Integer Trans)
882 :myTrans(Trans)
883 {
884   Handle(TDF_Attribute) Att;
885   if (Lab.FindAttribute(TNaming_NamedShape::GetID(),Trans,Att)) {
886     myNode = Handle(TNaming_NamedShape)::DownCast (Att)->myNode;
887   }
888   else {
889     myNode = 0L;
890 #ifdef OCCT_DEBUG
891     cout <<"TNaming_Iterator : No Shape for this label"<<endl;
892 #endif
893   }
894 }
895
896 //=======================================================================
897 //function : Next
898 //purpose  : 
899 //=======================================================================
900
901 void TNaming_Iterator::Next() 
902 {
903   Standard_NoMoreObject_Raise_if(myNode == 0L,
904                                  "TNaming_Iterator::Next");
905   myNode = myNode->nextSameAttribute;   
906 }
907
908 //=======================================================================
909 //function : OldShape
910 //purpose  : 
911 //=======================================================================
912
913 const TopoDS_Shape& TNaming_Iterator::OldShape() const 
914 {  
915   Standard_NoSuchObject_Raise_if(myNode == 0L,
916                                  "TNaming_Iterator::OldShape");
917   if (myNode->myOld == 0L) {
918     static TopoDS_Shape NullShape;
919     return NullShape;
920   }
921   return myNode->myOld->Shape();
922 }
923
924 //=======================================================================
925 //function : NewShape
926 //purpose  : 
927 //=======================================================================
928
929 const TopoDS_Shape& TNaming_Iterator::NewShape() const 
930 {
931   Standard_NoSuchObject_Raise_if(myNode == 0L,
932                                  "TNaming_Iterator::NewShape");
933   if (myNode->myNew == 0L) {
934     static TopoDS_Shape NullShape;
935     return NullShape;
936   }
937   return myNode->myNew->Shape();
938 }
939
940
941 //=======================================================================
942 //function : IsModification
943 //purpose  : 
944 //=======================================================================
945
946 Standard_Boolean TNaming_Iterator::IsModification() const
947 {
948   Standard_NoSuchObject_Raise_if(myNode == 0L,
949                                  "TNaming_Iterator::IsModification");
950   return (myNode->myAtt->myEvolution == TNaming_MODIFY || 
951           myNode->myAtt->myEvolution == TNaming_DELETE );
952 }
953
954 //=======================================================================
955 //function : Evolution
956 //purpose  : 
957 //=======================================================================
958
959 TNaming_Evolution  TNaming_Iterator::Evolution() const
960 {
961   Standard_NoSuchObject_Raise_if(myNode == 0L,
962                                  "TNaming_Iterator::IsModification");
963   return myNode->myAtt->myEvolution;
964 }
965
966
967
968 //**********************************************************************
969 //Methods of the TNaming_NewShapeIterator class
970 //**********************************************************************
971
972 //=======================================================================
973 //function : SelectSameShape
974 //purpose  : Selectionne le prochain noeud ou le shape est le meme que celui
975 //           de RS. Old = 0 si il doit etre new dans le noeud a chercher.
976 //           selection dans la transaction valide.
977 //           On saute aussi les noeud ou OS = NS;
978 //=======================================================================
979
980 static void SelectSameShape (TNaming_Node*&          myNode,
981                              Standard_Boolean        Old,
982                              TNaming_RefShape*&      RS,
983                              const Standard_Integer& Trans)
984 {
985   TNaming_Node* pdn = myNode;
986   
987   while (pdn != 0L) {
988     Standard_Boolean Valid;
989     if (Trans < 0) Valid = pdn->myAtt->IsValid(); 
990     else Valid = pdn->IsValidInTrans(Trans);
991
992     if (Valid)
993     {
994       if (Old) {
995         if( pdn->myOld == RS && pdn->myNew != 0L && pdn->myNew != RS) {
996           break;
997         }  
998       }
999       else {
1000         if( pdn->myNew == RS && pdn->myOld != 0L && pdn->myOld != RS) {
1001           break;
1002         }
1003       }
1004     }
1005     pdn = pdn->NextSameShape(RS);
1006   }
1007   myNode = pdn;
1008 }  
1009
1010 //=======================================================================
1011 //function : TNaming_NewShapeIterator
1012 //purpose  : 
1013 //=======================================================================
1014
1015 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1016 (const TopoDS_Shape&               aShape,
1017  const Standard_Integer            Trans,
1018  const Handle(TNaming_UsedShapes)& Shapes)
1019 :myTrans(Trans)
1020
1021   Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1022                                      "TNaming_NewShapeIterator::TNaming_NewShapeIterator aShape");  
1023   TNaming_RefShape* RS = Shapes->Map().ChangeFind(aShape);  
1024   myNode = RS->FirstUse();
1025   Standard_Boolean  Old(Standard_True); 
1026   SelectSameShape(myNode,Old,RS,myTrans);
1027 }
1028
1029 //=======================================================================
1030 //function : TNaming_NewShapeIterator
1031 //purpose  : 
1032 //=======================================================================
1033
1034 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1035 (const TopoDS_Shape&               aShape,
1036  const Standard_Integer            Trans,
1037  const TDF_Label&                  access)
1038 :myTrans(Trans)
1039 {  
1040   Handle(TNaming_UsedShapes) Shapes;
1041   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {    
1042         Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1043                                            "TNaming_NewShapeIterator::TNaming_NewShapeIterator aShape");
1044     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);   
1045     myNode = RS->FirstUse();
1046         Standard_Boolean  Old(Standard_True);
1047     SelectSameShape(myNode,Old,RS,myTrans);
1048   }
1049 }
1050
1051 //=======================================================================
1052 //function : TNaming_NewShapeIterator
1053 //purpose  : 
1054 //=======================================================================
1055
1056 TNaming_NewShapeIterator::TNaming_NewShapeIterator (const TNaming_Iterator& anIterator)
1057 :myTrans(anIterator.myTrans)
1058 {
1059   Standard_NoSuchObject_Raise_if(anIterator.myNode == 0L,
1060                                  "TNaming_NewShapeIterator::TNaming_NewShapeIterator");
1061   myNode = anIterator.myNode;  
1062   TNaming_RefShape* RS = myNode->myNew;
1063   if (RS == 0L) 
1064     myNode = 0L;  // No descendant
1065   else {    
1066     // il faut repartir de la premiere utilisation.
1067     myNode = RS->FirstUse();
1068         Standard_Boolean Old(Standard_True);  
1069     SelectSameShape(myNode,Old,RS,myTrans);
1070   }
1071 }
1072
1073 //=======================================================================
1074 //function : TNaming_NewShapeIterator
1075 //purpose  : 
1076 //=======================================================================
1077
1078 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1079 (const TopoDS_Shape&               aShape,
1080  const Handle(TNaming_UsedShapes)& Shapes)
1081 :myTrans(-1)
1082 {
1083   Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1084                                          "TNaming_NewShapeIterator::TNaming_NewShapeIterator aShape");
1085   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1086   myNode = RS->FirstUse();
1087    Standard_Boolean  Old(Standard_True);  
1088   SelectSameShape(myNode,Old,RS,myTrans);
1089 }
1090
1091 //=======================================================================
1092 //function : TNaming_NewShapeIterator
1093 //purpose  : 
1094 //=======================================================================
1095
1096 TNaming_NewShapeIterator::TNaming_NewShapeIterator
1097 (const TopoDS_Shape& aShape,
1098  const TDF_Label&    access)
1099 :myTrans(-1)
1100 {
1101   Handle(TNaming_UsedShapes) Shapes;
1102   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {
1103     Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1104                                            "TNaming_NewShapeIterator::TNaming_NewShapeIterator aShape");
1105     Standard_Boolean  Old(Standard_True);  
1106     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);   
1107     myNode = RS->FirstUse();
1108     SelectSameShape(myNode,Old,RS,myTrans);
1109   }
1110 }
1111
1112 //=======================================================================
1113 //function : TNaming_NewShapeIterator
1114 //purpose  : 
1115 //=======================================================================
1116
1117 TNaming_NewShapeIterator::TNaming_NewShapeIterator(const TNaming_NewShapeIterator& anIterator)
1118 :myTrans(anIterator.myTrans)
1119 {
1120   Standard_NoSuchObject_Raise_if(anIterator.myNode == 0L,
1121                                  "TNaming_NewShapeIterator::TNaming_NewShapeIterator");
1122   myNode = anIterator.myNode;
1123   TNaming_RefShape* RS = myNode->myNew;
1124   if (RS == 0L) 
1125     myNode = 0L;  // No descendant
1126   else  {
1127     // il faut repartir de la premiere utilisation.
1128     myNode = RS->FirstUse();
1129         Standard_Boolean Old(Standard_True);
1130     SelectSameShape(myNode,Old,RS,myTrans);
1131   }
1132 }
1133
1134 //=======================================================================
1135 //function : Next
1136 //purpose  : 
1137 //=======================================================================
1138
1139 void TNaming_NewShapeIterator::Next() 
1140 {
1141   TNaming_RefShape* RS  = myNode->myOld;
1142   myNode = myNode->NextSameShape(RS);
1143   Standard_Boolean  Old(Standard_True);
1144   SelectSameShape(myNode,Old,RS,myTrans);
1145 }
1146
1147 //=======================================================================
1148 //function : Label
1149 //purpose  : 
1150 //=======================================================================
1151
1152 TDF_Label TNaming_NewShapeIterator::Label() const
1153 {  
1154   Standard_NoSuchObject_Raise_if(myNode == 0L,
1155                                  "TNaming_NewShapeIterator::Label");
1156   return myNode->Label();
1157 }
1158
1159 //=======================================================================
1160 //function : NamedShape
1161 //purpose  : 
1162 //=======================================================================
1163
1164 Handle(TNaming_NamedShape) TNaming_NewShapeIterator::NamedShape() const
1165 {  
1166   Standard_NoSuchObject_Raise_if(myNode == 0L,
1167                                  "TNaming_NewShapeIterator::Label");
1168   return myNode->myAtt;
1169 }
1170
1171 //=======================================================================
1172 //function : Shape
1173 //purpose  : 
1174 //=======================================================================
1175
1176 const TopoDS_Shape& TNaming_NewShapeIterator::Shape() const
1177 {
1178   Standard_NoSuchObject_Raise_if(myNode == 0L,
1179                                  "TNaming_NewShapeIterator::Shape"); 
1180   return myNode->myNew->Shape();
1181 }
1182
1183 //=======================================================================
1184 //function : IsModification
1185 //purpose  : 
1186 //=======================================================================
1187
1188 Standard_Boolean TNaming_NewShapeIterator::IsModification() const
1189 {  
1190   Standard_NoSuchObject_Raise_if(myNode == 0L,
1191                                  "TNaming_NewShapeIterator::IsModification");
1192
1193   return (myNode->myAtt->myEvolution == TNaming_MODIFY || 
1194           myNode->myAtt->myEvolution == TNaming_DELETE );
1195 }
1196
1197 //**********************************************************************
1198 //Methods of the TNaming_OldShapeIterator class
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 Handle(TNaming_UsedShapes)& Shapes)
1209 :myTrans(Trans)
1210 {
1211   Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1212                                          "TNaming_OldShapeIterator::TNaming_OldShapeIterator aShape");
1213   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1214   myNode = RS->FirstUse();
1215   Standard_Boolean  Old(Standard_False);
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 Standard_Integer Trans,
1227  const TDF_Label& access)
1228 :myTrans(Trans)
1229 {
1230   Handle(TNaming_UsedShapes) Shapes;
1231   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {
1232         Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1233                                            "TNaming_OldShapeIterator::TNaming_OldShapeIterator aShape");    
1234     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1235     myNode = RS->FirstUse();
1236         Standard_Boolean  Old(Standard_False);
1237     SelectSameShape(myNode,Old,RS,myTrans);
1238   }
1239 }
1240 //=======================================================================
1241 //function : TNaming_OldShapeIterator
1242 //purpose  : 
1243 //=======================================================================
1244
1245 TNaming_OldShapeIterator::TNaming_OldShapeIterator
1246 (const TopoDS_Shape&               aShape,
1247  const Handle(TNaming_UsedShapes)& Shapes)
1248 :myTrans(-1)
1249 {  
1250   Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1251                                          "TNaming_OldShapeIterator::TNaming_OldShapeIterator aShape"); 
1252   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1253   myNode = RS->FirstUse();
1254   Standard_Boolean  Old(Standard_False);
1255   SelectSameShape(myNode,Old,RS,myTrans);
1256 }
1257
1258 //=======================================================================
1259 //function : TNaming_OldShapeIterator
1260 //purpose  : 
1261 //=======================================================================
1262
1263 TNaming_OldShapeIterator::TNaming_OldShapeIterator
1264 (const TopoDS_Shape& aShape,
1265  const TDF_Label& access)
1266 :myTrans(-1)
1267 {  
1268   Handle(TNaming_UsedShapes) Shapes;
1269   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) {
1270     Standard_NoSuchObject_Raise_if(!Shapes->Map().IsBound(aShape), 
1271                                            "TNaming_OldShapeIterator::TNaming_OldShapeIterator aShape"); 
1272     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1273     myNode = RS->FirstUse();
1274         Standard_Boolean  Old(Standard_False);
1275     SelectSameShape(myNode,Old,RS,myTrans);
1276   }
1277 }
1278
1279 //=======================================================================
1280 //function : TNaming_OldShapeIterator
1281 //purpose  : 
1282 //=======================================================================
1283
1284 TNaming_OldShapeIterator::TNaming_OldShapeIterator (const TNaming_Iterator& anIterator)
1285 :myTrans(anIterator.myTrans)
1286 {
1287   Standard_NoSuchObject_Raise_if(anIterator.myNode == 0L,
1288                                                  "TNaming_OldShapeIterator::TNaming_OldShapeIterator");
1289   myNode = anIterator.myNode; 
1290   TNaming_RefShape* RS = myNode->myNew;
1291   if (RS == 0L) 
1292     myNode = 0L;  // No descendant
1293   else {    
1294     // il faut repartir de la premiere utilisation.
1295     myNode = RS->FirstUse();
1296         Standard_Boolean Old(Standard_False);  
1297     SelectSameShape(myNode,Old,RS,myTrans);
1298   }
1299 }
1300
1301 //=======================================================================
1302 //function : TNaming_OldShapeIterator
1303 //purpose  : 
1304 //=======================================================================
1305
1306 TNaming_OldShapeIterator::TNaming_OldShapeIterator(const TNaming_OldShapeIterator& anIterator)
1307 :myTrans(anIterator.myTrans)
1308 {
1309   Standard_NoSuchObject_Raise_if(anIterator.myNode == 0L,
1310                                                  "TNaming_OldShapeIterator::TNaming_OldShapeIterator");
1311   myNode = anIterator.myNode;  
1312   TNaming_RefShape* RS = myNode->myOld;
1313   if (RS == 0L) 
1314     myNode = 0L;  // No descendant
1315   else  {
1316     // il faut repartir de la premiere utilisation.
1317     myNode = RS->FirstUse();
1318         Standard_Boolean Old(Standard_False);  
1319     SelectSameShape(myNode,Old,RS,myTrans);
1320   }
1321 }
1322
1323 //=======================================================================
1324 //function : Next
1325 //purpose  : 
1326 //=======================================================================
1327
1328 void TNaming_OldShapeIterator::Next() 
1329 {
1330   Standard_Boolean  Old = Standard_False;  
1331   TNaming_RefShape* RS  = myNode->myNew;
1332   myNode = myNode->NextSameShape(RS);
1333   SelectSameShape(myNode,Old,RS,myTrans);
1334 }
1335
1336 //=======================================================================
1337 //function : Label
1338 //purpose  : 
1339 //=======================================================================
1340
1341 TDF_Label TNaming_OldShapeIterator::Label() const
1342 {  
1343   if (myNode == 0L) throw Standard_NoSuchObject("TNaming_OldShapeIterator::Label");
1344   return myNode->Label();
1345   
1346 }
1347
1348 //=======================================================================
1349 //function : NamedShape
1350 //purpose  : 
1351 //=======================================================================
1352
1353 Handle(TNaming_NamedShape) TNaming_OldShapeIterator::NamedShape() const
1354 {  
1355   if (myNode == 0L) throw Standard_NoSuchObject("TNaming_OldShapeIterator::Label");
1356   return myNode->myAtt;
1357 }
1358 //=======================================================================
1359 //function : Shape
1360 //purpose  : 
1361 //=======================================================================
1362
1363 const TopoDS_Shape& TNaming_OldShapeIterator::Shape() const
1364 {   
1365   if(myNode == 0L) throw Standard_NoSuchObject("TNaming_OldShapeIterator::Shape");
1366   return myNode->myOld->Shape();
1367 }
1368
1369 //=======================================================================
1370 //function : IsModification
1371 //purpose  : 
1372 //=======================================================================
1373
1374 Standard_Boolean TNaming_OldShapeIterator::IsModification() const
1375 {  
1376   Standard_NoSuchObject_Raise_if(myNode == 0L,
1377                                  "TNaming_OldShapeIterator::IsModification");  
1378   return (myNode->myAtt->myEvolution == TNaming_MODIFY || 
1379           myNode->myAtt->myEvolution == TNaming_DELETE );
1380 }
1381
1382
1383 //**********************************************************************
1384 //Methods of the SameShapeIterator
1385 //**********************************************************************
1386
1387 //=======================================================================
1388 //function : 
1389 //purpose  : 
1390 //=======================================================================
1391
1392 TNaming_SameShapeIterator::TNaming_SameShapeIterator
1393 (const TopoDS_Shape& aShape,
1394  const Handle(TNaming_UsedShapes)& Shapes)
1395 {
1396   TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1397   myNode  = RS->FirstUse();
1398   myIsNew = (myNode->myNew == RS);
1399 }
1400
1401
1402 //=======================================================================
1403 //function : TNaming_SameShapeIterator
1404 //purpose  : 
1405 //=======================================================================
1406
1407 TNaming_SameShapeIterator::TNaming_SameShapeIterator
1408 (const TopoDS_Shape& aShape,
1409  const TDF_Label& access)
1410 {  
1411   Handle(TNaming_UsedShapes) Shapes;
1412   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),Shapes)) { 
1413     TNaming_RefShape* RS  = Shapes->Map().ChangeFind(aShape);
1414     myNode  = RS->FirstUse();
1415     myIsNew = (myNode->myNew == RS);
1416   }
1417 }
1418
1419 //=======================================================================
1420 //function : Next
1421 //purpose  : 
1422 //=======================================================================
1423
1424 void TNaming_SameShapeIterator::Next() 
1425 {
1426   TNaming_RefShape* prs;
1427   if (myIsNew) prs = myNode->myNew; else prs = myNode->myOld;
1428   
1429   myNode = myNode->NextSameShape(prs);
1430   if (myNode != 0L) myIsNew = (myNode->myNew == prs);
1431 }
1432
1433 //=======================================================================
1434 //function : Label
1435 //purpose  : 
1436 //=======================================================================
1437
1438 TDF_Label TNaming_SameShapeIterator::Label() const
1439 {  
1440   Standard_NoSuchObject_Raise_if(myNode == 0L,
1441                                  "TNaming_SameShapeIterator::Label");
1442   return myNode->Label();
1443 }
1444
1445
1446 //**********************************************************************
1447 //Methods of the TNaming_RefShape
1448 //**********************************************************************
1449 //=======================================================================
1450 //function : Label
1451 //purpose  : 
1452 //=======================================================================
1453
1454 TDF_Label TNaming_RefShape::Label() const
1455 {
1456   return myFirstUse->myAtt->Label();
1457 }
1458
1459 //=======================================================================
1460 //function : NamedShape
1461 //purpose  : 
1462 //=======================================================================
1463
1464 Handle(TNaming_NamedShape) TNaming_RefShape::NamedShape() const
1465 {
1466   return myFirstUse->myAtt;
1467 }
1468
1469
1470 //**********************************************************************
1471 //Methods of the TNaming_Tool class
1472 //**********************************************************************
1473
1474 //=======================================================================
1475 //function : HasLabel
1476 //purpose  : 
1477 //=======================================================================
1478
1479 Standard_Boolean TNaming_Tool::HasLabel (const TDF_Label&    access,
1480                                          const TopoDS_Shape& S)
1481 {
1482   Handle(TNaming_UsedShapes) US;
1483   if (access.Root().FindAttribute(TNaming_UsedShapes::GetID(),US)) {
1484     return (US->Map().IsBound(S));
1485   }
1486 #ifdef OCCT_DEBUG_HASL
1487   cout << "##==> Sub-Shape has no Label!" <<endl;
1488 #endif
1489   return Standard_False;
1490 }
1491
1492
1493 //=======================================================================
1494 //function : Label
1495 //purpose  : 
1496 //=======================================================================
1497
1498 TDF_Label TNaming_Tool::Label(const TDF_Label&    access,
1499                               const TopoDS_Shape& S,
1500                               Standard_Integer&   Trans)
1501
1502   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(access,S),"TNaming_Tool::Label"); 
1503   Handle(TNaming_UsedShapes) US;
1504   access.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
1505   return TNaming_Tool::Label(US,S,Trans);
1506 }
1507
1508
1509 //=======================================================================
1510 //function : IsValidInTrans
1511 //purpose  : un shape est valid tant que l attribut ou il est cree est valid 
1512 //=======================================================================
1513
1514 Standard_Integer TNaming_Tool::ValidUntil (const TDF_Label& access, const TopoDS_Shape& S)
1515 {  
1516   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(access,S),"TNaming_Tool::ValidUntil"); 
1517   Handle(TNaming_UsedShapes) US;
1518   access.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
1519   return TNaming_Tool::ValidUntil(S,US);
1520 }
1521  
1522
1523 //=======================================================================
1524 //function : HasLabel
1525 //purpose  : 
1526 //=======================================================================
1527
1528 Standard_Boolean TNaming_Tool::HasLabel(const Handle(TNaming_UsedShapes)& Shapes,
1529                                         const TopoDS_Shape&               S)
1530 {
1531   return (Shapes->Map().IsBound(S));
1532 }
1533
1534
1535 //=======================================================================
1536 //function : Label
1537 //purpose  : 
1538 //=======================================================================
1539
1540 TDF_Label TNaming_Tool::Label(const Handle(TNaming_UsedShapes)& Shapes,
1541                               const TopoDS_Shape&               S,
1542                               Standard_Integer&                 Trans)
1543 {
1544   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(Shapes,S),"TNaming_Tool::Label");
1545   TNaming_RefShape* prs = Shapes->Map().Find(S);
1546   TNaming_Node*     pdn = prs->FirstUse();
1547
1548   while (pdn != 0L && !(pdn->myNew == prs && pdn->myAtt->Evolution() != TNaming_SELECTED)){
1549     pdn = pdn->NextSameShape(prs);
1550   }
1551   if (pdn == 0L) pdn = prs->FirstUse();
1552
1553   TDF_Label      L   = pdn->Label();
1554   Trans = pdn->myAtt->Transaction();
1555   return L;
1556 }
1557 //=======================================================================
1558 //function : NamedShape
1559 //purpose  : 
1560 //=======================================================================
1561 Handle(TNaming_NamedShape) TNaming_Tool::NamedShape(const TopoDS_Shape& S,
1562                                                     const TDF_Label&    Acces) 
1563
1564   Handle(TNaming_UsedShapes) US;
1565   Acces.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
1566   Handle(TNaming_NamedShape) NS;
1567   
1568   if(!TNaming_Tool::HasLabel(US,S)) {
1569     return NS;
1570   }
1571   
1572   TNaming_RefShape* prs = US->Map().Find(S);
1573   TNaming_Node*     pdn = prs->FirstUse();
1574   TNaming_Node*     res = 0L;
1575
1576   while (pdn != 0L) {
1577     if (pdn->myNew == prs && pdn->myAtt->Evolution() != TNaming_SELECTED) {
1578       res = pdn;
1579       if (pdn->myAtt->Evolution() != TNaming_GENERATED) {
1580         // Les modifications sont privilegiees par rapport au generation.
1581         // Dans le cas des shapes qui sont a la fois des modifications et des generations
1582         // faces tangentes.
1583         break;
1584       }
1585     }
1586     pdn = pdn->NextSameShape(prs);
1587   }
1588   
1589   if (res == 0L) return NS;
1590
1591   // VERUE EN ATTENDANT DE REVOIR ABORT 03/11/98
1592   // Protection pour eviter de renvoyer un attribut backuped
1593   TDF_Label Lab = res->Label();
1594   Lab.FindAttribute(TNaming_NamedShape::GetID(),NS);
1595   return NS;
1596   //  return res->myAtt;
1597
1598
1599 //=======================================================================
1600 //function : IsValidInTrans
1601 //purpose  : un shape est valid tant que l attribut ou il est cree est valid 
1602 //=======================================================================
1603
1604 Standard_Integer TNaming_Tool::ValidUntil (const TopoDS_Shape&               S,
1605                                            const Handle(TNaming_UsedShapes)& US)
1606 {  
1607   Standard_NoSuchObject_Raise_if(!TNaming_Tool::HasLabel(US,S),"TNaming_Tool::ValidUntil"); 
1608   
1609   TNaming_RefShape* RS  = US->Map().ChangeFind(S);
1610   Standard_Integer  Cur;
1611   Standard_Integer  Until  = 0;  
1612   TNaming_Node*     Node   = RS->FirstUse();
1613
1614   while (Node != 0L) {
1615     if (Node->myNew != 0L && Node->myNew == RS) {
1616       Cur    = Node->myAtt->UntilTransaction();
1617       if (Cur > Until) Until = Cur;
1618     }
1619     Node = Node->NextSameShape(RS);
1620   }
1621   return Until;
1622 }