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