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