0023664: Eliminate linker warnings on import of local symbol
[occt.git] / src / BRepFeat / BRepFeat_Form.cxx
1 // Created on: 1996-02-13
2 // Created by: Olga KOULECHOVA
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22
23 #include <BRepFeat_Form.ixx>
24
25 #include <LocOpe.hxx>
26 #include <LocOpe_Builder.hxx>
27 #include <LocOpe_Gluer.hxx>
28 #include <LocOpe_FindEdges.hxx>
29 #include <LocOpe_CSIntersector.hxx>
30 #include <LocOpe_SequenceOfCirc.hxx>
31 #include <LocOpe_PntFace.hxx>
32 #include <LocOpe_BuildShape.hxx>
33
34 #include <TopExp_Explorer.hxx>
35 #include <TopOpeBRepBuild_HBuilder.hxx>
36 #include <TopTools_MapOfShape.hxx>
37 #include <TopTools_ListIteratorOfListOfShape.hxx>
38 #include <TopTools_MapIteratorOfMapOfShape.hxx>
39 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
40 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
41 #include <TColgp_SequenceOfPnt.hxx>
42 #include <Standard_NoSuchObject.hxx>
43 #include <Precision.hxx>
44
45 #include <BRep_Tool.hxx>
46 #include <Geom_RectangularTrimmedSurface.hxx>
47 #include <Geom_Plane.hxx>
48 #include <Geom_CylindricalSurface.hxx>
49 #include <Geom_ConicalSurface.hxx>
50
51 #include <TopoDS_Solid.hxx>
52 #include <TopoDS_Compound.hxx>
53 #include <BRepTools_Modifier.hxx>
54 #include <BRepTools_TrsfModification.hxx>
55 #include <BRepFeat.hxx>
56 #include <BRepCheck_Analyzer.hxx>
57 #include <TopoDS.hxx>
58
59 #include <Bnd_Box.hxx>
60 #include <BRepBndLib.hxx>
61 #include <BRepLib.hxx>
62
63 #include <ElCLib.hxx>
64
65 #include <BRepAlgo.hxx>
66 //modified by NIZNHY-PKV Thu Mar 21 17:30:25 2002 f
67 //#include <BRepAlgo_Cut.hxx>
68 //#include <BRepAlgo_Fuse.hxx>
69
70 #include <BRepAlgoAPI_Cut.hxx>
71 #include <BRepAlgoAPI_Fuse.hxx>
72 //modified by NIZNHY-PKV Thu Mar 21 17:30:29 2002 t
73
74 #ifdef DEB
75 extern Standard_Boolean BRepFeat_GettraceFEAT();
76 #endif
77
78 static void Descendants(const TopoDS_Shape&,
79                         const LocOpe_Builder&,
80                         TopTools_MapOfShape&);
81
82
83
84 //=======================================================================
85 //function : Perform
86 //purpose  : topological reconstruction of the result
87 //=======================================================================
88   void BRepFeat_Form::GlobalPerform () 
89 {
90
91 #ifdef DEB
92   Standard_Boolean trc = BRepFeat_GettraceFEAT();
93   if (trc) cout << "BRepFeat_Form::GlobalPerform ()" << endl;
94 #endif
95
96   if (!mySbOK || !myGSOK || !mySFOK || !mySUOK || !myGFOK || 
97       !mySkOK || !myPSOK) {
98 #ifdef DEB
99     if (trc) cout << " Fields not initialized in BRepFeat_Form" << endl;
100 #endif
101     myStatusError = BRepFeat_NotInitialized;
102     NotDone();
103     return;
104   }
105
106
107 //--- Initialisation
108   Standard_Integer addflag = 0;
109
110   TopExp_Explorer exp,exp2;
111   Standard_Integer theOpe = 2;
112
113   if(myJustFeat && !myFuse) {
114 #ifdef DEB
115     if (trc) cout << " Invalid option : myJustFeat + Cut" << endl;
116 #endif
117     myStatusError = BRepFeat_InvOption;
118     NotDone();
119     return;    
120   }
121   else if(myJustFeat) {
122     theOpe = 2;
123   }
124   else if (!myGluedF.IsEmpty()) {
125     theOpe = 1;
126   }
127   else {}
128   Standard_Boolean ChangeOpe = Standard_False;
129
130
131 //--- Add Shape From and Until in the map to avoid setting them in LShape
132   Standard_Boolean FromInShape = Standard_False;
133   Standard_Boolean UntilInShape = Standard_False;
134   TopTools_MapOfShape M;
135   
136   if (!mySFrom.IsNull()) {
137     FromInShape = Standard_True;
138     for (exp2.Init(mySFrom,TopAbs_FACE); exp2.More(); exp2.Next()) {
139       const TopoDS_Shape& ffrom = exp2.Current();
140       for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
141         if (exp.Current().IsSame(ffrom)) {
142           break;
143         }
144       }
145       if (!exp.More()) {
146         FromInShape = Standard_False;
147 #ifdef DEB
148         if (trc) cout << " From not in Shape" << endl;
149 #endif
150         break;
151       }
152       else {
153         addflag++;
154         M.Add(ffrom);
155       }
156     }
157   }
158
159   if (!mySUntil.IsNull()) {
160     UntilInShape = Standard_True;
161     for (exp2.Init(mySUntil,TopAbs_FACE); exp2.More(); exp2.Next()) {
162       const TopoDS_Shape& funtil = exp2.Current();
163       for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
164         if (exp.Current().IsSame(funtil)) {
165           break;
166         }
167       }
168       if (!exp.More()) {
169         UntilInShape = Standard_False;
170 #ifdef DEB
171         if (trc) cout << " Until not in Shape" << endl;
172 #endif
173         break;
174       }
175       else {
176         addflag++;
177         M.Add(funtil);
178       }
179     }
180   }
181
182
183 //--- Add Faces of glueing in the map to avoid setting them in LShape
184   TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
185   for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
186     M.Add(itm.Value());
187   }
188
189
190 //--- Find in the list LShape faces concerned by the feature
191
192   TopTools_ListOfShape LShape;
193   TopTools_ListIteratorOfListOfShape it,it2;
194   Standard_Integer sens = 0;
195
196   TColGeom_SequenceOfCurve scur;
197   Curves(scur);
198
199   Standard_Integer tempo;
200   Standard_Real locmin;
201   Standard_Real locmax;
202   Standard_Real mf, Mf, mu, Mu;
203
204   TopAbs_Orientation Orifuntil = TopAbs_INTERNAL;
205   TopAbs_Orientation Oriffrom = TopAbs_INTERNAL;
206   TopoDS_Face FFrom,FUntil;
207   
208   LocOpe_CSIntersector ASI1;
209   LocOpe_CSIntersector ASI2;
210
211
212 #ifndef VREF  
213   LocOpe_CSIntersector ASI3(mySbase);
214   ASI3.Perform(scur);
215 #endif
216
217   TopTools_ListOfShape IntList;
218   IntList.Clear();
219
220
221 //--- 1) by intersection
222
223 // Intersection Tool Shape From
224   if (!mySFrom.IsNull()) {
225     ASI1.Init(mySFrom);
226     ASI1.Perform(scur);
227   }
228
229 // Intersection Tool Shape Until
230   if (!mySUntil.IsNull()) {
231     ASI2.Init(mySUntil);
232     ASI2.Perform(scur);
233   }
234
235 #ifndef VREF
236 // Intersection Tool base Shape 
237   if (!ASI3.IsDone()) {
238     theOpe = 2;
239     LShape.Clear();
240   }
241   else
242 #endif
243   {
244 //  Find sens, locmin, locmax, FFrom, FUntil
245     tempo=0;
246     locmin = RealFirst();
247     locmax = RealLast();
248     for (Standard_Integer jj=1; jj<=scur.Length(); jj++) {
249       if (ASI1.IsDone() && ASI2.IsDone()) {
250         if (ASI1.NbPoints(jj) <= 0) {
251           continue;
252         }
253         mf = ASI1.Point(jj,1).Parameter();
254         Mf = ASI1.Point(jj,ASI1.NbPoints(jj)).Parameter();
255         if (ASI2.NbPoints(jj) <= 0) {
256           continue;
257         }
258         mu = ASI2.Point(jj,1).Parameter();
259         Mu = ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter();
260         if (scur(jj)->IsPeriodic()) {
261           Standard_Real period = scur(jj)->Period();
262           locmin = mf;
263           locmax = ElCLib::InPeriod(Mu,locmin,locmin+period);
264         }
265         else {
266           Standard_Integer ku, kf;
267           if (! (mu > Mf || mf > Mu)) { //overlapping intervals
268             sens = 1;
269             kf = 1;
270             ku = ASI2.NbPoints(jj);
271             locmin = mf;
272             locmax = Max(Mf, Mu);
273           }   
274           else if (mu > Mf) {    
275             if (sens == -1) {
276               myStatusError = BRepFeat_IntervalOverlap;
277               NotDone();
278               return;
279             }
280             sens = 1;
281             kf = 1;
282             ku = ASI2.NbPoints(jj);
283             locmin = mf;
284             locmax = Mu;
285           }
286           else {
287             if (sens == 1) {
288               myStatusError = BRepFeat_IntervalOverlap;
289               NotDone();
290               return;
291             }
292             sens = -1;
293             kf = ASI1.NbPoints(jj);
294             ku = 1;
295             locmin = mu;
296             locmax = Mf;
297           }
298           if (Oriffrom == TopAbs_INTERNAL) {
299             TopAbs_Orientation Oript = ASI1.Point(jj,kf).Orientation();
300             if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
301               if (sens == -1) {
302                 Oript = TopAbs::Reverse(Oript);
303               }
304               Oriffrom = TopAbs::Reverse(Oript);
305               FFrom = ASI1.Point(jj,kf).Face();
306             }
307           }
308           if (Orifuntil == TopAbs_INTERNAL) {
309               TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
310               if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
311                 if (sens == -1) {
312                   Oript = TopAbs::Reverse(Oript);
313                 }
314                 Orifuntil = Oript;
315                 FUntil = ASI2.Point(jj,ku).Face();
316               }
317             }
318         }
319       }
320       else if (ASI2.IsDone()) {
321         if (ASI2.NbPoints(jj) <= 0) 
322           continue;
323
324 // for base case prism on mySUntil -> ambivalent direction
325 //      ->  preferrable direction = 1
326         if(sens != 1) {
327           if (ASI2.Point(jj,1).Parameter()*
328               ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter()<=0) 
329             sens=1;
330           else if (ASI2.Point(jj,1).Parameter()<0.) 
331             sens =-1;
332           else 
333             sens =1;
334         }
335
336         Standard_Integer ku;
337         if (sens == -1) {
338           ku = 1;
339           locmax = -ASI2.Point(jj,ku).Parameter();
340           locmin = 0.;
341         }
342         else {
343           ku = ASI2.NbPoints(jj);
344           locmin = 0;
345           locmax =  ASI2.Point(jj,ku).Parameter();
346         }
347         if (Orifuntil == TopAbs_INTERNAL && sens != 0) {
348           TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
349           if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
350             if (sens == -1) {
351               Oript = TopAbs::Reverse(Oript);
352             }
353             Orifuntil = Oript;
354             FUntil = ASI2.Point(jj,ku).Face();
355           }
356         }
357       }
358       else { 
359         locmin = 0.;
360         locmax = RealLast();
361         sens = 1;
362         break;
363       }
364
365
366 //      Update LShape by adding faces of the base Shape 
367 //        that are OK (sens, locmin and locmax)
368 //        that are not yet in the map (Shape From Until and glue faces)
369 #ifndef VREF
370       if (theOpe == 2) {
371         for (Standard_Integer i=1; i<=ASI3.NbPoints(jj); i++) {
372           Standard_Real theprm = ASI3.Point(jj,i).Parameter() ;
373           if(locmin > locmax) {
374             Standard_Real temp = locmin;
375             locmin = locmax; locmax = temp;
376           }
377           if (theprm <= locmax &&
378               theprm >= locmin) {
379             const TopoDS_Face& fac = ASI3.Point(jj,i).Face();
380             if (M.Add(fac)) { 
381               LShape.Append(ASI3.Point(jj,i).Face());
382             }
383           }
384         }
385       }
386       else {
387         TopAbs_Orientation Or;
388         Standard_Integer Indfm,IndtM,i;
389         Standard_Real Tol = -Precision::Confusion();
390         if(sens == 1) {
391           if (ASI3.LocalizeAfter(jj,locmin,Tol,Or,Indfm,i) && 
392               ASI3.LocalizeBefore(jj,locmax,Tol,Or,i,IndtM)) {
393             for (i= Indfm; i<=IndtM; i++) {
394               const TopoDS_Face& fac = ASI3.Point(jj,i).Face();
395               if (M.Add(fac)) { 
396                 LShape.Append(fac);
397               }
398             }
399           }
400         }
401         else if(sens == -1) {
402           if (ASI3.LocalizeBefore(jj,locmin,Tol,Or,Indfm,i) && 
403               ASI3.LocalizeAfter(jj,-locmax,Tol,Or,i,IndtM)) {
404             for (i= Indfm; i<=IndtM; i++) {
405               const TopoDS_Face& fac = ASI3.Point(jj,i).Face();
406               if (M.Add(fac)) { 
407                 LShape.Append(fac);
408               }
409             }
410           }       
411         }
412       }
413 #endif
414     }
415   }
416
417 #ifndef VREF 
418       
419 //--- 2) by section with the bounding box
420     
421   Bnd_Box prbox;
422   BRepBndLib::Add(myGShape,prbox);
423   
424   Bnd_Box bbb;
425   if(!mySFrom.IsNull() && !mySUntil.IsNull()) {
426     BRepBndLib::Add(mySUntil, bbb);
427     BRepBndLib::Add(mySFrom, bbb);
428   }
429   else if(!mySUntil.IsNull() && !mySkface.IsNull()) {
430     BRepBndLib::Add(mySUntil, bbb);
431     BRepBndLib::Add(mySkface, bbb);
432   }
433   else {
434     bbb.SetWhole();
435   }
436   
437   TopExp_Explorer exx1(mySbase, TopAbs_FACE);
438   Standard_Integer counter = 0;
439   
440
441 // Are not processed: the face of gluing 
442 //                    the faces of Shape From
443 //                    the faces of Shape Until
444 //                    the faces already in LShape
445 //                    the faces of myGluedF
446 // If the face was not eliminated ... it is preserved if bounding box 
447 // collides with the box of myGShape = outil
448 //                    or the box of limit faces (mySFrom mySUntil mySkface)    
449   for(; exx1.More(); exx1.Next()) {
450     const TopoDS_Face& sh = TopoDS::Face(exx1.Current());
451     counter++;    
452     
453     if(sh.IsSame(mySkface) && theOpe==1) continue;
454
455     if(!mySFrom.IsNull()) {
456       TopExp_Explorer explor(mySFrom, TopAbs_FACE);
457       for(; explor.More(); explor.Next()) {
458         const TopoDS_Face& fff = TopoDS::Face(explor.Current());
459         if(fff.IsSame(sh)) break;
460       }
461       if(explor.More()) continue;
462     }
463     
464     if(!mySUntil.IsNull()) {
465       TopExp_Explorer explor(mySUntil, TopAbs_FACE);
466       for(; explor.More(); explor.Next()) {
467         const TopoDS_Face& fff = TopoDS::Face(explor.Current());
468         if(fff.IsSame(sh)) break;
469       }
470       if(explor.More()) continue;
471     }
472     
473     TopTools_ListIteratorOfListOfShape iter1(LShape);
474     for(; iter1.More(); iter1.Next()) {
475       if(iter1.Value().IsSame(sh)) break;
476     }
477     if(iter1.More()) continue;
478     
479     for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
480       const TopoDS_Face& glf = TopoDS::Face(itm.Value());
481       if(glf.IsSame(sh)) break;
482     }
483     if(itm.More()) continue;
484     
485     Bnd_Box shbox;
486     BRepBndLib::Add(sh,shbox);
487     
488     if(shbox.IsOut(bbb) || shbox.IsOut(prbox)) continue;
489     //    if(shbox.IsOut(prbox)) continue;
490     
491     if(M.Add(sh)) {
492       LShape.Append(sh);
493     }
494   }
495
496 #endif
497
498 #ifdef VREF
499 // test of performance : add all faces of the base Shape in LShape
500 // (no phase of parsing, but more faces) -> no concluant
501   TopExp_Explorer exx1;
502   for (exx1.Init(mySbase, TopAbs_FACE);
503        exx1.More(); exx1.Next()) {
504     const TopoDS_Shape& fac = exx1.Current();
505     if (M.Add(fac)) {
506       LShape.Append(fac);
507     }
508   }
509
510 #endif
511
512   LocOpe_Gluer theGlue;
513   
514 //--- case of gluing
515
516   if (theOpe == 1) {
517 #ifdef DEB
518     if (trc) cout << " Gluer" << endl;
519 #endif
520     Standard_Boolean Collage = Standard_True;  
521     // cut by FFrom && FUntil
522     TopoDS_Shape Comp;
523     BRep_Builder B;
524     B.MakeCompound(TopoDS::Compound(Comp));
525     if (!mySFrom.IsNull()) {
526       TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
527       if (!S.IsNull()) {
528         B.Add(Comp,S);
529       }
530     }
531     if (!mySUntil.IsNull()) {
532       TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
533       if (!S.IsNull()) {
534         B.Add(Comp,S);
535       }
536     }
537
538     LocOpe_FindEdges theFE;
539     TopTools_DataMapOfShapeListOfShape locmap;
540     TopExp_Explorer expp(Comp, TopAbs_SOLID);
541     if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())  {
542       //modified by NIZNHY-PKV Thu Mar 21 17:15:36 2002 f
543       //BRepAlgo_Cut trP(myGShape,Comp);
544       BRepAlgoAPI_Cut trP(myGShape, Comp);
545       //modified by NIZNHY-PKV Thu Mar 21 17:15:58 2002 t
546       exp.Init(trP.Shape(), TopAbs_SOLID);
547       if (exp.Current().IsNull()) {
548         theOpe = 2;
549         ChangeOpe = Standard_True;
550         Collage = Standard_False;
551       }
552       else {// else X0
553         // Only solids are preserved
554         TopoDS_Shape theGShape;
555         BRep_Builder B;
556         B.MakeCompound(TopoDS::Compound(theGShape));
557         for (; exp.More(); exp.Next()) {
558           B.Add(theGShape,exp.Current());
559         }
560         if (!BRepAlgo::IsValid(theGShape)) {
561           theOpe = 2;
562           ChangeOpe = Standard_True;
563           Collage = Standard_False;
564         }
565         else {// else X1
566           if(!mySFrom.IsNull()) { 
567             TopExp_Explorer ex;
568             ex.Init(mySFrom, TopAbs_FACE);
569             for(; ex.More(); ex.Next()) {
570               const TopoDS_Face& fac = TopoDS::Face(ex.Current());
571               if (!FromInShape) {
572                 TopTools_ListOfShape thelist;
573                 myMap.Bind(fac, thelist);
574               }
575               else {
576                 TopTools_ListOfShape thelist1;
577                 locmap.Bind(fac, thelist1);
578               }
579               if (trP.IsDeleted(fac)) {
580               }
581               else if (!FromInShape) {
582                 myMap(fac) = trP.Modified(fac);
583                 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
584               }
585               else {
586                 locmap(fac) =trP.Modified(fac) ;
587                 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
588               }
589             }
590           }// if(!mySFrom.IsNull()) 
591           //
592           if(!mySUntil.IsNull()) { 
593             TopExp_Explorer ex;
594             ex.Init(mySUntil, TopAbs_FACE);
595             for(; ex.More(); ex.Next()) {
596               const TopoDS_Face& fac = TopoDS::Face(ex.Current());
597               if (!UntilInShape) {              
598                 TopTools_ListOfShape thelist2;
599                 myMap.Bind(fac,thelist2);
600               }
601               else {
602                 TopTools_ListOfShape thelist3;
603                 locmap.Bind(fac,thelist3);
604               }
605               if (trP.IsDeleted(fac)) {
606               }
607               else if (!UntilInShape) {
608                 myMap(fac) = trP.Modified(fac);
609                 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
610               }
611               else {
612                 locmap(fac) = trP.Modified(fac);
613                 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
614               }
615             }
616           }// if(!mySUntil.IsNull())
617           //
618           //modified by NIZNHY-PKV Thu Mar 21 17:21:49 2002 f
619           //UpdateDescendants(trP.Builder(),theGShape,Standard_True); // skip faces
620           UpdateDescendants(trP,theGShape,Standard_True); // skip faces
621           //modified by NIZNHY-PKV Thu Mar 21 17:22:32 2002 t
622
623           theGlue.Init(mySbase,theGShape);
624           for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
625             const TopoDS_Face& gl = TopoDS::Face(itm.Key());
626             TopTools_ListOfShape ldsc;
627             if (trP.IsDeleted(gl)) {
628             }
629             else {
630               ldsc = trP.Modified(gl);
631               if (ldsc.IsEmpty()) ldsc.Append(gl);
632             }
633             const TopoDS_Face& glface = TopoDS::Face(itm.Value());      
634             for (it.Initialize(ldsc);it.More();it.Next()) {
635               const TopoDS_Face& fac = TopoDS::Face(it.Value());
636               Collage = BRepFeat::IsInside(fac, glface);
637               if(!Collage) {
638                 theOpe = 2;
639                 ChangeOpe = Standard_True;
640                 break;
641               }
642               else {
643                 theGlue.Bind(fac,glface);
644                 theFE.Set(fac,glface);
645                 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
646                   theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
647                 }
648               }
649             }
650           }
651         }// else X1
652       }// else X0
653     }// if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) 
654     else {
655       theGlue.Init(mySbase,myGShape);
656       for (itm.Initialize(myGluedF); itm.More();itm.Next()) {
657         const TopoDS_Face& glface = TopoDS::Face(itm.Key());
658         const TopoDS_Face& fac = TopoDS::Face(myGluedF(glface));
659         for (exp.Init(myGShape,TopAbs_FACE); exp.More(); exp.Next()) {
660           if (exp.Current().IsSame(glface)) {
661             break;
662           }
663         }
664         if (exp.More()) {
665           Collage = BRepFeat::IsInside(glface, fac);
666           if(!Collage) {
667             theOpe = 2;
668             ChangeOpe = Standard_True;
669             break;
670           }
671           else {
672             theGlue.Bind(glface, fac);
673             theFE.Set(glface, fac);
674             for (theFE.InitIterator(); theFE.More();theFE.Next()) {
675               theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
676             }
677           }
678         }
679       }
680     }
681
682     // Add gluing on start and end face if necessary !!!
683     if (FromInShape && Collage) {
684       TopExp_Explorer ex(mySFrom,TopAbs_FACE);
685       for(; ex.More(); ex.Next()) {
686         const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
687 //      for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
688         for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
689           const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
690           theFE.Set(fac1, fac2);
691           theGlue.Bind(fac1, fac2);
692           for (theFE.InitIterator(); theFE.More();theFE.Next()) {
693             theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
694           }
695         }
696 //      myMap.UnBind(fac2);
697       }
698     }
699
700     if (UntilInShape && Collage) {
701       TopExp_Explorer ex(mySUntil, TopAbs_FACE);
702       for(; ex.More(); ex.Next()) {
703         const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
704 //      for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
705         for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
706           const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
707           theGlue.Bind(fac1, fac2);
708           theFE.Set(fac1, fac2);
709           for (theFE.InitIterator(); theFE.More();theFE.Next()) {
710             theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
711           }
712         }
713         //myMap.UnBind(fac2); // to avoid fac2 in Map when
714         // UpdateDescendants(theGlue) is called
715       }
716     }
717
718     LocOpe_Operation ope = theGlue.OpeType();
719     if (ope == LocOpe_INVALID ||
720         (myFuse && ope != LocOpe_FUSE) ||
721         (!myFuse && ope != LocOpe_CUT) ||
722         (!Collage)) {
723       theOpe = 2;
724       ChangeOpe = Standard_True;
725     }
726   }
727
728 //--- if the gluing is always applicable
729
730   if (theOpe == 1) {
731 #ifdef DEB
732     if (trc) cout << " still Gluer" << endl;
733 #endif
734     theGlue.Perform();
735     if (theGlue.IsDone()) {
736       TopoDS_Shape shshs = theGlue.ResultingShape();
737 //      if (BRepOffsetAPI::IsTopologicallyValid(shshs)) {
738       if (BRepAlgo::IsValid(shshs)) {
739         UpdateDescendants(theGlue);
740         myNewEdges = theGlue.Edges();
741         myTgtEdges = theGlue.TgtEdges();
742 //      TopTools_ListIteratorOfListOfShape itt1;
743         if (myModify && !LShape.IsEmpty()) {
744           TopTools_ListOfShape LTool,LGShape;
745           LocOpe_Builder theTOpe(theGlue.ResultingShape());
746           
747           for (it2.Initialize(LShape);it2.More();it2.Next()) {
748             const TopTools_ListOfShape& ldf = myMap(it2.Value());
749             if (ldf.Extent() == 1 && ldf.First().IsSame(it2.Value())) {
750 //            const TopoDS_Shape& s = it2.Value();
751               LGShape.Append(it2.Value());
752             }
753             else {
754               for (it.Initialize(ldf);it.More();it.Next()) {
755                 if (M.Add(it.Value())) {
756 //                const TopoDS_Shape& s = it.Value();
757                   LGShape.Append(it.Value());
758                 }
759               }
760             }
761           }
762           for (exp.Init(theGlue.GluedShape(),TopAbs_FACE);
763                exp.More();exp.Next()) {
764             for (it.Initialize(theGlue.DescendantFaces
765                                (TopoDS::Face(exp.Current())));
766                  it.More();it.Next()) {
767               if (M.Add(it.Value())) {
768                 LTool.Append(it.Value());
769               }
770             }
771           }
772           
773           if (!(LGShape .IsEmpty() || LTool.IsEmpty())) {
774 //          TopTools_ListIteratorOfListOfShape it1(LGShape);
775 //          TopTools_ListIteratorOfListOfShape it2(LTool);
776             theTOpe.Perform(LGShape,LTool,myFuse);
777             theTOpe.PerformResult();
778             TopTools_ListOfShape TOpeNewEdges, TOpeTgtEdges;
779             TOpeNewEdges = theTOpe.Edges();
780             TOpeTgtEdges = theTOpe.TgtEdges();
781             TopTools_ListIteratorOfListOfShape itt1, itt2;
782             itt1.Initialize(TOpeNewEdges);
783             itt2.Initialize(myNewEdges);          
784             for(; itt1.More(); itt1.Next()) {
785               TopoDS_Edge e1 = TopoDS::Edge(itt1.Value());
786               Standard_Boolean Adde1 = Standard_True;
787               for(; itt2.More(); itt2.Next()) {
788                 TopoDS_Edge e2 = TopoDS::Edge(itt2.Value());
789                 if(e1.IsSame(e2))  {
790                   Adde1 = Standard_False;
791                   break;
792                 }
793               }
794               if(Adde1) {
795                 myNewEdges.Append(e1);
796               }
797             }
798             itt1.Initialize(TOpeTgtEdges);
799             itt2.Initialize(myTgtEdges);          
800             for(; itt1.More(); itt1.Next()) {
801               TopoDS_Edge e1 = TopoDS::Edge(itt1.Value());
802               Standard_Boolean Adde1 = Standard_True;
803               for(; itt2.More(); itt2.Next()) {
804                 TopoDS_Edge e2 = TopoDS::Edge(itt2.Value());
805                 if(e1.IsSame(e2))  {
806                   Adde1 = Standard_False;
807                   break;
808                 }
809               }
810               if(Adde1) {
811                 myTgtEdges.Append(e1);
812               }
813             }
814             
815             if (theTOpe.IsDone()) {
816               Done();
817               myShape = theTOpe.ResultingShape();
818               TopExp_Explorer exf(myShape, TopAbs_FACE);
819               if (exf.More() && BRepAlgo::IsTopologicallyValid(myShape)) {
820                 theOpe = 3; // ???
821 //              UpdateDescendants(theTOpe.Builder(),myShape);
822                 UpdateDescendants(theTOpe.History(),myShape);
823               }
824               else {
825                 theOpe = 2;
826                 ChangeOpe = Standard_True;
827               }
828             }
829             else {
830               theOpe = 2;
831               ChangeOpe = Standard_True;
832             }
833           }
834           else {
835 #ifdef DEB
836             if (trc) cout << " WARNING Gluer failure" << endl;
837 #endif
838             Done();
839             myShape = theGlue.ResultingShape();
840           }
841         }
842         else {
843 #ifdef DEB
844           if (trc) cout << " Gluer result" << endl;
845 #endif
846           Done();
847           myShape = theGlue.ResultingShape();
848         }
849       }
850       else {
851         theOpe = 2;
852         ChangeOpe = Standard_True;
853       }
854     }
855     else {
856       theOpe = 2;
857       ChangeOpe = Standard_True;
858     }
859   }
860
861
862 //--- case without gluing + Tool with proper dimensions
863
864   if (theOpe == 2 && ChangeOpe && myJustGluer) {
865 #ifdef DEB
866     if (trc) cout << " Gluer failure" << endl;
867 #endif
868     myJustGluer = Standard_False;
869     theOpe = 0;
870 //    Done();
871 //    return;
872   }
873
874 //--- case without gluing
875
876   if (theOpe == 2) {
877 #ifdef DEB
878     if (trc) cout << " No Gluer" << endl;
879 #endif
880     TopoDS_Shape theGShape = myGShape;
881     if (ChangeOpe) {
882 #ifdef DEB
883       if (trc) cout << " Passage to topological operations" << endl;
884 #endif
885       for (itm.Initialize(myGluedF); itm.More();itm.Next()) {
886         const TopoDS_Face& fac = TopoDS::Face(itm.Value());
887         Standard_Boolean found = Standard_False;
888         TopTools_ListIteratorOfListOfShape it(LShape);
889         for(; it.More(); it.Next()) {
890           if(it.Value().IsSame(fac)) {
891             found = Standard_True;
892             break;        
893           }
894           if(found) break;
895         }
896         if(!found) {
897 // failed gluing -> reset faces of gluing in LShape
898           LShape.Append(fac);
899         }
900       }
901     }    
902
903     TopoDS_Shape Comp;
904     BRep_Builder B;
905     B.MakeCompound(TopoDS::Compound(Comp));
906     if (!mySFrom.IsNull() || !mySUntil.IsNull()) {
907       if (!mySFrom.IsNull() && !FromInShape) {
908         TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
909         if (!S.IsNull()) {
910           B.Add(Comp,S);
911         }
912       }
913       if (!mySUntil.IsNull() && !UntilInShape) {
914         if (!mySFrom.IsNull()) {
915           if (!mySFrom.IsSame(mySUntil)) {
916             TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
917             if (!S.IsNull()) {
918               B.Add(Comp,S);
919             }
920           }
921         }
922         else {
923           TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
924           if (!S.IsNull()) {
925             B.Add(Comp,S);
926           }
927         }
928       }
929     }
930
931 // update type of selection
932     if(myPerfSelection == BRepFeat_SelectionU && !UntilInShape) {
933       myPerfSelection = BRepFeat_NoSelection;
934     }
935     else if(myPerfSelection == BRepFeat_SelectionFU &&
936             !FromInShape && !UntilInShape) {
937       myPerfSelection = BRepFeat_NoSelection;
938     }
939     else if(myPerfSelection == BRepFeat_SelectionShU && !UntilInShape) {
940       myPerfSelection = BRepFeat_NoSelection;
941     }
942     else {}
943
944     TopExp_Explorer expp(Comp, TopAbs_SOLID);
945     if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())  {
946       //modified by NIZNHY-PKV Thu Mar 21 17:24:52 2002 f
947       //BRepAlgo_Cut trP(myGShape,Comp);
948       BRepAlgoAPI_Cut trP(myGShape, Comp);
949       //modified by NIZNHY-PKV Thu Mar 21 17:24:56 2002 t
950       // the result is necessarily a compound.
951       exp.Init(trP.Shape(),TopAbs_SOLID);
952       if (!exp.More()) {
953         myStatusError = BRepFeat_EmptyCutResult;
954         NotDone();
955         return;
956       }
957       // Only solids are preserved
958       theGShape.Nullify();
959       BRep_Builder B;
960       B.MakeCompound(TopoDS::Compound(theGShape));
961       for (; exp.More(); exp.Next()) {
962         B.Add(theGShape,exp.Current());
963       }
964       if (!BRepAlgo::IsValid(theGShape)) {
965         myStatusError = BRepFeat_InvShape;
966         NotDone();
967         return;
968       }
969       if(!mySFrom.IsNull()) {
970         if(!FromInShape) {
971           TopExp_Explorer ex(mySFrom, TopAbs_FACE);
972           for(; ex.More(); ex.Next()) {
973             const TopoDS_Face& fac = TopoDS::Face(ex.Current());
974             TopTools_ListOfShape thelist4;
975             myMap.Bind(fac,thelist4);
976             if (trP.IsDeleted(fac)) {
977             }
978             else {
979               myMap(fac) = trP.Modified(fac);
980              if (myMap(fac).IsEmpty())  myMap(fac).Append(fac);
981             }
982           }
983         }
984         else {
985           TopExp_Explorer ex(mySFrom, TopAbs_FACE);
986           for(; ex.More(); ex.Next()) {
987             const TopoDS_Face& fac = TopoDS::Face(ex.Current());
988             Standard_Boolean found = Standard_False;
989             TopTools_ListIteratorOfListOfShape it(LShape);
990             for(; it.More(); it.Next()) {
991               if(it.Value().IsSame(fac)) {
992                 found = Standard_True;
993                 break;    
994               }
995               if(found) break;
996             }
997             if(!found) {
998               LShape.Append(fac);    
999             }
1000           }
1001         }
1002       }
1003       if(!mySUntil.IsNull()) {
1004         if(!UntilInShape) {
1005           TopExp_Explorer ex(mySUntil, TopAbs_FACE);
1006           for(; ex.More(); ex.Next()) {
1007             const TopoDS_Face& fac = TopoDS::Face(ex.Current());
1008             TopTools_ListOfShape thelist5;
1009             myMap.Bind(fac,thelist5);
1010             if (trP.IsDeleted(fac)) {
1011             }
1012             else {
1013               myMap(fac) = trP.Modified(fac);
1014               if (myMap.IsEmpty()) myMap(fac).Append(fac);
1015             }
1016           }
1017         }
1018         else {
1019           TopExp_Explorer ex(mySUntil, TopAbs_FACE);
1020           for(; ex.More(); ex.Next()) {
1021             const TopoDS_Face& fac = TopoDS::Face(ex.Current());
1022             Standard_Boolean found = Standard_False;
1023             TopTools_ListIteratorOfListOfShape it(LShape);
1024             for(; it.More(); it.Next()) {
1025               if(it.Value().IsSame(fac)) {
1026                 found = Standard_True;
1027                 break;    
1028               }
1029               if(found) break;
1030             }
1031             if(!found) {
1032               LShape.Append(fac);
1033             }
1034           }
1035         }
1036       }
1037       //modified by NIZNHY-PKV Thu Mar 21 17:27:23 2002 f
1038       //UpdateDescendants(trP.Builder(),theGShape,Standard_True); 
1039       UpdateDescendants(trP,theGShape,Standard_True); 
1040       //modified by NIZNHY-PKV Thu Mar 21 17:27:31 2002 t
1041     }//if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())  {
1042     //
1043     else {
1044       if(!mySFrom.IsNull()) {
1045         TopExp_Explorer ex(mySFrom, TopAbs_FACE);
1046         for(; ex.More(); ex.Next()) {
1047           const TopoDS_Face& fac = TopoDS::Face(ex.Current());
1048           Standard_Boolean found = Standard_False;
1049           TopTools_ListIteratorOfListOfShape it(LShape);
1050           for(; it.More(); it.Next()) {
1051             if(it.Value().IsSame(fac)) {
1052               found = Standard_True;
1053               break;      
1054             }
1055             if(found) break;
1056           }
1057           if(!found) {
1058             LShape.Append(fac);   
1059           }
1060         }
1061       }
1062       if(!mySUntil.IsNull()) {
1063         TopExp_Explorer ex(mySUntil, TopAbs_FACE);
1064         for(; ex.More(); ex.Next()) {
1065           const TopoDS_Face& fac = TopoDS::Face(ex.Current());
1066           Standard_Boolean found = Standard_False;
1067           TopTools_ListIteratorOfListOfShape it(LShape);
1068           for(; it.More(); it.Next()) {
1069             if(it.Value().IsSame(fac)) {
1070               found = Standard_True;
1071               break;      
1072             }
1073             if(found) break;
1074           }
1075           if(!found) {
1076             LShape.Append(fac);
1077           }
1078         }
1079       }
1080     }
1081
1082
1083 //--- generation of "just feature" for assembly = Parts of tool
1084     TopTools_ListOfShape lshape; 
1085     LocOpe_Builder theTOpe;
1086     Standard_Real pbmin, pbmax, prmin, prmax;
1087     Standard_Boolean flag1;
1088     Handle(Geom_Curve) C;
1089     if(!myJustFeat) {
1090       theTOpe.Init(mySbase);
1091       theTOpe.Perform(theGShape,LShape,myFuse);
1092       theTOpe.BuildPartsOfTool();
1093       lshape = theTOpe.PartsOfTool();
1094     }
1095     else {
1096       theTOpe.Init(theGShape, mySbase);
1097       TopTools_ListOfShape list;
1098       theTOpe.Perform(list,LShape,Standard_False);
1099       theTOpe.PerformResult();
1100       if (theTOpe.IsDone()) {
1101         myShape = theTOpe.ResultingShape();
1102 //      UpdateDescendants(theTOpe.Builder(),myShape); // a priori bug of update
1103         UpdateDescendants(theTOpe.History(),myShape); // a priori bug of update
1104         // to be done after selection of parts to be preserved
1105         myNewEdges = theTOpe.Edges();
1106         myTgtEdges = theTOpe.TgtEdges();
1107         TopExp_Explorer explo(theTOpe.ResultingShape(), TopAbs_SOLID);
1108         for (; explo.More(); explo.Next()) {
1109           lshape.Append(explo.Current());
1110         }
1111       }
1112       else {
1113         myStatusError = BRepFeat_LocOpeNotDone;
1114         NotDone();
1115         return;
1116       }
1117     }
1118
1119 //--- Selection of pieces of tool to be preserved
1120     TopoDS_Solid thePartsOfTool;
1121     if(!lshape.IsEmpty() && myPerfSelection != BRepFeat_NoSelection) {
1122
1123 //      Find ParametricMinMax depending on the constraints of Shape From and Until
1124 //   -> prmin, prmax, pbmin and pbmax
1125       C = BarycCurve();
1126       if (C.IsNull()) {
1127         myStatusError = BRepFeat_EmptyBaryCurve; 
1128         NotDone();
1129         return;
1130       }
1131
1132       if(myPerfSelection == BRepFeat_SelectionSh) {
1133         BRepFeat::ParametricMinMax(mySbase,C, 
1134                                    prmin, prmax, pbmin, pbmax, flag1);
1135       }
1136       else if(myPerfSelection == BRepFeat_SelectionFU) {
1137         Standard_Real prmin1, prmax1, prmin2, prmax2;
1138         Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
1139       
1140         BRepFeat::ParametricMinMax(mySFrom,C, 
1141                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
1142         BRepFeat::ParametricMinMax(mySUntil,C, 
1143                                    prmin2, prmax2, prbmin2, prbmax2, flag1);
1144
1145 // case of revolutions
1146         if (C->IsPeriodic()) {
1147           Standard_Real period = C->Period();
1148           prmax = prmax2;
1149           if (flag1) {
1150             prmin = ElCLib::InPeriod(prmin1,prmax-period,prmax);
1151           }
1152           else {
1153             prmin = Min(prmin1, prmin2);
1154           }
1155           pbmax = prbmax2;
1156           pbmin = ElCLib::InPeriod(prbmin1,pbmax-period,pbmax);
1157         }
1158         else {
1159           prmin = Min(prmin1, prmin2);
1160           prmax = Max(prmax1, prmax2);
1161           pbmin = Min(prbmin1, prbmin2);
1162           pbmax = Max(prbmax1, prbmax2);
1163         }
1164       }
1165       else if(myPerfSelection == BRepFeat_SelectionShU) {
1166         Standard_Real prmin1, prmax1, prmin2, prmax2;
1167         Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
1168         
1169         if(!myJustFeat && sens == 0) sens =1;
1170         if (sens == 0) {
1171           myStatusError = BRepFeat_IncDirection;
1172           NotDone();
1173           return;
1174         }
1175         
1176         BRepFeat::ParametricMinMax(mySUntil,C, 
1177                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
1178
1179         BRepFeat::ParametricMinMax(mySbase,C, 
1180                                    prmin2, prmax2, prbmin2, prbmax2, flag1);
1181         if (sens == 1) {
1182           prmin = prmin2;
1183           prmax = prmax1;
1184           pbmin = prbmin2;
1185           pbmax = prbmax1;
1186         }
1187         else if (sens == -1) {
1188           prmin = prmin1;
1189           prmax = prmax2;
1190           pbmin = prbmin1;
1191           pbmax = prbmax2;
1192         }
1193       }
1194       else if (myPerfSelection == BRepFeat_SelectionU) {
1195         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1196         if (sens == 0) {
1197           myStatusError = BRepFeat_IncDirection;
1198           NotDone();
1199           return;
1200         }
1201         
1202         // Find parts of the tool containing descendants of Shape Until
1203         BRepFeat::ParametricMinMax(mySUntil,C, 
1204                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
1205         if (sens == 1) {
1206           prmin = RealFirst();
1207           prmax = prmax1;
1208           pbmin = RealFirst();
1209           pbmax = prbmax1;
1210         }
1211         else if(sens == -1) {
1212           prmin = prmin1;
1213           prmax = RealLast();
1214           pbmin = prbmin1;
1215           pbmax = RealLast();
1216         }
1217       }
1218
1219
1220 // Finer choice of ParametricMinMax in case when the tool 
1221 // intersects Shapes From and Until
1222 //       case of several intersections (keep PartsOfTool according to the selection)  
1223 //       position of the face of intersection in PartsOfTool (before or after)
1224       Standard_Real delta = Precision::Confusion();
1225
1226       if (myPerfSelection != BRepFeat_NoSelection) {
1227 // modif of the test for cts21181 : (prbmax2 and prnmin2) -> (prbmin1 and prbmax1)
1228 // correction take into account flag2 for pro15323 and flag3 for pro16060
1229         if (!mySUntil.IsNull()) {
1230           TopTools_MapOfShape mapFuntil;
1231           Descendants(mySUntil,theTOpe,mapFuntil);
1232           if (!mapFuntil.IsEmpty()) {
1233             for (it.Initialize(lshape); it.More(); it.Next()) {
1234               TopExp_Explorer expf;
1235               for (expf.Init(it.Value(),TopAbs_FACE); 
1236                    expf.More(); expf.Next()) {
1237                 if (mapFuntil.Contains(expf.Current())) {
1238                   Standard_Boolean flag2,flag3;
1239                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1240                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
1241                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
1242                                              prbmin1, prbmax1,flag3);
1243                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
1244                                              prbmin2, prbmax2,flag2);
1245                   if (sens == 1) {
1246                     Standard_Boolean testOK = !flag2;
1247                     if (flag2) {
1248                       testOK = !flag1;
1249                       if (flag1 && prmax2 > prmin + delta) {
1250                         testOK = !flag3;
1251                         if (flag3 && prmax1 == prmax2) {
1252                           testOK = Standard_True;
1253                         }
1254                       }
1255                     }
1256                     if (prbmin1 < pbmax && testOK) {
1257                       if (flag2) {
1258                         flag1 = flag2;
1259                         prmax  = prmax2;
1260                       }
1261                       pbmax = prbmin1;
1262                     }
1263                   }
1264                   else if (sens == -1){ 
1265                     Standard_Boolean testOK = !flag2;
1266                     if (flag2) {
1267                       testOK = !flag1;
1268                       if (flag1 && prmin2 < prmax - delta) {
1269                         testOK = !flag3;
1270                         if (flag3 && prmin1 == prmin2) {
1271                           testOK = Standard_True;
1272                         }
1273                       }
1274                     }
1275                     if (prbmax1 > pbmin && testOK) {
1276                       if (flag2) {
1277                         flag1 = flag2;
1278                         prmin  = prmin2;
1279                       }
1280                       pbmin = prbmax1;
1281                     }
1282                   }
1283                   break;
1284                 }               
1285               }
1286             }
1287             it.Initialize(lshape);
1288           }
1289         }
1290         if (!mySFrom.IsNull()) {
1291           TopTools_MapOfShape mapFfrom;
1292           Descendants(mySFrom,theTOpe,mapFfrom);
1293           if (!mapFfrom.IsEmpty()) {
1294             for (it.Initialize(lshape); it.More(); it.Next()) {
1295               TopExp_Explorer expf;
1296               for (expf.Init(it.Value(),TopAbs_FACE); 
1297                    expf.More(); expf.Next()) {
1298                 if (mapFfrom.Contains(expf.Current())) {
1299                   Standard_Boolean flag2,flag3;
1300                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1301                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
1302                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
1303                                              prbmin1, prbmax1,flag3);
1304                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
1305                                              prbmin2, prbmax2,flag2);
1306                   if (sens == 1) {
1307                     Standard_Boolean testOK = !flag2;
1308                     if (flag2) {
1309                       testOK = !flag1;
1310                       if (flag1 && prmin2 < prmax - delta) {
1311                         testOK = !flag3;
1312                         if (flag3 && prmin1 == prmin2) {
1313                           testOK = Standard_True;
1314                         }
1315                       }
1316                     }
1317                     if (prbmax1 > pbmin && testOK) {
1318                       if (flag2) {
1319                         flag1 = flag2;
1320                         prmin  = prmin2;
1321                       }
1322                       pbmin = prbmax1;
1323                     }
1324                   }
1325                   else if (sens == -1){
1326                     Standard_Boolean testOK = !flag2;
1327                     if (flag2) {
1328                       testOK = !flag1;
1329                       if (flag1 && prmax2 > prmin + delta) {
1330                         testOK = !flag3;
1331                         if (flag3 && prmax1 == prmax2) {
1332                           testOK = Standard_True;
1333                         }
1334                       }
1335                     }
1336                     if (prbmin1 < pbmax && testOK) {
1337                       if (flag2) {
1338                         flag1 = flag2;
1339                         prmax  = prmax2;
1340                       }
1341                       pbmax = prbmin1;
1342                     }
1343                   }
1344                   break;
1345                 }               
1346               }
1347             }
1348             it.Initialize(lshape);
1349           }
1350         }
1351       }
1352
1353
1354 // Parse PartsOfTool to preserve or not depending on ParametricMinMax
1355       if (!myJustFeat) {
1356         Standard_Boolean KeepParts = Standard_False;
1357         BRep_Builder BB;
1358         BB.MakeSolid(thePartsOfTool);
1359         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1360         Standard_Real min, max, pmin, pmax;
1361         Standard_Boolean flag2;
1362         for (it.Initialize(lshape); it.More(); it.Next()) {
1363           if (C->IsPeriodic()) {
1364             Standard_Real period = C->Period();
1365             Standard_Real pr, prb;
1366             BRepFeat::ParametricMinMax(it.Value(),C, pr, prmax1,
1367                                        prb, prbmax1,flag2,Standard_True);
1368             if (flag2) {
1369               prmin1 = ElCLib::InPeriod(pr,prmax1-period,prmax1);
1370             }
1371             else {
1372               prmin1 = pr;
1373             }
1374             prbmin1 = ElCLib::InPeriod(prb,prbmax1-period,prbmax1);
1375           }
1376           else {
1377             BRepFeat::ParametricMinMax(it.Value(),C, 
1378                                        prmin1, prmax1, prbmin1, prbmax1,flag2);
1379           }
1380           if(flag2 == Standard_False || flag1 == Standard_False) {
1381             pmin = pbmin;
1382             pmax = pbmax;
1383             min = prbmin1;
1384             max = prbmax1;
1385           }
1386           else {
1387             pmin = prmin;
1388             pmax = prmax;
1389             min = prmin1;
1390             max = prmax1;
1391           }
1392           if ((min > pmax - delta) || 
1393               (max < pmin + delta)){
1394             theTOpe.RemovePart(it.Value());
1395           }
1396           else {
1397             KeepParts = Standard_True;
1398             const TopoDS_Shape& S = it.Value();
1399             B.Add(thePartsOfTool,S);
1400           }
1401         }
1402
1403 // Case when no part of the tool is preserved
1404         if (!KeepParts) {
1405 #ifdef DEB
1406           if (trc) cout << " No parts of tool kept" << endl;
1407 #endif
1408           myStatusError = BRepFeat_NoParts;
1409           NotDone();
1410           return;
1411         }
1412       }
1413       else {
1414 // case JustFeature -> all PartsOfTool are preserved
1415         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1416         Standard_Real min, max, pmin, pmax;
1417         Standard_Boolean flag2;
1418         TopoDS_Shape Compo;
1419         BRep_Builder B;
1420         B.MakeCompound(TopoDS::Compound(Compo));
1421         for (it.Initialize(lshape); it.More(); it.Next()) {
1422           BRepFeat::ParametricMinMax(it.Value(),C, 
1423                                      prmin1, prmax1, prbmin1, prbmax1,flag2);
1424           if(flag2 == Standard_False || flag1 == Standard_False) {
1425             pmin = pbmin;
1426             pmax = pbmax;
1427             min = prbmin1;
1428             max = prbmax1;
1429           }
1430           else { 
1431             pmin = prmin;
1432             pmax = prmax;
1433             min = prmin1;
1434             max = prmax1;
1435           }
1436           if ((min < pmax - delta) && 
1437               (max > pmin + delta)){
1438             if (!it.Value().IsNull()) {
1439               B.Add(Compo,it.Value());
1440             }
1441           }
1442         }
1443         myShape = Compo;
1444       }
1445     }
1446
1447  
1448 //--- Generation of result myShape
1449
1450     if (!myJustFeat) {
1451 // removal of edges of section that have no common vertices
1452 // with PartsOfTool preserved
1453       theTOpe.PerformResult();
1454       if (theTOpe.IsDone()) {
1455         Done();
1456         myShape = theTOpe.ResultingShape();
1457 //
1458         BRepLib::SameParameter(myShape, 1.e-7, Standard_True);
1459 //
1460 // update new and tangent edges
1461 //      UpdateDescendants(theTOpe.Builder(),myShape);
1462         UpdateDescendants(theTOpe.History(),myShape);
1463         myNewEdges = theTOpe.Edges();
1464         if(!theTOpe.TgtEdges().IsEmpty()) {
1465           myTgtEdges = theTOpe.TgtEdges();
1466         }
1467         //      else myTgtEdges.Clear();
1468       }
1469       else {// last recourse (attention new and tangent edges)
1470         if (!thePartsOfTool.IsNull()) {
1471 #ifdef DEB
1472           if (trc) cout << " Parts of Tool : direct Ope. Top." << endl;
1473 #endif
1474           if(myFuse == 1) {
1475             //modified by NIZNHY-PKV Thu Mar 21 17:28:09 2002 f
1476             //BRepAlgo_Fuse f(mySbase, thePartsOfTool);
1477             BRepAlgoAPI_Fuse f(mySbase, thePartsOfTool);
1478             //modified by NIZNHY-PKV Thu Mar 21 17:28:18 2002 t
1479             myShape = f.Shape();
1480             //modified by NIZNHY-PKV Thu Mar 21 17:28:41 2002 f
1481             //UpdateDescendants(f.Builder(), myShape, Standard_False);
1482             UpdateDescendants(f, myShape, Standard_False);
1483             //modified by NIZNHY-PKV Thu Mar 21 17:28:46 2002 t
1484             Done();
1485             return;
1486           }
1487           else if(myFuse == 0) {
1488             //modified by NIZNHY-PKV Thu Mar 21 17:29:04 2002 f
1489             //BRepAlgo_Cut c(mySbase, thePartsOfTool);
1490             BRepAlgoAPI_Cut c(mySbase, thePartsOfTool);
1491             //modified by NIZNHY-PKV Thu Mar 21 17:29:07 2002 t
1492             myShape = c.Shape();
1493             //modified by NIZNHY-PKV Thu Mar 21 17:29:23 2002 f
1494             //UpdateDescendants(c.Builder(), myShape, Standard_False);
1495             UpdateDescendants(c, myShape, Standard_False);
1496             //modified by NIZNHY-PKV Thu Mar 21 17:29:32 2002 t
1497             Done();
1498             return;
1499           }
1500         }
1501         if (theTOpe.IsInvDone()) {  
1502           myStatusError = BRepFeat_LocOpeNotDone;
1503         }
1504         else {
1505           myStatusError = BRepFeat_LocOpeInvNotDone;
1506         }
1507         NotDone();
1508         return;
1509       }
1510     }
1511     else {
1512       // all is already done
1513       Done();
1514     }
1515   }
1516
1517   myStatusError = BRepFeat_OK;
1518 }
1519
1520
1521
1522 //=======================================================================
1523 //function : IsDeleted
1524 //purpose  : 
1525 //=======================================================================
1526
1527 Standard_Boolean BRepFeat_Form::IsDeleted(const TopoDS_Shape& F)
1528 {
1529   return (myMap(F).IsEmpty());
1530 }
1531
1532 //=======================================================================
1533 //function : Modified
1534 //purpose  : 
1535 //=======================================================================
1536
1537 const TopTools_ListOfShape& BRepFeat_Form::Modified
1538    (const TopoDS_Shape& F)
1539 {
1540   if (myMap.IsBound(F)) {
1541     static TopTools_ListOfShape list;
1542     list.Clear(); // For the second passage DPF
1543     TopTools_ListIteratorOfListOfShape ite(myMap(F));
1544     for(; ite.More(); ite.Next()) {
1545       const TopoDS_Shape& sh = ite.Value();
1546       if(!sh.IsSame(F)) 
1547         list.Append(sh);
1548     }
1549     return list;
1550   }
1551   return myGenerated; // empty list
1552 }
1553
1554 //=======================================================================
1555 //function : Generated
1556 //purpose  : 
1557 //=======================================================================
1558
1559 const TopTools_ListOfShape& BRepFeat_Form::Generated
1560    (const TopoDS_Shape& S)
1561 {
1562   if (myMap.IsBound(S) && 
1563       S.ShapeType() != TopAbs_FACE) { // check if filter on face or not
1564     static TopTools_ListOfShape list;
1565     list.Clear(); // For the second passage DPF
1566     TopTools_ListIteratorOfListOfShape ite(myMap(S));
1567     for(; ite.More(); ite.Next()) {
1568       const TopoDS_Shape& sh = ite.Value();
1569       if(!sh.IsSame(S)) 
1570         list.Append(sh);
1571     }
1572     return list;
1573   }
1574   else return myGenerated;
1575 }
1576
1577
1578
1579 //=======================================================================
1580 //function : UpdateDescendants
1581 //purpose  : 
1582 //=======================================================================
1583
1584 void BRepFeat_Form::UpdateDescendants(const LocOpe_Gluer& G)
1585 {
1586   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1587   TopTools_ListIteratorOfListOfShape it,it2;
1588   TopTools_MapIteratorOfMapOfShape itm;
1589
1590   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1591     const TopoDS_Shape& orig = itdm.Key();
1592     TopTools_MapOfShape newdsc;
1593     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1594       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1595       for (it2.Initialize(G.DescendantFaces(fdsc));
1596            it2.More();it2.Next()) {
1597         newdsc.Add(it2.Value());
1598       }
1599     }
1600     myMap.ChangeFind(orig).Clear();
1601     for (itm.Initialize(newdsc);itm.More();itm.Next()) {
1602       myMap.ChangeFind(orig).Append(itm.Key());
1603     }
1604   }
1605 }
1606
1607
1608
1609
1610
1611 //=======================================================================
1612 //function : FirstShape
1613 //purpose  : 
1614 //=======================================================================
1615
1616 const TopTools_ListOfShape& BRepFeat_Form::FirstShape() const
1617 {
1618   if (!myFShape.IsNull()) {
1619     return myMap(myFShape);
1620   }
1621   return myGenerated; // empty list
1622 }
1623
1624
1625 //=======================================================================
1626 //function : LastShape
1627 //purpose  : 
1628 //=======================================================================
1629
1630 const TopTools_ListOfShape& BRepFeat_Form::LastShape() const
1631 {
1632   if (!myLShape.IsNull()) {
1633     return myMap(myLShape);
1634   }
1635   return myGenerated; // empty list
1636 }
1637
1638
1639 //=======================================================================
1640 //function : NewEdges
1641 //purpose  : 
1642 //=======================================================================
1643
1644 const TopTools_ListOfShape& BRepFeat_Form::NewEdges() const
1645 {
1646   return myNewEdges;
1647 }
1648
1649
1650 //=======================================================================
1651 //function : NewEdges
1652 //purpose  : 
1653 //=======================================================================
1654
1655 const TopTools_ListOfShape& BRepFeat_Form::TgtEdges() const
1656 {
1657   return myTgtEdges;
1658 }
1659
1660
1661 //=======================================================================
1662 //function : TransformSUntil
1663 //purpose  : Limitation of the shape until the case of infinite faces
1664 //=======================================================================
1665
1666 Standard_Boolean BRepFeat_Form::TransformShapeFU(const Standard_Integer flag)
1667 {
1668 #ifdef DEB
1669   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1670 #endif
1671   Standard_Boolean Trf = Standard_False;
1672
1673   TopoDS_Shape shapefu;
1674   if(flag == 0)
1675     shapefu = mySFrom;
1676   else if(flag == 1)
1677     shapefu = mySUntil;
1678   else 
1679     return Trf;
1680
1681   TopExp_Explorer exp(shapefu, TopAbs_FACE);
1682   if (!exp.More()) { // no faces... It is necessary to return an error
1683 #ifdef DEB
1684     if (trc) cout << " BRepFeat_Form::TransformShapeFU : invalid Shape" << endl;
1685 #endif
1686     return Trf;
1687   }
1688
1689   exp.Next();
1690   if (!exp.More()) { // the only face. Is it infinite?
1691     exp.ReInit();
1692     TopoDS_Face fac = TopoDS::Face(exp.Current());
1693
1694     Handle(Geom_Surface) S = BRep_Tool::Surface(fac);
1695     Handle(Standard_Type) styp = S->DynamicType();
1696     if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1697       S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
1698       styp =  S->DynamicType();
1699     }
1700
1701     if (styp == STANDARD_TYPE(Geom_Plane) ||
1702         styp == STANDARD_TYPE(Geom_CylindricalSurface) ||
1703         styp == STANDARD_TYPE(Geom_ConicalSurface)) {
1704       TopExp_Explorer exp1(fac, TopAbs_WIRE);
1705       if (!exp1.More()) {
1706         Trf = Standard_True;
1707       }
1708       else {
1709         Trf = BRep_Tool::NaturalRestriction(fac);
1710       }
1711
1712     }
1713     if (Trf) {
1714       BRepFeat::FaceUntil(mySbase, fac);
1715     }
1716
1717     if(flag == 0) {
1718       TopTools_ListOfShape thelist6;
1719       myMap.Bind(mySFrom,thelist6);
1720       myMap(mySFrom).Append(fac);
1721       mySFrom = fac;
1722     }
1723     else if(flag == 1) {
1724       TopTools_ListOfShape thelist7;
1725       myMap.Bind(mySUntil,thelist7);
1726       myMap(mySUntil).Append(fac);
1727       mySUntil = fac;
1728     }
1729     else {
1730     }
1731   }
1732   else {
1733     for (exp.ReInit(); exp.More(); exp.Next()) {
1734       const TopoDS_Shape& fac = exp.Current();
1735       TopTools_ListOfShape thelist8;
1736       myMap.Bind(fac,thelist8);
1737       myMap(fac).Append(fac);
1738     }
1739   }
1740 #ifdef DEB
1741   if (trc) {
1742     if (Trf && (flag == 0)) cout << " TransformShapeFU From" << endl;
1743     if (Trf && (flag == 1)) cout << " TransformShapeFU Until" << endl;
1744   }
1745 #endif
1746   return Trf;
1747 }
1748
1749
1750 //=======================================================================
1751 //function : CurrentStatusError
1752 //purpose  : 
1753 //=======================================================================
1754
1755 BRepFeat_StatusError BRepFeat_Form::CurrentStatusError() const
1756 {
1757   return myStatusError;
1758 }
1759
1760 /*
1761 //=======================================================================
1762 //function : Descendants
1763 //purpose  : 
1764 //=======================================================================
1765
1766 static void Descendants(const TopoDS_Shape& S,
1767                         const LocOpe_Builder& theTOpe,
1768                         TopTools_MapOfShape& mapF)
1769 {
1770   mapF.Clear();
1771   const Handle(TopOpeBRepBuild_HBuilder) B = theTOpe.Builder();
1772   TopTools_ListIteratorOfListOfShape it;
1773   TopExp_Explorer exp;
1774   for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1775     const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1776     if (B->IsSplit(fdsc, TopAbs_OUT)) {
1777       for (it.Initialize(B->Splits(fdsc,TopAbs_OUT));
1778            it.More();it.Next()) {
1779         mapF.Add(it.Value());
1780       }
1781     }
1782     if (B->IsSplit(fdsc, TopAbs_IN)) {
1783       for (it.Initialize(B->Splits(fdsc,TopAbs_IN));
1784            it.More();it.Next()) {
1785         mapF.Add(it.Value());
1786       }
1787     }
1788     if (B->IsSplit(fdsc, TopAbs_ON)) {
1789       for (it.Initialize(B->Splits(fdsc,TopAbs_ON));
1790            it.More();it.Next()) {
1791         mapF.Add(it.Value());
1792       }
1793     }
1794     if (B->IsMerged(fdsc, TopAbs_OUT)) {
1795       for (it.Initialize(B->Merged(fdsc,TopAbs_OUT));
1796            it.More();it.Next()) {
1797         mapF.Add(it.Value());
1798       }
1799     }
1800     if (B->IsMerged(fdsc, TopAbs_IN)) {
1801       for (it.Initialize(B->Merged(fdsc,TopAbs_IN));
1802            it.More();it.Next()) {
1803         mapF.Add(it.Value());
1804       }
1805     }
1806     if (B->IsMerged(fdsc, TopAbs_ON)) {
1807       for (it.Initialize(B->Merged(fdsc,TopAbs_ON));
1808            it.More();it.Next()) {
1809         mapF.Add(it.Value());
1810       }
1811     }
1812   }
1813 }
1814 */
1815
1816 //=======================================================================
1817 //function : Descendants
1818 //purpose  : 
1819 //=======================================================================
1820
1821 static void Descendants(const TopoDS_Shape& S,
1822                         const LocOpe_Builder& theTOpe,
1823                         TopTools_MapOfShape& mapF)
1824 {
1825   mapF.Clear();
1826   const Handle(BOP_HistoryCollector)& B = theTOpe.History();
1827   TopTools_ListIteratorOfListOfShape it;
1828   TopExp_Explorer exp;
1829   for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1830    
1831     const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1832     const TopTools_ListOfShape& aLM=B->Modified(fdsc);
1833     it.Initialize(aLM);
1834     for (; it.More(); it.Next()) {
1835       mapF.Add(it.Value());
1836     }
1837     
1838   }
1839 }
1840
1841 //=======================================================================
1842 //function : UpdateDescendants
1843 //purpose  : 
1844 //=======================================================================
1845   void BRepFeat_Form::UpdateDescendants(const Handle(TopOpeBRepBuild_HBuilder)& B,
1846                                         const TopoDS_Shape& S,
1847                                         const Standard_Boolean SkipFace)
1848 {
1849   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1850   TopTools_ListIteratorOfListOfShape it,it2;
1851   TopTools_MapIteratorOfMapOfShape itm;
1852   TopExp_Explorer exp;
1853
1854   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1855     const TopoDS_Shape& orig = itdm.Key();
1856     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1857       continue;
1858     }
1859     TopTools_MapOfShape newdsc;
1860
1861     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1862
1863     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1864       const TopoDS_Shape& sh = it.Value();
1865       if(sh.ShapeType() != TopAbs_FACE) continue;
1866       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1867       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1868         if (exp.Current().IsSame(fdsc)) { // preserved
1869           newdsc.Add(fdsc);
1870           break;
1871         }
1872       }
1873       if (!exp.More()) {
1874         if (B->IsSplit(fdsc, TopAbs_OUT)) {
1875           for (it2.Initialize(B->Splits(fdsc,TopAbs_OUT));
1876                it2.More();it2.Next()) {
1877             newdsc.Add(it2.Value());
1878           }
1879         }
1880         if (B->IsSplit(fdsc, TopAbs_IN)) {
1881           for (it2.Initialize(B->Splits(fdsc,TopAbs_IN));
1882                it2.More();it2.Next()) {
1883             newdsc.Add(it2.Value());
1884           }
1885         }
1886         if (B->IsSplit(fdsc, TopAbs_ON)) {
1887           for (it2.Initialize(B->Splits(fdsc,TopAbs_ON));
1888                it2.More();it2.Next()) {
1889             newdsc.Add(it2.Value());
1890           }
1891         }
1892         if (B->IsMerged(fdsc, TopAbs_OUT)) {
1893           for (it2.Initialize(B->Merged(fdsc,TopAbs_OUT));
1894                it2.More();it2.Next()) {
1895             newdsc.Add(it2.Value());
1896           }
1897         }
1898         if (B->IsMerged(fdsc, TopAbs_IN)) {
1899           for (it2.Initialize(B->Merged(fdsc,TopAbs_IN));
1900                it2.More();it2.Next()) {
1901             newdsc.Add(it2.Value());
1902           }
1903         }
1904         if (B->IsMerged(fdsc, TopAbs_ON)) {
1905           for (it2.Initialize(B->Merged(fdsc,TopAbs_ON));
1906                it2.More();it2.Next()) {
1907             newdsc.Add(it2.Value());
1908           }
1909         }
1910       }
1911     }
1912     myMap.ChangeFind(orig).Clear();
1913     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1914        // check the appartenance to the shape...
1915       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1916         if (exp.Current().IsSame(itm.Key())) {
1917 //        const TopoDS_Shape& sh = itm.Key();
1918           myMap.ChangeFind(orig).Append(itm.Key());
1919           break;
1920         }
1921       }
1922     }
1923   }
1924 }
1925 //modified by NIZNHY-PKV Thu Mar 21 18:43:18 2002 f
1926 //=======================================================================
1927 //function : UpdateDescendants
1928 //purpose  : 
1929 //=======================================================================
1930   void BRepFeat_Form::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
1931                                         const TopoDS_Shape& S,
1932                                         const Standard_Boolean SkipFace)
1933 {
1934   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1935   TopTools_ListIteratorOfListOfShape it,it2;
1936   TopTools_MapIteratorOfMapOfShape itm;
1937   TopExp_Explorer exp;
1938
1939   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1940     const TopoDS_Shape& orig = itdm.Key();
1941     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1942       continue;
1943     }
1944     TopTools_MapOfShape newdsc;
1945
1946     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1947
1948     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1949       const TopoDS_Shape& sh = it.Value();
1950       if(sh.ShapeType() != TopAbs_FACE) continue;
1951       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1952       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1953         if (exp.Current().IsSame(fdsc)) { // preserved
1954           newdsc.Add(fdsc);
1955           break;
1956         }
1957       }
1958       if (!exp.More()) {
1959         BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
1960         const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
1961         it2.Initialize(aLM);
1962         for (; it2.More(); it2.Next()) {
1963           const TopoDS_Shape& aS=it2.Value();
1964           newdsc.Add(aS);
1965         }
1966         
1967       }
1968     }
1969     myMap.ChangeFind(orig).Clear();
1970     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1971        // check the appartenance to the shape...
1972       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1973         if (exp.Current().IsSame(itm.Key())) {
1974 //        const TopoDS_Shape& sh = itm.Key();
1975           myMap.ChangeFind(orig).Append(itm.Key());
1976           break;
1977         }
1978       }
1979     }
1980   }
1981 }
1982 //modified by NIZNHY-PKV Thu Mar 21 18:43:36 2002 t
1983 //=======================================================================
1984 //function : UpdateDescendants
1985 //purpose  : 
1986 //=======================================================================
1987   void BRepFeat_Form::UpdateDescendants(const Handle(BOP_HistoryCollector)& aBOP,
1988                                         const TopoDS_Shape& S,
1989                                         const Standard_Boolean SkipFace)
1990 {
1991   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1992   TopTools_ListIteratorOfListOfShape it,it2;
1993   TopTools_MapIteratorOfMapOfShape itm;
1994   TopExp_Explorer exp;
1995
1996   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1997     const TopoDS_Shape& orig = itdm.Key();
1998     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1999       continue;
2000     }
2001     TopTools_MapOfShape newdsc;
2002
2003     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
2004
2005     for (it.Initialize(itdm.Value());it.More();it.Next()) {
2006       const TopoDS_Shape& sh = it.Value();
2007       if(sh.ShapeType() != TopAbs_FACE) continue;
2008       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
2009       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
2010         if (exp.Current().IsSame(fdsc)) { // preserved
2011           newdsc.Add(fdsc);
2012           break;
2013         }
2014       }
2015       if (!exp.More()) {
2016         const TopTools_ListOfShape& aLM=aBOP->Modified(fdsc);
2017         it2.Initialize(aLM);
2018         for (; it2.More(); it2.Next()) {
2019           const TopoDS_Shape& aS=it2.Value();
2020           newdsc.Add(aS);
2021         }
2022         
2023       }
2024     }
2025     myMap.ChangeFind(orig).Clear();
2026     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
2027        // check the appartenance to the shape...
2028       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
2029         if (exp.Current().IsSame(itm.Key())) {
2030 //        const TopoDS_Shape& sh = itm.Key();
2031           myMap.ChangeFind(orig).Append(itm.Key());
2032           break;
2033         }
2034       }
2035     }
2036   }
2037 }