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