0028567: Get rid of the unused DRAW commands based on old Boolean Operations (BRepAlgo)
[occt.git] / src / BRepFeat / BRepFeat_MakeRevolutionForm.cxx
1 // Created on: 1997-10-14
2 // Created by: Olga KOULECHOVA
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAlgo.hxx>
21 #include <BRepAlgoAPI_Common.hxx>
22 #include <BRepAlgoAPI_Cut.hxx>
23 #include <BRepAlgoAPI_Section.hxx>
24 #include <BRepBuilderAPI_MakeFace.hxx>
25 #include <BRepBuilderAPI_Transform.hxx>
26 #include <BRepExtrema_ExtCF.hxx>
27 #include <BRepExtrema_ExtPC.hxx>
28 #include <BRepFeat.hxx>
29 #include <BRepFeat_MakeRevolutionForm.hxx>
30 #include <BRepLib_MakeEdge.hxx>
31 #include <BRepLib_MakeFace.hxx>
32 #include <BRepLib_MakeVertex.hxx>
33 #include <BRepPrimAPI_MakeBox.hxx>
34 #include <BRepTools.hxx>
35 #include <BRepTools_Modifier.hxx>
36 #include <BRepTools_TrsfModification.hxx>
37 #include <BRepTools_WireExplorer.hxx>
38 #include <BRepTopAdaptor_FClass2d.hxx>
39 #include <CSLib.hxx>
40 #include <ElCLib.hxx>
41 #include <ElSLib.hxx>
42 #include <Geom2d_Curve.hxx>
43 #include <Geom2d_Line.hxx>
44 #include <Geom2dAPI_ExtremaCurveCurve.hxx>
45 #include <Geom2dAPI_InterCurveCurve.hxx>
46 #include <Geom_Circle.hxx>
47 #include <Geom_ConicalSurface.hxx>
48 #include <Geom_Curve.hxx>
49 #include <Geom_CylindricalSurface.hxx>
50 #include <Geom_Line.hxx>
51 #include <Geom_Plane.hxx>
52 #include <Geom_RectangularTrimmedSurface.hxx>
53 #include <Geom_Surface.hxx>
54 #include <Geom_ToroidalSurface.hxx>
55 #include <Geom_TrimmedCurve.hxx>
56 #include <GeomAPI.hxx>
57 #include <GeomAPI_ProjectPointOnCurve.hxx>
58 #include <GeomLProp_CLProps.hxx>
59 #include <GeomProjLib.hxx>
60 #include <gp_Ax1.hxx>
61 #include <gp_Lin.hxx>
62 #include <gp_Pln.hxx>
63 #include <gp_Pnt.hxx>
64 #include <gp_Pnt2d.hxx>
65 #include <gp_Vec.hxx>
66 #include <gp_Vec2d.hxx>
67 #include <IntRes2d_IntersectionPoint.hxx>
68 #include <LocOpe.hxx>
69 #include <LocOpe_CSIntersector.hxx>
70 #include <LocOpe_FindEdges.hxx>
71 #include <LocOpe_Gluer.hxx>
72 #include <LocOpe_PntFace.hxx>
73 #include <LocOpe_RevolutionForm.hxx>
74 #include <Precision.hxx>
75 #include <Standard_ConstructionError.hxx>
76 #include <TColGeom_Array1OfCurve.hxx>
77 #include <TColGeom_SequenceOfCurve.hxx>
78 #include <TColgp_Array1OfPnt.hxx>
79 #include <TColgp_SequenceOfPnt.hxx>
80 #include <TColStd_Array1OfReal.hxx>
81 #include <TopExp.hxx>
82 #include <TopExp_Explorer.hxx>
83 #include <TopoDS.hxx>
84 #include <TopoDS_Edge.hxx>
85 #include <TopoDS_Face.hxx>
86 #include <TopoDS_Shape.hxx>
87 #include <TopoDS_Wire.hxx>
88 #include <TopOpeBRepBuild_HBuilder.hxx>
89 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
90 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
91 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
92 #include <TopTools_ListIteratorOfListOfShape.hxx>
93 #include <TopTools_ListOfShape.hxx>
94 #include <TopTools_MapIteratorOfMapOfShape.hxx>
95 #include <TopTools_MapOfShape.hxx>
96
97 #ifdef OCCT_DEBUG
98 extern Standard_Boolean BRepFeat_GettraceFEAT();
99 extern Standard_Boolean BRepFeat_GettraceFEATRIB();
100 #endif
101
102 static void MajMap(const TopoDS_Shape&, // base
103                    const LocOpe_RevolutionForm&,
104                    TopTools_DataMapOfShapeListOfShape&, // myMap
105                    TopoDS_Shape&,  // myFShape
106                    TopoDS_Shape&); // myLShape
107
108 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
109                           LocOpe_RevolutionForm&,
110                           const TopTools_DataMapOfShapeListOfShape& SlidingMap,
111                           TopTools_DataMapOfShapeShape&);
112
113 //=======================================================================
114 //function : Init
115 //purpose  : 
116 //=======================================================================
117
118 void BRepFeat_MakeRevolutionForm::Init(const TopoDS_Shape& Sbase,
119                                        const TopoDS_Wire& W,
120                                        const Handle(Geom_Plane)& Plane,
121                                        const gp_Ax1& Axis,
122                                        const Standard_Real H1,
123                                        const Standard_Real H2,
124                                        const Standard_Integer Mode,
125                                        Standard_Boolean& Modify)
126
127 #ifdef OCCT_DEBUG
128   Standard_Boolean trc = BRepFeat_GettraceFEAT();
129   if (trc) cout << "BRepFeat_MakeRevolutionForm::Init" << endl;
130 #endif
131   Standard_Boolean RevolRib = Standard_True;
132   Done();
133
134 // modify = 0 if it is not required to make sliding
135 //        = 1 if it is intended to try to make sliding
136   Standard_Boolean Sliding = Modify;
137
138   myAxe = Axis;
139   Handle(Geom_Line) Line = new Geom_Line(Axis); 
140   Standard_Real LineFirst, LineLast;
141   
142   LocOpe_CSIntersector ASI(Sbase);
143   TColGeom_SequenceOfCurve scur;
144   scur.Clear();
145   scur.Append(Line);
146   ASI.Perform(scur);
147   if(ASI.IsDone() && ASI.NbPoints(1) >= 2) {
148     LineLast = ASI.Point(1, ASI.NbPoints(1)).Parameter();
149     LineFirst = ASI.Point(1, 1).Parameter();
150   }
151   else {
152     LineFirst = RealFirst();
153     LineLast = RealLast();
154   }
155   
156   Handle(Geom2d_Curve) ln2d = GeomAPI::To2d(Line, Plane->Pln());
157   
158   TopExp_Explorer exx;
159   Standard_Real Rad = RealLast();
160   
161   exx.Init(W, TopAbs_EDGE);
162   for(; exx.More(); exx.Next()) {
163     const TopoDS_Edge& e = TopoDS::Edge(exx.Current());
164     Standard_Real f, l;
165     Handle(Geom_Curve) c = BRep_Tool::Curve(e, f, l);
166     Handle(Geom2d_Curve) c2d = GeomAPI::To2d(c, Plane->Pln());
167     Geom2dAPI_ExtremaCurveCurve extr(ln2d, c2d, LineFirst, LineLast,f,l);
168     Quantity_Length L = RealLast();
169     if(extr.NbExtrema() >= 1) {
170       L = extr.LowerDistance();
171     }
172     gp_Pnt p1 = c->Value(f);
173     gp_Pnt p2 = c->Value(l);
174     GeomAPI_ProjectPointOnCurve proj1(p1, Line);
175     GeomAPI_ProjectPointOnCurve proj2(p2, Line);
176     if(proj1.NbPoints() < 1 || proj2.NbPoints() < 1) {
177 #ifdef OCCT_DEBUG
178       if (trc) cout << " No projection points" << endl;
179 #endif
180       myStatusError = BRepFeat_NoProjPt;
181       NotDone();
182       return;
183     }
184     Standard_Real par1 = proj1.Distance(1);
185     Standard_Real par2 = proj2.Distance(1);
186     Standard_Real Par  = Min(par1, par2);
187     if(Par<L) L = Par;
188     if(L<Rad && L > 0.) Rad = L;
189   }
190   
191   Standard_Real height = Min(H1, H2);
192   
193   if(Rad <= height) Rad = height + 0.01*height;  
194   
195   myAngle1 = asin(H1/Rad) + M_PI/10.;
196   myAngle2 = asin(H2/Rad) + M_PI/10.;
197   
198   if((myAngle1 - M_PI/2) > Precision::Confusion())
199     myAngle1 = M_PI/2;
200   if((myAngle2 - M_PI/2) > Precision::Confusion())
201     myAngle2 = M_PI/2;
202   
203   mySkface.Nullify();
204   myPbase.Nullify();
205
206   if(Mode == 0) 
207     myFuse   = Standard_False;
208   else // if(Mode == 1) 
209     myFuse   = Standard_True;
210 #ifdef OCCT_DEBUG
211   if (trc) {
212     if (myFuse)  cout << " Fuse" << endl;
213     if (!myFuse)  cout << " Cut" << endl;
214   }
215 #endif
216
217 // ---Determination Tolerance : tolerance max on parameters
218   myTol = Precision::Confusion();
219   
220   exx.Init(W, TopAbs_VERTEX);
221   for(; exx.More(); exx.Next()) {
222     const Standard_Real& tol = BRep_Tool::
223       Tolerance(TopoDS::Vertex(exx.Current()));
224     if(tol > myTol) myTol = tol;
225   }
226   
227   exx.Init(Sbase, TopAbs_VERTEX);
228   for(; exx.More(); exx.Next()) {
229     const Standard_Real& tol = BRep_Tool::
230       Tolerance(TopoDS::Vertex(exx.Current()));
231     if(tol > myTol) myTol = tol;
232   }
233
234   TopoDS_Shape aLocalShapeW = W.Oriented(TopAbs_FORWARD);
235   myWire = TopoDS::Wire(aLocalShapeW);
236 //  myWire = TopoDS::Wire(W.Oriented(TopAbs_FORWARD));
237   myPln = Plane;
238   myHeight1 = H1;
239   myHeight2 = H2;
240   
241   mySbase  = Sbase;
242   mySlface.Clear();
243   myShape.Nullify();
244   myMap.Clear();
245   myFShape.Nullify();
246   myLShape.Nullify();
247
248 // ---Calculate bounding box
249   BRep_Builder BB;
250   
251   TopTools_ListOfShape theList;  
252   
253   TopoDS_Shape U;
254   U.Nullify();
255   gp_Pnt FirstCorner, LastCorner;
256   Standard_Real bnd = HeightMax(mySbase, U, FirstCorner, LastCorner);
257   myBnd = bnd;
258   
259   BRepPrimAPI_MakeBox Bndbox(FirstCorner, LastCorner);
260   TopoDS_Solid BndBox = Bndbox.Solid();
261
262
263 // ---Construction of the working plane face (section bounding box)
264   BRepLib_MakeFace PlaneF(myPln->Pln(), -6.*myBnd, 
265                           6.*myBnd, -6.*myBnd, 6.*myBnd);
266   TopoDS_Face PlaneFace = TopoDS::Face(PlaneF.Shape());
267   
268   BRepAlgoAPI_Common PlaneS(BndBox, PlaneFace);
269   TopExp_Explorer EXP;
270   TopoDS_Shape PlaneSect = PlaneS.Shape();
271   EXP.Init(PlaneSect, TopAbs_WIRE);
272   TopoDS_Wire www = TopoDS::Wire(EXP.Current());
273   BRepLib_MakeFace Bndface(myPln->Pln(), www, Standard_True);
274   TopoDS_Face BndFace = TopoDS::Face(Bndface.Shape());
275
276
277 // ---Find base faces of the rib    
278   TopoDS_Edge FirstEdge, LastEdge;
279   TopoDS_Face FirstFace, LastFace;
280   TopoDS_Vertex FirstVertex, LastVertex;
281   
282   Standard_Boolean OnFirstFace = Standard_False;
283   Standard_Boolean OnLastFace = Standard_False;
284   Standard_Boolean PtOnFirstEdge = Standard_False;
285   Standard_Boolean PtOnLastEdge = Standard_False;
286   TopoDS_Edge OnFirstEdge, OnLastEdge;
287   OnFirstEdge.Nullify();
288   OnLastEdge.Nullify();
289
290   Standard_Boolean Data = ExtremeFaces(RevolRib, myBnd, myPln, FirstEdge, LastEdge, 
291                                        FirstFace, LastFace, FirstVertex, 
292                                        LastVertex, OnFirstFace, OnLastFace,
293                                        PtOnFirstEdge, PtOnLastEdge,
294                                        OnFirstEdge, OnLastEdge);
295   
296   if(!Data) {
297 #ifdef OCCT_DEBUG
298     if (trc) cout << " No Extreme faces" << endl;
299 #endif
300     myStatusError = BRepFeat_NoExtFace;
301     NotDone();
302     return;
303   }
304
305
306 // ---Proofing Point for the side of the wire to be filled - material side
307   gp_Pnt CheckPnt = CheckPoint(FirstEdge, bnd/10., myPln);
308   
309 //  Standard_Real f, l;
310
311 // ---Control sliding valid
312 // Many cases when the sliding is abandoned
313   Standard_Integer Concavite = 3;  // a priori the profile is not concave
314   
315   myFirstPnt = BRep_Tool::Pnt(FirstVertex);
316   myLastPnt  = BRep_Tool::Pnt(LastVertex);
317
318 // SliList : list of faces concerned by the rib
319   TopTools_ListOfShape SliList;
320   SliList.Append(FirstFace);
321   
322   if(Sliding) {    // sliding
323 #ifdef OCCT_DEBUG
324     if (trc) cout << " Sliding" << endl;
325 #endif
326     Handle(Geom_Surface) s = BRep_Tool::Surface(FirstFace);
327     if (s->DynamicType() == 
328         STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
329       s = Handle(Geom_RectangularTrimmedSurface)::
330         DownCast(s)->BasisSurface();
331     }
332     if(s->DynamicType() != STANDARD_TYPE(Geom_Plane) && 
333        s->DynamicType() != STANDARD_TYPE(Geom_CylindricalSurface) &&
334        s->DynamicType() != STANDARD_TYPE(Geom_ConicalSurface) &&
335        s->DynamicType() != STANDARD_TYPE(Geom_ToroidalSurface)) 
336       Sliding = Standard_False;
337   }
338
339   if(Sliding) {     // sliding
340     Handle(Geom_Surface) ss = BRep_Tool::Surface(LastFace);
341     if (ss->DynamicType() == 
342         STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
343       ss = Handle(Geom_RectangularTrimmedSurface)::
344         DownCast(ss)->BasisSurface();
345     }
346     if(ss->DynamicType() != STANDARD_TYPE(Geom_Plane) && 
347        ss->DynamicType() != STANDARD_TYPE(Geom_CylindricalSurface) &&
348        ss->DynamicType() != STANDARD_TYPE(Geom_ConicalSurface) &&
349        ss->DynamicType() != STANDARD_TYPE(Geom_ToroidalSurface)) 
350       Sliding = Standard_False;
351   }
352
353 // Control only start and end points no control at the middle to improve
354 // If make a control between Surface and segment 2 points limited
355 // -> too expensive - to improve  
356   //gp_Pnt FirstCenter, LastCenter;
357   gp_Circ FirstCircle, LastCircle;
358   Handle(Geom_Curve) FirstCrv, LastCrv;
359   
360   if(Sliding) {    // sliding
361     GeomAPI_ProjectPointOnCurve proj(myFirstPnt, Line);
362     if(proj.NbPoints() < 1) {
363 #ifdef OCCT_DEBUG
364       if (trc) cout << " No First Point projection" << endl;
365 #endif
366       myStatusError = BRepFeat_NoProjPt;
367       NotDone();
368       return;
369     }
370     Standard_Real FirstRayon = proj.Distance(1);
371     gp_Pnt FirstCenter = proj.Point(1);
372     
373     GeomAPI_ProjectPointOnCurve proj1(myLastPnt, Line);
374     if(proj.NbPoints() < 1) {
375 #ifdef OCCT_DEBUG
376       if (trc) cout << " No Last Point projection" << endl;
377 #endif
378       myStatusError = BRepFeat_NoProjPt;
379       NotDone();
380       return;
381     }
382     Standard_Real LastRayon = proj1.Distance(1);
383     gp_Pnt LastCenter = proj1.Point(1);
384     
385     gp_Vec axv(myAxe.Direction());
386     gp_Ax2 ax2(FirstCenter, axv);
387     gp_Ax2 ax2p(LastCenter, axv);
388     gp_Circ theFC(ax2, FirstRayon);
389     gp_Circ theLC(ax2p, LastRayon);
390     
391     gp_Pnt RFirstPnt1 = myFirstPnt.Rotated(myAxe, myAngle1);
392     gp_Pnt RLastPnt1 = myLastPnt.Rotated(myAxe, myAngle1);
393     gp_Pnt RFirstPnt2 = myFirstPnt.Rotated(myAxe, -myAngle2);
394     gp_Pnt RLastPnt2 = myLastPnt.Rotated(myAxe, -myAngle2);
395     
396     BRep_Builder Bu;
397     TopoDS_Vertex v1, v2, v3, v4;
398     Bu.MakeVertex(v1, RFirstPnt2, Precision::Confusion());
399     Bu.MakeVertex(v2, RFirstPnt1, Precision::Confusion());
400     Bu.MakeVertex(v3, RLastPnt2, Precision::Confusion());
401     Bu.MakeVertex(v4, RLastPnt1, Precision::Confusion());
402     
403     BRepLib_MakeEdge ee1(theFC, v1, v2);
404     BRepLib_MakeEdge ee2(theLC, v3, v4);
405     
406     if(Sliding && !PtOnFirstEdge) {
407       BRepExtrema_ExtCF ext1(TopoDS::Edge(ee1.Shape()), FirstFace);
408       if(ext1.NbExt() < 1 || ext1.SquareDistance(1) > Precision::SquareConfusion())
409         Sliding = Standard_False;
410     }
411     if(Sliding && !PtOnLastEdge) {
412       BRepExtrema_ExtCF ext2(ee2, LastFace); // ExtCF : curves and surfaces
413       if(ext2.NbExt() < 1 || ext2.SquareDistance(1) > Precision::SquareConfusion())
414         Sliding = Standard_False;
415     }
416     if(Sliding && PtOnFirstEdge) {
417       Standard_Real f, l;
418       FirstCrv = BRep_Tool::Curve(OnFirstEdge, f, l);
419       if(FirstCrv->DynamicType() != STANDARD_TYPE(Geom_Circle)) 
420         Sliding = Standard_False;
421       else {
422         Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(FirstCrv);
423         gp_Circ Circ = C1->Circ();
424         FirstCircle = Circ;
425         gp_Ax1 circax = FirstCircle.Axis();
426         if(!circax.IsCoaxial(myAxe, Precision::Confusion(), 
427                              Precision::Confusion())) 
428           Sliding = Standard_False;
429         else {
430 //#ifndef OCCT_DEBUG
431           if(fabs(FirstCircle.Radius()-FirstRayon) >=
432 //#else
433 //        if(abs(FirstCircle.Radius()-FirstRayon) >=
434 //#endif
435              Precision::Confusion()) 
436             Sliding = Standard_False;
437         }       
438       }
439     }
440     
441     if(Sliding && PtOnLastEdge) {
442       Standard_Real f, l;
443       LastCrv = BRep_Tool::Curve(OnLastEdge, f, l);
444       if(LastCrv->DynamicType() != STANDARD_TYPE(Geom_Circle)) 
445         Sliding = Standard_False;
446       else {
447         Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(LastCrv);
448         gp_Circ Circ = C1->Circ();
449         LastCircle = Circ;
450         gp_Ax1 circax = LastCircle.Axis();
451         if(!circax.IsCoaxial(myAxe, Precision::Confusion(), 
452                              Precision::Confusion())) 
453           Sliding = Standard_False;
454         else {
455           Standard_Real rad = LastCircle.Radius();
456 //#ifndef OCCT_DEBUG
457           if(fabs(rad - LastRayon) >= Precision::Confusion()) { 
458 //#else
459 //        if(abs(rad - LastRayon) >= Precision::Confusion()) { 
460 //#endif
461             Sliding = Standard_False;
462           }     
463         }
464       }
465     }
466   }
467
468
469 // Construct a great profile that goes till the bounding box
470 // -> by tangency with first and last edge of the Wire
471 // -> by normals to base faces : statistically better
472 // Intersect everythin to find the final profile
473
474
475 // ---case of sliding : construction of the face profile
476   if(Sliding) {
477 #ifdef OCCT_DEBUG
478     if (trc) cout << " still Sliding" << endl;
479 #endif
480     TopoDS_Face Prof;
481     Standard_Boolean ProfileOK;
482     ProfileOK = SlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,BndFace,CheckPnt,
483                                FirstFace,LastFace,FirstVertex,LastVertex,
484                                FirstEdge,LastEdge);
485
486     if (!ProfileOK) {
487 #ifdef OCCT_DEBUG
488       if (trc)
489       {
490         cout << "Not computable" << endl;
491         cout << "Face profile not computable" << endl;
492       }
493 #endif
494       myStatusError = BRepFeat_NoFaceProf;
495       NotDone();
496       return;
497     }
498
499
500 // ---Propagation on faces of the initial shape
501 // to find the faces concerned by the rib
502     Standard_Boolean falseside = Standard_True;
503     Sliding = Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
504 // Control if there is everything required to have the material at the proper side
505     if(falseside == Standard_False) {
506 #ifdef OCCT_DEBUG
507       cout << " Verify plane and wire orientation" << endl;
508 #endif
509       myStatusError = BRepFeat_FalseSide;
510       NotDone();
511       return;
512     }
513   }
514
515
516 // ---Generation of the base profile of the rib
517
518   TopoDS_Wire w;
519   BB.MakeWire(w);
520   TopoDS_Edge thePreviousEdge;
521   TopoDS_Vertex theFV;
522   thePreviousEdge.Nullify();
523
524 // counter of the number of edges to fill the map
525   Standard_Integer counter = 1;
526
527 // ---case of sliding 
528   if(Sliding && !myListOfEdges.IsEmpty()) {
529     BRepTools_WireExplorer EX1(myWire);
530     for(; EX1.More(); EX1.Next()) {
531       const TopoDS_Edge& E = EX1.Current();
532       if(!myLFMap.IsBound(E)) {
533         TopTools_ListOfShape theTmpList;
534         myLFMap.Bind(E, theTmpList);
535       }      
536       if(E.IsSame(FirstEdge)) {
537         Standard_Real f, l;
538         Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
539         gp_Pnt pt;
540         if(!FirstEdge.IsSame(LastEdge)) {
541           pt = BRep_Tool::Pnt(TopExp::LastVertex(E,Standard_True)); 
542         }
543         else {
544           pt = myLastPnt;
545           Standard_Real fpar = IntPar(cc, myFirstPnt);
546           Standard_Real lpar = IntPar(cc, pt);
547           if(fpar > lpar) {
548             cc = cc->Reversed();
549           }
550         }
551         TopoDS_Edge ee1;
552         if(thePreviousEdge.IsNull()) {
553           BRepLib_MakeVertex v1(myFirstPnt);
554           BRepLib_MakeVertex v2(pt);      
555           BRepLib_MakeEdge e(cc, v1, v2);
556           ee1 = TopoDS::Edge(e.Shape());
557         } 
558         else {
559           const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
560           BRepLib_MakeVertex v2(pt);
561           
562           BRepLib_MakeEdge e(cc, v1, v2);
563           ee1 = TopoDS::Edge(e.Shape());
564         }
565         TopoDS_Shape aLocalShape = ee1.Oriented(E.Orientation());
566         ee1 = TopoDS::Edge(aLocalShape);
567 //      ee1 = TopoDS::Edge(ee1.Oriented(E.Orientation()));
568         if(counter == 1) theFV = TopExp::FirstVertex(ee1,Standard_True);
569         myLFMap(E).Append(ee1);
570         BB.Add(w, ee1);
571         thePreviousEdge = ee1;
572         counter++;
573         EX1.Next();
574         break;
575       }
576     }
577
578 // Case of several edges
579     if(!FirstEdge.IsSame(LastEdge)) {
580       for(; EX1.More(); EX1.Next()) {
581         const TopoDS_Edge& E = EX1.Current();
582         if(!myLFMap.IsBound(E)) {
583           TopTools_ListOfShape thelist1;
584           myLFMap.Bind(E, thelist1);
585         }      
586         theList.Append(E);
587         Standard_Real f, l;
588         if(!E.IsSame(LastEdge)) {
589           Handle(Geom_Curve) ccc = BRep_Tool::Curve(E, f, l);
590           TopoDS_Vertex v1, v2;
591           if(!thePreviousEdge.IsNull()) {
592             v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
593             v2 = TopExp::LastVertex(E,Standard_True);
594           }
595           else {
596 //          v1 = TopExp::LastVertex(E,Standard_True);
597             v1 = TopExp::FirstVertex(E,Standard_True);
598             v2 = TopExp::LastVertex(E,Standard_True);
599           }
600           BRepLib_MakeEdge E1(ccc, v1, v2);
601           TopoDS_Edge E11 = TopoDS::Edge(E1.Shape());
602           TopoDS_Shape aLocalShape = E11.Oriented(E.Orientation());
603           E11 = TopoDS::Edge(aLocalShape);
604 //        E11 = TopoDS::Edge(E11.Oriented(E.Orientation()));
605           thePreviousEdge = E11;
606           myLFMap(E).Append(E11);
607           BB.Add(w, E11);
608           if(counter == 1) theFV = TopExp::FirstVertex(E11,Standard_True);
609           counter++;
610         }
611         else {
612           Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
613           gp_Pnt pf = BRep_Tool::Pnt(TopExp::FirstVertex(E,Standard_True));
614           gp_Pnt pl = myLastPnt;
615           TopoDS_Edge ee;
616           if(thePreviousEdge.IsNull()) {
617             BRepLib_MakeEdge e(cc, pf , pl); 
618             ee = TopoDS::Edge(e.Shape());
619           }
620           else {
621             const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
622             BRepLib_MakeVertex v2(pl);
623             BRepLib_MakeEdge e(cc, v1, v2);
624             ee = TopoDS::Edge(e.Shape());
625           }
626           TopoDS_Shape aLocalShape = ee.Oriented(E.Orientation());
627           ee = TopoDS::Edge(aLocalShape);
628 //        ee = TopoDS::Edge(ee.Oriented(E.Orientation()));
629           BB.Add(w, ee);
630           myLFMap(E).Append(ee);
631           if(counter == 1) theFV = TopExp::FirstVertex(ee,Standard_True);
632           thePreviousEdge = ee;
633           counter++;
634           break;
635         }
636       }
637     }
638     
639     TopTools_ListIteratorOfListOfShape it(myListOfEdges);
640     Standard_Boolean FirstOK = Standard_False;
641     Standard_Boolean LastOK = Standard_False;
642     
643     gp_Pnt theLastPnt = myLastPnt;
644     Standard_Integer sens = 0;
645     TopoDS_Edge theEdge, theLEdge, theFEdge;
646     Standard_Integer counter1 = counter;
647     TopTools_ListOfShape NewListOfEdges;
648     NewListOfEdges.Clear();
649     while (!FirstOK) {
650       const TopoDS_Edge& edg = TopoDS::Edge(it.Value());
651       gp_Pnt fp, lp;
652       Standard_Real f, l;
653       Handle(Geom_Curve) ccc = BRep_Tool::Curve(edg, f, l);
654       Handle(Geom_TrimmedCurve) cc = new Geom_TrimmedCurve(ccc, f, l);
655       if ( edg.Orientation() == TopAbs_REVERSED) cc->Reverse();
656       
657       fp = cc->Value(cc->FirstParameter());
658       lp = cc->Value(cc->LastParameter());
659       Standard_Real dist = fp.Distance(theLastPnt);
660       if(dist <= myTol) {
661         sens = 1;
662         LastOK = Standard_True;
663       }
664       else {
665         dist = lp.Distance(theLastPnt);
666         if(dist <= myTol) {
667           sens = 2;
668           LastOK = Standard_True;
669           cc->Reverse();
670         }
671       }
672       Standard_Integer FirstFlag = 0;
673       if(sens==1 && lp.Distance(myFirstPnt) <= myTol) {
674         FirstOK = Standard_True;
675         FirstFlag = 1;
676       }
677       else if(sens==2 && fp.Distance(myFirstPnt) <= myTol) {
678         FirstOK = Standard_True;
679         FirstFlag = 2;
680       }
681       
682       if (LastOK) {
683         TopoDS_Edge eeee;
684         Standard_Real fpar = cc->FirstParameter();
685         Standard_Real lpar = cc->LastParameter();
686         if(!FirstOK) {
687           if(thePreviousEdge.IsNull()) {
688             BRepLib_MakeEdge e(cc, fpar, lpar);
689             eeee = TopoDS::Edge(e.Shape());
690           }
691           else {
692             const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
693             BRepLib_MakeVertex v2(cc->Value(lpar));
694             BRepLib_MakeEdge e(cc, v1, v2);
695             eeee = TopoDS::Edge(e.Shape());
696           }
697         }
698         else {
699           if(thePreviousEdge.IsNull()) {
700             BRepLib_MakeVertex v1(cc->Value(fpar)); 
701             BRepLib_MakeEdge e(cc, v1, theFV);
702             eeee = TopoDS::Edge(e.Shape());
703           }
704           else {
705             const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
706             BRepLib_MakeEdge e(cc, v1, theFV);
707             eeee = TopoDS::Edge(e.Shape());
708           }
709         }
710
711         thePreviousEdge = eeee;
712         BB.Add(w, eeee);
713         if(counter == 1) theFV = TopExp::FirstVertex(eeee,Standard_True);
714         counter1++;
715         NewListOfEdges.Append(edg);
716         theEdge = eeee;
717
718         if(dist <= myTol) 
719           theFEdge = edg;
720         theLastPnt = BRep_Tool::Pnt(TopExp::LastVertex(theEdge,Standard_True));
721       }
722
723       if(FirstFlag == 1) {
724         theLEdge = edg;
725       }
726       else if(FirstFlag == 2) {
727         theLEdge = theEdge;
728       }
729
730       if(LastOK) {
731         it.Initialize(myListOfEdges);
732         LastOK = Standard_False;
733       }
734       else if(it.More()) it.Next();
735       else {
736         Sliding = Standard_False;
737         break;
738       } 
739       sens = 0;
740     }
741     
742     
743     TopTools_DataMapOfShapeListOfShape SlidMap;
744     SlidMap.Clear();
745     
746     if(Sliding && counter1 > counter) {
747       TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm;
748       TopExp_Explorer EX2(w, TopAbs_EDGE);
749       Standard_Integer ii = 0;
750       for(; EX2.More(); EX2.Next()) {
751         const TopoDS_Edge& E = TopoDS::Edge(EX2.Current());
752         ii++;   
753         if(ii >= counter && ii <= counter1) {
754           it.Initialize(NewListOfEdges);
755           Standard_Integer jj = 0;
756           for(; it.More(); it.Next()) {
757             const TopoDS_Edge& e2 = TopoDS::Edge(it.Value());
758             jj++;
759             if(jj== (ii - counter +1)) {          
760               itm.Initialize(mySlface);
761               for(; itm.More(); itm.Next()) {
762                 const TopoDS_Face& fac = TopoDS::Face(itm.Key());
763                 const TopTools_ListOfShape& ledg = itm.Value();
764                 TopTools_ListIteratorOfListOfShape itedg(ledg);
765                 //Standard_Integer iiii = 0;
766                 for(; itedg.More(); itedg.Next()) {
767                   const TopoDS_Edge& e1 = TopoDS::Edge(itedg.Value());
768                   if(e1.IsSame(e2)){
769                     if(!SlidMap.IsBound(fac)) {
770                       TopTools_ListOfShape thelist2;
771                       SlidMap.Bind(fac, thelist2);
772                     }
773                     SlidMap(fac).Append(E);
774                   }
775                 }               
776               }
777             }
778           } 
779         }
780       }
781     }
782     
783     mySlface.Clear();
784     mySlface = SlidMap;
785   }
786
787 // ---Arguments of LocOpe_LinearForm : arguments of the prism
788 // sliding
789   if(Sliding) {
790     TopoDS_Face F;
791     BB.MakeFace(F, myPln, myTol);
792     w.Closed (BRep_Tool::IsClosed (w));
793     BB.Add(F, w);
794     mySkface = F;
795     myPbase  = mySkface;
796     mySUntil.Nullify();
797   }
798
799
800 // ---Case without sliding : construction of the face profile  
801   if(!Sliding) {
802 #ifdef OCCT_DEBUG
803     if (trc) {
804       if (Modify) cout << " Sliding failure" << endl;
805       cout << " no Sliding" << endl;
806     }
807 #endif
808     TopExp_Explorer explo1(BndFace, TopAbs_WIRE);
809     TopoDS_Wire WWW = TopoDS::Wire(explo1.Current());
810     BRepTools_WireExplorer explo(WWW);
811     BRep_Builder Bu;
812     TopoDS_Wire Wiwiwi;
813     Bu.MakeWire(Wiwiwi);
814     TopoDS_Vertex NewV1, NewV2, LastV, v; 
815     NewV1.Nullify(); NewV2.Nullify(); LastV.Nullify();
816
817     for(; explo.More(); explo.Next()) {
818       const TopoDS_Edge& e = TopoDS::Edge(explo.Current());
819       TopoDS_Vertex v1 = TopExp::FirstVertex(e,Standard_True);
820       TopoDS_Vertex v2 = TopExp::LastVertex(e,Standard_True);
821             
822       Standard_Real f, l;//, t;
823       Handle(Geom_Curve) ln = BRep_Tool::Curve(e, f, l);
824 //      Handle(Geom_Curve) lln = BRep_Tool::Curve(e, f, l);
825 //      Handle(Geom_Curve) ln;
826 //      if(e.Orientation() == TopAbs_REVERSED) {
827 //      ln = Handle(Geom_Curve)::DownCast(lln->Reversed());
828 //      v = v1; v1 = v2; v2= v;
829 //      f = IntPar(ln, BRep_Tool::Pnt(v1));
830 //      l = IntPar(ln, BRep_Tool::Pnt(v2));
831 //      }
832 //      else ln = lln;
833
834       Handle(Geom2d_Curve) l2d = GeomAPI::To2d(ln, Plane->Pln());
835       Geom2dAPI_InterCurveCurve intcc(l2d, ln2d, Precision::Confusion());
836       TopoDS_Vertex VV; VV.Nullify();
837
838       if(intcc.NbPoints() > 0) {
839         gp_Pnt2d P = intcc.Point(1);
840         gp_Pnt point;
841         myPln->D0(P.X(), P.Y(), point);
842         Standard_Real par = IntPar(ln, point);
843         if(f <= par && l >= par) {
844           Bu.MakeVertex(VV, point, Precision::Confusion());
845         }
846       }
847       
848       if(VV.IsNull() && NewV1.IsNull()) continue;
849
850       if(!VV.IsNull() && NewV1.IsNull()) {
851         NewV1 = VV;
852         LastV = v2;
853         BRepLib_MakeEdge ee1(NewV1, LastV);
854         Bu.Add(Wiwiwi, ee1); 
855         continue;
856       } 
857
858       if(VV.IsNull() && !NewV1.IsNull()) {
859         BRepLib_MakeEdge ee1(LastV, v2);
860         LastV = v2;
861         Bu.Add(Wiwiwi, e); 
862         continue;
863       } 
864       
865       if(!VV.IsNull() && !NewV1.IsNull()) {
866         NewV2 = VV;
867         BRepLib_MakeEdge ee1(LastV, NewV2);
868         LastV = NewV2;
869         Bu.Add(Wiwiwi, ee1); 
870         BRepLib_MakeEdge ee2(LastV, NewV1);
871         Bu.Add(Wiwiwi, ee2);
872         break;
873       } 
874     }
875     Wiwiwi.Closed (BRep_Tool::IsClosed (Wiwiwi));
876     
877     BRepLib_MakeFace newbndface(myPln->Pln(), Wiwiwi, Standard_True);
878     TopoDS_Face NewBndFace = TopoDS::Face(newbndface.Shape());
879
880     BRepTopAdaptor_FClass2d Cl(NewBndFace, Precision::Confusion());
881     Standard_Real paru, parv;
882     ElSLib::Parameters(myPln->Pln(), CheckPnt, paru, parv);
883     gp_Pnt2d checkpnt2d(paru, parv);
884     if(Cl.Perform(checkpnt2d, Standard_True) == TopAbs_OUT) {
885       BRepAlgoAPI_Cut c(BndFace, NewBndFace);     
886       TopExp_Explorer exp(c.Shape(), TopAbs_WIRE);
887       const TopoDS_Wire& aCurWire = TopoDS::Wire(exp.Current());
888       BRepLib_MakeFace ff(myPln->Pln(), aCurWire, Standard_True);
889       NewBndFace = TopoDS::Face(ff.Shape());
890     }
891    
892     
893     if(!BRepAlgo::IsValid(NewBndFace)) {
894 #ifdef OCCT_DEBUG
895       cout << "Invalid new bounding face" << endl;
896 #endif
897       myStatusError = BRepFeat_InvShape;
898       NotDone();
899       return;      
900     }
901     
902     BndFace = NewBndFace;
903
904
905     TopoDS_Face Prof;
906     Standard_Boolean ProfileOK;
907     ProfileOK = NoSlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,
908                                  bnd,BndFace,CheckPnt,
909                                  FirstFace,LastFace,FirstVertex,LastVertex,
910                                  FirstEdge,LastEdge,OnFirstFace,OnLastFace);
911
912     if (!ProfileOK) {
913 #ifdef OCCT_DEBUG
914       if (trc)
915       {
916         cout << "Not computable" << endl;
917         cout << " Face profile not computable" << endl;
918       }
919 #endif
920       myStatusError = BRepFeat_NoFaceProf;
921       NotDone();
922       return;
923     }
924
925
926 // ---Propagation on the faces of the initial shape
927 // to find the faces concerned by the rib
928     Standard_Boolean falseside = Standard_True;
929     Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
930 // Control if there is everything required to have the material at the proper side
931     if(falseside == Standard_False) {
932 #ifdef OCCT_DEBUG
933       cout << " Verify plane and wire orientation" << endl;
934 #endif
935       myStatusError = BRepFeat_FalseSide;
936       NotDone();
937       return;
938     }
939     
940     mySlface.Clear();
941
942     TopTools_ListIteratorOfListOfShape it;
943     it.Initialize(SliList);
944     
945     TopoDS_Shape comp;
946     
947     BB.MakeShell(TopoDS::Shell(comp));
948     
949     for(; it.More(); it.Next()) {
950       BB.Add(comp, it.Value());
951     }
952     comp.Closed (BRep_Tool::IsClosed (comp));
953     
954     mySUntil = comp;
955    
956     mySkface = Prof;
957     myPbase  = Prof;
958   }
959
960   mySliding = Sliding;
961
962   TopExp_Explorer exp;
963   for ( exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
964     TopTools_ListOfShape thelist3;
965     myMap.Bind(exp.Current(), thelist3);
966     myMap(exp.Current()).Append(exp.Current());
967   }
968 }
969
970
971
972 //=======================================================================
973 //function : Add
974 //purpose  : add elements of gluing
975 //=======================================================================
976
977 void BRepFeat_MakeRevolutionForm::Add(const TopoDS_Edge& E,
978                              const TopoDS_Face& F)
979 {
980 #ifdef OCCT_DEBUG
981   Standard_Boolean trc = BRepFeat_GettraceFEAT();
982   if (trc) cout << "BRepFeat_MakeRevolutionForm::Add" << endl;
983 #endif 
984   if(mySlface.IsEmpty()) {
985     TopExp_Explorer exp;
986     for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
987       if (exp.Current().IsSame(F)) {
988         break;
989       }
990     }
991     if (!exp.More()) {
992       throw Standard_ConstructionError();
993     }
994   
995     if (!mySlface.IsBound(F)) {
996       TopTools_ListOfShape thelist;
997       mySlface.Bind(F, thelist);
998     }
999     TopTools_ListIteratorOfListOfShape itl(mySlface(F));
1000     for (; itl.More();itl.Next()) {
1001       if (itl.Value().IsSame(E)) {
1002         break;
1003       }
1004     }
1005     if (!itl.More()) {
1006       mySlface(F).Append(E);
1007     }
1008   } 
1009 }
1010
1011   
1012
1013 //=======================================================================
1014 //function : Perform
1015 //purpose  : construction
1016 //=======================================================================
1017
1018 void BRepFeat_MakeRevolutionForm::Perform()
1019 {
1020 #ifdef OCCT_DEBUG
1021   Standard_Boolean trc = BRepFeat_GettraceFEAT();
1022   if (trc) cout << "BRepFeat_MakeRevolutionForm::Perform()" << endl;
1023 #endif
1024   if(mySbase.IsNull() || mySkface.IsNull() || myPbase.IsNull()) {
1025 #ifdef OCCT_DEBUG
1026     if (trc) cout << " Fields not initialized" << endl;
1027 #endif
1028     myStatusError = BRepFeat_NotInitialized;
1029     NotDone();
1030     return;
1031   }
1032
1033   gp_Pnt Pt;
1034
1035   TopExp_Explorer exx(myPbase, TopAbs_VERTEX);
1036   for(; exx.More(); exx.Next()) {
1037     const TopoDS_Vertex& vv = TopoDS::Vertex(exx.Current());
1038     if(!vv.IsNull()) {
1039       Pt = BRep_Tool::Pnt(vv);
1040       break;
1041     }
1042   }
1043
1044   if(myAngle2 != 0) {
1045     gp_Trsf T;
1046     T.SetRotation(myAxe, -myAngle2);
1047     BRepBuilderAPI_Transform trsf(T);
1048     trsf.Perform(myPbase, Standard_False);
1049     TopoDS_Face Pbase = TopoDS::Face(trsf.Shape());
1050     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(myLFMap);
1051     for(; iter.More(); iter.Next()) {
1052       const TopoDS_Shape& e1 = iter.Value().First();
1053       TopExp_Explorer ex1(myPbase, TopAbs_EDGE); 
1054       TopExp_Explorer ex2(Pbase, TopAbs_EDGE);
1055       for(; ex1.More(); ex1.Next()) {
1056         if(ex1.Current().IsSame(e1)) {
1057           myLFMap(iter.Key()).Clear();
1058           myLFMap(iter.Key()).Append(ex2.Current());
1059         }
1060         ex2.Next();       
1061       }
1062     }
1063
1064     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter1(mySlface);
1065     for(; iter1.More(); iter1.Next()) {
1066       const TopoDS_Shape& f1 = iter1.Key();
1067       const TopoDS_Shape& e1 = iter1.Value().First();
1068       TopExp_Explorer ex1(myPbase, TopAbs_EDGE); 
1069       TopExp_Explorer ex2(Pbase, TopAbs_EDGE);
1070       for(; ex1.More(); ex1.Next()) {
1071         const TopoDS_Shape& E1 = ex1.Current();
1072         const TopoDS_Shape& E2 = ex2.Current();
1073         if(E1.IsSame(e1)) {
1074           mySlface(f1).Clear();
1075           mySlface(f1).Append(E2);
1076         }
1077         ex2.Next();       
1078       }
1079     }
1080     myPbase = Pbase;
1081     trsf.Perform(mySkface, Standard_False);
1082 // flo : check if it is required to reattributr the field mySkface
1083 //    TopoDS_Face mySkface = TopoDS::Face(trsf.Shape());
1084     mySkface = TopoDS::Face(trsf.Shape());
1085   }
1086
1087   LocOpe_RevolutionForm theForm;
1088   theForm.Perform(myPbase, myAxe, (myAngle1+myAngle2));
1089   TopoDS_Shape VraiForm = theForm.Shape();   // uncut  primitive
1090
1091 // management of descendants
1092   MajMap(myPbase,theForm,myMap,myFShape,myLShape);
1093
1094   myGluedF.Clear();
1095
1096
1097
1098   gp_Pln Pln0 = myPln->Pln();
1099   BRepLib_MakeFace f(Pln0);
1100   
1101
1102   gp_Vec vec1 = myHeight1*Normal(f, Pt);
1103   gp_Vec vec2 = -myHeight2*Normal(f, Pt);
1104
1105   gp_Pln Pln1 = Pln0.Translated(vec1);
1106   gp_Pln Pln2 = Pln0.Translated(vec2);
1107   
1108   BRepLib_MakeFace ff1(Pln1);
1109   BRepLib_MakeFace ff2(Pln2);
1110   TopoDS_Face f1 = TopoDS::Face(ff1.Shape());
1111   TopoDS_Face f2 = TopoDS::Face(ff2.Shape());
1112   BRepFeat::FaceUntil(mySbase, f1);
1113   BRepFeat::FaceUntil(mySbase, f2);
1114
1115   LocOpe_CSIntersector ASI1(f1);
1116   LocOpe_CSIntersector ASI2(f2);
1117
1118   Handle(Geom_Line) normale = new Geom_Line(Pt, vec1);
1119   TColGeom_SequenceOfCurve scur;
1120   scur.Append(normale);
1121
1122   ASI1.Perform(scur);
1123   ASI2.Perform(scur);
1124
1125   if(!ASI1.IsDone() || !ASI2.IsDone() ||
1126      ASI1.NbPoints(1) != 1 || ASI2.NbPoints(1) != 1) {
1127 #ifdef OCCT_DEBUG
1128     if (trc) cout << " Intersection failure" << endl;
1129 #endif
1130     myStatusError = BRepFeat_BadIntersect;
1131     NotDone();
1132     return;
1133   }
1134
1135   TopAbs_Orientation Ori1 = ASI1.Point(1,1).Orientation();
1136   TopAbs_Orientation Ori2 = TopAbs::Reverse(ASI2.Point(1,1).Orientation());
1137   TopoDS_Face FF1 = ASI1.Point(1,1).Face();
1138   TopoDS_Face FF2 = ASI2.Point(1,1).Face();
1139
1140   TopoDS_Shape Comp;
1141   BRep_Builder B;
1142   B.MakeCompound(TopoDS::Compound(Comp));
1143   TopoDS_Solid S1 = BRepFeat::Tool(f1,FF1,Ori1);
1144   TopoDS_Solid S2 = BRepFeat::Tool(f2,FF2,Ori2);
1145   if (!S1.IsNull()) B.Add(Comp,S1);
1146   if (!S2.IsNull()) B.Add(Comp,S2);
1147
1148   BRepAlgoAPI_Cut trP(VraiForm,Comp);    
1149   // coupe de la nervure par deux plans parallels
1150   TopTools_DataMapOfShapeListOfShape SlidingMap;
1151
1152 // management of descendants
1153
1154   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it1;
1155   it1.Initialize(myMap);
1156   for(; it1.More(); it1.Next()) {
1157     const TopoDS_Shape& orig = it1.Key();
1158     if(it1.Value().IsEmpty()) continue;
1159     const TopoDS_Shape& sh = it1.Value().First();
1160     exx.Init(VraiForm, TopAbs_FACE);
1161     for(; exx.More(); exx.Next()) {
1162       const TopoDS_Face& fac = TopoDS::Face(exx.Current());
1163       TopExp_Explorer exx1(fac, TopAbs_WIRE);
1164       const TopoDS_Wire& thew = TopoDS::Wire(exx1.Current());
1165       if(thew.IsSame(myFShape)) {
1166         const TopTools_ListOfShape& desfaces = trP.Modified(f2);
1167         myMap(myFShape) = desfaces;
1168         continue;
1169       }
1170       else if(thew.IsSame(myLShape)) {
1171         const TopTools_ListOfShape& desfaces = trP.Modified(f1);
1172         myMap(myLShape) = desfaces;
1173         continue;
1174       }
1175       if(fac.IsSame(sh)) { 
1176         if (trP.IsDeleted(fac)) {
1177         }
1178         else {
1179           const TopTools_ListOfShape& desfaces = trP.Modified(fac);
1180           if(!desfaces.IsEmpty()) {
1181             myMap(orig).Clear();
1182             myMap(orig) = trP.Modified(fac);
1183           }
1184         }
1185       }
1186     }
1187   }
1188
1189   exx.Init(VraiForm, TopAbs_FACE);
1190   for(; exx.More(); exx.Next()) {
1191     const TopoDS_Face& fac = TopoDS::Face(exx.Current());
1192     TopTools_ListOfShape thelist;
1193     SlidingMap.Bind(fac, thelist);
1194     if (trP.IsDeleted(fac)) {
1195     }
1196     else {
1197       const TopTools_ListOfShape& desfaces = trP.Modified(fac);
1198       if(!desfaces.IsEmpty()) 
1199         SlidingMap(fac) = desfaces;
1200       else 
1201         SlidingMap(fac).Append(fac);
1202     }
1203   }
1204
1205
1206 // gestion of faces of sliding
1207   SetGluedFaces(mySlface, theForm, SlidingMap, myGluedF);
1208
1209   VraiForm = trP.Shape();   // primitive cut
1210
1211   if(!myGluedF.IsEmpty()) 
1212     myPerfSelection = BRepFeat_NoSelection;
1213   else 
1214     myPerfSelection = BRepFeat_SelectionSh;
1215
1216   exx.Init(myPbase, TopAbs_EDGE);
1217   for(; exx.More(); exx.Next()) {
1218     const TopoDS_Edge& e = TopoDS::Edge(exx.Current());
1219     if(!myMap.IsBound(e)) {
1220 #ifdef OCCT_DEBUG
1221       if (trc) cout << " Sliding face not in Base shape" << endl;
1222 #endif
1223       myStatusError = BRepFeat_IncSlidFace;
1224       NotDone();
1225       return;
1226     }
1227   }
1228
1229   myGShape = VraiForm;
1230
1231   if(!myGluedF.IsEmpty() && !mySUntil.IsNull()) {
1232 #ifdef OCCT_DEBUG
1233     if (trc)
1234     {
1235       cout << "The case is not computable" << endl;
1236       cout << " Glued faces not empty and Until shape not null" << endl;
1237     }
1238 #endif
1239     myStatusError = BRepFeat_InvShape;
1240     NotDone();
1241     return;
1242   }
1243
1244   LFPerform();    // topological reconstruction
1245 }
1246
1247
1248 //=======================================================================
1249 //function : Propagate
1250 //purpose  : propagation on the faces of the inital shape, find faces 
1251 // concerned by the rib
1252 //=======================================================================
1253
1254 Standard_Boolean BRepFeat_MakeRevolutionForm::Propagate(TopTools_ListOfShape& SliList,
1255                                                         const TopoDS_Face& fac,
1256                                                         const gp_Pnt& Firstpnt, 
1257                                                         const gp_Pnt& Lastpnt, 
1258                                                         Standard_Boolean& falseside)
1259 {
1260 #ifdef OCCT_DEBUG
1261   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
1262   if (trc) cout << "BRepFeat_MakeRevolutionForm::Propagate" << endl;
1263 #endif
1264   gp_Pnt Firstpoint = Firstpnt;
1265   gp_Pnt Lastpoint = Lastpnt;
1266
1267   Standard_Boolean result = Standard_True;
1268   TopoDS_Face CurrentFace, saveFace;
1269   CurrentFace = TopoDS::Face(SliList.First());
1270   saveFace = CurrentFace;
1271   //  BRepBuilderAPI_MakeFace fac(myPln);
1272   Standard_Boolean LastOK = Standard_False, FirstOK= Standard_False;
1273   TopoDS_Vertex v1, v2, v3, v4, Vert;
1274   BRepAlgoAPI_Section sect (fac, CurrentFace, Standard_False);
1275   sect.Approximation(Standard_True);
1276   sect.Build();
1277   TopExp_Explorer Ex;
1278   TopoDS_Edge e, e1;
1279   gp_Pnt FP, LP;
1280   Standard_Integer ii = 0;
1281   for (Ex.Init(sect.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
1282     ii++;
1283     if(ii==1){
1284       e = TopoDS::Edge(Ex.Current());
1285     }    
1286     else if (ii > 1) {
1287       e1 = TopoDS::Edge(Ex.Current());
1288       break;
1289     }
1290   }
1291   if(e.IsNull()) {
1292     falseside = Standard_False;
1293     return Standard_False;
1294   }
1295   //
1296   if(!e1.IsNull()) {
1297     Standard_Real aTolV1, aTolV2;
1298     myListOfEdges.Clear();
1299     TopTools_ListOfShape thelist;
1300     mySlface.Bind(CurrentFace, thelist);
1301     mySlface(CurrentFace).Append(e1);
1302     
1303     myListOfEdges.Append(e1);
1304     
1305     v1 = TopExp::FirstVertex(e1,Standard_True);
1306     v2 = TopExp::LastVertex (e1,Standard_True);
1307
1308     FP = BRep_Tool::Pnt(v1);
1309     LP = BRep_Tool::Pnt(v2);
1310
1311     aTolV1=BRep_Tool::Tolerance(v1);
1312     aTolV2=BRep_Tool::Tolerance(v2);
1313
1314     if(FP.Distance(Firstpoint) <= aTolV1 || 
1315        FP.Distance(Lastpoint)  <= aTolV1) {
1316       FirstOK = Standard_True;
1317     }
1318     if(LP.Distance(Firstpoint)<= aTolV2 || 
1319        LP.Distance(Lastpoint) <= aTolV2) {
1320       LastOK = Standard_True;
1321     }
1322     
1323     if(LastOK && FirstOK) {
1324       return result;
1325     }
1326     
1327     else {
1328       myListOfEdges.Clear();
1329     }
1330   }
1331   //
1332   if(!e1.IsNull()) {
1333     myListOfEdges.Clear();
1334     TopTools_ListOfShape thelist1;    
1335     mySlface.Bind(CurrentFace, thelist1);
1336     mySlface(CurrentFace).Append(e);
1337     
1338     myListOfEdges.Append(e);
1339
1340 //    mySlface.Bind(CurrentFace,TopTools_ListOfShape());
1341     mySlface(CurrentFace).Append(e1);    
1342 //    myListOfEdges.Append(e1);
1343
1344     v1 = TopExp::FirstVertex(e,Standard_True); 
1345     v2 = TopExp::LastVertex(e,Standard_True);
1346     v3 = TopExp::FirstVertex(e1,Standard_True); 
1347     v4 = TopExp::LastVertex(e1,Standard_True);
1348     gp_Pnt p1, p2, p3, p4;
1349     p1 = BRep_Tool::Pnt(v1); FP = p1;
1350     p2 = BRep_Tool::Pnt(v2);  LP = p2;
1351     p3 = BRep_Tool::Pnt(v3);
1352     p4 = BRep_Tool::Pnt(v4);
1353     if(p1.Distance(Firstpoint) <= BRep_Tool::Tolerance(v1)) {
1354       if(p3.Distance(Lastpoint) <= BRep_Tool::Tolerance(v3)) {
1355         FirstOK = Standard_True;
1356         Lastpoint = p4;
1357       } 
1358       else if(p4.Distance(Lastpoint) <= BRep_Tool::Tolerance(v4)) {
1359         FirstOK = Standard_True;
1360         Lastpoint = p3;
1361       } 
1362       else {
1363         e1.Nullify();
1364       }
1365     }
1366     else if(p1.Distance(Lastpoint) <= BRep_Tool::Tolerance(v1)) {
1367       if(p3.Distance(Firstpoint) <= BRep_Tool::Tolerance(v3)) {
1368         FirstOK = Standard_True;
1369         Firstpoint = p4;
1370       } 
1371       else if(p4.Distance(Firstpoint) <= BRep_Tool::Tolerance(v4)) {
1372         FirstOK = Standard_True;
1373         Firstpoint = p3;
1374       } 
1375       else {
1376         e1.Nullify();
1377       }
1378     }
1379     else if(p2.Distance(Firstpoint) <= BRep_Tool::Tolerance(v2)) {
1380       if(p3.Distance(Lastpoint) <= BRep_Tool::Tolerance(v3)) {
1381         LastOK = Standard_True;
1382         Lastpoint = p4;
1383       } 
1384       else if(p4.Distance(Lastpoint) <= BRep_Tool::Tolerance(v4)) {
1385         LastOK = Standard_True;
1386         Lastpoint = p3;
1387       } 
1388       else {
1389         e1.Nullify();
1390       }
1391     }
1392     else if(p2.Distance(Lastpoint) <= BRep_Tool::Tolerance(v2)) {
1393       if(p3.Distance(Firstpoint) <= BRep_Tool::Tolerance(v3)) {
1394         LastOK = Standard_True;
1395         Firstpoint = p4;
1396       } 
1397       else if(p4.Distance(Firstpoint) <= BRep_Tool::Tolerance(v4)) {
1398         LastOK = Standard_True;
1399         Firstpoint = p3;
1400       } 
1401       else {
1402         e1.Nullify();
1403       }
1404     }
1405     else {
1406       e = e1;
1407       e1.Nullify();
1408     }
1409   }
1410   if(e1.IsNull()) {
1411     myListOfEdges.Clear();
1412     TopTools_ListOfShape thelist2;    
1413     mySlface.Bind(CurrentFace, thelist2);
1414     mySlface(CurrentFace).Append(e);
1415     
1416     myListOfEdges.Append(e);
1417     
1418     v1 = TopExp::FirstVertex(e,Standard_True);
1419     v2 = TopExp::LastVertex(e,Standard_True);
1420
1421     FP = BRep_Tool::Pnt(v1);
1422     LP = BRep_Tool::Pnt(v2);
1423     
1424     if(FP.Distance(Firstpoint) <= BRep_Tool::Tolerance(v1)
1425        || FP.Distance(Lastpoint) <= BRep_Tool::Tolerance(v1)) {
1426       FirstOK = Standard_True;
1427     }
1428     if(LP.Distance(Firstpoint) <= BRep_Tool::Tolerance(v2)
1429        || LP.Distance(Lastpoint) <= BRep_Tool::Tolerance(v2)) {
1430       LastOK = Standard_True;
1431     }
1432     
1433     if(LastOK && FirstOK) {
1434       return result;
1435     }
1436   }
1437   
1438   TopTools_IndexedDataMapOfShapeListOfShape mapedges;
1439   TopExp::MapShapesAndAncestors(mySbase, TopAbs_EDGE, TopAbs_FACE, mapedges);
1440   TopExp_Explorer ex;
1441   TopoDS_Edge FirstEdge;
1442
1443   TopoDS_Vertex Vprevious;  Vprevious.Nullify();
1444   TopoDS_Vertex Vpreprevious;  Vpreprevious.Nullify();
1445
1446   while(!FirstOK) {
1447    // find edge connected to v1:
1448     gp_Pnt pt;
1449     if(!v1.IsNull()) pt= BRep_Tool::Pnt(v1);
1450     gp_Pnt ptprev;
1451     if(!Vprevious.IsNull()) ptprev = BRep_Tool::Pnt(Vprevious);
1452     gp_Pnt ptpreprev;
1453     if(!Vpreprevious.IsNull()) ptpreprev = BRep_Tool::Pnt(Vpreprevious);
1454     
1455     if((!Vprevious.IsNull() && ptprev.Distance(pt) <= myTol) ||
1456        (!Vpreprevious.IsNull() && ptpreprev.Distance(pt) <= myTol)) {
1457       falseside = Standard_False;
1458       return Standard_False;
1459     }
1460
1461     for (ex.Init(CurrentFace, TopAbs_EDGE); ex.More(); ex.Next()) {
1462       const TopoDS_Edge& aCurEdge = TopoDS::Edge(ex.Current());
1463
1464       BRepExtrema_ExtPC projF(v1, aCurEdge);
1465
1466       if(projF.IsDone() && projF.NbExt() >=1) {
1467         Standard_Real dist2min = RealLast();
1468         Standard_Integer index = 0;
1469         for (Standard_Integer sol =1 ; sol <= projF.NbExt(); sol++) {
1470           if (projF.SquareDistance(sol) <= dist2min) {
1471             index = sol;
1472             dist2min = projF.SquareDistance(sol);
1473           }
1474         }
1475         if (index != 0) {
1476           if (dist2min <= BRep_Tool::Tolerance(aCurEdge) * BRep_Tool::Tolerance(aCurEdge)) {
1477             FirstEdge = aCurEdge;
1478             break;
1479           }
1480         }
1481       }
1482     }
1483     
1484     const TopTools_ListOfShape& L = mapedges.FindFromKey(FirstEdge);
1485     TopTools_ListIteratorOfListOfShape It(L);
1486
1487     for (; It.More(); It.Next()) {
1488       const TopoDS_Face& FF = TopoDS::Face(It.Value());
1489       if (!FF.IsSame(CurrentFace)) {
1490         CurrentFace = FF;
1491         break;
1492       }
1493     }
1494
1495     BRepAlgoAPI_Section sectf (fac, CurrentFace, Standard_False);
1496     sectf.Approximation(Standard_True);
1497     sectf.Build();
1498
1499     TopoDS_Edge edg1;
1500     for (Ex.Init(sectf.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
1501       edg1 = TopoDS::Edge(Ex.Current());
1502       gp_Pnt ppp1 = BRep_Tool::Pnt(TopExp::FirstVertex(edg1,Standard_True));
1503       gp_Pnt ppp2 = BRep_Tool::Pnt(TopExp::LastVertex(edg1,Standard_True));
1504       if(ppp1.Distance(BRep_Tool::Pnt(v1)) <= BRep_Tool::Tolerance(v1) ||
1505          ppp2.Distance(BRep_Tool::Pnt(v1)) <= BRep_Tool::Tolerance(v1))
1506         break;      
1507     }    
1508
1509     TopTools_ListOfShape thelist3;
1510     mySlface.Bind(CurrentFace, thelist3);
1511     mySlface(CurrentFace).Append(edg1);
1512     myListOfEdges.Append(edg1);
1513
1514     if (!edg1.IsNull()) SliList.Prepend(CurrentFace);
1515     else return Standard_False;
1516
1517     Vert = TopExp::FirstVertex(edg1,Standard_True);
1518     gp_Pnt PP = BRep_Tool::Pnt(Vert);
1519     FP = BRep_Tool::Pnt(v1);
1520     Standard_Real tol = BRep_Tool::Tolerance(edg1);
1521     Standard_Real tol1 = BRep_Tool::Tolerance(v1);
1522     if(tol1 > tol) tol = tol1;
1523     Standard_Real dist = PP.Distance(FP);
1524     if (dist <= tol) {
1525       Vpreprevious = Vprevious;
1526       Vprevious = v1;
1527       v1 = TopExp::LastVertex(edg1,Standard_True);
1528     }
1529     else {
1530       Vpreprevious = Vprevious;
1531       Vprevious = v1;
1532       v1 = Vert;
1533     }
1534
1535     FP = BRep_Tool::Pnt(v1);
1536     
1537     if(FP.Distance(Firstpoint) <= BRep_Tool::Tolerance(v1)
1538        || FP.Distance(Lastpoint) <= BRep_Tool::Tolerance(v1)) {
1539       FirstOK = Standard_True;
1540     }
1541   }
1542
1543   CurrentFace = saveFace;
1544   Vprevious.Nullify();
1545   Vpreprevious.Nullify();
1546
1547   while(!LastOK) {
1548     // find edge connected to v2:
1549     gp_Pnt pt;
1550     if(!v2.IsNull()) pt= BRep_Tool::Pnt(v2);
1551     gp_Pnt ptprev;
1552     if(!Vprevious.IsNull()) ptprev = BRep_Tool::Pnt(Vprevious);
1553     gp_Pnt ptpreprev;
1554     if(!Vpreprevious.IsNull()) ptpreprev = BRep_Tool::Pnt(Vpreprevious);
1555     
1556     if((!Vprevious.IsNull() && ptprev.Distance(pt) <= myTol) ||
1557        (!Vpreprevious.IsNull() && ptpreprev.Distance(pt) <= myTol)) {
1558       falseside = Standard_False;
1559       return Standard_False;
1560     }
1561     
1562     for (ex.Init(CurrentFace, TopAbs_EDGE); ex.More(); ex.Next()) {
1563       const TopoDS_Edge& aCurEdge = TopoDS::Edge(ex.Current());
1564       BRepExtrema_ExtPC projF(v2, aCurEdge);
1565
1566       if(projF.IsDone() && projF.NbExt() >=1) {
1567         Standard_Real dist2min = RealLast();
1568         Standard_Integer index = 0;
1569         for (Standard_Integer sol =1 ; sol <= projF.NbExt(); sol++) {
1570           if (projF.SquareDistance(sol) <= dist2min) {
1571             index = sol;
1572             dist2min = projF.SquareDistance(sol);
1573           }
1574         }
1575         if (index != 0) {
1576           if (dist2min <= BRep_Tool::Tolerance(aCurEdge) * BRep_Tool::Tolerance(aCurEdge)) {
1577             FirstEdge = aCurEdge;
1578             break;
1579           }
1580         }
1581       }
1582     }
1583     
1584     const TopTools_ListOfShape& L = mapedges.FindFromKey(FirstEdge);
1585     TopTools_ListIteratorOfListOfShape It(L);
1586
1587     for (; It.More(); It.Next()) {
1588       const TopoDS_Face& FF = TopoDS::Face(It.Value());
1589       if (!FF.IsSame(CurrentFace)) {
1590         CurrentFace = FF;
1591         break;
1592       }
1593     }
1594
1595     ii = 0;
1596  
1597     BRepAlgoAPI_Section sectf (fac, CurrentFace, Standard_False);
1598     sectf.Approximation(Standard_True);
1599     sectf.Build();
1600
1601     TopoDS_Edge edg2;
1602     for (Ex.Init(sectf.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {      
1603       edg2 = TopoDS::Edge(Ex.Current());
1604       gp_Pnt ppp1 = BRep_Tool::Pnt(TopExp::FirstVertex(edg2,Standard_True));
1605       gp_Pnt ppp2 = BRep_Tool::Pnt(TopExp::LastVertex(edg2,Standard_True));
1606       if(ppp1.Distance(BRep_Tool::Pnt(v2)) <= BRep_Tool::Tolerance(v2) ||
1607          ppp2.Distance(BRep_Tool::Pnt(v2)) <= BRep_Tool::Tolerance(v2))
1608         break;
1609     }    
1610     TopTools_ListOfShape thelist4;
1611     mySlface.Bind(CurrentFace, thelist4);
1612     mySlface(CurrentFace).Append(edg2);
1613     myListOfEdges.Append(edg2);
1614
1615     if (!edg2.IsNull()) SliList.Append(CurrentFace);
1616     else return Standard_False;
1617
1618     Vert = TopExp::FirstVertex(edg2,Standard_True);
1619     gp_Pnt PP = BRep_Tool::Pnt(Vert);
1620     FP = BRep_Tool::Pnt(v2);
1621     if (PP.Distance(FP)<= BRep_Tool::Tolerance(v2)) {
1622       Vpreprevious = Vprevious;
1623       Vprevious = v2;
1624       v2 = TopExp::LastVertex(edg2,Standard_True);
1625     }
1626     else {
1627       v2 = Vert;
1628     }
1629     FP = BRep_Tool::Pnt(v2);
1630
1631     
1632     if(FP.Distance(Firstpoint) <= BRep_Tool::Tolerance(v2)
1633        || FP.Distance(Lastpoint) <= BRep_Tool::Tolerance(v2)) {
1634       LastOK = Standard_True;
1635     }
1636   }
1637   if(!e1.IsNull())     myListOfEdges.Append(e1);
1638   return result;
1639   
1640 }
1641
1642
1643 //=======================================================================
1644 //function : MajMap
1645 //purpose  : management of descendants
1646 //=======================================================================
1647
1648 static void MajMap(const TopoDS_Shape& theB,
1649                    const LocOpe_RevolutionForm& theP,
1650                    TopTools_DataMapOfShapeListOfShape& theMap, // myMap
1651                    TopoDS_Shape& theFShape,  // myFShape
1652                    TopoDS_Shape& theLShape) // myLShape
1653 {
1654   TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
1655   if (exp.More()) {
1656     theFShape = exp.Current();
1657     TopTools_ListOfShape thelist;
1658     theMap.Bind(theFShape, thelist);
1659     for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
1660       const TopoDS_Shape& sh = exp.Current();
1661       theMap(theFShape).Append(sh);
1662     }
1663   }
1664   
1665   exp.Init(theP.LastShape(),TopAbs_WIRE);
1666   if (exp.More()) {
1667     theLShape = exp.Current();
1668     TopTools_ListOfShape thelist1;
1669     theMap.Bind(theLShape, thelist1);
1670     for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
1671       const TopoDS_Shape& sh = exp.Current();
1672       theMap(theLShape).Append(sh);
1673     }
1674   }
1675
1676   for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
1677     if (!theMap.IsBound(exp.Current())) {
1678       TopTools_ListOfShape thelist2;
1679       theMap.Bind(exp.Current(), thelist2);
1680       theMap(exp.Current()) = theP.Shapes(exp.Current());
1681     }
1682   }
1683 }
1684
1685
1686  //=======================================================================
1687 //function : SetGluedFaces
1688 //purpose  : managemnet of sliding faces
1689 //=======================================================================
1690
1691 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
1692                           LocOpe_RevolutionForm& thePrism,
1693                           const TopTools_DataMapOfShapeListOfShape& SlidingMap,
1694                           TopTools_DataMapOfShapeShape& theMap)
1695 {
1696   // Slidings
1697   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(theSlmap);
1698   if(!theSlmap.IsEmpty()) {
1699     for (; itm.More(); itm.Next()) {
1700       const TopoDS_Face& fac = TopoDS::Face(itm.Key());
1701       const TopTools_ListOfShape& ledg = itm.Value();
1702       TopTools_ListIteratorOfListOfShape it;
1703       for (it.Initialize(ledg); it.More(); it.Next()) {
1704         const TopTools_ListOfShape& gfac = thePrism.Shapes(it.Value());
1705         if (gfac.Extent() != 1) {
1706 #ifdef OCCT_DEBUG
1707           cout << "Pb SetGluedFace" << endl;
1708 #endif
1709         }
1710         TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iterm(SlidingMap);
1711         for(; iterm.More(); iterm.Next()) {
1712           const TopoDS_Face& ff = TopoDS::Face(iterm.Key());
1713           const TopTools_ListOfShape& lfaces = iterm.Value();
1714           if(lfaces.IsEmpty()) continue;
1715           const TopoDS_Face& fff = TopoDS::Face(lfaces.First());
1716           if(gfac.First().IsSame(ff)) theMap.Bind(fff,fac);
1717         }
1718       }
1719     }
1720   }
1721 }
1722