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