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