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