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