39976e3d6734449f5ce046ef7a24da5eef3de273
[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 #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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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 OCCT_DEBUG
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       OrF = TopAbs::Reverse(OrU);
609       FFrom = ASI2.Point(1,1).Face();
610       PrF = Max(pr1, pr2);
611     }
612     else {
613       NotDone();
614       myStatusError = BRepFeat_NoIntersectF;
615       return;
616     }
617     if(!(PrU > PrF)) {
618       NotDone();
619       myStatusError = BRepFeat_IncParameter;
620       return;
621     }
622     TopoDS_Shape Comp;
623     BRep_Builder B;
624     B.MakeCompound(TopoDS::Compound(Comp));
625     TopoDS_Solid SF = BRepFeat::Tool(mySFrom, FFrom, OrF);
626     if (!SF.IsNull()) B.Add(Comp,SF);
627     TopoDS_Solid SU = BRepFeat::Tool(mySUntil, FUntil, OrU);
628     if (!SU.IsNull()) B.Add(Comp,SU);
629     //modified by NIZNHY-PKV Thu Mar 21 18:18:54 2002 f
630     //BRepAlgo_Cut trP(VraiRevol,Comp);
631     BRepAlgoAPI_Cut trP(VraiRevol,Comp);
632     //modified by NIZNHY-PKV Thu Mar 21 18:18:57 2002 t
633     TopoDS_Shape Cutsh = trP.Shape();
634     TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
635     //    Standard_Real PrF = BRepFeat::ParametricBarycenter(mySFrom, myBCurve);
636     //    Standard_Real PrU = BRepFeat::ParametricBarycenter(mySUntil, myBCurve);
637     VraiRevol = ex.Current();
638     for(; ex.More(); ex.Next()) {
639       Standard_Real PrCur = BRepFeat::
640         ParametricBarycenter(ex.Current(), myBCurve);
641       if(PrF <= PrCur && PrU >= PrCur) {
642         VraiRevol = ex.Current();
643         break;
644       }
645     }
646     if(myFuse == 1 && !myJustFeat) {
647       //modified by NIZNHY-PKV Thu Mar 21 18:19:14 2002 f
648       //BRepAlgo_Fuse f(mySbase, VraiRevol);
649       //myShape = f.Shape();
650       //UpdateDescendants(f.Builder(), myShape, Standard_False);
651       BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
652       myShape = f.Shape();
653       UpdateDescendants(f, myShape, Standard_False);
654       //modified by NIZNHY-PKV Thu Mar 21 18:19:18 2002 t
655       Done();
656     }
657     else if(myFuse == 0 && !myJustFeat) {
658       //modified by NIZNHY-PKV Thu Mar 21 18:19:46 2002 f
659       //BRepAlgo_Cut c(mySbase, VraiRevol);
660       //myShape = c.Shape();
661       //UpdateDescendants(c.Builder(), myShape, Standard_False);
662       BRepAlgoAPI_Cut c(mySbase, VraiRevol);
663       myShape = c.Shape();
664       UpdateDescendants(c, myShape, Standard_False);
665       //modified by NIZNHY-PKV Thu Mar 21 18:19:50 2002 t
666       Done();
667     }
668     else {
669       myShape = VraiRevol;
670       Done();   
671     }
672   }
673 }
674
675
676 //=======================================================================
677 //function : PerformThruAll
678 //purpose  : feature throughout the initial shape
679 //=======================================================================
680
681 void BRepFeat_MakeRevol::PerformThruAll()
682 {
683 #ifdef OCCT_DEBUG
684   Standard_Boolean trc = BRepFeat_GettraceFEAT();
685   if (trc) cout << "BRepFeat_MakeRevol::PerformThruAll()" << endl;
686 #endif
687   Perform(2.*M_PI);
688 }
689
690 //=======================================================================
691 //function : PerformUntilAngle
692 //purpose  : feature till shape Until defined with the angle
693 //=======================================================================
694
695 void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until,
696   const Standard_Real Angle)
697 {
698 #ifdef OCCT_DEBUG
699   Standard_Boolean trc = BRepFeat_GettraceFEAT();
700   if (trc) cout << "BRepFeat_MakeRevol::PerformUntilAngle(Until,Angle)" << endl;
701 #endif
702   if (Until.IsNull()) {
703     Perform(Angle);
704   }
705   if(Angle == 0) {
706     Perform(Until);
707   }
708   TopExp_Explorer exp(Until, TopAbs_FACE);
709   if (!exp.More()) {
710     Standard_ConstructionError::Raise();
711   }
712   if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
713     Perform(Angle);
714     return;
715   }
716   myGluedF.Clear();
717   myPerfSelection = BRepFeat_NoSelection;
718   PerfSelectionValid();
719   mySFrom.Nullify();
720   ShapeFromValid();
721   mySUntil = Until;
722   Standard_Boolean Trf = TransformShapeFU(1);
723   ShapeUntilValid();
724
725   // Produce systematicallt an almost complete revolution
726   //  BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular());
727   LocOpe_Revol theRevol;
728   theRevol.Perform(myPbase, myAxis, Angle);
729   TopoDS_Shape VraiRevol = theRevol.Shape();
730
731   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
732
733   if(Trf) {
734     myGShape = VraiRevol;
735     GeneratedShapeValid();
736
737     TopoDS_Shape Base = theRevol.FirstShape();
738     exp.Init(Base, TopAbs_FACE);
739     TopoDS_Face theBase = TopoDS::Face(exp.Current());
740     exp.Next();
741     if(exp.More()) {
742       NotDone();
743       myStatusError = BRepFeat_InvFirstShape;
744       return;
745     }
746     GluedFacesValid();
747     //VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
748
749
750     theRevol.Curves(myCurves);
751     myBCurve = theRevol.BarycCurve();
752     GlobalPerform();
753   }
754   else {
755     TColGeom_SequenceOfCurve scur;
756     theRevol.Curves(myCurves);
757     myBCurve = theRevol.BarycCurve();    
758     scur.Clear();    
759     scur.Append(myBCurve);
760     LocOpe_CSIntersector ASI(mySUntil);
761     ASI.Perform(scur);
762     if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
763       TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
764       TopoDS_Face FUntil = ASI.Point(1,1).Face();
765       TopoDS_Shape Comp;
766       BRep_Builder B;
767       B.MakeCompound(TopoDS::Compound(Comp));
768       TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
769       if (!S.IsNull()) B.Add(Comp,S);
770       //modified by NIZNHY-PKV Thu Mar 21 18:20:14 2002 f
771       //BRepAlgo_Cut trP(VraiRevol,Comp);
772       BRepAlgoAPI_Cut trP(VraiRevol,Comp);
773       //modified by NIZNHY-PKV Thu Mar 21 18:20:19 2002 t
774       TopoDS_Shape Cutsh = trP.Shape();
775       TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
776       for(; ex.More(); ex.Next()) {
777         TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
778         for(; ex1.More(); ex1.Next()) {
779           const TopoDS_Face& fac = TopoDS::Face(ex1.Current());
780           if(fac.IsSame(myPbase)) {
781             VraiRevol = ex.Current();
782             break;
783           }
784         }
785       }
786       if(myFuse == 1) {
787         //modified by NIZNHY-PKV Thu Mar 21 18:20:36 2002 f
788         //BRepAlgo_Fuse f(mySbase, VraiRevol);
789         //myShape = f.Shape();
790         //UpdateDescendants(f.Builder(), myShape, Standard_False);
791         BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
792         myShape = f.Shape();
793         UpdateDescendants(f, myShape, Standard_False);
794         //modified by NIZNHY-PKV Thu Mar 21 18:20:40 2002 t
795         Done();
796       }
797       else if(myFuse == 0) {
798         //modified by NIZNHY-PKV Thu Mar 21 18:21:07 2002 f
799         //BRepAlgo_Cut c(mySbase, VraiRevol);
800         //myShape = c.Shape();
801         //UpdateDescendants(c.Builder(), myShape, Standard_False);
802         BRepAlgoAPI_Cut c(mySbase, VraiRevol);
803         myShape = c.Shape();
804         UpdateDescendants(c, myShape, Standard_False);
805         //modified by NIZNHY-PKV Thu Mar 21 18:21:26 2002 t
806         Done();
807       }
808       else {
809         myShape = VraiRevol;
810         Done(); 
811       }
812     }         
813   }
814 }
815 //=======================================================================
816 //function : Curves
817 //purpose  : circles parallel to the generating edge of revolution
818 //=======================================================================
819
820 void BRepFeat_MakeRevol::Curves(TColGeom_SequenceOfCurve& scur)
821 {
822   scur = myCurves;
823 }
824
825 //=======================================================================
826 //function : BarycCurve
827 //purpose  : pass through the center of mass of the primitive
828 //=======================================================================
829
830 Handle(Geom_Curve) BRepFeat_MakeRevol::BarycCurve()
831 {
832   return myBCurve;
833 }
834
835 //=======================================================================
836 //function : VerifGluedFaces
837 //purpose  : Check intersection Tool/theSkface = thePbase
838 //           if yes -> OK otherwise -> case without gluing
839 //=======================================================================
840
841 static void VerifGluedFaces(const TopoDS_Face& theSkface,
842   const TopoDS_Shape& thePbase,
843   Handle(Geom_Curve)& theBCurve,
844   TColGeom_SequenceOfCurve& theCurves,
845   LocOpe_Revol& theRevol,
846   TopTools_DataMapOfShapeShape& theMap)
847 {
848   Standard_Boolean GluedFaces = Standard_True;
849   TopoDS_Shape VraiRevol = theRevol.Shape();
850
851   TColGeom_SequenceOfCurve scur;
852   theRevol.Curves(theCurves);
853   theBCurve = theRevol.BarycCurve();    
854   scur.Clear();    
855   scur.Append(theBCurve);
856   LocOpe_CSIntersector ASI(theSkface);
857   ASI.Perform(scur);
858   if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
859     TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
860     TopoDS_Face FSk = ASI.Point(1,1).Face();
861     TopoDS_Shape Comp;
862     BRep_Builder B;
863     B.MakeCompound(TopoDS::Compound(Comp));
864     TopoDS_Solid S = BRepFeat::Tool(theSkface, FSk, Or);
865     if (!S.IsNull()) B.Add(Comp,S);
866     //modified by NIZNHY-PKV Thu Mar 21 18:21:54 2002 f
867     //BRepAlgo_Cut trP(VraiRevol,Comp);
868     BRepAlgoAPI_Cut trP(VraiRevol,Comp);
869     //modified by NIZNHY-PKV Thu Mar 21 18:21:58 2002 t
870     TopoDS_Shape Cutsh = trP.Shape();
871     TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
872     for(; ex.More(); ex.Next()) {
873       TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
874       for(; ex1.More(); ex1.Next()) {
875         const TopoDS_Face& fac1 = TopoDS::Face(ex1.Current());
876         TopExp_Explorer ex2(thePbase, TopAbs_FACE);
877         for(; ex2.More(); ex2.Next()) {
878           const TopoDS_Face& fac2 = TopoDS::Face(ex2.Current());
879           if(fac1.IsSame(fac2)) break;
880         }
881         if (ex2.More()) break;
882       }
883       if (ex1.More()) continue;
884       GluedFaces = Standard_False;
885       break;
886     }
887     if (!GluedFaces) {
888 #ifdef OCCT_DEBUG
889       Standard_Boolean trc = BRepFeat_GettraceFEAT();
890       if (trc) cout << " Intersection Revol/skface : no gluing" << endl;
891 #endif
892       theMap.Clear();
893     }
894   }
895 }
896
897 //=======================================================================
898 //function : MajMap
899 //purpose  : management of descendants
900 //=======================================================================
901
902 static void MajMap(const TopoDS_Shape& theB,
903   const LocOpe_Revol& theP,
904   TopTools_DataMapOfShapeListOfShape& theMap, // myMap
905   TopoDS_Shape& theFShape,  // myFShape
906   TopoDS_Shape& theLShape) // myLShape
907 {
908   TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
909   if (exp.More()) {
910     theFShape = exp.Current();
911     TopTools_ListOfShape thelist;
912     theMap.Bind(theFShape, thelist);
913     for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
914       theMap(theFShape).Append(exp.Current());
915     }
916   }
917
918   exp.Init(theP.LastShape(),TopAbs_WIRE);
919   if (exp.More()) {
920     theLShape = exp.Current();
921     TopTools_ListOfShape thelist1;
922     theMap.Bind(theLShape, thelist1);
923     for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
924       theMap(theLShape).Append(exp.Current());
925     }
926   }
927
928   for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
929     if (!theMap.IsBound(exp.Current())) {
930       TopTools_ListOfShape thelist2;
931       theMap.Bind(exp.Current(), thelist2);
932       theMap(exp.Current()) = theP.Shapes(exp.Current());
933     }
934   }
935 }
936
937
938
939 //=======================================================================
940 //function : ToFuse
941 //purpose  : two faces samedomaine or not
942 //=======================================================================
943
944 Standard_Boolean ToFuse(const TopoDS_Face& F1,
945   const TopoDS_Face& F2)
946 {
947   if (F1.IsNull() || F2.IsNull()) {
948     return Standard_False;
949   }
950
951   Handle(Geom_Surface) S1,S2;
952   TopLoc_Location loc1, loc2;
953   Handle(Standard_Type) typS1,typS2;
954   const Standard_Real tollin = Precision::Confusion();
955   const Standard_Real tolang = Precision::Angular();
956
957   S1 = BRep_Tool::Surface(F1,loc1);
958   S2 = BRep_Tool::Surface(F2,loc2);
959
960   typS1 = S1->DynamicType();
961   typS2 = S2->DynamicType();
962
963   if (typS1 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
964     S1 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S1)->BasisSurface();
965     typS1 = S1->DynamicType();
966   }
967
968   if (typS2 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
969     S2 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S2)->BasisSurface();
970     typS2 = S2->DynamicType();
971   }
972
973   if (typS1 != typS2) {
974     return Standard_False;
975   }
976
977
978   Standard_Boolean ValRet = Standard_False;
979   if (typS1 == STANDARD_TYPE(Geom_Plane)) {
980     S1 = BRep_Tool::Surface(F1);  // to apply the location.
981     S2 = BRep_Tool::Surface(F2);
982     gp_Pln pl1( Handle(Geom_Plane)::DownCast (S1)->Pln());
983     gp_Pln pl2( Handle(Geom_Plane)::DownCast (S2)->Pln());
984
985     if (pl1.Position().IsCoplanar(pl2.Position(),tollin,tolang)) {
986       ValRet = Standard_True;
987     }
988   }
989
990   return ValRet;
991 }
992
993
994
995
996
997
998
999
1000