0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / BRepFeat / BRepFeat_RibSlot.cxx
1 // Created on: 1997-10-08
2 // Created by: Olga KOULECHOVA
3 // Copyright (c) 1997-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 <BRepAdaptor_Surface.hxx>
22 #include <BRepAlgo.hxx>
23 #include <BRepAlgoAPI_BooleanOperation.hxx>
24 #include <BRepAlgoAPI_Cut.hxx>
25 #include <BRepAlgoAPI_Fuse.hxx>
26 #include <BRepBndLib.hxx>
27 #include <BRepClass3d_SolidClassifier.hxx>
28 #include <BRepFeat.hxx>
29 #include <BRepFeat_Builder.hxx>
30 #include <BRepFeat_RibSlot.hxx>
31 #include <BRepIntCurveSurface_Inter.hxx>
32 #include <BRepLib.hxx>
33 #include <BRepLib_MakeEdge.hxx>
34 #include <BRepLib_MakeFace.hxx>
35 #include <BRepLib_MakeVertex.hxx>
36 #include <BRepLib_MakeWire.hxx>
37 #include <BRepTools_WireExplorer.hxx>
38 #include <BRepTopAdaptor_FClass2d.hxx>
39 #include <CSLib.hxx>
40 #include <ElCLib.hxx>
41 #include <ElSLib.hxx>
42 #include <Geom2dAPI_InterCurveCurve.hxx>
43 #include <Geom_Circle.hxx>
44 #include <Geom_Curve.hxx>
45 #include <Geom_Ellipse.hxx>
46 #include <Geom_Hyperbola.hxx>
47 #include <Geom_Line.hxx>
48 #include <Geom_Parabola.hxx>
49 #include <Geom_Plane.hxx>
50 #include <Geom_TrimmedCurve.hxx>
51 #include <GeomAdaptor_Curve.hxx>
52 #include <GeomAPI.hxx>
53 #include <GeomAPI_ProjectPointOnCurve.hxx>
54 #include <GeomLib.hxx>
55 #include <gp_Ax1.hxx>
56 #include <gp_Dir.hxx>
57 #include <gp_Pln.hxx>
58 #include <gp_Pnt.hxx>
59 #include <gp_Vec.hxx>
60 #include <LocOpe.hxx>
61 #include <LocOpe_CSIntersector.hxx>
62 #include <LocOpe_FindEdges.hxx>
63 #include <LocOpe_Gluer.hxx>
64 #include <LocOpe_PntFace.hxx>
65 #include <Precision.hxx>
66 #include <Standard_ConstructionError.hxx>
67 #include <Standard_NoSuchObject.hxx>
68 #include <TColGeom_SequenceOfCurve.hxx>
69 #include <TopAbs.hxx>
70 #include <TopExp.hxx>
71 #include <TopExp_Explorer.hxx>
72 #include <TopoDS.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
75 #include <TopoDS_Shape.hxx>
76 #include <TopoDS_Vertex.hxx>
77 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
78 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
79 #include <TopTools_ListIteratorOfListOfShape.hxx>
80 #include <TopTools_ListOfShape.hxx>
81 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 #include <TopTools_MapOfShape.hxx>
83
84 #ifdef OCCT_DEBUG
85 extern Standard_Boolean BRepFeat_GettraceFEAT();
86 extern Standard_Boolean BRepFeat_GettraceFEATRIB();
87 #endif
88
89 //=======================================================================
90 //function : LFPerform
91 //purpose  : topological reconstruction of ribs 
92 //=======================================================================
93
94 void BRepFeat_RibSlot::LFPerform()
95 {
96 #ifdef OCCT_DEBUG
97   Standard_Boolean trc = BRepFeat_GettraceFEAT();
98   if (trc) std::cout << "BRepFeat_RibSlot::LFPerform()" << std::endl;
99 #endif
100   if (mySbase.IsNull() || myPbase.IsNull() || mySkface.IsNull() 
101       || myGShape.IsNull() || myLFMap.IsEmpty()) {
102 #ifdef OCCT_DEBUG
103     std::cout << "Topological reconstruction is impossible" << std::endl;
104     if (trc) std::cout << " Fields not initialized" << std::endl;
105 #endif
106     myStatusError = BRepFeat_NotInitialized;
107     NotDone();
108     return;
109   }
110
111   TopExp_Explorer exp,exp2;
112   Standard_Integer theOpe = 2;
113
114   if (!myGluedF.IsEmpty()) {
115     theOpe = 1;
116   }
117
118       // Hope that there is just a solid in the result
119   if (!mySUntil.IsNull()) {
120     for (exp2.Init(mySUntil,TopAbs_FACE); exp2.More(); exp2.Next()) {
121       const TopoDS_Shape& funtil = exp2.Current();
122       for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
123         if (exp.Current().IsSame(funtil)) {
124           break;
125         }
126       }
127       if (!exp.More()) {
128         break;
129       }
130     }
131   }
132
133   TopTools_ListIteratorOfListOfShape it,it2;
134   TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
135   //Standard_Integer sens = 0;
136
137   LocOpe_Gluer theGlue;
138   
139   //case of gluing 
140
141   if (theOpe == 1) {
142     Standard_Boolean Collage = Standard_True;  
143
144     LocOpe_FindEdges theFE;
145     TopTools_DataMapOfShapeListOfShape locmap;
146     theGlue.Init(mySbase,myGShape);
147     for (itm.Initialize(myGluedF); itm.More();itm.Next()) {
148       const TopoDS_Face& glface = TopoDS::Face(itm.Key());
149       const TopoDS_Face& fac = TopoDS::Face(myGluedF(glface));
150       for (exp.Init(myGShape,TopAbs_FACE); exp.More(); exp.Next()) {
151         if (exp.Current().IsSame(glface)) {
152           break;
153         }
154       }
155       if (exp.More()) {
156         Collage = BRepFeat::IsInside(glface, fac);
157         if(!Collage) {
158           theOpe = 2;
159           break;
160         }
161         else {
162           theGlue.Bind(glface, fac);
163           theFE.Set(glface, fac);
164           for (theFE.InitIterator(); theFE.More();theFE.Next()) {
165             theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
166           }
167         }
168       }
169     }
170   
171     LocOpe_Operation ope = theGlue.OpeType();
172     if (ope == LocOpe_INVALID ||
173         (myFuse && ope != LocOpe_FUSE) ||
174         (!myFuse && ope != LocOpe_CUT) ||
175         (!Collage)) {
176       theOpe = 2;
177 #ifdef OCCT_DEBUG
178       std::cout << "Passage to topological operations" << std::endl;
179 #endif
180     }
181   }
182
183 // gluing is always applicable
184
185   if (theOpe == 1) {
186     theGlue.Perform();
187     if (theGlue.IsDone()) {
188       UpdateDescendants(theGlue);
189       myNewEdges = theGlue.Edges();
190       myTgtEdges = theGlue.TgtEdges();
191       //
192       Done();
193       myShape = theGlue.ResultingShape();
194       BRepLib::SameParameter(myShape, 1.e-7, Standard_True);
195     }
196     else {
197       theOpe = 2;
198 #ifdef OCCT_DEBUG
199       std::cout << "Passage to topologic operation" << std::endl;
200 #endif
201     }
202   }
203
204   // case without gluing
205   if (theOpe == 2) {
206     BRepFeat_Builder theBuilder;
207     TopTools_ListOfShape partsoftool;
208     BRepClass3d_SolidClassifier oussa;
209     Standard_Boolean bFlag;
210     TopTools_ListIteratorOfListOfShape aIt;
211
212     bFlag = (myPerfSelection == BRepFeat_NoSelection) ? 0 : 1;
213     //
214     theBuilder.Init(mySbase, myGShape);
215     theBuilder.SetOperation(myFuse, bFlag);
216     //
217     theBuilder.Perform();
218     if (bFlag) { 
219       theBuilder.PartsOfTool(partsoftool);
220       aIt.Initialize(partsoftool);
221       if (aIt.More() && myPerfSelection != BRepFeat_NoSelection) {
222         Standard_Real toler = (BRep_Tool::Tolerance(myPbase))*2;
223         //
224         for(; aIt.More(); aIt.Next()) {
225           oussa.Load(aIt.Value());
226           oussa.Perform(myFirstPnt, toler);
227           TopAbs_State sp1=oussa.State();
228           oussa.Perform(myLastPnt, toler);
229           TopAbs_State sp2=oussa.State();
230           if (!(sp1 == TopAbs_OUT || sp2 == TopAbs_OUT)) {
231             const TopoDS_Shape& S = aIt.Value();
232             theBuilder.KeepPart(S);
233           }
234         }
235       }
236       //
237       theBuilder.PerformResult();
238       myShape = theBuilder.Shape();
239     } else {
240       myShape = theBuilder.Shape();
241     }
242     Done();
243   }
244 }
245
246 //=======================================================================
247 //function : IsDeleted
248 //purpose  : 
249 //=======================================================================
250
251 Standard_Boolean BRepFeat_RibSlot::IsDeleted(const TopoDS_Shape& F) 
252 {
253   return (myMap(F).IsEmpty());
254 }
255
256
257 //=======================================================================
258 //function : Modified
259 //purpose  : 
260 //=======================================================================
261
262 const TopTools_ListOfShape& BRepFeat_RibSlot::Modified
263    (const TopoDS_Shape& F)
264 {
265 #ifdef OCCT_DEBUG
266   Standard_Boolean trc = BRepFeat_GettraceFEAT();
267   if (trc) std::cout << "BRepFeat_RibSlot::Modified" << std::endl;
268 #endif
269   if (myMap.IsBound(F)) {
270     static TopTools_ListOfShape list;
271     list.Clear();
272     TopTools_ListIteratorOfListOfShape ite(myMap(F));
273     for(; ite.More(); ite.Next()) {
274       const TopoDS_Shape& sh = ite.Value();
275       if(!sh.IsSame(F)) 
276         list.Append(sh);
277     }
278     return list;
279   }
280   return myGenerated; // empty list
281 }
282
283 //=======================================================================
284 //function : Generated
285 //purpose  : 
286 //=======================================================================
287
288 const TopTools_ListOfShape& BRepFeat_RibSlot::Generated
289    (const TopoDS_Shape& S)
290 {
291 #ifdef OCCT_DEBUG
292   Standard_Boolean trc = BRepFeat_GettraceFEAT();
293   if (trc) std::cout << "BRepFeat_RibSlot::Generated" << std::endl;
294 #endif
295   if(S.ShapeType() != TopAbs_FACE) {
296     myGenerated.Clear();
297     if(myLFMap.IsEmpty() || !myLFMap.IsBound(S)) {
298       if (myMap.IsBound(S)) { // check if filter on face or not
299         static TopTools_ListOfShape list;
300         list.Clear();
301         TopTools_ListIteratorOfListOfShape ite(myMap(S));
302         for(; ite.More(); ite.Next()) {
303           const TopoDS_Shape& sh = ite.Value();
304           if(!sh.IsSame(S)) 
305             list.Append(sh);
306         }
307         return list;
308       }
309       else return myGenerated;
310     }
311     else {
312       myGenerated.Clear();
313       TopTools_ListIteratorOfListOfShape it(myLFMap(S));
314       static TopTools_ListOfShape list;
315       list.Clear();
316       for(; it.More(); it.Next()) {
317         if(myMap.IsBound(it.Value())) {
318           TopTools_ListIteratorOfListOfShape it1(myMap(it.Value()));
319           for(; it1.More(); it1.Next()) {
320             const TopoDS_Shape& sh = it1.Value();
321             if(!sh.IsSame(S)) 
322               list.Append(sh);
323           }
324         }
325       }
326       return list;
327     }
328   }
329   else return myGenerated;
330
331
332
333 //=======================================================================
334 //function : UpdateDescendants
335 //purpose  : 
336 //=======================================================================
337
338 void BRepFeat_RibSlot::UpdateDescendants(const LocOpe_Gluer& G)
339 {
340   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
341   TopTools_ListIteratorOfListOfShape it,it2;
342   TopTools_MapIteratorOfMapOfShape itm;
343
344   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
345     const TopoDS_Shape& orig = itdm.Key();
346     TopTools_MapOfShape newdsc;
347     for (it.Initialize(itdm.Value());it.More();it.Next()) {
348       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
349       for (it2.Initialize(G.DescendantFaces(fdsc));
350            it2.More();it2.Next()) {
351         newdsc.Add(it2.Value());
352       }
353     }
354     myMap.ChangeFind(orig).Clear();
355     for (itm.Initialize(newdsc);itm.More();itm.Next()) {
356       myMap.ChangeFind(orig).Append(itm.Key());
357     }
358   }
359 }
360
361
362 //=======================================================================
363 //function : FirstShape
364 //purpose  : 
365 //=======================================================================
366
367 const TopTools_ListOfShape& BRepFeat_RibSlot::FirstShape() const
368 {
369   if (!myFShape.IsNull()) {
370     return myMap(myFShape);
371   }
372   return myGenerated; // empty list
373 }
374
375
376 //=======================================================================
377 //function : LastShape
378 //purpose  : 
379 //=======================================================================
380
381 const TopTools_ListOfShape& BRepFeat_RibSlot::LastShape() const
382 {
383   if (!myLShape.IsNull()) {
384     return myMap(myLShape);
385   }
386   return myGenerated; // empty list
387 }
388
389 //=======================================================================
390 //function : FacesForDraft
391 //purpose  : 
392 //=======================================================================
393
394 const TopTools_ListOfShape& BRepFeat_RibSlot::FacesForDraft() const
395 {
396   return myFacesForDraft;
397 }
398
399
400 //=======================================================================
401 //function : NewEdges
402 //purpose  : 
403 //=======================================================================
404
405 const TopTools_ListOfShape& BRepFeat_RibSlot::NewEdges() const
406 {
407  return myNewEdges;
408 }
409
410 //=======================================================================
411 //function : TgtEdges
412 //purpose  : 
413 //=======================================================================
414
415 const TopTools_ListOfShape& BRepFeat_RibSlot::TgtEdges() const
416 {
417   return myTgtEdges;
418 }
419
420
421 //=======================================================================
422 //function : CurrentStatusError
423 //purpose  : 
424 //=======================================================================
425
426 BRepFeat_StatusError BRepFeat_RibSlot::CurrentStatusError() const
427 {
428   return myStatusError;
429 }
430
431
432 //=======================================================================
433 //function : CheckPoint
434 //purpose  : Proofing point material side (side of extrusion)
435 //=======================================================================
436
437 gp_Pnt BRepFeat_RibSlot::CheckPoint(const TopoDS_Edge& e,
438                                     const Standard_Real ,//bnd,
439                                     const Handle(Geom_Plane)& Pln) 
440
441 {
442 #ifdef OCCT_DEBUG
443   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
444   if (trc) std::cout << "BRepFeat_RibSlot::CheckPoint" << std::endl;
445 #endif
446 // Vector product : normal to plane X direction Wire
447 // -> gives the material side
448 // Proofing point somewhat inside the material side
449   Standard_Real f, l;
450   Handle(Geom_Curve) cc = BRep_Tool::Curve(e, f, l);
451
452   gp_Vec tgt; gp_Pnt pp;
453   Standard_Real par = ( f + l) / 2.;
454   
455   cc->D1(par, pp, tgt);
456
457   if ( e.Orientation() == TopAbs_REVERSED) tgt.Reverse();
458
459   gp_Vec D = -tgt.Crossed(Pln->Pln().Position().Direction())/10.;
460   pp.Translate(D);
461
462   return pp;
463
464 }
465
466
467 //=======================================================================
468 //function : Normal
469 //purpose  : calculate the normal to a face in a point
470 //=======================================================================
471
472 gp_Dir BRepFeat_RibSlot::Normal(const TopoDS_Face& F,const gp_Pnt& P)
473
474 {
475 #ifdef OCCT_DEBUG
476   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
477   if (trc) std::cout << "BRepFeat_RibSlot::Normal" << std::endl;
478 #endif 
479   Standard_Real U, V;
480   gp_Pnt pt;
481
482   BRepAdaptor_Surface AS(F, Standard_True);
483     
484   switch ( AS.GetType()) {
485     
486   case GeomAbs_Plane:
487     ElSLib::Parameters(AS.Plane(),P,U,V); break;
488     
489   case GeomAbs_Cylinder:
490     ElSLib::Parameters(AS.Cylinder(),P,U,V); break;
491
492   case GeomAbs_Cone:
493     ElSLib::Parameters(AS.Cone(),P,U,V); break;
494
495   case GeomAbs_Torus:
496     ElSLib::Parameters(AS.Torus(),P,U,V); break;
497     
498   default:
499     {
500       return gp_Dir(1., 0., 0.);
501     }    
502   }
503
504   gp_Vec D1U, D1V;
505
506   AS.D1(U, V, pt, D1U, D1V);             
507   gp_Dir N;
508   CSLib_DerivativeStatus St;
509   CSLib::Normal(D1U, D1V, Precision::Confusion(), St, N);
510   if(F.Orientation() == TopAbs_FORWARD) N.Reverse();
511   return N;
512 }
513
514 //=======================================================================
515 //function : IntPar
516 //purpose  : calculate the parameter of a point on a curve
517 //=======================================================================
518
519 Standard_Real BRepFeat_RibSlot::IntPar(const Handle(Geom_Curve)& C,
520                                        const gp_Pnt& P)
521
522 {
523   if ( C.IsNull()) return 0.;
524
525   GeomAdaptor_Curve AC(C);
526   Standard_Real U;
527   
528   switch ( AC.GetType()) {
529     
530   case GeomAbs_Line:
531     U = ElCLib::Parameter(AC.Line(),P); break;
532     
533   case GeomAbs_Circle:
534     U = ElCLib::Parameter(AC.Circle(),P); break;
535     
536   case GeomAbs_Ellipse:
537     U = ElCLib::Parameter(AC.Ellipse(),P); break;
538     
539   case GeomAbs_Hyperbola:
540     U = ElCLib::Parameter(AC.Hyperbola(),P); break;
541     
542   case GeomAbs_Parabola:
543     U = ElCLib::Parameter(AC.Parabola(),P); break;
544     
545   default:
546     U = 0.;
547   }
548
549   return U;
550 }
551
552
553 //=======================================================================
554 //function : EdgeExtention
555 //purpose  : extention of a edge by tangence
556 //=======================================================================
557
558 void BRepFeat_RibSlot::EdgeExtention(TopoDS_Edge& e,
559                                      const Standard_Real bnd,
560                                      const Standard_Boolean FirstLast)
561 {
562 #ifdef OCCT_DEBUG
563   Standard_Boolean trc = BRepFeat_GettraceFEAT();
564   if (trc) std::cout << "BRepFeat_RibSlot::EdgeExtention" << std::endl;
565 #endif
566   Standard_Real f, l;
567   Handle(Geom_Curve) cu = BRep_Tool::Curve(e, f, l);
568   Handle(Geom_BoundedCurve) C = 
569     new Geom_TrimmedCurve(cu, f, l);
570
571   TopoDS_Edge E;
572
573   if(cu->DynamicType() == STANDARD_TYPE(Geom_Line) ||
574      cu->DynamicType() == STANDARD_TYPE(Geom_Circle) ||
575      cu->DynamicType() == STANDARD_TYPE(Geom_Ellipse) ||
576      cu->DynamicType() == STANDARD_TYPE(Geom_Hyperbola) ||
577      cu->DynamicType() == STANDARD_TYPE(Geom_Parabola)) {
578     if(FirstLast) {
579       BRepLib_MakeEdge Edg(cu, f-bnd/10., l);      
580       E = TopoDS::Edge(Edg.Shape());
581     }
582     else { 
583       BRepLib_MakeEdge Edg(cu, f, l+bnd/10.); 
584       E = TopoDS::Edge(Edg.Shape());
585     }
586   }
587   else {
588     Handle(Geom_Line) ln;
589     gp_Pnt Pt;
590     gp_Pnt pnt;
591     gp_Vec vct;
592     if(FirstLast) {
593       C->D1(f, pnt, vct);
594       ln = new Geom_Line(pnt, -vct);
595       ln->D0(bnd/1000., Pt); 
596       GeomLib::ExtendCurveToPoint(C, Pt, GeomAbs_G1, Standard_False);
597       BRepLib_MakeEdge Edg(C, Pt, BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True)));
598       E = TopoDS::Edge(Edg.Shape());
599     }
600     else {
601       C->D1(l, pnt, vct);
602       ln = new Geom_Line(pnt, vct);
603       ln->D0(bnd/1000., Pt); 
604       GeomLib::ExtendCurveToPoint(C, Pt, GeomAbs_G1, Standard_True);
605       BRepLib_MakeEdge Edg(C, BRep_Tool::Pnt(TopExp::FirstVertex(e,Standard_True)), Pt);
606       E = TopoDS::Edge(Edg.Shape());
607     }
608   }
609   e = E;
610 }
611
612
613 //=======================================================================
614 //function : ChoiceOfFaces
615 //purpose  : choose face of support in case of support on an edge
616 //=======================================================================
617
618 TopoDS_Face BRepFeat_RibSlot::ChoiceOfFaces(TopTools_ListOfShape& faces,
619                                             const Handle(Geom_Curve)& cc,
620                                             const Standard_Real par,
621                                             const Standard_Real ,//bnd,
622                                             const Handle(Geom_Plane)& Pln)
623
624 {
625 #ifdef OCCT_DEBUG
626   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
627   if (trc) std::cout << "BRepFeat_RibSlot::ChoiceOfFaces" << std::endl;
628 #endif
629   TopoDS_Face FFF;
630
631   gp_Pnt pp;
632   gp_Vec tgt;
633
634   cc->D1(par, pp, tgt);
635
636   Handle(Geom_Line) l1 = new Geom_Line(pp, tgt);
637
638   TColGeom_SequenceOfCurve scur;
639   Standard_Integer Counter = 0;
640   
641
642   gp_Ax1 Axe(pp, Pln->Position().Direction());
643   for ( Standard_Integer i = 1; i <=8; i++) {
644     Handle(Geom_Curve) L = 
645       Handle(Geom_Curve)::DownCast(l1->Rotated(Axe, i*M_PI/9.));
646     scur.Append(L);
647     Counter++;
648   }
649
650   TopTools_ListIteratorOfListOfShape it;
651   it.Initialize(faces);
652   Standard_Real Par = RealLast();
653   for(; it.More(); it.Next()) {
654     const TopoDS_Face& f = TopoDS::Face(it.Value());
655     LocOpe_CSIntersector ASI(f);
656     ASI.Perform(scur);
657     if(!ASI.IsDone()) continue;
658     for(Standard_Integer jj = 1; jj<=Counter; jj++) {
659       if(ASI.NbPoints(jj) >= 1) {
660         Standard_Real app = ASI.Point(jj,1).Parameter();
661         if(app >= 0 &&  app < Par) {
662           Par = app;
663           FFF = f;
664         }
665       }
666     }
667   }
668       
669   return FFF;      
670 }
671
672
673 //=======================================================================
674 //function : HeightMax
675 //purpose  : Calculate the height of the prism following the parameters of a bounding box
676 //=======================================================================
677
678 Standard_Real BRepFeat_RibSlot::HeightMax(const TopoDS_Shape& theSbase,
679                                           const TopoDS_Shape& theSUntil,
680                                           gp_Pnt& p1, 
681                                           gp_Pnt& p2)
682 {
683 #ifdef OCCT_DEBUG
684   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
685   if (trc) std::cout << "BRepFeat_RibSlot::HeightMax" << std::endl;
686 #endif
687   Bnd_Box Box;
688   BRepBndLib::Add(theSbase,Box);
689   if(!theSUntil.IsNull()) {
690     BRepBndLib::Add(theSUntil,Box);
691   }
692   Standard_Real c[6], bnd;
693   Box.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
694   bnd = c[0];
695   for(Standard_Integer i = 0 ; i < 6; i++) {
696     if(c[i] > bnd) bnd = c[i];
697   }
698   p1.SetCoord(c[0]-2.*bnd, c[1]-2.*bnd, c[2]-2.*bnd);
699   p2.SetCoord(c[3]+2.*bnd, c[4]+2.*bnd, c[5]+2.*bnd);
700   return(bnd);
701 }
702
703 //=======================================================================
704 //function : ExtremeFaces
705 //purpose  : Calculate the base faces of the rib
706 //=======================================================================
707
708 Standard_Boolean BRepFeat_RibSlot::ExtremeFaces(const Standard_Boolean RevolRib,
709                                                 const Standard_Real bnd,
710                                                 const Handle(Geom_Plane)& Pln,
711                                                 TopoDS_Edge&   FirstEdge,
712                                                 TopoDS_Edge&   LastEdge,
713                                                 TopoDS_Face&   FirstFace,
714                                                 TopoDS_Face&   LastFace,
715                                                 TopoDS_Vertex& FirstVertex,
716                                                 TopoDS_Vertex& LastVertex, 
717                                                 Standard_Boolean& OnFirstFace,
718                                                 Standard_Boolean& OnLastFace,
719                                                 Standard_Boolean& PtOnFirstEdge,
720                                                 Standard_Boolean& PtOnLastEdge,
721                                                 TopoDS_Edge& OnFirstEdge,
722                                                 TopoDS_Edge& OnLastEdge)
723
724 {
725 #ifdef OCCT_DEBUG
726   Standard_Boolean trc = BRepFeat_GettraceFEAT();
727   if (trc) std::cout << "BRepFeat_RibSlot::ExtremeFaces" << std::endl;
728 #endif
729   Standard_Boolean Data = Standard_True;
730   FirstFace.Nullify();
731   LastFace.Nullify();
732   FirstEdge.Nullify();
733   LastEdge.Nullify();
734   PtOnFirstEdge = Standard_False;
735   PtOnLastEdge = Standard_False;
736   OnFirstEdge.Nullify();
737   OnLastEdge.Nullify();
738
739   BRepIntCurveSurface_Inter inter;
740   BRep_Builder B;
741   TopExp_Explorer ex1;
742
743   Standard_Boolean FirstOK = Standard_False, LastOK = Standard_False;
744
745   Standard_Integer NumberOfEdges = 0;
746   TopExp_Explorer exp(myWire, TopAbs_EDGE);
747   
748   for(; exp.More(); exp.Next()) {
749     NumberOfEdges++;
750   }
751
752 // ---the wire includes only one edge
753   if(NumberOfEdges == 1) {
754 #ifdef OCCT_DEBUG
755     if (trc) std::cout << " One Edge" << std::endl;
756 #endif
757     exp.ReInit();
758     Standard_Real f, l;//, f1, l1, temp;
759     gp_Pnt firstpoint, lastpoint;
760    
761 // Points limit the unique edge
762     const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
763     Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
764     gp_Pnt p1 = BRep_Tool::Pnt(TopExp::FirstVertex(E,Standard_True));
765     gp_Pnt p2 = BRep_Tool::Pnt(TopExp::LastVertex(E,Standard_True));
766
767     Standard_Real FirstPar = f; Standard_Real LastPar = l;
768
769
770 // ---Find if 2 points limiting the unique edge of the wire
771 //    are on an edge or a vertex of the base shape
772     Standard_Boolean PtOnFirstVertex = Standard_False; 
773     Standard_Boolean PtOnLastVertex = Standard_False;
774     TopoDS_Vertex OnFirstVertex, OnLastVertex;
775     PtOnEdgeVertex(RevolRib, mySbase, p1, FirstVertex, LastVertex,
776                    PtOnFirstEdge, OnFirstEdge, PtOnFirstVertex, OnFirstVertex);
777     PtOnEdgeVertex(RevolRib, mySbase, p2, FirstVertex, LastVertex,
778                    PtOnLastEdge, OnLastEdge, PtOnLastVertex, OnLastVertex);
779
780     TopTools_MapOfShape Map;
781
782     if(PtOnFirstEdge) {
783       if (!PtOnFirstVertex) {
784 // Find FirstFace : face of the base shape containing OnFirstEdge
785 //                  meeting ChoiceOfFaces
786         TopExp_Explorer ex4, ex5;
787         ex4.Init(mySbase, TopAbs_FACE);
788         TopTools_ListOfShape faces;
789         faces.Clear();
790         Map.Clear();
791         for(; ex4.More(); ex4.Next()) {
792           const TopoDS_Face& fx = TopoDS::Face(ex4.Current());
793           if ( !Map.Add(fx)) continue;
794           ex5.Init(ex4.Current(), TopAbs_EDGE);
795           for(; ex5.More(); ex5.Next()) {
796             const TopoDS_Edge& ee = TopoDS::Edge(ex5.Current()); 
797             if(ee.IsSame(OnFirstEdge)) {
798               faces.Append(fx);
799             }
800           }
801         }
802         if(!faces.IsEmpty())  {
803           TopoDS_Face FFF = ChoiceOfFaces(faces, cc, FirstPar+bnd/50., bnd/50., Pln);
804           if(!FFF.IsNull()) FirstFace = FFF;
805         }
806       }
807       else if(PtOnFirstVertex) {
808 // Find FirstFace : face of the base shape containing OnFirstVertex
809 //                  meeting ChoiceOfFaces
810         TopExp_Explorer ex4, ex5;
811         ex4.Init(mySbase, TopAbs_FACE);
812         TopTools_ListOfShape faces;
813         faces.Clear();
814         Map.Clear();
815         for(; ex4.More(); ex4.Next()) {
816           const TopoDS_Face& fx = TopoDS::Face(ex4.Current());
817           if ( !Map.Add(fx)) continue;
818           ex5.Init(ex4.Current(), TopAbs_VERTEX);
819           for(; ex5.More(); ex5.Next()) {
820             const TopoDS_Vertex& vv = TopoDS::Vertex(ex5.Current()); 
821             if(vv.IsSame(OnFirstVertex)) {
822               faces.Append(fx);
823               break;
824             }
825           }
826         }
827         if(!faces.IsEmpty())  {
828           TopoDS_Face FFF = ChoiceOfFaces(faces, cc, FirstPar+bnd/50., bnd/50., Pln);
829           if(!FFF.IsNull()) FirstFace = FFF;
830         }
831       }
832       FirstEdge = E;
833       BRepLib_MakeVertex v(p1);
834       FirstVertex = v;
835       OnFirstFace = Standard_True;
836     }
837
838     if(PtOnLastEdge) {
839       if (!PtOnLastVertex) {
840 // Find LastFace : face of the base shape containing OnLastEdge
841 //                 meeting ChoiceOfFaces
842         TopExp_Explorer ex4, ex5;
843         ex4.Init(mySbase, TopAbs_FACE);
844         TopTools_ListOfShape faces;
845         faces.Clear();
846         Map.Clear();
847         for(; ex4.More(); ex4.Next()) {
848           const TopoDS_Face& fx = TopoDS::Face(ex4.Current());
849           if ( !Map.Add(fx)) continue;
850           ex5.Init(ex4.Current(), TopAbs_EDGE);
851           for(; ex5.More(); ex5.Next()) {
852             const TopoDS_Edge& ee = TopoDS::Edge(ex5.Current()); 
853             if(ee.IsSame(OnLastEdge)) {
854               faces.Append(fx);
855               break;
856             }
857           }
858         }
859         if(!faces.IsEmpty())  {
860           TopoDS_Face FFF = ChoiceOfFaces(faces, cc, LastPar-bnd/50., bnd/50., Pln);
861           if(!FFF.IsNull()) LastFace = FFF;
862         }
863       }
864       else if(PtOnLastEdge && PtOnLastVertex) {
865 // Find LastFace : face of the base shape containing OnLastVertex
866 //                 meeting ChoiceOfFaces
867         TopExp_Explorer ex4, ex5;
868         ex4.Init(mySbase, TopAbs_FACE);
869         TopTools_ListOfShape faces;
870         faces.Clear();
871         Map.Clear();
872         for(; ex4.More(); ex4.Next()) {
873           const TopoDS_Face& fx = TopoDS::Face(ex4.Current());
874           if ( !Map.Add(fx)) continue;
875           ex5.Init(ex4.Current(), TopAbs_VERTEX);
876           for(; ex5.More(); ex5.Next()) {
877             const TopoDS_Vertex& vv = TopoDS::Vertex(ex5.Current()); 
878             if(vv.IsSame(OnLastVertex)) {
879               faces.Append(fx);
880               break;
881             }
882           }
883         }
884         if(!faces.IsEmpty())  {
885           TopoDS_Face FFF = ChoiceOfFaces(faces, cc, LastPar-bnd/50., bnd/50., Pln);
886           if(!FFF.IsNull()) LastFace = FFF;
887         }
888       }
889       LastEdge = E;
890       BRepLib_MakeVertex v(p2);
891       LastVertex = v;
892       OnLastFace = Standard_True;
893     }
894     
895     if(!FirstFace.IsNull() && !LastFace.IsNull())  {
896       return Standard_True;
897     }
898
899 //--- FirstFace or LastFace was not found
900 #ifdef OCCT_DEBUG
901     if (trc) std::cout << " FirstFace or LastFace null" << std::endl;
902 #endif
903     LocOpe_CSIntersector ASI(mySbase);
904     TColGeom_SequenceOfCurve scur;
905     scur.Clear();
906     scur.Append(cc);
907     ASI.Perform(scur);
908     Standard_Real lastpar, firstpar;
909     if(ASI.IsDone() && ASI.NbPoints(1) >= 2) {
910       lastpar = ASI.Point(1, ASI.NbPoints(1)).Parameter();
911       Standard_Integer lastindex = ASI.NbPoints(1);
912       if(lastpar > l) {
913         for(Standard_Integer jj=ASI.NbPoints(1)-1; jj>=1; jj--) {
914           Standard_Real par = ASI.Point(1,jj).Parameter();
915           if(par <= l) {
916             lastpar = par;
917             lastindex = jj;
918             break;
919           }
920         }
921       } 
922       Standard_Integer firstindex = lastindex -1;      
923       firstpar = ASI.Point(1,firstindex).Parameter();
924
925       if(FirstFace.IsNull()) {
926         FirstFace = ASI.Point(1, firstindex).Face();
927         cc->D0(firstpar, firstpoint);
928         BRepLib_MakeVertex v1(firstpoint);
929         FirstVertex = TopoDS::Vertex(v1.Shape());
930         FirstEdge = E;
931       }
932
933       if(LastFace.IsNull()) {      
934         LastFace = ASI.Point(1, lastindex).Face();
935         cc->D0(lastpar, lastpoint);
936         BRepLib_MakeVertex v2(lastpoint);
937         LastVertex = TopoDS::Vertex(v2.Shape());
938         LastEdge = E;
939       }
940     }
941     else {
942 #ifdef OCCT_DEBUG
943       if (trc) std::cout << " Less than 2 intersection points" << std::endl;
944 #endif
945       Data = Standard_False;
946       return Data;
947     }
948
949     if(!OnFirstFace) {
950       if(p1.Distance(firstpoint) <= Precision::Confusion()) 
951         OnFirstFace = Standard_True;
952       else OnFirstFace = Standard_False;
953     }
954     
955     if(!OnLastFace) {
956       if(p2.Distance(lastpoint) <= Precision::Confusion()) 
957         OnLastFace = Standard_True;
958       else OnLastFace = Standard_False;      
959     }
960
961     if(FirstFace.IsNull() || LastFace.IsNull()) {
962 #ifdef OCCT_DEBUG
963       if (trc) std::cout << " First or Last Faces still null" << std::endl;
964 #endif
965       Data = Standard_False;
966     }
967     else {
968 #ifdef OCCT_DEBUG
969       if (trc) std::cout << " FirstFace and LastFace OK" << std::endl;
970 #endif
971       Data = Standard_True;
972     }
973     
974     return Data;
975   }
976 // ---The wire consists of several edges
977   else {
978 #ifdef OCCT_DEBUG
979     if (trc) std::cout << " Multiple Edges" << std::endl;
980 #endif
981     BRepTools_WireExplorer ex(myWire);
982     for(; ex.More(); ex.Next()) {
983       const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
984       Standard_Real f, l;
985       Handle(Geom_Curve) Cur = BRep_Tool::Curve(E, f, l);
986       f = f - bnd/10000; l = l +bnd/10000;
987       Handle(Geom_TrimmedCurve) curve;
988       curve = new Geom_TrimmedCurve(Cur, f, l, Standard_True);
989 #ifdef OCCT_DEBUG
990       gp_Pnt P1 = BRep_Tool::Pnt(TopExp::FirstVertex(E,Standard_True)); (void)P1;
991 #endif
992       gp_Pnt P2 = BRep_Tool::Pnt(TopExp::LastVertex(E,Standard_True));
993       ex1.Init(mySbase, TopAbs_FACE);
994       TopoDS_Vertex theVertex;
995       TopoDS_Edge theEdge;
996       TopoDS_Face theFace;
997       Standard_Boolean PtOnEdge = Standard_False;
998       Standard_Boolean PtOnVertex = Standard_False;
999       TopoDS_Edge OnEdge; 
1000       TopoDS_Vertex OnVertex;
1001       Standard_Real intpar;
1002       for(; ex1.More(); ex1.Next()) {
1003         const TopoDS_Face& aCurFace = TopoDS::Face(ex1.Current());
1004         GeomAdaptor_Curve aGAC (curve);
1005         inter.Init (aCurFace, aGAC, BRep_Tool::Tolerance(aCurFace));
1006         if(!inter.More()) continue;
1007         for(; inter.More(); inter.Next()) {
1008           gp_Pnt thePoint = inter.Pnt();
1009           if(!FirstVertex.IsNull()) {
1010             gp_Pnt point = BRep_Tool::Pnt(FirstVertex);
1011             if(point.Distance(thePoint) <= BRep_Tool::Tolerance(aCurFace)) {
1012               continue;
1013             }
1014           }
1015           intpar = IntPar(curve, thePoint);
1016           theEdge = E;
1017           theFace = aCurFace;
1018           B.MakeVertex(theVertex, thePoint, Precision::Confusion());       
1019           if(!FirstOK) {
1020             if(thePoint.Distance(P2) <= Precision::Confusion()) {
1021               continue;
1022             }
1023           }
1024
1025 // ---Find thepoint on an edge or a vertex of face f
1026           PtOnEdgeVertex(RevolRib, aCurFace, thePoint, FirstVertex, LastVertex,
1027                          PtOnEdge,OnEdge,PtOnVertex,OnVertex);
1028
1029
1030 //          if(!theEdge.IsNull()) break;
1031
1032           if (FirstEdge.IsNull() && !theEdge.IsNull() &&
1033               !theFace.IsNull() && !theVertex.IsNull()) {
1034             FirstEdge = theEdge;
1035             FirstFace = theFace;
1036             FirstVertex = theVertex;
1037             PtOnFirstEdge = PtOnEdge;
1038             OnFirstEdge = OnEdge;
1039             theEdge.Nullify(); theFace.Nullify(); theVertex.Nullify();
1040             if(PtOnEdge && !PtOnVertex) {
1041               TopTools_ListOfShape faces;
1042               faces.Clear();
1043               faces.Append(FirstFace);
1044               TopExp_Explorer ex2;
1045               ex2.Init(mySbase, TopAbs_FACE);
1046               for(; ex2.More(); ex2.Next()) {
1047                 TopoDS_Face fx = TopoDS::Face(ex2.Current());
1048                 TopExp_Explorer ex3;
1049                 ex3.Init(fx, TopAbs_EDGE);
1050                 for(; ex3.More(); ex3.Next()) {
1051                   const TopoDS_Edge& e = TopoDS::Edge(ex3.Current());
1052                   if(e.IsSame(OnEdge) && !fx.IsSame(FirstFace)) {
1053                     faces.Append(fx);
1054                   }
1055                 }
1056               }
1057               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar+bnd/10., bnd/10., Pln);
1058               if(!FFF.IsNull()) FirstFace = FFF;
1059             }
1060             else if(PtOnEdge && PtOnVertex) {
1061               TopTools_ListOfShape faces;
1062               faces.Clear();
1063               faces.Append(FirstFace);
1064               TopExp_Explorer ex2;
1065               ex2.Init(mySbase, TopAbs_FACE);
1066               for(; ex2.More(); ex2.Next()) {
1067                 TopoDS_Face fx = TopoDS::Face(ex2.Current());
1068                 TopExp_Explorer ex3;
1069                 ex3.Init(fx, TopAbs_VERTEX);
1070                 for(; ex3.More(); ex3.Next()) {
1071                   const TopoDS_Vertex& v = TopoDS::Vertex(ex3.Current());
1072                   if(v.IsSame(OnVertex) && !fx.IsSame(FirstFace)) {
1073                     faces.Append(fx);
1074                   }
1075                 }
1076               }
1077               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar+bnd/10., bnd/10.,  Pln);
1078               if(!FFF.IsNull()) FirstFace = FFF;
1079             }
1080             if(!FirstEdge.IsNull() && !FirstFace.IsNull() 
1081              && !FirstVertex.IsNull()) {
1082               FirstOK = Standard_True;
1083             }
1084           }
1085           if(LastEdge.IsNull() && !theEdge.IsNull() &&
1086              !theFace.IsNull() && !theVertex.IsNull() && 
1087              !FirstEdge.IsNull()) {
1088             LastEdge = theEdge;
1089             LastFace = theFace;
1090             LastVertex = theVertex;
1091             PtOnLastEdge = PtOnEdge;
1092             OnLastEdge = OnEdge; 
1093             if(PtOnEdge && !PtOnVertex) {
1094               TopTools_ListOfShape faces;
1095               faces.Clear();
1096               faces.Append(LastFace);
1097               TopExp_Explorer ex2;
1098               ex2.Init(mySbase, TopAbs_FACE);
1099               for(; ex2.More(); ex2.Next()) {
1100                 TopoDS_Face fx = TopoDS::Face(ex2.Current());
1101                 TopExp_Explorer ex3;
1102                 ex3.Init(fx, TopAbs_EDGE);
1103                 for(; ex3.More(); ex3.Next()) {
1104                   const TopoDS_Edge& e = TopoDS::Edge(ex3.Current());
1105                   if(e.IsSame(OnEdge) && !fx.IsSame(LastFace)) {
1106                     faces.Append(fx);
1107                   }
1108                 }
1109               }
1110               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar-bnd/10.,bnd/10.,  Pln);
1111               if(!FFF.IsNull()) LastFace = FFF;          
1112             }
1113             else if(PtOnEdge && PtOnVertex) {
1114               TopTools_ListOfShape faces;
1115               faces.Clear();
1116               faces.Append(LastFace);
1117               TopExp_Explorer ex2;
1118               ex2.Init(mySbase, TopAbs_FACE);
1119               for(; ex2.More(); ex2.Next()) {
1120                 TopoDS_Face fx = TopoDS::Face(ex2.Current());
1121                 TopExp_Explorer ex3;
1122                 ex3.Init(fx, TopAbs_VERTEX);
1123                 for(; ex3.More(); ex3.Next()) {
1124                   const TopoDS_Vertex& v = TopoDS::Vertex(ex3.Current());
1125                   if(v.IsSame(OnVertex) && !fx.IsSame(LastFace)) {
1126                     faces.Append(fx);
1127                   }
1128                 }
1129               }
1130               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar-bnd/10.,bnd/10.,  Pln);
1131               if(!FFF.IsNull()) LastFace = FFF;
1132             }
1133             if(!LastEdge.IsNull() && !LastFace.IsNull() 
1134                && !LastVertex.IsNull()) {
1135               LastOK = Standard_True;
1136             }
1137             break;     
1138           }
1139         }
1140       }
1141     }
1142     
1143     if(FirstOK && LastOK)  {
1144       Data = Standard_True;
1145       gp_Pnt PP1 = BRep_Tool::Pnt(TopExp::FirstVertex(FirstEdge,Standard_True));
1146       gp_Pnt PP2 = BRep_Tool::Pnt(TopExp::LastVertex(LastEdge,Standard_True));
1147       gp_Pnt p1 = BRep_Tool::Pnt(FirstVertex);
1148       gp_Pnt p2 = BRep_Tool::Pnt(LastVertex);
1149       if(p1.Distance(PP1) <= BRep_Tool::Tolerance(FirstFace)) {
1150         OnFirstFace = Standard_True;
1151       }
1152       if(p2.Distance(PP2) <= BRep_Tool::Tolerance(LastFace)) {
1153         OnLastFace = Standard_True;
1154       }     
1155       return Standard_True;
1156     }
1157     else {
1158 #ifdef OCCT_DEBUG
1159       if (trc) std::cout << " First or Last not OK" << std::endl;
1160 #endif
1161       return Standard_False;
1162     }
1163   }
1164 }
1165
1166
1167 //=======================================================================
1168 //function : PtOnEdgeVertex
1169 //purpose  : Find if 2 limit points of the unique edge of a wire
1170 //           are on an edge or a vertex of the base shape
1171 //=======================================================================
1172
1173 void BRepFeat_RibSlot::PtOnEdgeVertex(const Standard_Boolean RevolRib,
1174                                       const TopoDS_Shape& shape,
1175                                       const gp_Pnt& point,
1176                                       const TopoDS_Vertex& ,//FirstVertex,
1177                                       const TopoDS_Vertex& ,//LastVertex,
1178                                       Standard_Boolean& PtOnEdge,
1179                                       TopoDS_Edge& OnEdge,
1180                                       Standard_Boolean& PtOnVertex,
1181                                       TopoDS_Vertex& OnVertex)
1182      
1183 {
1184 #ifdef OCCT_DEBUG
1185   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
1186   if (trc) std::cout << "BRepFeat_RibSlot::PtOnEdgeVertex" << std::endl;
1187 #endif
1188   Standard_Boolean TestOK;
1189 //  PtOnEdge = Standard_False;
1190 //  OnEdge.Nullify();
1191 //  PtOnVertex = Standard_False;
1192 //  OnVertex.Nullify();
1193
1194   TopExp_Explorer EXP;
1195   EXP.Init(shape, TopAbs_EDGE);
1196   TopTools_MapOfShape Map;
1197   for(; EXP.More(); EXP.Next()) {
1198     const TopoDS_Edge& e = TopoDS::Edge(EXP.Current());
1199     if ( !Map.Add(e)) continue;
1200     if (!RevolRib) {
1201       if (BRep_Tool::Degenerated(e)) continue;
1202     }
1203     Standard_Real fff, lll;
1204     Handle(Geom_Curve) ccc = BRep_Tool::Curve(e, fff, lll);
1205     if (!RevolRib) {
1206       ccc = new Geom_TrimmedCurve(ccc, fff, lll);
1207     }
1208     GeomAPI_ProjectPointOnCurve proj(point, ccc);
1209     TestOK = Standard_False;
1210     if (!RevolRib) {
1211       if(proj.NbPoints() == 1) TestOK = Standard_True;
1212     } 
1213     else {
1214       if(proj.NbPoints() >= 1) TestOK = Standard_True;
1215     }
1216     if(TestOK && proj.Distance(1) <= BRep_Tool::Tolerance(e)) {
1217       PtOnEdge = Standard_True;
1218       OnEdge = e;            
1219       TopoDS_Vertex ev1 = TopExp::FirstVertex(e,Standard_True);
1220       TopoDS_Vertex ev2 = TopExp::LastVertex(e,Standard_True);
1221       gp_Pnt ep1 = BRep_Tool::Pnt(ev1);
1222       gp_Pnt ep2 = BRep_Tool::Pnt(ev2);
1223       if(point.Distance(ep1) <= BRep_Tool::Tolerance(ev1)) {
1224         PtOnVertex = Standard_True;
1225         OnVertex = ev1;
1226         break;
1227       }
1228       else if(point.Distance(ep2) <= BRep_Tool::Tolerance(ev1)) {
1229         PtOnVertex = Standard_True;
1230         OnVertex = ev2;
1231         break;
1232       }        
1233       break;
1234     }
1235   } 
1236 }
1237
1238
1239 //=======================================================================
1240 //function : SlidingProfile
1241 //purpose  : construction of the profile face in case of sliding
1242 //=======================================================================
1243  
1244 Standard_Boolean BRepFeat_RibSlot::SlidingProfile(TopoDS_Face& Prof,
1245                                                   const Standard_Boolean RevolRib,
1246                                                   const Standard_Real myTol,
1247                                                   Standard_Integer& Concavite,
1248                                                   const Handle(Geom_Plane)& myPln,
1249                                                   const TopoDS_Face& BndFace,
1250                                                   const gp_Pnt& CheckPnt,
1251                                                   const TopoDS_Face& FirstFace,
1252                                                   const TopoDS_Face& LastFace,
1253                                                   const TopoDS_Vertex& ,//FirstVertex,
1254                                                   const TopoDS_Vertex& ,//LastVertex,
1255                                                   const TopoDS_Edge& FirstEdge,
1256                                                   const TopoDS_Edge& LastEdge)
1257      
1258 {
1259 #ifdef OCCT_DEBUG
1260   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1261   if (trc) std::cout << "BRepFeat_RibSlot::SlidingProfile" << std::endl;
1262 #endif
1263   Standard_Boolean ProfileOK = Standard_True;
1264 // --case of sliding : construction of the wire of the profile
1265 // --> 1 part bounding box + 1 part wire
1266 //   attention to the compatibility of orientations
1267
1268   gp_Dir FN, LN;
1269   BRepLib_MakeWire WW;
1270   
1271   FN = Normal(FirstFace, myFirstPnt);
1272   LN = Normal(LastFace, myLastPnt);
1273
1274 // Case of the groove (cut) <> rib (fuse)
1275 // -> we are in the material
1276 // -> make everything in 2d in the working plane : easier  
1277   if(!myFuse) {
1278     FN = -FN;
1279     LN = -LN;
1280   }
1281   
1282   
1283   Handle(Geom_Line) ln1, ln2;
1284   gp_Pnt  Pt;//,p1, p2;
1285   
1286   ln2 = new Geom_Line(myFirstPnt, FN);
1287   ln1 = new Geom_Line(myLastPnt, LN);
1288   
1289   Handle(Geom2d_Curve) ln2d1 = GeomAPI::To2d(ln1, myPln->Pln());
1290   Handle(Geom2d_Curve) ln2d2 = GeomAPI::To2d(ln2, myPln->Pln());
1291   
1292   Geom2dAPI_InterCurveCurve inter(ln2d1, ln2d2, Precision::Confusion());
1293     
1294   Standard_Boolean TestOK = Standard_True;
1295   if (RevolRib) {
1296     gp_Dir d1, d2;
1297     d1 = ln1->Position().Direction();
1298     d2 = ln2->Position().Direction();
1299     if(d1.IsOpposite(d2, myTol)) {
1300       Standard_Real par1 = ElCLib::Parameter(ln1->Lin(), myFirstPnt);
1301       Standard_Real par2 = ElCLib::Parameter(ln2->Lin(), myLastPnt);
1302       if(par1 >= myTol  ||  par2 >= myTol)  {
1303         Concavite = 2;    //paralel and concave
1304         BRepLib_MakeEdge e1(myLastPnt, myFirstPnt);
1305         WW.Add(e1);
1306       } 
1307     } 
1308     if(d1.IsEqual(d2, myTol)) {
1309        if(Concavite == 3) TestOK = Standard_False;
1310     }
1311   }
1312   
1313   if(TestOK) {
1314     if(inter.NbPoints() > 0) {
1315       gp_Pnt2d P = inter.Point(1);
1316       myPln->D0(P.X(), P.Y(), Pt);
1317       Standard_Real par = IntPar(ln1, Pt);
1318       if(par>0) Concavite = 1;    //concave
1319     }
1320   }
1321
1322 // ---Construction of the profile face 
1323   if(Concavite == 1) {
1324 // if concave : it is possible to extend first and last edges of the wire
1325 //              to the bounding box
1326     BRepLib_MakeEdge e1(myLastPnt, Pt);
1327     WW.Add(e1);
1328     BRepLib_MakeEdge e2(Pt, myFirstPnt);
1329     WW.Add(e2);
1330   }
1331   else if(Concavite == 3) {
1332 // BndEdge : edges of intersection with the bounding box
1333     TopoDS_Edge BndEdge1, BndEdge2;
1334 // Points of intersection with the bounding box / Find Profile
1335     gp_Pnt BndPnt1, BndPnt2, LastPnt;
1336     TopExp_Explorer expl;
1337     expl.Init(BndFace, TopAbs_WIRE);
1338     BRepTools_WireExplorer explo;
1339     TopoDS_Wire BndWire = TopoDS::Wire(expl.Current());
1340     explo.Init(BndWire);
1341     for(; explo.More(); explo.Next()) {
1342       const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1343       Standard_Real first, last;
1344       Handle(Geom_Curve) c = BRep_Tool::Curve(e, first, last);
1345       Handle(Geom2d_Curve) c2d = GeomAPI::To2d(c, myPln->Pln());
1346       Geom2dAPI_InterCurveCurve intcln1(ln2d1, c2d, 
1347                                         Precision::Confusion());
1348       if(intcln1.NbPoints() > 0) {
1349         gp_Pnt2d p2d = intcln1.Point(1);
1350         gp_Pnt p;
1351         myPln->D0(p2d.X(), p2d.Y(), p);
1352         Standard_Real parl = IntPar(ln1, p);
1353         Standard_Real parc = IntPar(c, p);
1354         if(parc >= first && parc <= last && parl >= 0) {
1355           BndEdge1 = e;
1356           BndPnt1 = p;
1357         }
1358       }
1359       
1360       Geom2dAPI_InterCurveCurve intcln2(ln2d2, c2d, 
1361                                         Precision::Confusion());
1362       if(intcln2.NbPoints() > 0) {
1363         gp_Pnt2d p2d = intcln2.Point(1);
1364         gp_Pnt p;
1365         myPln->D0(p2d.X(), p2d.Y(), p);
1366         Standard_Real parl = IntPar(ln2, p);
1367         Standard_Real parc = IntPar(c, p);
1368         if(parc >= first && parc <= last && parl >= 0) {
1369           BndEdge2 = e;
1370           BndPnt2 = p;
1371         }
1372       }
1373       if(!BndEdge1.IsNull() && !BndEdge2.IsNull()) break;
1374     }
1375     
1376     if(BndEdge1.IsNull() || BndEdge2.IsNull())  {
1377 #ifdef OCCT_DEBUG
1378       if (trc) std::cout << " Null bounding edge" << std::endl;
1379 #endif
1380       ProfileOK = Standard_False;
1381       return ProfileOK;
1382     }
1383     
1384     
1385     BRepLib_MakeEdge e1(myLastPnt, BndPnt1);
1386     WW.Add(e1);
1387     
1388     if(BndEdge1.IsSame(BndEdge2)) {
1389 // Particular case : same edge -> simply determined path
1390       BRepLib_MakeEdge e2(BndPnt1, BndPnt2);
1391       WW.Add(e2);
1392       BRepLib_MakeEdge e3(BndPnt2, myFirstPnt);
1393       WW.Add(e3);        
1394     }
1395     else {
1396       explo.Init(BndWire);
1397       for(; explo.More(); explo.Next()) {
1398         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1399         if(e.IsSame(BndEdge1)) {
1400           gp_Pnt pp;
1401           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));
1402           if(pp.Distance(BndPnt1) >= BRep_Tool::Tolerance(e)) {
1403             LastPnt = pp;
1404           }
1405 //            else {         //LinearForm
1406 //              gp_Pnt ppp = BRep_Tool::Pnt(TopExp::FirstVertex(e,Standard_True));
1407 //              LastPnt = ppp;
1408 //            }
1409           BRepLib_MakeEdge e2(BndPnt1, LastPnt);
1410           WW.Add(e2);
1411           break;        
1412         }
1413       }
1414       
1415       if(explo.More()) {
1416         explo.Next();
1417         if(explo.Current().IsNull()) explo.Init(BndWire);
1418       }
1419       else explo.Init(BndWire);
1420
1421 // Check if this is BndEdge2
1422 // -> if yes : it is required to turn to join FirstPnt
1423 // -> if no : add edges
1424       Standard_Boolean Fin = Standard_False;
1425       while(!Fin) {
1426         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1427         if(!e.IsSame(BndEdge2)) {
1428           gp_Pnt pp;
1429           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));  
1430           BRepLib_MakeEdge ee(LastPnt, pp);
1431           WW.Add(ee);
1432           LastPnt = pp;
1433         }
1434         else {
1435 // the path is closed
1436 // -> since met BndEdge2, end of borders on BndFace
1437           Fin = Standard_True;
1438           BRepLib_MakeEdge ee(LastPnt, BndPnt2);
1439           WW.Add(ee);
1440           LastPnt = BndPnt2;
1441         }
1442         if(explo.More()) {
1443           explo.Next();
1444           if(explo.Current().IsNull()) {
1445             explo.Init(BndWire);
1446           }
1447         }
1448         else explo.Init(BndWire);
1449       }
1450       
1451       BRepLib_MakeEdge e3(BndPnt2, myFirstPnt);
1452       WW.Add(e3);
1453     }   
1454   }
1455
1456 // ---Construction of the profile
1457
1458 // Explore the wire provided by the user
1459 // BRepTools_WireExplorer : correct order - without repetition <> TopExp : non ordered
1460   BRepTools_WireExplorer EX(myWire);
1461   
1462   Standard_Real ff, ll;
1463   Handle(Geom_Curve) FirstCurve = BRep_Tool::Curve(FirstEdge, ff, ll);
1464   
1465   if(!FirstEdge.IsSame(LastEdge)) {
1466     TopoDS_Vertex FLVert = TopExp::LastVertex(FirstEdge,Standard_True);
1467     gp_Pnt FLPnt = BRep_Tool::Pnt(FLVert);
1468     BRepLib_MakeEdge ef(FirstCurve, myFirstPnt, FLPnt);
1469     WW.Add(ef);   
1470     for(; EX.More(); EX.Next()) {
1471       const TopoDS_Edge& E = EX.Current();
1472       if(E.IsSame(FirstEdge))        break;
1473     }      
1474     EX.Next();
1475     for(; EX.More(); EX.Next()) {
1476       const TopoDS_Edge& E = EX.Current();
1477       if(!E.IsSame(LastEdge)) {
1478         WW.Add(E);
1479       }        
1480       else break;
1481     }
1482     Handle(Geom_Curve) LastCurve = BRep_Tool::Curve(LastEdge, ff, ll);
1483     TopoDS_Vertex LFVert = TopExp::FirstVertex(LastEdge,Standard_True);
1484     gp_Pnt LFPnt = BRep_Tool::Pnt(LFVert);
1485     BRepLib_MakeEdge el(LastCurve, LFPnt, myLastPnt);
1486     WW.Add(el);
1487   }
1488   else {
1489 // only one edge : particular processing
1490     Standard_Real fpar = IntPar(FirstCurve, myFirstPnt);
1491     Standard_Real lpar = IntPar(FirstCurve, myLastPnt);
1492     Handle(Geom_Curve) c;
1493     if(fpar > lpar) 
1494       c = FirstCurve->Reversed();
1495     else 
1496       c = FirstCurve;
1497     
1498     BRepLib_MakeEdge ef(c, myFirstPnt, myLastPnt);
1499     WW.Add(ef);
1500   }
1501   
1502   BRepLib_MakeFace f(myPln->Pln(), WW, Standard_True);
1503   TopoDS_Face fac = TopoDS::Face(f.Shape());
1504     
1505   if (!BRepAlgo::IsValid(fac)) {
1506 #ifdef OCCT_DEBUG
1507     if (trc) std::cout << " Invalid Face" << std::endl;
1508 #endif
1509     ProfileOK = Standard_False;
1510     return ProfileOK;
1511   }
1512   
1513   if(Concavite != 3) {
1514 // if concave : face is OK
1515     Prof = fac;
1516   }
1517   else {
1518 // if not concave
1519 // CheckPnt : point slightly inside the material side
1520 // Bndface  : face/cut of the bounding box in the plane of the profile
1521     BRepTopAdaptor_FClass2d Cl(fac, BRep_Tool::Tolerance(fac));
1522     Standard_Real u, v;
1523     ElSLib::Parameters(myPln->Pln(), CheckPnt, u, v);
1524     gp_Pnt2d checkpnt2d(u, v);
1525     if(Cl.Perform(checkpnt2d, Standard_True) == TopAbs_OUT) {
1526 // If face is not the correct part of BndFace take the complementary
1527       BRepAlgoAPI_Cut c(BndFace, fac);     
1528       TopExp_Explorer exp(c.Shape(), TopAbs_WIRE);
1529       const TopoDS_Wire& w = TopoDS::Wire(exp.Current());
1530       BRepLib_MakeFace ffx(w);
1531       Prof = TopoDS::Face(ffx.Shape());
1532     }
1533     else {
1534 // If face is the correct part of BndFace  : face is OK
1535       Prof = fac;
1536     }
1537   }
1538   
1539   if (!BRepAlgo::IsValid(Prof)) {
1540 #ifdef OCCT_DEBUG
1541     if (trc) std::cout << " Invalid Face Profile" << std::endl;
1542 #endif
1543     ProfileOK = Standard_False;
1544     return ProfileOK;    
1545   }
1546   return ProfileOK;
1547 }
1548 //=======================================================================
1549 //function : NoSlidingProfile
1550 //purpose  : construction of the face profile in case of sliding
1551 //=======================================================================
1552  
1553 Standard_Boolean BRepFeat_RibSlot::NoSlidingProfile(TopoDS_Face& Prof,
1554                                                     const Standard_Boolean RevolRib,
1555                                                     const Standard_Real myTol,
1556                                                     Standard_Integer& Concavite,
1557                                                     const Handle(Geom_Plane)& myPln,
1558                                                     const Standard_Real bnd,
1559                                                     const TopoDS_Face& BndFace,
1560                                                     const gp_Pnt& CheckPnt,
1561                                                     const TopoDS_Face& ,//FirstFace,
1562                                                     const TopoDS_Face& ,//LastFace,
1563                                                     const TopoDS_Vertex& ,//FirstVertex,
1564                                                     const TopoDS_Vertex& ,//LastVertex,
1565                                                     const TopoDS_Edge& FirstEdge,
1566                                                     const TopoDS_Edge& LastEdge,
1567                                                     const Standard_Boolean OnFirstFace,
1568                                                     const Standard_Boolean OnLastFace)
1569      
1570 {
1571 #ifdef OCCT_DEBUG
1572   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1573   if (trc) std::cout << "BRepFeat_RibSlot::NoSlidingProfile" << std::endl;
1574 #endif
1575   Standard_Boolean ProfileOK = Standard_True;
1576
1577   Standard_Real l1, f1, f2, l2;//, p;        
1578   TopoDS_Vertex theFV; theFV.Nullify();
1579   gp_Pnt theFirstpoint;
1580   TopoDS_Edge theLastEdge; theLastEdge.Nullify();
1581   gp_Pnt firstpoint, lastpoint;//, pp1, pp2;
1582   gp_Vec firstvect, lastvect; 
1583   TopoDS_Wire w;
1584   BRep_Builder BB;
1585   BB.MakeWire(w);
1586   //gp_Pnt p1, p3;
1587   TopoDS_Edge FalseFirstEdge, FalseLastEdge, FalseOnlyOne;
1588   
1589   Handle(Geom_Curve) FirstCurve = BRep_Tool::Curve(FirstEdge, f1, l1);
1590   Handle(Geom_Curve) LastCurve = BRep_Tool::Curve(LastEdge, f2, l2);
1591
1592   Handle(Geom_Line) firstln, lastln;  
1593   FirstCurve->D1(f1, firstpoint, firstvect);
1594   lastln = new Geom_Line(firstpoint, -firstvect);
1595   LastCurve->D1(l2, lastpoint, lastvect);
1596   firstln = new Geom_Line(lastpoint, lastvect);
1597   
1598   gp_Pnt Pt;
1599   
1600   Handle(Geom2d_Curve) ln2d1 = GeomAPI::To2d(firstln, myPln->Pln());
1601   Handle(Geom2d_Curve) ln2d2 = GeomAPI::To2d(lastln, myPln->Pln());
1602   
1603   Geom2dAPI_InterCurveCurve inter(ln2d1, ln2d2, Precision::Confusion());
1604
1605   Standard_Boolean TestOK = Standard_True;
1606   if (RevolRib) {
1607     gp_Dir d1, d2;
1608     d1 = firstln->Position().Direction();
1609     d2 = lastln->Position().Direction();
1610     if(d1.IsOpposite(d2, myTol)) {
1611       Standard_Real par1 = ElCLib::Parameter(firstln->Lin(), myFirstPnt);
1612       Standard_Real par2 = ElCLib::Parameter(lastln->Lin(), myLastPnt);
1613       if(par1 >= myTol  ||  par2 >= myTol)  
1614         Concavite = 2;    //parallel and concave
1615     }      
1616     if(d1.IsEqual(d2, myTol)) {
1617        if(Concavite == 3) TestOK = Standard_False;
1618     }
1619   }
1620   
1621   if(TestOK) {
1622     if(inter.NbPoints() > 0) {
1623       gp_Pnt2d P = inter.Point(1);
1624       myPln->D0(P.X(), P.Y(), Pt);
1625       Standard_Real par = IntPar(firstln, Pt);
1626       if(par>0) Concavite = 1;    //concave
1627     }
1628   }
1629
1630 // ---Construction of the face profile  
1631   if(Concavite == 3) {
1632     if(OnFirstFace) {
1633       Standard_Real f, l;
1634       FalseFirstEdge = FirstEdge;
1635       EdgeExtention(FalseFirstEdge, bnd, Standard_True);
1636       const TopoDS_Vertex& vv1 = TopExp::FirstVertex(FalseFirstEdge,Standard_True);
1637       firstpoint = BRep_Tool::Pnt(vv1);
1638       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseFirstEdge, f, l);
1639       cc->D1(f, firstpoint, firstvect);
1640       lastln = new Geom_Line(firstpoint, -firstvect);
1641       if(FirstEdge.IsSame(LastEdge)) FalseOnlyOne = FalseFirstEdge;         
1642       ln2d2 = GeomAPI::To2d(lastln, myPln->Pln());
1643     }
1644     if(OnLastFace) {
1645       Standard_Real f, l;
1646       if(!FirstEdge.IsSame(LastEdge)) {
1647         FalseLastEdge = LastEdge;
1648       }
1649       else {
1650         if(FalseOnlyOne.IsNull()) FalseOnlyOne = LastEdge;
1651         FalseLastEdge = FalseOnlyOne;
1652       }
1653       EdgeExtention(FalseLastEdge, bnd, Standard_False);
1654       if(FirstEdge.IsSame(LastEdge)) {
1655         FalseOnlyOne = FalseLastEdge;
1656       }
1657       const TopoDS_Vertex& vv2 = TopExp::LastVertex(FalseLastEdge,Standard_True);
1658       lastpoint = BRep_Tool::Pnt(vv2);
1659       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseLastEdge, f, l);
1660       cc->D1(l, lastpoint, lastvect);
1661       lastpoint = BRep_Tool::Pnt(vv2);
1662       firstln = new Geom_Line(lastpoint, lastvect);
1663       ln2d1 = GeomAPI::To2d(firstln, myPln->Pln());
1664     }
1665     
1666     TopoDS_Edge BndEdge1, BndEdge2;
1667     gp_Pnt BndPnt1, BndPnt2, LastPnt;
1668     TopExp_Explorer expl;
1669     expl.Init(BndFace, TopAbs_WIRE);
1670     BRepTools_WireExplorer explo;
1671     TopoDS_Wire BndWire = TopoDS::Wire(expl.Current());
1672     explo.Init(BndWire);
1673     for(; explo.More(); explo.Next()) {
1674       const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1675       Standard_Real first, last;
1676       Handle(Geom_Curve) c = BRep_Tool::Curve(e, first, last);
1677       Handle(Geom2d_Curve) c2d = GeomAPI::To2d(c, myPln->Pln());
1678       Geom2dAPI_InterCurveCurve intcln1(ln2d1, c2d, 
1679                                         Precision::Confusion());
1680       if(intcln1.NbPoints() > 0) {
1681         gp_Pnt2d p2d = intcln1.Point(1);
1682         gp_Pnt p;
1683         myPln->D0(p2d.X(), p2d.Y(), p);
1684         Standard_Real parl = IntPar(firstln, p);
1685         Standard_Real parc = IntPar(c, p);
1686         if(parc >= first && parc <= last && parl >= 0) {
1687           BndEdge1 = e;
1688           BndPnt1 = p;
1689         }
1690       }
1691       
1692       Geom2dAPI_InterCurveCurve intcln2(ln2d2, c2d, 
1693                                         Precision::Confusion());
1694       if(intcln2.NbPoints() > 0) {
1695         gp_Pnt2d p2d = intcln2.Point(1);
1696         gp_Pnt p;
1697         myPln->D0(p2d.X(), p2d.Y(), p);
1698         Standard_Real parl = IntPar(lastln, p);
1699         Standard_Real parc = IntPar(c, p);
1700         if(parc >= first && parc <= last && parl >= 0) {
1701           BndEdge2 = e;
1702           BndPnt2 = p;
1703         }
1704       }
1705       if(!BndEdge1.IsNull() && !BndEdge2.IsNull()) break;
1706     }
1707     
1708     if(BndEdge1.IsNull() || BndEdge2.IsNull())  {
1709 #ifdef OCCT_DEBUG
1710       if (trc) std::cout << " Null bounding edge" << std::endl;
1711 #endif
1712       ProfileOK = Standard_False;
1713       return ProfileOK;
1714     }
1715     
1716     TopoDS_Edge ee1;
1717     if(theLastEdge.IsNull()) {
1718       BRepLib_MakeEdge e1(lastpoint, BndPnt1);
1719       ee1 = TopoDS::Edge(e1.Shape());
1720     }
1721     else {
1722       const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1723       BRepLib_MakeVertex v2(BndPnt1);
1724       BRepLib_MakeEdge e1(v1, v2);
1725       ee1 = TopoDS::Edge(e1.Shape());
1726     }
1727     BB.Add(w, ee1);
1728     theLastEdge = ee1;
1729     if(theFV.IsNull()) {
1730       theFV = TopExp::FirstVertex(ee1,Standard_True);
1731       theFirstpoint = BRep_Tool::Pnt(theFV);
1732     }
1733     
1734     if(BndEdge1.IsSame(BndEdge2)) {
1735       TopoDS_Edge ee2, ee3;
1736       if(theLastEdge.IsNull()) {
1737         BRepLib_MakeEdge e2(BndPnt1, BndPnt2);
1738         ee2 = TopoDS::Edge(e2.Shape());
1739       }
1740       else {
1741         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1742         BRepLib_MakeVertex v2(BndPnt2);
1743         BRepLib_MakeEdge e2(v1, v2);
1744         ee2 = TopoDS::Edge(e2.Shape());
1745       }
1746       BB.Add(w, ee2);
1747       theLastEdge = ee2;
1748       if(theFV.IsNull()) {
1749         theFV = TopExp::FirstVertex(ee2,Standard_True);
1750         theFirstpoint = BRep_Tool::Pnt(theFV);
1751       }
1752       if(theLastEdge.IsNull()) {
1753         BRepLib_MakeEdge e3(BndPnt2, firstpoint);
1754         ee3 = TopoDS::Edge(e3.Shape());        
1755       }
1756       else {
1757         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1758         BRepLib_MakeVertex v2(firstpoint);
1759         BRepLib_MakeEdge e3(v1, v2);
1760         ee3 = TopoDS::Edge(e3.Shape());
1761       }
1762       BB.Add(w, ee3);        
1763       theLastEdge = ee3;
1764       if(theFV.IsNull()) {
1765         theFV = TopExp::FirstVertex(ee3,Standard_True);
1766         theFirstpoint = BRep_Tool::Pnt(theFV);
1767       }
1768     }
1769     else {
1770       explo.Init(BndWire);
1771       for(; explo.More(); explo.Next()) {
1772         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1773         if(e.IsSame(BndEdge1)) {
1774           gp_Pnt pp;
1775           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));
1776           if(pp.Distance(BndPnt1) > BRep_Tool::Tolerance(e)) {
1777             LastPnt = pp;
1778           }
1779           TopoDS_Edge eee;
1780           if(theLastEdge.IsNull()) {
1781             BRepLib_MakeEdge e2(BndPnt1, LastPnt);
1782             eee = TopoDS::Edge(e2.Shape());
1783           }
1784           else {
1785             const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1786             BRepLib_MakeVertex v2(LastPnt);
1787             BRepLib_MakeEdge e2(v1, v2);
1788             eee = TopoDS::Edge(e2.Shape());
1789           }
1790           BB.Add(w, eee);
1791           theLastEdge = eee;
1792           if(theFV.IsNull()) {
1793             theFV = TopExp::FirstVertex(eee,Standard_True);
1794             theFirstpoint = BRep_Tool::Pnt(theFV);
1795           }
1796           break;        
1797         }
1798       }
1799       
1800       if(explo.More()) {
1801         explo.Next();
1802         if(explo.Current().IsNull()) explo.Init(BndWire);
1803       }
1804       else explo.Init(BndWire);
1805       Standard_Boolean Fin = Standard_False;
1806       while(!Fin) {
1807         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1808         if(!e.IsSame(BndEdge2)) {
1809           gp_Pnt pp;
1810           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));
1811           TopoDS_Edge eee1;
1812           if(theLastEdge.IsNull()) {
1813             BRepLib_MakeEdge ee(LastPnt, pp);
1814             eee1 = TopoDS::Edge(ee.Shape());
1815           }
1816           else {
1817             const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1818             BRepLib_MakeVertex v2(pp);
1819             BRepLib_MakeEdge ee(v1, v2);
1820             eee1 = TopoDS::Edge(ee.Shape());
1821           }
1822           BB.Add(w, eee1);
1823           theLastEdge = eee1;
1824           if(theFV.IsNull()) {
1825             theFV = TopExp::FirstVertex(eee1,Standard_True);
1826             theFirstpoint = BRep_Tool::Pnt(theFV);
1827           }
1828           LastPnt = pp;
1829         }
1830         else {
1831           Fin = Standard_True;
1832           TopoDS_Edge eee2;
1833           if(theLastEdge.IsNull()) {
1834             BRepLib_MakeEdge ee(LastPnt, BndPnt2);
1835             eee2 = TopoDS::Edge(ee.Shape());
1836           }
1837           else {
1838             const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1839             BRepLib_MakeVertex v2(BndPnt2);
1840             BRepLib_MakeEdge ee(v1, v2);
1841             eee2 = TopoDS::Edge(ee.Shape());
1842           }
1843           BB.Add(w, eee2);
1844           theLastEdge = eee2;
1845           if(theFV.IsNull()) {
1846             theFV = TopExp::FirstVertex(eee2,Standard_True);
1847             theFirstpoint = BRep_Tool::Pnt(theFV);
1848           }
1849           LastPnt = BndPnt2;
1850         }
1851         if(explo.More()) {
1852           explo.Next();
1853           if(explo.Current().IsNull()) {
1854             explo.Init(BndWire);
1855           }
1856         }
1857         else explo.Init(BndWire);
1858       }
1859       
1860       TopoDS_Edge eee3;
1861       if(theLastEdge.IsNull()) {
1862         BRepLib_MakeEdge e3(BndPnt2, firstpoint);
1863         eee3 = TopoDS::Edge(e3.Shape());
1864       }
1865       else {
1866         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1867         BRepLib_MakeVertex v2(firstpoint);
1868         BRepLib_MakeEdge e3(v1, v2);
1869         eee3 = TopoDS::Edge(e3.Shape());
1870       }
1871       BB.Add(w, eee3);
1872       theLastEdge = eee3;
1873       if(theFV.IsNull()) {
1874         theFV = TopExp::FirstVertex(eee3,Standard_True);
1875         theFirstpoint = BRep_Tool::Pnt(theFV);
1876       }
1877     }   
1878   }
1879  
1880   if(Concavite == 1) {
1881     TopoDS_Edge eee4;
1882     if(theLastEdge.IsNull()) {
1883       BRepLib_MakeEdge  e(Pt, firstpoint); 
1884       eee4 = TopoDS::Edge(e.Shape());      
1885     }
1886     else {
1887       const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1888       BRepLib_MakeVertex v2(firstpoint);
1889       BRepLib_MakeEdge e(v1, v2);
1890       eee4 = TopoDS::Edge(e.Shape());
1891     }
1892     BB.Add(w, eee4);
1893     if(theFV.IsNull()) {
1894       theFV = TopExp::FirstVertex(eee4,Standard_True);
1895       theFirstpoint = BRep_Tool::Pnt(theFV);
1896     }
1897     theLastEdge = eee4;
1898   }
1899   
1900   
1901   if(FirstEdge.IsSame(LastEdge)) {
1902     if(!myLFMap.IsBound(FirstEdge)) {
1903       TopTools_ListOfShape thelist;
1904       myLFMap.Bind(FirstEdge, thelist);
1905     }
1906     if(OnFirstFace || OnLastFace) {
1907       TopoDS_Edge theEdge;
1908       Standard_Real f, l;
1909       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseOnlyOne, f, l);
1910       if(!theLastEdge.IsNull()) {
1911         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1912         TopoDS_Vertex v2;
1913         const gp_Pnt& pp = BRep_Tool::
1914           Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
1915         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
1916           v2 = theFV;
1917         }
1918         else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);
1919         BRepLib_MakeEdge e(cc, v1, v2);
1920         theEdge = TopoDS::Edge(e.Shape());
1921       }
1922       else {
1923         const TopoDS_Vertex& v1 = TopExp::FirstVertex(FalseOnlyOne,Standard_True);
1924         TopoDS_Vertex v2;
1925         const gp_Pnt& pp = BRep_Tool::
1926           Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
1927         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
1928           v2 = theFV;
1929         }
1930         else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);                  
1931         BRepLib_MakeEdge e(cc, v1, v2);
1932         theEdge = TopoDS::Edge(e.Shape());
1933       }
1934       myLFMap(FirstEdge).Append(theEdge);
1935       BB.Add(w, theEdge);
1936       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
1937       theLastEdge = theEdge;
1938     }
1939     else {
1940       Standard_Real f, l;
1941       Handle(Geom_Curve) cc = BRep_Tool::Curve(FirstEdge, f, l);
1942       TopoDS_Edge theEdge;
1943       if(!theLastEdge.IsNull()) {
1944         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1945         TopoDS_Vertex v2;
1946 // Attention case Wire Reversed -> LastVertex without Standard_True
1947         const gp_Pnt& pp = BRep_Tool::Pnt(TopExp::LastVertex(FirstEdge));
1948         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
1949           v2 = theFV;
1950         }
1951         else v2 = TopExp::LastVertex(FirstEdge);
1952         BRepLib_MakeEdge e(cc, v1, v2);
1953         theEdge = TopoDS::Edge(e.Shape());
1954       }
1955       else {
1956         const TopoDS_Vertex& v1 = TopExp::FirstVertex(FirstEdge,Standard_True);
1957         TopoDS_Vertex v2;
1958         const gp_Pnt& pp = BRep_Tool::
1959           Pnt(TopExp::LastVertex(FirstEdge,Standard_True));
1960         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
1961           v2 = theFV;
1962         }
1963         else v2 = TopExp::LastVertex(FirstEdge,Standard_True);
1964         BRepLib_MakeEdge e(cc, v1, v2);
1965         theEdge = TopoDS::Edge(e.Shape());
1966       }
1967       myLFMap(FirstEdge).Append(theEdge);
1968       BB.Add(w, theEdge); 
1969       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
1970       theLastEdge = theEdge;
1971     }
1972   }
1973   else {
1974     if(!myLFMap.IsBound(FirstEdge)) {
1975       TopTools_ListOfShape thelist1;
1976       myLFMap.Bind(FirstEdge, thelist1);
1977     }
1978     if(!OnFirstFace) {
1979       TopoDS_Edge theEdge;
1980       Standard_Real f, l;
1981       Handle(Geom_Curve) cc = BRep_Tool::Curve(FirstEdge, f, l);
1982       if(!theLastEdge.IsNull()) {
1983         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1984         const TopoDS_Vertex& v2 = TopExp::LastVertex(FirstEdge,Standard_True);
1985         BRepLib_MakeEdge e(cc, v1, v2);
1986         theEdge = TopoDS::Edge(e.Shape());          
1987       }
1988       else {
1989         theEdge = FirstEdge;
1990       }
1991       myLFMap(FirstEdge).Append(theEdge);
1992       BB.Add(w, theEdge); 
1993       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
1994       theLastEdge = theEdge;
1995     }
1996     else {
1997       TopoDS_Edge theEdge;
1998       Standard_Real f, l;
1999       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseFirstEdge, f, l);
2000       if(!theLastEdge.IsNull()) {
2001         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2002         const TopoDS_Vertex& v2 = TopExp::LastVertex(FalseFirstEdge,Standard_True);
2003         BRepLib_MakeEdge e(cc, v1, v2);
2004         theEdge = TopoDS::Edge(e.Shape());          
2005       }
2006       else {
2007         theEdge = FalseFirstEdge;
2008       }
2009       myLFMap(FirstEdge).Append(theEdge);
2010       BB.Add(w, theEdge); 
2011       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
2012       theLastEdge = theEdge;
2013     }
2014
2015     BRepTools_WireExplorer ex(myWire);
2016     for(; ex.More(); ex.Next()) {
2017       const TopoDS_Edge& E = ex.Current();
2018       if(E.IsSame(FirstEdge)) break;
2019     }
2020     
2021     ex.Next();
2022     
2023     for(; ex.More(); ex.Next()) {
2024       const TopoDS_Edge& E = ex.Current();
2025       if(!E.IsSame(LastEdge)) {
2026         if(!myLFMap.IsBound(E)) {
2027           TopTools_ListOfShape thelist2;
2028           myLFMap.Bind(E, thelist2);
2029         }
2030         TopoDS_Edge eee;
2031         Standard_Real f, l;
2032         Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
2033         if(!theLastEdge.IsNull()) {
2034           const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2035           const TopoDS_Vertex& v2 = TopExp::LastVertex(E,Standard_True);
2036           BRepLib_MakeEdge e(cc, v1, v2);
2037           eee = TopoDS::Edge(e.Shape());          
2038         }
2039         else {
2040           eee = E;
2041         }
2042         myLFMap(E).Append(eee);
2043         BB.Add(w, eee);
2044         if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2045         theLastEdge = eee;
2046       }
2047       else break;
2048     }
2049     
2050     
2051     if(!OnLastFace) {
2052       if(!FirstEdge.IsSame(LastEdge)) {
2053         const TopoDS_Edge& edg = TopoDS::Edge(ex.Current()); 
2054         if(!myLFMap.IsBound(edg)) {
2055           TopTools_ListOfShape thelist3;
2056           myLFMap.Bind(edg, thelist3);
2057         }
2058         TopoDS_Edge eee;
2059         Standard_Real f, l;
2060         Handle(Geom_Curve) cc = BRep_Tool::Curve(edg, f, l);
2061         if(!theLastEdge.IsNull()) {
2062           const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2063           TopoDS_Vertex v2;
2064           const gp_Pnt& pp = BRep_Tool::
2065             Pnt(TopExp::LastVertex(edg,Standard_True));
2066           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2067             v2 = theFV;
2068           }
2069           else v2 = TopExp::LastVertex(edg,Standard_True);
2070           BRepLib_MakeEdge e(cc, v1, v2);
2071           eee = TopoDS::Edge(e.Shape());          
2072         }
2073         else {
2074           const TopoDS_Vertex& v1 = TopExp::FirstVertex(edg,Standard_True);
2075           TopoDS_Vertex v2;
2076           const gp_Pnt& pp = BRep_Tool::
2077             Pnt(TopExp::LastVertex(edg,Standard_True));
2078           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2079             v2 = theFV;
2080           }
2081           else v2 = TopExp::LastVertex(edg,Standard_True);
2082           BRepLib_MakeEdge e(cc, v1, v2);
2083           eee = TopoDS::Edge(e.Shape());          
2084         }
2085         myLFMap(edg).Append(eee);
2086         BB.Add(w, eee);
2087         if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2088         theLastEdge = eee;
2089       }
2090       else {
2091         TopoDS_Edge eee;
2092         Standard_Real f, l;
2093         if(!myLFMap.IsBound(LastEdge)) {
2094           TopTools_ListOfShape thelist4;
2095           myLFMap.Bind(LastEdge, thelist4);
2096         }
2097         Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseOnlyOne, f, l);
2098         if(!theLastEdge.IsNull()) {
2099           const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2100           TopoDS_Vertex v2;
2101           const gp_Pnt& pp = BRep_Tool::
2102             Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
2103           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2104             v2 = theFV;
2105           }
2106           else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);
2107           BRepLib_MakeEdge e(cc, v1, v2);
2108           eee = TopoDS::Edge(e.Shape());          
2109         }          
2110         else {
2111           const TopoDS_Vertex& v1 = TopExp::FirstVertex(FalseOnlyOne,Standard_True);
2112           TopoDS_Vertex v2;
2113           const gp_Pnt& pp = BRep_Tool::
2114             Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
2115           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2116             v2 = theFV;
2117           }
2118           else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);
2119           BRepLib_MakeEdge e(cc, v1, v2);
2120           eee = TopoDS::Edge(e.Shape());          
2121         }
2122         myLFMap(LastEdge).Append(eee);
2123         BB.Add(w, eee);
2124         if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2125         theLastEdge = eee;
2126       }
2127     }
2128     else {
2129       TopoDS_Edge eee;
2130       Standard_Real f, l;
2131       if(!myLFMap.IsBound(LastEdge)) {
2132         TopTools_ListOfShape thelist5;
2133         myLFMap.Bind(LastEdge, thelist5);
2134       }
2135       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseLastEdge, f, l);
2136       if(!theLastEdge.IsNull()) {
2137         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2138         TopoDS_Vertex v2;
2139         const gp_Pnt& pp = BRep_Tool::
2140           Pnt(TopExp::LastVertex(FalseLastEdge,Standard_True));
2141         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2142           v2 = theFV;
2143         }
2144         else v2 = TopExp::LastVertex(FalseLastEdge,Standard_True);
2145         BRepLib_MakeEdge e(cc, v1, v2);
2146         eee = TopoDS::Edge(e.Shape());          
2147       }          
2148       else {
2149         const TopoDS_Vertex& v1 = TopExp::FirstVertex(FalseLastEdge,Standard_True);
2150         TopoDS_Vertex v2;
2151         const gp_Pnt& pp = BRep_Tool::
2152           Pnt(TopExp::LastVertex(FalseLastEdge,Standard_True));
2153         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2154           v2 = theFV;
2155         }
2156         else v2 = TopExp::LastVertex(FalseLastEdge,Standard_True);
2157         BRepLib_MakeEdge e(cc, v1, v2);
2158         eee = TopoDS::Edge(e.Shape());          
2159       }
2160       myLFMap(LastEdge).Append(eee);
2161       BB.Add(w, eee);
2162       if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2163       theLastEdge = eee;
2164     }
2165   }
2166   
2167   if(Concavite == 1)  {
2168     TopoDS_Edge eef;
2169     if(theLastEdge.IsNull()) {        
2170       BRepLib_MakeEdge ef(lastpoint, Pt);
2171       eef = TopoDS::Edge(ef.Shape());
2172     }
2173     else {
2174       const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2175       BRepLib_MakeVertex vv(Pt);
2176       TopoDS_Vertex v2 = TopoDS::Vertex(vv.Shape());
2177       if(!theFV.IsNull() && 
2178          Pt.Distance(theFirstpoint) <= myTol) v2 = theFV;
2179       
2180       BRepLib_MakeEdge ef(v1, v2);
2181       eef = TopoDS::Edge(ef.Shape());        
2182     }
2183     BB.Add(w, eef);
2184     if(theFV.IsNull()) theFV = TopExp::FirstVertex(eef,Standard_True);
2185     theLastEdge = eef;
2186   }
2187   
2188   if(Concavite == 2) {
2189     BRepLib_MakeEdge ee(lastpoint, firstpoint);
2190     const TopoDS_Edge& e = ee.Edge();
2191     BB.Add(w, e);
2192   }
2193   
2194   w.Closed (BRep_Tool::IsClosed (w));
2195   BRepLib_MakeFace fa(myPln->Pln(), w, Standard_True);
2196   TopoDS_Face fac = TopoDS::Face(fa.Shape());
2197   
2198   if (!BRepAlgo::IsValid(fac)) {
2199 #ifdef OCCT_DEBUG
2200     if (trc) std::cout << " Invalid Face" << std::endl;
2201 #endif
2202     ProfileOK = Standard_False;
2203     return ProfileOK;
2204   }
2205   
2206 //    if(!Concavite) {
2207   if(Concavite == 3) {
2208     BRepTopAdaptor_FClass2d Cl(fac, BRep_Tool::Tolerance(fac));
2209     Standard_Real u, v;
2210     ElSLib::Parameters(myPln->Pln(), CheckPnt, u, v);
2211     gp_Pnt2d checkpnt2d(u, v);
2212     if(Cl.Perform(checkpnt2d, Standard_True) == TopAbs_OUT) {
2213       BRepAlgoAPI_Cut c(BndFace, fac);     
2214       TopExp_Explorer exp(c.Shape(), TopAbs_WIRE);
2215       UpdateDescendants(c, c.Shape(), Standard_False);
2216       const TopoDS_Wire& ww = TopoDS::Wire(exp.Current());
2217       BRepLib_MakeFace ff(ww);
2218       Prof = TopoDS::Face(ff.Shape());
2219     }
2220     else {
2221       Prof = fac;
2222     }
2223   }
2224   else {
2225     Prof = fac;
2226   }  
2227
2228   if (!BRepAlgo::IsValid(Prof)) {
2229 #ifdef OCCT_DEBUG
2230     if (trc) std::cout << " Invalid Face Profile" << std::endl;
2231 #endif
2232     ProfileOK = Standard_False;
2233     return ProfileOK;
2234   }
2235   return ProfileOK;
2236 }
2237
2238 //=======================================================================
2239 //function : UpdateDescendants
2240 //purpose  : 
2241 //=======================================================================
2242   void BRepFeat_RibSlot::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
2243                                            const TopoDS_Shape& S,
2244                                            const Standard_Boolean SkipFace)
2245 {
2246   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
2247   TopTools_ListIteratorOfListOfShape it,it2;
2248   TopTools_MapIteratorOfMapOfShape itm;
2249   TopExp_Explorer exp;
2250
2251   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
2252     const TopoDS_Shape& orig = itdm.Key();
2253     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
2254       continue;
2255     }
2256     TopTools_MapOfShape newdsc;
2257
2258     //if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
2259
2260     for (it.Initialize(itdm.Value());it.More();it.Next()) {
2261       const TopoDS_Shape& sh = it.Value();
2262       if(sh.ShapeType() != TopAbs_FACE) continue;
2263       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
2264       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
2265         if (exp.Current().IsSame(fdsc)) { // preserved
2266           newdsc.Add(fdsc);
2267           break;
2268         }
2269       }
2270       if (!exp.More()) {
2271         BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
2272         const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
2273         it2.Initialize(aLM);
2274         for (; it2.More(); it2.Next()) {
2275           const TopoDS_Shape& aS=it2.Value();
2276           newdsc.Add(aS);
2277         }
2278         
2279       }
2280     }
2281     myMap.ChangeFind(orig).Clear();
2282     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
2283        // check the belonging to the shape...
2284       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
2285         if (exp.Current().IsSame(itm.Key())) {
2286 //          const TopoDS_Shape& sh = itm.Key();
2287           myMap.ChangeFind(orig).Append(itm.Key());
2288           break;
2289         }
2290       }
2291     }
2292   }
2293 }