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