0024624: Lost word in license statement in source files
[occt.git] / src / BRepFeat / BRepFeat_Form.cxx
1 // Created on: 1996-02-13
2 // Created by: Olga KOULECHOVA
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepFeat_Form.ixx>
18
19 #include <LocOpe.hxx>
20 #include <LocOpe_Gluer.hxx>
21 #include <LocOpe_FindEdges.hxx>
22 #include <LocOpe_CSIntersector.hxx>
23 #include <LocOpe_SequenceOfCirc.hxx>
24 #include <LocOpe_PntFace.hxx>
25 #include <LocOpe_BuildShape.hxx>
26
27 #include <TopExp_Explorer.hxx>
28 #include <TopOpeBRepBuild_HBuilder.hxx>
29 #include <TopTools_MapOfShape.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopTools_MapIteratorOfMapOfShape.hxx>
32 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
33 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
34 #include <TColgp_SequenceOfPnt.hxx>
35 #include <Standard_NoSuchObject.hxx>
36 #include <Precision.hxx>
37
38 #include <BRep_Tool.hxx>
39 #include <Geom_RectangularTrimmedSurface.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Geom_CylindricalSurface.hxx>
42 #include <Geom_ConicalSurface.hxx>
43
44 #include <TopoDS_Solid.hxx>
45 #include <TopoDS_Compound.hxx>
46 #include <BRepTools_Modifier.hxx>
47 #include <BRepTools_TrsfModification.hxx>
48 #include <BRepFeat.hxx>
49 #include <BRepCheck_Analyzer.hxx>
50 #include <TopoDS.hxx>
51
52 #include <Bnd_Box.hxx>
53 #include <BRepBndLib.hxx>
54 #include <BRepLib.hxx>
55
56 #include <ElCLib.hxx>
57
58 #include <BRepAlgo.hxx>
59 //modified by NIZNHY-PKV Thu Mar 21 17:30:25 2002 f
60 //#include <BRepAlgo_Cut.hxx>
61 //#include <BRepAlgo_Fuse.hxx>
62
63 #include <BRepAlgoAPI_Cut.hxx>
64 #include <BRepAlgoAPI_Fuse.hxx>
65 #include <BRepFeat_Builder.hxx>
66 //modified by NIZNHY-PKV Thu Mar 21 17:30:29 2002 t
67
68 #ifdef DEB
69 extern Standard_Boolean BRepFeat_GettraceFEAT();
70 #endif
71
72 static void Descendants(const TopoDS_Shape&,
73                         BRepFeat_Builder&,
74                         TopTools_MapOfShape&);
75
76 //=======================================================================
77 //function : Perform
78 //purpose  : topological reconstruction of the result
79 //=======================================================================
80   void BRepFeat_Form::GlobalPerform () 
81 {
82
83 #ifdef DEB
84   Standard_Boolean trc = BRepFeat_GettraceFEAT();
85   if (trc) cout << "BRepFeat_Form::GlobalPerform ()" << endl;
86 #endif
87
88   if (!mySbOK || !myGSOK || !mySFOK || !mySUOK || !myGFOK || 
89       !mySkOK || !myPSOK) {
90 #ifdef DEB
91     if (trc) cout << " Fields not initialized in BRepFeat_Form" << endl;
92 #endif
93     myStatusError = BRepFeat_NotInitialized;
94     NotDone();
95     return;
96   }
97
98 //--- Initialisation
99   TopExp_Explorer exp,exp2;
100   Standard_Integer theOpe = 2;
101   TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
102
103   if(myJustFeat && !myFuse) {
104 #ifdef DEB
105     if (trc) cout << " Invalid option : myJustFeat + Cut" << endl;
106 #endif
107     myStatusError = BRepFeat_InvOption;
108     NotDone();
109     return;    
110   }
111   else if(myJustFeat) {
112     theOpe = 2;
113   }
114   else if (!myGluedF.IsEmpty()) {
115     theOpe = 1;
116   }
117   else {}
118   Standard_Boolean ChangeOpe = Standard_False;
119
120   Standard_Boolean FromInShape = Standard_False;
121   Standard_Boolean UntilInShape = Standard_False;
122   
123   if (!mySFrom.IsNull()) {
124     FromInShape = Standard_True;
125     for (exp2.Init(mySFrom,TopAbs_FACE); exp2.More(); exp2.Next()) {
126       const TopoDS_Shape& ffrom = exp2.Current();
127       for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
128         if (exp.Current().IsSame(ffrom)) {
129           break;
130         }
131       }
132       if (!exp.More()) {
133         FromInShape = Standard_False;
134 #ifdef DEB
135         if (trc) cout << " From not in Shape" << endl;
136 #endif
137         break;
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     }
159   }
160
161   TopTools_ListIteratorOfListOfShape it,it2;
162   Standard_Integer sens = 0;
163
164   TColGeom_SequenceOfCurve scur;
165   Curves(scur);
166
167   Standard_Real locmin;
168   Standard_Real locmax;
169   Standard_Real mf, Mf, mu, Mu;
170
171   TopAbs_Orientation Orifuntil = TopAbs_INTERNAL;
172   TopAbs_Orientation Oriffrom = TopAbs_INTERNAL;
173   TopoDS_Face FFrom,FUntil;
174   
175   LocOpe_CSIntersector ASI1;
176   LocOpe_CSIntersector ASI2;
177
178   TopTools_ListOfShape IntList;
179   IntList.Clear();
180
181 //--- 1) by intersection
182
183 // Intersection Tool Shape From
184   if (!mySFrom.IsNull()) {
185     ASI1.Init(mySFrom);
186     ASI1.Perform(scur);
187   }
188
189 // Intersection Tool Shape Until
190   if (!mySUntil.IsNull()) {
191     ASI2.Init(mySUntil);
192     ASI2.Perform(scur);
193   }
194
195   {
196 //  Find sens, locmin, locmax, FFrom, FUntil
197     locmin = RealFirst();
198     locmax = RealLast();
199     for (Standard_Integer jj=1; jj<=scur.Length(); jj++) {
200       if (ASI1.IsDone() && ASI2.IsDone()) {
201         if (ASI1.NbPoints(jj) <= 0) {
202           continue;
203         }
204         mf = ASI1.Point(jj,1).Parameter();
205         Mf = ASI1.Point(jj,ASI1.NbPoints(jj)).Parameter();
206         if (ASI2.NbPoints(jj) <= 0) {
207           continue;
208         }
209         mu = ASI2.Point(jj,1).Parameter();
210         Mu = ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter();
211         if (scur(jj)->IsPeriodic()) {
212           Standard_Real period = scur(jj)->Period();
213           locmin = mf;
214           locmax = ElCLib::InPeriod(Mu,locmin,locmin+period);
215         }
216         else {
217           Standard_Integer ku, kf;
218           if (! (mu > Mf || mf > Mu)) { //overlapping intervals
219             sens = 1;
220             kf = 1;
221             ku = ASI2.NbPoints(jj);
222             locmin = mf;
223             locmax = Max(Mf, Mu);
224           }   
225           else if (mu > Mf) {    
226             if (sens == -1) {
227               myStatusError = BRepFeat_IntervalOverlap;
228               NotDone();
229               return;
230             }
231             sens = 1;
232             kf = 1;
233             ku = ASI2.NbPoints(jj);
234             locmin = mf;
235             locmax = Mu;
236           }
237           else {
238             if (sens == 1) {
239               myStatusError = BRepFeat_IntervalOverlap;
240               NotDone();
241               return;
242             }
243             sens = -1;
244             kf = ASI1.NbPoints(jj);
245             ku = 1;
246             locmin = mu;
247             locmax = Mf;
248           }
249           if (Oriffrom == TopAbs_INTERNAL) {
250             TopAbs_Orientation Oript = ASI1.Point(jj,kf).Orientation();
251             if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
252               if (sens == -1) {
253                 Oript = TopAbs::Reverse(Oript);
254               }
255               Oriffrom = TopAbs::Reverse(Oript);
256               FFrom = ASI1.Point(jj,kf).Face();
257             }
258           }
259           if (Orifuntil == TopAbs_INTERNAL) {
260             TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
261             if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
262               if (sens == -1) {
263                 Oript = TopAbs::Reverse(Oript);
264               }
265               Orifuntil = Oript;
266               FUntil = ASI2.Point(jj,ku).Face();
267             }
268           }
269         }
270       }
271       else if (ASI2.IsDone()) {
272         if (ASI2.NbPoints(jj) <= 0) 
273           continue;
274
275 // for base case prism on mySUntil -> ambivalent direction
276 //      ->  preferrable direction = 1
277         if(sens != 1) {
278           if (ASI2.Point(jj,1).Parameter()*
279               ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter()<=0) 
280             sens=1;
281           else if (ASI2.Point(jj,1).Parameter()<0.) 
282             sens =-1;
283           else 
284             sens =1;
285         }
286
287         Standard_Integer ku;
288         if (sens == -1) {
289           ku = 1;
290           locmax = -ASI2.Point(jj,ku).Parameter();
291           locmin = 0.;
292         }
293         else {
294           ku = ASI2.NbPoints(jj);
295           locmin = 0;
296           locmax =  ASI2.Point(jj,ku).Parameter();
297         }
298         if (Orifuntil == TopAbs_INTERNAL && sens != 0) {
299           TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
300           if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
301             if (sens == -1) {
302               Oript = TopAbs::Reverse(Oript);
303             }
304             Orifuntil = Oript;
305             FUntil = ASI2.Point(jj,ku).Face();
306           }
307         }
308       }
309       else { 
310         locmin = 0.;
311         locmax = RealLast();
312         sens = 1;
313         break;
314       }
315     }
316   }
317
318   LocOpe_Gluer theGlue;
319   
320 //--- case of gluing
321
322   if (theOpe == 1) {
323 #ifdef DEB
324     if (trc) cout << " Gluer" << endl;
325 #endif
326     Standard_Boolean Collage = Standard_True;  
327     // cut by FFrom && FUntil
328     TopoDS_Shape Comp;
329     BRep_Builder B;
330     B.MakeCompound(TopoDS::Compound(Comp));
331     if (!mySFrom.IsNull()) {
332       TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
333       if (!S.IsNull()) {
334         B.Add(Comp,S);
335       }
336     }
337     if (!mySUntil.IsNull()) {
338       TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
339       if (!S.IsNull()) {
340         B.Add(Comp,S);
341       }
342     }
343
344     LocOpe_FindEdges theFE;
345     TopTools_DataMapOfShapeListOfShape locmap;
346     TopExp_Explorer expp(Comp, TopAbs_SOLID);
347     if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())  {
348       //modified by NIZNHY-PKV Thu Mar 21 17:15:36 2002 f
349       //BRepAlgo_Cut trP(myGShape,Comp);
350       BRepAlgoAPI_Cut trP(myGShape, Comp);
351       //modified by NIZNHY-PKV Thu Mar 21 17:15:58 2002 t
352       exp.Init(trP.Shape(), TopAbs_SOLID);
353       if (exp.Current().IsNull()) {
354         theOpe = 2;
355         ChangeOpe = Standard_True;
356         Collage = Standard_False;
357       }
358       else {// else X0
359         // Only solids are preserved
360         TopoDS_Shape theGShape;
361         BRep_Builder B;
362         B.MakeCompound(TopoDS::Compound(theGShape));
363         for (; exp.More(); exp.Next()) {
364           B.Add(theGShape,exp.Current());
365         }
366         if (!BRepAlgo::IsValid(theGShape)) {
367           theOpe = 2;
368           ChangeOpe = Standard_True;
369           Collage = Standard_False;
370         }
371         else {// else X1
372           if(!mySFrom.IsNull()) { 
373             TopExp_Explorer ex;
374             ex.Init(mySFrom, TopAbs_FACE);
375             for(; ex.More(); ex.Next()) {
376               const TopoDS_Face& fac = TopoDS::Face(ex.Current());
377               if (!FromInShape) {
378                 TopTools_ListOfShape thelist;
379                 myMap.Bind(fac, thelist);
380               }
381               else {
382                 TopTools_ListOfShape thelist1;
383                 locmap.Bind(fac, thelist1);
384               }
385               if (trP.IsDeleted(fac)) {
386               }
387               else if (!FromInShape) {
388                 myMap(fac) = trP.Modified(fac);
389                 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
390               }
391               else {
392                 locmap(fac) =trP.Modified(fac) ;
393                 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
394               }
395             }
396           }// if(!mySFrom.IsNull()) 
397           //
398           if(!mySUntil.IsNull()) { 
399             TopExp_Explorer ex;
400             ex.Init(mySUntil, TopAbs_FACE);
401             for(; ex.More(); ex.Next()) {
402               const TopoDS_Face& fac = TopoDS::Face(ex.Current());
403               if (!UntilInShape) {                
404                 TopTools_ListOfShape thelist2;
405                 myMap.Bind(fac,thelist2);
406               }
407               else {
408                 TopTools_ListOfShape thelist3;
409                 locmap.Bind(fac,thelist3);
410               }
411               if (trP.IsDeleted(fac)) {
412               }
413               else if (!UntilInShape) {
414                 myMap(fac) = trP.Modified(fac);
415                 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
416               }
417               else {
418                 locmap(fac) = trP.Modified(fac);
419                 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
420               }
421             }
422           }// if(!mySUntil.IsNull())
423           //
424           //modified by NIZNHY-PKV Thu Mar 21 17:21:49 2002 f
425           //UpdateDescendants(trP.Builder(),theGShape,Standard_True); // skip faces
426           UpdateDescendants(trP,theGShape,Standard_True); // skip faces
427           //modified by NIZNHY-PKV Thu Mar 21 17:22:32 2002 t
428
429           theGlue.Init(mySbase,theGShape);
430           for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
431             const TopoDS_Face& gl = TopoDS::Face(itm.Key());
432             TopTools_ListOfShape ldsc;
433             if (trP.IsDeleted(gl)) {
434             }
435             else {
436               ldsc = trP.Modified(gl);
437               if (ldsc.IsEmpty()) ldsc.Append(gl);
438             }
439             const TopoDS_Face& glface = TopoDS::Face(itm.Value());        
440             for (it.Initialize(ldsc);it.More();it.Next()) {
441               const TopoDS_Face& fac = TopoDS::Face(it.Value());
442               Collage = BRepFeat::IsInside(fac, glface);
443               if(!Collage) {
444                 theOpe = 2;
445                 ChangeOpe = Standard_True;
446                 break;
447               }
448               else {
449                 theGlue.Bind(fac,glface);
450                 theFE.Set(fac,glface);
451                 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
452                   theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
453                 }
454               }
455             }
456           }
457         }// else X1
458       }// else X0
459     }// if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) 
460     else {
461       theGlue.Init(mySbase,myGShape);
462       for (itm.Initialize(myGluedF); itm.More();itm.Next()) {
463         const TopoDS_Face& glface = TopoDS::Face(itm.Key());
464         const TopoDS_Face& fac = TopoDS::Face(myGluedF(glface));
465         for (exp.Init(myGShape,TopAbs_FACE); exp.More(); exp.Next()) {
466           if (exp.Current().IsSame(glface)) {
467             break;
468           }
469         }
470         if (exp.More()) {
471           Collage = BRepFeat::IsInside(glface, fac);
472           if(!Collage) {
473             theOpe = 2;
474             ChangeOpe = Standard_True;
475             break;
476           }
477           else {
478             theGlue.Bind(glface, fac);
479             theFE.Set(glface, fac);
480             for (theFE.InitIterator(); theFE.More();theFE.Next()) {
481               theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
482             }
483           }
484         }
485       }
486     }
487
488     // Add gluing on start and end face if necessary !!!
489     if (FromInShape && Collage) {
490       TopExp_Explorer ex(mySFrom,TopAbs_FACE);
491       for(; ex.More(); ex.Next()) {
492         const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
493 //        for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
494         for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
495           const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
496           theFE.Set(fac1, fac2);
497           theGlue.Bind(fac1, fac2);
498           for (theFE.InitIterator(); theFE.More();theFE.Next()) {
499             theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
500           }
501         }
502 //        myMap.UnBind(fac2);
503       }
504     }
505
506     if (UntilInShape && Collage) {
507       TopExp_Explorer ex(mySUntil, TopAbs_FACE);
508       for(; ex.More(); ex.Next()) {
509         const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
510 //        for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
511         for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
512           const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
513           theGlue.Bind(fac1, fac2);
514           theFE.Set(fac1, fac2);
515           for (theFE.InitIterator(); theFE.More();theFE.Next()) {
516             theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
517           }
518         }
519         //myMap.UnBind(fac2); // to avoid fac2 in Map when
520         // UpdateDescendants(theGlue) is called
521       }
522     }
523
524     LocOpe_Operation ope = theGlue.OpeType();
525     if (ope == LocOpe_INVALID ||
526         (myFuse && ope != LocOpe_FUSE) ||
527         (!myFuse && ope != LocOpe_CUT) ||
528         (!Collage)) {
529       theOpe = 2;
530       ChangeOpe = Standard_True;
531     }
532   }
533
534 //--- if the gluing is always applicable
535
536   if (theOpe == 1) {
537 #ifdef DEB
538     if (trc) cout << " still Gluer" << endl;
539 #endif
540     theGlue.Perform();
541     if (theGlue.IsDone()) {
542       TopoDS_Shape shshs = theGlue.ResultingShape();
543 //      if (BRepOffsetAPI::IsTopologicallyValid(shshs)) {
544       if (BRepAlgo::IsValid(shshs)) {
545         UpdateDescendants(theGlue);
546         myNewEdges = theGlue.Edges();
547         myTgtEdges = theGlue.TgtEdges();
548 #ifdef DEB
549           if (trc) cout << " Gluer result" << endl;
550 #endif
551         Done();
552         myShape = theGlue.ResultingShape();
553       }
554       else {
555         theOpe = 2;
556         ChangeOpe = Standard_True;
557       }
558     }
559     else {
560       theOpe = 2;
561       ChangeOpe = Standard_True;
562     }
563   }
564
565
566 //--- case without gluing + Tool with proper dimensions
567
568   if (theOpe == 2 && ChangeOpe && myJustGluer) {
569 #ifdef DEB
570     if (trc) cout << " Gluer failure" << endl;
571 #endif
572     myJustGluer = Standard_False;
573     theOpe = 0;
574 //    Done();
575 //    return;
576   }
577
578 //--- case without gluing
579
580   if (theOpe == 2) {
581 #ifdef DEB
582     if (trc) cout << " No Gluer" << endl;
583 #endif
584     TopoDS_Shape theGShape = myGShape;
585     if (ChangeOpe) {
586 #ifdef DEB
587       if (trc) cout << " Passage to topological operations" << endl;
588 #endif
589     }    
590
591     TopoDS_Shape Comp;
592     BRep_Builder B;
593     B.MakeCompound(TopoDS::Compound(Comp));
594     if (!mySFrom.IsNull() || !mySUntil.IsNull()) {
595       if (!mySFrom.IsNull() && !FromInShape) {
596         TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
597         if (!S.IsNull()) {
598           B.Add(Comp,S);
599         }
600       }
601       if (!mySUntil.IsNull() && !UntilInShape) {
602         if (!mySFrom.IsNull()) {
603           if (!mySFrom.IsSame(mySUntil)) {
604             TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
605             if (!S.IsNull()) {
606               B.Add(Comp,S);
607             }
608           }
609         }
610         else {
611           TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
612           if (!S.IsNull()) {
613             B.Add(Comp,S);
614           }
615         }
616       }
617     }
618
619 // update type of selection
620     if(myPerfSelection == BRepFeat_SelectionU && !UntilInShape) {
621       myPerfSelection = BRepFeat_NoSelection;
622     }
623     else if(myPerfSelection == BRepFeat_SelectionFU &&
624             !FromInShape && !UntilInShape) {
625       myPerfSelection = BRepFeat_NoSelection;
626     }
627     else if(myPerfSelection == BRepFeat_SelectionShU && !UntilInShape) {
628       myPerfSelection = BRepFeat_NoSelection;
629     }
630     else {}
631
632     TopExp_Explorer expp(Comp, TopAbs_SOLID);
633     if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())  {
634       //modified by NIZNHY-PKV Thu Mar 21 17:24:52 2002 f
635       //BRepAlgo_Cut trP(myGShape,Comp);
636       BRepAlgoAPI_Cut trP(myGShape, Comp);
637       //modified by NIZNHY-PKV Thu Mar 21 17:24:56 2002 t
638       // the result is necessarily a compound.
639       exp.Init(trP.Shape(),TopAbs_SOLID);
640       if (!exp.More()) {
641         myStatusError = BRepFeat_EmptyCutResult;
642         NotDone();
643         return;
644       }
645       // Only solids are preserved
646       theGShape.Nullify();
647       BRep_Builder B;
648       B.MakeCompound(TopoDS::Compound(theGShape));
649       for (; exp.More(); exp.Next()) {
650         B.Add(theGShape,exp.Current());
651       }
652       if (!BRepAlgo::IsValid(theGShape)) {
653         myStatusError = BRepFeat_InvShape;
654         NotDone();
655         return;
656       }
657       if(!mySFrom.IsNull()) {
658         if(!FromInShape) {
659           TopExp_Explorer ex(mySFrom, TopAbs_FACE);
660           for(; ex.More(); ex.Next()) {
661             const TopoDS_Face& fac = TopoDS::Face(ex.Current());
662             TopTools_ListOfShape thelist4;
663             myMap.Bind(fac,thelist4);
664             if (trP.IsDeleted(fac)) {
665             }
666             else {
667               myMap(fac) = trP.Modified(fac);
668              if (myMap(fac).IsEmpty())  myMap(fac).Append(fac);
669             }
670           }
671         }
672       }
673       if(!mySUntil.IsNull()) {
674         if(!UntilInShape) {
675           TopExp_Explorer ex(mySUntil, TopAbs_FACE);
676           for(; ex.More(); ex.Next()) {
677             const TopoDS_Face& fac = TopoDS::Face(ex.Current());
678             TopTools_ListOfShape thelist5;
679             myMap.Bind(fac,thelist5);
680             if (trP.IsDeleted(fac)) {
681             }
682             else {
683               myMap(fac) = trP.Modified(fac);
684               if (myMap.IsEmpty()) myMap(fac).Append(fac);
685             }
686           }
687         }
688       }
689       //modified by NIZNHY-PKV Thu Mar 21 17:27:23 2002 f
690       //UpdateDescendants(trP.Builder(),theGShape,Standard_True); 
691       UpdateDescendants(trP,theGShape,Standard_True); 
692       //modified by NIZNHY-PKV Thu Mar 21 17:27:31 2002 t
693     }//if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())  {
694     //
695
696 //--- generation of "just feature" for assembly = Parts of tool
697     Standard_Boolean bFlag = (myPerfSelection == BRepFeat_NoSelection) ? 0 : 1;
698     BRepFeat_Builder theBuilder;
699     theBuilder.Init(mySbase, theGShape);
700     theBuilder.SetOperation(myFuse, bFlag);
701     theBuilder.Perform();
702     //
703     TopTools_ListOfShape lshape;
704     theBuilder.PartsOfTool(lshape);
705     //
706     Standard_Real pbmin = RealLast(), pbmax = RealFirst();
707     Standard_Real prmin = RealLast()  - 2*Precision::Confusion();
708     Standard_Real prmax = RealFirst() + 2*Precision::Confusion();
709     Standard_Boolean flag1 = Standard_False;
710     Handle(Geom_Curve) C;
711
712 //--- Selection of pieces of tool to be preserved
713     if(!lshape.IsEmpty() && myPerfSelection != BRepFeat_NoSelection) {
714 //      Find ParametricMinMax depending on the constraints of Shape From and Until
715 //   -> prmin, prmax, pbmin and pbmax
716       C = BarycCurve();
717       if (C.IsNull()) {
718         myStatusError = BRepFeat_EmptyBaryCurve; 
719         NotDone();
720         return;
721       }
722
723       if(myPerfSelection == BRepFeat_SelectionSh) {
724         BRepFeat::ParametricMinMax(mySbase,C, 
725                                    prmin, prmax, pbmin, pbmax, flag1);
726       }
727       else if(myPerfSelection == BRepFeat_SelectionFU) {
728         Standard_Real prmin1, prmax1, prmin2, prmax2;
729         Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
730       
731         BRepFeat::ParametricMinMax(mySFrom,C, 
732                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
733         BRepFeat::ParametricMinMax(mySUntil,C, 
734                                    prmin2, prmax2, prbmin2, prbmax2, flag1);
735
736 // case of revolutions
737         if (C->IsPeriodic()) {
738           Standard_Real period = C->Period();
739           prmax = prmax2;
740           if (flag1) {
741             prmin = ElCLib::InPeriod(prmin1,prmax-period,prmax);
742           }
743           else {
744             prmin = Min(prmin1, prmin2);
745           }
746           pbmax = prbmax2;
747           pbmin = ElCLib::InPeriod(prbmin1,pbmax-period,pbmax);
748         }
749         else {
750           prmin = Min(prmin1, prmin2);
751           prmax = Max(prmax1, prmax2);
752           pbmin = Min(prbmin1, prbmin2);
753           pbmax = Max(prbmax1, prbmax2);
754         }
755       }
756       else if(myPerfSelection == BRepFeat_SelectionShU) {
757         Standard_Real prmin1, prmax1, prmin2, prmax2;
758         Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
759         
760         if(!myJustFeat && sens == 0) sens =1;
761         if (sens == 0) {
762           myStatusError = BRepFeat_IncDirection;
763           NotDone();
764           return;
765         }
766         
767         BRepFeat::ParametricMinMax(mySUntil,C, 
768                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
769
770         BRepFeat::ParametricMinMax(mySbase,C, 
771                                    prmin2, prmax2, prbmin2, prbmax2, flag1);
772         if (sens == 1) {
773           prmin = prmin2;
774           prmax = prmax1;
775           pbmin = prbmin2;
776           pbmax = prbmax1;
777         }
778         else if (sens == -1) {
779           prmin = prmin1;
780           prmax = prmax2;
781           pbmin = prbmin1;
782           pbmax = prbmax2;
783         }
784       }
785       else if (myPerfSelection == BRepFeat_SelectionU) {
786         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
787               if (sens == 0) {
788           myStatusError = BRepFeat_IncDirection;
789           NotDone();
790           return;
791         }
792         
793         // Find parts of the tool containing descendants of Shape Until
794         BRepFeat::ParametricMinMax(mySUntil,C, 
795                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
796         if (sens == 1) {
797           prmin = RealFirst();
798           prmax = prmax1;
799           pbmin = RealFirst();
800           pbmax = prbmax1;
801         }
802         else if(sens == -1) {
803           prmin = prmin1;
804           prmax = RealLast();
805           pbmin = prbmin1;
806           pbmax = RealLast();
807         }
808       }
809
810
811 // Finer choice of ParametricMinMax in case when the tool 
812 // intersects Shapes From and Until
813 //       case of several intersections (keep PartsOfTool according to the selection)  
814 //       position of the face of intersection in PartsOfTool (before or after)
815       Standard_Real delta = Precision::Confusion();
816
817       if (myPerfSelection != BRepFeat_NoSelection) {
818 // modif of the test for cts21181 : (prbmax2 and prnmin2) -> (prbmin1 and prbmax1)
819 // correction take into account flag2 for pro15323 and flag3 for pro16060
820         if (!mySUntil.IsNull()) {
821           TopTools_MapOfShape mapFuntil;
822           Descendants(mySUntil,theBuilder,mapFuntil);
823           if (!mapFuntil.IsEmpty()) {
824             for (it.Initialize(lshape); it.More(); it.Next()) {
825               TopExp_Explorer expf;
826               for (expf.Init(it.Value(),TopAbs_FACE); 
827                    expf.More(); expf.Next()) {
828                 if (mapFuntil.Contains(expf.Current())) {
829                   Standard_Boolean flag2,flag3;
830                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
831                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
832                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
833                                              prbmin1, prbmax1,flag3);
834                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
835                                              prbmin2, prbmax2,flag2);
836                   if (sens == 1) {
837                     Standard_Boolean testOK = !flag2;
838                     if (flag2) {
839                       testOK = !flag1;
840                       if (flag1 && prmax2 > prmin + delta) {
841                         testOK = !flag3;
842                         if (flag3 && prmax1 == prmax2) {
843                           testOK = Standard_True;
844                         }
845                       }
846                     }
847                     if (prbmin1 < pbmax && testOK) {
848                       if (flag2) {
849                         flag1 = flag2;
850                         prmax  = prmax2;
851                       }
852                       pbmax = prbmin1;
853                     }
854                   }
855                   else if (sens == -1){ 
856                     Standard_Boolean testOK = !flag2;
857                     if (flag2) {
858                       testOK = !flag1;
859                       if (flag1 && prmin2 < prmax - delta) {
860                         testOK = !flag3;
861                         if (flag3 && prmin1 == prmin2) {
862                           testOK = Standard_True;
863                         }
864                       }
865                     }
866                     if (prbmax1 > pbmin && testOK) {
867                       if (flag2) {
868                         flag1 = flag2;
869                         prmin  = prmin2;
870                       }
871                       pbmin = prbmax1;
872                     }
873                   }
874                   break;
875                 }                
876               }
877             }
878             it.Initialize(lshape);
879           }
880         }
881         if (!mySFrom.IsNull()) {
882           TopTools_MapOfShape mapFfrom;
883           Descendants(mySFrom, theBuilder, mapFfrom);
884           if (!mapFfrom.IsEmpty()) {
885             for (it.Initialize(lshape); it.More(); it.Next()) {
886               TopExp_Explorer expf;
887               for (expf.Init(it.Value(),TopAbs_FACE); 
888                    expf.More(); expf.Next()) {
889                 if (mapFfrom.Contains(expf.Current())) {
890                   Standard_Boolean flag2,flag3;
891                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
892                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
893                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
894                                              prbmin1, prbmax1,flag3);
895                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
896                                              prbmin2, prbmax2,flag2);
897                   if (sens == 1) {
898                     Standard_Boolean testOK = !flag2;
899                     if (flag2) {
900                       testOK = !flag1;
901                       if (flag1 && prmin2 < prmax - delta) {
902                         testOK = !flag3;
903                         if (flag3 && prmin1 == prmin2) {
904                           testOK = Standard_True;
905                         }
906                       }
907                     }
908                     if (prbmax1 > pbmin && testOK) {
909                       if (flag2) {
910                         flag1 = flag2;
911                         prmin  = prmin2;
912                       }
913                       pbmin = prbmax1;
914                     }
915                   }
916                   else if (sens == -1){
917                     Standard_Boolean testOK = !flag2;
918                     if (flag2) {
919                       testOK = !flag1;
920                       if (flag1 && prmax2 > prmin + delta) {
921                         testOK = !flag3;
922                         if (flag3 && prmax1 == prmax2) {
923                           testOK = Standard_True;
924                         }
925                       }
926                     }
927                     if (prbmin1 < pbmax && testOK) {
928                       if (flag2) {
929                         flag1 = flag2;
930                         prmax  = prmax2;
931                       }
932                       pbmax = prbmin1;
933                     }
934                   }
935                   break;
936                 }                
937               }
938             }
939             it.Initialize(lshape);
940           }
941         }
942       }
943
944
945 // Parse PartsOfTool to preserve or not depending on ParametricMinMax
946       if (!myJustFeat) {
947         Standard_Boolean KeepParts = Standard_False;
948         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
949         Standard_Real min, max, pmin, pmax;
950         Standard_Boolean flag2;
951         for (it.Initialize(lshape); it.More(); it.Next()) {
952           if (C->IsPeriodic()) {
953             Standard_Real period = C->Period();
954             Standard_Real pr, prb;
955             BRepFeat::ParametricMinMax(it.Value(),C, pr, prmax1,
956                                        prb, prbmax1,flag2,Standard_True);
957             if (flag2) {
958               prmin1 = ElCLib::InPeriod(pr,prmax1-period,prmax1);
959             }
960             else {
961               prmin1 = pr;
962             }
963             prbmin1 = ElCLib::InPeriod(prb,prbmax1-period,prbmax1);
964           }
965           else {
966             BRepFeat::ParametricMinMax(it.Value(),C, 
967                                        prmin1, prmax1, prbmin1, prbmax1,flag2);
968           }
969           if(flag2 == Standard_False || flag1 == Standard_False) {
970             pmin = pbmin;
971             pmax = pbmax;
972             min = prbmin1;
973             max = prbmax1;
974           }
975           else {
976             pmin = prmin;
977             pmax = prmax;
978             min = prmin1;
979             max = prmax1;
980           }
981           if (!((min > pmax - delta) || 
982                 (max < pmin + delta))) {
983             KeepParts = Standard_True;
984             const TopoDS_Shape& S = it.Value();
985             theBuilder.KeepPart(S);
986           }
987         }
988
989 // Case when no part of the tool is preserved
990         if (!KeepParts) {
991 #ifdef DEB
992           if (trc) cout << " No parts of tool kept" << endl;
993 #endif
994           myStatusError = BRepFeat_NoParts;
995           NotDone();
996           return;
997         }
998       }
999       else {
1000 // case JustFeature -> all PartsOfTool are preserved
1001         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1002         Standard_Real min, max, pmin, pmax;
1003         Standard_Boolean flag2;
1004         TopoDS_Shape Compo;
1005         BRep_Builder B;
1006         B.MakeCompound(TopoDS::Compound(Compo));
1007         for (it.Initialize(lshape); it.More(); it.Next()) {
1008           BRepFeat::ParametricMinMax(it.Value(),C, 
1009                                      prmin1, prmax1, prbmin1, prbmax1,flag2);
1010           if(flag2 == Standard_False || flag1 == Standard_False) {
1011             pmin = pbmin;
1012             pmax = pbmax;
1013             min = prbmin1;
1014             max = prbmax1;
1015           }
1016           else { 
1017             pmin = prmin;
1018             pmax = prmax;
1019             min = prmin1;
1020             max = prmax1;
1021           }
1022           if ((min < pmax - delta) && 
1023               (max > pmin + delta)){
1024             if (!it.Value().IsNull()) {
1025               B.Add(Compo,it.Value());
1026             }
1027           }
1028         }
1029         myShape = Compo;
1030       }
1031     }
1032  
1033 //--- Generation of result myShape
1034
1035     if (!myJustFeat) {
1036       // removal of edges of section that have no common vertices
1037       // with PartsOfTool preserved
1038       //modified by NIZHNY-EMV Thu May 10 15:56:24 2012
1039       if (bFlag) { 
1040         theBuilder.PerformResult();
1041         myShape = theBuilder.Shape();
1042       } else {
1043         myShape = theBuilder.Shape();
1044       }
1045       //modified by NIZHNY-EMV Thu May 10 15:56:26 2012
1046       Done();
1047     }
1048     else {
1049       // all is already done
1050       Done();
1051     }
1052   }
1053
1054   myStatusError = BRepFeat_OK;
1055 }
1056
1057 //=======================================================================
1058 //function : IsDeleted
1059 //purpose  : 
1060 //=======================================================================
1061
1062 Standard_Boolean BRepFeat_Form::IsDeleted(const TopoDS_Shape& F)
1063 {
1064   return (myMap(F).IsEmpty());
1065 }
1066
1067 //=======================================================================
1068 //function : Modified
1069 //purpose  : 
1070 //=======================================================================
1071
1072 const TopTools_ListOfShape& BRepFeat_Form::Modified
1073    (const TopoDS_Shape& F)
1074 {
1075   if (myMap.IsBound(F)) {
1076     static TopTools_ListOfShape list;
1077     list.Clear(); // For the second passage DPF
1078     TopTools_ListIteratorOfListOfShape ite(myMap(F));
1079     for(; ite.More(); ite.Next()) {
1080       const TopoDS_Shape& sh = ite.Value();
1081       if(!sh.IsSame(F)) 
1082         list.Append(sh);
1083     }
1084     return list;
1085   }
1086   return myGenerated; // empty list
1087 }
1088
1089 //=======================================================================
1090 //function : Generated
1091 //purpose  : 
1092 //=======================================================================
1093
1094 const TopTools_ListOfShape& BRepFeat_Form::Generated
1095    (const TopoDS_Shape& S)
1096 {
1097   if (myMap.IsBound(S) && 
1098       S.ShapeType() != TopAbs_FACE) { // check if filter on face or not
1099     static TopTools_ListOfShape list;
1100     list.Clear(); // For the second passage DPF
1101     TopTools_ListIteratorOfListOfShape ite(myMap(S));
1102     for(; ite.More(); ite.Next()) {
1103       const TopoDS_Shape& sh = ite.Value();
1104       if(!sh.IsSame(S)) 
1105         list.Append(sh);
1106     }
1107     return list;
1108   }
1109   else return myGenerated;
1110 }
1111
1112
1113
1114 //=======================================================================
1115 //function : UpdateDescendants
1116 //purpose  : 
1117 //=======================================================================
1118
1119 void BRepFeat_Form::UpdateDescendants(const LocOpe_Gluer& G)
1120 {
1121   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1122   TopTools_ListIteratorOfListOfShape it,it2;
1123   TopTools_MapIteratorOfMapOfShape itm;
1124
1125   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1126     const TopoDS_Shape& orig = itdm.Key();
1127     TopTools_MapOfShape newdsc;
1128     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1129       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1130       for (it2.Initialize(G.DescendantFaces(fdsc));
1131            it2.More();it2.Next()) {
1132         newdsc.Add(it2.Value());
1133       }
1134     }
1135     myMap.ChangeFind(orig).Clear();
1136     for (itm.Initialize(newdsc);itm.More();itm.Next()) {
1137       myMap.ChangeFind(orig).Append(itm.Key());
1138     }
1139   }
1140 }
1141
1142
1143
1144
1145
1146 //=======================================================================
1147 //function : FirstShape
1148 //purpose  : 
1149 //=======================================================================
1150
1151 const TopTools_ListOfShape& BRepFeat_Form::FirstShape() const
1152 {
1153   if (!myFShape.IsNull()) {
1154     return myMap(myFShape);
1155   }
1156   return myGenerated; // empty list
1157 }
1158
1159
1160 //=======================================================================
1161 //function : LastShape
1162 //purpose  : 
1163 //=======================================================================
1164
1165 const TopTools_ListOfShape& BRepFeat_Form::LastShape() const
1166 {
1167   if (!myLShape.IsNull()) {
1168     return myMap(myLShape);
1169   }
1170   return myGenerated; // empty list
1171 }
1172
1173
1174 //=======================================================================
1175 //function : NewEdges
1176 //purpose  : 
1177 //=======================================================================
1178
1179 const TopTools_ListOfShape& BRepFeat_Form::NewEdges() const
1180 {
1181   return myNewEdges;
1182 }
1183
1184
1185 //=======================================================================
1186 //function : NewEdges
1187 //purpose  : 
1188 //=======================================================================
1189
1190 const TopTools_ListOfShape& BRepFeat_Form::TgtEdges() const
1191 {
1192   return myTgtEdges;
1193 }
1194
1195
1196 //=======================================================================
1197 //function : TransformSUntil
1198 //purpose  : Limitation of the shape until the case of infinite faces
1199 //=======================================================================
1200
1201 Standard_Boolean BRepFeat_Form::TransformShapeFU(const Standard_Integer flag)
1202 {
1203 #ifdef DEB
1204   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1205 #endif
1206   Standard_Boolean Trf = Standard_False;
1207
1208   TopoDS_Shape shapefu;
1209   if(flag == 0)
1210     shapefu = mySFrom;
1211   else if(flag == 1)
1212     shapefu = mySUntil;
1213   else 
1214     return Trf;
1215
1216   TopExp_Explorer exp(shapefu, TopAbs_FACE);
1217   if (!exp.More()) { // no faces... It is necessary to return an error
1218 #ifdef DEB
1219     if (trc) cout << " BRepFeat_Form::TransformShapeFU : invalid Shape" << endl;
1220 #endif
1221     return Trf;
1222   }
1223
1224   exp.Next();
1225   if (!exp.More()) { // the only face. Is it infinite?
1226     exp.ReInit();
1227     TopoDS_Face fac = TopoDS::Face(exp.Current());
1228
1229     Handle(Geom_Surface) S = BRep_Tool::Surface(fac);
1230     Handle(Standard_Type) styp = S->DynamicType();
1231     if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1232       S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
1233       styp =  S->DynamicType();
1234     }
1235
1236     if (styp == STANDARD_TYPE(Geom_Plane) ||
1237         styp == STANDARD_TYPE(Geom_CylindricalSurface) ||
1238         styp == STANDARD_TYPE(Geom_ConicalSurface)) {
1239       TopExp_Explorer exp1(fac, TopAbs_WIRE);
1240       if (!exp1.More()) {
1241         Trf = Standard_True;
1242       }
1243       else {
1244         Trf = BRep_Tool::NaturalRestriction(fac);
1245       }
1246
1247     }
1248     if (Trf) {
1249       BRepFeat::FaceUntil(mySbase, fac);
1250     }
1251
1252     if(flag == 0) {
1253       TopTools_ListOfShape thelist6;
1254       myMap.Bind(mySFrom,thelist6);
1255       myMap(mySFrom).Append(fac);
1256       mySFrom = fac;
1257     }
1258     else if(flag == 1) {
1259       TopTools_ListOfShape thelist7;
1260       myMap.Bind(mySUntil,thelist7);
1261       myMap(mySUntil).Append(fac);
1262       mySUntil = fac;
1263     }
1264     else {
1265     }
1266   }
1267   else {
1268     for (exp.ReInit(); exp.More(); exp.Next()) {
1269       const TopoDS_Shape& fac = exp.Current();
1270       TopTools_ListOfShape thelist8;
1271       myMap.Bind(fac,thelist8);
1272       myMap(fac).Append(fac);
1273     }
1274   }
1275 #ifdef DEB
1276   if (trc) {
1277     if (Trf && (flag == 0)) cout << " TransformShapeFU From" << endl;
1278     if (Trf && (flag == 1)) cout << " TransformShapeFU Until" << endl;
1279   }
1280 #endif
1281   return Trf;
1282 }
1283
1284
1285 //=======================================================================
1286 //function : CurrentStatusError
1287 //purpose  : 
1288 //=======================================================================
1289
1290 BRepFeat_StatusError BRepFeat_Form::CurrentStatusError() const
1291 {
1292   return myStatusError;
1293 }
1294
1295 //=======================================================================
1296 //function : Descendants
1297 //purpose  : 
1298 //=======================================================================
1299
1300 static void Descendants(const TopoDS_Shape& S,
1301                         BRepFeat_Builder& theFB,
1302                         TopTools_MapOfShape& mapF)
1303 {
1304   mapF.Clear();
1305   TopTools_ListIteratorOfListOfShape it;
1306   TopExp_Explorer exp;
1307   for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1308    
1309     const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1310     const TopTools_ListOfShape& aLM=theFB.Modified(fdsc);
1311     it.Initialize(aLM);
1312     for (; it.More(); it.Next()) {
1313       mapF.Add(it.Value());
1314     }
1315     
1316   }
1317 }
1318
1319 //=======================================================================
1320 //function : UpdateDescendants
1321 //purpose  : 
1322 //=======================================================================
1323   void BRepFeat_Form::UpdateDescendants(const Handle(TopOpeBRepBuild_HBuilder)& B,
1324                                         const TopoDS_Shape& S,
1325                                         const Standard_Boolean SkipFace)
1326 {
1327   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1328   TopTools_ListIteratorOfListOfShape it,it2;
1329   TopTools_MapIteratorOfMapOfShape itm;
1330   TopExp_Explorer exp;
1331
1332   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1333     const TopoDS_Shape& orig = itdm.Key();
1334     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1335       continue;
1336     }
1337     TopTools_MapOfShape newdsc;
1338
1339     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1340
1341     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1342       const TopoDS_Shape& sh = it.Value();
1343       if(sh.ShapeType() != TopAbs_FACE) continue;
1344       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1345       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1346         if (exp.Current().IsSame(fdsc)) { // preserved
1347           newdsc.Add(fdsc);
1348           break;
1349         }
1350       }
1351       if (!exp.More()) {
1352         if (B->IsSplit(fdsc, TopAbs_OUT)) {
1353           for (it2.Initialize(B->Splits(fdsc,TopAbs_OUT));
1354                it2.More();it2.Next()) {
1355             newdsc.Add(it2.Value());
1356           }
1357         }
1358         if (B->IsSplit(fdsc, TopAbs_IN)) {
1359           for (it2.Initialize(B->Splits(fdsc,TopAbs_IN));
1360                it2.More();it2.Next()) {
1361             newdsc.Add(it2.Value());
1362           }
1363         }
1364         if (B->IsSplit(fdsc, TopAbs_ON)) {
1365           for (it2.Initialize(B->Splits(fdsc,TopAbs_ON));
1366                it2.More();it2.Next()) {
1367             newdsc.Add(it2.Value());
1368           }
1369         }
1370         if (B->IsMerged(fdsc, TopAbs_OUT)) {
1371           for (it2.Initialize(B->Merged(fdsc,TopAbs_OUT));
1372                it2.More();it2.Next()) {
1373             newdsc.Add(it2.Value());
1374           }
1375         }
1376         if (B->IsMerged(fdsc, TopAbs_IN)) {
1377           for (it2.Initialize(B->Merged(fdsc,TopAbs_IN));
1378                it2.More();it2.Next()) {
1379             newdsc.Add(it2.Value());
1380           }
1381         }
1382         if (B->IsMerged(fdsc, TopAbs_ON)) {
1383           for (it2.Initialize(B->Merged(fdsc,TopAbs_ON));
1384                it2.More();it2.Next()) {
1385             newdsc.Add(it2.Value());
1386           }
1387         }
1388       }
1389     }
1390     myMap.ChangeFind(orig).Clear();
1391     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1392        // check the appartenance to the shape...
1393       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1394         if (exp.Current().IsSame(itm.Key())) {
1395 //          const TopoDS_Shape& sh = itm.Key();
1396           myMap.ChangeFind(orig).Append(itm.Key());
1397           break;
1398         }
1399       }
1400     }
1401   }
1402 }
1403 //modified by NIZNHY-PKV Thu Mar 21 18:43:18 2002 f
1404 //=======================================================================
1405 //function : UpdateDescendants
1406 //purpose  : 
1407 //=======================================================================
1408   void BRepFeat_Form::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
1409                                         const TopoDS_Shape& S,
1410                                         const Standard_Boolean SkipFace)
1411 {
1412   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1413   TopTools_ListIteratorOfListOfShape it,it2;
1414   TopTools_MapIteratorOfMapOfShape itm;
1415   TopExp_Explorer exp;
1416
1417   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1418     const TopoDS_Shape& orig = itdm.Key();
1419     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1420       continue;
1421     }
1422     TopTools_MapOfShape newdsc;
1423
1424     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1425
1426     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1427       const TopoDS_Shape& sh = it.Value();
1428       if(sh.ShapeType() != TopAbs_FACE) continue;
1429       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1430       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1431         if (exp.Current().IsSame(fdsc)) { // preserved
1432           newdsc.Add(fdsc);
1433           break;
1434         }
1435       }
1436       if (!exp.More()) {
1437         BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
1438         const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
1439         it2.Initialize(aLM);
1440         for (; it2.More(); it2.Next()) {
1441           const TopoDS_Shape& aS=it2.Value();
1442           newdsc.Add(aS);
1443         }
1444         
1445       }
1446     }
1447     myMap.ChangeFind(orig).Clear();
1448     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1449        // check the appartenance to the shape...
1450       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1451         if (exp.Current().IsSame(itm.Key())) {
1452 //          const TopoDS_Shape& sh = itm.Key();
1453           myMap.ChangeFind(orig).Append(itm.Key());
1454           break;
1455         }
1456       }
1457     }
1458   }
1459 }
1460 //modified by NIZNHY-PKV Thu Mar 21 18:43:36 2002 t