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