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