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