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