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