0026155: TNaming, CurrentShape: order of shapes in Modification compound is unpredictable
[occt.git] / src / TNaming / TNaming_Name.cxx
1 // Created on: 1997-03-21
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <TNaming_Name.ixx>
18 #include <TNaming.hxx>
19 #include <TNaming_NamingTool.hxx>
20 #include <TNaming_Naming.hxx>
21 #include <TNaming_ShapesSet.hxx>
22 #include <TNaming_Builder.hxx>
23 #include <TNaming_NamedShape.hxx>
24 #include <TNaming_Iterator.hxx>
25 #include <TNaming_NewShapeIterator.hxx>
26 #include <TNaming_ListOfNamedShape.hxx>
27 #include <TNaming_ListIteratorOfListOfNamedShape.hxx>
28 #include <TopExp.hxx>
29 #include <TopExp_Explorer.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRepTools.hxx>
33
34 #include <TopTools_MapOfShape.hxx>
35 #include <TopTools_MapIteratorOfMapOfShape.hxx>
36 #include <TopTools_IndexedMapOfShape.hxx>
37 #include <TDF_Label.hxx>
38 #include <TDF_LabelList.hxx>
39 #include <TDF_LabelMap.hxx>
40 #include <TNaming_Tool.hxx>
41
42 #include <Standard_NotImplemented.hxx>
43 #include <Standard_ConstructionError.hxx>
44 #include <Standard_ErrorHandler.hxx>
45 #include <TopTools_Array1OfShape.hxx>
46 #include <TColStd_Array1OfInteger.hxx>
47 #include <TopoDS_Wire.hxx>
48 #include <TopoDS_Shell.hxx>
49
50 // mpv modifications 08.04.2002
51 #include <BRepBuilderAPI_MakeWire.hxx>
52 #include <BRepBuilderAPI_MakeFace.hxx>
53 #include <TopoDS.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS_Solid.hxx>
56 #include <TopoDS_Face.hxx>
57 #include <TopoDS_CompSolid.hxx>
58 #include <TopoDS_Compound.hxx>
59 #include <TopoDS_Iterator.hxx>
60 #include <TopTools_ListOfShape.hxx>
61 #include <TopTools_ListIteratorOfListOfShape.hxx>
62 #include <BRepBuilderAPI_MakeSolid.hxx>
63 #include <TopTools_HArray2OfShape.hxx>
64 #include <TopTools_ListOfShape.hxx>
65 #include <TopTools_DataMapOfShapeListOfShape.hxx>
66 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
67 // end of mpv modifications 08.04.2002
68
69 #include <TNaming_NCollections.hxx>
70
71 #ifdef OCCT_DEBUG_DBGTOOLS_WRITE
72 #define MDTV_DEB
73 #define MDTV_DEB_OR
74 #define MDTV_DEB_UNN
75 #define  MDTV_DEB_INT
76 #define MDTV_DEB_GEN
77 #define  MDTV_DEB_MODUN
78 #define MDTV_DEB_FNB
79 #define  MDTV_DEB_WIN
80 #define MDTV_DEB_ARG
81 #define MDTV_DEB_SHELL
82 #endif
83 #ifdef OCCT_DEBUG
84 #include <TCollection_AsciiString.hxx>
85 #include <TDF_Tool.hxx>
86 #include <BRepTools.hxx>
87 #endif
88 #ifdef OCCT_DEBUG
89 #include <TCollection_AsciiString.hxx>
90 #include <TDF_Tool.hxx>
91 #include <TDF_ChildIterator.hxx>
92 #include <TDF_MapIteratorOfLabelMap.hxx>
93 //=======================================================================
94 void PrintEntry(const TDF_Label&       label)
95 {
96   TCollection_AsciiString entry;
97   TDF_Tool::Entry(label, entry);
98   cout << "LabelEntry = "<< entry << endl;
99 }
100 //=======================================================================
101 void PrintEntries(const TDF_LabelMap& map)
102 {
103   cout << "=== Labels Map ===" <<endl;
104   TCollection_AsciiString entry;
105   TDF_MapIteratorOfLabelMap it(map);
106   for(;it.More();it.Next()) {
107     TDF_Tool::Entry(it.Key(), entry);
108       cout << "LabelEntry = "<< entry << endl;
109     }
110 }
111 #ifdef OCCT_DEBUG_DBGTOOLS_WRITE
112 //=======================================================================
113 static void DbgTools_Write(const TopoDS_Shape& shape,
114                       const Standard_CString filename) 
115 {
116   char buf[256];
117   if(strlen(filename) > 256) return;
118   strcpy (buf, filename);
119   char* p = buf;
120   while (*p) {
121     if(*p == ':')
122       *p = '-';
123     p++;
124   }
125   ofstream save (buf);
126   if(!save) 
127     cout << "File " << buf << " was not created: rdstate = " << save.rdstate() << endl;
128   save << "DBRep_DrawableShape" << endl << endl;
129   if(!shape.IsNull()) BRepTools::Write(shape, save);
130   save.close();
131 }
132 //=======================================================================
133 static void DbgTools_Write(const TopTools_IndexedMapOfShape& MS,  const Standard_CString filename) 
134 {
135   if (!MS.IsEmpty ()) {
136     TCollection_AsciiString aNam (filename);
137     for (Standard_Integer anIt = 1; anIt <= MS.Extent(); ++anIt) {
138       TCollection_AsciiString aName = aNam + "_" + (anIt - 1) + ".brep";
139       DbgTools_Write (MS (anIt), aName.ToCString());
140     }
141   }
142 }
143 //=======================================================================
144 static void DbgTools_WriteNSOnLabel (const Handle(TNaming_NamedShape)& NS,  
145                                      const Standard_CString filename) 
146 {
147   if(!NS.IsNull() && !NS->IsEmpty() ) {
148     TCollection_AsciiString aNam (filename);
149     TCollection_AsciiString oldS ("_Old");
150     TCollection_AsciiString newS ("_New_");
151     Standard_Integer i(0);
152     TNaming_Iterator it(NS);
153     for(;it.More(); it.Next(),i++) {
154       TCollection_AsciiString aName1 = aNam + oldS + i + ".brep";
155       TCollection_AsciiString aName2 = aNam + newS + i + ".brep";
156       const TopoDS_Shape& oldShape = it.OldShape();
157       const TopoDS_Shape& newShape = it.NewShape();
158       if(!oldShape.IsNull())
159         DbgTools_Write ( oldShape, aName1.ToCString());
160       if(!newShape.IsNull())
161         DbgTools_Write ( newShape, aName2.ToCString());      
162     }
163   }
164 }
165 #endif
166 #endif
167 //
168 //====================================================================
169 static Standard_Boolean ValidArgs(const TNaming_ListOfNamedShape& Args)
170 {
171   TNaming_ListIteratorOfListOfNamedShape it(Args);
172   for (;it.More();it.Next()) {
173     const Handle(TNaming_NamedShape)& aNS = it.Value();
174     if(aNS.IsNull()) {
175 #ifdef OCCT_DEBUG_ARG 
176       cout << "ValidArgs:: NS (Naming argument) is NULL" <<endl;
177 #endif  
178       return Standard_False;
179     }
180     else 
181       if(aNS->IsEmpty()) {
182 #ifdef OCCT_DEBUG_ARG
183         TCollection_AsciiString entry;
184         TDF_Tool::Entry(aNS->Label(), entry);
185         cout << "ValidArgs:: Empty NS, Label = " << entry <<endl;
186 #endif  
187       return Standard_False;
188     }
189       else  
190         if(!aNS->IsValid()) {
191 #ifdef OCCT_DEBUG_ARG 
192           TCollection_AsciiString entry;
193           TDF_Tool::Entry(aNS->Label(), entry);
194           cout << "ValidArgs::Not valid NS Label = " << entry <<endl;
195 #endif  
196           return Standard_False; 
197         }
198     }
199   return Standard_True;
200 }
201
202 //=======================================================================
203 //function : TNaming_Name
204 //purpose  : 
205 //=======================================================================
206
207 TNaming_Name::TNaming_Name() : 
208    myType(TNaming_UNKNOWN),
209    myIndex(-1)
210 {
211 }
212
213
214 //=======================================================================
215 //function : Type
216 //purpose  : 
217 //=======================================================================
218
219 void TNaming_Name::Type(const TNaming_NameType aType) 
220 {
221   myType = aType;
222 }
223
224 //=======================================================================
225 //function : Type
226 //purpose  : 
227 //=======================================================================
228
229 void TNaming_Name::ShapeType(const TopAbs_ShapeEnum T) 
230 {
231   myShapeType = T;
232 }
233
234 //=======================================================================
235 //function : Shape
236 //purpose  : 
237 //=======================================================================
238
239 void TNaming_Name::Shape(const TopoDS_Shape& theShape) 
240 {
241   myShape = theShape;
242   
243 }
244
245 //=======================================================================
246 //function : Shape
247 //purpose  : 
248 //=======================================================================
249
250 TopoDS_Shape TNaming_Name::Shape() const
251 {
252   return myShape;
253 }
254
255 //=======================================================================
256 //function : Append
257 //purpose  : 
258 //=======================================================================
259
260 void TNaming_Name::Append(const Handle(TNaming_NamedShape)& arg) 
261 {
262   myArgs.Append (arg);
263 }
264
265 //=======================================================================
266 //function : StopNamedShape
267 //purpose  : 
268 //=======================================================================
269
270 void TNaming_Name::StopNamedShape (const Handle(TNaming_NamedShape)& arg) 
271 {
272   myStop = arg;
273 }
274
275 //=======================================================================
276 //function : Index
277 //purpose  : 
278 //=======================================================================
279
280 void TNaming_Name::Index (const Standard_Integer I)
281 {
282   myIndex = I;
283 }
284
285
286 //=======================================================================
287 //function : TNaming_NameType
288 //purpose  : 
289 //=======================================================================
290
291 TNaming_NameType TNaming_Name::Type() const 
292 {
293   return myType;
294 }
295
296 //=======================================================================
297 //function : TNaming_NameType
298 //purpose  : 
299 //=======================================================================
300
301 TopAbs_ShapeEnum TNaming_Name::ShapeType() const 
302 {
303   return myShapeType;
304 }
305
306 //=======================================================================
307 //function : Paste
308 //purpose  : 
309 //=======================================================================
310
311 void TNaming_Name::Paste (TNaming_Name& into,
312                           const Handle(TDF_RelocationTable)& RT) const
313 {
314   into.myType      = myType;
315   into.myShapeType = myShapeType;
316   into.myShape     = myShape;
317   into.myIndex     = myIndex;
318   into.myArgs.Clear();
319 //  into.myOrientation = myOrientation;
320   Handle(TNaming_NamedShape) NS;
321
322   for (TNaming_ListIteratorOfListOfNamedShape it(myArgs); it.More(); it.Next()) {
323     RT->HasRelocation(it.Value(),NS);
324     into.myArgs.Append (NS);
325   }
326   if (!myStop.IsNull()) {
327     RT->HasRelocation(myStop,NS);
328     into.myStop = NS;
329   }
330   if (!myContextLabel.IsNull()) {
331     RT->HasRelocation(myContextLabel,into.myContextLabel);
332   }
333 }
334
335 //=======================================================================
336 //function : Arguments
337 //purpose  : 
338 //=======================================================================
339       
340 const TNaming_ListOfNamedShape& TNaming_Name::Arguments() const
341 {
342   return myArgs;
343 }
344
345 //=======================================================================
346 //function : Arguments
347 //purpose  : 
348 //=======================================================================
349       
350 Handle(TNaming_NamedShape) TNaming_Name::StopNamedShape() const
351 {
352   return myStop;
353 }
354
355 //=======================================================================
356 //function : Index
357 //purpose  : 
358 //=======================================================================
359       
360 Standard_Integer TNaming_Name::Index() const
361 {
362   return myIndex;
363 }
364
365 //=======================================================================
366 //function : MakeShape
367 //purpose  : 
368 //=======================================================================
369
370 static TopoDS_Shape MakeShape (const TopTools_IndexedMapOfShape& MS) 
371 {  
372   if (!MS.IsEmpty ()) {
373     if (MS.Extent() == 1) {
374       return MS (1);
375     }
376     else {
377       TopoDS_Compound C;
378       BRep_Builder B;
379       B.MakeCompound(C);
380       for (Standard_Integer anIt = 1; anIt <= MS.Extent(); ++anIt)
381         B.Add (C, MS (anIt));
382       return C;
383     }
384   }
385   return TopoDS_Shape();  
386 }
387
388 //=======================================================================
389 //function : ShapeWithType
390 //purpose  : Tries to make shape with given type from the given shape
391 //=======================================================================
392
393 static TopoDS_Shape ShapeWithType(const TopoDS_Shape     theShape,
394                                   const TopAbs_ShapeEnum theType ) {
395   if (theShape.IsNull() || theType == TopAbs_SHAPE) return theShape;
396   Standard_Integer aType = theShape.ShapeType();
397   if (aType == theType) return theShape;
398
399   TopTools_ListOfShape aShapes;
400   if (aType == TopAbs_COMPOUND) {
401     TopoDS_Iterator anIter(theShape);
402     if (anIter.More()) aType = anIter.Value().ShapeType();
403     for(;anIter.More();anIter.Next()) aShapes.Append(anIter.Value());
404     if (aType == theType) {
405       if (aShapes.Extent() == 1) return aShapes.First();
406       else return theShape;
407     }
408   } else aShapes.Append(theShape);
409
410   TopoDS_Shape aResult;
411   TopTools_ListIteratorOfListOfShape aListIter(aShapes);
412
413   if (aType < theType) {
414     Standard_Integer aCount;
415     for(aCount=0;aListIter.More();aListIter.Next()) {
416       TopExp_Explorer anExp(aListIter.Value(),theType);
417       if (anExp.More()) {
418         if (!anExp.Current().IsNull()) {
419           aResult = anExp.Current();
420           aCount++;
421           if (aCount > 1) return theShape;
422         }
423       }
424     }
425     if (aCount == 1) return aResult;
426   } else { // if the shape type more complex than shapes from aShapes list, try make it
427     switch (aType) {
428     case TopAbs_VERTEX: // can't do something from vertex
429       break;
430     case TopAbs_EDGE: {// make wire from edges
431       if (theType <= TopAbs_SOLID) break;
432       BRepBuilderAPI_MakeWire aMakeWire;
433       aMakeWire.Add(aShapes);
434       if (!aMakeWire.IsDone()) return theShape;
435       if (theType == TopAbs_WIRE) return aMakeWire.Wire();
436       aShapes.Clear(); // don't break: we can do something more of it
437       aShapes.Append(aMakeWire.Wire());
438       aListIter.Initialize(aShapes);
439     }
440     case TopAbs_WIRE: {// make faceS from wires (one per one)
441       if (theType < TopAbs_SOLID) break;
442       TopTools_ListOfShape aFaces;
443       for(;aListIter.More();aListIter.Next()) {
444         BRepBuilderAPI_MakeFace aMakeFace(TopoDS::Wire(aListIter.Value()));
445         if (!aMakeFace.IsDone()) aFaces.Append(aMakeFace.Face());
446       }
447       if (theType == TopAbs_FACE) {
448         if (aFaces.Extent() == 1) return aFaces.First();
449         return theShape;
450       }
451       aShapes.Assign(aFaces); // don't break: we can do something more of it
452       aListIter.Initialize(aShapes);
453     }
454     case TopAbs_FACE: {// make shell from faces
455       if (theType < TopAbs_SOLID) break;
456       BRep_Builder aShellBuilder;
457       TopoDS_Shell aShell;
458       aShellBuilder.MakeShell(aShell);
459       for(;aListIter.More();aListIter.Next()) aShellBuilder.Add(aShell,TopoDS::Face(aListIter.Value()));
460       aShell.Closed (BRep_Tool::IsClosed (aShell));
461       if (theType == TopAbs_SHELL) return aShell;
462       aShapes.Clear(); // don't break: we can do something more of it
463       aShapes.Append(aShell);
464       aListIter.Initialize(aShapes);
465     }
466     case TopAbs_SHELL: {// make solids from shells (one per one)
467       TopTools_ListOfShape aSolids;
468       for(;aListIter.More();aListIter.Next()) {
469         BRepBuilderAPI_MakeSolid aMakeSolid(TopoDS::Shell(aListIter.Value()));
470         if (aMakeSolid.IsDone()) aSolids.Append(aMakeSolid.Solid());
471       }
472       if (theType == TopAbs_SOLID) {
473         if (aSolids.Extent() == 1) return aSolids.First();
474         return theShape;
475       }
476       aShapes.Assign(aSolids); // don't break: we can do something more of it
477       aListIter.Initialize(aShapes);
478     }
479     case TopAbs_SOLID: {// make compsolid from solids
480       BRep_Builder aCompBuilder;
481       TopoDS_CompSolid aCompSolid;
482       aCompBuilder.MakeCompSolid(aCompSolid);
483       for(;aListIter.More();aListIter.Next()) aCompBuilder.Add(aCompSolid,TopoDS::Solid(aListIter.Value()));
484       if (theType == TopAbs_COMPSOLID) return aCompSolid;
485     }
486     }
487   }
488   return theShape;
489 }
490
491 //=======================================================================
492 //function : FindModifUntil
493 //purpose  : 
494 //=======================================================================
495
496 static Standard_Boolean FindModifUntil (TNaming_NewShapeIterator&         it,
497                                         TopTools_IndexedMapOfShape& MS,
498                                         const TopoDS_Shape&               S,
499                                         const Handle(TNaming_NamedShape)& Context)
500
501 #ifdef OCCT_DEBUG_MODUN
502   if(!Context.IsNull())
503     PrintEntry(Context->Label());
504 #endif
505   Standard_Boolean found = Standard_False;
506   for (; it.More(); it.Next()) {
507     if (!it.Shape().IsNull()) {
508 #ifdef OCCT_DEBUG_MODUN
509       if(!it.NamedShape().IsNull())
510         PrintEntry(it.NamedShape()->Label());
511 #endif
512       if (it.NamedShape() == Context) {
513         MS.Add(S);
514         found = Standard_True;
515       }
516       else { // New shape != Context
517         TNaming_NewShapeIterator it2(it);
518         found = FindModifUntil (it2,MS,it.Shape(),Context);
519       }
520     }
521   }
522   return found;
523 }
524
525 //=======================================================================
526 //function : ModifUntil
527 //purpose  : returns map <theMS> of generators of Target
528 //=======================================================================
529
530 static void SearchModifUntil (const TDF_LabelMap&               /*Valid*/,
531                               const Handle(TNaming_NamedShape)& Target,
532                               const TNaming_ListOfNamedShape& theListOfGenerators,
533                               TopTools_IndexedMapOfShape& theMS)
534 {
535
536 #ifdef OCCT_DEBUG_MODUN
537    DbgTools_WriteNSOnLabel(Target, "SMUntil_"); // Target <== generated
538   Standard_Integer i = 0;
539   TCollection_AsciiString aGen1("Gens_New_"), aGen2("Gented_Old_"), Und("_");
540 #endif 
541   // Test si S apparait comme oldshape dans Context. : Test if S appears as oldshape in Context.
542   Standard_Boolean found = Standard_False;
543   for (TNaming_ListIteratorOfListOfNamedShape it(theListOfGenerators); it.More(); it.Next()) {
544     const Handle(TNaming_NamedShape)& aNS = it.Value();
545 #ifdef OCCT_DEBUG_MODUN  
546     i++;
547     Standard_Integer j = 0;
548 #endif
549     for (TNaming_Iterator itL (aNS); itL.More(); itL.Next()) { // <- generators
550       const TopoDS_Shape& S = itL.NewShape();
551       found = Standard_False;
552       
553 #ifdef OCCT_DEBUG_MODUN
554       j++;
555       Standard_Integer k = 0;
556       TCollection_AsciiString aNam1 = aGen1 + i + Und + j + ".brep";
557       DbgTools_Write(S, aNam1.ToCString());
558       PrintEntry(aNS->Label());//NSLabel
559 #endif   
560       TNaming_Iterator itC (Target);
561       for  (; itC.More(); itC.Next()) {  // <- generated
562         const TopoDS_Shape& OS = itC.OldShape();
563 #ifdef OCCT_DEBUG_MODUN
564         k++;
565         TCollection_AsciiString aNam2 = aGen2 + i + Und + j + Und + k + ".brep";
566         DbgTools_Write(OS, aNam2.ToCString());
567         PrintEntry(Target->Label());//Target Label
568 #endif 
569         if (OS.IsSame(S)) {
570           theMS.Add(S);
571           found = Standard_True;
572 #ifdef OCCT_DEBUG_MODUN
573           cout << aNam2 << " is Same with " << aNam1 <<endl;
574 #endif
575           break;
576         }
577       }
578       if (!found) {
579         TNaming_NewShapeIterator it1(itL);
580         found = FindModifUntil (it1,theMS,S,Target);
581       }
582     }
583   }
584 }
585
586 //=======================================================================
587 //function : ModifUntil
588 //purpose  : 
589 //=======================================================================
590 // NamedShape for this type is assembled from all last modifications of the 
591 // last argument shapes (see method  TNaming_NamingTool::CurrentShape), 
592 // which are not descendants (see method TNaming_NamingTool::BuildDescendants) 
593 // of the stop shape. This type of naming is used for identification shapes, 
594 // which has only one parent with evolution PRIMITIVE (or itself), which 
595 // uniquely identifies it. In most cases stop shape is empty and this algorithm 
596 // is equal to the algorithm for IDENTITY. 
597 //=======================================================================
598 static Standard_Boolean ModifUntil (const TDF_Label&                  L,
599                                     const TDF_LabelMap&               Valid,
600                                     const TNaming_ListOfNamedShape&   Args,
601                                     const Handle(TNaming_NamedShape)& Stop)
602 {
603   TopTools_IndexedMapOfShape MS; 
604   TDF_LabelMap Forbiden;
605   if(!ValidArgs(Args)) return Standard_False;
606   TNaming_NamingTool::BuildDescendants (Stop, Forbiden); // fills Forbidden from Stop
607
608 #ifdef OCCT_DEBUG_GEN  
609   cout <<"Regenerating ModifUntil => ";
610   PrintEntry(L);
611   DbgTools_WriteNSOnLabel(Args.Last(), "ModifUntil-");
612  
613 #endif
614   // all last modifications of the last argument
615   TNaming_NamingTool::CurrentShape  (Valid, Forbiden,Args.Last(),MS); 
616 #ifdef OCCT_DEBUG_GEN  
617   Standard_Integer i(0);
618   TCollection_AsciiString aNam("ModifUnti_MS_");
619   TCollection_AsciiString ext(".brep"); 
620 #endif
621   TNaming_Builder B(L);
622   for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
623     const TopoDS_Shape& S = MS (anItMS);
624     B.Select(S,S);
625 #ifdef OCCT_DEBUG_GEN  
626     TCollection_AsciiString aName = aNam + ++i + ext;
627     DbgTools_Write(S, aName.ToCString()) ;
628     cout << aName.ToCString() << " TS = " << S.TShape()->This() <<endl;
629 #endif
630   }
631   return Standard_True;
632 }
633
634 //=======================================================================
635 //function : ContShape
636 //purpose  : 
637 //=======================================================================
638 // from the NS of the first argument TNaming_Iterator is started, shape "S" 
639 // is the NewShape from Iterator with index "myIndex" of the Name, this 
640 // shape and all last modifications (except NamedShapes - descendants of 
641 // the stop shape) are the parts of resulting NamedShape.
642 //=======================================================================
643 static Standard_Boolean ConstShape (const TDF_Label&                  L,
644                                     const TDF_LabelMap&               Valid,
645                                     const TNaming_ListOfNamedShape&   Args,
646                                     const Handle(TNaming_NamedShape)& Stop,
647                                     const Standard_Integer            Index)
648 {
649   TopTools_IndexedMapOfShape MS; 
650   TDF_LabelMap Forbiden;
651   if(!ValidArgs(Args)) return Standard_False;
652   TNaming_NamingTool::BuildDescendants (Stop, Forbiden);
653
654   TopoDS_Shape S;
655   Standard_Integer i = 1;
656   for (TNaming_Iterator it(Args.First()); it.More(); it.Next(), i++) {
657     if (Index == i) {
658       S = it.NewShape();
659       break;
660     }
661   }
662   if (S.IsNull()) return Standard_False;
663
664   TNaming_NamingTool::CurrentShapeFromShape  (Valid,Forbiden,L,S,MS);
665
666  
667   TNaming_Builder B(L);
668   for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
669     const TopoDS_Shape& SS = MS (anItMS);
670     B.Select(SS,SS);
671   }
672   return Standard_True;
673 }
674
675 //=======================================================================
676 //function : Intersection
677 //purpose  : 
678 //=======================================================================
679 //algorithm does next steps:
680 // 1. Sets to the "Forbiden" map  all shapes, which are descendants of stop 
681 //    shape. Named shapes at these labels can't be used.
682 // 2. Takes first argument (with method CurrentShape) and sets map "S" of 
683 //    ancestors (shapes, which belong to this one) of its shape with type 
684 //    "ShapeType" of Name.
685 // 3. Takes next argument of Name (with method CurrentShape) and removes 
686 //    from the map "S" all ancestors, which not belongs to the shape of 
687 //    this argument. This step is repeated for all arguments of this Name.
688 // 4. Adds to the result NamedShape all rest of shapes from the map "S".
689 //=======================================================================
690 static Standard_Boolean Intersection (const TDF_Label&                  L,
691                                       const TDF_LabelMap&               Valid,
692                                       const TNaming_ListOfNamedShape&   Args,
693                                       const Handle(TNaming_NamedShape)& Stop,
694                                       const TopAbs_ShapeEnum            ShapeType,
695                                       const Standard_Integer            Index)
696 {
697   if (Args.IsEmpty()) return Standard_False;
698   if(!ValidArgs(Args)) return Standard_False;
699   TNaming_ListIteratorOfListOfNamedShape it(Args); 
700   TopTools_IndexedMapOfShape MS; 
701   TDF_LabelMap        Forbiden;
702
703 #ifdef OCCT_DEBUG_INT
704   if(!Stop.IsNull() && !Stop->Get().IsNull()) {
705     DbgTools_Write(Stop->Get(), "Ints_Stop.brep");
706     PrintEntry(Stop->Label());
707   }
708   cout <<"Ints: ShapeType = " << ShapeType << endl;
709   cout <<"Argument 1 at ";
710   PrintEntry(it.Value()->Label());
711 #endif 
712
713   TNaming_NamingTool::BuildDescendants (Stop, Forbiden); // <==<1>
714
715 #ifdef OCCT_DEBUG_INT
716   cout << "Intersection:: Valid Map: "<<endl;
717   PrintEntries(Valid);
718   cout << "Intersection:: Forbidden Map: "<<endl;
719   PrintEntries(Forbiden);
720 #endif
721   TopTools_ListOfShape aListOfAnc;
722   TNaming_NamingTool::CurrentShape  (Valid, Forbiden,it.Value(),MS); // first argument
723   TopoDS_Shape  CS = MakeShape(MS);
724   TNaming_ShapesSet S(CS,ShapeType); // <==<2>
725   aListOfAnc.Append(CS);
726 #ifdef OCCT_DEBUG_INT
727   if(!CS.IsNull())
728     DbgTools_Write(CS, "Int_CS_1.brep");
729   Standard_Integer i=2;
730   TCollection_AsciiString aNam("Int_CS_");
731   TCollection_AsciiString ext(".brep");
732  
733 #endif 
734   it.Next();  // <<===<3.1>
735   for (; it.More(); it.Next()) {
736     MS.Clear();
737     TNaming_NamingTool::CurrentShape (Valid,Forbiden,it.Value(),MS);
738     CS = MakeShape(MS);
739     aListOfAnc.Append(CS);
740 #ifdef OCCT_DEBUG_INT
741     TCollection_AsciiString aName = aNam + i++ + ext;      
742     DbgTools_Write(CS, aName.ToCString()) ;
743     cout <<"Argument " << i << " at ";
744     PrintEntry(it.Value()->Label());
745 #endif  
746
747     TNaming_ShapesSet OS(CS,ShapeType);
748     S.Filter(OS); //<<===<3.2>
749 #ifdef OCCT_DEBUG_INT
750     Standard_Integer j = 1;
751     TCollection_AsciiString aNam2("SSMap_"), aName3;
752     TopTools_MapIteratorOfMapOfShape itm(S.Map());
753     for(;itm.More();itm.Next(), j++) {
754       aName3 = aNam2 + i + "_" + j + ".brep";
755       DbgTools_Write(itm.Key(), aName3.ToCString());
756     }
757 #endif 
758   }
759
760 #ifdef OCCT_DEBUG_INT
761   aNam = "Int_S_";
762   i =1;
763 #endif
764
765   TNaming_Builder B(L); //<<===<4>
766   Standard_Boolean isOK(Standard_False);
767   if(S.Map().Extent() > 1 && Index > 0 && ShapeType == TopAbs_EDGE) {
768     Standard_Integer indxE(0), nbE(0), indxW(0),nbW(0), indxF(0);
769     indxE =  Index & 0x000000FF;
770     nbE   = (Index & 0x0000FF00) >> 8;
771     indxW = (Index & 0x000F0000) >> 16;
772     nbW   = (Index & 0x00F00000) >> 20;
773     indxF = (Index & 0x0F000000) >> 24;
774     Standard_Integer i(1);
775     TopoDS_Shape aS;
776     TopTools_ListIteratorOfListOfShape itl(aListOfAnc);
777     for(;itl.More();itl.Next(),i++) {
778       if(indxF == i) {
779         aS = itl.Value();
780         break;
781       }      
782     }
783 #ifdef OCCT_DEBUG_INT
784     cout <<"Kept: indxE = " << indxE  <<" maxENum = " << nbE << " indxW = " <<indxW << " nbW = " <<nbW<<endl;
785 #endif      
786     Standard_Integer aNbW(0), aCaseW(0);
787     TopoDS_Iterator it2(aS);
788     for (;it2.More();it2.Next()) aNbW++;  
789     if(aNbW == nbW) aCaseW = 1;//exact solution for wire (nb of wires is kept)
790     else aCaseW = 2; // indefinite description ==> compound which can include expected wire    
791     if(aCaseW == 1) {      
792       TopoDS_Shape aWire;
793       Standard_Integer i(1);
794       it2.Initialize(aS);
795       for (;it2.More();it2.Next(),i++) {
796         if(indxW == i) {
797           aWire = it2.Value();
798           break;
799         }
800       }
801       Standard_Integer aNbE(0), aCaseE(0);
802       it2.Initialize(aWire);
803       for (;it2.More();it2.Next()) aNbE++;
804       if(aNbE == nbE) aCaseE = 1;//exact solution for edge
805       else aCaseE = 2;
806       if(aCaseE == 1) {
807         i=1;
808         TopoDS_Shape anEdge;
809         it2.Initialize(aWire);
810         for (;it2.More();it2.Next(),i++) {
811           if(indxE == i) {
812             anEdge = it2.Value();
813             break;
814           }
815         }
816         if(!anEdge.IsNull()) {
817           B.Select(anEdge, anEdge);
818           isOK = Standard_True;
819         }
820       }
821     }   
822   } 
823   if(!isOK)
824 #ifdef OCCT_DEBUG_INT
825     for (TopTools_MapIteratorOfMapOfShape itM(S.Map()); itM.More(); itM.Next(),i++) {
826 #else
827       
828     for (TopTools_MapIteratorOfMapOfShape itM(S.Map()); itM.More(); itM.Next()) {
829 #endif
830       const TopoDS_Shape& S1 = itM.Key();
831 #ifdef OCCT_DEBUG_INT
832       TCollection_AsciiString aName = aNam + i + ext;      
833       DbgTools_Write(S1, aName.ToCString()) ;
834 #endif  
835
836       B.Select(S1,S1);
837       isOK = Standard_True;
838     }
839   return isOK;
840 }
841 //=======================================================================
842 static void KeepInList(const TopoDS_Shape& CS, const TopAbs_ShapeEnum Type, TopTools_ListOfShape& aList)   
843 {
844   if (CS.IsNull()) return;
845
846   if (Type == TopAbs_SHAPE) { 
847     if (CS.ShapeType() == TopAbs_SOLID ||
848         CS.ShapeType() == TopAbs_FACE  ||
849         CS.ShapeType() == TopAbs_EDGE  ||
850         CS.ShapeType() == TopAbs_VERTEX ) {
851       aList.Append(CS);
852     }
853     else {
854       for (TopoDS_Iterator it(CS) ; it.More(); it.Next()) {
855         aList.Append(it.Value());
856       }
857     }
858   }
859   else {
860     if (Type > CS.ShapeType()) {
861       for (TopExp_Explorer exp(CS,Type) ; exp.More(); exp.Next()) {
862         aList.Append(exp.Current());
863       }
864     } else {
865      aList.Append(CS);
866     }
867   }
868 }
869
870 //=======================================================================
871 //function : Union
872 //purpose  : 
873 //=======================================================================
874 // Resulting NamedShape contains compound of next shapes: 
875 // compound of last modifications of each argument (see CurrentShape method) 
876 // without descendants of the stop shape.
877 //=======================================================================
878 static Standard_Boolean Union (const TDF_Label&                  L,
879                                const TDF_LabelMap&               Valid,
880                                const TNaming_ListOfNamedShape&   Args,
881                                const Handle(TNaming_NamedShape)& Stop,
882                                const TopAbs_ShapeEnum            ShapeType,
883                                const TDF_Label&                  ContextLabel)
884 {  
885   if (Args.IsEmpty()) return Standard_False;
886   if(!ValidArgs(Args)) return Standard_False;
887   // temporary solution for Orientation name
888   Standard_Boolean isOr(Standard_True);
889 /* not completed
890   const TDF_Label& aLabel = L.Father();
891   if(!aLabel.IsNull()) {
892   PrintEntry(L);
893   PrintEntry(aLabel);
894     Handle (TNaming_Naming)  Naming;
895     if(aLabel.FindAttribute(TNaming_Naming::GetID(), Naming)) {
896       const TNaming_Name& aName = Naming->GetName();
897       if(aName.Type() == TNaming_ORIENTATION) {
898         const TNaming_ListOfNamedShape&   Args = aName.Arguments();
899         if(Args.Extent() > 2) {
900           const Handle(TNaming_NamedShape)& A = Args.First();
901           if(!A.IsNull()) {
902             PrintEntry(A->Label());
903             if (A->Label() == L) 
904               isOr = Standard_True;         
905           }
906         } else 
907           if(!Args.Extent())
908             isOr = Standard_True;
909       }
910     }
911   }
912 */
913   // end of temp. sol.
914
915   TNaming_ListIteratorOfListOfNamedShape it(Args);
916   TopTools_IndexedMapOfShape MS; 
917   TDF_LabelMap        Forbiden;
918   
919   TNaming_NamingTool::BuildDescendants (Stop, Forbiden);//fill Forbidden
920   TNaming_NamingTool::CurrentShape  (Valid, Forbiden,it.Value(),MS); // fill MS with last modifications of the first argument
921   TopoDS_Shape  CS = MakeShape(MS);
922
923   TopTools_ListOfShape aListS;
924   if(isOr)
925     KeepInList(CS,ShapeType,aListS);
926   TNaming_ShapesSet S(CS,ShapeType);//fill internal map of shapeset by shapes of the specified type
927 #ifdef OCCT_DEBUG_UNN
928   TCollection_AsciiString entry; 
929   TDF_Tool::Entry(it.Value()->Label(), entry);
930   TCollection_AsciiString Nam("Arg_");
931   TCollection_AsciiString aNam = Nam + entry + "_" + "1.brep";
932   DbgTools_Write(CS, aNam.ToCString());
933   Standard_Integer ii = 1;
934 #endif
935   it.Next();
936   for (; it.More(); it.Next()) {
937 #ifdef OCCT_DEBUG_UNN  
938     TDF_Tool::Entry(it.Value()->Label(), entry);
939 #endif
940       MS.Clear();
941       TNaming_NamingTool::CurrentShape (Valid, Forbiden,it.Value(),MS);// fill MS with last modifications of the it.Value()
942       CS = MakeShape(MS);
943       if(isOr)
944         KeepInList(CS,ShapeType,aListS); 
945       TNaming_ShapesSet OS(CS,ShapeType);
946       S.Add(OS); //concatenate both shapesets
947  
948 #ifdef OCCT_DEBUG_UNN 
949     ii++;
950     TCollection_AsciiString aNm = Nam + entry + "_" + ii + ".brep";
951     DbgTools_Write(CS, aNm.ToCString());
952     cout <<"Arg: Entry = " <<entry <<"  TShape = " << CS.TShape() <<endl;
953 #endif
954   }
955
956 // start szy 27.05.08
957   TopoDS_Shape aCand;
958   Standard_Boolean found = Standard_False;
959   if(!ContextLabel.IsNull()) {
960     Handle(TNaming_NamedShape) CNS;
961     ContextLabel.FindAttribute(TNaming_NamedShape::GetID(),CNS);
962     TopoDS_Shape aContext;
963     if(!CNS.IsNull()) {
964       MS.Clear();
965       TNaming_NamingTool::CurrentShape (Valid, Forbiden, CNS, MS);
966       aContext = MakeShape(MS);
967 #ifdef OCCT_DEBUG_UNN 
968       TCollection_AsciiString anEntry;
969       TDF_Tool::Entry(ContextLabel, anEntry);
970       cout << "UNION: Context Label = " <<  anEntry << endl;
971       DbgTools_Write(aContext, "Union_Context.brep");
972       TCollection_AsciiString aN ("aMap_");
973       TopTools_MapIteratorOfMapOfShape it(S.Map());
974       for(Standard_Integer i=1; it.More();it.Next(), i++) {
975         TCollection_AsciiString aName = aN + i + ".brep";
976         DbgTools_Write(it.Key(), aName.ToCString());
977       }
978 #endif
979     }
980     TopTools_ListOfShape aList;
981     TopExp_Explorer anExpl(aContext, ShapeType);
982     for(;anExpl.More(); anExpl.Next()) 
983       aList.Append(anExpl.Current());
984 #ifdef OCCT_DEBUG_UNN
985     cout <<"UNION: ShapeType = " << ShapeType << " List ext = " << aList.Extent()<<endl;
986     TopAbs_ShapeEnum aTyp = TopAbs_SHAPE;
987     TopTools_MapIteratorOfMapOfShape it1 (S.Map());
988     for (int i=1;it1.More();it1.Next(),i++) {
989       cout << "Map("<<i<<"): TShape = " << it1.Key().TShape() << " Orient = " << it1.Key().Orientation() <<endl;
990       aTyp = it1.Key().ShapeType();
991     }
992     
993     TopExp_Explorer exp(aContext, aTyp);
994     for(int i =1;exp.More();exp.Next(), i++) {
995      cout << "Context("<<i<<"): TShape = " << exp.Current().TShape() << " Orient = " << exp.Current().Orientation() <<endl;
996     }
997             
998 #endif
999     TopTools_ListIteratorOfListOfShape itl(aList);
1000     for(;itl.More();itl.Next()) {
1001       aCand = itl.Value(); 
1002 #ifdef OCCT_DEBUG_UNN 
1003       DbgTools_Write(aCand, "Cand.brep");
1004 #endif
1005       Standard_Integer num = S.Map().Extent();
1006       anExpl.Init(aCand, (ShapeType == TopAbs_WIRE) ? TopAbs_EDGE : TopAbs_FACE); 
1007       for(;anExpl.More();anExpl.Next()) {
1008         if(S.Map().Contains(anExpl.Current()))
1009           num--;
1010       } 
1011       if(num == 0) {
1012         found = Standard_True; 
1013         break;
1014       }
1015     }
1016 // end szy 27.05.08
1017   }
1018
1019   TNaming_Builder B(L);
1020 #ifdef OCCT_DEBUG_UNN
1021   if(!ContextLabel.IsNull()) {
1022     if(found) cout << "UNION: Shape is found in Context" <<endl;
1023     else cout << "UNION: Shape is NOT found in Context" <<endl;
1024   }
1025 #endif
1026   if(found) 
1027     B.Select(aCand, aCand);
1028   else {
1029     BRep_Builder aCompoundBuilder;
1030     TopoDS_Compound aCompound;
1031     aCompoundBuilder.MakeCompound(aCompound);
1032     if(!isOr)
1033       for (TopTools_MapIteratorOfMapOfShape itM(S.Map()); itM.More(); itM.Next()) {
1034         aCompoundBuilder.Add(aCompound,itM.Key());
1035       }
1036     else
1037       for (TopTools_ListIteratorOfListOfShape itL(aListS); itL.More(); itL.Next()) {
1038         aCompoundBuilder.Add(aCompound,itL.Value());
1039       }
1040     TopoDS_Shape aShape = ShapeWithType(aCompound,ShapeType);
1041 #ifdef OCCT_DEBUG_UNN 
1042     DbgTools_Write(aShape, "Union_Selected.brep");
1043     DbgTools_Write(aCompound, "Union_Compound.brep");
1044 #endif
1045     B.Select(aShape,aShape);
1046   }
1047   return Standard_True;
1048 }
1049
1050 //=======================================================================
1051 static TopoDS_Shape FindShape(const TNaming_DataMapOfShapeMapOfShape& DM) 
1052 {
1053   TopoDS_Shape aResult;
1054   Standard_Integer aNum = DM.Extent();
1055   if(aNum < 1) return aResult;  
1056   TopTools_ListOfShape List;
1057   TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape it(DM);
1058   if(it.More()) {
1059     const TopoDS_Shape& aKey1 = it.Key();
1060     const TNaming_MapOfShape& aMap = it.Value();
1061
1062     TNaming_MapIteratorOfMapOfShape itm(aMap); // iterate first map
1063     for (;itm.More();itm.Next()) {
1064       const TopoDS_Shape& aS = itm.Key(); // element of the first map
1065       Standard_Boolean isCand(Standard_True); // aS is a Candidate
1066       TNaming_DataMapIteratorOfDataMapOfShapeMapOfShape it2(DM);
1067       for (;it2.More();it2.Next()) {
1068         const TopoDS_Shape& aKey2 = it2.Key();
1069         if(aKey2 == aKey1) continue;
1070         const TNaming_MapOfShape& aMap2 = it2.Value();
1071         if(!aMap2.Contains(aS)) isCand = Standard_False;
1072       } 
1073       if(isCand)
1074         List.Append(aS);
1075     }
1076   }
1077   if(List.IsEmpty()) return aResult;
1078   if(List.Extent() == 1) return List.First();
1079   TopTools_ListIteratorOfListOfShape itl (List);
1080   TopoDS_Compound Compound;
1081   BRep_Builder B;
1082   B.MakeCompound(Compound);
1083   for (; itl.More(); itl.Next()){ 
1084     B.Add(Compound,itl.Value());
1085   }
1086   return Compound; 
1087 }
1088
1089 //=======================================================================
1090 //function : Generation
1091 //purpose  : Resolves Name from arguments: arg1 - generated (target shape)
1092 //         : arg2 - the generator: the oldest ancestor (usually NS with 
1093 //         : PRIMITIVE evolution. (See TNaming_Localizer::FindGenerator).
1094 //         : Resulting NamedShape contains shape, which is in the first 
1095 //         : argument NamedShape and is modification of the last argument NS.
1096 //=======================================================================
1097
1098 static Standard_Boolean  Generated (const TDF_Label&                L,
1099                                     const TDF_LabelMap&             Valid,
1100                                     const TNaming_ListOfNamedShape& Args)
1101 {
1102   if (Args.Extent() < 2) {
1103     Standard_ConstructionError::Raise("TNaming_Name::Solve: => Generated");
1104   }
1105   // First argument : label of generation
1106   // Next arguments : generators.
1107
1108   if(!ValidArgs(Args)) return Standard_False;
1109
1110   TDF_Label   LabelOfGeneration = Args.First()->Label();
1111 #ifdef OCCT_DEBUG_GEN
1112       DbgTools_Write(Args.First()->Get(),  "Generated.brep") ;
1113 #endif
1114   // Nouvell valeurs des generateurs dans l attribut de generation
1115   TopTools_IndexedMapOfShape aMS;
1116   TNaming_ListOfNamedShape aGenerators; 
1117   aGenerators.Assign(Args); 
1118   aGenerators.RemoveFirst(); 
1119 #ifdef OCCT_DEBUG_GEN
1120       DbgTools_Write(aGenerators.First()->Get(),  "Generators.brep") ;
1121 #endif
1122   SearchModifUntil (Valid, Args.First(), aGenerators, aMS);
1123   Handle(TNaming_Naming) aNaming;
1124   TopoDS_Shape aSelection;
1125   L.FindAttribute(TNaming_Naming::GetID(),aNaming);
1126   if(!aNaming.IsNull()) 
1127     aSelection = aNaming->GetName().Shape();
1128 #ifdef OCCT_DEBUG_GEN
1129   DbgTools_Write(aSelection,  "G_Selection.brep") ;
1130   cout << "Generated::SearchModifUntil aMS.Extent() = " << aMS.Extent() <<endl;
1131   DbgTools_Write(aMS, "SearchModifUntil_Result");
1132 #endif
1133    Handle(TNaming_NamedShape) anOldNS;
1134    Standard_Integer aVer = -1;// Initial build of name
1135    L.FindAttribute(TNaming_NamedShape::GetID(),anOldNS);
1136    if(!anOldNS.IsNull()) 
1137      aVer = anOldNS->Version();
1138
1139 #ifdef OCCT_DEBUG_GEN
1140   Standard_Integer i = 0, j=1;
1141   TCollection_AsciiString aNam2("Gen_New_");
1142   TCollection_AsciiString aNam1("Gen_Old_");
1143   TCollection_AsciiString ext(".brep");
1144 #endif
1145   TNaming_Builder B(L); // NS
1146   TopTools_ListOfShape aList;
1147   TNaming_DataMapOfShapeMapOfShape aDM; 
1148   for (Standard_Integer anItMS = 1; anItMS <= aMS.Extent(); ++anItMS) {
1149     const TopoDS_Shape& OS = aMS (anItMS);
1150 #ifdef OCCT_DEBUG_GEN
1151     TCollection_AsciiString aName = aNam1 + ++i + ext;      
1152     DbgTools_Write(OS, aName.ToCString()) ;
1153     Standard_Integer j=0;
1154 #endif
1155     TNaming_MapOfShape aMapDM; 
1156     for (TNaming_NewShapeIterator itNew(OS,L); itNew.More(); itNew.Next()) 
1157       if (itNew.Label() == LabelOfGeneration) {
1158         aMapDM.Add(itNew.Shape());
1159         aList.Append(itNew.Shape());//szy 21.10.03
1160 #ifdef OCCT_DEBUG_GEN
1161         TCollection_AsciiString aName = aNam2 + i +  "_" + ++j + ext;      
1162         DbgTools_Write(itNew.Shape(), aName.ToCString()) ;
1163 #endif
1164       }
1165     if(aMapDM.Extent())
1166       aDM.Bind(OS, aMapDM);
1167   }
1168
1169   if(aVer == -1) { //initial 
1170     Standard_Integer i = 1;
1171     TNaming_Name& aName =  aNaming->ChangeName();
1172     TopTools_ListIteratorOfListOfShape it(aList);
1173     if(!aSelection.IsNull()) {
1174       for(;it.More();it.Next(),i++) {
1175         if(it.Value().IsSame(aSelection)) {
1176           B.Select(it.Value(), it.Value());
1177           aName.Index(i); // for debug - index of selection in the list
1178           break;
1179         }
1180       }
1181     } else {// Selection == Null
1182       for(;it.More();it.Next())
1183         B.Select(it.Value(), it.Value()); 
1184     }
1185   }
1186   else { 
1187     // *** Regeneration *** //
1188     if(aList.Extent() == 1) { // trivial case
1189       B.Select(aList.Last(), aList.Last()); 
1190     } 
1191     else {
1192       TNaming_Name& aName =  aNaming->ChangeName();
1193       const TopAbs_ShapeEnum aType = aName.ShapeType();
1194       TopTools_ListOfShape aList2; 
1195       TopTools_ListIteratorOfListOfShape it(aList);
1196       for(;it.More();it.Next()) {
1197         if(it.Value().ShapeType() == aType) //collect only the same type
1198           aList2.Append(it.Value());
1199       }
1200       if(!aList2.Extent()) return Standard_False; // Empty
1201
1202       Standard_Boolean found = Standard_False;
1203       TopoDS_Shape aShape = FindShape(aDM);
1204 #ifdef OCCT_DEBUG_GEN
1205       if(!aShape.IsNull())
1206         DbgTools_Write(aShape,  "G_FindShape.brep") ;
1207 #endif
1208       if(!aShape.IsNull()) found = Standard_True;
1209 #ifdef OCCT_DEBUG_GEN
1210       cout << "Generated ==>aGenerators.Extent() = " <<aGenerators.Extent() <<" aMS.Extent()= " <<aMS.Extent()<<endl;
1211 #endif
1212       if(found) {
1213 #ifdef OCCT_DEBUG_GEN
1214       cout << "Generated ==> Shape is found!" <<endl;
1215 #endif
1216         TopTools_ListOfShape aLM;
1217         Standard_Boolean aHas = Standard_False;
1218         Standard_Boolean a1NB = Standard_False;
1219         if(aGenerators.Extent() != aMS.Extent()) { //missed generators
1220           aHas = Standard_True;//has lost generatos
1221 #ifdef OCCT_DEBUG_GEN
1222       cout << "Generated ==> has lost generatos!" <<endl;
1223 #endif
1224           for (TNaming_ListIteratorOfListOfNamedShape itg(aGenerators); itg.More(); itg.Next()) {
1225             if(!aMS.Contains(itg.Value()->Get())) 
1226               aLM.Append(itg.Value()->Get());
1227           }
1228           if(aLM.Extent() == 1) {//lost 1
1229             TopTools_ListIteratorOfListOfShape itm(aLM);
1230             TopoDS_Shape aSM = itm.Value(); // Missed
1231       for (Standard_Integer anItMS1 = 1; anItMS1 <= aMS.Extent(); ++anItMS1) {
1232               const TopoDS_Shape& aS = aMS (anItMS1);
1233               if(aSM.ShapeType() == aS.ShapeType()) {
1234                 if(aS.ShapeType() == TopAbs_EDGE) {
1235                   TopoDS_Vertex aVCom;
1236                   if(TopExp::CommonVertex(TopoDS::Edge(aS), TopoDS::Edge(aSM), aVCom))
1237                     {a1NB = Standard_True; 
1238                      break;} //lost only 1 neigbour
1239                 } else if(aS.ShapeType() == TopAbs_FACE) {
1240                   TopExp_Explorer expl1(aS, TopAbs_EDGE);
1241                   for(;expl1.More();expl1.Next()) {
1242                     TopExp_Explorer expl2(aSM, TopAbs_EDGE);
1243                     for(;expl2.More();expl2.Next()) {
1244                       if(expl1.Current().IsSame(expl2.Current()))
1245                         {a1NB = Standard_True;
1246                          break;} //lost only 1 neigbour
1247                     }
1248                   }
1249                 }
1250               }
1251             }
1252 //          if(aShape.ShapeType() == TopAbs_VERTEX && a1NBE) {
1253 //      //if atleast 1 Gen was missed and the Gen is Edge
1254 //            TopTools_ListIteratorOfListOfShape it(aList);
1255 //            for(;it.More();it.Next()) {
1256 //              if(it.Value().ShapeType() == TopAbs_EDGE) {
1257 //                const TopoDS_Shape& aV1 = TopExp::FirstVertex(TopoDS::Edge(it.Value()));
1258 //                const TopoDS_Shape& aV2 = TopExp::LastVertex(TopoDS::Edge(it.Value()));
1259 //                if(aShape.IsSame(aV1)) {aShape2 =  aV2;       cout << "##### => V2 " <<endl;break;}
1260 //                else 
1261 //                  if(aShape.IsSame(aV2)) {aShape2 =  aV1;     cout << "##### => V1 " <<endl;break;}
1262 //              }         
1263 //            }
1264 //          }
1265           }
1266         }
1267         if(!aHas) // all arguments were kept
1268           B.Select(aShape, aShape); //only this case is correct on 100%
1269         else {
1270           if (a1NB) //Has, but may be ...
1271             B.Select(aShape, aShape);   
1272           else { 
1273             // put Compound, may be if possible processed later in Sel. Driver
1274             TopTools_ListIteratorOfListOfShape it1(aList2);
1275             for(;it1.More();it1.Next())
1276               B.Select(it1.Value(), it1.Value()); 
1277           }
1278         }
1279     } else 
1280       { //not found
1281 #ifdef OCCT_DEBUG_GEN
1282         cout << "Generated ==> Shape is NOT found! Probably Compound will be built" <<endl;
1283 #endif
1284
1285         TopTools_ListIteratorOfListOfShape it2(aList2);
1286         for(;it2.More();it2.Next())
1287           B.Select(it2.Value(), it2.Value()); 
1288       }
1289     }
1290   }    
1291   return Standard_True;
1292 }
1293
1294 //=======================================================================
1295 //function : Identity
1296 //purpose  : Regenerates Naming attribute with Name = IDENTITY
1297 //=======================================================================
1298 // Name with this type must contain only one NamedShape attribute as argument. 
1299 // Algorithm takes all last modifications of NamedShape of this argument  
1300 // starting with this one ( see method TNaming_NamingTool::CurrentShape ). 
1301 // Algorithm takes only NamedShapes belonging to the labels from the Valid 
1302 // labels map (if it's not empty) and put to the resulting NamedShape as compound. 
1303 //=======================================================================
1304 static Standard_Boolean Identity (const TDF_Label&                L,
1305                                   const TDF_LabelMap&             Valid,
1306                                   const TNaming_ListOfNamedShape& Args,
1307                                   const TopAbs_ShapeEnum          ShapeType)
1308 {
1309   if (Args.Extent() > 2) {
1310     Standard_ConstructionError::Raise("TNaming_Name::Solve");
1311     }
1312   if(!ValidArgs(Args)) return Standard_False;
1313   const Handle(TNaming_NamedShape)& A = Args.First();
1314   TopTools_IndexedMapOfShape MS;
1315   TDF_LabelMap        Forbiden;
1316   TNaming_NamingTool::CurrentShape (Valid,Forbiden,A,MS);
1317 #ifdef OCCT_DEBUG_SOL2
1318   //TCollection_AsciiString entry;
1319   //TDF_Tool::Entry(L, entry);
1320   //TDF_Tool::Entry(A->Label(), entry);
1321 #endif  
1322   TNaming_Builder B(L);
1323   for (Standard_Integer anItMS = 1; anItMS <= MS.Extent(); ++anItMS) {
1324     const TopoDS_Shape& S = ShapeWithType (MS (anItMS), ShapeType);
1325 #ifdef OCCT_DEBUG_SOL2
1326     //TopAbs_Orientation Or = S.Orientation();
1327 #endif
1328     B.Select(S,S);
1329   }
1330   return Standard_True;
1331 }
1332
1333 //=======================================================================
1334 //function : FilterByNeighbourgs
1335 //purpose  : regenerated the specified shape with help of its neighbours
1336 //=======================================================================
1337 // result -  is a subshape of the first argument of the Name with type = 
1338 // ShapeType of this Name, which has a common subshapes (boundaries) with 
1339 // each neighbour - shapes from the other arguments of the Name.
1340 //=======================================================================
1341 static Standard_Boolean  FilterByNeighbourgs (const TDF_Label&                L,
1342                                               const TDF_LabelMap&             Valid,
1343                                               const TNaming_ListOfNamedShape& Args,
1344                                               const Handle(TNaming_NamedShape)& Stop,
1345                                               const TopAbs_ShapeEnum          ShapeType)
1346 {  
1347
1348   TNaming_Builder B(L); 
1349
1350   TDF_LabelMap        Forbiden;
1351   if(!ValidArgs(Args)) return Standard_False;
1352   TNaming_NamingTool::BuildDescendants (Stop, Forbiden); //all descendants of Stop (New shapes) are forbidden
1353   if (!Stop.IsNull())    Forbiden.Remove(Stop->Label());
1354   //----------------------------------------
1355   // First argument: collection has to be filtered.
1356   //----------------------------------------
1357   Handle(TNaming_NamedShape) Cand  = Args.First(); //collection of candidates
1358    
1359 #ifdef OCCT_DEBUG_FNB
1360   Standard_Integer i = 1;
1361   TCollection_AsciiString aNam("Cand_");
1362   TCollection_AsciiString ext(".brep");
1363   DbgTools_WriteNSOnLabel(Cand, aNam.ToCString());  
1364   cout << "Cand (Args.First()) Label = ";
1365   PrintEntry(Cand->Label());  
1366   cout << "Valid Label map:" <<endl;
1367   PrintEntries(Valid);
1368 #endif
1369
1370   TopTools_IndexedMapOfShape SCand;
1371   TNaming_NamingTool::CurrentShape  (Valid, Forbiden,Cand,SCand);//fills SCand with last modifications of Cand. CandNS should be at the same level (before) as NS of FilterByNBS
1372
1373 #ifdef OCCT_DEBUG_FNB
1374   TCollection_AsciiString aNam2("SCand");
1375   DbgTools_Write(SCand, aNam2.ToCString());  
1376   cout <<"SCand Extent = " << SCand.Extent() << " Expected ShapeType = " << ShapeType << endl;
1377 #endif 
1378
1379   //------------------------------------------------------------
1380   // Autres arguments : contiennent les voisins du bon candidat.
1381   // Other arguments  : contains the neighbors of the good candidate.
1382   //------------------------------------------------------------
1383   TopAbs_ShapeEnum              TC = TopAbs_EDGE;
1384   if (ShapeType == TopAbs_EDGE) TC = TopAbs_VERTEX;
1385   if (ShapeType == TopAbs_VERTEX) TC = TopAbs_VERTEX; // szy 31.03.10 - to process case when Candidate is of type Vertex
1386  
1387 #ifdef OCCT_DEBUG_FNB
1388   i=1;
1389   aNam = "Boundaries";
1390 #endif
1391   Standard_Boolean isDone = Standard_False;
1392   if(SCand.Extent() == 1) { // check if a collection is inside
1393     TopoDS_Shape aS = SCand (1);
1394     if(!aS.IsNull()) 
1395       if(aS.ShapeType() == TopAbs_COMPOUND && aS.ShapeType() != ShapeType) {
1396         SCand.Clear();
1397         TopoDS_Iterator itt(aS);
1398         for(;itt.More();itt.Next()) 
1399           SCand.Add(itt.Value());      
1400       }
1401   }
1402   for (Standard_Integer anItSCand = 1; anItSCand <= SCand.Extent(); ++anItSCand) { //1
1403     const TopoDS_Shape& S = SCand (anItSCand);
1404     TopTools_MapOfShape Boundaries;
1405     if(S.ShapeType() == TopAbs_VERTEX) //# szy 31.03.10
1406       Boundaries.Add (S); //#
1407     else  //#
1408       for (TopExp_Explorer exp(S,TC); exp.More(); exp.Next()) { //put boundaries of each candidate (from SCand) to the Boundaries map
1409         Boundaries.Add (exp.Current());
1410 #ifdef OCCT_DEBUG_FNB
1411         TCollection_AsciiString aName = aNam + i++ + ext;      
1412         DbgTools_Write(exp.Current(),  aName.ToCString()) ;
1413 #endif
1414       }
1415     
1416     TNaming_ListIteratorOfListOfNamedShape it(Args); 
1417     it.Next(); 
1418     Standard_Boolean Keep = 1;
1419 #ifdef OCCT_DEBUG_FNB
1420     cout <<"Args number = " << Args.Extent() <<endl;
1421     i=1;
1422     aNam = "Boundaries";
1423 #endif
1424     for ( ; it.More(); it.Next()) { //2 ==> for each Arg
1425       Standard_Boolean Connected = Standard_False;
1426       // Le candidat doit etre  connexe a au moins un shape de
1427       // chaque NamedShape des voisins.
1428       // The candidate should be connectedand and have at least one shape of NamedShape
1429       // of each neighbor.
1430       const Handle(TNaming_NamedShape)& NSVois = it.Value();  //neighbor 
1431
1432 #ifdef OCCT_DEBUG_FNB
1433       DbgTools_WriteNSOnLabel(NSVois, "Next_Neighbor_") ;
1434 #endif
1435       
1436       TopTools_IndexedMapOfShape SVois;
1437       TNaming_NamingTool::CurrentShape  (Valid, Forbiden,NSVois,SVois); // fills SVois with last modifications of NSVois
1438
1439 #ifdef OCCT_DEBUG_FNB
1440       TCollection_AsciiString aNam2("SVois");
1441       DbgTools_Write(SVois, aNam2.ToCString());
1442 #endif 
1443
1444       for (Standard_Integer anItSVois = 1; anItSVois <= SVois.Extent(); ++anItSVois) { //6
1445         const TopoDS_Shape& Vois = SVois (anItSVois);
1446         for (TopExp_Explorer exp1(Vois,TC); exp1.More(); exp1.Next()) { //7
1447           if (Boundaries.Contains(exp1.Current())) {
1448             Connected = Standard_True; // has common boundaries with candidate shape
1449 #ifdef OCCT_DEBUG_FNB
1450             DbgTools_Write(Vois, "Neighbor_Connected.brep");
1451 #endif
1452             break;
1453           }
1454         } //7
1455         if (Connected) break;
1456       } //6
1457       if (!Connected) {
1458         Keep = 0;
1459         break;
1460       }
1461     } //2
1462     if (Keep) {
1463       B.Select (S,S);
1464           isDone = Standard_True;
1465 #ifdef OCCT_DEBUG_FNB
1466       DbgTools_Write(S,  "FilterByNbs_Sel.brep") ;
1467 #endif
1468     }
1469   } //1
1470   return isDone;
1471 }
1472
1473 //=======================================================================
1474 static const TopoDS_Shape FindSubShapeInAncestor(const TopoDS_Shape& Selection, const TopoDS_Shape& Context )
1475 {
1476 #ifdef OCCT_DEBUG_OR_AG
1477   DbgTools_Write(Selection, "Orientation_Selection.brep");
1478   DbgTools_Write(Context, "Orientation_Context.brep");
1479   TopExp_Explorer expl1(Context, Selection.ShapeType());
1480   int i = 0;
1481   TCollection_AsciiString SS( "Orientation_Current_");
1482   for(;expl1.More(); expl1.Next()) {      
1483     if(expl1.Current().IsSame(Selection)) {
1484       i++;
1485       cout <<"FindSubShape:  = " <<expl1.Current().ShapeType() << " TS = " <<expl1.Current().TShape() << endl;
1486       TCollection_AsciiString nam = SS + i + ".brep";
1487       DbgTools_Write(expl1.Current(), nam.ToCString()); 
1488     }
1489   }
1490 #endif 
1491   if(Selection.ShapeType() != TopAbs_COMPOUND) {
1492     TopExp_Explorer anExpl(Context, Selection.ShapeType());
1493     for(;anExpl.More(); anExpl.Next()) {
1494 #ifdef OCCT_DEBUG_OR_AG
1495       cout <<"FindSubShape:  = " <<anExpl.Current().ShapeType() << " TS = " <<anExpl.Current().TShape()->This() << endl;
1496       DbgTools_Write(anExpl.Current(), "Orientation_Current.brep");
1497 #endif    
1498       if(anExpl.Current().IsSame(Selection)) 
1499         return anExpl.Current();
1500     }
1501   }
1502
1503   return TopoDS_Shape();
1504 }
1505
1506 //=======================================================================
1507 //static Standard_Integer Count(const TopoDS_Shape& S)
1508 //{
1509 //  Standard_Integer N(0);
1510 //  TopoDS_Iterator it(S);
1511 //  for(;it.More();it.Next()) {
1512 //    if(it.Value().ShapeType() != TopAbs_COMPOUND && it.Value().ShapeType() != TopAbs_COMPSOLID)
1513 //      N++;
1514 //    else {
1515 //      N += Count(it.Value());
1516 //    }
1517 //  }
1518 //  return N;
1519 //}
1520 //=======================================================================
1521 static Standard_Integer Aggregation (const TopoDS_Shape& S, const TopoDS_Shape& AS, TNaming_Builder& B)
1522 {
1523   Standard_Integer N(0);
1524   TopoDS_Iterator it(S);
1525   for(;it.More();it.Next()) {
1526     const TopoDS_Shape& sel = it.Value();
1527     if(sel.ShapeType() > TopAbs_COMPSOLID) {
1528       const TopoDS_Shape& CS = FindSubShapeInAncestor(sel, AS);
1529       if(!CS.IsNull()) {
1530         B.Select(CS, CS);
1531         N++;
1532       }
1533     } else 
1534       N += Aggregation(sel, AS, B);    
1535   }
1536   return N;
1537 }
1538
1539 //==========================================================================
1540 //function : Orientation
1541 //purpose  : to solve  ORIENTATION name
1542 // this function explores the second argument | arguments (Context) and 
1543 // keeps at the label (L) the first argument (S) with the orientation it  
1544 // has in the context. Index is used only for Seam edge recomputing 
1545 //==========================================================================
1546 static Standard_Boolean ORientation (const TDF_Label&                L,
1547                                      const TDF_LabelMap&             Valid,
1548                                      const TNaming_ListOfNamedShape& Args,
1549                                      const Handle(TNaming_NamedShape)& Stop,
1550                                      const Standard_Integer          Index)
1551 {
1552
1553   if(!ValidArgs(Args)) return Standard_False;
1554
1555   const Handle(TNaming_NamedShape)& A = Args.First();
1556   TopTools_IndexedMapOfShape MS; 
1557   TDF_LabelMap        Forbiden;
1558   TNaming_NamingTool::BuildDescendants (Stop, Forbiden);
1559   TNaming_NamingTool::CurrentShape (Valid,Forbiden,A,MS);
1560
1561   TopoDS_Shape S; 
1562   Standard_Boolean isSplit(Standard_False);
1563   if (!MS.IsEmpty ()) {
1564     if (MS.Extent() == 1) {
1565       S = MS (1);
1566     } 
1567     else {
1568       isSplit = Standard_True;
1569       S = MakeShape(MS);
1570 #ifdef OCCT_DEBUG_OR
1571       for(Standard_Integer anItMS = 1; anItMS <= MS.Extent(); anItMS++) {
1572         TCollection_AsciiString aNam("OR_Selection_");
1573         TCollection_AsciiString aName = aNam + anItMS + ".brep";
1574         DbgTools_Write(MS (anItMS), aName.ToCString());
1575       }
1576 #endif
1577     }
1578   }
1579
1580   TNaming_Builder B(L);
1581   if(S.IsNull()) 
1582     return Standard_False;
1583 #ifdef OCCT_DEBUG_OR
1584   DbgTools_Write(S, "Orientation_S.brep");
1585 #endif
1586
1587   TopTools_ListOfShape aSList;
1588   // tmp. solution
1589   if(S.ShapeType() == TopAbs_COMPOUND && !isSplit) {
1590     TopoDS_Iterator it(S);
1591     for(;it.More();it.Next())
1592       aSList.Append(it.Value());
1593   } //
1594  
1595   TopTools_IndexedMapOfShape MSC; 
1596   if(aSList.Extent() == 0) {
1597     const Handle(TNaming_NamedShape)& Anc = Args.Last();
1598 #ifdef OCCT_DEBUG_OR
1599     cout << "### ORIENTATION: Ancestor ";
1600     PrintEntry(Anc->Label());
1601 #endif
1602     MSC.Clear();
1603     TNaming_NamingTool::CurrentShape (Valid,Forbiden,Anc,MSC);
1604     if(MSC.Extent() == 1) {
1605       for (Standard_Integer anItMSC = 1; anItMSC <= MSC.Extent(); ++anItMSC) {
1606         const TopoDS_Shape& AS = MSC (anItMSC);
1607 // <=== start 21.10.2009
1608         TopoDS_Shape CS;
1609         if(Index > 0) { //only for seam edge
1610           TopoDS_Iterator itw(AS);
1611           for(;itw.More();itw.Next()) {
1612             Standard_Boolean found(Standard_False);
1613             TopoDS_Iterator it(itw.Value());
1614             for(int i=1;it.More();it.Next(),i++) {
1615               if(i == Index && it.Value().IsSame(S)) {
1616                 CS = it.Value();
1617                 found = Standard_True;
1618 #ifdef OCCT_DEBUG_OR
1619                 cout << "ORIENTATION => ORDER = " << i <<endl;
1620 #endif
1621                 break;
1622               }
1623             }
1624             if(found) break;
1625           }
1626         } else
1627           CS =  FindSubShapeInAncestor(S, AS);
1628 // <=== end 21.10.2009
1629 #ifdef OCCT_DEBUG_OR
1630         cout << "ORIENTATION: Selection" <<" TShape = " <<CS.TShape() <<" Orientation = " << CS.Orientation() <<endl;
1631         cout << "ORIENTATION: Context " << "ShapeType = "<<AS.ShapeType() << " TShape = " <<AS.TShape() <<endl;
1632         DbgTools_Write(AS, "Orientation_Cnt.brep");
1633 #endif
1634         if(!CS.IsNull()) {
1635           B.Select(CS, CS);
1636         } else {
1637           if(!Aggregation(S, AS, B)) 
1638             return Standard_False;        
1639         }
1640       }  
1641     } else {
1642       const TopoDS_Shape  AS = MakeShape(MSC);
1643       const TopoDS_Shape& CS =  FindSubShapeInAncestor(S, AS);
1644       if(!CS.IsNull()) {
1645         B.Select(CS, CS);
1646       }  else {
1647         if(!Aggregation(S, AS, B)) 
1648           return Standard_False;        
1649       }
1650     }
1651   } else {
1652     TNaming_ListIteratorOfListOfNamedShape it(Args); 
1653     it.Next(); //skip first
1654
1655     // temporary solution. To be optimized (+ has connection with Union name)
1656     Handle(TopTools_HArray2OfShape) Arr; // Arr(1,1) - selection; Arr(1,2) - Context shape
1657     Arr = new TopTools_HArray2OfShape (1, aSList.Extent(), 1, 2);
1658     TopTools_ListIteratorOfListOfShape it1(aSList);
1659     Standard_Integer i = 1;
1660     for(; it1.More(); it1.Next(), it.Next(), i++) {
1661       Arr->SetValue(i, 1, it1.Value());
1662       MSC.Clear();
1663       TNaming_NamingTool::CurrentShape (Valid,Forbiden,it.Value(),MSC);
1664       if(MSC.Extent() == 1) {
1665         Arr->SetValue(i, 2, MSC (1));
1666       } else {
1667         const TopoDS_Shape  AS = MakeShape(MSC);
1668         Arr->SetValue(i, 2, AS);
1669       }
1670     } 
1671     
1672     if(aSList.Extent() == 1) {
1673       const TopoDS_Shape& S = Arr->Value(1,1);
1674       if(S.ShapeType() != TopAbs_COMPOUND) {        
1675         const TopoDS_Shape& CS =  FindSubShapeInAncestor(S, Arr->Value(1,2));
1676         if(!CS.IsNull()) {
1677           B.Select(CS, CS);
1678         } else 
1679           return Standard_False;
1680       } 
1681       else {
1682 #ifdef OCCT_DEBUG_OR
1683         DbgTools_Write(Arr->Value(1,2), "Ancestor.brep");
1684 #endif
1685         if(!Aggregation(S, Arr->Value(1,2), B)) { 
1686           return Standard_False;
1687         }
1688       }
1689     }
1690     else { // > 1   
1691       for(Standard_Integer i = Arr->LowerRow();i <= Arr->UpperRow();i++) {
1692         const TopoDS_Shape& S = Arr->Value(i,1);
1693         const TopoDS_Shape& AC = Arr->Value(i,2);
1694         if(S.ShapeType() != TopAbs_COMPOUND) {      
1695           const TopoDS_Shape& CS =  FindSubShapeInAncestor(S, AC);
1696           if(!CS.IsNull()) {
1697             B.Select(CS, CS);
1698           } else 
1699             return Standard_False;
1700         }
1701         else {
1702 #ifdef OCCT_DEBUG_OR
1703           DbgTools_Write(AC, "Aggregation.brep");
1704 #endif
1705           if(!Aggregation(S, AC, B)) { 
1706             return Standard_False;
1707           }
1708         }
1709       }
1710     }
1711   } // end of tmp. solution 
1712
1713   return Standard_True;
1714 }
1715
1716 //===========================================================================
1717 //function : WireIN
1718 //purpose  : to solve  WIREIN name
1719 //=======================================================================
1720 static Standard_Boolean WireIN(const TDF_Label&                L,
1721                                const TDF_LabelMap&             Valid,
1722                                const TNaming_ListOfNamedShape& Args, 
1723                                    const Handle(TNaming_NamedShape)& Stop,
1724                                    Standard_Integer Index)
1725 {
1726   Standard_Boolean aResult(Standard_False);
1727   if(!ValidArgs(Args)) return aResult;
1728   TopTools_IndexedMapOfShape MS; 
1729   TDF_LabelMap        Forbiden;
1730   if (Args.Extent() < 1 ) 
1731     Standard_ConstructionError::Raise("TNaming_Name::Solve"); 
1732   const Handle(TNaming_NamedShape)& A = Args.First();
1733   TNaming_NamingTool::CurrentShape (Valid,Forbiden,A,MS);
1734   if (MS.Extent() != 1) return aResult;
1735   const TopoDS_Shape& aCF = MS (1);
1736 #ifdef OCCT_DEBUG_WIN
1737   cout <<"MS Extent = " <<MS.Extent() <<endl;
1738   DbgTools_Write(aCF, "Context_Face.brep");
1739 #endif
1740   TNaming_Builder B(L);
1741   if(Index == 1 ){ //Outer wire case 
1742     TopoDS_Wire anOuterWire;
1743     TNaming::OuterWire(TopoDS::Face(aCF), anOuterWire);
1744         if(!anOuterWire.IsNull()) {
1745       B.Select(anOuterWire, anOuterWire);
1746           aResult = Standard_True;
1747         }
1748   } else { //has internal wires
1749         TNaming_ListOfNamedShape ArgsE;
1750     ArgsE.Assign(Args);
1751     ArgsE.RemoveFirst();
1752         // fill Map with edges 
1753     TNaming_ListIteratorOfListOfNamedShape it(ArgsE);
1754     TopTools_IndexedMapOfShape MS; 
1755     TDF_LabelMap        Forbiden;
1756   
1757     TNaming_NamingTool::BuildDescendants (Stop, Forbiden);//fill Forbidden
1758     TNaming_NamingTool::CurrentShape  (Valid, Forbiden,it.Value(),MS); // fill MS with last modifications of the first additional argument
1759     TopoDS_Shape  CS = MakeShape(MS);
1760
1761     TNaming_ShapesSet aSet(CS,TopAbs_EDGE);//fill internal map of shapeset by shapes of the specified type
1762 #ifdef OCCT_DEBUG_WIN
1763     TCollection_AsciiString entry; 
1764     TDF_Tool::Entry(it.Value()->Label(), entry);
1765     TCollection_AsciiString Nam("Arg_");
1766     TCollection_AsciiString aNam = Nam + entry + "_" + "2.brep";
1767     DbgTools_Write(CS, aNam.ToCString());
1768     Standard_Integer ii = 2;
1769 #endif
1770     it.Next();
1771     for (; it.More(); it.Next()) {
1772 #ifdef OCCT_DEBUG_WIN 
1773       TDF_Tool::Entry(it.Value()->Label(), entry);
1774 #endif
1775       MS.Clear();
1776       TNaming_NamingTool::CurrentShape (Valid, Forbiden,it.Value(),MS);// fill MS with last modifications of the it.Value()
1777       CS = MakeShape(MS); 
1778       TNaming_ShapesSet OS(CS,TopAbs_EDGE);
1779       aSet.Add(OS); //concatenate both shapesets
1780  
1781 #ifdef OCCT_DEBUG_WIN
1782       ii++;
1783       TCollection_AsciiString aNm = Nam + entry + "_" + ii + ".brep";
1784       DbgTools_Write(CS, aNm.ToCString());
1785       cout <<"Arg: Entry = " <<entry <<"  TShape = " << CS.TShape() <<endl;
1786 #endif
1787         }
1788
1789 #ifdef OCCT_DEBUG_WIN
1790     cout <<"WIREIN: " << " Internal Map ext = " << aSet.Map().Extent()<<endl;
1791     TopTools_MapIteratorOfMapOfShape it1 (aSet.Map());
1792     for (int i=1;it1.More();it1.Next(),i++) {
1793       cout << "Map("<<i<<"): TShape = " << it1.Key().TShape() << " Orient = " << it1.Key().Orientation() <<" Type = " <<
1794                   it1.Key().ShapeType()<<endl;
1795     }
1796     
1797     TopExp_Explorer exp(aCF, TopAbs_EDGE);
1798     for(int i =1;exp.More();exp.Next(), i++) {
1799      cout << "Context_Face("<<i<<"): TShape = " << exp.Current().TShape() << " Orient = " << exp.Current().Orientation() <<endl;
1800     }       
1801 #endif
1802 //end for edges
1803         
1804   for (TopoDS_Iterator itF(aCF); itF.More(); itF.Next()) {// find the expected wire in the face
1805     const TopoDS_Shape& S = itF.Value();//wire
1806         if(!S.IsNull()) {
1807 #ifdef OCCT_DEBUG_WIN    
1808       DbgTools_Write(S, "WireIN_S.brep");
1809       cout <<"WIREIN: ShapeType = " << S.ShapeType() << " TS = " << S.TShape()->This() <<endl;
1810 #endif       
1811       if(S.ShapeType() == TopAbs_WIRE) {
1812                 TopTools_MapOfShape aView;
1813                 Standard_Integer aNum(0x7FFFFFFF);
1814             for (TopoDS_Iterator it(S);it.More();it.Next())
1815           aView.Add(it.Value());// edges of wire of the face in map
1816
1817         TopTools_MapIteratorOfMapOfShape it (aSet.Map());
1818                 aNum = aView.Extent();
1819                 if(aNum == aSet.Map().Extent()) {
1820           for (;it.More();it.Next()) {
1821                         if(aView.Contains(it.Key())) {
1822                                 aNum--;
1823                         }
1824                   }
1825                 }
1826                 if(aNum == 0) {
1827                   B.Select(S, S);
1828               aResult = Standard_True;
1829               break;
1830                 }
1831           }
1832         }       
1833   } //
1834
1835   if(!aResult) {
1836         TopoDS_Wire anOuterWire;
1837     TNaming::OuterWire(TopoDS::Face(aCF), anOuterWire);
1838         if(!anOuterWire.IsNull()) {
1839       for (TopoDS_Iterator itF(aCF); itF.More(); itF.Next()) {
1840         const TopoDS_Shape& S = itF.Value();//wire
1841             if(!S.IsNull()&& S.ShapeType() == TopAbs_WIRE) {
1842                   if(S.IsEqual(anOuterWire)) continue;
1843                   B.Select(S, S);
1844                 }
1845           }
1846         }
1847   }
1848   }
1849   return aResult;
1850 }
1851 //===========================================================================
1852 //function : ShellIN
1853 //purpose  : to solve  SHELLIN name
1854 //===========================================================================
1855 static Standard_Boolean ShellIN(const TDF_Label&                L,
1856                                const TDF_LabelMap&             Valid,
1857                                const TNaming_ListOfNamedShape& Args, 
1858                                    const Handle(TNaming_NamedShape)& Stop,
1859                                    Standard_Integer Index)
1860 {
1861   Standard_Boolean aResult(Standard_False);
1862   if(!ValidArgs(Args)) 
1863           return aResult;
1864   TopTools_IndexedMapOfShape MS; 
1865   TDF_LabelMap        Forbiden;
1866   if (Args.Extent() < 1 ) 
1867     Standard_ConstructionError::Raise("TNaming_Name::Solve"); 
1868   const Handle(TNaming_NamedShape)& A = Args.First();
1869   TNaming_NamingTool::CurrentShape (Valid,Forbiden,A,MS);
1870   if (MS.Extent() != 1) return aResult;
1871   const TopoDS_Shape& aCSO = MS (1);
1872 #ifdef OCCT_DEBUG_SHELL
1873   cout <<"MS Extent = " <<MS.Extent() <<endl;
1874   DbgTools_Write(aCSO, "Context_Solid.brep");
1875 #endif
1876   TNaming_Builder B(L);
1877   if(Index == 1 ){ //Outer Shell case  
1878         TopoDS_Shell anOuterShell;
1879         TNaming::OuterShell(TopoDS::Solid(aCSO), anOuterShell);
1880         if(!anOuterShell.IsNull()) {
1881       B.Select(anOuterShell, anOuterShell);
1882           aResult = Standard_True;
1883 #ifdef OCCT_DEBUG_SHELL      
1884           cout << "Outer Shell case" <<endl;
1885       PrintEntry(L);
1886           DbgTools_Write(anOuterShell, "ShellOut_S.brep");
1887           TopoDS_Iterator it (aCSO);
1888                 for(;it.More();it.Next()){ 
1889           DbgTools_Write(it.Value(), "ShOut_S.brep");
1890                 }
1891 #endif       
1892         }
1893   } else { //has internal Shells
1894         TNaming_ListOfNamedShape ArgsF;
1895     ArgsF.Assign(Args);
1896     ArgsF.RemoveFirst();
1897         // fill Map with faces 
1898     TNaming_ListIteratorOfListOfNamedShape it(ArgsF);
1899     TopTools_IndexedMapOfShape MS; 
1900     TDF_LabelMap        Forbiden;
1901   
1902     TNaming_NamingTool::BuildDescendants (Stop, Forbiden);//fill Forbidden
1903     TNaming_NamingTool::CurrentShape  (Valid, Forbiden,it.Value(),MS); // fill MS with last modifications of the first additional argument
1904     TopoDS_Shape  CS = MakeShape(MS);
1905
1906     TNaming_ShapesSet aSet(CS,TopAbs_FACE);//fill internal map of shapeset by shapes of the specified type
1907 #ifdef OCCT_DEBUG_SHELL
1908     TCollection_AsciiString entry; 
1909     TDF_Tool::Entry(it.Value()->Label(), entry);
1910     TCollection_AsciiString Nam("Arg_");
1911     TCollection_AsciiString aNam = Nam + entry + "_" + "2.brep";
1912     DbgTools_Write(CS, aNam.ToCString());
1913     Standard_Integer ii = 2;
1914 #endif
1915     it.Next();
1916     for (; it.More(); it.Next()) {
1917 #ifdef OCCT_DEBUG_SHELL 
1918       TDF_Tool::Entry(it.Value()->Label(), entry);
1919 #endif
1920       MS.Clear();
1921       TNaming_NamingTool::CurrentShape (Valid, Forbiden,it.Value(),MS);// fill MS with last modifications of the it.Value()
1922       CS = MakeShape(MS); 
1923       TNaming_ShapesSet OS(CS,TopAbs_FACE);
1924       aSet.Add(OS); //concatenate both shapesets
1925  
1926 #ifdef OCCT_DEBUG_SHELL
1927       ii++;
1928       TCollection_AsciiString aNm = Nam + entry + "_" + ii + ".brep";
1929       DbgTools_Write(CS, aNm.ToCString());
1930       cout <<"Arg: Entry = " <<entry <<"  TShape = " << CS.TShape() <<endl;
1931 #endif
1932         }
1933
1934 #ifdef OCCT_DEBUG_SHELL
1935     cout <<"SHELLIN: " << " Internal Map ext = " << aSet.Map().Extent()<<endl;
1936     TopTools_MapIteratorOfMapOfShape it1 (aSet.Map());
1937     for (int i=1;it1.More();it1.Next(),i++) {
1938       cout << "Map("<<i<<"): TShape = " << it1.Key().TShape() << " Orient = " << it1.Key().Orientation() <<" Type = " <<
1939                   it1.Key().ShapeType()<<endl;
1940     }
1941     
1942     TopExp_Explorer exp(aCSO, TopAbs_FACE);
1943     for(int i = 1;exp.More();exp.Next(), i++) {
1944      cout << "Context_Solid("<<i<<"): TShape = " << exp.Current().TShape() << " Orient = " << exp.Current().Orientation() <<endl;
1945     }       
1946 #endif
1947 //end for faces
1948         
1949   for (TopoDS_Iterator itS(aCSO); itS.More(); itS.Next()) {// find the expected shell in the solid
1950     const TopoDS_Shape& S = itS.Value();//shell
1951         if(!S.IsNull()) {
1952 #ifdef OCCT_DEBUG_SHELL    
1953       DbgTools_Write(S, "ShellIN_S.brep");
1954       cout <<"SHELLIN: ShapeType = " << S.ShapeType() << " TS = " << S.TShape()->This() <<endl;
1955 #endif       
1956           if(S.ShapeType() == TopAbs_SHELL) {
1957                 TopTools_MapOfShape aView;
1958                 Standard_Integer aNum(0x7FFFFFFF);
1959             for (TopoDS_Iterator it(S);it.More();it.Next())
1960           aView.Add(it.Value());// faces of shell of the solid in map
1961         
1962                 aNum = aView.Extent();
1963                 if(aNum == aSet.Map().Extent()) {
1964                   TopTools_MapIteratorOfMapOfShape it (aSet.Map());
1965           for (;it.More();it.Next()) {
1966                         if(aView.Contains(it.Key())) {
1967                                 aNum--;
1968                         }
1969                   }
1970                 }
1971                 if(aNum == 0) {
1972                   B.Select(S, S);
1973               aResult = Standard_True;
1974               break;
1975                 }
1976           }
1977         }       
1978   } //
1979
1980   if(!aResult) {    
1981         TopoDS_Shell anOuterShell; 
1982         TNaming::OuterShell(TopoDS::Solid(aCSO), anOuterShell);
1983         if(!anOuterShell.IsNull()) {
1984       for (TopoDS_Iterator itS(aCSO); itS.More(); itS.Next()) {
1985         const TopoDS_Shape& S = itS.Value();//shell
1986             if(!S.IsNull()&& S.ShapeType() == TopAbs_SHELL) {
1987                   if(S.IsEqual(anOuterShell)) continue;
1988                   B.Select(S, S);
1989                 }
1990           }
1991         }
1992   }
1993   }
1994   return aResult;
1995 }
1996 #ifdef OCCT_DEBUG
1997 //=======================================================================
1998 static  Standard_CString NameTypeToString (const TNaming_NameType Type)
1999 {
2000   switch(Type)
2001     {
2002     case  TNaming_UNKNOWN             : return "UNKNOWN";
2003     case  TNaming_IDENTITY            : return "IDENTITY";
2004     case  TNaming_MODIFUNTIL          : return "MODIFUNTIL";
2005     case  TNaming_GENERATION          : return "GENERATION";
2006     case  TNaming_INTERSECTION        : return "INTERSECTION";
2007     case  TNaming_UNION               : return "UNION";
2008     case  TNaming_SUBSTRACTION        : return "SUBSTRACTION";
2009     case  TNaming_CONSTSHAPE          : return "CONSTSHAPE";
2010     case  TNaming_FILTERBYNEIGHBOURGS : return "FILTERBYNEIGHBOURGS";
2011     case  TNaming_ORIENTATION         : return "ORIENTATION";
2012     case  TNaming_WIREIN              : return "WIREIN";
2013       default :
2014         Standard_DomainError::Raise("TNaming_NameType; enum term unknown ");
2015     }
2016   return "";
2017 }
2018 #endif
2019 //=======================================================================
2020 //function : Solve
2021 //purpose  : 
2022 //=======================================================================
2023
2024 Standard_Boolean TNaming_Name::Solve(const TDF_Label&    aLab,
2025                                      const TDF_LabelMap& Valid) const
2026 {
2027   Standard_Boolean Done = 0;
2028 #ifdef OCCT_DEBUG_WIN
2029   PrintEntry(aLab);
2030 #endif
2031   try {
2032   OCC_CATCH_SIGNALS
2033   switch (myType) {
2034   case TNaming_UNKNOWN :
2035     {
2036       break;
2037     }  
2038   case TNaming_IDENTITY :
2039     {  
2040       Done = Identity(aLab,Valid,myArgs,myShapeType); 
2041       break;
2042     }
2043   case TNaming_MODIFUNTIL:
2044     {
2045       Done = ModifUntil (aLab,Valid,myArgs,myStop);
2046       break;
2047     }
2048   case TNaming_GENERATION:
2049     {
2050       Done = Generated (aLab,Valid,myArgs);
2051       break;
2052     }
2053   case TNaming_INTERSECTION:
2054     {
2055       Done = Intersection (aLab,Valid,myArgs,myStop,myShapeType,myIndex); 
2056       break;
2057     }
2058   case TNaming_UNION:
2059     {
2060       Done = Union (aLab,Valid,myArgs,myStop,myShapeType, myContextLabel);
2061       break;
2062     }
2063   case TNaming_SUBSTRACTION: 
2064     {
2065       Standard_NotImplemented::Raise();
2066 //      Done = Substraction (aLab,Valid,myArgs);
2067       break;
2068     }
2069   case TNaming_CONSTSHAPE:
2070     {
2071       Done = ConstShape (aLab,Valid,myArgs,myStop,myIndex);
2072       break;
2073     }
2074   case TNaming_FILTERBYNEIGHBOURGS:
2075     {
2076       Done = FilterByNeighbourgs (aLab,Valid,myArgs,myStop,myShapeType);
2077       break;
2078     }
2079   case TNaming_ORIENTATION: 
2080     {
2081       Done = ORientation (aLab,Valid,myArgs,myStop,myIndex);
2082       break;
2083     }
2084   case TNaming_WIREIN: 
2085     {
2086 #ifdef OCCT_DEBUG_WIN  
2087       cout << "Name::Solve: NameType = " << myType << "  ";
2088   PrintEntry(aLab);
2089 #endif
2090       Done = WireIN (aLab,Valid,myArgs,myStop,myIndex);
2091       break;
2092     }
2093 case TNaming_SHELLIN: 
2094     {
2095 #ifdef OCCT_DEBUG_SHELL
2096       cout << "Name::Solve: NameType = " << myType << "  ";
2097       PrintEntry(aLab);
2098 #endif
2099       Done = ShellIN (aLab,Valid,myArgs,myStop,myIndex);      
2100       break;
2101     }
2102   }
2103 } catch (Standard_Failure) {
2104 #ifdef OCCT_DEBUG
2105   cout << "Name::Solve: EXCEPTION==> NameType = " << NameTypeToString(myType) << "  ";
2106   PrintEntry(aLab);
2107 #endif
2108 }
2109   return Done;
2110 }
2111
2112 //=======================================================================
2113 //function : ContextLabel
2114 //purpose  : Set
2115 //=======================================================================
2116
2117 void TNaming_Name::ContextLabel(const TDF_Label& theLabel)
2118 {
2119   myContextLabel = theLabel;
2120 }
2121
2122 //=======================================================================
2123 //function : ContextLabel
2124 //purpose  : Get
2125 //=======================================================================
2126
2127 const TDF_Label&  TNaming_Name::ContextLabel() const
2128
2129   return myContextLabel;
2130 }
2131
2132 //=======================================================================
2133 //function : Orientation
2134 //purpose  : Set
2135 //=======================================================================
2136 void TNaming_Name::Orientation(const TopAbs_Orientation theOrientation) 
2137 {
2138   myOrientation = theOrientation;
2139 }
2140