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