0024023: Revamp the OCCT Handle -- ambiguity
[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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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_BoundedCurve) 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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
1066       if (trc) cout << " First or Last Faces still null" << endl;
1067 #endif
1068       Data = Standard_False;
1069     }
1070     else {
1071 #ifdef OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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         GeomAdaptor_Curve aGAC (curve);
1109         inter.Init (f, aGAC, BRep_Tool::Tolerance(f));
1110         if(!inter.More()) continue;
1111         for(; inter.More(); inter.Next()) {
1112           gp_Pnt thePoint = inter.Pnt();
1113           if(!FirstVertex.IsNull()) {
1114             gp_Pnt point = BRep_Tool::Pnt(FirstVertex);
1115             if(point.Distance(thePoint) <= BRep_Tool::Tolerance(f)) {
1116               continue;
1117             }
1118           }
1119           intpar = IntPar(curve, thePoint);
1120           theEdge = E;
1121           theFace = f;
1122           B.MakeVertex(theVertex, thePoint, Precision::Confusion());       
1123           if(!FirstOK) {
1124             if(thePoint.Distance(P2) <= Precision::Confusion()) {
1125               continue;
1126             }
1127           }
1128
1129 // ---Find thepoint on an edge or a vertex of face f
1130           PtOnEdgeVertex(RevolRib, f, thePoint, FirstVertex, LastVertex,
1131                          PtOnEdge,OnEdge,PtOnVertex,OnVertex);
1132
1133
1134 //          if(!theEdge.IsNull()) break;
1135
1136           if (FirstEdge.IsNull() && !theEdge.IsNull() &&
1137               !theFace.IsNull() && !theVertex.IsNull()) {
1138             FirstEdge = theEdge;
1139             FirstFace = theFace;
1140             FirstVertex = theVertex;
1141             PtOnFirstEdge = PtOnEdge;
1142             OnFirstEdge = OnEdge;
1143             theEdge.Nullify(); theFace.Nullify(); theVertex.Nullify();
1144             if(PtOnEdge && !PtOnVertex) {
1145               TopTools_ListOfShape faces;
1146               faces.Clear();
1147               faces.Append(FirstFace);
1148               TopExp_Explorer ex2;
1149               ex2.Init(mySbase, TopAbs_FACE);
1150               for(; ex2.More(); ex2.Next()) {
1151                 TopoDS_Face fx = TopoDS::Face(ex2.Current());//modified by NIZNHY-PKV Fri Mar 22 17:16:44 2002 fx/f
1152                 TopExp_Explorer ex3;
1153                 ex3.Init(fx, TopAbs_EDGE);
1154                 for(; ex3.More(); ex3.Next()) {
1155                   const TopoDS_Edge& e = TopoDS::Edge(ex3.Current());
1156                   if(e.IsSame(OnEdge) && !fx.IsSame(FirstFace)) {
1157                     faces.Append(fx);
1158                   }
1159                 }
1160               }
1161               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar+bnd/10., bnd/10., Pln);
1162               if(!FFF.IsNull()) FirstFace = FFF;
1163             }
1164             else if(PtOnEdge && PtOnVertex) {
1165               TopTools_ListOfShape faces;
1166               faces.Clear();
1167               faces.Append(FirstFace);
1168               TopExp_Explorer ex2;
1169               ex2.Init(mySbase, TopAbs_FACE);
1170               for(; ex2.More(); ex2.Next()) {
1171                 TopoDS_Face fx = TopoDS::Face(ex2.Current());//modified by NIZNHY-PKV Fri Mar 22 17:13:08 2002 fx/f
1172                 TopExp_Explorer ex3;
1173                 ex3.Init(fx, TopAbs_VERTEX);
1174                 for(; ex3.More(); ex3.Next()) {
1175                   const TopoDS_Vertex& v = TopoDS::Vertex(ex3.Current());
1176                   if(v.IsSame(OnVertex) && !fx.IsSame(FirstFace)) {
1177                     faces.Append(fx);
1178                   }
1179                 }
1180               }
1181               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar+bnd/10., bnd/10.,  Pln);
1182               if(!FFF.IsNull()) FirstFace = FFF;
1183             }
1184             if(!FirstEdge.IsNull() && !FirstFace.IsNull() 
1185              && !FirstVertex.IsNull()) {
1186               FirstOK = Standard_True;
1187             }
1188           }
1189           if(LastEdge.IsNull() && !theEdge.IsNull() &&
1190              !theFace.IsNull() && !theVertex.IsNull() && 
1191              !FirstEdge.IsNull()) {
1192             LastEdge = theEdge;
1193             LastFace = theFace;
1194             LastVertex = theVertex;
1195             PtOnLastEdge = PtOnEdge;
1196             OnLastEdge = OnEdge; 
1197             if(PtOnEdge && !PtOnVertex) {
1198               TopTools_ListOfShape faces;
1199               faces.Clear();
1200               faces.Append(LastFace);
1201               TopExp_Explorer ex2;
1202               ex2.Init(mySbase, TopAbs_FACE);
1203               for(; ex2.More(); ex2.Next()) {
1204                 TopoDS_Face fx = TopoDS::Face(ex2.Current());//modified by NIZNHY-PKV Fri Mar 22 17:12:06 2002 fx/f
1205                 TopExp_Explorer ex3;
1206                 ex3.Init(fx, TopAbs_EDGE);
1207                 for(; ex3.More(); ex3.Next()) {
1208                   const TopoDS_Edge& e = TopoDS::Edge(ex3.Current());
1209                   if(e.IsSame(OnEdge) && !fx.IsSame(LastFace)) {
1210                     faces.Append(fx);
1211                   }
1212                 }
1213               }
1214               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar-bnd/10.,bnd/10.,  Pln);
1215               if(!FFF.IsNull()) LastFace = FFF;          
1216             }
1217             else if(PtOnEdge && PtOnVertex) {
1218               TopTools_ListOfShape faces;
1219               faces.Clear();
1220               faces.Append(LastFace);
1221               TopExp_Explorer ex2;
1222               ex2.Init(mySbase, TopAbs_FACE);
1223               for(; ex2.More(); ex2.Next()) {
1224                 TopoDS_Face fx = TopoDS::Face(ex2.Current());//modified by NIZNHY-PKV Fri Mar 22 17:11:36 2002 fx/f
1225                 TopExp_Explorer ex3;
1226                 ex3.Init(fx, TopAbs_VERTEX);
1227                 for(; ex3.More(); ex3.Next()) {
1228                   const TopoDS_Vertex& v = TopoDS::Vertex(ex3.Current());
1229                   if(v.IsSame(OnVertex) && !fx.IsSame(LastFace)) {
1230                     faces.Append(fx);
1231                   }
1232                 }
1233               }
1234               TopoDS_Face FFF = ChoiceOfFaces(faces, curve, intpar-bnd/10.,bnd/10.,  Pln);
1235               if(!FFF.IsNull()) LastFace = FFF;
1236             }
1237             if(!LastEdge.IsNull() && !LastFace.IsNull() 
1238                && !LastVertex.IsNull()) {
1239               LastOK = Standard_True;
1240             }
1241             break;     
1242           }
1243         }
1244       }
1245     }
1246     
1247     if(FirstOK && LastOK)  {
1248       Data = Standard_True;
1249       gp_Pnt PP1 = BRep_Tool::Pnt(TopExp::FirstVertex(FirstEdge,Standard_True));
1250       gp_Pnt PP2 = BRep_Tool::Pnt(TopExp::LastVertex(LastEdge,Standard_True));
1251       gp_Pnt p1 = BRep_Tool::Pnt(FirstVertex);
1252       gp_Pnt p2 = BRep_Tool::Pnt(LastVertex);
1253       if(p1.Distance(PP1) <= BRep_Tool::Tolerance(FirstFace)) {
1254         OnFirstFace = Standard_True;
1255       }
1256       if(p2.Distance(PP2) <= BRep_Tool::Tolerance(LastFace)) {
1257         OnLastFace = Standard_True;
1258       }     
1259       return Standard_True;
1260     }
1261     else {
1262 #ifdef OCCT_DEBUG
1263       if (trc) cout << " First or Last not OK" << endl;
1264 #endif
1265       return Standard_False;
1266     }
1267   }
1268 }
1269
1270
1271 //=======================================================================
1272 //function : PtOnEdgeVertex
1273 //purpose  : Find if 2 limit points of the unique edge of a wire
1274 //           are on an edge or a vertex of the base shape
1275 //=======================================================================
1276
1277 void BRepFeat_RibSlot::PtOnEdgeVertex(const Standard_Boolean RevolRib,
1278                                       const TopoDS_Shape& shape,
1279                                       const gp_Pnt& point,
1280                                       const TopoDS_Vertex& ,//FirstVertex,
1281                                       const TopoDS_Vertex& ,//LastVertex,
1282                                       Standard_Boolean& PtOnEdge,
1283                                       TopoDS_Edge& OnEdge,
1284                                       Standard_Boolean& PtOnVertex,
1285                                       TopoDS_Vertex& OnVertex)
1286      
1287 {
1288 #ifdef OCCT_DEBUG
1289   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
1290   if (trc) cout << "BRepFeat_RibSlot::PtOnEdgeVertex" << endl;
1291 #endif
1292   Standard_Boolean TestOK;
1293 //  PtOnEdge = Standard_False;
1294 //  OnEdge.Nullify();
1295 //  PtOnVertex = Standard_False;
1296 //  OnVertex.Nullify();
1297
1298   TopExp_Explorer EXP;
1299   EXP.Init(shape, TopAbs_EDGE);
1300   TopTools_MapOfShape Map;
1301   for(; EXP.More(); EXP.Next()) {
1302     const TopoDS_Edge& e = TopoDS::Edge(EXP.Current());
1303     if ( !Map.Add(e)) continue;
1304     if (!RevolRib) {
1305       if (BRep_Tool::Degenerated(e)) continue;
1306     }
1307     Standard_Real fff, lll;
1308     Handle(Geom_Curve) ccc = BRep_Tool::Curve(e, fff, lll);
1309     if (!RevolRib) {
1310       ccc = new Geom_TrimmedCurve(ccc, fff, lll);
1311     }
1312     GeomAPI_ProjectPointOnCurve proj(point, ccc);
1313     TestOK = Standard_False;
1314     if (!RevolRib) {
1315       if(proj.NbPoints() == 1) TestOK = Standard_True;
1316     } 
1317     else {
1318       if(proj.NbPoints() >= 1) TestOK = Standard_True;
1319     }
1320     if(TestOK && proj.Distance(1) <= BRep_Tool::Tolerance(e)) {
1321       PtOnEdge = Standard_True;
1322       OnEdge = e;            
1323       TopoDS_Vertex ev1 = TopExp::FirstVertex(e,Standard_True);
1324       TopoDS_Vertex ev2 = TopExp::LastVertex(e,Standard_True);
1325       gp_Pnt ep1 = BRep_Tool::Pnt(ev1);
1326       gp_Pnt ep2 = BRep_Tool::Pnt(ev2);
1327       if(point.Distance(ep1) <= BRep_Tool::Tolerance(ev1)) {
1328         PtOnVertex = Standard_True;
1329         OnVertex = ev1;
1330         break;
1331       }
1332       else if(point.Distance(ep2) <= BRep_Tool::Tolerance(ev1)) {
1333         PtOnVertex = Standard_True;
1334         OnVertex = ev2;
1335         break;
1336       }        
1337       break;
1338     }
1339   } 
1340 }
1341
1342
1343 //=======================================================================
1344 //function : SlidingProfile
1345 //purpose  : construction of the profile face in case of sliding
1346 //=======================================================================
1347  
1348 Standard_Boolean BRepFeat_RibSlot::SlidingProfile(TopoDS_Face& Prof,
1349                                                   const Standard_Boolean RevolRib,
1350                                                   const Standard_Real myTol,
1351                                                   Standard_Integer& Concavite,
1352                                                   const Handle(Geom_Plane)& myPln,
1353                                                   const TopoDS_Face& BndFace,
1354                                                   const gp_Pnt& CheckPnt,
1355                                                   const TopoDS_Face& FirstFace,
1356                                                   const TopoDS_Face& LastFace,
1357                                                   const TopoDS_Vertex& ,//FirstVertex,
1358                                                   const TopoDS_Vertex& ,//LastVertex,
1359                                                   const TopoDS_Edge& FirstEdge,
1360                                                   const TopoDS_Edge& LastEdge)
1361      
1362 {
1363 #ifdef OCCT_DEBUG
1364   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1365   if (trc) cout << "BRepFeat_RibSlot::SlidingProfile" << endl;
1366 #endif
1367   Standard_Boolean ProfileOK = Standard_True;
1368 // --case of sliding : construction of the wire of the profile
1369 // --> 1 part bounding box + 1 part wire
1370 //   attention to the compatibility of orientations
1371
1372   gp_Dir FN, LN;
1373   BRepLib_MakeWire WW;
1374   
1375   FN = Normal(FirstFace, myFirstPnt);
1376   LN = Normal(LastFace, myLastPnt);
1377
1378 // Case of the groove (cut) <> rib (fuse)
1379 // -> we are in the material
1380 // -> make everything in 2d in the working plane : easier  
1381   if(!myFuse) {
1382     FN = -FN;
1383     LN = -LN;
1384   }
1385   
1386   
1387   Handle(Geom_Line) ln1, ln2;
1388   gp_Pnt  Pt;//,p1, p2;
1389   
1390   ln2 = new Geom_Line(myFirstPnt, FN);
1391   ln1 = new Geom_Line(myLastPnt, LN);
1392   
1393   Handle(Geom2d_Curve) ln2d1 = GeomAPI::To2d(ln1, myPln->Pln());
1394   Handle(Geom2d_Curve) ln2d2 = GeomAPI::To2d(ln2, myPln->Pln());
1395   
1396   Geom2dAPI_InterCurveCurve inter(ln2d1, ln2d2, Precision::Confusion());
1397     
1398   Standard_Boolean TestOK = Standard_True;
1399   if (RevolRib) {
1400     gp_Dir d1, d2;
1401     d1 = ln1->Position().Direction();
1402     d2 = ln2->Position().Direction();
1403     if(d1.IsOpposite(d2, myTol)) {
1404       Standard_Real par1 = ElCLib::Parameter(ln1->Lin(), myFirstPnt);
1405       Standard_Real par2 = ElCLib::Parameter(ln2->Lin(), myLastPnt);
1406       if(par1 >= myTol  ||  par2 >= myTol)  {
1407         Concavite = 2;    //paralel and concave
1408         BRepLib_MakeEdge e1(myLastPnt, myFirstPnt);
1409         WW.Add(e1);
1410       } 
1411     } 
1412     if(d1.IsEqual(d2, myTol)) {
1413        if(Concavite == 3) TestOK = Standard_False;
1414     }
1415   }
1416   
1417   if(TestOK) {
1418     if(inter.NbPoints() > 0) {
1419       gp_Pnt2d P = inter.Point(1);
1420       myPln->D0(P.X(), P.Y(), Pt);
1421       Standard_Real par = IntPar(ln1, Pt);
1422       if(par>0) Concavite = 1;    //concave
1423     }
1424   }
1425
1426 // ---Construction of the profile face 
1427   if(Concavite == 1) {
1428 // if concave : it is possible to extend first and last edges of the wire
1429 //              to the bounding box
1430     BRepLib_MakeEdge e1(myLastPnt, Pt);
1431     WW.Add(e1);
1432     BRepLib_MakeEdge e2(Pt, myFirstPnt);
1433     WW.Add(e2);
1434   }
1435   else if(Concavite == 3) {
1436 // BndEdge : edges of intersection with the bounding box
1437     TopoDS_Edge BndEdge1, BndEdge2;
1438 // Points of intersection with the bounding box / Find Profile
1439     gp_Pnt BndPnt1, BndPnt2, LastPnt;
1440     TopExp_Explorer expl;
1441     expl.Init(BndFace, TopAbs_WIRE);
1442     BRepTools_WireExplorer explo;
1443     TopoDS_Wire BndWire = TopoDS::Wire(expl.Current());
1444     explo.Init(BndWire);
1445     for(; explo.More(); explo.Next()) {
1446       const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1447       Standard_Real first, last;
1448       Handle(Geom_Curve) c = BRep_Tool::Curve(e, first, last);
1449       Handle(Geom2d_Curve) c2d = GeomAPI::To2d(c, myPln->Pln());
1450       Geom2dAPI_InterCurveCurve intcln1(ln2d1, c2d, 
1451                                         Precision::Confusion());
1452       if(intcln1.NbPoints() > 0) {
1453         gp_Pnt2d p2d = intcln1.Point(1);
1454         gp_Pnt p;
1455         myPln->D0(p2d.X(), p2d.Y(), p);
1456         Standard_Real parl = IntPar(ln1, p);
1457         Standard_Real parc = IntPar(c, p);
1458         if(parc >= first && parc <= last && parl >= 0) {
1459           BndEdge1 = e;
1460           BndPnt1 = p;
1461         }
1462       }
1463       
1464       Geom2dAPI_InterCurveCurve intcln2(ln2d2, c2d, 
1465                                         Precision::Confusion());
1466       if(intcln2.NbPoints() > 0) {
1467         gp_Pnt2d p2d = intcln2.Point(1);
1468         gp_Pnt p;
1469         myPln->D0(p2d.X(), p2d.Y(), p);
1470         Standard_Real parl = IntPar(ln2, p);
1471         Standard_Real parc = IntPar(c, p);
1472         if(parc >= first && parc <= last && parl >= 0) {
1473           BndEdge2 = e;
1474           BndPnt2 = p;
1475         }
1476       }
1477       if(!BndEdge1.IsNull() && !BndEdge2.IsNull()) break;
1478     }
1479     
1480     if(BndEdge1.IsNull() || BndEdge2.IsNull())  {
1481 #ifdef OCCT_DEBUG
1482       if (trc) cout << " Null bounding edge" << endl;
1483 #endif
1484       ProfileOK = Standard_False;
1485       return ProfileOK;
1486     }
1487     
1488     
1489     BRepLib_MakeEdge e1(myLastPnt, BndPnt1);
1490     WW.Add(e1);
1491     
1492     if(BndEdge1.IsSame(BndEdge2)) {
1493 // Particular case : same edge -> simply determined path
1494       BRepLib_MakeEdge e2(BndPnt1, BndPnt2);
1495       WW.Add(e2);
1496       BRepLib_MakeEdge e3(BndPnt2, myFirstPnt);
1497       WW.Add(e3);        
1498     }
1499     else {
1500       explo.Init(BndWire);
1501       for(; explo.More(); explo.Next()) {
1502         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1503         if(e.IsSame(BndEdge1)) {
1504           gp_Pnt pp;
1505           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));
1506           if(pp.Distance(BndPnt1) >= BRep_Tool::Tolerance(e)) {
1507             LastPnt = pp;
1508           }
1509 //            else {         //LinearForm
1510 //              gp_Pnt ppp = BRep_Tool::Pnt(TopExp::FirstVertex(e,Standard_True));
1511 //              LastPnt = ppp;
1512 //            }
1513           BRepLib_MakeEdge e2(BndPnt1, LastPnt);
1514           WW.Add(e2);
1515           break;        
1516         }
1517       }
1518       
1519       if(explo.More()) {
1520         explo.Next();
1521         if(explo.Current().IsNull()) explo.Init(BndWire);
1522       }
1523       else explo.Init(BndWire);
1524
1525 // Check if this is BndEdge2
1526 // -> if yes : it is required to turn to join FirstPnt
1527 // -> if no : add edges
1528       Standard_Boolean Fin = Standard_False;
1529       while(!Fin) {
1530         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1531         if(!e.IsSame(BndEdge2)) {
1532           gp_Pnt pp;
1533           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));  
1534           BRepLib_MakeEdge ee(LastPnt, pp);
1535           WW.Add(ee);
1536           LastPnt = pp;
1537         }
1538         else {
1539 // the path is closed
1540 // -> since met BndEdge2, end of borders on BndFace
1541           Fin = Standard_True;
1542           BRepLib_MakeEdge ee(LastPnt, BndPnt2);
1543           WW.Add(ee);
1544           LastPnt = BndPnt2;
1545         }
1546         if(explo.More()) {
1547           explo.Next();
1548           if(explo.Current().IsNull()) {
1549             explo.Init(BndWire);
1550           }
1551         }
1552         else explo.Init(BndWire);
1553       }
1554       
1555       BRepLib_MakeEdge e3(BndPnt2, myFirstPnt);
1556       WW.Add(e3);
1557     }   
1558   }
1559
1560 // ---Construction of the profile
1561
1562 // Explore the wire provided by the user
1563 // BRepTools_WireExplorer : correct order - without repetition <> TopExp : non ordered
1564   BRepTools_WireExplorer EX(myWire);
1565   
1566   Standard_Real ff, ll;
1567   Handle(Geom_Curve) FirstCurve = BRep_Tool::Curve(FirstEdge, ff, ll);
1568   
1569   if(!FirstEdge.IsSame(LastEdge)) {
1570     TopoDS_Vertex FLVert = TopExp::LastVertex(FirstEdge,Standard_True);
1571     gp_Pnt FLPnt = BRep_Tool::Pnt(FLVert);
1572     BRepLib_MakeEdge ef(FirstCurve, myFirstPnt, FLPnt);
1573     WW.Add(ef);   
1574     for(; EX.More(); EX.Next()) {
1575       const TopoDS_Edge& E = EX.Current();
1576       if(E.IsSame(FirstEdge))        break;
1577     }      
1578     EX.Next();
1579     for(; EX.More(); EX.Next()) {
1580       const TopoDS_Edge& E = EX.Current();
1581       if(!E.IsSame(LastEdge)) {
1582         WW.Add(E);
1583       }        
1584       else break;
1585     }
1586     Handle(Geom_Curve) LastCurve = BRep_Tool::Curve(LastEdge, ff, ll);
1587     TopoDS_Vertex LFVert = TopExp::FirstVertex(LastEdge,Standard_True);
1588     gp_Pnt LFPnt = BRep_Tool::Pnt(LFVert);
1589     BRepLib_MakeEdge el(LastCurve, LFPnt, myLastPnt);
1590     WW.Add(el);
1591   }
1592   else {
1593 // only one edge : particular processing
1594     Standard_Real fpar = IntPar(FirstCurve, myFirstPnt);
1595     Standard_Real lpar = IntPar(FirstCurve, myLastPnt);
1596     Handle(Geom_Curve) c;
1597     if(fpar > lpar) 
1598       c = Handle(Geom_Curve)::DownCast(FirstCurve->Reversed());
1599     else 
1600       c = FirstCurve;
1601     
1602     BRepLib_MakeEdge ef(c, myFirstPnt, myLastPnt);
1603     WW.Add(ef);
1604   }
1605   
1606   BRepLib_MakeFace f(myPln->Pln(), WW, Standard_True);
1607   TopoDS_Face fac = TopoDS::Face(f.Shape());
1608     
1609   if (!BRepAlgo::IsValid(fac)) {
1610 #ifdef OCCT_DEBUG
1611     if (trc) cout << " Invalid Face" << endl;
1612 #endif
1613     ProfileOK = Standard_False;
1614     return ProfileOK;
1615   }
1616   
1617   if(Concavite != 3) {
1618 // if concave : face is OK
1619     Prof = fac;
1620   }
1621   else {
1622 // if not concave
1623 // CheckPnt : point slightly inside the material side
1624 // Bndface  : face/cut of the bounding box in the plane of the profile
1625     BRepTopAdaptor_FClass2d Cl(fac, BRep_Tool::Tolerance(fac));
1626     Standard_Real u, v;
1627     ElSLib::Parameters(myPln->Pln(), CheckPnt, u, v);
1628     gp_Pnt2d checkpnt2d(u, v);
1629     if(Cl.Perform(checkpnt2d, Standard_True) == TopAbs_OUT) {
1630 // If face is not the correct part of BndFace take the complementary
1631       //modified by NIZNHY-PKV Fri Mar 22 16:46:20 2002 f
1632       //BRepAlgo_Cut c(BndFace, fac);     
1633       BRepAlgoAPI_Cut c(BndFace, fac);     
1634       //modified by NIZNHY-PKV Fri Mar 22 16:46:23 2002 t
1635       TopExp_Explorer exp(c.Shape(), TopAbs_WIRE);
1636       const TopoDS_Wire& w = TopoDS::Wire(exp.Current());
1637       BRepLib_MakeFace ffx(w);//modified by NIZNHY-PKV Fri Mar 22 17:10:43 2002 ffx/ff
1638       Prof = TopoDS::Face(ffx.Shape());
1639     }
1640     else {
1641 // If face is the correct part of BndFace  : face is OK
1642       Prof = fac;
1643     }
1644   }
1645   
1646   if (!BRepAlgo::IsValid(Prof)) {
1647 #ifdef OCCT_DEBUG
1648     if (trc) cout << " Invalid Face Profile" << endl;
1649 #endif
1650     ProfileOK = Standard_False;
1651     return ProfileOK;    
1652   }
1653   return ProfileOK;
1654 }
1655 //=======================================================================
1656 //function : NoSlidingProfile
1657 //purpose  : construction of the face profile in case of sliding
1658 //=======================================================================
1659  
1660 Standard_Boolean BRepFeat_RibSlot::NoSlidingProfile(TopoDS_Face& Prof,
1661                                                     const Standard_Boolean RevolRib,
1662                                                     const Standard_Real myTol,
1663                                                     Standard_Integer& Concavite,
1664                                                     const Handle(Geom_Plane)& myPln,
1665                                                     const Standard_Real bnd,
1666                                                     const TopoDS_Face& BndFace,
1667                                                     const gp_Pnt& CheckPnt,
1668                                                     const TopoDS_Face& ,//FirstFace,
1669                                                     const TopoDS_Face& ,//LastFace,
1670                                                     const TopoDS_Vertex& ,//FirstVertex,
1671                                                     const TopoDS_Vertex& ,//LastVertex,
1672                                                     const TopoDS_Edge& FirstEdge,
1673                                                     const TopoDS_Edge& LastEdge,
1674                                                     const Standard_Boolean OnFirstFace,
1675                                                     const Standard_Boolean OnLastFace)
1676      
1677 {
1678 #ifdef OCCT_DEBUG
1679   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1680   if (trc) cout << "BRepFeat_RibSlot::NoSlidingProfile" << endl;
1681 #endif
1682   Standard_Boolean ProfileOK = Standard_True;
1683
1684   Standard_Real l1, f1, f2, l2;//, p;        
1685   TopoDS_Vertex theFV; theFV.Nullify();
1686   gp_Pnt theFirstpoint;
1687   TopoDS_Edge theLastEdge; theLastEdge.Nullify();
1688   gp_Pnt firstpoint, lastpoint;//, pp1, pp2;
1689   gp_Vec firstvect, lastvect; 
1690   TopoDS_Wire w;
1691   BRep_Builder BB;
1692   BB.MakeWire(w);
1693   //gp_Pnt p1, p3;
1694   TopoDS_Edge FalseFirstEdge, FalseLastEdge, FalseOnlyOne;
1695   
1696   Handle(Geom_Curve) FirstCurve = BRep_Tool::Curve(FirstEdge, f1, l1);
1697   Handle(Geom_Curve) LastCurve = BRep_Tool::Curve(LastEdge, f2, l2);
1698
1699   Handle(Geom_Line) firstln, lastln;  
1700   FirstCurve->D1(f1, firstpoint, firstvect);
1701   lastln = new Geom_Line(firstpoint, -firstvect);
1702   LastCurve->D1(l2, lastpoint, lastvect);
1703   firstln = new Geom_Line(lastpoint, lastvect);
1704   
1705   gp_Pnt Pt;
1706   
1707   Handle(Geom2d_Curve) ln2d1 = GeomAPI::To2d(firstln, myPln->Pln());
1708   Handle(Geom2d_Curve) ln2d2 = GeomAPI::To2d(lastln, myPln->Pln());
1709   
1710   Geom2dAPI_InterCurveCurve inter(ln2d1, ln2d2, Precision::Confusion());
1711
1712   Standard_Boolean TestOK = Standard_True;
1713   if (RevolRib) {
1714     gp_Dir d1, d2;
1715     d1 = firstln->Position().Direction();
1716     d2 = lastln->Position().Direction();
1717     if(d1.IsOpposite(d2, myTol)) {
1718       Standard_Real par1 = ElCLib::Parameter(firstln->Lin(), myFirstPnt);
1719       Standard_Real par2 = ElCLib::Parameter(lastln->Lin(), myLastPnt);
1720       if(par1 >= myTol  ||  par2 >= myTol)  
1721         Concavite = 2;    //parallel and concave
1722     }      
1723     if(d1.IsEqual(d2, myTol)) {
1724        if(Concavite == 3) TestOK = Standard_False;
1725     }
1726   }
1727   
1728   if(TestOK) {
1729     if(inter.NbPoints() > 0) {
1730       gp_Pnt2d P = inter.Point(1);
1731       myPln->D0(P.X(), P.Y(), Pt);
1732       Standard_Real par = IntPar(firstln, Pt);
1733       if(par>0) Concavite = 1;    //concave
1734     }
1735   }
1736
1737 // ---Construction of the face profile  
1738   if(Concavite == 3) {
1739     if(OnFirstFace) {
1740       Standard_Real f, l;
1741       FalseFirstEdge = FirstEdge;
1742       EdgeExtention(FalseFirstEdge, bnd, Standard_True);
1743       const TopoDS_Vertex& vv1 = TopExp::FirstVertex(FalseFirstEdge,Standard_True);
1744       firstpoint = BRep_Tool::Pnt(vv1);
1745       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseFirstEdge, f, l);
1746       cc->D1(f, firstpoint, firstvect);
1747       lastln = new Geom_Line(firstpoint, -firstvect);
1748       if(FirstEdge.IsSame(LastEdge)) FalseOnlyOne = FalseFirstEdge;         
1749       ln2d2 = GeomAPI::To2d(lastln, myPln->Pln());
1750     }
1751     if(OnLastFace) {
1752       Standard_Real f, l;
1753       if(!FirstEdge.IsSame(LastEdge)) {
1754         FalseLastEdge = LastEdge;
1755       }
1756       else {
1757         if(FalseOnlyOne.IsNull()) FalseOnlyOne = LastEdge;
1758         FalseLastEdge = FalseOnlyOne;
1759       }
1760       EdgeExtention(FalseLastEdge, bnd, Standard_False);
1761       if(FirstEdge.IsSame(LastEdge)) {
1762         FalseOnlyOne = FalseLastEdge;
1763       }
1764       const TopoDS_Vertex& vv2 = TopExp::LastVertex(FalseLastEdge,Standard_True);
1765       lastpoint = BRep_Tool::Pnt(vv2);
1766       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseLastEdge, f, l);
1767       cc->D1(l, lastpoint, lastvect);
1768       lastpoint = BRep_Tool::Pnt(vv2);
1769       firstln = new Geom_Line(lastpoint, lastvect);
1770       ln2d1 = GeomAPI::To2d(firstln, myPln->Pln());
1771     }
1772     
1773     TopoDS_Edge BndEdge1, BndEdge2;
1774     gp_Pnt BndPnt1, BndPnt2, LastPnt;
1775     TopExp_Explorer expl;
1776     expl.Init(BndFace, TopAbs_WIRE);
1777     BRepTools_WireExplorer explo;
1778     TopoDS_Wire BndWire = TopoDS::Wire(expl.Current());
1779     explo.Init(BndWire);
1780     for(; explo.More(); explo.Next()) {
1781       const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1782       Standard_Real first, last;
1783       Handle(Geom_Curve) c = BRep_Tool::Curve(e, first, last);
1784       Handle(Geom2d_Curve) c2d = GeomAPI::To2d(c, myPln->Pln());
1785       Geom2dAPI_InterCurveCurve intcln1(ln2d1, c2d, 
1786                                         Precision::Confusion());
1787       if(intcln1.NbPoints() > 0) {
1788         gp_Pnt2d p2d = intcln1.Point(1);
1789         gp_Pnt p;
1790         myPln->D0(p2d.X(), p2d.Y(), p);
1791         Standard_Real parl = IntPar(firstln, p);
1792         Standard_Real parc = IntPar(c, p);
1793         if(parc >= first && parc <= last && parl >= 0) {
1794           BndEdge1 = e;
1795           BndPnt1 = p;
1796         }
1797       }
1798       
1799       Geom2dAPI_InterCurveCurve intcln2(ln2d2, c2d, 
1800                                         Precision::Confusion());
1801       if(intcln2.NbPoints() > 0) {
1802         gp_Pnt2d p2d = intcln2.Point(1);
1803         gp_Pnt p;
1804         myPln->D0(p2d.X(), p2d.Y(), p);
1805         Standard_Real parl = IntPar(lastln, p);
1806         Standard_Real parc = IntPar(c, p);
1807         if(parc >= first && parc <= last && parl >= 0) {
1808           BndEdge2 = e;
1809           BndPnt2 = p;
1810         }
1811       }
1812       if(!BndEdge1.IsNull() && !BndEdge2.IsNull()) break;
1813     }
1814     
1815     if(BndEdge1.IsNull() || BndEdge2.IsNull())  {
1816 #ifdef OCCT_DEBUG
1817       if (trc) cout << " Null bounding edge" << endl;
1818 #endif
1819       ProfileOK = Standard_False;
1820       return ProfileOK;
1821     }
1822     
1823     TopoDS_Edge ee1;
1824     if(theLastEdge.IsNull()) {
1825       BRepLib_MakeEdge e1(lastpoint, BndPnt1);
1826       ee1 = TopoDS::Edge(e1.Shape());
1827     }
1828     else {
1829       const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1830       BRepLib_MakeVertex v2(BndPnt1);
1831       BRepLib_MakeEdge e1(v1, v2);
1832       ee1 = TopoDS::Edge(e1.Shape());
1833     }
1834     BB.Add(w, ee1);
1835     theLastEdge = ee1;
1836     if(theFV.IsNull()) {
1837       theFV = TopExp::FirstVertex(ee1,Standard_True);
1838       theFirstpoint = BRep_Tool::Pnt(theFV);
1839     }
1840     
1841     if(BndEdge1.IsSame(BndEdge2)) {
1842       TopoDS_Edge ee2, ee3;
1843       if(theLastEdge.IsNull()) {
1844         BRepLib_MakeEdge e2(BndPnt1, BndPnt2);
1845         ee2 = TopoDS::Edge(e2.Shape());
1846       }
1847       else {
1848         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1849         BRepLib_MakeVertex v2(BndPnt2);
1850         BRepLib_MakeEdge e2(v1, v2);
1851         ee2 = TopoDS::Edge(e2.Shape());
1852       }
1853       BB.Add(w, ee2);
1854       theLastEdge = ee2;
1855       if(theFV.IsNull()) {
1856         theFV = TopExp::FirstVertex(ee2,Standard_True);
1857         theFirstpoint = BRep_Tool::Pnt(theFV);
1858       }
1859       if(theLastEdge.IsNull()) {
1860         BRepLib_MakeEdge e3(BndPnt2, firstpoint);
1861         ee3 = TopoDS::Edge(e3.Shape());        
1862       }
1863       else {
1864         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1865         BRepLib_MakeVertex v2(firstpoint);
1866         BRepLib_MakeEdge e3(v1, v2);
1867         ee3 = TopoDS::Edge(e3.Shape());
1868       }
1869       BB.Add(w, ee3);        
1870       theLastEdge = ee3;
1871       if(theFV.IsNull()) {
1872         theFV = TopExp::FirstVertex(ee3,Standard_True);
1873         theFirstpoint = BRep_Tool::Pnt(theFV);
1874       }
1875     }
1876     else {
1877       explo.Init(BndWire);
1878       for(; explo.More(); explo.Next()) {
1879         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1880         if(e.IsSame(BndEdge1)) {
1881           gp_Pnt pp;
1882           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));
1883           if(pp.Distance(BndPnt1) > BRep_Tool::Tolerance(e)) {
1884             LastPnt = pp;
1885           }
1886           TopoDS_Edge eee;
1887           if(theLastEdge.IsNull()) {
1888             BRepLib_MakeEdge e2(BndPnt1, LastPnt);
1889             eee = TopoDS::Edge(e2.Shape());
1890           }
1891           else {
1892             const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1893             BRepLib_MakeVertex v2(LastPnt);
1894             BRepLib_MakeEdge e2(v1, v2);
1895             eee = TopoDS::Edge(e2.Shape());
1896           }
1897           BB.Add(w, eee);
1898           theLastEdge = eee;
1899           if(theFV.IsNull()) {
1900             theFV = TopExp::FirstVertex(eee,Standard_True);
1901             theFirstpoint = BRep_Tool::Pnt(theFV);
1902           }
1903           break;        
1904         }
1905       }
1906       
1907       if(explo.More()) {
1908         explo.Next();
1909         if(explo.Current().IsNull()) explo.Init(BndWire);
1910       }
1911       else explo.Init(BndWire);
1912       Standard_Boolean Fin = Standard_False;
1913       while(!Fin) {
1914         const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
1915         if(!e.IsSame(BndEdge2)) {
1916           gp_Pnt pp;
1917           pp = BRep_Tool::Pnt(TopExp::LastVertex(e,Standard_True));
1918           TopoDS_Edge eee1;
1919           if(theLastEdge.IsNull()) {
1920             BRepLib_MakeEdge ee(LastPnt, pp);
1921             eee1 = TopoDS::Edge(ee.Shape());
1922           }
1923           else {
1924             const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1925             BRepLib_MakeVertex v2(pp);
1926             BRepLib_MakeEdge ee(v1, v2);
1927             eee1 = TopoDS::Edge(ee.Shape());
1928           }
1929           BB.Add(w, eee1);
1930           theLastEdge = eee1;
1931           if(theFV.IsNull()) {
1932             theFV = TopExp::FirstVertex(eee1,Standard_True);
1933             theFirstpoint = BRep_Tool::Pnt(theFV);
1934           }
1935           LastPnt = pp;
1936         }
1937         else {
1938           Fin = Standard_True;
1939           TopoDS_Edge eee2;
1940           if(theLastEdge.IsNull()) {
1941             BRepLib_MakeEdge ee(LastPnt, BndPnt2);
1942             eee2 = TopoDS::Edge(ee.Shape());
1943           }
1944           else {
1945             const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1946             BRepLib_MakeVertex v2(BndPnt2);
1947             BRepLib_MakeEdge ee(v1, v2);
1948             eee2 = TopoDS::Edge(ee.Shape());
1949           }
1950           BB.Add(w, eee2);
1951           theLastEdge = eee2;
1952           if(theFV.IsNull()) {
1953             theFV = TopExp::FirstVertex(eee2,Standard_True);
1954             theFirstpoint = BRep_Tool::Pnt(theFV);
1955           }
1956           LastPnt = BndPnt2;
1957         }
1958         if(explo.More()) {
1959           explo.Next();
1960           if(explo.Current().IsNull()) {
1961             explo.Init(BndWire);
1962           }
1963         }
1964         else explo.Init(BndWire);
1965       }
1966       
1967       TopoDS_Edge eee3;
1968       if(theLastEdge.IsNull()) {
1969         BRepLib_MakeEdge e3(BndPnt2, firstpoint);
1970         eee3 = TopoDS::Edge(e3.Shape());
1971       }
1972       else {
1973         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1974         BRepLib_MakeVertex v2(firstpoint);
1975         BRepLib_MakeEdge e3(v1, v2);
1976         eee3 = TopoDS::Edge(e3.Shape());
1977       }
1978       BB.Add(w, eee3);
1979       theLastEdge = eee3;
1980       if(theFV.IsNull()) {
1981         theFV = TopExp::FirstVertex(eee3,Standard_True);
1982         theFirstpoint = BRep_Tool::Pnt(theFV);
1983       }
1984     }   
1985   }
1986  
1987   if(Concavite == 1) {
1988     TopoDS_Edge eee4;
1989     if(theLastEdge.IsNull()) {
1990       BRepLib_MakeEdge  e(Pt, firstpoint); 
1991       eee4 = TopoDS::Edge(e.Shape());      
1992     }
1993     else {
1994       const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
1995       BRepLib_MakeVertex v2(firstpoint);
1996       BRepLib_MakeEdge e(v1, v2);
1997       eee4 = TopoDS::Edge(e.Shape());
1998     }
1999     BB.Add(w, eee4);
2000     if(theFV.IsNull()) {
2001       theFV = TopExp::FirstVertex(eee4,Standard_True);
2002       theFirstpoint = BRep_Tool::Pnt(theFV);
2003     }
2004     theLastEdge = eee4;
2005   }
2006   
2007   
2008   if(FirstEdge.IsSame(LastEdge)) {
2009     if(!myLFMap.IsBound(FirstEdge)) {
2010       TopTools_ListOfShape thelist;
2011       myLFMap.Bind(FirstEdge, thelist);
2012     }
2013     if(OnFirstFace || OnLastFace) {
2014       TopoDS_Edge theEdge;
2015       Standard_Real f, l;
2016       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseOnlyOne, f, l);
2017       if(!theLastEdge.IsNull()) {
2018         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2019         TopoDS_Vertex v2;
2020         const gp_Pnt& pp = BRep_Tool::
2021           Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
2022         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2023           v2 = theFV;
2024         }
2025         else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);
2026         BRepLib_MakeEdge e(cc, v1, v2);
2027         theEdge = TopoDS::Edge(e.Shape());
2028       }
2029       else {
2030         const TopoDS_Vertex& v1 = TopExp::FirstVertex(FalseOnlyOne,Standard_True);
2031         TopoDS_Vertex v2;
2032         const gp_Pnt& pp = BRep_Tool::
2033           Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
2034         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2035           v2 = theFV;
2036         }
2037         else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);                  
2038         BRepLib_MakeEdge e(cc, v1, v2);
2039         theEdge = TopoDS::Edge(e.Shape());
2040       }
2041       myLFMap(FirstEdge).Append(theEdge);
2042       BB.Add(w, theEdge);
2043       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
2044       theLastEdge = theEdge;
2045     }
2046     else {
2047       Standard_Real f, l;
2048       Handle(Geom_Curve) cc = BRep_Tool::Curve(FirstEdge, f, l);
2049       TopoDS_Edge theEdge;
2050       if(!theLastEdge.IsNull()) {
2051         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2052         TopoDS_Vertex v2;
2053 // Attention case Wire Reversed -> LastVertex without Standard_True
2054         const gp_Pnt& pp = BRep_Tool::Pnt(TopExp::LastVertex(FirstEdge));
2055         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2056           v2 = theFV;
2057         }
2058         else v2 = TopExp::LastVertex(FirstEdge);
2059         BRepLib_MakeEdge e(cc, v1, v2);
2060         theEdge = TopoDS::Edge(e.Shape());
2061       }
2062       else {
2063         const TopoDS_Vertex& v1 = TopExp::FirstVertex(FirstEdge,Standard_True);
2064         TopoDS_Vertex v2;
2065         const gp_Pnt& pp = BRep_Tool::
2066           Pnt(TopExp::LastVertex(FirstEdge,Standard_True));
2067         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2068           v2 = theFV;
2069         }
2070         else v2 = TopExp::LastVertex(FirstEdge,Standard_True);
2071         BRepLib_MakeEdge e(cc, v1, v2);
2072         theEdge = TopoDS::Edge(e.Shape());
2073       }
2074       myLFMap(FirstEdge).Append(theEdge);
2075       BB.Add(w, theEdge); 
2076       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
2077       theLastEdge = theEdge;
2078     }
2079   }
2080   else {
2081     if(!myLFMap.IsBound(FirstEdge)) {
2082       TopTools_ListOfShape thelist1;
2083       myLFMap.Bind(FirstEdge, thelist1);
2084     }
2085     if(!OnFirstFace) {
2086       TopoDS_Edge theEdge;
2087       Standard_Real f, l;
2088       Handle(Geom_Curve) cc = BRep_Tool::Curve(FirstEdge, f, l);
2089       if(!theLastEdge.IsNull()) {
2090         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2091         const TopoDS_Vertex& v2 = TopExp::LastVertex(FirstEdge,Standard_True);
2092         BRepLib_MakeEdge e(cc, v1, v2);
2093         theEdge = TopoDS::Edge(e.Shape());          
2094       }
2095       else {
2096         theEdge = FirstEdge;
2097       }
2098       myLFMap(FirstEdge).Append(theEdge);
2099       BB.Add(w, theEdge); 
2100       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
2101       theLastEdge = theEdge;
2102     }
2103     else {
2104       TopoDS_Edge theEdge;
2105       Standard_Real f, l;
2106       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseFirstEdge, f, l);
2107       if(!theLastEdge.IsNull()) {
2108         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2109         const TopoDS_Vertex& v2 = TopExp::LastVertex(FalseFirstEdge,Standard_True);
2110         BRepLib_MakeEdge e(cc, v1, v2);
2111         theEdge = TopoDS::Edge(e.Shape());          
2112       }
2113       else {
2114         theEdge = FalseFirstEdge;
2115       }
2116       myLFMap(FirstEdge).Append(theEdge);
2117       BB.Add(w, theEdge); 
2118       if(theFV.IsNull()) theFV = TopExp::FirstVertex(theEdge,Standard_True);
2119       theLastEdge = theEdge;
2120     }
2121
2122     BRepTools_WireExplorer ex(myWire);
2123     for(; ex.More(); ex.Next()) {
2124       const TopoDS_Edge& E = ex.Current();
2125       if(E.IsSame(FirstEdge)) break;
2126     }
2127     
2128     ex.Next();
2129     
2130     for(; ex.More(); ex.Next()) {
2131       const TopoDS_Edge& E = ex.Current();
2132       if(!E.IsSame(LastEdge)) {
2133         if(!myLFMap.IsBound(E)) {
2134           TopTools_ListOfShape thelist2;
2135           myLFMap.Bind(E, thelist2);
2136         }
2137         TopoDS_Edge eee;
2138         Standard_Real f, l;
2139         Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
2140         if(!theLastEdge.IsNull()) {
2141           const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2142           const TopoDS_Vertex& v2 = TopExp::LastVertex(E,Standard_True);
2143           BRepLib_MakeEdge e(cc, v1, v2);
2144           eee = TopoDS::Edge(e.Shape());          
2145         }
2146         else {
2147           eee = E;
2148         }
2149         myLFMap(E).Append(eee);
2150         BB.Add(w, eee);
2151         if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2152         theLastEdge = eee;
2153       }
2154       else break;
2155     }
2156     
2157     
2158     if(!OnLastFace) {
2159       if(!FirstEdge.IsSame(LastEdge)) {
2160         const TopoDS_Edge& edg = TopoDS::Edge(ex.Current()); 
2161         if(!myLFMap.IsBound(edg)) {
2162           TopTools_ListOfShape thelist3;
2163           myLFMap.Bind(edg, thelist3);
2164         }
2165         TopoDS_Edge eee;
2166         Standard_Real f, l;
2167         Handle(Geom_Curve) cc = BRep_Tool::Curve(edg, f, l);
2168         if(!theLastEdge.IsNull()) {
2169           const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2170           TopoDS_Vertex v2;
2171           const gp_Pnt& pp = BRep_Tool::
2172             Pnt(TopExp::LastVertex(edg,Standard_True));
2173           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2174             v2 = theFV;
2175           }
2176           else v2 = TopExp::LastVertex(edg,Standard_True);
2177           BRepLib_MakeEdge e(cc, v1, v2);
2178           eee = TopoDS::Edge(e.Shape());          
2179         }
2180         else {
2181           const TopoDS_Vertex& v1 = TopExp::FirstVertex(edg,Standard_True);
2182           TopoDS_Vertex v2;
2183           const gp_Pnt& pp = BRep_Tool::
2184             Pnt(TopExp::LastVertex(edg,Standard_True));
2185           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2186             v2 = theFV;
2187           }
2188           else v2 = TopExp::LastVertex(edg,Standard_True);
2189           BRepLib_MakeEdge e(cc, v1, v2);
2190           eee = TopoDS::Edge(e.Shape());          
2191         }
2192         myLFMap(edg).Append(eee);
2193         BB.Add(w, eee);
2194         if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2195         theLastEdge = eee;
2196       }
2197       else {
2198         TopoDS_Edge eee;
2199         Standard_Real f, l;
2200         if(!myLFMap.IsBound(LastEdge)) {
2201           TopTools_ListOfShape thelist4;
2202           myLFMap.Bind(LastEdge, thelist4);
2203         }
2204         Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseOnlyOne, f, l);
2205         if(!theLastEdge.IsNull()) {
2206           const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2207           TopoDS_Vertex v2;
2208           const gp_Pnt& pp = BRep_Tool::
2209             Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
2210           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2211             v2 = theFV;
2212           }
2213           else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);
2214           BRepLib_MakeEdge e(cc, v1, v2);
2215           eee = TopoDS::Edge(e.Shape());          
2216         }          
2217         else {
2218           const TopoDS_Vertex& v1 = TopExp::FirstVertex(FalseOnlyOne,Standard_True);
2219           TopoDS_Vertex v2;
2220           const gp_Pnt& pp = BRep_Tool::
2221             Pnt(TopExp::LastVertex(FalseOnlyOne,Standard_True));
2222           if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2223             v2 = theFV;
2224           }
2225           else v2 = TopExp::LastVertex(FalseOnlyOne,Standard_True);
2226           BRepLib_MakeEdge e(cc, v1, v2);
2227           eee = TopoDS::Edge(e.Shape());          
2228         }
2229         myLFMap(LastEdge).Append(eee);
2230         BB.Add(w, eee);
2231         if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2232         theLastEdge = eee;
2233       }
2234     }
2235     else {
2236       TopoDS_Edge eee;
2237       Standard_Real f, l;
2238       if(!myLFMap.IsBound(LastEdge)) {
2239         TopTools_ListOfShape thelist5;
2240         myLFMap.Bind(LastEdge, thelist5);
2241       }
2242       Handle(Geom_Curve) cc = BRep_Tool::Curve(FalseLastEdge, f, l);
2243       if(!theLastEdge.IsNull()) {
2244         const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2245         TopoDS_Vertex v2;
2246         const gp_Pnt& pp = BRep_Tool::
2247           Pnt(TopExp::LastVertex(FalseLastEdge,Standard_True));
2248         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2249           v2 = theFV;
2250         }
2251         else v2 = TopExp::LastVertex(FalseLastEdge,Standard_True);
2252         BRepLib_MakeEdge e(cc, v1, v2);
2253         eee = TopoDS::Edge(e.Shape());          
2254       }          
2255       else {
2256         const TopoDS_Vertex& v1 = TopExp::FirstVertex(FalseLastEdge,Standard_True);
2257         TopoDS_Vertex v2;
2258         const gp_Pnt& pp = BRep_Tool::
2259           Pnt(TopExp::LastVertex(FalseLastEdge,Standard_True));
2260         if(!theFV.IsNull() && theFirstpoint.Distance(pp) <= myTol) {
2261           v2 = theFV;
2262         }
2263         else v2 = TopExp::LastVertex(FalseLastEdge,Standard_True);
2264         BRepLib_MakeEdge e(cc, v1, v2);
2265         eee = TopoDS::Edge(e.Shape());          
2266       }
2267       myLFMap(LastEdge).Append(eee);
2268       BB.Add(w, eee);
2269       if(theFV.IsNull()) theFV = TopExp::FirstVertex(eee,Standard_True);
2270       theLastEdge = eee;
2271     }
2272   }
2273   
2274   if(Concavite == 1)  {
2275     TopoDS_Edge eef;
2276     if(theLastEdge.IsNull()) {        
2277       BRepLib_MakeEdge ef(lastpoint, Pt);
2278       eef = TopoDS::Edge(ef.Shape());
2279     }
2280     else {
2281       const TopoDS_Vertex& v1 = TopExp::LastVertex(theLastEdge,Standard_True);
2282       BRepLib_MakeVertex vv(Pt);
2283       TopoDS_Vertex v2 = TopoDS::Vertex(vv.Shape());
2284       if(!theFV.IsNull() && 
2285          Pt.Distance(theFirstpoint) <= myTol) v2 = theFV;
2286       
2287       BRepLib_MakeEdge ef(v1, v2);
2288       eef = TopoDS::Edge(ef.Shape());        
2289     }
2290     BB.Add(w, eef);
2291     if(theFV.IsNull()) theFV = TopExp::FirstVertex(eef,Standard_True);
2292     theLastEdge = eef;
2293   }
2294   
2295   if(Concavite == 2) {
2296     BRepLib_MakeEdge ee(lastpoint, firstpoint);
2297     const TopoDS_Edge& e = ee.Edge();
2298     BB.Add(w, e);
2299   }
2300   
2301   w.Closed (BRep_Tool::IsClosed (w));
2302   BRepLib_MakeFace fa(myPln->Pln(), w, Standard_True);
2303   TopoDS_Face fac = TopoDS::Face(fa.Shape());
2304   
2305   if (!BRepAlgo::IsValid(fac)) {
2306 #ifdef OCCT_DEBUG
2307     if (trc) cout << " Invalid Face" << endl;
2308 #endif
2309     ProfileOK = Standard_False;
2310     return ProfileOK;
2311   }
2312   
2313 //    if(!Concavite) {
2314   if(Concavite == 3) {
2315     BRepTopAdaptor_FClass2d Cl(fac, BRep_Tool::Tolerance(fac));
2316     Standard_Real u, v;
2317     ElSLib::Parameters(myPln->Pln(), CheckPnt, u, v);
2318     gp_Pnt2d checkpnt2d(u, v);
2319     if(Cl.Perform(checkpnt2d, Standard_True) == TopAbs_OUT) {
2320       //modified by NIZNHY-PKV Fri Mar 22 16:47:06 2002 f
2321       //BRepAlgo_Cut c(BndFace, fac);     
2322       BRepAlgoAPI_Cut c(BndFace, fac);     
2323       //modified by NIZNHY-PKV Fri Mar 22 16:47:09 2002 t
2324       TopExp_Explorer exp(c.Shape(), TopAbs_WIRE);
2325       //modified by NIZNHY-PKV Fri Mar 22 16:47:23 2002 f
2326       //UpdateDescendants(c.Builder(), c.Shape(), Standard_False);
2327       UpdateDescendants(c, c.Shape(), Standard_False);
2328       //modified by NIZNHY-PKV Fri Mar 22 16:47:28 2002 t
2329       const TopoDS_Wire& ww = TopoDS::Wire(exp.Current());//modified by NIZNHY-PKV Fri Mar 22 17:10:16 2002 ww/w
2330       BRepLib_MakeFace ff(ww);
2331       Prof = TopoDS::Face(ff.Shape());
2332     }
2333     else {
2334       Prof = fac;
2335     }
2336   }
2337   else {
2338     Prof = fac;
2339   }  
2340
2341   if (!BRepAlgo::IsValid(Prof)) {
2342 #ifdef OCCT_DEBUG
2343     if (trc) cout << " Invalid Face Profile" << endl;
2344 #endif
2345     ProfileOK = Standard_False;
2346     return ProfileOK;
2347   }
2348   return ProfileOK;
2349 }
2350
2351 //modified by NIZNHY-PKV Thu Mar 21 18:43:18 2002 f
2352 //=======================================================================
2353 //function : UpdateDescendants
2354 //purpose  : 
2355 //=======================================================================
2356   void BRepFeat_RibSlot::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
2357                                            const TopoDS_Shape& S,
2358                                            const Standard_Boolean SkipFace)
2359 {
2360   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
2361   TopTools_ListIteratorOfListOfShape it,it2;
2362   TopTools_MapIteratorOfMapOfShape itm;
2363   TopExp_Explorer exp;
2364
2365   for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
2366     const TopoDS_Shape& orig = itdm.Key();
2367     if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
2368       continue;
2369     }
2370     TopTools_MapOfShape newdsc;
2371
2372     //if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
2373
2374     for (it.Initialize(itdm.Value());it.More();it.Next()) {
2375       const TopoDS_Shape& sh = it.Value();
2376       if(sh.ShapeType() != TopAbs_FACE) continue;
2377       const TopoDS_Face& fdsc = TopoDS::Face(it.Value()); 
2378       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
2379         if (exp.Current().IsSame(fdsc)) { // preserved
2380           newdsc.Add(fdsc);
2381           break;
2382         }
2383       }
2384       if (!exp.More()) {
2385         BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
2386         const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
2387         it2.Initialize(aLM);
2388         for (; it2.More(); it2.Next()) {
2389           const TopoDS_Shape& aS=it2.Value();
2390           newdsc.Add(aS);
2391         }
2392         
2393       }
2394     }
2395     myMap.ChangeFind(orig).Clear();
2396     for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
2397        // check the belonging to the shape...
2398       for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
2399         if (exp.Current().IsSame(itm.Key())) {
2400 //          const TopoDS_Shape& sh = itm.Key();
2401           myMap.ChangeFind(orig).Append(itm.Key());
2402           break;
2403         }
2404       }
2405     }
2406   }
2407 }
2408 //modified by NIZNHY-PKV Thu Mar 21 18:43:36 2002 t