49381ad0aaf739154fdb0f398815551847c83473
[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  : reconstruction topologique du resultat
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 //--- Ajout Shape From et Until dans la map pour ne pas les mettre dans 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 //--- Ajout Faces de collage dans la map pour ne pas les mettre dans LShape
167   TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
168   for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
169     M.Add(itm.Value());
170   }
171
172
173 //--- Recherche de la liste LShape des faces concernees par la 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) par intersection
205
206 // Intersection Outil Shape From
207   if (!mySFrom.IsNull()) {
208     ASI1.Init(mySFrom);
209     ASI1.Perform(scur);
210   }
211
212 // Intersection Outil Shape Until
213   if (!mySUntil.IsNull()) {
214     ASI2.Init(mySUntil);
215     ASI2.Perform(scur);
216   }
217
218 #ifndef VREF
219 // Intersection Outil Shape de base
220   if (!ASI3.IsDone()) {
221     theOpe = 2;
222     LShape.Clear();
223   }
224   else
225 #endif
226   {
227 //  Determination 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)) { //chevauchement des intervales
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 // pour cas base prism a cheval sur mySUntil -> sens ambigu
308 //      -> on privilegie sens = 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 // Mise a jour LShape par ajout des faces du Shape de base
350 //        qui sont OK pour (sens, locmin et locmax)
351 //        qui ne sont pas deja dans la map (Shape From Until et faces collage)
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) par section avec la boite englobante
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 // On ne traite pas : la face de collage
425 //                    les faces du Shape From
426 //                    les faces du Shape Until
427 //                    les faces deja dans LShape
428 //                    les faces de myGluedF
429 // Si la face n'a pas ete eliminee ... on la garde si boite enblobante
430 // est en collision avec celle de myGShape = outil
431 //                    ou celle des faces limites (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 de performance : ajout de toutes les faces du Shape de base dans LShape
483 // (pas de phase de tri mais plus de faces) -> pas 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 //--- cas de collage
498
499   if (theOpe == 1) {
500 #ifdef DEB
501     if (trc) cout << " Gluer" << endl;
502 #endif
503     Standard_Boolean Collage = Standard_True;  
504     // on coupe par 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         // On ne garde que les solides
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     // On rajoute le collage sur face de depart et fin , si necessaire !!!
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); // pour ne pas avoir fac2 dans la Map quand
697         // on .appelle UpdateDescendants(theGlue)
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 //--- si le collage est toujours 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 //--- cas sans collage + Outil aux bonnes 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 //--- cas sans collage
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 en ope. topologique" << 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 // echec collage -> on remet les faces de collage dans 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 // mise a jour type de 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       // le resultat est necessairement un compound.
934       exp.Init(trP.Shape(),TopAbs_SOLID);
935       if (!exp.More()) {
936         myStatusError = BRepFeat_EmptyCutResult;
937         NotDone();
938         return;
939       }
940       // On ne garde que les solides
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 de "just feature" pour assemblage = Parties d'outil
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 de mise a jour
1086         UpdateDescendants(theTOpe.History(),myShape); // a priori bug de mise a jour
1087         // a faire apres selection des parties a garder
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 des morceaux d'outil a garder
1103     TopoDS_Solid thePartsOfTool;
1104     if(!lshape.IsEmpty() && myPerfSelection != BRepFeat_NoSelection) {
1105
1106 //Recherche ParametricMinMax en fonction contraintes des Shape From et Until
1107 //   -> prmin, prmax, pbmin et 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 // cas des revol
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         // On cherche les parties de l`outil contenant les descendants du
1186         // Shape Until
1187         BRepFeat::ParametricMinMax(mySUntil,C, 
1188                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
1189         if (sens == 1) {
1190           prmin = RealFirst();
1191           prmax = prmax1;
1192           pbmin = RealFirst();
1193           pbmax = prbmax1;
1194         }
1195         else if(sens == -1) {
1196           prmin = prmin1;
1197           prmax = RealLast();
1198           pbmin = prbmin1;
1199           pbmax = RealLast();
1200         }
1201       }
1202
1203
1204 // Choix plus fin des ParametricMinMax dans le cas ou l'outil 
1205 // intersecte les Shapes From et Until
1206 //       cas de plusieurs intersections (retenir PartsOfTool en accord avec selection)  
1207 //       position de la face d`intersection dans PartsOfTool (avant ou arriere)
1208       Standard_Real delta = Precision::Confusion();
1209
1210       if (myPerfSelection != BRepFeat_NoSelection) {
1211 // modif du test pour cts21181 : (prbmax2 et prnmin2) -> (prbmin1 et prbmax1)
1212 // correction prise en compte de flag2 pour pro15323 et de flag3 pour pro16060
1213         if (!mySUntil.IsNull()) {
1214           TopTools_MapOfShape mapFuntil;
1215           Descendants(mySUntil,theTOpe,mapFuntil);
1216           if (!mapFuntil.IsEmpty()) {
1217             for (it.Initialize(lshape); it.More(); it.Next()) {
1218               TopExp_Explorer expf;
1219               for (expf.Init(it.Value(),TopAbs_FACE); 
1220                    expf.More(); expf.Next()) {
1221                 if (mapFuntil.Contains(expf.Current())) {
1222                   Standard_Boolean flag2,flag3;
1223                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1224                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
1225                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
1226                                              prbmin1, prbmax1,flag3);
1227                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
1228                                              prbmin2, prbmax2,flag2);
1229                   if (sens == 1) {
1230                     Standard_Boolean testOK = !flag2;
1231                     if (flag2) {
1232                       testOK = !flag1;
1233                       if (flag1 && prmax2 > prmin + delta) {
1234                         testOK = !flag3;
1235                         if (flag3 && prmax1 == prmax2) {
1236                           testOK = Standard_True;
1237                         }
1238                       }
1239                     }
1240                     if (prbmin1 < pbmax && testOK) {
1241                       if (flag2) {
1242                         flag1 = flag2;
1243                         prmax  = prmax2;
1244                       }
1245                       pbmax = prbmin1;
1246                     }
1247                   }
1248                   else if (sens == -1){ 
1249                     Standard_Boolean testOK = !flag2;
1250                     if (flag2) {
1251                       testOK = !flag1;
1252                       if (flag1 && prmin2 < prmax - delta) {
1253                         testOK = !flag3;
1254                         if (flag3 && prmin1 == prmin2) {
1255                           testOK = Standard_True;
1256                         }
1257                       }
1258                     }
1259                     if (prbmax1 > pbmin && testOK) {
1260                       if (flag2) {
1261                         flag1 = flag2;
1262                         prmin  = prmin2;
1263                       }
1264                       pbmin = prbmax1;
1265                     }
1266                   }
1267                   break;
1268                 }               
1269               }
1270             }
1271             it.Initialize(lshape);
1272           }
1273         }
1274         if (!mySFrom.IsNull()) {
1275           TopTools_MapOfShape mapFfrom;
1276           Descendants(mySFrom,theTOpe,mapFfrom);
1277           if (!mapFfrom.IsEmpty()) {
1278             for (it.Initialize(lshape); it.More(); it.Next()) {
1279               TopExp_Explorer expf;
1280               for (expf.Init(it.Value(),TopAbs_FACE); 
1281                    expf.More(); expf.Next()) {
1282                 if (mapFfrom.Contains(expf.Current())) {
1283                   Standard_Boolean flag2,flag3;
1284                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1285                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
1286                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
1287                                              prbmin1, prbmax1,flag3);
1288                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
1289                                              prbmin2, prbmax2,flag2);
1290                   if (sens == 1) {
1291                     Standard_Boolean testOK = !flag2;
1292                     if (flag2) {
1293                       testOK = !flag1;
1294                       if (flag1 && prmin2 < prmax - delta) {
1295                         testOK = !flag3;
1296                         if (flag3 && prmin1 == prmin2) {
1297                           testOK = Standard_True;
1298                         }
1299                       }
1300                     }
1301                     if (prbmax1 > pbmin && testOK) {
1302                       if (flag2) {
1303                         flag1 = flag2;
1304                         prmin  = prmin2;
1305                       }
1306                       pbmin = prbmax1;
1307                     }
1308                   }
1309                   else if (sens == -1){
1310                     Standard_Boolean testOK = !flag2;
1311                     if (flag2) {
1312                       testOK = !flag1;
1313                       if (flag1 && prmax2 > prmin + delta) {
1314                         testOK = !flag3;
1315                         if (flag3 && prmax1 == prmax2) {
1316                           testOK = Standard_True;
1317                         }
1318                       }
1319                     }
1320                     if (prbmin1 < pbmax && testOK) {
1321                       if (flag2) {
1322                         flag1 = flag2;
1323                         prmax  = prmax2;
1324                       }
1325                       pbmax = prbmin1;
1326                     }
1327                   }
1328                   break;
1329                 }               
1330               }
1331             }
1332             it.Initialize(lshape);
1333           }
1334         }
1335       }
1336
1337
1338 // Tri des PartsOfTool a garder ou non en fonction des ParametricMinMax
1339       if (!myJustFeat) {
1340         Standard_Boolean KeepParts = Standard_False;
1341         BRep_Builder BB;
1342         BB.MakeSolid(thePartsOfTool);
1343         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1344         Standard_Real min, max, pmin, pmax;
1345         Standard_Boolean flag2;
1346         for (it.Initialize(lshape); it.More(); it.Next()) {
1347           if (C->IsPeriodic()) {
1348             Standard_Real period = C->Period();
1349             Standard_Real pr, prb;
1350             BRepFeat::ParametricMinMax(it.Value(),C, pr, prmax1,
1351                                        prb, prbmax1,flag2,Standard_True);
1352             if (flag2) {
1353               prmin1 = ElCLib::InPeriod(pr,prmax1-period,prmax1);
1354             }
1355             else {
1356               prmin1 = pr;
1357             }
1358             prbmin1 = ElCLib::InPeriod(prb,prbmax1-period,prbmax1);
1359           }
1360           else {
1361             BRepFeat::ParametricMinMax(it.Value(),C, 
1362                                        prmin1, prmax1, prbmin1, prbmax1,flag2);
1363           }
1364           if(flag2 == Standard_False || flag1 == Standard_False) {
1365             pmin = pbmin;
1366             pmax = pbmax;
1367             min = prbmin1;
1368             max = prbmax1;
1369           }
1370           else {
1371             pmin = prmin;
1372             pmax = prmax;
1373             min = prmin1;
1374             max = prmax1;
1375           }
1376           if ((min > pmax - delta) || 
1377               (max < pmin + delta)){
1378             theTOpe.RemovePart(it.Value());
1379           }
1380           else {
1381             KeepParts = Standard_True;
1382             const TopoDS_Shape& S = it.Value();
1383             B.Add(thePartsOfTool,S);
1384           }
1385         }
1386
1387 // Cas ou on ne garde aucune partie d`outil
1388         if (!KeepParts) {
1389 #ifdef DEB
1390           if (trc) cout << " No parts of tool kept" << endl;
1391 #endif
1392           myStatusError = BRepFeat_NoParts;
1393           NotDone();
1394           return;
1395         }
1396       }
1397       else {
1398 // cas JustFeature -> on garde tous les PartsOfTool
1399         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1400         Standard_Real min, max, pmin, pmax;
1401         Standard_Boolean flag2;
1402         TopoDS_Shape Compo;
1403         BRep_Builder B;
1404         B.MakeCompound(TopoDS::Compound(Compo));
1405         for (it.Initialize(lshape); it.More(); it.Next()) {
1406           BRepFeat::ParametricMinMax(it.Value(),C, 
1407                                      prmin1, prmax1, prbmin1, prbmax1,flag2);
1408           if(flag2 == Standard_False || flag1 == Standard_False) {
1409             pmin = pbmin;
1410             pmax = pbmax;
1411             min = prbmin1;
1412             max = prbmax1;
1413           }
1414           else { 
1415             pmin = prmin;
1416             pmax = prmax;
1417             min = prmin1;
1418             max = prmax1;
1419           }
1420           if ((min < pmax - delta) && 
1421               (max > pmin + delta)){
1422             if (!it.Value().IsNull()) {
1423               B.Add(Compo,it.Value());
1424             }
1425           }
1426         }
1427         myShape = Compo;
1428       }
1429     }
1430
1431  
1432 //--- Generation du resultat myShape
1433
1434     if (!myJustFeat) {
1435 // suppression des edges de section qui n'ont aucun vertex commun
1436 // avec les PartsOfTool converves
1437       theTOpe.PerformResult();
1438       if (theTOpe.IsDone()) {
1439         Done();
1440         myShape = theTOpe.ResultingShape();
1441 //
1442         BRepLib::SameParameter(myShape, 1.e-7, Standard_True);
1443 //
1444 // mise a jour des new et tangent edges
1445 //      UpdateDescendants(theTOpe.Builder(),myShape);
1446         UpdateDescendants(theTOpe.History(),myShape);
1447         myNewEdges = theTOpe.Edges();
1448         if(!theTOpe.TgtEdges().IsEmpty()) {
1449           myTgtEdges = theTOpe.TgtEdges();
1450         }
1451         //      else myTgtEdges.Clear();
1452       }
1453       else {// dernier recours (attention new et tangent edges)
1454         if (!thePartsOfTool.IsNull()) {
1455 #ifdef DEB
1456           if (trc) cout << " Parts of Tool : direct Ope. Top." << endl;
1457 #endif
1458           if(myFuse == 1) {
1459             //modified by NIZNHY-PKV Thu Mar 21 17:28:09 2002 f
1460             //BRepAlgo_Fuse f(mySbase, thePartsOfTool);
1461             BRepAlgoAPI_Fuse f(mySbase, thePartsOfTool);
1462             //modified by NIZNHY-PKV Thu Mar 21 17:28:18 2002 t
1463             myShape = f.Shape();
1464             //modified by NIZNHY-PKV Thu Mar 21 17:28:41 2002 f
1465             //UpdateDescendants(f.Builder(), myShape, Standard_False);
1466             UpdateDescendants(f, myShape, Standard_False);
1467             //modified by NIZNHY-PKV Thu Mar 21 17:28:46 2002 t
1468             Done();
1469             return;
1470           }
1471           else if(myFuse == 0) {
1472             //modified by NIZNHY-PKV Thu Mar 21 17:29:04 2002 f
1473             //BRepAlgo_Cut c(mySbase, thePartsOfTool);
1474             BRepAlgoAPI_Cut c(mySbase, thePartsOfTool);
1475             //modified by NIZNHY-PKV Thu Mar 21 17:29:07 2002 t
1476             myShape = c.Shape();
1477             //modified by NIZNHY-PKV Thu Mar 21 17:29:23 2002 f
1478             //UpdateDescendants(c.Builder(), myShape, Standard_False);
1479             UpdateDescendants(c, myShape, Standard_False);
1480             //modified by NIZNHY-PKV Thu Mar 21 17:29:32 2002 t
1481             Done();
1482             return;
1483           }
1484         }
1485         if (theTOpe.IsInvDone()) {  
1486           myStatusError = BRepFeat_LocOpeNotDone;
1487         }
1488         else {
1489           myStatusError = BRepFeat_LocOpeInvNotDone;
1490         }
1491         NotDone();
1492         return;
1493       }
1494     }
1495     else {
1496       // tout est deja fait
1497       Done();
1498     }
1499   }
1500
1501   myStatusError = BRepFeat_OK;
1502 }
1503
1504
1505
1506 //=======================================================================
1507 //function : IsDeleted
1508 //purpose  : 
1509 //=======================================================================
1510
1511 Standard_Boolean BRepFeat_Form::IsDeleted(const TopoDS_Shape& F)
1512 {
1513   return (myMap(F).IsEmpty());
1514 }
1515
1516 //=======================================================================
1517 //function : Modified
1518 //purpose  : 
1519 //=======================================================================
1520
1521 const TopTools_ListOfShape& BRepFeat_Form::Modified
1522    (const TopoDS_Shape& F)
1523 {
1524   if (myMap.IsBound(F)) {
1525     static TopTools_ListOfShape list;
1526     list.Clear(); // Pour le second passage DPF
1527     TopTools_ListIteratorOfListOfShape ite(myMap(F));
1528     for(; ite.More(); ite.Next()) {
1529       const TopoDS_Shape& sh = ite.Value();
1530       if(!sh.IsSame(F)) 
1531         list.Append(sh);
1532     }
1533     return list;
1534   }
1535   return myGenerated; // empty list
1536 }
1537
1538 //=======================================================================
1539 //function : Generated
1540 //purpose  : 
1541 //=======================================================================
1542
1543 const TopTools_ListOfShape& BRepFeat_Form::Generated
1544    (const TopoDS_Shape& S)
1545 {
1546   if (myMap.IsBound(S) && 
1547       S.ShapeType() != TopAbs_FACE) { // voir si on filtre sur face ou pas
1548     static TopTools_ListOfShape list;
1549     list.Clear(); // Pour le second passage DPF
1550     TopTools_ListIteratorOfListOfShape ite(myMap(S));
1551     for(; ite.More(); ite.Next()) {
1552       const TopoDS_Shape& sh = ite.Value();
1553       if(!sh.IsSame(S)) 
1554         list.Append(sh);
1555     }
1556     return list;
1557   }
1558   else return myGenerated;
1559 }
1560
1561
1562
1563 //=======================================================================
1564 //function : UpdateDescendants
1565 //purpose  : 
1566 //=======================================================================
1567
1568 void BRepFeat_Form::UpdateDescendants(const LocOpe_Gluer& G)
1569 {
1570   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1571   TopTools_ListIteratorOfListOfShape it,it2;
1572   TopTools_MapIteratorOfMapOfShape itm;
1573
1574   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1575     const TopoDS_Shape& orig = itdm.Key();
1576     TopTools_MapOfShape newdsc;
1577     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1578       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1579       for (it2.Initialize(G.DescendantFaces(fdsc));
1580            it2.More();it2.Next()) {
1581         newdsc.Add(it2.Value());
1582       }
1583     }
1584     myMap.ChangeFind(orig).Clear();
1585     for (itm.Initialize(newdsc);itm.More();itm.Next()) {
1586       myMap.ChangeFind(orig).Append(itm.Key());
1587     }
1588   }
1589 }
1590
1591
1592
1593
1594
1595 //=======================================================================
1596 //function : FirstShape
1597 //purpose  : 
1598 //=======================================================================
1599
1600 const TopTools_ListOfShape& BRepFeat_Form::FirstShape() const
1601 {
1602   if (!myFShape.IsNull()) {
1603     return myMap(myFShape);
1604   }
1605   return myGenerated; // empty list
1606 }
1607
1608
1609 //=======================================================================
1610 //function : LastShape
1611 //purpose  : 
1612 //=======================================================================
1613
1614 const TopTools_ListOfShape& BRepFeat_Form::LastShape() const
1615 {
1616   if (!myLShape.IsNull()) {
1617     return myMap(myLShape);
1618   }
1619   return myGenerated; // empty list
1620 }
1621
1622
1623 //=======================================================================
1624 //function : NewEdges
1625 //purpose  : 
1626 //=======================================================================
1627
1628 const TopTools_ListOfShape& BRepFeat_Form::NewEdges() const
1629 {
1630   return myNewEdges;
1631 }
1632
1633
1634 //=======================================================================
1635 //function : NewEdges
1636 //purpose  : 
1637 //=======================================================================
1638
1639 const TopTools_ListOfShape& BRepFeat_Form::TgtEdges() const
1640 {
1641   return myTgtEdges;
1642 }
1643
1644
1645 //=======================================================================
1646 //function : TransformSUntil
1647 //purpose  : Limitation du shape until dans le cas des faces infinies
1648 //=======================================================================
1649
1650 Standard_Boolean BRepFeat_Form::TransformShapeFU(const Standard_Integer flag)
1651 {
1652 #ifdef DEB
1653   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1654 #endif
1655   Standard_Boolean Trf = Standard_False;
1656
1657   TopoDS_Shape shapefu;
1658   if(flag == 0)
1659     shapefu = mySFrom;
1660   else if(flag == 1)
1661     shapefu = mySUntil;
1662   else 
1663     return Trf;
1664
1665   TopExp_Explorer exp(shapefu, TopAbs_FACE);
1666   if (!exp.More()) { // pas de faces... Il faudrait renvoyer une erreur
1667 #ifdef DEB
1668     if (trc) cout << " BRepFeat_Form::TransformShapeFU : invalid Shape" << endl;
1669 #endif
1670     return Trf;
1671   }
1672
1673   exp.Next();
1674   if (!exp.More()) { // une seule face. Est-elle infinie??
1675     exp.ReInit();
1676     TopoDS_Face fac = TopoDS::Face(exp.Current());
1677
1678     Handle(Geom_Surface) S = BRep_Tool::Surface(fac);
1679     Handle(Standard_Type) styp = S->DynamicType();
1680     if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1681       S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
1682       styp =  S->DynamicType();
1683     }
1684
1685     if (styp == STANDARD_TYPE(Geom_Plane) ||
1686         styp == STANDARD_TYPE(Geom_CylindricalSurface) ||
1687         styp == STANDARD_TYPE(Geom_ConicalSurface)) {
1688       TopExp_Explorer exp1(fac, TopAbs_WIRE);
1689       if (!exp1.More()) {
1690         Trf = Standard_True;
1691       }
1692       else {
1693         Trf = BRep_Tool::NaturalRestriction(fac);
1694       }
1695
1696     }
1697     if (Trf) {
1698       BRepFeat::FaceUntil(mySbase, fac);
1699     }
1700
1701     if(flag == 0) {
1702       TopTools_ListOfShape thelist6;
1703       myMap.Bind(mySFrom,thelist6);
1704       myMap(mySFrom).Append(fac);
1705       mySFrom = fac;
1706     }
1707     else if(flag == 1) {
1708       TopTools_ListOfShape thelist7;
1709       myMap.Bind(mySUntil,thelist7);
1710       myMap(mySUntil).Append(fac);
1711       mySUntil = fac;
1712     }
1713     else {
1714     }
1715   }
1716   else {
1717     for (exp.ReInit(); exp.More(); exp.Next()) {
1718       const TopoDS_Shape& fac = exp.Current();
1719       TopTools_ListOfShape thelist8;
1720       myMap.Bind(fac,thelist8);
1721       myMap(fac).Append(fac);
1722     }
1723   }
1724 #ifdef DEB
1725   if (trc) {
1726     if (Trf && (flag == 0)) cout << " TransformShapeFU From" << endl;
1727     if (Trf && (flag == 1)) cout << " TransformShapeFU Until" << endl;
1728   }
1729 #endif
1730   return Trf;
1731 }
1732
1733
1734 //=======================================================================
1735 //function : CurrentStatusError
1736 //purpose  : 
1737 //=======================================================================
1738
1739 BRepFeat_StatusError BRepFeat_Form::CurrentStatusError() const
1740 {
1741   return myStatusError;
1742 }
1743
1744 /*
1745 //=======================================================================
1746 //function : Descendants
1747 //purpose  : 
1748 //=======================================================================
1749
1750 static void Descendants(const TopoDS_Shape& S,
1751                         const LocOpe_Builder& theTOpe,
1752                         TopTools_MapOfShape& mapF)
1753 {
1754   mapF.Clear();
1755   const Handle(TopOpeBRepBuild_HBuilder) B = theTOpe.Builder();
1756   TopTools_ListIteratorOfListOfShape it;
1757   TopExp_Explorer exp;
1758   for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1759     const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1760     if (B->IsSplit(fdsc, TopAbs_OUT)) {
1761       for (it.Initialize(B->Splits(fdsc,TopAbs_OUT));
1762            it.More();it.Next()) {
1763         mapF.Add(it.Value());
1764       }
1765     }
1766     if (B->IsSplit(fdsc, TopAbs_IN)) {
1767       for (it.Initialize(B->Splits(fdsc,TopAbs_IN));
1768            it.More();it.Next()) {
1769         mapF.Add(it.Value());
1770       }
1771     }
1772     if (B->IsSplit(fdsc, TopAbs_ON)) {
1773       for (it.Initialize(B->Splits(fdsc,TopAbs_ON));
1774            it.More();it.Next()) {
1775         mapF.Add(it.Value());
1776       }
1777     }
1778     if (B->IsMerged(fdsc, TopAbs_OUT)) {
1779       for (it.Initialize(B->Merged(fdsc,TopAbs_OUT));
1780            it.More();it.Next()) {
1781         mapF.Add(it.Value());
1782       }
1783     }
1784     if (B->IsMerged(fdsc, TopAbs_IN)) {
1785       for (it.Initialize(B->Merged(fdsc,TopAbs_IN));
1786            it.More();it.Next()) {
1787         mapF.Add(it.Value());
1788       }
1789     }
1790     if (B->IsMerged(fdsc, TopAbs_ON)) {
1791       for (it.Initialize(B->Merged(fdsc,TopAbs_ON));
1792            it.More();it.Next()) {
1793         mapF.Add(it.Value());
1794       }
1795     }
1796   }
1797 }
1798 */
1799
1800 //=======================================================================
1801 //function : Descendants
1802 //purpose  : 
1803 //=======================================================================
1804
1805 static void Descendants(const TopoDS_Shape& S,
1806                         const LocOpe_Builder& theTOpe,
1807                         TopTools_MapOfShape& mapF)
1808 {
1809   mapF.Clear();
1810   const Handle(BOP_HistoryCollector)& B = theTOpe.History();
1811   TopTools_ListIteratorOfListOfShape it;
1812   TopExp_Explorer exp;
1813   for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1814    
1815     const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1816     const TopTools_ListOfShape& aLM=B->Modified(fdsc);
1817     it.Initialize(aLM);
1818     for (; it.More(); it.Next()) {
1819       mapF.Add(it.Value());
1820     }
1821     
1822   }
1823 }
1824
1825 //=======================================================================
1826 //function : UpdateDescendants
1827 //purpose  : 
1828 //=======================================================================
1829   void BRepFeat_Form::UpdateDescendants(const Handle(TopOpeBRepBuild_HBuilder)& B,
1830                                         const TopoDS_Shape& S,
1831                                         const Standard_Boolean SkipFace)
1832 {
1833   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1834   TopTools_ListIteratorOfListOfShape it,it2;
1835   TopTools_MapIteratorOfMapOfShape itm;
1836   TopExp_Explorer exp;
1837
1838   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1839     const TopoDS_Shape& orig = itdm.Key();
1840     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1841       continue;
1842     }
1843     TopTools_MapOfShape newdsc;
1844
1845     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1846
1847     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1848       const TopoDS_Shape& sh = it.Value();
1849       if(sh.ShapeType() != TopAbs_FACE) continue;
1850       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1851       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1852         if (exp.Current().IsSame(fdsc)) { // preserved
1853           newdsc.Add(fdsc);
1854           break;
1855         }
1856       }
1857       if (!exp.More()) {
1858         if (B->IsSplit(fdsc, TopAbs_OUT)) {
1859           for (it2.Initialize(B->Splits(fdsc,TopAbs_OUT));
1860                it2.More();it2.Next()) {
1861             newdsc.Add(it2.Value());
1862           }
1863         }
1864         if (B->IsSplit(fdsc, TopAbs_IN)) {
1865           for (it2.Initialize(B->Splits(fdsc,TopAbs_IN));
1866                it2.More();it2.Next()) {
1867             newdsc.Add(it2.Value());
1868           }
1869         }
1870         if (B->IsSplit(fdsc, TopAbs_ON)) {
1871           for (it2.Initialize(B->Splits(fdsc,TopAbs_ON));
1872                it2.More();it2.Next()) {
1873             newdsc.Add(it2.Value());
1874           }
1875         }
1876         if (B->IsMerged(fdsc, TopAbs_OUT)) {
1877           for (it2.Initialize(B->Merged(fdsc,TopAbs_OUT));
1878                it2.More();it2.Next()) {
1879             newdsc.Add(it2.Value());
1880           }
1881         }
1882         if (B->IsMerged(fdsc, TopAbs_IN)) {
1883           for (it2.Initialize(B->Merged(fdsc,TopAbs_IN));
1884                it2.More();it2.Next()) {
1885             newdsc.Add(it2.Value());
1886           }
1887         }
1888         if (B->IsMerged(fdsc, TopAbs_ON)) {
1889           for (it2.Initialize(B->Merged(fdsc,TopAbs_ON));
1890                it2.More();it2.Next()) {
1891             newdsc.Add(it2.Value());
1892           }
1893         }
1894       }
1895     }
1896     myMap.ChangeFind(orig).Clear();
1897     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1898        // on verifie l`appartenance au shape...
1899       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1900         if (exp.Current().IsSame(itm.Key())) {
1901 //        const TopoDS_Shape& sh = itm.Key();
1902           myMap.ChangeFind(orig).Append(itm.Key());
1903           break;
1904         }
1905       }
1906     }
1907   }
1908 }
1909 //modified by NIZNHY-PKV Thu Mar 21 18:43:18 2002 f
1910 //=======================================================================
1911 //function : UpdateDescendants
1912 //purpose  : 
1913 //=======================================================================
1914   void BRepFeat_Form::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
1915                                         const TopoDS_Shape& S,
1916                                         const Standard_Boolean SkipFace)
1917 {
1918   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1919   TopTools_ListIteratorOfListOfShape it,it2;
1920   TopTools_MapIteratorOfMapOfShape itm;
1921   TopExp_Explorer exp;
1922
1923   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1924     const TopoDS_Shape& orig = itdm.Key();
1925     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1926       continue;
1927     }
1928     TopTools_MapOfShape newdsc;
1929
1930     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1931
1932     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1933       const TopoDS_Shape& sh = it.Value();
1934       if(sh.ShapeType() != TopAbs_FACE) continue;
1935       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1936       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1937         if (exp.Current().IsSame(fdsc)) { // preserved
1938           newdsc.Add(fdsc);
1939           break;
1940         }
1941       }
1942       if (!exp.More()) {
1943         BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
1944         const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
1945         it2.Initialize(aLM);
1946         for (; it2.More(); it2.Next()) {
1947           const TopoDS_Shape& aS=it2.Value();
1948           newdsc.Add(aS);
1949         }
1950         
1951       }
1952     }
1953     myMap.ChangeFind(orig).Clear();
1954     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1955        // on verifie l`appartenance au shape...
1956       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1957         if (exp.Current().IsSame(itm.Key())) {
1958 //        const TopoDS_Shape& sh = itm.Key();
1959           myMap.ChangeFind(orig).Append(itm.Key());
1960           break;
1961         }
1962       }
1963     }
1964   }
1965 }
1966 //modified by NIZNHY-PKV Thu Mar 21 18:43:36 2002 t
1967 //=======================================================================
1968 //function : UpdateDescendants
1969 //purpose  : 
1970 //=======================================================================
1971   void BRepFeat_Form::UpdateDescendants(const Handle(BOP_HistoryCollector)& aBOP,
1972                                         const TopoDS_Shape& S,
1973                                         const Standard_Boolean SkipFace)
1974 {
1975   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1976   TopTools_ListIteratorOfListOfShape it,it2;
1977   TopTools_MapIteratorOfMapOfShape itm;
1978   TopExp_Explorer exp;
1979
1980   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1981     const TopoDS_Shape& orig = itdm.Key();
1982     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1983       continue;
1984     }
1985     TopTools_MapOfShape newdsc;
1986
1987     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1988
1989     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1990       const TopoDS_Shape& sh = it.Value();
1991       if(sh.ShapeType() != TopAbs_FACE) continue;
1992       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1993       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1994         if (exp.Current().IsSame(fdsc)) { // preserved
1995           newdsc.Add(fdsc);
1996           break;
1997         }
1998       }
1999       if (!exp.More()) {
2000         const TopTools_ListOfShape& aLM=aBOP->Modified(fdsc);
2001         it2.Initialize(aLM);
2002         for (; it2.More(); it2.Next()) {
2003           const TopoDS_Shape& aS=it2.Value();
2004           newdsc.Add(aS);
2005         }
2006         
2007       }
2008     }
2009     myMap.ChangeFind(orig).Clear();
2010     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
2011        // on verifie l`appartenance au shape...
2012       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
2013         if (exp.Current().IsSame(itm.Key())) {
2014 //        const TopoDS_Shape& sh = itm.Key();
2015           myMap.ChangeFind(orig).Append(itm.Key());
2016           break;
2017         }
2018       }
2019     }
2020   }
2021 }