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