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