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