0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / TNaming / TNaming_Naming.cxx
1 // Created on: 1997-09-03
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_Tool.hxx>
19 #include <BRepTools.hxx>
20 #include <NCollection_DataMap.hxx>
21 #include <NCollection_Map.hxx>
22 #include <Standard_DomainError.hxx>
23 #include <Standard_GUID.hxx>
24 #include <Standard_Type.hxx>
25 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
26 #include <TColStd_MapOfInteger.hxx>
27 #include <TDF_Attribute.hxx>
28 #include <TDF_ChildIterator.hxx>
29 #include <TDF_Data.hxx>
30 #include <TDF_DataSet.hxx>
31 #include <TDF_IDFilter.hxx>
32 #include <TDF_Label.hxx>
33 #include <TDF_LabelList.hxx>
34 #include <TDF_LabelMap.hxx>
35 #include <TDF_RelocationTable.hxx>
36 #include <TDF_TagSource.hxx>
37 #include <TNaming.hxx>
38 #include <TNaming_Builder.hxx>
39 #include <TNaming_Identifier.hxx>
40 #include <TNaming_Iterator.hxx>
41 #include <TNaming_ListIteratorOfListOfNamedShape.hxx>
42 #include <TNaming_Localizer.hxx>
43 #include <TNaming_Name.hxx>
44 #include <TNaming_NamedShape.hxx>
45 #include <TNaming_Naming.hxx>
46 #include <TNaming_NamingTool.hxx>
47 #include <TNaming_NewShapeIterator.hxx>
48 #include <TNaming_OldShapeIterator.hxx>
49 #include <TNaming_Scope.hxx>
50 #include <TNaming_Selector.hxx>
51 #include <TNaming_Tool.hxx>
52 #include <TopExp.hxx>
53 #include <TopExp_Explorer.hxx>
54 #include <TopoDS.hxx>
55 #include <TopoDS_Face.hxx>
56 #include <TopoDS_Iterator.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <TopoDS_Shell.hxx>
59 #include <TopoDS_Solid.hxx>
60 #include <TopoDS_Wire.hxx>
61 #include <TopTools_HArray1OfShape.hxx>
62 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
63 #include <TopTools_IndexedMapOfShape.hxx>
64 #include <TopTools_ListIteratorOfListOfShape.hxx>
65 #include <TopTools_ListOfShape.hxx>
66 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
67 #include <TopTools_MapIteratorOfMapOfShape.hxx>
68 #include <TopTools_MapOfShape.hxx>
69
70 IMPLEMENT_STANDARD_RTTIEXT(TNaming_Naming,TDF_Attribute)
71
72 // #include <TNaming_NCollections.hxx>
73 typedef NCollection_Map<TopoDS_Shape> TNaming_MapOfShape; 
74 typedef TNaming_MapOfShape::Iterator TNaming_MapIteratorOfMapOfShape;
75 typedef NCollection_DataMap<TopoDS_Shape, TNaming_MapOfShape> TNaming_DataMapOfShapeMapOfShape; 
76 typedef TNaming_DataMapOfShapeMapOfShape::Iterator TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape; 
77 // The bug concerns access to a null object in the method Filter():
78
79 #define ALLOW_CHILD_NBS
80 //#define MDTV_DEB_CC
81 //#define MDTV_DEB_OR
82 //#define MDTV_DEB_MOD
83 //#define MDTV_OR
84 //#define MDTV_DEB_INNS
85 //#define MDTV_DEB_NBS
86 //#define MDTV_DEB_71
87 //#define MDTV_DEB_WIN
88 #ifdef OCCT_DEBUG
89 #include <TDF_MapIteratorOfLabelMap.hxx> 
90 #include <TCollection_AsciiString.hxx>
91 #include <TDF_Tool.hxx>
92 #include <BRepTools.hxx>
93 #include <TNaming_Tool.hxx>
94 #include <TDF_Tool.hxx>
95 #include <TDF_MapIteratorOfLabelMap.hxx>
96
97 #include <TCollection_AsciiString.hxx>
98 #include <BRepTools.hxx>
99 void Print_Entry(const TDF_Label&       label)
100 {
101   TCollection_AsciiString entry;
102   TDF_Tool::Entry(label, entry);
103   cout << "LabelEntry = "<< entry << endl;
104 }
105 static void Write(const TopoDS_Shape& shape,
106                       const Standard_CString filename) 
107 {
108   char buf[256];
109   if(strlen(filename) > 256) return;
110   strcpy (buf, filename);
111   char* p = buf;
112   while (*p) {
113     if(*p == ':')
114       *p = '-';
115     p++;
116   }
117   ofstream save (buf);
118   if(!save) 
119     cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << endl;
120   save << "DBRep_DrawableShape" << endl << endl;
121   if(!shape.IsNull()) BRepTools::Write(shape, save);
122   save.close();
123 }
124 void WriteNSOnLabel(const Handle(TNaming_NamedShape) & NS, const TCollection_AsciiString& Nam)
125 {
126   if (!NS.IsNull()) {
127     TCollection_AsciiString entry;
128     TDF_Tool::Entry(NS->Label(), entry);
129     TopoDS_Shape Sh = TNaming_Tool::GetShape (NS);
130     if(!Sh.IsNull()) {
131       TCollection_AsciiString Entry = Nam + entry + ".brep";
132       Write(Sh, Entry.ToCString());
133     }
134     else
135       cout << "WriteNSOnLabel>>> TopoDS_Shape IS NULL on Entry = "<< entry << endl;
136   }
137   else
138     cout << "WriteNSOnLabel >>>  NamedShape IS NULL" << endl;
139 }
140 #endif
141
142 //==========================================================================================
143 static Handle(TNaming_NamedShape) BuildName (const  TDF_Label&   F,
144                                              TNaming_Scope&                    MDF,
145                                              const TopoDS_Shape&               S,
146                                              const TopoDS_Shape&               Context, 
147                                              const Handle(TNaming_NamedShape)& Stop,
148                                              const Standard_Boolean            Geometry);
149
150 //=======================================================================
151 static Standard_Integer RepeatabilityInContext(const TopoDS_Shape& Selection, 
152                                                const TopoDS_Shape& Context);
153 //=======================================================================
154 extern Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2);
155
156 //=======================================================================
157 //function : Solve
158 //purpose  : voir avec YFR comment retrouver le bon resulat et le mettre 
159 //         : dans le NamedShape de L
160 //=======================================================================
161 Standard_Boolean  TNaming_Naming::Solve (TDF_LabelMap& Valid) 
162
163   Handle(TNaming_Naming) subname;
164   for (TDF_ChildIterator it (Label(),Standard_False); it.More(); it.Next()) {
165 #ifdef OCCT_DEBUG_NBS
166     TCollection_AsciiString anEntry;
167     TDF_Tool::Entry(it.Value(), anEntry);
168     cout << "TNaming_Naming::Solve: Label to be solved = " << anEntry << endl;
169 #endif
170     if (it.Value().FindAttribute(TNaming_Naming::GetID(),subname)) {
171       if (!subname->Solve (Valid)) {
172         return Standard_False; // not necessary to continue
173       }
174     }
175   }
176 #ifdef OCCT_DEBUG_CC
177   TDF_MapIteratorOfLabelMap anItr(Valid);
178   cout << "TNaming_Naming::Solve:: Valid label Map" << endl;
179   for (; anItr.More(); anItr.Next()) {
180     const TDF_Label& aLabel = anItr.Key();
181     TCollection_AsciiString anEntry;
182     TDF_Tool::Entry(aLabel, anEntry);
183     cout << "Label = " << anEntry << endl;
184   }
185 #endif
186   if (Regenerate(Valid)) {
187     if (!Valid.IsEmpty()) Valid.Add(Label());
188     return Standard_True;
189   }
190   return Standard_False; 
191 }
192  
193  
194 //=======================================================================
195 //function : GetID
196 //purpose  : 
197 //=======================================================================
198
199 const Standard_GUID& TNaming_Naming::GetID () 
200 {
201   static Standard_GUID TNaming_NamingID("c0a19201-5b78-11d1-8940-080009dc3333");
202   return TNaming_NamingID; 
203 }
204
205 //=======================================================================
206 //function : Insert
207 //purpose  : 
208 //=======================================================================
209
210 Handle(TNaming_Naming) TNaming_Naming::Insert (const TDF_Label& under) 
211 {
212   Handle(TNaming_Naming) N;  
213   TDF_Label child = TDF_TagSource::NewChild(under);
214   N = new TNaming_Naming ();  
215   child.AddAttribute (N);
216   return N;
217 }  
218   
219 //=======================================================================
220 //function : BuildNS
221 //purpose  : returns a new NamedShape, which is built as selection: 
222 //         : TNaming_Builder::Select("S","S") at the new child label of the label <F>. 
223 //=======================================================================
224
225 static Handle(TNaming_NamedShape)  BuildNS (const TDF_Label&        F,
226                                             const TopoDS_Shape&     S,
227                                             const TNaming_NameType& Name)
228 {
229   Handle (TNaming_Naming) Naming = TNaming_Naming::Insert (F);
230   
231   TNaming_Name& theName = Naming->ChangeName();
232   theName.ShapeType(S.ShapeType());
233   theName.Shape(S); 
234   theName.Orientation(S.Orientation());
235   theName.Type(Name);
236   TNaming_Builder B(Naming->Label());
237   B.Select(S,S);
238   return B.NamedShape();
239 }
240
241 //=======================================================================
242 //function : FindIndex
243 //purpose  : 
244 //=======================================================================
245
246 static Standard_Integer FindIndex(const Handle(TNaming_NamedShape)& NS,
247                                   const TopoDS_Shape&               S)
248 {
249   TDF_LabelList Labels;
250   TopoDS_Shape IS = TNaming_Tool::InitialShape(S,NS->Label(),Labels);
251   Standard_Integer Index = 1;
252   for (TNaming_Iterator itNS(NS); itNS.More(); itNS.Next(),Index++) {
253     if (IS.IsSame(itNS.NewShape())) break;
254   }
255   return Index;
256 }
257
258
259 //=======================================================================
260 //function : CompareInGeneration
261 //purpose  : returns true, only if the specified NS contains only <S> in 
262 //         : the "new shapes" set.
263 //=======================================================================
264
265 static Standard_Boolean CompareInGeneration (const Handle(TNaming_NamedShape)& NS,
266                                              const TopoDS_Shape&               S)
267 {
268   for (TNaming_Iterator it(NS); it.More(); it.Next()) {
269     if (!it.NewShape().IsSame(S)) return 0;
270   }
271   return 1;
272 }
273
274 //=======================================================================
275 //function : GetShapeEvolutions
276 //purpose  : returns Standard_True, if target has parent in source; list contains inheritance chain
277 //=======================================================================
278 static Standard_Boolean GetShapeEvolutions(const TopoDS_Shape&               theTarget, // this is changed in recursion
279                                            const Handle(TNaming_NamedShape)& theSource,
280                                            TopTools_ListOfShape&             aList)     // returns list in the backward order
281 {
282   Handle(TNaming_NamedShape) aTarget = TNaming_Tool::NamedShape(theTarget,theSource->Label());
283   if (!aTarget.IsNull()) {
284 #ifdef OCCT_DEBUG_71
285     cout <<"GetShapeEvolutions: target NS = ";
286     Print_Entry(aTarget->Label());
287     cout <<"GetShapeEvolutions: Source NS = ";
288     Print_Entry(theSource->Label());
289     TCollection_AsciiString aNam("GetShapeEvolutions");
290     WriteNSOnLabel(aTarget,aNam);
291 #endif
292     if (aTarget->Label() == theSource->Label()) return Standard_True; // check if target is in the source
293   } else return Standard_False;
294
295   TNaming_Iterator anIter(aTarget);
296   for(;anIter.More();anIter.Next()) { // check all appropriate old shapes of target
297 #ifdef OCCT_DEBUG_71
298     if(!anIter.OldShape().IsNull()) {
299       Write(anIter.OldShape(), "Target_OldS.brep");
300       cout <<"Target OldS TS =" <<anIter.OldShape().TShape()->This() <<endl;
301     }
302     if(!anIter.NewShape().IsNull()) {
303       Write(anIter.NewShape(), "Target_NewS.brep");
304       cout <<"Target NewS TS =" <<anIter.NewShape().TShape()->This() <<endl;
305     }  
306 #endif
307     if (anIter.OldShape().IsNull() || anIter.NewShape().IsNull()) continue;
308     if (!anIter.NewShape().IsSame(theTarget)) continue;
309     if (GetShapeEvolutions(anIter.OldShape(),theSource,aList)) { // recursion: now target is old shape
310       aList.Append(theTarget); // if oldshape has the source as parent (or belongs to it) , fill the list
311       return Standard_True;
312     }
313   }
314   return Standard_False;
315 }
316
317 //=======================================================================
318 //function : CompareInModification
319 //purpose  : returns empty named shape if naming is already done
320 //=======================================================================
321
322 static Handle(TNaming_NamedShape) CompareInModification (const Handle(TNaming_NamedShape)& NS, // parent
323                                                          const TopoDS_Shape&               S)  // target
324 {
325   Handle(TNaming_NamedShape) aResult;
326   if (S.IsNull() || NS.IsNull()) return aResult;
327 #ifdef OCCT_DEBUG_71
328   cout <<"CompareInModification: parent NS = ";
329   Print_Entry(NS->Label());
330   Write(S, "CompareInM_S.brep");
331   TCollection_AsciiString aNam("CompareInM");
332   WriteNSOnLabel(NS,aNam);
333 #endif
334   Handle(TNaming_NamedShape) aSource; // parent NamedShape, which can be found by TopoDS shape
335   TNaming_Iterator anIt(NS);
336   for(;anIt.More() && aSource.IsNull();anIt.Next()) {
337     if (!anIt.NewShape().IsNull()) {
338       aSource = TNaming_Tool::NamedShape(anIt.NewShape(),NS->Label());
339 #ifdef OCCT_DEBUG_71
340       TCollection_AsciiString aNam("CompareInM_Source");
341       WriteNSOnLabel(aSource,aNam);
342 #endif
343     }
344   }
345   // searching for 1:n to the same label modifications (in this case current naming is insufficient)
346   TopTools_ListOfShape aList;
347   if (GetShapeEvolutions(S,aSource,aList) && aList.Extent() > 0) {
348     TopTools_ListIteratorOfListOfShape anIter(aList);
349     for(;anIter.More();anIter.Next()) {
350       aResult = TNaming_Tool::NamedShape(anIter.Value(),NS->Label());
351       if (aResult->Evolution()!=TNaming_MODIFY) { // evolution must be modify, otherwise everything is OK
352         aResult.Nullify();
353         return aResult;
354       }
355       TopTools_MapOfShape aMap; // collection of the old shapes of the shape from list
356       TNaming_Iterator aNIter1(aResult);
357
358       for(;aNIter1.More();aNIter1.Next()) {
359         if (aNIter1.NewShape().IsSame(anIter.Value()))  {// if isSame 
360           aMap.Add(aNIter1.OldShape());
361         }
362       }
363       TNaming_Iterator aNIter2(aResult); // if some another shapes has oldshape from map, return namedshape with this oldshape
364
365       for(;aNIter2.More();aNIter2.Next()) {
366         if (aNIter2.NewShape().IsSame(anIter.Value())) continue;
367         if (aMap.Contains(aNIter2.OldShape())) { // if one shape was modified to the two at the shared label, return this one
368           aResult = TNaming_Tool::NamedShape(aNIter2.OldShape(),NS->Label());
369           if (!aResult.IsNull()) return aResult;
370         }
371       }
372     }
373     aResult.Nullify();
374   }
375   return aResult;
376 }
377
378 //=======================================================================
379 static Standard_Boolean FillSMap(const TopoDS_Shape& S, TopTools_MapOfShape& MS)
380 {   
381   if(S.IsNull()) return Standard_False; 
382   Standard_Boolean isHomogen(Standard_True);
383   TopAbs_ShapeEnum aPrevType(TopAbs_SHAPE);
384   TopoDS_Iterator it(S);
385   for (; it.More(); it.Next()) {
386     const TopAbs_ShapeEnum aType = it.Value().ShapeType();      
387 #ifdef OCCT_DEBUG_CC
388     cout <<"TestSolution_FillMap: S_Type = :" << it.Value().ShapeType() <<" TShape = " << it.Value().TShape()->This() <<endl;
389 #endif
390     if(aType > TopAbs_COMPSOLID) {
391       MS.Add(it.Value());
392       if(aPrevType == TopAbs_SHAPE)
393         aPrevType = aType;
394       else if(aPrevType != aType) 
395         isHomogen = Standard_False;       
396     }
397     else 
398       if(!FillSMap(it.Value(), MS))
399         isHomogen = Standard_False;  
400   }
401   return isHomogen;
402 }
403 //=======================================================================
404 //function : Compare
405 //purpose  : checks naming of the shape <S> in the NamedShape <NS>. 
406 //         : Returns true, if it's correct. Details ==>
407 //         : The method takes all modifications of the "NS" (see CurrentShape method), 
408 //         : which are in the "MDF" (if it's not empty) before <Stop> shape and check them.
409 //         : whether these modifications contain only "S". If yes then the method 
410 //         : returns true, otherwise it returns false.
411 //=======================================================================
412
413 static Standard_Boolean Compare (const Handle(TNaming_NamedShape)& NS,
414                                  const TNaming_Scope&              MDF,
415                                  const Handle(TNaming_NamedShape)& Stop,
416                                  const TopoDS_Shape&               S)
417 {
418   TDF_LabelMap Forbiden;
419   TopTools_IndexedMapOfShape MS;
420   if (!Stop.IsNull()) TNaming_NamingTool::BuildDescendants(Stop,Forbiden);
421   TNaming_NamingTool::CurrentShape(MDF.GetValid(),Forbiden,NS,MS);
422 #ifdef OCCT_DEBUG_NBS
423   Write(S, "Compare_S.brep");
424   cout <<  "S: TShape = " <<S.TShape()->This() <<endl;
425   TCollection_AsciiString aNam("Compare_MS_");
426   TCollection_AsciiString ext(".brep");
427   for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
428     TCollection_AsciiString aName = aNam + anItMS + ext;
429     Write (MS (anItMS), aName.ToCString());
430     cout << aName.ToCString()<< ": TShape = " << MS (anItMS).TShape()->This() << endl;
431   }
432 #endif
433   return (MS.Contains(S) && MS.Extent() == 1);
434 }
435 //=======================================================================
436 //function : TestSolution
437 //purpose  : returns true, if last modification of shape from "NS" is equal to "S":
438 //         : If shape "S" has atomic type (TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX), 
439 //         : then returns S.IsSame(shape from "NS"). 
440 //         : Otherwise the result of exploration of these shapes must be same.
441 //=======================================================================
442
443 static Standard_Boolean TestSolution(const TNaming_Scope&      MDF,
444                                      const Handle(TNaming_NamedShape)& NS,
445                                      const TopoDS_Shape&               S)
446
447
448   if (NS.IsNull()) return Standard_False;
449   TopoDS_Shape Res = MDF.CurrentShape(NS);// last modification of NS taken into account Valid map
450   if(S.IsNull() || Res.IsNull()) return Standard_False;
451 #ifdef OCCT_DEBUG_CC
452   Write(S, "TSol_S.brep");
453   Write(Res, "TSol_Res.brep");
454 #endif  
455
456   if ((S.ShapeType() == TopAbs_FACE  ||
457       S.ShapeType() == TopAbs_EDGE  ||
458       S.ShapeType() == TopAbs_VERTEX ) && 
459       Res.ShapeType() != TopAbs_COMPOUND) { 
460     return (Res.IsSame(S));
461   } else if (S.ShapeType() == TopAbs_SOLID ||
462         S.ShapeType() == TopAbs_COMPSOLID) {
463     TopTools_MapOfShape aMS;
464     TopExp_Explorer exp;
465     for (exp.Init(S,TopAbs_FACE) ; exp.More(); exp.Next()) {
466       aMS.Add(exp.Current());
467     }
468     for (exp.Init(Res,TopAbs_FACE) ; exp.More(); exp.Next()) { //content of MS and Res should be the same 
469       if (aMS.Contains(exp.Current())) {
470         aMS.Remove(exp.Current());
471       }
472       else return 0;
473     }
474     return aMS.IsEmpty();
475   } else {
476
477     TopTools_MapOfShape MS;
478     Standard_Boolean isHom = FillSMap(S, MS);
479     TopAbs_ShapeEnum aType(TopAbs_SHAPE); 
480     TColStd_MapOfInteger aView;
481     TopTools_MapIteratorOfMapOfShape itm(MS);
482     for(;itm.More();itm.Next()) {
483       aType = itm.Key().ShapeType();
484       if(isHom) 
485         break;
486        else 
487         aView.Add(itm.Key().ShapeType());      
488     }
489     
490     if (MS.Contains(Res)) {
491       MS.Remove(Res);
492       if (MS.IsEmpty()) return 1;
493     }
494     if (Res.ShapeType() == TopAbs_SOLID ||
495         Res.ShapeType() == TopAbs_COMPSOLID || 
496         Res.ShapeType() == TopAbs_COMPOUND) 
497       {
498         TopExp_Explorer exp;
499         if(isHom)
500           for (exp.Init(Res,aType) ; exp.More(); exp.Next()) {
501             if (MS.Contains(exp.Current())) {
502               MS.Remove(exp.Current());
503             }
504           } else {
505             TColStd_MapIteratorOfMapOfInteger aMapIter(aView);
506             for(; aMapIter.More(); aMapIter.Next()) {
507               TopAbs_ShapeEnum aCurType = (TopAbs_ShapeEnum)aMapIter.Key();
508               for (exp.Init(Res, aCurType) ; exp.More(); exp.Next()) {
509                 if (MS.Contains(exp.Current())) {
510                   MS.Remove(exp.Current());
511                 }
512               }
513             }
514           }
515       } else {
516         if(S.IsSame(Res))
517           return Standard_True;
518         TopoDS_Iterator it(Res);
519         for (; it.More(); it.Next()) { //content of MS and Res should be the same 
520           if (MS.Contains(it.Value())) {
521             MS.Remove(it.Value());
522           }
523           else return 0; 
524         }
525       }
526     return MS.IsEmpty();
527   }
528 }
529
530 //=======================================================================
531 //function : FindNewShapeInFather
532 //purpose  :
533 //=======================================================================
534
535 static void FindNewShapeInFather (const Handle(TNaming_NamedShape)& NS,
536                                   TopoDS_Shape&                     SC)
537 {  
538   const TDF_Label& Father = NS->Label().Father(); 
539   TNaming_Iterator  itLab(Father);
540   if(itLab.More()) 
541     SC = itLab.NewShape();    
542 }
543
544 //=======================================================================
545 //function : NextModif
546 //purpose  : 
547 //=======================================================================
548
549 static Handle(TNaming_NamedShape) NextModif(const Handle(TNaming_NamedShape)& NS)
550 {
551   Handle (TNaming_NamedShape) Next;
552   if (!NS.IsNull()) {
553     TNaming_NewShapeIterator it(NS); 
554     if (it.More()&& it.IsModification()) Next = it.NamedShape();
555   }
556   return Next;
557 }
558 //=======================================================================
559 // C1 - cand shape of the father, C2 - shape of rebuild child Naming attr.
560 //      (to be Compound of elementary shapes)
561 //=======================================================================
562 static Standard_Boolean IsContSame(const TopoDS_Shape& C1, const TopoDS_Shape& C2)
563 {
564   Standard_Boolean aRes(Standard_False);
565   if(!C1.IsNull() && !C2.IsNull()) {
566     TopTools_MapOfShape aMap;
567     if(FillSMap(C1, aMap)) {
568       aRes = Standard_True;
569       TopoDS_Iterator it(C2);
570       for(;it.More();it.Next()) {
571         if(!aMap.Contains(it.Value())) {
572           aRes = Standard_False;
573           break;
574         }
575       }
576     }
577   }
578   return aRes;
579 }
580
581 //=======================================================================
582 // Identifies the case when Filter haven't sense because of multiplicity
583 //=======================================================================
584 static Standard_Boolean IsMultipleCase(const TopoDS_Shape&        S,
585                                  const TopoDS_Shape&        Context,
586                                  const TopTools_MapOfShape& Neighbourgs) {
587   
588   TopTools_IndexedDataMapOfShapeListOfShape aDM;
589   TNaming_MapOfShape aM;
590   TopTools_MapOfShape aNbs;
591   aNbs.Assign(Neighbourgs);
592   aNbs.Add(S);
593   TNaming_DataMapOfShapeMapOfShape aDMM;
594   TopExp::MapShapesAndAncestors (Context, TopAbs_EDGE, TopAbs_FACE, aDM);
595   TopTools_MapIteratorOfMapOfShape it(aNbs);
596   for(;it.More();it.Next()) {
597     if(aDM.Contains(it.Key())) {
598       TNaming_MapOfShape aMS;
599       const TopTools_ListOfShape& aL = aDM.FindFromKey(it.Key());      
600       TopTools_ListIteratorOfListOfShape lit(aL);
601       for(;lit.More();lit.Next()) {
602         aM.Add(lit.Value());
603         aMS.Add(lit.Value());
604       }
605       if(aMS.Extent())
606         aDMM.Bind(it.Key(), aMS);
607     } else {
608 #ifdef OCCT_DEBUG
609       cout << "Key is not BOUND!" <<endl;
610 #endif
611       return Standard_False;
612     }
613   }
614   
615   Standard_Boolean isCommon(Standard_True);
616   TNaming_MapIteratorOfMapOfShape itm(aM);
617   for(;itm.More();itm.Next()) {
618     isCommon = Standard_True; // statement: this shape (itm.Key()) is common (to be checked below)
619     TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape itdm(aDMM);
620     for (;itdm.More();itdm.Next()) {
621       const TNaming_MapOfShape& aMap = itdm.Value();
622       if(!aMap.Contains(itm.Key())) {
623         isCommon = Standard_False;
624         break;
625       }
626     }
627     if(isCommon) break; // common single face found
628   }
629   if(isCommon && aM.Extent() < aNbs.Extent()) {// number of unique faces (to have single solution) 
630                                                //should be at least no less than (Nb of Neighbourgs) +1
631     return Standard_True;
632   }
633   return Standard_False;
634 }
635 //=======================================================================
636 //function : Filter
637 //purpose  : sets the name with type "FILTERBYNEIGHBOURGS" and returns true, 
638 //         : if it was correctly done.
639 //         : 
640 //         :
641 //=======================================================================
642
643 static Standard_Boolean Filter (const TDF_Label&                  F,
644                                 TNaming_Scope&                    MDF,
645                                 const TopoDS_Shape&               S,
646                                 const TopoDS_Shape&               Context,
647                                 TNaming_Localizer&                Localizer,
648                                 Handle(TNaming_NamedShape)&       NS,
649                                 const Standard_Integer            Lev)
650
651   // 1. Localizer.FindNeighbourg("Context", "S", "Neighbourg") - looks for neighbourgs of  "S" with the same shape type in the "Context" 
652   //    shape and adds them to the "Neighbourg" map;
653   // 2. If "Neighbourg" map is empty, tries to do the same with the new context shape: shape from the father label of the "S" named shape;
654   // 3. If "Neighbourg" map is still empty, returns false;
655   // 4. Adds to the new child of label "L" new TNaming_Naming attribute with the next properties name: shape type is shape type of the "S",
656   //     type is TNaming_FILTERBYNEIGHBOURGS, stop shape ( "Until" ) is "Context" of corresponding NamedShape; 
657   //     first argument of name is "NS" NamedShape.
658   // 5. Adds to the Name all shapes from "Neighbourg" map: build it with the BuildName( new generated TNaming_Naming attribute, MDF, 
659   //    argument shape from "Neighbourg", "Context", NextModif( "Until" ), true ) method.
660   // 6. Creates resulting NamedShape with the "Regenerate" ( it just calls TName::Solve method ) method from TNaming_Naming class.
661   // 7. If Compare( result NamedShape, MDF, stop, "S" ) returns true, "Filter" method returns true, else returns false.
662
663   //------------------------------
664   // Construction des voisins ==> of neighbors.
665   //------------------------------
666   Standard_Integer aLev(Lev);
667   TopTools_MapOfShape Neighbourg;
668   Localizer.FindNeighbourg (Context,S,Neighbourg);
669 #ifdef OCCT_DEBUG_NBS
670   //DbgTools::DisplayShape(Context, F, Quantity_NOC_GREEN);
671   //DbgTools::DisplayShape(S, F, Quantity_NOC_BLUE1);  
672   Write(Context, "FNBS_Context.brep");
673   Write(S, "FNBS_S.brep");
674   Write(Neighbourg, "NBS");
675 #endif
676   // mpv : NS and shape must be the same
677   Standard_Boolean isIn = Standard_False;
678   TNaming_Iterator anIter(NS);
679   for(;anIter.More();anIter.Next()) {
680 #ifdef OCCT_DEBUG
681           //DbgTools::DisplayShape(anIter.NewShape(), F, Quantity_NOC_RED);
682 #endif
683     if (anIter.NewShape().IsSame(S)) {
684       isIn = Standard_True;
685       break;
686     }
687   }
688   if (!isIn) if (!TNaming_Tool::NamedShape(S,F).IsNull()) NS = TNaming_Tool::NamedShape(S,F);
689 //  if (!TNaming_Tool::NamedShape(S,F).IsNull()) NS = TNaming_Tool::NamedShape(S,F);
690   
691   if (Neighbourg.IsEmpty()) {
692     // Recherche du vrai context. (Research of context truth)
693     Handle(TNaming_NamedShape) GenS = TNaming_Tool::NamedShape(S,NS->Label());
694     if (GenS.IsNull()) return Standard_False;
695     TDF_Label Father = (GenS->Label()).Father();
696     Father.FindAttribute(TNaming_NamedShape::GetID(),GenS);
697     TopoDS_Shape GoodContext = TNaming_Tool::GetShape(GenS);
698     Localizer.FindNeighbourg (GoodContext,S,Neighbourg);
699   }
700   
701
702   if (Neighbourg.IsEmpty()) {
703 #ifdef OCCT_DEBUG
704     cout <<"FindNeighbourg: impossible"<<endl;
705 #endif
706     return 0;  
707   } else {
708 #ifdef OCCT_DEBUG_NBS
709     Write(Neighbourg, "Neighbourgs");
710 #endif
711     aLev++;
712     //cout <<"Filter: Lev = " << aLev << endl;
713   }
714   if(aLev > 3) return 0; 
715 #ifdef ALLOW_CHILD_NBS   
716   Handle(TNaming_Naming) aFNaming;
717   TopoDS_Shape aFatherCandSh;
718   F.FindAttribute(TNaming_Naming::GetID(), aFNaming);
719   if(!aFNaming.IsNull()) {
720     const TNaming_Name& aName = aFNaming->GetName();
721     if (aName.Type() == TNaming_FILTERBYNEIGHBOURGS) {
722       aFatherCandSh = aName.Arguments().First()->Get();
723     }
724   } 
725   if(S.ShapeType() == TopAbs_EDGE && aFatherCandSh.IsNull()) {
726     //check the applicability
727     if(!NS.IsNull() && !NS->Get().IsNull() && NS->Get().ShapeType() == TopAbs_COMPOUND)
728       if(IsMultipleCase(S, Context, Neighbourg)) {
729         //cout << "Filter: ==> MultipleCase!" << endl;
730         NS->Label().FindAttribute(TNaming_Naming::GetID(), aFNaming);
731         if(!aFNaming.IsNull()) {
732           TNaming_Name& aName = aFNaming->ChangeName();
733           if (aName.Type() == TNaming_INTERSECTION) {
734             Standard_Integer ij(1);
735             TNaming_ListIteratorOfListOfNamedShape itA(aName.Arguments()); 
736             for (; itA.More(); itA.Next(), ij++) {
737               const TopoDS_Shape& aFace = TNaming_Tool::CurrentShape(itA.Value());
738 #ifdef OCCT_DEBUG_MOD
739               Write(aFace, "First_Face.brep");
740               cout <<"Selection TS = " << S.TShape()->This() <<endl;
741 #endif
742               Standard_Integer i(1), indxW(0),indxE(0),nbW(0),nbE(0), indxF(0);
743               Standard_Boolean isFound(Standard_False);
744               TopoDS_Iterator it(aFace);
745               for (;it.More();it.Next(),i++) {
746                 nbW++;
747 #ifdef OCCT_DEBUG_MOD
748                 Write(it.Value(), "First_Wire.brep");
749 #endif
750                 if(!isFound) {
751                   Standard_Integer j(1);
752                   TopoDS_Iterator it2(it.Value());
753                   for (;it2.More();it2.Next(),j++) {
754                     nbE++;
755 #ifdef OCCT_DEBUG_MOD
756                     Write(it2.Value(), "First_Wire.brep");
757                     cout <<"Edge TS = " << it2.Value().TShape()->This() <<endl;
758 #endif
759                     if(S.IsEqual(it2.Value())) {
760                       indxE = j;
761                       indxW = i;
762                       indxF = ij;
763                       isFound = Standard_True;              
764                     }
765                   }
766                 }             
767               }
768               if(isFound) {
769                 Standard_Integer Index = indxE & 0x000000FF;
770                 Index = Index | (nbE   << 8);
771                 Index = Index | (indxW << 16);
772                 Index = Index | (nbW   << 20);
773                 Index = Index | (indxF << 24);
774                 aName.Index(Index);           
775                 //------------------------------
776                 // Compute the TNaming_NamedShape
777                 //------------------------------
778                 aFNaming->Regenerate(MDF.ChangeValid());
779                 aFNaming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
780                 Handle (TNaming_NamedShape) Until = TNaming_Tool::NamedShape(Context,NS->Label());
781                 Handle (TNaming_NamedShape) Stop  = NextModif(Until); 
782                 if (Compare (NS,MDF,Stop,S)) return 1;
783                 break; 
784               }    
785             }
786           } 
787         }       
788         return 0;
789       }
790   }
791 #endif
792
793   //-----------------------------------------------------
794   // Construction function de naming. et insertion sous F
795   //-----------------------------------------------------
796   Handle (TNaming_Naming) NF = TNaming_Naming::Insert (F);
797   
798   Handle (TNaming_NamedShape) Until = TNaming_Tool::NamedShape(Context,NS->Label());
799   Handle (TNaming_NamedShape) Stop  = NextModif(Until); 
800   TNaming_Name& theName = NF->ChangeName();
801   theName.ShapeType(S.ShapeType());
802   theName.Shape(S);
803   theName.Orientation(S.Orientation());
804   theName.Type(TNaming_FILTERBYNEIGHBOURGS);
805   theName.Append(NS);
806   theName.StopNamedShape (Until);
807 #ifdef OCCT_DEBUG_NBS
808   cout << "FilterByNBS: ";
809   Print_Entry(NF->Label());
810   cout <<"AppendNS = " ;
811   Print_Entry(NS->Label());
812 #endif
813   //---------------------
814   // Naming des voisins.
815   //---------------------
816
817   TopTools_MapIteratorOfMapOfShape itN(Neighbourg);
818   for (; itN.More(); itN.Next()) {
819 #ifdef ALLOW_CHILD_NBS    
820     const TopoDS_Shape& aS = itN.Key();   
821     Handle (TNaming_NamedShape) aNS = 
822       BuildName(NF->Label(), MDF, aS, Context, Stop, 1);          
823 #ifdef OCCT_DEBUG_NBS
824     const TopoDS_Shape& aS2 = aNS->Get(); 
825     if(!aS.IsNull())
826       cout << "Shape arg type = " << aS.ShapeType() <<" TSH = " << aS.TShape()->This()<<endl;
827     if(!aS2.IsNull()) {
828       cout << "Build shape type = " << aS2.ShapeType() <<" TSH = " << aS2.TShape()->This()<<endl;
829       Write (aS2, "NBS_BuildShape.brep");
830     }
831     if(aNS.IsNull()) {
832      cout <<"AppendNS = " ;
833      Print_Entry(aNS->Label());
834     }
835 #endif
836                   
837     const TopoDS_Shape aSNS = aNS->Get();  //allow child level
838     Standard_Boolean allowChild(Standard_True);
839     if(!aSNS.IsNull() && aSNS.ShapeType() == TopAbs_COMPOUND && !aFatherCandSh.IsNull()) 
840       allowChild = !IsContSame(aFatherCandSh, aSNS);
841     if(allowChild && !aSNS.IsNull() && aS.ShapeType() != aSNS.ShapeType() && 
842        aSNS.ShapeType() == TopAbs_COMPOUND)
843       { // aLev < 3 
844 #ifdef OCCT_DEBUG_NBS
845         cout <<"Father label = ";
846         Print_Entry(aNS->Label().Father());
847         Write(aS,"SelectionS.brep");
848         Write(aSNS,"SelectionSNS.brep");
849 #endif
850         Handle(TNaming_Naming) aNaming;
851         Standard_Boolean StandardFilter(Standard_True);
852         aNS->FindAttribute(TNaming_Naming::GetID(), aNaming);
853         if(!aNaming.IsNull()) {
854           const TNaming_Name& aName = aNaming->GetName();
855           if (aName.Type() == TNaming_GENERATION) 
856             StandardFilter = Standard_False;
857           if(StandardFilter)
858             if (!Compare (aNS,MDF,Stop,aS)) {
859               TNaming_Localizer aLocalizer;
860               Filter (NF->Label(), MDF,aS,Context, aLocalizer,aNS, aLev);
861             }
862         }
863       }    
864     theName.Append(aNS);
865 #else 
866     theName.Append(BuildName(NF->Label(), MDF, itN.Key(), Context, Stop, 1));
867 #endif
868   }
869   //------------------------------
870   // Compute the TNaming_NamedShape
871   //------------------------------
872   NF->Regenerate(MDF.ChangeValid());
873   NF->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
874
875   //-----------------
876   // Check du filtre.
877   //-----------------
878   if (Compare (NS,MDF,Stop,S)) return 1;
879 #ifdef OCCT_DEBUG
880   cout <<"TNaming_Naming::Name Filter insufficient"<<endl;
881 #endif
882   return 0;
883 }
884
885
886 //=======================================================================
887 //function : BuildNameInNS
888 //purpose  : Calls BuildName method, but with new context and new stop shape.  
889 //         : Context is searched at the father label of the "Context" label : 
890 //         : old shapes from the NamedShape at the defined father label.
891 //         : If it's impossible, then "S" set as context. 
892 //         : If "S" is in new context, then stop shape is named shape, 
893 //         : which belongs to the father label of the "Context" named shape.
894 //         : For example, face (F2) of prism (P) is generated from the edge (E) 
895 //         : of primitive face (F1) of box (B). F2 is named as GENERATION from E.
896 //         : Naming of E is done with help BuildNameInNS function:   
897 //         : with context B and stop shape P. 
898 //=======================================================================
899 static Handle(TNaming_NamedShape) BuildNameInNS (const TDF_Label&                  F,
900                                                  TNaming_Scope&                    MDF,
901                                                  const TopoDS_Shape&               S,
902                                                  const Handle(TNaming_NamedShape)& Context,
903                                                  const Handle(TNaming_NamedShape)& Stop,
904                                                  const Standard_Boolean            Geometry)
905
906 {
907   // il faut determiner un nouveau context et un nouveau Stop.
908   // it is necessary to determine a new context and a new Stop
909   TopoDS_Shape SC;
910   Handle(TNaming_NamedShape) NewStop = Stop;
911   
912   TNaming_Localizer::FindShapeContext (Context,S,SC);
913
914   if(!SC.IsNull()){
915 // <Context> is Ident.NamedShapeOfGeneration() ==
916     TDF_Label Father = Context->Label().Father();
917     Father.FindAttribute(TNaming_NamedShape::GetID(),NewStop);
918 #ifdef OCCT_DEBUG_INNS
919     if(!Stop.IsNull())
920       {cout <<" Stop NS : "; Print_Entry( Stop->Label());}
921     if(!NewStop.IsNull())
922       {cout <<" NewStop : ";  Print_Entry( NewStop->Label());}
923     cout <<"ContextLabel: "; Print_Entry( Context->Label());
924     cout <<"Father      : "; Print_Entry( Father);
925 #endif
926   }
927 #ifdef OCCT_DEBUG_INNS
928   if(NewStop.IsNull())
929     cout <<"BuildNameInNS:: NewStop shape is  NULL" << endl;  
930 #endif 
931   return BuildName (F,MDF,S,SC,NewStop,Geometry);
932 }
933
934 //=======================================================================
935 //function : 
936 //purpose  : 
937 //=======================================================================
938
939 static Handle(TNaming_NamedShape) BuildName (const TDF_Label&                  F,
940                                              TNaming_Scope&               MDF,
941                                              const TopoDS_Shape&               Selection,
942                                              const TopoDS_Shape&               Context,
943                                              const Handle(TNaming_NamedShape)& Stop,
944                                              const Standard_Boolean            Geom)
945 {
946
947  
948   
949   // Create an identifier
950   Standard_Boolean OnlyOne      = !Geom;
951   Standard_Boolean IsGeneration = Standard_False;
952 #ifdef OCCT_DEBUG_MOD
953   cout <<"BuildName: F =>  ";
954   Print_Entry(F);
955   cout <<" Selection type = " << Selection.ShapeType() << " TS = " << Selection.TShape()->This() << endl;
956   Write(Selection, "BName_Selection.brep");
957   Write(Context, "BName_Context.brep");
958 #endif
959   TNaming_Identifier Ident(F, Selection, Context,OnlyOne);
960
961   Handle (TNaming_Naming)  Naming;
962   Handle (TNaming_NamedShape) NS;
963
964   if (!Ident.IsDone()) {
965     return BuildNS (F,Selection, TNaming_UNKNOWN);
966   }
967   if (Ident.IsFeature() && Stop.IsNull()) {
968     //-------------
969     // Deja Nomme
970     //-------------
971     if   (!OnlyOne) return Ident.FeatureArg();
972     else            NS =   Ident.FeatureArg();
973   }
974   else {  
975     //---------------------------------------------
976     // Construction de la fonction d identification.
977     //---------------------------------------------
978     //Standard_Boolean NotOnlyOne = 0;
979
980     Naming = TNaming_Naming::Insert(F);
981    
982     TNaming_Name& theName = Naming->ChangeName();
983     theName.ShapeType(Selection.ShapeType());
984     theName.Shape(Selection);
985         theName.Orientation(Selection.Orientation());
986     theName.Type(Ident.Type());
987 #ifdef OCCT_DEBUG_MOD
988     cout <<"BuildName: Inserted Naming Att at ";
989     Print_Entry(Naming->Label());
990     cout <<" NameType = " << theName.Type() <<endl;             
991 #endif
992     if (Ident.IsFeature()) {
993       theName.Append(Ident.FeatureArg());
994     }
995     if (theName.Type() == TNaming_GENERATION) { 
996       theName.Append(Ident.NamedShapeOfGeneration());
997       IsGeneration = Standard_True;
998     } 
999     if (theName.Type() == TNaming_CONSTSHAPE) {
1000       theName.Index(FindIndex(Ident.FeatureArg(),Selection));
1001     } 
1002     //------------------------------------
1003     // Renseignement du NamedShape d arret.
1004     //------------------------------------
1005     theName.StopNamedShape (Stop);
1006 #ifdef OCCT_DEBUG_MOD
1007     if(!Stop.IsNull()) {
1008         TCollection_AsciiString Es;
1009       TDF_Tool::Entry(Stop->Label(), Es);
1010       cout <<"StopNS at Label = "<< Es << endl;
1011     }
1012 #endif 
1013     //---------------------------------
1014     // Identification des arguments. 
1015     //---------------------------------
1016
1017     for (Ident.InitArgs(); Ident.MoreArgs(); Ident.NextArg()) {
1018       if (Ident.ArgIsFeature()) {
1019         theName.Append(Ident.FeatureArg());
1020 #ifdef OCCT_DEBUG_MOD
1021         if(!Ident.FeatureArg().IsNull()) {
1022           TCollection_AsciiString E;
1023           TDF_Tool::Entry(Ident.FeatureArg()->Label(), E);
1024           cout <<"Added argument NS from Label = "<< E << endl;
1025         }
1026 #endif 
1027       }
1028       else {
1029 #ifdef OCCT_DEBUG_MOD
1030           cout <<"BuildName: NameType = " <<theName.Type() << " NS ";
1031           Print_Entry(Naming->Label());
1032           cout <<"Ident.ShapeArg() type = " << Ident.ShapeArg().ShapeType() << " TS = " << Ident.ShapeArg().TShape()->This() << endl;   
1033            Write(Ident.ShapeArg(), "BName_ShapeArg.brep");
1034 #endif  
1035           if (theName.Type() == TNaming_GENERATION)
1036           theName.Append(BuildNameInNS(Naming->Label(),MDF,Ident.ShapeArg(),Ident.NamedShapeOfGeneration(),Stop,Geom));
1037         else 
1038           theName.Append(BuildName(Naming->Label(),MDF,Ident.ShapeArg(),Context,Stop,Geom));
1039       }
1040     }
1041
1042     //------------------------
1043     // Reconstruction of Name
1044     //------------------------
1045     Naming->Regenerate(MDF.ChangeValid()); 
1046 #ifdef OCCT_DEBUG_MOD
1047     TCollection_AsciiString E2;
1048     TDF_Tool::Entry(Naming->Label(), E2);
1049     cout <<"Regenerated Naming Att at Label = "<< E2 << endl;
1050 #endif 
1051     Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1052     if(NS.IsNull()) return NS; 
1053     if (MDF.WithValid()) MDF.Valid(NS->Label());
1054 #ifdef OCCT_DEBUG_MOD
1055     if(!NS.IsNull()) {
1056       TCollection_AsciiString E;
1057       TDF_Tool::Entry(NS->Label(), E);
1058       cout <<"Regenerated NS at Label = "<< E << endl;
1059     }
1060 #endif 
1061   }
1062
1063   if (OnlyOne) {
1064     //-------------------------------------------------
1065     // Filtre par les voisins
1066     // pour construire le nom correspondant a S.
1067     //------------------------------------------------- 
1068
1069    if(NS.IsNull()) return NS; 
1070
1071     TNaming_Localizer Localizer;
1072     TNaming_Iterator itNS(NS); 
1073     if (itNS.More()) {
1074       //----------------
1075       // Check + Filtre
1076       //----------------
1077
1078       Standard_Boolean StandardFilter = !IsGeneration;
1079       if (IsGeneration) {
1080         if (!CompareInGeneration (NS,Selection)) {
1081
1082           TopoDS_Shape               NewContext;
1083           Handle(TNaming_NamedShape) NewStop;
1084           FindNewShapeInFather (Ident.NamedShapeOfGeneration(),NewContext);
1085           Filter (F,MDF,Selection,NewContext,Localizer,NS,0);
1086         }
1087       } else if (Ident.Type() == TNaming_MODIFUNTIL ||
1088                  (Ident.Type() == TNaming_INTERSECTION && Naming->ChangeName().Arguments().Extent() == 1)) {
1089 #ifdef OCCT_DEBUG_MOD
1090         cout <<"BuildName(CompareInModification): NameType = " <<Ident.Type() << " NS ";
1091         Print_Entry(Ident.Type() == TNaming_MODIFUNTIL ? NS->Label() : Naming->ChangeName().Arguments().First()->Label());
1092         cout <<"Selection type = " << Selection.ShapeType() << " TS = " << Selection.TShape()->This() << endl;  
1093 #endif
1094         Handle(TNaming_NamedShape) NewNS =
1095           CompareInModification(Ident.Type() == TNaming_MODIFUNTIL ? NS : Naming->ChangeName().Arguments().First(), Selection);
1096         if (!NewNS.IsNull()) { // there is need to describe name in detail: modification with type 1:n in the same label
1097           StandardFilter = Standard_False;
1098           if (Ident.IsFeature()) { // for MODIFUNTIL: change it to the GENERATION
1099             Naming = TNaming_Naming::Insert(F);
1100             TNaming_Name& theName = Naming->ChangeName();
1101             theName.ShapeType(Selection.ShapeType());
1102             theName.Shape(Selection); 
1103                 theName.Orientation(Selection.Orientation());
1104             theName.Type(TNaming_GENERATION);
1105             theName.Append(TNaming_Tool::NamedShape(Selection,F));
1106             theName.Append(NewNS);
1107             Naming->Regenerate(MDF.ChangeValid());
1108             Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1109
1110           }
1111           Filter (F,MDF,Selection,Context,Localizer,NS,0);
1112         }
1113       }
1114       if (StandardFilter) if (!Compare (NS,MDF,Stop,Selection)) {
1115         Filter (F,MDF,Selection,Context,Localizer,NS,0);
1116       }
1117     }
1118   }
1119   if (MDF.WithValid()) MDF.Valid(NS->Label());
1120 #ifdef OCCT_DEBUG_MOD
1121     if(!NS.IsNull()) {
1122       TCollection_AsciiString E;
1123       TDF_Tool::Entry(NS->Label(), E);
1124       cout <<"Returned NS from Label = "<< E << endl;
1125     }
1126 #endif 
1127   return NS;
1128 }
1129
1130 //=======================================================================
1131 //function : Validate
1132 //purpose  : 
1133 //=======================================================================
1134
1135 static void Validate(TNaming_Scope&    MDF,
1136                      TNaming_OldShapeIterator& it)
1137 {
1138   MDF.Valid(it.Label()); 
1139   MDF.ValidChildren(it.Label());
1140
1141   TNaming_OldShapeIterator it2(it);
1142   for (; it2.More(); it2.Next()) {
1143     Validate (MDF,it2);
1144   }
1145 }
1146
1147 //=======================================================================
1148 //function : UnValidate
1149 //purpose  : 
1150 //=======================================================================
1151
1152 static void UnValidate(TNaming_Scope&    MDF,
1153                        TNaming_NewShapeIterator& it)
1154 {
1155   MDF.Unvalid(it.Label()); 
1156   MDF.UnvalidChildren(it.Label());
1157
1158   TNaming_NewShapeIterator it2(it);
1159   for (; it2.More(); it2.Next()) {
1160     UnValidate (MDF,it2);
1161   }
1162 }
1163
1164 //=======================================================================
1165 //function : BuildScope
1166 //purpose  : adds to the MDF the label of <Context> NamedShape, 
1167 //         : its children, all its oldShapes and its children.
1168 //         : unvalidates all newShapes and it's children.
1169 //         : If <Context> is null or next modification has an empty newShape 
1170 //         : ( this shape was deleted ), then MDF.WithValid(Standard_False) 
1171 //         : and nothing is added to the scope.
1172 //=======================================================================
1173
1174 static void BuildScope (TNaming_Scope&    MDF,
1175                              const TopoDS_Shape&    Context,
1176                              const TDF_Label&       Acces) 
1177 {
1178   if (Context.IsNull()) {
1179     MDF.WithValid(Standard_False);
1180     return;
1181   }
1182
1183   //----------------------------------------------------
1184   // Is context the current state
1185   //----------------------------------------------------
1186   Handle(TNaming_NamedShape) NS   = TNaming_Tool::NamedShape(Context,Acces);
1187   Handle(TNaming_NamedShape) Next = NextModif(NS); // if NS has subsequent evolution = MODIFY, return it
1188   if (Next.IsNull()) {  
1189     MDF.WithValid(Standard_False);
1190     return;
1191   }
1192   //----------------------------- 
1193   // a posteriori naming
1194   //-----------------------------  
1195   MDF.WithValid(Standard_True);
1196   MDF.Valid(NS->Label());
1197   MDF.ValidChildren(NS->Label());
1198   TNaming_OldShapeIterator it(Context,Acces);
1199
1200   for (; it.More(); it.Next()) {
1201     Validate(MDF,it);
1202   }
1203
1204   TNaming_NewShapeIterator it2(Context,Acces);
1205   for (;it2.More(); it2.Next()) {
1206     UnValidate (MDF,it2);
1207   }
1208 }
1209
1210 //=======================================================================
1211 //function : HasAncFace
1212 //purpose  : Returns True & <Face> if ancestor face is found
1213 //=======================================================================
1214 static Standard_Boolean HasAncFace(const TopoDS_Shape& Context, 
1215                                    const TopoDS_Shape& W, TopoDS_Shape& Face, Standard_Boolean& isOuter)
1216
1217   Standard_Boolean hasFace(Standard_False);
1218   if(W.ShapeType() != TopAbs_WIRE)
1219     return hasFace;
1220   TopExp_Explorer exp(Context, TopAbs_FACE);
1221   for(;exp.More(); exp.Next()) {
1222     for (TopoDS_Iterator it(exp.Current()) ; it.More(); it.Next()) {
1223       if(it.Value().IsEqual(W)) {// is the Wire ?
1224             Face = exp.Current();
1225             if(!Face.IsNull()) {
1226               hasFace = Standard_True;
1227         //        cout << "HasAncFace: TS = " <<theFace.TShape()->This() <<endl;
1228                   const TopoDS_Face aFace(TopoDS::Face(Face));
1229                   TopoDS_Wire anOuterW; 
1230                   if(TNaming::OuterWire(aFace, anOuterW)) {
1231                     if(!anOuterW.IsNull() && anOuterW.IsEqual(W)) 
1232                           isOuter = Standard_True;
1233                     else 
1234                           isOuter = Standard_False;             
1235                   }
1236               break;                              
1237                 }
1238           }
1239         }
1240     if(hasFace) break;
1241   }
1242   return hasFace;
1243 }
1244
1245 //=======================================================================
1246 //function : BuildNameWire
1247 //purpose  : Names Wire
1248 //=======================================================================
1249
1250 static Handle(TNaming_NamedShape) BuildNameWire (const TDF_Label&                  F,
1251                                                  TNaming_Scope&                    MDF,
1252                                                  const TopoDS_Shape&               Selection,
1253                                                  const TopoDS_Shape&               Context,
1254                                                  const Handle(TNaming_NamedShape)& Stop,
1255                                                  const Standard_Boolean            Geom)
1256 {  
1257   Handle (TNaming_NamedShape) NS;
1258   Standard_Boolean found(Standard_False);
1259   Handle (TNaming_Naming)  Naming;
1260   if(!F.FindAttribute(TNaming_Naming::GetID(), Naming)) {
1261     Naming = new TNaming_Naming ();
1262     F.AddAttribute (Naming);
1263     TNaming_Name& theName = Naming->ChangeName();
1264     theName.ShapeType(Selection.ShapeType());
1265     theName.Shape(Selection);
1266         theName.Orientation(Selection.Orientation());
1267   } 
1268
1269   TNaming_Name& theName = Naming->ChangeName();  
1270   TopoDS_Shape aFace;
1271   Standard_Boolean isOuter(Standard_False);
1272   Standard_Boolean hasFace = HasAncFace(Context, Selection, aFace, isOuter);  
1273   if(hasFace && Selection.ShapeType() > Context.ShapeType()) {
1274     theName.Type(TNaming_WIREIN);
1275         if(Context.ShapeType() == TopAbs_FACE) {
1276                 for (TopoDS_Iterator it(Context) ; it.More(); it.Next()) {
1277                   if(it.Value().IsEqual(Selection)) {
1278                 if (TNaming_Selector::IsIdentified (F, Context, NS, Geom)) {            
1279                   theName.Append(NS);
1280                   found = Standard_True;
1281                   break;
1282                         }
1283                   }
1284           }
1285                 if(found) {
1286                   theName.Append(BuildName (Naming->Label(),MDF,aFace,Context,Stop,Geom));
1287                   if(isOuter) {
1288                     theName.Index(1);
1289                   } else {
1290                           theName.Index(-1);
1291                           for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) {
1292                             if(exp.Current().IsNull()) continue;
1293                             if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue;
1294                              theName.Append(TNaming_Naming::Name(Naming->Label(),exp.Current(),Context, Geom, 1, 0));
1295                           }
1296                   }
1297                 } else
1298                return BuildNS (F,Selection, TNaming_UNKNOWN);
1299
1300         } else { // context is not Face
1301                 theName.Append(BuildName (Naming->Label(),MDF,aFace,Context,Stop,Geom));
1302                 if(isOuter) {
1303                 theName.Index(1);
1304                 } else {
1305                         for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) {
1306                           if(exp.Current().IsNull()) continue;
1307                           if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue;
1308                            theName.Append(TNaming_Naming::Name(Naming->Label(),exp.Current(),Context, Geom, 1, 0));
1309                         }
1310                 }
1311         }//
1312   } 
1313   else { // => no Face
1314     theName.Type(TNaming_UNION);
1315     for (TopExp_Explorer exp(Selection,TopAbs_EDGE) ; exp.More(); exp.Next()) {
1316           if(exp.Current().IsNull()) continue;
1317       if (BRep_Tool::Degenerated(TopoDS::Edge(exp.Current()))) continue;
1318       theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1319     }
1320   }
1321   //Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
1322   Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);  
1323   return NS;
1324 }
1325
1326 //=======================================================================
1327 static Standard_Boolean IsOneIn (const TopoDS_Shape& S, const TopoDS_Shape& Context)
1328 {
1329   Standard_Boolean found(Standard_False);
1330   if(S.IsNull() || Context.IsNull()) return found;
1331   for (TopExp_Explorer exp(Context,S.ShapeType()); exp.More(); exp.Next()) {
1332     if (exp.Current().IsEqual(S)) {
1333       found = Standard_True;
1334       break;
1335     }
1336   }
1337   return found;
1338 }
1339
1340 //=======================================================================
1341 static Standard_Boolean IsAllIn (const TopoDS_Shape& S, const TopoDS_Shape& Context)
1342 {
1343 #ifdef OCCT_DEBUG_CC
1344   Write(S, "IsAllIn_Sel.brep");
1345 #endif
1346   Standard_Boolean found(Standard_False);
1347   if(S.IsNull() || Context.IsNull()) return found;
1348   Standard_Integer num1(0), num2(0);
1349   for(TopoDS_Iterator it(S);it.More();it.Next(),num1++) {
1350 #ifdef OCCT_DEBUG_CC
1351   cout <<"S sub-shape type = " << it.Value().ShapeType() <<endl;
1352   Write (it.Value(), "Sel_ItValue.brep");
1353 #endif
1354   if(it.Value().ShapeType() != TopAbs_COMPOUND)
1355     for (TopExp_Explorer exp(Context,it.Value().ShapeType()); exp.More(); exp.Next()) {
1356 #ifdef OCCT_DEBUG_CC
1357   cout <<"Context sub-shape type = " << exp.Current().ShapeType() <<endl;
1358   Write(exp.Current(), "Contex_Curnt.brep");
1359 #endif
1360       if (exp.Current().IsEqual(it.Value())) { 
1361         num2++;
1362         break;
1363       }
1364     } else {
1365       Standard_Boolean isAll = IsAllIn(it.Value(), Context);
1366       if(isAll) 
1367         num2++;
1368     }
1369   }
1370   if(num1 == num2)
1371     found = Standard_True;
1372 #ifdef OCCT_DEBUG_CC
1373   else
1374     cout <<"Compound case : selected num1 = " << num1 << " context contains num2 = " << num2 << endl;
1375 #endif
1376   return found;
1377 }
1378 //=======================================================================
1379 //function : RepeatabilityInContext
1380 //purpose  : 
1381 //=======================================================================
1382 static Standard_Integer RepeatabilityInContext(const TopoDS_Shape& Selection, 
1383                                                const TopoDS_Shape& Context)
1384 {
1385   Standard_Integer aNum(0);
1386   if (!Context.IsNull() && !Selection.IsNull()) {
1387 //    Write(Selection, "Repeat_Selection.brep");
1388 //    Write(Context, "Repeat_Context.brep");
1389     if (Context.ShapeType() < Selection.ShapeType()) {
1390           if(Selection.ShapeType() != TopAbs_SHELL) {
1391         for (TopExp_Explorer exp(Context,Selection.ShapeType()); exp.More(); exp.Next()) {
1392               if (exp.Current().IsSame(Selection)) 
1393                 aNum++;
1394                 }
1395           } 
1396         }
1397     else if(Selection.ShapeType() == TopAbs_COMPOUND) {
1398       TopoDS_Iterator it(Selection);
1399       for(;it.More();it.Next()) {
1400         Standard_Integer n(0);
1401         for (TopExp_Explorer exp(Context,it.Value().ShapeType()); exp.More(); exp.Next()) {
1402           if (exp.Current().IsSame(it.Value())) {
1403             n++;
1404           }
1405         }
1406         if(n > aNum) aNum = n;
1407       }
1408     } 
1409   }
1410 #ifdef OCCT_DEBUG_OR
1411       cout <<"RepeatabilityInContext: = " <<aNum <<endl;
1412 #endif 
1413   return aNum;
1414 }
1415
1416 //=======================================================================
1417 //function : HasAncSolid
1418 //purpose  : Returns true if Sh has ancestor solid in this context
1419 //=======================================================================
1420 static Standard_Boolean HasAncSolid(const TopoDS_Shape& Context, 
1421                                                const TopoDS_Shape& Sh, TopoDS_Shape& Solid, 
1422                                                Standard_Boolean& isOuter)
1423
1424   Standard_Boolean hasSolid(Standard_False);
1425   if(Sh.ShapeType() != TopAbs_SHELL)
1426     return hasSolid;
1427   TopExp_Explorer exp(Context, TopAbs_SOLID);
1428   for(;exp.More(); exp.Next()) {
1429     for (TopoDS_Iterator it(exp.Current()) ; it.More(); it.Next()) {
1430       if(it.Value().IsEqual(Sh)) {// is the Solid ?
1431             Solid = exp.Current();
1432             if(!Solid.IsNull()) {
1433               hasSolid = Standard_True;
1434                   TopoDS_Shell anOuterShell;            
1435                   if(TNaming::OuterShell(TopoDS::Solid(Solid), anOuterShell)) {
1436 #ifdef OCCT_DEBUG_TSOL
1437                 Write(anOuterShell, "OuterShell.brep");
1438 #endif
1439                     if(!anOuterShell.IsNull() && anOuterShell.IsEqual(Sh))
1440                           isOuter = Standard_True;
1441                     else 
1442                           isOuter = Standard_False;
1443                   }
1444               break;
1445                 }
1446           }
1447         }
1448     if(hasSolid) break;
1449   }
1450   return hasSolid;
1451 }
1452 //=======================================================================
1453 //function : BuildNameShell
1454 //purpose  : Names Shell
1455 //=======================================================================
1456
1457 static Handle(TNaming_NamedShape) BuildNameShell (const TDF_Label& F,
1458                                                  TNaming_Scope&                    MDF,
1459                                                  const TopoDS_Shape&               Selection,
1460                                                  const TopoDS_Shape&               Context,
1461                                                  const Handle(TNaming_NamedShape)& Stop,
1462                                                  const Standard_Boolean            Geom)
1463 {  
1464   Handle (TNaming_NamedShape) NS;
1465   Standard_Boolean found(Standard_False);
1466   Handle (TNaming_Naming)  Naming;
1467   if(!F.FindAttribute(TNaming_Naming::GetID(), Naming)) {
1468     Naming = new TNaming_Naming ();
1469     F.AddAttribute (Naming);
1470     TNaming_Name& theName = Naming->ChangeName();
1471     theName.ShapeType(Selection.ShapeType());
1472     theName.Shape(Selection);
1473         theName.Orientation(Selection.Orientation());
1474   } 
1475
1476   TNaming_Name& theName = Naming->ChangeName(); 
1477   TopoDS_Shape aSolid;
1478   Standard_Boolean isOuter(Standard_False);
1479   Standard_Boolean hasSolid = HasAncSolid(Context, Selection, aSolid, isOuter);  
1480   if(hasSolid && Selection.ShapeType() > Context.ShapeType()) {
1481     theName.Type(TNaming_SHELLIN);// SHELLIN
1482
1483         if(Context.ShapeType() == TopAbs_SOLID) {
1484                 for (TopoDS_Iterator it(Context) ; it.More(); it.Next()) {
1485 #ifdef OCCT_DEBUG_TSOL
1486           Write(it.Value(), "Shell_inSo.brep");
1487 #endif
1488                 if(it.Value().IsEqual(Selection)) {
1489                 found = Standard_True;
1490                 break;
1491                   }
1492           }
1493           if(found) {
1494                 // solid => aSolid which is also a context
1495                   Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1496                   if(!aNS.IsNull())
1497                         theName.ContextLabel(aNS->Label());       
1498                   theName.Append(aNS);
1499                   if(isOuter) {
1500                     theName.Index(1);                            
1501                   } else { //not OuterShell
1502             theName.Index(-1);
1503                         for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) {
1504                           if(exp.Current().IsNull()) continue;
1505                           theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1506                         }
1507                   }
1508           } else
1509                   return BuildNS (F,Selection, TNaming_UNKNOWN);
1510         } else { 
1511         // context is not SOLID
1512                 //theName.Append(BuildName (Naming->Label(),MDF,aSolid,Context,Stop,Geom));//###########                
1513                 if(isOuter) {
1514 #ifdef OCCT_DEBUG_TSOL
1515           Write(aSolid, "foundSolid.brep");
1516 #endif
1517                   theName.Index(1);
1518                   Handle (TNaming_Naming)  NamingSo = TNaming_Naming::Insert(F); 
1519                   TNaming_Name&           theNameSo = NamingSo->ChangeName();
1520           theNameSo.ShapeType(aSolid.ShapeType());
1521           theNameSo.Shape(aSolid);       
1522           theNameSo.Type(TNaming_UNION);
1523                   Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1524                   if(!aNS.IsNull())
1525                         theNameSo.ContextLabel(aNS->Label());
1526               for (TopExp_Explorer exp(aSolid,TopAbs_FACE) ; exp.More(); exp.Next()) 
1527                 theNameSo.Append(BuildName (NamingSo->Label(),MDF,exp.Current(),Context,Stop,Geom));
1528                   NamingSo->GetName().Solve(NamingSo->Label(),MDF.GetValid());
1529                   aNS.Nullify();
1530                   NamingSo->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS); 
1531                   theName.Append(aNS);
1532                 } else {
1533                         theName.Index(-1);
1534                         // - name Solid: theName.Append(BuildName (Naming->Label(),MDF, aSolid,Context,Stop,Geom));
1535                     Handle (TNaming_Naming)  NamingSo = TNaming_Naming::Insert(F); 
1536                     TNaming_Name&           theNameSo = NamingSo->ChangeName();
1537             theNameSo.ShapeType(aSolid.ShapeType());
1538             theNameSo.Shape(aSolid);       
1539             theNameSo.Type(TNaming_UNION);
1540                     Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1541                     if(!aNS.IsNull())
1542                           theNameSo.ContextLabel(aNS->Label());
1543                 for (TopExp_Explorer exp(aSolid,TopAbs_FACE) ; exp.More(); exp.Next()) 
1544                   theNameSo.Append(BuildName (NamingSo->Label(),MDF,exp.Current(),Context,Stop,Geom));                  
1545                         NamingSo->GetName().Solve(NamingSo->Label(),MDF.GetValid());
1546                         aNS.Nullify();
1547                         NamingSo->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS); 
1548                     theName.Append(aNS);
1549
1550                         for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) {
1551                           if(exp.Current().IsNull()) continue;
1552                           theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1553                         }
1554                 }
1555         }//
1556   } 
1557   else { // => no Solid
1558     theName.Type(TNaming_UNION);
1559         Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(Context,F);
1560         if(!aNS.IsNull())
1561           theName.ContextLabel(aNS->Label());
1562     for (TopExp_Explorer exp(Selection,TopAbs_FACE) ; exp.More(); exp.Next()) {
1563           if(exp.Current().IsNull()) continue;     
1564       theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1565     }
1566   }
1567   //Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
1568   Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);  
1569   return NS;
1570 }
1571
1572 //=======================================================================
1573 //function : BuildAggregationNam
1574 //purpose  : 
1575 //=======================================================================
1576 static void BuildAggregationName (const TDF_Label&                  F,
1577                                   TNaming_Scope&                    MDF,
1578                                   const TopoDS_Shape&               S,
1579                                   const TopoDS_Shape&               Context,
1580                                   const Handle(TNaming_NamedShape)& Stop,
1581                                   const Standard_Boolean            Geom)
1582 {
1583   const Standard_Boolean found2 = IsAllIn(S, Context); 
1584   Handle (TNaming_Naming)  Naming;
1585   if(!F.FindAttribute(TNaming_Naming::GetID(), Naming)) {
1586     Naming = new TNaming_Naming ();
1587     F.AddAttribute (Naming);
1588     TNaming_Name& theName = Naming->ChangeName();
1589     theName.ShapeType(S.ShapeType());
1590     theName.Shape(S); 
1591         theName.Orientation(S.Orientation());
1592   } 
1593 #ifdef OCCT_DEBUG_CC
1594   cout <<"BuildAggregationName ==> ";
1595   Print_Entry(Naming->Label());
1596 #endif
1597   TNaming_Name& theName = Naming->ChangeName();  
1598   for (TopoDS_Iterator itc(S) ; itc.More(); itc.Next()) {
1599     const TopoDS_Shape& aS = itc.Value();
1600     if ((aS.ShapeType() == TopAbs_SOLID && !TNaming_Tool::NamedShape(aS,Naming->Label()).IsNull()) ||
1601         aS.ShapeType() == TopAbs_FACE  ||
1602         aS.ShapeType() == TopAbs_EDGE  ||
1603         aS.ShapeType() == TopAbs_VERTEX ) {
1604       theName.Append(BuildName (F, MDF, aS,Context,Stop,Geom));
1605     } else { // ==> union of union || union of wires
1606       TopAbs_ShapeEnum atomTyp; 
1607       switch (aS.ShapeType()) 
1608         {
1609         case TopAbs_SOLID:
1610         case TopAbs_SHELL:
1611           atomTyp = TopAbs_FACE;
1612           break;
1613         case TopAbs_WIRE:
1614           atomTyp = TopAbs_EDGE;
1615           break;
1616         default: 
1617           atomTyp = TopAbs_SHAPE;
1618         }
1619       
1620       Handle(TNaming_NamedShape) aNS;
1621       Handle (TNaming_Naming)  aNaming = TNaming_Naming::Insert(F); 
1622       TNaming_Name&               aName = aNaming->ChangeName();          
1623       aName.ShapeType(aS.ShapeType());
1624       aName.Shape(aS);
1625           theName.Orientation(aS.Orientation());
1626       aName.Type(TNaming_UNION);
1627       
1628       if (atomTyp != TopAbs_SHAPE) {
1629         if(aS.ShapeType() == TopAbs_WIRE) {
1630           aNS = BuildNameWire (aNaming->Label(), MDF, aS, Context,Stop,Geom);
1631         }
1632          else if(aS.ShapeType() == TopAbs_SHELL) 
1633             aNS = BuildNameShell (aNaming->Label(), MDF, aS, Context,Stop,Geom);
1634         else {
1635           for (TopExp_Explorer exp(aS,atomTyp) ; exp.More(); exp.Next()) {
1636             aName.Append(BuildName (aNaming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1637           }
1638         }
1639       } else {
1640 #ifdef OCCT_DEBUG_CC
1641         cout << "atomic type is NOT defined ... ==> Aggregation" <<endl;
1642 #endif
1643         BuildAggregationName(aNaming->Label(),MDF, aS, Context,Stop,Geom);
1644       }
1645       if(found2) {
1646         aNS = TNaming_Tool::NamedShape(Context, F);
1647         if(!aNS.IsNull()) 
1648           aNaming->ChangeName().ContextLabel(aNS->Label());
1649       }
1650       
1651       aNaming->GetName().Solve(aNaming->Label(),MDF.GetValid());
1652       if(aNaming->Label().FindAttribute(TNaming_NamedShape::GetID(),aNS))
1653         if (!Geom && TestSolution(MDF,aNS,aS)) {
1654           theName.Append(aNS);
1655         }
1656     }
1657   }
1658 }
1659
1660
1661 //=======================================================================
1662 //function : Name
1663 //purpose  : 
1664 //=======================================================================
1665
1666 Handle(TNaming_NamedShape) TNaming_Naming::Name (const TDF_Label&       F,
1667                                                  const TopoDS_Shape&    S,
1668                                                  const TopoDS_Shape&    Context,
1669                                                  const Standard_Boolean Geom,
1670                                                  const Standard_Boolean KeepOrientation,
1671                                                  const Standard_Boolean BNProblem)
1672
1673 {
1674   Handle(TNaming_NamedShape) aNamedShape;
1675   if (KeepOrientation) {
1676 #ifdef OCCT_DEBUG_INNS
1677     cout <<"KeepOR = 1: "; Print_Entry(F);
1678 #endif
1679     Standard_Integer aNum = RepeatabilityInContext(S, Context);
1680
1681     Standard_Boolean aBNproblem = (BNProblem) ? (aNum /*== 1*/ && S != Context) : Standard_False;
1682
1683     if (aNum > 1 || aBNproblem) {
1684       TopoDS_Shape UC = TNaming::FindUniqueContext(S, Context);
1685       Handle(TopTools_HArray1OfShape) Arr;
1686       if (UC.IsNull() && S.ShapeType() == TopAbs_COMPOUND) {
1687         UC = TNaming::FindUniqueContextSet(S, Context, Arr);
1688 #ifdef OCCT_DEBUG_CC
1689         Write(UC, "UniqueContextSet.brep");
1690         Write(S,  "InitialSelection.brep");
1691         if(S.ShapeType()==TopAbs_COMPOUND) {
1692           TCollection_AsciiString aNam("S_");
1693           TopoDS_Iterator it(S);
1694           for(int i=1;it.More();it.Next(),i++) {           
1695             TCollection_AsciiString aName = aNam + i + ".brep";     
1696             Write(it.Value(), aName.ToCString());
1697           }
1698         }
1699 #endif  
1700       }
1701       if(!UC.IsNull()) {
1702         Handle (TNaming_Naming)  Naming = TNaming_Naming::Insert(F);
1703         TNaming_Name&           theName = Naming->ChangeName();
1704         theName.ShapeType(S.ShapeType());
1705         theName.Shape(S); 
1706         theName.Type(TNaming_ORIENTATION);
1707         theName.Orientation(S.Orientation());
1708
1709         if (!TNaming_Selector::IsIdentified (F, S, aNamedShape, Geom))
1710     aNamedShape = TNaming_Naming::Name(Naming->Label(),S,Context,Geom,0);
1711         theName.Append (aNamedShape);
1712 #ifdef MDTV_OR
1713         cout << " Sel Label ==> "; Print_Entry(NS->Label());
1714 #endif
1715 //szy 21.10.2009        
1716         if(S.ShapeType() == TopAbs_EDGE && UC.ShapeType() == TopAbs_FACE) {
1717           if(RepeatabilityInContext(S, UC) == 2) { //sim. edge
1718             TopoDS_Iterator itw(UC);
1719             for(;itw.More();itw.Next()) {
1720               Standard_Boolean found(Standard_False);
1721               TopoDS_Iterator it(itw.Value());
1722               for(int i=1;it.More();it.Next(),i++) {
1723                 if(it.Value().IsEqual(S)) {
1724                   theName.Index(i);//We use this field to save a Seam Shape Index; Before this field was used for GENERATED only
1725                   found = Standard_True;
1726 #ifdef MDTV_OR
1727                   cout << "ORDER = " << i <<endl;
1728 #endif
1729                   break;
1730                 }
1731               }
1732               if(found) break;
1733             }
1734           }
1735         }
1736 //      
1737         if(S.ShapeType() == TopAbs_COMPOUND && Arr->Length() > 1) {
1738           // N arguments: to be optimized to avoid duplication of the same Context shape
1739           for(Standard_Integer i = Arr->Lower(); i <= Arr->Upper(); i++) {
1740       aNamedShape = TNaming_Naming::Name(Naming->Label(), Arr->Value(i), Context, Geom, 1, aBNproblem);
1741             theName.Append (aNamedShape);
1742           }
1743         } else {          
1744     aNamedShape = TNaming_Naming::Name(Naming->Label(),UC,Context, Geom, 1, aBNproblem);
1745           theName.Append (aNamedShape);
1746 #ifdef MDTV_OR
1747         cout << " Cont Label ==> "; Print_Entry(NS->Label());
1748 #endif
1749         }
1750       //Naming->Update();
1751         TNaming_Scope MDF;
1752         BuildScope (MDF,Context,F);
1753         Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
1754         Naming->Label().FindAttribute(TNaming_NamedShape::GetID(), aNamedShape);
1755         theName.ContextLabel(aNamedShape->Label());
1756         if (Geom) return aNamedShape;
1757         if(aNamedShape.IsNull()) {
1758         cout <<" %%% WARNING: TNaming_Naming::Name:  FAILED"<<endl;
1759         return BuildNS (F,S, TNaming_UNKNOWN);
1760       }
1761
1762         if (!Geom && TestSolution(MDF, aNamedShape,S)) return aNamedShape;
1763         cout <<" %%% WARNING: TNaming_Naming::Name:  FAILED"<<endl;
1764
1765         // Naming n is  unsatisfactory
1766         return BuildNS (F,S, TNaming_UNKNOWN);
1767       }
1768     } else
1769       if (TNaming_Selector::IsIdentified (F, S, aNamedShape, Geom))
1770         return aNamedShape;
1771   }
1772
1773   //------------------------------------------------------------
1774   // Construction du MDF tel que <Context> soit le dernier etat
1775   // valide,
1776   // Ceci pour les localisation a posteriori par exemple. 
1777   //------------------------------------------------------------  
1778
1779   TNaming_Scope MDF;
1780   BuildScope (MDF,Context,F);
1781   Handle(TNaming_NamedShape) Stop;
1782
1783
1784   if ((S.ShapeType() == TopAbs_SOLID && !TNaming_Tool::NamedShape(S,F).IsNull()) ||
1785
1786       S.ShapeType() == TopAbs_FACE  ||
1787       S.ShapeType() == TopAbs_EDGE  ||
1788       S.ShapeType() == TopAbs_VERTEX ) {
1789     //---------------------------------------
1790     // Localisation de S comme element simple.
1791     //---------------------------------------
1792     Handle(TNaming_NamedShape) NS = BuildName (F,MDF,S,Context,Stop,Geom);
1793     if (Geom) return NS; 
1794     if (!Geom && TestSolution(MDF,NS,S)) return NS; 
1795   }
1796   else {
1797     //----------------------------------------------------
1798     // Localisation de S comme ensemble d elements simples.
1799     //-----------------------------------------------------
1800     Handle(TNaming_NamedShape) NS;
1801     Handle (TNaming_Naming)  Naming = TNaming_Naming::Insert(F); 
1802     TNaming_Name&           theName = Naming->ChangeName();
1803
1804     theName.ShapeType(S.ShapeType());// modified by vro 05.09.00
1805     theName.Shape(S); 
1806         theName.Orientation(S.Orientation());
1807     if(S.ShapeType() != TopAbs_WIRE) 
1808       theName.Type(TNaming_UNION);
1809
1810     TopAbs_ShapeEnum atomType;
1811     switch (S.ShapeType()) {
1812     case TopAbs_COMPSOLID:
1813     case TopAbs_SOLID:
1814     case TopAbs_SHELL:
1815       atomType = TopAbs_FACE;
1816       break;
1817     case TopAbs_WIRE:
1818       atomType = TopAbs_EDGE;
1819       break;
1820     default:
1821       atomType = TopAbs_SHAPE;
1822     }
1823     Standard_Boolean found(Standard_False);
1824     if (!Context.IsNull()) {
1825       if (Context.ShapeType() < S.ShapeType()) 
1826         found = IsOneIn(S, Context);
1827       if(found) {
1828         NS = TNaming_Tool::NamedShape(Context, F);
1829         if(!NS.IsNull()) 
1830           theName.ContextLabel(NS->Label());
1831       }
1832     }
1833     if (atomType == TopAbs_SHAPE) {
1834       if(S.ShapeType() == TopAbs_COMPOUND) {
1835         BuildAggregationName(Naming->Label(),MDF, S, Context,Stop,Geom);
1836       } else { 
1837         for (TopoDS_Iterator it(S) ; it.More(); it.Next()) {
1838           theName.Append(BuildName (Naming->Label(),MDF,it.Value(),Context,Stop,Geom));
1839         }
1840       }
1841     } else {
1842       if(S.ShapeType() == TopAbs_WIRE)
1843             NS = BuildNameWire (Naming->Label(), MDF, S, Context,Stop,Geom);
1844           else if(S.ShapeType() == TopAbs_SHELL) {
1845                     NS = BuildNameShell (Naming->Label(), MDF, S, Context,Stop,Geom);
1846           }
1847           else {
1848             theName.Type(TNaming_UNION);
1849             for (TopExp_Explorer exp(S,atomType) ; exp.More(); exp.Next()) {
1850             theName.Append(BuildName (Naming->Label(),MDF,exp.Current(),Context,Stop,Geom));
1851                 }
1852           }
1853     }
1854
1855     //Naming->Update(); 
1856     Naming->GetName().Solve(Naming->Label(),MDF.GetValid());
1857     Naming->Label().FindAttribute(TNaming_NamedShape::GetID(),NS);
1858     if (Geom) return NS; 
1859
1860     if(NS.IsNull()) return BuildNS (F,S, TNaming_UNKNOWN); 
1861
1862     if (!Geom && TestSolution(MDF,NS,S)) return NS; 
1863   }
1864   
1865       cout <<" %%% WARNING: TNaming_Naming::Name:  FAILED"<<endl;
1866
1867   // Naming n is not satisfactory
1868   return BuildNS (F,S, TNaming_UNKNOWN); 
1869 }
1870
1871
1872 //=======================================================================
1873 //function : TNaming_Naming
1874 //purpose  : 
1875 //=======================================================================
1876
1877 TNaming_Naming::TNaming_Naming() {}
1878
1879 //=======================================================================
1880 //function : ID
1881 //purpose  : 
1882 //=======================================================================
1883
1884 const Standard_GUID& TNaming_Naming::ID () const
1885 {
1886   return GetID(); 
1887 }
1888
1889
1890 //=======================================================================
1891 //function : IsDefined
1892 //purpose  : 
1893 //=======================================================================
1894
1895 Standard_Boolean TNaming_Naming::IsDefined() const
1896 {
1897   return (myName.Type() != TNaming_UNKNOWN);
1898 }
1899
1900 //=======================================================================
1901 //function : GetName
1902 //purpose  : 
1903 //=======================================================================
1904
1905 const TNaming_Name& TNaming_Naming::GetName() const
1906 {
1907   return myName;
1908 }
1909
1910 //=======================================================================
1911 //function : ChangeName
1912 //purpose  : 
1913 //=======================================================================
1914
1915 TNaming_Name& TNaming_Naming::ChangeName()
1916 {
1917   return myName;
1918 }
1919
1920 //=======================================================================
1921 //function : Regenerate
1922 //purpose  : idem designer
1923 //=======================================================================
1924
1925 Standard_Boolean TNaming_Naming::Regenerate (TDF_LabelMap& MDF)  
1926
1927 {
1928   return myName.Solve(Label(),MDF);
1929 }
1930
1931
1932 //=======================================================================
1933 //function : NewEmpty
1934 //purpose  : 
1935 //=======================================================================
1936
1937 Handle(TDF_Attribute) TNaming_Naming::NewEmpty () const
1938 {  
1939   return new TNaming_Naming (); 
1940 }
1941
1942
1943 //=======================================================================
1944 //function : Restore
1945 //purpose  : 
1946 //=======================================================================
1947
1948 void TNaming_Naming::Restore(const Handle(TDF_Attribute)& other) 
1949 {
1950   Handle(TNaming_Naming) OtherNaming = Handle(TNaming_Naming)::DownCast(other);
1951   myName = OtherNaming->ChangeName();
1952 }
1953
1954 //=======================================================================
1955 //function : Paste
1956 //purpose  : 
1957 //=======================================================================
1958
1959 void TNaming_Naming::Paste (const Handle(TDF_Attribute)& into,
1960                                const Handle(TDF_RelocationTable)& RT) const
1961 {
1962   Handle(TNaming_Naming) NewNaming = Handle(TNaming_Naming)::DownCast(into);
1963   myName.Paste(NewNaming->ChangeName(),RT);
1964 }
1965   
1966 //=======================================================================
1967 //function : References
1968 //purpose  : Redefined from TDF_Attribute
1969 //=======================================================================
1970
1971 void TNaming_Naming::References(const Handle(TDF_DataSet)& DataSet) const
1972 {
1973   // Iteration on NamedShape of the name
1974   TNaming_ListIteratorOfListOfNamedShape it(myName.Arguments());
1975   for (;it.More();it.Next()) DataSet->AddAttribute(it.Value());
1976   if (!myName.StopNamedShape().IsNull()) DataSet->AddAttribute(myName.StopNamedShape());
1977 }
1978 //=======================================================================
1979 //function : Dump
1980 //purpose  : 
1981 //=======================================================================
1982
1983 Standard_OStream& TNaming_Naming::Dump (Standard_OStream& anOS) const
1984 {  
1985   anOS << "TNaming_Naming";
1986   return anOS;
1987 }
1988
1989
1990 //=======================================================================
1991 //function :ExtendedDump
1992 //purpose  : 
1993 //=======================================================================
1994
1995 void TNaming_Naming::ExtendedDump(Standard_OStream& anOS,
1996                                   const TDF_IDFilter& /*aFilter*/,
1997                                   TDF_AttributeIndexedMap& /*aMap*/) const
1998 {
1999   anOS << "TNaming_Naming ExtendedDump  ";
2000   //anOS<<"myContext: #" <<aMap.Add(myContext)<<endl; 
2001 }
2002