0021762: Integration of new Boolean Operation algorithm to OCCT.
[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, pbmax, prmin, prmax;
715     Standard_Boolean flag1;
716     Handle(Geom_Curve) C;
717
718 //--- Selection of pieces of tool to be preserved
719     if(!lshape.IsEmpty() && myPerfSelection != BRepFeat_NoSelection) {
720 //      Find ParametricMinMax depending on the constraints of Shape From and Until
721 //   -> prmin, prmax, pbmin and pbmax
722       C = BarycCurve();
723       if (C.IsNull()) {
724         myStatusError = BRepFeat_EmptyBaryCurve; 
725         NotDone();
726         return;
727       }
728
729       if(myPerfSelection == BRepFeat_SelectionSh) {
730         BRepFeat::ParametricMinMax(mySbase,C, 
731                                    prmin, prmax, pbmin, pbmax, flag1);
732       }
733       else if(myPerfSelection == BRepFeat_SelectionFU) {
734         Standard_Real prmin1, prmax1, prmin2, prmax2;
735         Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
736       
737         BRepFeat::ParametricMinMax(mySFrom,C, 
738                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
739         BRepFeat::ParametricMinMax(mySUntil,C, 
740                                    prmin2, prmax2, prbmin2, prbmax2, flag1);
741
742 // case of revolutions
743         if (C->IsPeriodic()) {
744           Standard_Real period = C->Period();
745           prmax = prmax2;
746           if (flag1) {
747             prmin = ElCLib::InPeriod(prmin1,prmax-period,prmax);
748           }
749           else {
750             prmin = Min(prmin1, prmin2);
751           }
752           pbmax = prbmax2;
753           pbmin = ElCLib::InPeriod(prbmin1,pbmax-period,pbmax);
754         }
755         else {
756           prmin = Min(prmin1, prmin2);
757           prmax = Max(prmax1, prmax2);
758           pbmin = Min(prbmin1, prbmin2);
759           pbmax = Max(prbmax1, prbmax2);
760         }
761       }
762       else if(myPerfSelection == BRepFeat_SelectionShU) {
763         Standard_Real prmin1, prmax1, prmin2, prmax2;
764         Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
765         
766         if(!myJustFeat && sens == 0) sens =1;
767         if (sens == 0) {
768           myStatusError = BRepFeat_IncDirection;
769           NotDone();
770           return;
771         }
772         
773         BRepFeat::ParametricMinMax(mySUntil,C, 
774                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
775
776         BRepFeat::ParametricMinMax(mySbase,C, 
777                                    prmin2, prmax2, prbmin2, prbmax2, flag1);
778         if (sens == 1) {
779           prmin = prmin2;
780           prmax = prmax1;
781           pbmin = prbmin2;
782           pbmax = prbmax1;
783         }
784         else if (sens == -1) {
785           prmin = prmin1;
786           prmax = prmax2;
787           pbmin = prbmin1;
788           pbmax = prbmax2;
789         }
790       }
791       else if (myPerfSelection == BRepFeat_SelectionU) {
792         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
793               if (sens == 0) {
794           myStatusError = BRepFeat_IncDirection;
795           NotDone();
796           return;
797         }
798         
799         // Find parts of the tool containing descendants of Shape Until
800         BRepFeat::ParametricMinMax(mySUntil,C, 
801                                    prmin1, prmax1, prbmin1, prbmax1, flag1);
802         if (sens == 1) {
803           prmin = RealFirst();
804           prmax = prmax1;
805           pbmin = RealFirst();
806           pbmax = prbmax1;
807         }
808         else if(sens == -1) {
809           prmin = prmin1;
810           prmax = RealLast();
811           pbmin = prbmin1;
812           pbmax = RealLast();
813         }
814       }
815
816
817 // Finer choice of ParametricMinMax in case when the tool 
818 // intersects Shapes From and Until
819 //       case of several intersections (keep PartsOfTool according to the selection)  
820 //       position of the face of intersection in PartsOfTool (before or after)
821       Standard_Real delta = Precision::Confusion();
822
823       if (myPerfSelection != BRepFeat_NoSelection) {
824 // modif of the test for cts21181 : (prbmax2 and prnmin2) -> (prbmin1 and prbmax1)
825 // correction take into account flag2 for pro15323 and flag3 for pro16060
826         if (!mySUntil.IsNull()) {
827           TopTools_MapOfShape mapFuntil;
828           Descendants(mySUntil,theBuilder,mapFuntil);
829           if (!mapFuntil.IsEmpty()) {
830             for (it.Initialize(lshape); it.More(); it.Next()) {
831               TopExp_Explorer expf;
832               for (expf.Init(it.Value(),TopAbs_FACE); 
833                    expf.More(); expf.Next()) {
834                 if (mapFuntil.Contains(expf.Current())) {
835                   Standard_Boolean flag2,flag3;
836                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
837                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
838                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
839                                              prbmin1, prbmax1,flag3);
840                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
841                                              prbmin2, prbmax2,flag2);
842                   if (sens == 1) {
843                     Standard_Boolean testOK = !flag2;
844                     if (flag2) {
845                       testOK = !flag1;
846                       if (flag1 && prmax2 > prmin + delta) {
847                         testOK = !flag3;
848                         if (flag3 && prmax1 == prmax2) {
849                           testOK = Standard_True;
850                         }
851                       }
852                     }
853                     if (prbmin1 < pbmax && testOK) {
854                       if (flag2) {
855                         flag1 = flag2;
856                         prmax  = prmax2;
857                       }
858                       pbmax = prbmin1;
859                     }
860                   }
861                   else if (sens == -1){ 
862                     Standard_Boolean testOK = !flag2;
863                     if (flag2) {
864                       testOK = !flag1;
865                       if (flag1 && prmin2 < prmax - delta) {
866                         testOK = !flag3;
867                         if (flag3 && prmin1 == prmin2) {
868                           testOK = Standard_True;
869                         }
870                       }
871                     }
872                     if (prbmax1 > pbmin && testOK) {
873                       if (flag2) {
874                         flag1 = flag2;
875                         prmin  = prmin2;
876                       }
877                       pbmin = prbmax1;
878                     }
879                   }
880                   break;
881                 }                
882               }
883             }
884             it.Initialize(lshape);
885           }
886         }
887         if (!mySFrom.IsNull()) {
888           TopTools_MapOfShape mapFfrom;
889           Descendants(mySFrom, theBuilder, mapFfrom);
890           if (!mapFfrom.IsEmpty()) {
891             for (it.Initialize(lshape); it.More(); it.Next()) {
892               TopExp_Explorer expf;
893               for (expf.Init(it.Value(),TopAbs_FACE); 
894                    expf.More(); expf.Next()) {
895                 if (mapFfrom.Contains(expf.Current())) {
896                   Standard_Boolean flag2,flag3;
897                   Standard_Real prmin1, prmax1, prbmin1, prbmax1;
898                   Standard_Real prmin2, prmax2, prbmin2, prbmax2;
899                   BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
900                                              prbmin1, prbmax1,flag3);
901                   BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
902                                              prbmin2, prbmax2,flag2);
903                   if (sens == 1) {
904                     Standard_Boolean testOK = !flag2;
905                     if (flag2) {
906                       testOK = !flag1;
907                       if (flag1 && prmin2 < prmax - delta) {
908                         testOK = !flag3;
909                         if (flag3 && prmin1 == prmin2) {
910                           testOK = Standard_True;
911                         }
912                       }
913                     }
914                     if (prbmax1 > pbmin && testOK) {
915                       if (flag2) {
916                         flag1 = flag2;
917                         prmin  = prmin2;
918                       }
919                       pbmin = prbmax1;
920                     }
921                   }
922                   else if (sens == -1){
923                     Standard_Boolean testOK = !flag2;
924                     if (flag2) {
925                       testOK = !flag1;
926                       if (flag1 && prmax2 > prmin + delta) {
927                         testOK = !flag3;
928                         if (flag3 && prmax1 == prmax2) {
929                           testOK = Standard_True;
930                         }
931                       }
932                     }
933                     if (prbmin1 < pbmax && testOK) {
934                       if (flag2) {
935                         flag1 = flag2;
936                         prmax  = prmax2;
937                       }
938                       pbmax = prbmin1;
939                     }
940                   }
941                   break;
942                 }                
943               }
944             }
945             it.Initialize(lshape);
946           }
947         }
948       }
949
950
951 // Parse PartsOfTool to preserve or not depending on ParametricMinMax
952       if (!myJustFeat) {
953         Standard_Boolean KeepParts = Standard_False;
954         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
955         Standard_Real min, max, pmin, pmax;
956         Standard_Boolean flag2;
957         for (it.Initialize(lshape); it.More(); it.Next()) {
958           if (C->IsPeriodic()) {
959             Standard_Real period = C->Period();
960             Standard_Real pr, prb;
961             BRepFeat::ParametricMinMax(it.Value(),C, pr, prmax1,
962                                        prb, prbmax1,flag2,Standard_True);
963             if (flag2) {
964               prmin1 = ElCLib::InPeriod(pr,prmax1-period,prmax1);
965             }
966             else {
967               prmin1 = pr;
968             }
969             prbmin1 = ElCLib::InPeriod(prb,prbmax1-period,prbmax1);
970           }
971           else {
972             BRepFeat::ParametricMinMax(it.Value(),C, 
973                                        prmin1, prmax1, prbmin1, prbmax1,flag2);
974           }
975           if(flag2 == Standard_False || flag1 == Standard_False) {
976             pmin = pbmin;
977             pmax = pbmax;
978             min = prbmin1;
979             max = prbmax1;
980           }
981           else {
982             pmin = prmin;
983             pmax = prmax;
984             min = prmin1;
985             max = prmax1;
986           }
987           if (!((min > pmax - delta) || 
988                 (max < pmin + delta))) {
989             KeepParts = Standard_True;
990             const TopoDS_Shape& S = it.Value();
991             theBuilder.KeepPart(S);
992           }
993         }
994
995 // Case when no part of the tool is preserved
996         if (!KeepParts) {
997 #ifdef DEB
998           if (trc) cout << " No parts of tool kept" << endl;
999 #endif
1000           myStatusError = BRepFeat_NoParts;
1001           NotDone();
1002           return;
1003         }
1004       }
1005       else {
1006 // case JustFeature -> all PartsOfTool are preserved
1007         Standard_Real prmin1, prmax1, prbmin1, prbmax1;
1008         Standard_Real min, max, pmin, pmax;
1009         Standard_Boolean flag2;
1010         TopoDS_Shape Compo;
1011         BRep_Builder B;
1012         B.MakeCompound(TopoDS::Compound(Compo));
1013         for (it.Initialize(lshape); it.More(); it.Next()) {
1014           BRepFeat::ParametricMinMax(it.Value(),C, 
1015                                      prmin1, prmax1, prbmin1, prbmax1,flag2);
1016           if(flag2 == Standard_False || flag1 == Standard_False) {
1017             pmin = pbmin;
1018             pmax = pbmax;
1019             min = prbmin1;
1020             max = prbmax1;
1021           }
1022           else { 
1023             pmin = prmin;
1024             pmax = prmax;
1025             min = prmin1;
1026             max = prmax1;
1027           }
1028           if ((min < pmax - delta) && 
1029               (max > pmin + delta)){
1030             if (!it.Value().IsNull()) {
1031               B.Add(Compo,it.Value());
1032             }
1033           }
1034         }
1035         myShape = Compo;
1036       }
1037     }
1038  
1039 //--- Generation of result myShape
1040
1041     if (!myJustFeat) {
1042       // removal of edges of section that have no common vertices
1043       // with PartsOfTool preserved
1044       //modified by NIZHNY-EMV Thu May 10 15:56:24 2012
1045       if (bFlag) { 
1046         theBuilder.PerformResult();
1047         myShape = theBuilder.Shape();
1048       } else {
1049         myShape = theBuilder.Shape();
1050       }
1051       //modified by NIZHNY-EMV Thu May 10 15:56:26 2012
1052       Done();
1053     }
1054     else {
1055       // all is already done
1056       Done();
1057     }
1058   }
1059
1060   myStatusError = BRepFeat_OK;
1061 }
1062
1063 //=======================================================================
1064 //function : IsDeleted
1065 //purpose  : 
1066 //=======================================================================
1067
1068 Standard_Boolean BRepFeat_Form::IsDeleted(const TopoDS_Shape& F)
1069 {
1070   return (myMap(F).IsEmpty());
1071 }
1072
1073 //=======================================================================
1074 //function : Modified
1075 //purpose  : 
1076 //=======================================================================
1077
1078 const TopTools_ListOfShape& BRepFeat_Form::Modified
1079    (const TopoDS_Shape& F)
1080 {
1081   if (myMap.IsBound(F)) {
1082     static TopTools_ListOfShape list;
1083     list.Clear(); // For the second passage DPF
1084     TopTools_ListIteratorOfListOfShape ite(myMap(F));
1085     for(; ite.More(); ite.Next()) {
1086       const TopoDS_Shape& sh = ite.Value();
1087       if(!sh.IsSame(F)) 
1088         list.Append(sh);
1089     }
1090     return list;
1091   }
1092   return myGenerated; // empty list
1093 }
1094
1095 //=======================================================================
1096 //function : Generated
1097 //purpose  : 
1098 //=======================================================================
1099
1100 const TopTools_ListOfShape& BRepFeat_Form::Generated
1101    (const TopoDS_Shape& S)
1102 {
1103   if (myMap.IsBound(S) && 
1104       S.ShapeType() != TopAbs_FACE) { // check if filter on face or not
1105     static TopTools_ListOfShape list;
1106     list.Clear(); // For the second passage DPF
1107     TopTools_ListIteratorOfListOfShape ite(myMap(S));
1108     for(; ite.More(); ite.Next()) {
1109       const TopoDS_Shape& sh = ite.Value();
1110       if(!sh.IsSame(S)) 
1111         list.Append(sh);
1112     }
1113     return list;
1114   }
1115   else return myGenerated;
1116 }
1117
1118
1119
1120 //=======================================================================
1121 //function : UpdateDescendants
1122 //purpose  : 
1123 //=======================================================================
1124
1125 void BRepFeat_Form::UpdateDescendants(const LocOpe_Gluer& G)
1126 {
1127   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1128   TopTools_ListIteratorOfListOfShape it,it2;
1129   TopTools_MapIteratorOfMapOfShape itm;
1130
1131   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1132     const TopoDS_Shape& orig = itdm.Key();
1133     TopTools_MapOfShape newdsc;
1134     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1135       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1136       for (it2.Initialize(G.DescendantFaces(fdsc));
1137            it2.More();it2.Next()) {
1138         newdsc.Add(it2.Value());
1139       }
1140     }
1141     myMap.ChangeFind(orig).Clear();
1142     for (itm.Initialize(newdsc);itm.More();itm.Next()) {
1143       myMap.ChangeFind(orig).Append(itm.Key());
1144     }
1145   }
1146 }
1147
1148
1149
1150
1151
1152 //=======================================================================
1153 //function : FirstShape
1154 //purpose  : 
1155 //=======================================================================
1156
1157 const TopTools_ListOfShape& BRepFeat_Form::FirstShape() const
1158 {
1159   if (!myFShape.IsNull()) {
1160     return myMap(myFShape);
1161   }
1162   return myGenerated; // empty list
1163 }
1164
1165
1166 //=======================================================================
1167 //function : LastShape
1168 //purpose  : 
1169 //=======================================================================
1170
1171 const TopTools_ListOfShape& BRepFeat_Form::LastShape() const
1172 {
1173   if (!myLShape.IsNull()) {
1174     return myMap(myLShape);
1175   }
1176   return myGenerated; // empty list
1177 }
1178
1179
1180 //=======================================================================
1181 //function : NewEdges
1182 //purpose  : 
1183 //=======================================================================
1184
1185 const TopTools_ListOfShape& BRepFeat_Form::NewEdges() const
1186 {
1187   return myNewEdges;
1188 }
1189
1190
1191 //=======================================================================
1192 //function : NewEdges
1193 //purpose  : 
1194 //=======================================================================
1195
1196 const TopTools_ListOfShape& BRepFeat_Form::TgtEdges() const
1197 {
1198   return myTgtEdges;
1199 }
1200
1201
1202 //=======================================================================
1203 //function : TransformSUntil
1204 //purpose  : Limitation of the shape until the case of infinite faces
1205 //=======================================================================
1206
1207 Standard_Boolean BRepFeat_Form::TransformShapeFU(const Standard_Integer flag)
1208 {
1209 #ifdef DEB
1210   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1211 #endif
1212   Standard_Boolean Trf = Standard_False;
1213
1214   TopoDS_Shape shapefu;
1215   if(flag == 0)
1216     shapefu = mySFrom;
1217   else if(flag == 1)
1218     shapefu = mySUntil;
1219   else 
1220     return Trf;
1221
1222   TopExp_Explorer exp(shapefu, TopAbs_FACE);
1223   if (!exp.More()) { // no faces... It is necessary to return an error
1224 #ifdef DEB
1225     if (trc) cout << " BRepFeat_Form::TransformShapeFU : invalid Shape" << endl;
1226 #endif
1227     return Trf;
1228   }
1229
1230   exp.Next();
1231   if (!exp.More()) { // the only face. Is it infinite?
1232     exp.ReInit();
1233     TopoDS_Face fac = TopoDS::Face(exp.Current());
1234
1235     Handle(Geom_Surface) S = BRep_Tool::Surface(fac);
1236     Handle(Standard_Type) styp = S->DynamicType();
1237     if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1238       S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
1239       styp =  S->DynamicType();
1240     }
1241
1242     if (styp == STANDARD_TYPE(Geom_Plane) ||
1243         styp == STANDARD_TYPE(Geom_CylindricalSurface) ||
1244         styp == STANDARD_TYPE(Geom_ConicalSurface)) {
1245       TopExp_Explorer exp1(fac, TopAbs_WIRE);
1246       if (!exp1.More()) {
1247         Trf = Standard_True;
1248       }
1249       else {
1250         Trf = BRep_Tool::NaturalRestriction(fac);
1251       }
1252
1253     }
1254     if (Trf) {
1255       BRepFeat::FaceUntil(mySbase, fac);
1256     }
1257
1258     if(flag == 0) {
1259       TopTools_ListOfShape thelist6;
1260       myMap.Bind(mySFrom,thelist6);
1261       myMap(mySFrom).Append(fac);
1262       mySFrom = fac;
1263     }
1264     else if(flag == 1) {
1265       TopTools_ListOfShape thelist7;
1266       myMap.Bind(mySUntil,thelist7);
1267       myMap(mySUntil).Append(fac);
1268       mySUntil = fac;
1269     }
1270     else {
1271     }
1272   }
1273   else {
1274     for (exp.ReInit(); exp.More(); exp.Next()) {
1275       const TopoDS_Shape& fac = exp.Current();
1276       TopTools_ListOfShape thelist8;
1277       myMap.Bind(fac,thelist8);
1278       myMap(fac).Append(fac);
1279     }
1280   }
1281 #ifdef DEB
1282   if (trc) {
1283     if (Trf && (flag == 0)) cout << " TransformShapeFU From" << endl;
1284     if (Trf && (flag == 1)) cout << " TransformShapeFU Until" << endl;
1285   }
1286 #endif
1287   return Trf;
1288 }
1289
1290
1291 //=======================================================================
1292 //function : CurrentStatusError
1293 //purpose  : 
1294 //=======================================================================
1295
1296 BRepFeat_StatusError BRepFeat_Form::CurrentStatusError() const
1297 {
1298   return myStatusError;
1299 }
1300
1301 //=======================================================================
1302 //function : Descendants
1303 //purpose  : 
1304 //=======================================================================
1305
1306 static void Descendants(const TopoDS_Shape& S,
1307                         BRepFeat_Builder& theFB,
1308                         TopTools_MapOfShape& mapF)
1309 {
1310   mapF.Clear();
1311   TopTools_ListIteratorOfListOfShape it;
1312   TopExp_Explorer exp;
1313   for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1314    
1315     const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1316     const TopTools_ListOfShape& aLM=theFB.Modified(fdsc);
1317     it.Initialize(aLM);
1318     for (; it.More(); it.Next()) {
1319       mapF.Add(it.Value());
1320     }
1321     
1322   }
1323 }
1324
1325 //=======================================================================
1326 //function : UpdateDescendants
1327 //purpose  : 
1328 //=======================================================================
1329   void BRepFeat_Form::UpdateDescendants(const Handle(TopOpeBRepBuild_HBuilder)& B,
1330                                         const TopoDS_Shape& S,
1331                                         const Standard_Boolean SkipFace)
1332 {
1333   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1334   TopTools_ListIteratorOfListOfShape it,it2;
1335   TopTools_MapIteratorOfMapOfShape itm;
1336   TopExp_Explorer exp;
1337
1338   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1339     const TopoDS_Shape& orig = itdm.Key();
1340     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1341       continue;
1342     }
1343     TopTools_MapOfShape newdsc;
1344
1345     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1346
1347     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1348       const TopoDS_Shape& sh = it.Value();
1349       if(sh.ShapeType() != TopAbs_FACE) continue;
1350       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1351       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1352         if (exp.Current().IsSame(fdsc)) { // preserved
1353           newdsc.Add(fdsc);
1354           break;
1355         }
1356       }
1357       if (!exp.More()) {
1358         if (B->IsSplit(fdsc, TopAbs_OUT)) {
1359           for (it2.Initialize(B->Splits(fdsc,TopAbs_OUT));
1360                it2.More();it2.Next()) {
1361             newdsc.Add(it2.Value());
1362           }
1363         }
1364         if (B->IsSplit(fdsc, TopAbs_IN)) {
1365           for (it2.Initialize(B->Splits(fdsc,TopAbs_IN));
1366                it2.More();it2.Next()) {
1367             newdsc.Add(it2.Value());
1368           }
1369         }
1370         if (B->IsSplit(fdsc, TopAbs_ON)) {
1371           for (it2.Initialize(B->Splits(fdsc,TopAbs_ON));
1372                it2.More();it2.Next()) {
1373             newdsc.Add(it2.Value());
1374           }
1375         }
1376         if (B->IsMerged(fdsc, TopAbs_OUT)) {
1377           for (it2.Initialize(B->Merged(fdsc,TopAbs_OUT));
1378                it2.More();it2.Next()) {
1379             newdsc.Add(it2.Value());
1380           }
1381         }
1382         if (B->IsMerged(fdsc, TopAbs_IN)) {
1383           for (it2.Initialize(B->Merged(fdsc,TopAbs_IN));
1384                it2.More();it2.Next()) {
1385             newdsc.Add(it2.Value());
1386           }
1387         }
1388         if (B->IsMerged(fdsc, TopAbs_ON)) {
1389           for (it2.Initialize(B->Merged(fdsc,TopAbs_ON));
1390                it2.More();it2.Next()) {
1391             newdsc.Add(it2.Value());
1392           }
1393         }
1394       }
1395     }
1396     myMap.ChangeFind(orig).Clear();
1397     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1398        // check the appartenance to the shape...
1399       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1400         if (exp.Current().IsSame(itm.Key())) {
1401 //          const TopoDS_Shape& sh = itm.Key();
1402           myMap.ChangeFind(orig).Append(itm.Key());
1403           break;
1404         }
1405       }
1406     }
1407   }
1408 }
1409 //modified by NIZNHY-PKV Thu Mar 21 18:43:18 2002 f
1410 //=======================================================================
1411 //function : UpdateDescendants
1412 //purpose  : 
1413 //=======================================================================
1414   void BRepFeat_Form::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
1415                                         const TopoDS_Shape& S,
1416                                         const Standard_Boolean SkipFace)
1417 {
1418   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1419   TopTools_ListIteratorOfListOfShape it,it2;
1420   TopTools_MapIteratorOfMapOfShape itm;
1421   TopExp_Explorer exp;
1422
1423   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1424     const TopoDS_Shape& orig = itdm.Key();
1425     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1426       continue;
1427     }
1428     TopTools_MapOfShape newdsc;
1429
1430     if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1431
1432     for (it.Initialize(itdm.Value());it.More();it.Next()) {
1433       const TopoDS_Shape& sh = it.Value();
1434       if(sh.ShapeType() != TopAbs_FACE) continue;
1435       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
1436       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1437         if (exp.Current().IsSame(fdsc)) { // preserved
1438           newdsc.Add(fdsc);
1439           break;
1440         }
1441       }
1442       if (!exp.More()) {
1443         BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
1444         const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
1445         it2.Initialize(aLM);
1446         for (; it2.More(); it2.Next()) {
1447           const TopoDS_Shape& aS=it2.Value();
1448           newdsc.Add(aS);
1449         }
1450         
1451       }
1452     }
1453     myMap.ChangeFind(orig).Clear();
1454     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1455        // check the appartenance to the shape...
1456       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1457         if (exp.Current().IsSame(itm.Key())) {
1458 //          const TopoDS_Shape& sh = itm.Key();
1459           myMap.ChangeFind(orig).Append(itm.Key());
1460           break;
1461         }
1462       }
1463     }
1464   }
1465 }
1466 //modified by NIZNHY-PKV Thu Mar 21 18:43:36 2002 t