da07f85debb13b2161baafb3bad69569281d5a47
[occt.git] / src / BRepFeat / BRepFeat_MakeRevol.cxx
1 // Created on: 1996-02-13
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Bnd_Box.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAlgoAPI_Cut.hxx>
22 #include <BRepAlgoAPI_Fuse.hxx>
23 #include <BRepBndLib.hxx>
24 #include <BRepBuilderAPI.hxx>
25 #include <BRepFeat.hxx>
26 #include <BRepFeat_MakeRevol.hxx>
27 #include <BRepLib_MakeFace.hxx>
28 #include <BRepSweep_Revol.hxx>
29 #include <BRepTools_Modifier.hxx>
30 #include <BRepTools_TrsfModification.hxx>
31 #include <ElCLib.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom_Circle.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_Plane.hxx>
36 #include <Geom_RectangularTrimmedSurface.hxx>
37 #include <Geom_Surface.hxx>
38 #include <gp_Ax1.hxx>
39 #include <gp_Pln.hxx>
40 #include <gp_Pnt.hxx>
41 #include <gp_Pnt2d.hxx>
42 #include <gp_Vec.hxx>
43 #include <LocOpe.hxx>
44 #include <LocOpe_BuildShape.hxx>
45 #include <LocOpe_CSIntersector.hxx>
46 #include <LocOpe_FindEdges.hxx>
47 #include <LocOpe_Gluer.hxx>
48 #include <LocOpe_PntFace.hxx>
49 #include <LocOpe_Revol.hxx>
50 #include <LocOpe_SequenceOfCirc.hxx>
51 #include <Precision.hxx>
52 #include <Standard_ConstructionError.hxx>
53 #include <TColgp_SequenceOfPnt.hxx>
54 #include <TopExp.hxx>
55 #include <TopExp_Explorer.hxx>
56 #include <TopoDS_Compound.hxx>
57 #include <TopoDS_Edge.hxx>
58 #include <TopoDS_Face.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Shell.hxx>
61 #include <TopoDS_Solid.hxx>
62 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
63 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
64 #include <TopTools_ListIteratorOfListOfShape.hxx>
65 #include <TopTools_MapIteratorOfMapOfShape.hxx>
66 #include <TopTools_MapOfShape.hxx>
67
68 #ifdef OCCT_DEBUG
69 extern Standard_Boolean BRepFeat_GettraceFEAT();
70 #endif
71
72 static void MajMap(const TopoDS_Shape&, // base
73   const LocOpe_Revol&,
74   TopTools_DataMapOfShapeListOfShape&, // myMap
75   TopoDS_Shape&,  // myFShape
76   TopoDS_Shape&); // myLShape
77
78
79 static void VerifGluedFaces(const TopoDS_Face& theSkface,
80   const TopoDS_Shape& thePbase,
81   Handle(Geom_Curve)& theBCurve,
82   TColGeom_SequenceOfCurve& theCurves,
83   LocOpe_Revol& theRevol,
84   TopTools_DataMapOfShapeShape& theMap);
85
86
87 static Standard_Boolean ToFuse(const TopoDS_Face& ,
88   const TopoDS_Face&);
89
90
91
92
93 //=======================================================================
94 //function : Init
95 //purpose  : 
96 //=======================================================================
97
98 void BRepFeat_MakeRevol::Init(const TopoDS_Shape& Sbase,
99   const TopoDS_Shape& Pbase,
100   const TopoDS_Face& Skface,
101   const gp_Ax1& Axis,
102   const Standard_Integer Mode,
103   const Standard_Boolean Modify)
104 {
105 #ifdef OCCT_DEBUG
106   Standard_Boolean trc = BRepFeat_GettraceFEAT();
107   if (trc) cout << "BRepFeat_MakeRevol::Init" << endl;
108 #endif
109   myAxis   = Axis;
110   myPbase  = Pbase;
111   mySbase  = Sbase;
112   BasisShapeValid();
113   mySkface = Skface;
114   SketchFaceValid();
115   myPbase  = Pbase;
116   mySlface.Clear();
117   if(Mode == 0) {
118     myFuse   = Standard_False;
119     myJustFeat = Standard_False;
120   }
121   else if(Mode == 1) {
122     myFuse   = Standard_True;
123     myJustFeat = Standard_False;
124   }
125   else if(Mode == 2) {
126     myFuse   = Standard_True;
127     myJustFeat = Standard_True;
128   }
129   else {    
130   }
131   myModify = Modify;
132   myJustGluer = Standard_False;
133
134   //-------------- ifv
135   //  mySkface.Nullify();
136   //-------------- ifv
137
138
139   myShape.Nullify();
140   myMap.Clear();
141   myFShape.Nullify();
142   myLShape.Nullify();
143   TopExp_Explorer exp;
144   for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
145     TopTools_ListOfShape thelist;
146     myMap.Bind(exp.Current(), thelist);
147     myMap(exp.Current()).Append(exp.Current());
148   }
149 #ifdef OCCT_DEBUG
150   if (trc) {
151     if (myJustFeat)  cout << " Just Feature" << endl;
152     if (myFuse)  cout << " Fuse" << endl;
153     if (!myFuse)  cout << " Cut" << endl;
154     if (!myModify) cout << " Modify = 0" << endl;
155   }
156 #endif 
157 }
158
159
160 //=======================================================================
161 //function : Add
162 //purpose  : add faces add edges of sliding
163 //=======================================================================
164
165 void BRepFeat_MakeRevol::Add(const TopoDS_Edge& E,
166   const TopoDS_Face& F)
167 {
168 #ifdef OCCT_DEBUG
169   Standard_Boolean trc = BRepFeat_GettraceFEAT();
170   if (trc) cout << "BRepFeat_MakeRevol::Add(Edge,face)" << endl;
171 #endif
172   TopExp_Explorer exp;
173   for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
174     if (exp.Current().IsSame(F)) {
175       break;
176     }
177   }
178   if (!exp.More()) {
179     throw Standard_ConstructionError();
180   }
181
182   for (exp.Init(myPbase,TopAbs_EDGE);exp.More();exp.Next()) {
183     if (exp.Current().IsSame(E)) {
184       break;
185     }
186   }
187   if (!exp.More()) {
188     throw Standard_ConstructionError();
189   }
190
191   if (!mySlface.IsBound(F)) {
192     TopTools_ListOfShape thelist;
193     mySlface.Bind(F, thelist);
194   }
195   TopTools_ListIteratorOfListOfShape itl(mySlface(F));
196   for (; itl.More();itl.Next()) {
197     if (itl.Value().IsSame(E)) {
198       break;
199     }
200   }
201   if (!itl.More()) {
202     mySlface(F).Append(E);
203   }
204 }
205
206
207 //=======================================================================
208 //function : Perform
209 //purpose  : 
210 //=======================================================================
211
212 void BRepFeat_MakeRevol::Perform(const Standard_Real Angle)
213 {
214 #ifdef OCCT_DEBUG
215   Standard_Boolean trc = BRepFeat_GettraceFEAT();
216   if (trc) cout << "BRepFeat_MakeRevol::Perform(Angle)" << endl;
217 #endif
218   mySFrom.Nullify();
219   ShapeFromValid();
220   mySUntil.Nullify();
221   ShapeUntilValid();
222   myGluedF.Clear();
223   myPerfSelection = BRepFeat_NoSelection;
224   PerfSelectionValid();
225   Standard_Boolean RevolComp = (2*M_PI-Abs(Angle) <= Precision::Angular());
226   LocOpe_Revol theRevol;
227   Standard_Real angledec = 0.;
228   TopExp_Explorer exp;
229   if(RevolComp) {
230     /*
231     if (!mySkface.IsNull() || !mySlface.IsEmpty()) {
232     for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
233     if (exp.Current().IsSame(mySkface)) {
234     angledec = M_PI/5; // pourquoi pas
235     if (myFuse) angledec = -angledec;
236     break;
237     }
238     }
239     }
240     */
241     mySkface.Nullify();
242   }
243   if(angledec == 0.) theRevol.Perform(myPbase, myAxis, Angle);
244   else theRevol.Perform(myPbase, myAxis, Angle, angledec);
245
246   TopoDS_Shape VraiRevol = theRevol.Shape();
247
248   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
249
250   myGShape = VraiRevol;
251   GeneratedShapeValid();
252   TopoDS_Shape Base = theRevol.FirstShape();
253   exp.Init(Base, TopAbs_FACE);
254   TopoDS_Face theBase = TopoDS::Face(exp.Current());
255   exp.Next();
256   if(exp.More()) {
257     NotDone();
258     myStatusError = BRepFeat_InvFirstShape;
259     return;
260   }
261
262   TopoDS_Face FFace;
263
264   Standard_Boolean found = Standard_False;
265
266   if(!mySkface.IsNull() || !mySlface.IsEmpty()) {
267     if(myLShape.ShapeType() == TopAbs_WIRE) {
268       TopExp_Explorer ex1(VraiRevol, TopAbs_FACE);
269       for(; ex1.More(); ex1.Next()) {
270         TopExp_Explorer ex2(ex1.Current(), TopAbs_WIRE);
271         for(; ex2.More(); ex2.Next()) {
272           if(ex2.Current().IsSame(myLShape)) {
273             FFace = TopoDS::Face(ex1.Current());
274             found = Standard_True;
275             break;
276           }
277         }
278         if(found) break;
279       }
280     }
281
282     TopExp_Explorer anExp(mySbase, TopAbs_FACE);
283     for(; anExp.More(); anExp.Next()) {
284       const TopoDS_Face& ff = TopoDS::Face(anExp.Current());
285       if(ToFuse(ff, FFace)) {
286         TopTools_DataMapOfShapeListOfShape sl;
287         if(!FFace.IsSame(myPbase) && BRepFeat::IsInside(ff, FFace)) 
288           break;
289       }
290     }
291   }
292   GluedFacesValid();
293   if (!mySkface.IsNull()) {
294     VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
295   }
296
297   if(myGluedF.IsEmpty()) {
298     if(myFuse == 1) {
299       BRepAlgoAPI_Fuse f(mySbase, myGShape);
300       myShape = f.Shape();
301       UpdateDescendants(f, myShape, Standard_False);
302       Done();
303     }
304     else if(myFuse == 0) {
305       BRepAlgoAPI_Cut c(mySbase, myGShape);
306       myShape = c.Shape();
307       UpdateDescendants(c, myShape, Standard_False);
308       Done();
309     }
310     else {
311       myShape = myGShape;
312       Done();
313     }
314   }
315   else {
316     theRevol.Curves(myCurves);
317     myBCurve = theRevol.BarycCurve();
318     GlobalPerform();
319   }
320 }
321
322
323 //=======================================================================
324 //function : Perform
325 //purpose  : feature till shape Until
326 //=======================================================================
327
328 void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& Until)
329 {
330 #ifdef OCCT_DEBUG
331   Standard_Boolean trc = BRepFeat_GettraceFEAT();
332   if (trc) cout << "BRepFeat_MakeRevol::Perform(Until)" << endl;
333 #endif
334   Standard_Real Angle = 0.;
335   Standard_Boolean TourComplet = Standard_False;
336
337   if (Until.IsNull()) {
338     throw Standard_ConstructionError();
339   }
340   TopExp_Explorer exp(Until, TopAbs_FACE);
341   if (!exp.More()) {
342     throw Standard_ConstructionError();
343   }
344   if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
345     Angle = 2*M_PI;
346     TourComplet = Standard_True;
347   }
348   myGluedF.Clear();
349   myPerfSelection = BRepFeat_SelectionU;
350   PerfSelectionValid();
351   mySFrom.Nullify();
352   ShapeFromValid();
353   mySUntil = Until;
354   Standard_Boolean Trf = TransformShapeFU(1);
355   ShapeUntilValid();
356
357   // Do systematically almost complete revolution
358   // BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular());
359   LocOpe_Revol theRevol;
360   if(!TourComplet) {
361     Angle = 2.*M_PI- 3*M_PI/180.;
362 #ifdef OCCT_DEBUG
363     if (trc) cout << " No complete Revolution" << endl;
364 #endif
365   }
366   theRevol.Perform(myPbase, myAxis, Angle);
367   TopoDS_Shape VraiRevol = theRevol.Shape();
368   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
369
370
371   if(!Trf) {
372
373     myGShape = VraiRevol;
374     GeneratedShapeValid();
375
376     TopoDS_Shape Base = theRevol.FirstShape();
377     exp.Init(Base, TopAbs_FACE);
378     TopoDS_Face theBase = TopoDS::Face(exp.Current());
379     exp.Next();
380     if(exp.More()) {
381       NotDone();
382       myStatusError = BRepFeat_InvFirstShape;
383       return;
384     }
385     GluedFacesValid();
386     //VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
387
388     theRevol.Curves(myCurves);
389     myBCurve = theRevol.BarycCurve();
390     GlobalPerform();
391   }
392   else {
393     TColGeom_SequenceOfCurve scur;
394     theRevol.Curves(myCurves);
395     myBCurve = theRevol.BarycCurve();    
396     scur.Clear();    
397     scur.Append(myBCurve);
398     LocOpe_CSIntersector ASI(mySUntil);
399     ASI.Perform(scur);
400     if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
401       TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
402       TopoDS_Face FUntil = ASI.Point(1,1).Face();
403       TopoDS_Shape Comp;
404       BRep_Builder B;
405       B.MakeCompound(TopoDS::Compound(Comp));
406       TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
407       if (!S.IsNull()) B.Add(Comp,S);
408       BRepAlgoAPI_Cut trP(VraiRevol,Comp);
409       TopoDS_Shape Cutsh = trP.Shape();
410       TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
411       for(; ex.More(); ex.Next()) {
412         TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
413         for(; ex1.More(); ex1.Next()) {
414           const TopoDS_Face& fac = TopoDS::Face(ex1.Current());
415           if(fac.IsSame(myPbase)) {
416             VraiRevol = ex.Current();
417             break;
418           }
419         }
420       }
421       if(myFuse == 1) {
422         BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
423         myShape = f.Shape();
424         UpdateDescendants(f, myShape, Standard_False);
425         Done();
426       }
427       else if(myFuse == 0) {
428         BRepAlgoAPI_Cut c(mySbase, VraiRevol);
429         myShape = c.Shape();
430         UpdateDescendants(c, myShape, Standard_False);
431         Done();
432       }
433       else {
434         myShape = VraiRevol;
435         Done(); 
436       }
437     }         
438   }
439 }
440
441
442 //=======================================================================
443 //function : Perform
444 //purpose  : feature limited by two shapes
445 //=======================================================================
446
447 void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
448   const TopoDS_Shape& Until)
449 {
450 #ifdef OCCT_DEBUG
451   Standard_Boolean trc = BRepFeat_GettraceFEAT();
452   if (trc) cout << "BRepFeat_MakeRevol::Perform(From,Until)" << endl;
453 #endif
454   if (From.IsNull() || Until.IsNull()) {
455     throw Standard_ConstructionError();
456   }
457   if (!mySkface.IsNull()) {
458     if (From.IsSame(mySkface)) {
459       myJustGluer = Standard_True;
460       Perform(Until);
461       if (myJustGluer) return;
462     }
463     else if (Until.IsSame(mySkface)) {
464       myJustGluer = Standard_True;
465       myAxis.Reverse();
466       Perform(From);
467       if (myJustGluer) return;
468     }
469   }
470
471   myGluedF.Clear();
472   myPerfSelection = BRepFeat_SelectionFU;
473   PerfSelectionValid();
474
475   TopExp_Explorer exp(From, TopAbs_FACE);
476   if (!exp.More()) {
477     throw Standard_ConstructionError();
478   }
479   exp.Init(Until, TopAbs_FACE);
480   if (!exp.More()) {
481     throw Standard_ConstructionError();
482   }
483
484   mySFrom = From;
485   Standard_Boolean Trff = TransformShapeFU(0);
486   ShapeFromValid();
487   mySUntil = Until;
488   Standard_Boolean Trfu = TransformShapeFU(1);
489   ShapeUntilValid();  
490
491   if(Trfu != Trff) {
492     NotDone();
493     myStatusError = BRepFeat_IncTypes;
494     return;
495   }
496
497   LocOpe_Revol theRevol;
498   theRevol.Perform(myPbase, myAxis, 2*M_PI);
499   TopoDS_Shape VraiRevol = theRevol.Shape();
500
501   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
502
503   if(!Trff) {    
504     myGShape = VraiRevol;
505     GeneratedShapeValid();
506     GluedFacesValid();
507     //    VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
508
509     theRevol.Curves(myCurves);
510     myBCurve = theRevol.BarycCurve();
511     GlobalPerform();
512   }
513   else {
514     theRevol.Curves(myCurves);
515     myBCurve = theRevol.BarycCurve();    
516     TColGeom_SequenceOfCurve scur;
517     scur.Clear();    
518     scur.Append(myBCurve);
519     LocOpe_CSIntersector ASI1(mySUntil);
520     LocOpe_CSIntersector ASI2(mySFrom);
521     ASI1.Perform(scur);
522     ASI2.Perform(scur);
523     TopAbs_Orientation OrU, OrF;
524     TopoDS_Face FFrom, FUntil;
525     Standard_Real PrF, PrU;
526     if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
527       OrU = ASI1.Point(1,1).Orientation();
528       FUntil = ASI1.Point(1,1).Face();
529       PrU = ASI1.Point(1,1).Parameter();
530     }
531     else {
532       NotDone();
533       myStatusError = BRepFeat_NoIntersectU;
534       return;
535     }
536     if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
537       Standard_Real pr1 = ASI2.Point(1,1).Parameter();
538       pr1 = ElCLib::InPeriod(pr1,PrU-2*M_PI,PrU);
539       Standard_Real pr2 = ASI2.Point(1,ASI2.NbPoints(1)).Parameter();
540       pr2 = ElCLib::InPeriod(pr2,PrU-2*M_PI,PrU);
541       //OrF = OrU;
542       OrF = TopAbs::Reverse(OrU);
543       FFrom = ASI2.Point(1,1).Face();
544       PrF = Max(pr1, pr2);
545     }
546     else {
547       NotDone();
548       myStatusError = BRepFeat_NoIntersectF;
549       return;
550     }
551     if(!(PrU > PrF)) {
552       NotDone();
553       myStatusError = BRepFeat_IncParameter;
554       return;
555     }
556     TopoDS_Shape Comp;
557     BRep_Builder B;
558     B.MakeCompound(TopoDS::Compound(Comp));
559     TopoDS_Solid SF = BRepFeat::Tool(mySFrom, FFrom, OrF);
560     if (!SF.IsNull()) B.Add(Comp,SF);
561     TopoDS_Solid SU = BRepFeat::Tool(mySUntil, FUntil, OrU);
562     if (!SU.IsNull()) B.Add(Comp,SU);
563     BRepAlgoAPI_Cut trP(VraiRevol,Comp);
564     TopoDS_Shape Cutsh = trP.Shape();
565     TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
566     VraiRevol = ex.Current();
567     for(; ex.More(); ex.Next()) {
568       Standard_Real PrCur = BRepFeat::
569         ParametricBarycenter(ex.Current(), myBCurve);
570       if(PrF <= PrCur && PrU >= PrCur) {
571         VraiRevol = ex.Current();
572         break;
573       }
574     }
575     if(myFuse == 1 && !myJustFeat) {
576       BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
577       myShape = f.Shape();
578       UpdateDescendants(f, myShape, Standard_False);
579       Done();
580     }
581     else if(myFuse == 0 && !myJustFeat) {
582       BRepAlgoAPI_Cut c(mySbase, VraiRevol);
583       myShape = c.Shape();
584       UpdateDescendants(c, myShape, Standard_False);
585       Done();
586     }
587     else {
588       myShape = VraiRevol;
589       Done();   
590     }
591   }
592 }
593
594
595 //=======================================================================
596 //function : PerformThruAll
597 //purpose  : feature throughout the initial shape
598 //=======================================================================
599
600 void BRepFeat_MakeRevol::PerformThruAll()
601 {
602 #ifdef OCCT_DEBUG
603   Standard_Boolean trc = BRepFeat_GettraceFEAT();
604   if (trc) cout << "BRepFeat_MakeRevol::PerformThruAll()" << endl;
605 #endif
606   Perform(2.*M_PI);
607 }
608
609 //=======================================================================
610 //function : PerformUntilAngle
611 //purpose  : feature till shape Until defined with the angle
612 //=======================================================================
613
614 void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until,
615   const Standard_Real Angle)
616 {
617 #ifdef OCCT_DEBUG
618   Standard_Boolean trc = BRepFeat_GettraceFEAT();
619   if (trc) cout << "BRepFeat_MakeRevol::PerformUntilAngle(Until,Angle)" << endl;
620 #endif
621   if (Until.IsNull()) {
622     Perform(Angle);
623   }
624   if(Angle == 0) {
625     Perform(Until);
626   }
627   TopExp_Explorer exp(Until, TopAbs_FACE);
628   if (!exp.More()) {
629     throw Standard_ConstructionError();
630   }
631   if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
632     Perform(Angle);
633     return;
634   }
635   myGluedF.Clear();
636   myPerfSelection = BRepFeat_NoSelection;
637   PerfSelectionValid();
638   mySFrom.Nullify();
639   ShapeFromValid();
640   mySUntil = Until;
641   Standard_Boolean Trf = TransformShapeFU(1);
642   ShapeUntilValid();
643
644   // Produce systematicallt an almost complete revolution
645   //  BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular());
646   LocOpe_Revol theRevol;
647   theRevol.Perform(myPbase, myAxis, Angle);
648   TopoDS_Shape VraiRevol = theRevol.Shape();
649
650   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
651
652   if(Trf) {
653     myGShape = VraiRevol;
654     GeneratedShapeValid();
655
656     TopoDS_Shape Base = theRevol.FirstShape();
657     exp.Init(Base, TopAbs_FACE);
658     TopoDS_Face theBase = TopoDS::Face(exp.Current());
659     exp.Next();
660     if(exp.More()) {
661       NotDone();
662       myStatusError = BRepFeat_InvFirstShape;
663       return;
664     }
665     GluedFacesValid();
666     //VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
667
668
669     theRevol.Curves(myCurves);
670     myBCurve = theRevol.BarycCurve();
671     GlobalPerform();
672   }
673   else {
674     TColGeom_SequenceOfCurve scur;
675     theRevol.Curves(myCurves);
676     myBCurve = theRevol.BarycCurve();    
677     scur.Clear();    
678     scur.Append(myBCurve);
679     LocOpe_CSIntersector ASI(mySUntil);
680     ASI.Perform(scur);
681     if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
682       TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
683       TopoDS_Face FUntil = ASI.Point(1,1).Face();
684       TopoDS_Shape Comp;
685       BRep_Builder B;
686       B.MakeCompound(TopoDS::Compound(Comp));
687       TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
688       if (!S.IsNull()) B.Add(Comp,S);
689       BRepAlgoAPI_Cut trP(VraiRevol,Comp);
690       TopoDS_Shape Cutsh = trP.Shape();
691       TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
692       for(; ex.More(); ex.Next()) {
693         TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
694         for(; ex1.More(); ex1.Next()) {
695           const TopoDS_Face& fac = TopoDS::Face(ex1.Current());
696           if(fac.IsSame(myPbase)) {
697             VraiRevol = ex.Current();
698             break;
699           }
700         }
701       }
702       if(myFuse == 1) {
703         BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
704         myShape = f.Shape();
705         UpdateDescendants(f, myShape, Standard_False);
706         Done();
707       }
708       else if(myFuse == 0) {
709         BRepAlgoAPI_Cut c(mySbase, VraiRevol);
710         myShape = c.Shape();
711         UpdateDescendants(c, myShape, Standard_False);
712         Done();
713       }
714       else {
715         myShape = VraiRevol;
716         Done(); 
717       }
718     }         
719   }
720 }
721 //=======================================================================
722 //function : Curves
723 //purpose  : circles parallel to the generating edge of revolution
724 //=======================================================================
725
726 void BRepFeat_MakeRevol::Curves(TColGeom_SequenceOfCurve& scur)
727 {
728   scur = myCurves;
729 }
730
731 //=======================================================================
732 //function : BarycCurve
733 //purpose  : pass through the center of mass of the primitive
734 //=======================================================================
735
736 Handle(Geom_Curve) BRepFeat_MakeRevol::BarycCurve()
737 {
738   return myBCurve;
739 }
740
741 //=======================================================================
742 //function : VerifGluedFaces
743 //purpose  : Check intersection Tool/theSkface = thePbase
744 //           if yes -> OK otherwise -> case without gluing
745 //=======================================================================
746
747 static void VerifGluedFaces(const TopoDS_Face& theSkface,
748   const TopoDS_Shape& thePbase,
749   Handle(Geom_Curve)& theBCurve,
750   TColGeom_SequenceOfCurve& theCurves,
751   LocOpe_Revol& theRevol,
752   TopTools_DataMapOfShapeShape& theMap)
753 {
754   Standard_Boolean GluedFaces = Standard_True;
755   TopoDS_Shape VraiRevol = theRevol.Shape();
756
757   TColGeom_SequenceOfCurve scur;
758   theRevol.Curves(theCurves);
759   theBCurve = theRevol.BarycCurve();    
760   scur.Clear();    
761   scur.Append(theBCurve);
762   LocOpe_CSIntersector ASI(theSkface);
763   ASI.Perform(scur);
764   if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
765     TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
766     TopoDS_Face FSk = ASI.Point(1,1).Face();
767     TopoDS_Shape Comp;
768     BRep_Builder B;
769     B.MakeCompound(TopoDS::Compound(Comp));
770     TopoDS_Solid S = BRepFeat::Tool(theSkface, FSk, Or);
771     if (!S.IsNull()) B.Add(Comp,S);
772     BRepAlgoAPI_Cut trP(VraiRevol,Comp);
773     TopoDS_Shape Cutsh = trP.Shape();
774     TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
775     for(; ex.More(); ex.Next()) {
776       TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
777       for(; ex1.More(); ex1.Next()) {
778         const TopoDS_Face& fac1 = TopoDS::Face(ex1.Current());
779         TopExp_Explorer ex2(thePbase, TopAbs_FACE);
780         for(; ex2.More(); ex2.Next()) {
781           const TopoDS_Face& fac2 = TopoDS::Face(ex2.Current());
782           if(fac1.IsSame(fac2)) break;
783         }
784         if (ex2.More()) break;
785       }
786       if (ex1.More()) continue;
787       GluedFaces = Standard_False;
788       break;
789     }
790     if (!GluedFaces) {
791 #ifdef OCCT_DEBUG
792       Standard_Boolean trc = BRepFeat_GettraceFEAT();
793       if (trc) cout << " Intersection Revol/skface : no gluing" << endl;
794 #endif
795       theMap.Clear();
796     }
797   }
798 }
799
800 //=======================================================================
801 //function : MajMap
802 //purpose  : management of descendants
803 //=======================================================================
804
805 static void MajMap(const TopoDS_Shape& theB,
806   const LocOpe_Revol& theP,
807   TopTools_DataMapOfShapeListOfShape& theMap, // myMap
808   TopoDS_Shape& theFShape,  // myFShape
809   TopoDS_Shape& theLShape) // myLShape
810 {
811   TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
812   if (exp.More()) {
813     theFShape = exp.Current();
814     TopTools_ListOfShape thelist;
815     theMap.Bind(theFShape, thelist);
816     for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
817       theMap(theFShape).Append(exp.Current());
818     }
819   }
820
821   exp.Init(theP.LastShape(),TopAbs_WIRE);
822   if (exp.More()) {
823     theLShape = exp.Current();
824     TopTools_ListOfShape thelist1;
825     theMap.Bind(theLShape, thelist1);
826     for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
827       theMap(theLShape).Append(exp.Current());
828     }
829   }
830
831   for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
832     if (!theMap.IsBound(exp.Current())) {
833       TopTools_ListOfShape thelist2;
834       theMap.Bind(exp.Current(), thelist2);
835       theMap(exp.Current()) = theP.Shapes(exp.Current());
836     }
837   }
838 }
839
840
841
842 //=======================================================================
843 //function : ToFuse
844 //purpose  : two faces samedomaine or not
845 //=======================================================================
846
847 Standard_Boolean ToFuse(const TopoDS_Face& F1,
848   const TopoDS_Face& F2)
849 {
850   if (F1.IsNull() || F2.IsNull()) {
851     return Standard_False;
852   }
853
854   Handle(Geom_Surface) S1,S2;
855   TopLoc_Location loc1, loc2;
856   Handle(Standard_Type) typS1,typS2;
857   const Standard_Real tollin = Precision::Confusion();
858   const Standard_Real tolang = Precision::Angular();
859
860   S1 = BRep_Tool::Surface(F1,loc1);
861   S2 = BRep_Tool::Surface(F2,loc2);
862
863   typS1 = S1->DynamicType();
864   typS2 = S2->DynamicType();
865
866   if (typS1 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
867     S1 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S1)->BasisSurface();
868     typS1 = S1->DynamicType();
869   }
870
871   if (typS2 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
872     S2 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S2)->BasisSurface();
873     typS2 = S2->DynamicType();
874   }
875
876   if (typS1 != typS2) {
877     return Standard_False;
878   }
879
880
881   Standard_Boolean ValRet = Standard_False;
882   if (typS1 == STANDARD_TYPE(Geom_Plane)) {
883     S1 = BRep_Tool::Surface(F1);  // to apply the location.
884     S2 = BRep_Tool::Surface(F2);
885     gp_Pln pl1( Handle(Geom_Plane)::DownCast (S1)->Pln());
886     gp_Pln pl2( Handle(Geom_Plane)::DownCast (S2)->Pln());
887
888     if (pl1.Position().IsCoplanar(pl2.Position(),tollin,tolang)) {
889       ValRet = Standard_True;
890     }
891   }
892
893   return ValRet;
894 }
895
896
897
898
899
900
901
902
903