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