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