0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / TNaming / TNaming.cxx
1 // Created on: 1998-01-20
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1997-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 <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepBuilderAPI_Transform.hxx>
21 #include <BRepClass3d_SolidClassifier.hxx>
22 #include <gp_Trsf.hxx>
23 #include <IntTools_FClass2d.hxx>
24 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
25 #include <TDF_ChildIterator.hxx>
26 #include <TDF_Label.hxx>
27 #include <TNaming.hxx>
28 #include <TNaming_Builder.hxx>
29 #include <TNaming_DataMapOfShapePtrRefShape.hxx>
30 #include <TNaming_Iterator.hxx>
31 #include <TNaming_ListIteratorOfListOfNamedShape.hxx>
32 #include <TNaming_ListOfNamedShape.hxx>
33 #include <TNaming_NamedShape.hxx>
34 #include <TNaming_NewShapeIterator.hxx>
35 #include <TNaming_RefShape.hxx>
36 #include <TNaming_ShapesSet.hxx>
37 #include <TNaming_Tool.hxx>
38 #include <TNaming_TranslateTool.hxx>
39 #include <TNaming_UsedShapes.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <TopLoc_Datum3D.hxx>
42 #include <TopLoc_Location.hxx>
43 #include <TopoDS.hxx>
44 #include <TopoDS_Compound.hxx>
45 #include <TopoDS_Face.hxx>
46 #include <TopoDS_Iterator.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Shell.hxx>
49 #include <TopoDS_Solid.hxx>
50 #include <TopoDS_Wire.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfOrientedShapeShape.hxx>
52 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
53 #include <TopTools_DataMapOfOrientedShapeShape.hxx>
54 #include <TopTools_DataMapOfShapeShape.hxx>
55 #include <TopTools_ListIteratorOfListOfShape.hxx>
56 #include <TopTools_ListOfShape.hxx>
57 #include <TopTools_MapIteratorOfMapOfShape.hxx>
58 #include <TopTools_MapOfShape.hxx>
59
60 // CopyShape
61 //=======================================================================
62 //function : MapShapes
63 //purpose  : TNaming
64 //=======================================================================
65 static void MapShapes(const TopoDS_Shape& SCible, const TopoDS_Shape& SSource, TopTools_DataMapOfShapeShape& M)
66 {
67   M.Bind(SCible,SSource);
68   TopoDS_Iterator icible(SCible);
69   TopoDS_Iterator isource(SSource);
70   while (icible.More()) {
71     if (!M.IsBound(icible.Value())) MapShapes(icible.Value(),isource.Value(),M);
72     icible.Next();
73     isource.Next();
74   }
75 }
76
77 //=======================================================================
78 //function : MapShapes
79 //purpose  : TNaming
80 //=======================================================================
81
82 static void MapShapes(const TDF_Label& LCible, const TDF_Label& LSource, TopTools_DataMapOfShapeShape& M)
83 {
84   TNaming_Iterator icible(LCible);
85   TNaming_Iterator isource(LSource);
86   while (icible.More()) {
87     if (!icible.OldShape().IsNull()) {
88       if (!M.IsBound(icible.OldShape())) MapShapes(icible.OldShape(),isource.OldShape(),M);
89     }
90     if (!icible.NewShape().IsNull()) {
91       if (!M.IsBound(icible.NewShape())) MapShapes(icible.NewShape(),isource.NewShape(),M);
92     }
93     icible.Next();
94     isource.Next();
95   }
96
97   TDF_ChildIterator iccible(LCible);
98   TDF_ChildIterator icsource(LSource);
99   while (iccible.More()) {
100     MapShapes(iccible.Value(),icsource.Value(),M);
101     iccible.Next();
102     icsource.Next();
103   }
104
105
106 //=======================================================================
107 //function : SubstituteShape
108 //purpose  : TNaming
109 //=======================================================================
110
111 static void SubstituteShape(const TopoDS_Shape& oldShape,
112                             const TopoDS_Shape& newShape,
113                             TNaming_DataMapOfShapePtrRefShape& amap) 
114 {
115   if (oldShape.IsSame(newShape)) {
116     cout <<"import_tool::Substitute : oldShape IsSame newShape"<<endl;
117   }
118
119   if (!amap.IsBound(oldShape)) {
120       return;
121   }
122   TNaming_RefShape* pos;
123   pos = amap.ChangeFind(oldShape);
124   pos->Shape(newShape);
125   amap.UnBind(oldShape);
126   amap.Bind(newShape,pos);
127 }
128
129 //=======================================================================
130 //function : MakeShape
131 //purpose  : ANaming 
132 //=======================================================================
133
134 TopoDS_Shape TNaming::MakeShape (const TopTools_MapOfShape& MS) 
135 {  
136   if (!MS.IsEmpty ()) {
137     TopTools_MapIteratorOfMapOfShape it(MS);
138     if (MS.Extent() == 1) {
139       return it.Key();
140     }
141     else {
142       TopoDS_Compound C;
143       BRep_Builder B;
144       B.MakeCompound(C);
145       for (; it.More(); it.Next()){ 
146         B.Add(C,it.Key());
147       }
148       return C;
149     }
150   }
151   return TopoDS_Shape();  
152 }
153
154 //=======================================================================
155 //function : Substitute
156 //purpose  : TNaming
157 //=======================================================================
158
159 void TNaming::Substitute(const TDF_Label& LSource, 
160                          const TDF_Label& LCible ,
161                          TopTools_DataMapOfShapeShape&  M) 
162 {
163 //attention pour etre en parallele au niveau structure il faut que Lciblble corresponde au premier fils recopie
164   MapShapes(LCible,LSource,M);
165   Handle(TNaming_UsedShapes) US;
166   LCible.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
167   TNaming_DataMapOfShapePtrRefShape& amap = US->Map();
168   for (TopTools_DataMapIteratorOfDataMapOfShapeShape It(M);It.More();It.Next()) {
169     SubstituteShape(It.Key(),It.Value(),amap);
170  }   
171 }  
172
173 //=======================================================================
174 //function : SubstituteSShape
175 //purpose  : 
176 //=======================================================================
177 Standard_Boolean TNaming::SubstituteSShape(const TDF_Label& Lab, const TopoDS_Shape& From, TopoDS_Shape& To)
178 {
179   Handle(TNaming_UsedShapes) US;
180   Lab.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
181   TNaming_DataMapOfShapePtrRefShape& amap = US->Map();
182   if (!amap.IsBound(To)) 
183     return Standard_False;
184   TNaming_RefShape* pos;
185   pos = amap.ChangeFind(To);
186   if(!amap.UnBind(To)) return Standard_False;
187   //update shape
188   To.Orientation(From.Orientation());
189   pos->Shape(To);
190   return amap.Bind(To, pos);
191 }
192
193 //=======================================================================
194 //function : Rebuild
195 //purpose  : TNaming
196 //=======================================================================
197
198 static Standard_Boolean  Rebuild (const TopoDS_Shape& S,
199                                   TopTools_DataMapOfShapeShape&  M)
200 {
201   Standard_Boolean IsModified = Standard_False;
202   if (M.IsBound(S)) return IsModified;
203   
204   BRep_Builder     B;
205   TopoDS_Iterator  iteS (S.Oriented(TopAbs_FORWARD));
206   
207   // Reconstruction des sous shapes si necessaire.
208   for (; iteS.More(); iteS.Next()) {
209     const TopoDS_Shape& SS = iteS.Value();
210     if (Rebuild (SS,M)) IsModified = Standard_True;
211   }
212   if (!IsModified) {
213     M.Bind(S,S);
214     return Standard_True;
215   }
216
217   // Reconstruction de S
218   TopoDS_Shape NewS = S.Oriented(TopAbs_FORWARD);
219   NewS.EmptyCopy();
220   if (NewS.ShapeType() == TopAbs_EDGE) {
221     Standard_Real f,l;
222     BRep_Tool::Range(TopoDS::Edge(S),f,l);
223     B.Range(TopoDS::Edge(NewS),f,l);
224   }
225   iteS.Initialize(S.Oriented(TopAbs_FORWARD));
226   for (iteS.Initialize(S.Oriented(TopAbs_FORWARD)) ;iteS.More(); iteS.Next()) { 
227     const TopoDS_Shape& OS = iteS.Value();
228     const TopoDS_Shape& NS = M(OS);
229     B.Add(NewS,NS.Oriented(OS.Orientation()));
230   }
231   M.Bind (S,NewS.Oriented(S.Orientation()));
232   return IsModified;
233 }
234
235
236 //=======================================================================
237 //function : Update
238 //purpose  : TNaming
239 //=======================================================================
240
241 void TNaming::Update(const TDF_Label& L,
242                      TopTools_DataMapOfShapeShape& M)
243
244 {
245   //Reconstruction des shapes de L suite aux substitutions decrites dans la map M.
246   // ex : si une face est remplacee par une autre il faut reconstruire les shapes
247   //      qui contiennent cette face.
248   Handle(TNaming_UsedShapes) US;
249   L.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
250   TNaming_DataMapOfShapePtrRefShape& amap = US->Map();
251
252   for (TNaming_Iterator it(L); it.More(); it.Next()) {
253     if (!it.OldShape().IsNull()) {
254       const TopoDS_Shape& S = it.OldShape();
255       if (!M.IsBound(S))
256         Rebuild (S,M);
257       SubstituteShape(S,M(S),amap);
258     }
259     if (!it.NewShape().IsNull()) {
260       const TopoDS_Shape& S = it.NewShape();
261       if (!M.IsBound(S)) 
262         Rebuild (S,M);
263       SubstituteShape(S,M(S),amap);
264     }
265   }
266
267   // SI Les shapes dans les sous-labels sont des sous shapes des shapes de L
268   // si les shapes de L n ont pas changes les shapes des sous-labels ne seront 
269   // pas changes non plus.
270   for (TDF_ChildIterator ciL(L); ciL.More(); ciL.Next()) {
271     TNaming::Update (ciL.Value(),M);
272   }
273 }
274
275 //=======================================================================
276 //function : BuilCompound
277 //purpose  : TNaming
278 //=======================================================================
279
280 static void BuildCompound(TopoDS_Compound& C,
281                           const TDF_Label& L)
282 {
283   BRep_Builder B;
284   for (TNaming_Iterator it(L); it.More(); it.Next()) {
285     if (!it.OldShape().IsNull()) {
286       B.Add(C,it.OldShape());
287     }
288     if (!it.NewShape().IsNull()) {
289       B.Add(C,it.NewShape());
290     }
291   }
292   for (TDF_ChildIterator ciL(L); ciL.More(); ciL.Next()) {
293     BuildCompound (C,ciL.Value());
294   }
295 }
296
297 //=======================================================================
298 //function : Update
299 //purpose  : TNaming
300 //=======================================================================
301
302 static void BuildMap(const TDF_Label& L,
303                      BRepBuilderAPI_Transform& Transformer,
304                      TopTools_DataMapOfShapeShape& M)
305 {                  
306   Handle(TNaming_UsedShapes) US;
307   L.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
308   for (TNaming_Iterator it(L); it.More(); it.Next()) {
309     if (!it.OldShape().IsNull()) {
310       const TopoDS_Shape& S = it.OldShape();
311       M.Bind(S,Transformer.ModifiedShape(S));
312     }
313     if (!it.NewShape().IsNull()) {
314       const TopoDS_Shape& S = it.NewShape();
315       M.Bind(S,Transformer.ModifiedShape(S));
316     }
317   }
318   for (TDF_ChildIterator ciL(L); ciL.More(); ciL.Next()) {
319     BuildMap (ciL.Value(),Transformer,M);
320   }
321 }   
322
323 //=======================================================================
324 //function : LoadNamedShape
325 //purpose  : TNaming
326 //=======================================================================
327
328 static void LoadNamedShape (TNaming_Builder& B, 
329                             TNaming_Evolution Evol, 
330                             const TopoDS_Shape& OS, 
331                             const TopoDS_Shape& NS)
332 {    
333   switch (Evol) {
334   case TNaming_PRIMITIVE :
335     {
336       B.Generated(NS);
337       break;
338     }
339   case TNaming_GENERATED :
340     {
341       B.Generated(OS,NS);
342       break;
343     }
344   case TNaming_MODIFY : 
345     {
346       B.Modify(OS,NS);
347       break;
348     }
349   case TNaming_DELETE : 
350     {
351       B.Delete (OS);
352       break;
353     }
354   case TNaming_SELECTED :
355     {
356       B.Select(NS,OS);
357           break;
358     }
359   default:
360     break;
361   }
362 }
363
364 //=======================================================================
365 //function : Displace
366 //purpose  : TNaming
367 //=======================================================================
368
369 void TNaming::Displace (const TDF_Label& L,
370                         const TopLoc_Location& Loc,
371                         const Standard_Boolean WithOld)
372 {  
373
374
375   TopTools_ListOfShape Olds;
376   TopTools_ListOfShape News;
377   TNaming_Evolution    Evol;
378   TNaming_Iterator     it(L);
379   
380   if (it.More()) {   // dp on continue de visiter les fils meme s'il y a pas de shape
381     Evol = it.Evolution();
382     for ( ; it.More(); it.Next()) {
383       Olds.Append(it.OldShape());
384       News.Append(it.NewShape());
385       
386     }
387     
388     TopTools_ListIteratorOfListOfShape itOlds(Olds);
389     TopTools_ListIteratorOfListOfShape itNews(News);
390     TNaming_Builder B(L);
391     
392     for ( ;itOlds.More() ; itOlds.Next(),itNews.Next()) {
393       TopoDS_Shape OS,NS;
394       const TopoDS_Shape& SO     = itOlds.Value();
395       const TopoDS_Shape& SN     = itNews.Value();
396       OS = SO;
397       if (WithOld && !SO.IsNull()) OS = SO.Moved(Loc);
398       if (!SN.IsNull()) NS = SN.Moved(Loc);
399       
400       LoadNamedShape ( B, Evol, OS, NS);
401     }
402   }
403   for (TDF_ChildIterator ciL(L); ciL.More(); ciL.Next()) {
404     Displace (ciL.Value(), Loc, WithOld);
405   }
406 }
407
408 //=======================================================================
409 //function : Replace
410 //purpose  : TNaming
411 //=======================================================================
412
413 static void Replace (const TDF_Label&                    L,
414                      const TopTools_DataMapOfShapeShape& M)
415 {  
416     
417   TNaming_Evolution    Evol;
418   TNaming_Iterator     it(L);
419   
420   if (!it.More()) return;
421   Evol = it.Evolution();
422
423   TNaming_Builder B(L);
424   
425   TopoDS_Shape OS,NS;
426
427   for ( ; it.More(); it.Next()) {  
428     if (!it.OldShape().IsNull()) {
429       OS = it.OldShape();
430       if (M.IsBound(OS)) OS = M(OS);
431     }
432     if (!it.NewShape().IsNull()) {
433       NS = it.NewShape();
434       if (M.IsBound(NS)) NS = M(NS);
435     }
436     LoadNamedShape ( B, Evol, OS, NS);
437   }
438   for (TDF_ChildIterator ciL(L); ciL.More(); ciL.Next()) {
439     Replace (ciL.Value(),M);
440   }
441 }
442
443 //=======================================================================
444 //function : Update
445 //purpose  : TNaming
446 //=======================================================================
447
448 void TNaming::Transform(const TDF_Label& L,
449                         const gp_Trsf&   T)
450 {
451
452   //--------------------------------------------------------------------
453   // Construction du compound qui contient tous les shapes sous le label
454   // et ses fils.
455   //--------------------------------------------------------------------
456   TopoDS_Compound CompShape;
457   BRep_Builder    B;
458   B.MakeCompound(CompShape);
459
460   BuildCompound (CompShape,L);
461
462   //----------------------------
463   // Transformation du compound.
464   //-----------------------------
465   BRepBuilderAPI_Transform Transformer(CompShape, T);
466
467   //-----------------------------------------------------------
468   //Remplacement des shapes initiaux par les shapes transformes.
469   //-----------------------------------------------------------
470   TopTools_DataMapOfShapeShape M;
471   BuildMap (L,Transformer,M);
472   Replace (L,M);
473 }
474
475 //=======================================================================
476 //function : IDList
477 //purpose  : TNaming
478 //=======================================================================
479
480 void TNaming::IDList(TDF_IDList& anIDList)
481 { anIDList.Append(TNaming_NamedShape::GetID()); }
482
483
484 //=======================================================================
485 //function : Replicate
486 //purpose  : 
487 //=======================================================================
488
489 void TNaming::Replicate(const Handle(TNaming_NamedShape)& NS,
490                         const gp_Trsf& T,
491                         const TDF_Label& L)
492 {
493   TopoDS_Shape SH = TNaming_Tool::CurrentShape(NS);
494   TNaming::Replicate(SH, T, L);
495 }
496
497 //=======================================================================
498 //function : Replicate
499 //purpose  : TNaming
500 //=======================================================================
501
502 void TNaming::Replicate (const TopoDS_Shape& SH,
503                          const gp_Trsf& T,
504                          const TDF_Label& L)
505 {
506   // transform
507   BRepBuilderAPI_Transform opeTrsf(T);
508   if (SH.ShapeType() == TopAbs_FACE || SH.ShapeType() == TopAbs_WIRE ) {  
509     opeTrsf.Perform(SH, Standard_True); // pour le pattern de prism
510   }
511   else {
512     opeTrsf.Perform(SH, Standard_False);
513   }
514   const TopoDS_Shape& newSH = opeTrsf.Shape();
515   //BRepLib::UpdateTolerances(newSH, Standard_True);
516   
517   // principal shape
518
519   TNaming_Builder Builder(L);
520   Builder.Generated(SH, newSH);    
521   
522   // sub shape
523   TopAbs_ShapeEnum SST = TopAbs_FACE;
524   if (SH.ShapeType() == TopAbs_FACE || SH.ShapeType() == TopAbs_WIRE )  
525     SST = TopAbs_EDGE;
526   
527   TNaming_Builder Builder2 (L.FindChild(1,Standard_True)); 
528   for (TopExp_Explorer exp(SH, SST); exp.More(); exp.Next()) {
529     const TopoDS_Shape& oldSubShape = exp.Current();
530     TopoDS_Shape newSubShape = opeTrsf.ModifiedShape(oldSubShape);
531     Builder2.Generated(oldSubShape, newSubShape);
532   }
533 }
534
535
536 //=======================================================================
537 //function : ShapeCopy
538 //purpose  : TNaming
539 //=======================================================================
540
541 static TopoDS_Shape  ShapeCopy(const TopoDS_Shape& S, 
542                                TopTools_DataMapOfShapeShape& M)
543 {
544   if (S.IsNull())   return S;
545   if (M.IsBound(S)) return M(S);
546   //----------------------------
547   //construction de la copie.
548   // 1- copie des sous shapes.
549   // 2- reconstruction du TShape
550   //----------------------------
551   BRep_Builder     B;
552   TopoDS_Iterator  it (S.Oriented(TopAbs_FORWARD));
553
554   for ( ; it.More(); it.Next()) {
555     const TopoDS_Shape& SS    = it.Value();
556     TopoDS_Shape        NewSS = ShapeCopy(SS,M);
557   }
558   TopoDS_Shape NewS = S.Oriented(TopAbs_FORWARD);
559   NewS.EmptyCopy();
560   if (NewS.ShapeType() == TopAbs_EDGE) {
561     Standard_Real f,l;
562     BRep_Tool::Range(TopoDS::Edge(S),f,l);
563     B.Range(TopoDS::Edge(NewS),f,l);
564   }
565   for (it.Initialize(S.Oriented(TopAbs_FORWARD)) ;it.More(); it.Next()) { 
566     const TopoDS_Shape& OS = it.Value();
567     const TopoDS_Shape& NS = M(OS);
568     B.Add(NewS,NS.Oriented(OS.Orientation()));
569   }
570   NewS.Orientation(S.Orientation());
571
572   NewS.Free      (S.Free())      ;NewS.Modified(S.Modified());NewS.Checked (S.Checked());
573   NewS.Orientable(S.Orientable());NewS.Closed  (S.Closed())  ;NewS.Infinite(S.Infinite());  
574   NewS.Convex    (S.Convex());
575
576   M.Bind (S,NewS);
577   return NewS;
578 }
579
580 //=======================================================================
581 //function : ChangeShapes
582 //purpose  : TNaming
583 //=======================================================================
584
585 void TNaming::ChangeShapes(const TDF_Label&              L,
586                            TopTools_DataMapOfShapeShape& M)
587 {
588   TopTools_ListOfShape Olds;
589   TopTools_ListOfShape News;
590
591   Handle(TNaming_NamedShape) NS;
592   L.FindAttribute(TNaming_NamedShape::GetID(),NS);
593
594   if (!NS.IsNull()) {
595     TNaming_Evolution Evol = NS->Evolution();
596     for (TNaming_Iterator it(L); it.More(); it.Next()) { 
597       const TopoDS_Shape& S1 = it.OldShape();
598       const TopoDS_Shape& S2 = it.NewShape();
599       Olds.Append(ShapeCopy(S1,M));News.Append(ShapeCopy(S2,M));
600     }
601
602     TopTools_ListIteratorOfListOfShape itOlds(Olds);
603     TopTools_ListIteratorOfListOfShape itNews(News);
604
605     TNaming_Builder B(L);
606     
607     for ( ;itOlds.More() ; itOlds.Next(),itNews.Next()) {
608       LoadNamedShape ( B, Evol, itOlds.Value(), itNews.Value());
609     }
610   }
611
612   for (TDF_ChildIterator ciL(L); ciL.More(); ciL.Next()) {
613     ChangeShapes (ciL.Value(),M);
614   }
615 }
616
617
618 //=======================================================================
619 //function : 
620 //purpose  : 
621 //=======================================================================
622
623 Standard_OStream& TNaming::Print (const TNaming_Evolution EVOL,  Standard_OStream& s)
624 {
625   switch(EVOL){
626   case TNaming_PRIMITIVE :
627     {
628       s <<"PRIMITIVE"; break;
629     }
630   case TNaming_GENERATED :
631     {
632       s <<"GENERATED"; break;
633     }  
634   case TNaming_MODIFY :
635     {
636       s <<"MODIFY"; break;
637     }
638   case TNaming_DELETE :
639     {
640       s <<"DELETE"; break;
641     }
642   case TNaming_SELECTED :
643     {
644       s <<"SELECTED"; break;
645     }
646     default :
647       s << "UNKNOWN_Evolution"; break;
648     }
649   return s;
650 }
651
652
653
654 //=======================================================================
655 //function : 
656 //purpose  : 
657 //=======================================================================
658
659 Standard_OStream& TNaming::Print (const TNaming_NameType NAME,  Standard_OStream& s)
660 {
661
662   switch (NAME) {
663   case TNaming_UNKNOWN :
664     {
665       s <<"UNKNOWN"; break;
666     }
667   case TNaming_IDENTITY :
668     {
669       s <<"IDENTITY"; break;
670     }
671   case TNaming_MODIFUNTIL :
672     {
673       s <<"MODIFUNTIL"; break;
674     }
675   case TNaming_GENERATION :
676     {
677       s <<"GENERATION"; break;
678     }
679   case TNaming_INTERSECTION :
680     {
681       s <<"INTERSECTION"; break;
682     }
683   case TNaming_UNION:
684     {
685       s <<"UNION"; break;
686     }
687   case TNaming_SUBSTRACTION :
688     {
689       s <<"SUBSTRACTION"; break;
690     }
691   case TNaming_CONSTSHAPE :
692     {
693       s <<"CONSTSHAPE"; break;
694     }
695   case TNaming_FILTERBYNEIGHBOURGS:
696     {
697       s <<"FILTERBYNEIGHBOURGS"; break;
698     }
699   case TNaming_ORIENTATION:
700     {
701       s <<"ORIENTATION"; break;
702     }
703   case TNaming_WIREIN:
704     {
705       s <<"WIREIN"; break;
706     }
707         case TNaming_SHELLIN:
708     {
709       s <<"SHELLIN"; break;
710     }
711     default :
712       {
713         s <<"UNKNOWN_NameType"; break;
714       }
715   } 
716   return s;
717 }
718
719 //=======================================================================
720 //function : Print
721 //purpose  : Prints UsedShapes.
722 //=======================================================================
723
724 Standard_OStream& TNaming::Print (const TDF_Label& ACCESS,  Standard_OStream& s) {
725   Handle(TNaming_UsedShapes) US;
726   if (!ACCESS.Root().FindAttribute(TNaming_UsedShapes::GetID(), US)) {
727 #ifdef OCCT_DEBUG
728     cout<<"TNaming::Print(US): Bad access"<<endl;
729 #endif
730     return s;
731   }
732   return US->Dump(s);
733 }
734
735 //=======================================================================
736 //function : BuildMapIn
737 //purpose  : 
738 //=======================================================================
739 static void BuildMapIn(const TopoDS_Shape& Context, const TopAbs_ShapeEnum StopType, 
740                          TopTools_DataMapOfOrientedShapeShape& Map)
741 {
742   TopAbs_ShapeEnum aType;     
743   if((Context.ShapeType() == TopAbs_SOLID || Context.ShapeType() == TopAbs_FACE) && (StopType - Context.ShapeType()) != 1)
744     aType = (TopAbs_ShapeEnum)(Context.ShapeType() +2);
745   else
746     aType = (TopAbs_ShapeEnum)(Context.ShapeType()+1);
747   for (TopExp_Explorer exp(Context,aType); exp.More(); exp.Next()) {
748 #ifdef OCCT_DEBUG
749     if(!Map.Bind(exp.Current(), Context))
750       cout << "Not bind = " <<exp.Current().ShapeType() <<endl; 
751     else 
752       cout <<"Bind = " <<exp.Current().ShapeType() << " to Context = " <<Context.ShapeType()<<endl;
753 #else
754     Map.Bind(exp.Current(), Context);
755 #endif
756     if(exp.Current().ShapeType() < StopType ) {
757       BuildMapIn(exp.Current(), StopType, Map);
758     }
759   }
760   // fix for NMT case
761   if(Context.ShapeType() < StopType) {
762     TopoDS_Iterator it(Context);
763     for(;it.More();it.Next()) {
764       if(it.Value().Orientation() != TopAbs_FORWARD && it.Value().Orientation() != TopAbs_REVERSED) {
765         Map.Bind(it.Value(), Context);
766         //cout << "INTERNAL || EXTERNAL Orientation found" <<endl;
767       }
768     }
769   }
770 }
771 //=======================================================================
772 //function : BuildMapC0
773 //purpose  : builds data map: key - context, C0 - top context
774 //=======================================================================
775 static void BuildMapC0(const TopoDS_Shape& Context, const TopoDS_Shape& C0, const TopAbs_ShapeEnum StopType, 
776                      TopTools_DataMapOfOrientedShapeShape& Map)
777 {
778   TopoDS_Iterator anIt(Context);
779   while(anIt.More()) {
780     const TopoDS_Shape& aKey = anIt.Value();
781 #ifdef OCCT_DEBUG
782     if(!Map.Bind(aKey, C0)) 
783       cout << "Not bind = " <<aKey.ShapeType() <<endl;      
784 #else
785     Map.Bind(aKey, C0);
786 #endif
787     if(aKey.ShapeType() < StopType ) {
788       if(aKey.ShapeType() < TopAbs_SOLID) {
789         BuildMapC0(aKey, Context, StopType, Map);
790       }
791       else
792         BuildMapIn(aKey, StopType, Map);
793     }
794     anIt.Next();
795   }
796 }
797
798 //=======================================================================
799 //function : BuildMap
800 //purpose  : builds data map: key - context
801 //=======================================================================
802 static void BuildMap(const TopoDS_Shape& Context, const TopAbs_ShapeEnum StopType, 
803                      TopTools_DataMapOfOrientedShapeShape& Map)
804 {
805   TopoDS_Iterator anIt(Context);
806   while(anIt.More()) {
807     const TopoDS_Shape& aKey = anIt.Value();
808 #ifdef OCCT_DEBUG
809     if(!Map.Bind(aKey, Context)) 
810       cout << "Not bind = " <<aKey.ShapeType() <<endl;      
811 #else
812     Map.Bind(aKey, Context);
813 #endif
814     if(aKey.ShapeType() < StopType ) {
815       if(aKey.ShapeType() < TopAbs_SOLID)
816         BuildMapC0(aKey, Context, StopType, Map);
817       else
818         BuildMapIn(aKey, StopType, Map);
819     }
820     anIt.Next();
821   }
822 }
823 //=======================================================================
824 //function : FindUniqueContext
825 //purpose  : Find unique context of selection
826 //=======================================================================
827 TopoDS_Shape TNaming::FindUniqueContext(const TopoDS_Shape& Selection, const TopoDS_Shape& Context)
828 {
829   TopTools_DataMapOfOrientedShapeShape aMap; 
830   BuildMap(Context, Selection.ShapeType(), aMap);
831 #ifdef OCCT_DEBUG
832   TopTools_DataMapIteratorOfDataMapOfOrientedShapeShape it (aMap);
833   for (;it.More();it.Next()) {
834     cout <<"FindUniqueContext: Key - " <<it.Key().ShapeType()<< " " << it.Key().TShape().get() <<" OR = " <<it.Key().Orientation() <<
835       "  Context - " << it.Value().ShapeType() << "  " << it.Value().TShape().get()  << " OR = " <<it.Value().Orientation() <<endl;
836   }
837 #endif
838   if(aMap.IsBound(Selection))
839     return aMap.Find(Selection); 
840   return TopoDS_Shape();
841 }
842
843 //=======================================================================
844 //function : FindUniqueContexts
845 //purpose  : Find unique context of selection which is pure concatenation 
846 //         : of atomic shapes (Compound)
847 //=======================================================================
848 TopoDS_Shape TNaming::FindUniqueContextSet(const TopoDS_Shape& Selection, const TopoDS_Shape& Context,
849                                            Handle(TopTools_HArray1OfShape)& Arr)
850 {
851   if(Selection.ShapeType() == TopAbs_COMPOUND) {
852     TopTools_DataMapOfOrientedShapeShape aMap;
853     Standard_Integer Up(0);
854     TopAbs_ShapeEnum aStopType(TopAbs_COMPOUND);
855     TopoDS_Iterator anIter(Selection);
856     for(; anIter.More(); anIter.Next()) {
857       const TopoDS_Shape& aS = anIter.Value();
858       if(aS.ShapeType() > aStopType)
859         aStopType = aS.ShapeType();     
860       Up++;
861     }
862     if(Up > 0) 
863       Arr = new  TopTools_HArray1OfShape(1, Up);
864     if(aStopType == TopAbs_SHAPE)
865       aStopType = Selection.ShapeType();
866     BuildMap(Context, aStopType, aMap);
867     if(aMap.IsBound(Selection))
868       return aMap.Find(Selection);
869     else if(Selection.ShapeType() == TopAbs_COMPOUND) {
870       Standard_Integer num1(0),num2(0);
871       TopoDS_Compound CompShape;
872       BRep_Builder    B;
873       B.MakeCompound(CompShape);
874       TopoDS_Iterator it(Selection);
875       TopTools_MapOfShape aView;
876       for(;it.More(); it.Next(),num1++) {
877         if(aMap.IsBound(it.Value())) {
878           if(aView.Add(aMap.Find(it.Value()))) {
879             B.Add(CompShape, aMap.Find(it.Value()));        
880           }
881           if(!Arr.IsNull()) 
882             Arr->SetValue(num1+1, aMap.Find(it.Value()));
883           
884           if(aMap.Find(it.Value()) == Context)
885             num2++;
886         }
887       }
888       if(num1 == num2 && num2)
889         return Context;
890       else {
891         TopoDS_Iterator anIt(CompShape);
892         Standard_Integer n(0);
893         TopoDS_Shape aCmp;
894         for(; anIt.More(); anIt.Next()) {
895             n++;
896             aCmp = anIt.Value();
897         }
898         if(n == 1) {
899 #ifdef OCCT_DEBUG_FSET
900           cout << "FindUniqueContextSet: n = " << n <<endl;
901 #endif
902           return aCmp;
903         }
904         return CompShape;
905       }
906     }
907   }
908   return TopoDS_Shape();
909 }
910
911 //=======================================================================
912 //function : OuterWire
913 //purpose  : Returns True & <theWire> if Outer wire is found.
914 //=======================================================================
915 Standard_Boolean TNaming::OuterWire(const TopoDS_Face& theFace, TopoDS_Wire& theWire)
916
917   TopoDS_Face aFx;
918   TopoDS_Wire aWx;
919   BRep_Builder aBB;
920   IntTools_FClass2d aFC;
921   Standard_Boolean bFlag(Standard_False);
922   Standard_Real aTol = BRep_Tool::Tolerance(theFace);
923   TopoDS_Iterator aIt(theFace);
924   for (; aIt.More(); aIt.Next()) {
925     aWx=*((TopoDS_Wire*)&aIt.Value());
926     aFx = theFace;
927     aFx.EmptyCopy();
928     aBB.Add(aFx, aWx);
929     aFC.Init(aFx, aTol);
930     bFlag = aFC.IsHole();
931     if (!bFlag) 
932       break;
933   }
934   theWire=aWx;
935   return !bFlag;// if bFlag == True -  not found
936 }
937 //=======================================================================
938 //function : IsInternal
939 //purpose  :
940 //=======================================================================
941 static Standard_Boolean IsInternal(const TopoDS_Shape& aSx)
942 {   
943   TopAbs_Orientation aOr; 
944   Standard_Boolean bInternal(Standard_False);
945   TopoDS_Iterator aIt(aSx);
946   if(aIt.More()) {
947     const TopoDS_Shape& aSy = aIt.Value();
948     aOr = aSy.Orientation();
949     bInternal = (aOr == TopAbs_INTERNAL || aOr == TopAbs_EXTERNAL);    
950   }
951   return bInternal;
952 }
953 //=======================================================================
954 //function : OuterShell
955 //purpose  : returns True & <theShell>, if Outer shell is found
956 //=======================================================================
957 Standard_Boolean TNaming::OuterShell(const TopoDS_Solid& theSolid, 
958                                              TopoDS_Shell& theShell)
959 {
960   TopoDS_Solid aSDx;
961   TopoDS_Shell aSHx;
962   TopAbs_State aState;
963   Standard_Boolean bFound(Standard_False);
964   Standard_Real aTol(1.e-7);
965   //
966   BRep_Builder aBB;
967   BRepClass3d_SolidClassifier aSC;
968   TopoDS_Iterator aIt(theSolid);
969   for (; aIt.More(); aIt.Next()) {
970     const TopoDS_Shape& aSx = aIt.Value();
971
972     if (aSx.ShapeType() != TopAbs_SHELL)
973       continue;
974     if (IsInternal(aSx)) 
975       continue;
976     //
977     aSHx = *((TopoDS_Shell*)&aSx);
978     //
979     aSDx = theSolid;
980     aSDx.EmptyCopy();
981     //
982     aBB.Add(aSDx, aSHx);
983     //
984     aSC.Load(aSDx);
985     //BRepClass3d_SolidClassifier& aSC=aCtx.SolidClassifier(aSDx);
986     aSC.PerformInfinitePoint(aTol);
987     aState = aSC.State();
988     if(aState == TopAbs_OUT) {
989       bFound = Standard_True;
990       break;
991     }
992   }
993   theShell = aSHx;
994
995   return bFound;
996 }
997
998
999