193b1232777784b42650dbf82b33103cfd5a76f1
[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     Standard_ConstructionError::Raise();
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     Standard_ConstructionError::Raise();
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       //modified by NIZNHY-PKV Thu Mar 21 18:15:06 2002 f
300       //BRepAlgo_Fuse f(mySbase, myGShape);
301       //myShape = f.Shape();
302       //UpdateDescendants(f.Builder(), myShape, Standard_False);
303       BRepAlgoAPI_Fuse f(mySbase, myGShape);
304       myShape = f.Shape();
305       UpdateDescendants(f, myShape, Standard_False);
306       //modified by NIZNHY-PKV Thu Mar 21 18:15:11 2002 t
307       Done();
308     }
309     else if(myFuse == 0) {
310       //modified by NIZNHY-PKV Thu Mar 21 18:15:37 2002 f
311       //BRepAlgo_Cut c(mySbase, myGShape);
312       //myShape = c.Shape();
313       //UpdateDescendants(c.Builder(), myShape, Standard_False);
314       BRepAlgoAPI_Cut c(mySbase, myGShape);
315       myShape = c.Shape();
316       UpdateDescendants(c, myShape, Standard_False);
317       //modified by NIZNHY-PKV Thu Mar 21 18:15:47 2002 t
318       Done();
319     }
320     else {
321       myShape = myGShape;
322       Done();
323     }
324   }
325   else {
326     theRevol.Curves(myCurves);
327     myBCurve = theRevol.BarycCurve();
328     GlobalPerform();
329   }
330 }
331
332
333 //=======================================================================
334 //function : Perform
335 //purpose  : feature till shape Until
336 //=======================================================================
337
338 void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& Until)
339 {
340 #ifdef OCCT_DEBUG
341   Standard_Boolean trc = BRepFeat_GettraceFEAT();
342   if (trc) cout << "BRepFeat_MakeRevol::Perform(Until)" << endl;
343 #endif
344   Standard_Real Angle = 0.;
345   Standard_Boolean TourComplet = Standard_False;
346
347   if (Until.IsNull()) {
348     Standard_ConstructionError::Raise();
349   }
350   TopExp_Explorer exp(Until, TopAbs_FACE);
351   if (!exp.More()) {
352     Standard_ConstructionError::Raise();
353   }
354   if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
355     Angle = 2*M_PI;
356     TourComplet = Standard_True;
357   }
358   myGluedF.Clear();
359   myPerfSelection = BRepFeat_SelectionU;
360   PerfSelectionValid();
361   mySFrom.Nullify();
362   ShapeFromValid();
363   mySUntil = Until;
364   Standard_Boolean Trf = TransformShapeFU(1);
365   ShapeUntilValid();
366
367   // Do systematically almost complete revolution
368   // BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular());
369   LocOpe_Revol theRevol;
370   if(!TourComplet) {
371     Angle = 2.*M_PI- 3*M_PI/180.;
372 #ifdef OCCT_DEBUG
373     if (trc) cout << " No complete Revolution" << endl;
374 #endif
375   }
376   theRevol.Perform(myPbase, myAxis, Angle);
377   TopoDS_Shape VraiRevol = theRevol.Shape();
378   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
379
380
381   if(!Trf) {
382
383     myGShape = VraiRevol;
384     GeneratedShapeValid();
385
386     TopoDS_Shape Base = theRevol.FirstShape();
387     exp.Init(Base, TopAbs_FACE);
388     TopoDS_Face theBase = TopoDS::Face(exp.Current());
389     exp.Next();
390     if(exp.More()) {
391       NotDone();
392       myStatusError = BRepFeat_InvFirstShape;
393       return;
394     }
395     GluedFacesValid();
396     //VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
397
398     theRevol.Curves(myCurves);
399     myBCurve = theRevol.BarycCurve();
400     GlobalPerform();
401   }
402   else {
403     TColGeom_SequenceOfCurve scur;
404     theRevol.Curves(myCurves);
405     myBCurve = theRevol.BarycCurve();    
406     scur.Clear();    
407     scur.Append(myBCurve);
408     LocOpe_CSIntersector ASI(mySUntil);
409     ASI.Perform(scur);
410     if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
411       TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
412       TopoDS_Face FUntil = ASI.Point(1,1).Face();
413       TopoDS_Shape Comp;
414       BRep_Builder B;
415       B.MakeCompound(TopoDS::Compound(Comp));
416       TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
417       if (!S.IsNull()) B.Add(Comp,S);
418       //modified by NIZNHY-PKV Thu Mar 21 18:17:31 2002 f
419       //BRepAlgo_Cut trP(VraiRevol,Comp);
420       BRepAlgoAPI_Cut trP(VraiRevol,Comp);
421       //modified by NIZNHY-PKV Thu Mar 21 18:17:37 2002 t
422       TopoDS_Shape Cutsh = trP.Shape();
423       TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
424       for(; ex.More(); ex.Next()) {
425         TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
426         for(; ex1.More(); ex1.Next()) {
427           const TopoDS_Face& fac = TopoDS::Face(ex1.Current());
428           if(fac.IsSame(myPbase)) {
429             VraiRevol = ex.Current();
430             break;
431           }
432         }
433       }
434       if(myFuse == 1) {
435         //modified by NIZNHY-PKV Thu Mar 21 18:17:53 2002 f
436         //BRepAlgo_Fuse f(mySbase, VraiRevol);
437         //myShape = f.Shape();
438         //UpdateDescendants(f.Builder(), myShape, Standard_False);
439         BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
440         myShape = f.Shape();
441         UpdateDescendants(f, myShape, Standard_False);
442         //modified by NIZNHY-PKV Thu Mar 21 18:17:57 2002 t
443         Done();
444       }
445       else if(myFuse == 0) {
446         //modified by NIZNHY-PKV Thu Mar 21 18:18:23 2002 f
447         //BRepAlgo_Cut c(mySbase, VraiRevol);
448         //myShape = c.Shape();
449         //UpdateDescendants(c.Builder(), myShape, Standard_False);
450         BRepAlgoAPI_Cut c(mySbase, VraiRevol);
451         myShape = c.Shape();
452         UpdateDescendants(c, myShape, Standard_False);
453         //modified by NIZNHY-PKV Thu Mar 21 18:18:28 2002 t
454         Done();
455       }
456       else {
457         myShape = VraiRevol;
458         Done(); 
459       }
460     }         
461   }
462   // Loop of control of descendance
463   /*
464   TopExp_Explorer expr(mySbase, TopAbs_FACE);
465   char nom1[20], nom2[20];
466   Standard_Integer ii = 0;
467   for(; expr.More(); expr.Next()) {
468   ii++;
469   sprintf(nom1, "faceinitial_%d", ii);
470   DBRep::Set(nom1, expr.Current());
471   Standard_Integer jj = 0;
472   const TopTools_ListOfShape& list = Modified(expr.Current());
473   TopTools_ListIteratorOfListOfShape ite(list);
474   for(; ite.More(); ite.Next()) {
475   jj++;
476   sprintf(nom2, "facemodifie_%d_%d", ii, jj);
477   DBRep::Set(nom2, ite.Value());
478   }
479   }
480
481   expr.Init(myPbase, TopAbs_EDGE); 
482   ii=0; 
483   for(; expr.More(); expr.Next()) {
484   ii++;
485   sprintf(nom1, "edgeinitial_%d", ii); 
486   DBRep::Set(nom1, expr.Current()); 
487   Standard_Integer jj = 0;
488   const TopTools_ListOfShape& list = Generated(expr.Current());
489   TopTools_ListIteratorOfListOfShape ite(list);
490   for(; ite.More(); ite.Next()) {
491   jj++;
492   sprintf(nom2, "facegeneree_%d_%d", ii, jj);
493   DBRep::Set(nom2, ite.Value());
494   }
495   }
496   */
497 }
498
499
500 //=======================================================================
501 //function : Perform
502 //purpose  : feature limited by two shapes
503 //=======================================================================
504
505 void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
506   const TopoDS_Shape& Until)
507 {
508 #ifdef OCCT_DEBUG
509   Standard_Boolean trc = BRepFeat_GettraceFEAT();
510   if (trc) cout << "BRepFeat_MakeRevol::Perform(From,Until)" << endl;
511 #endif
512   if (From.IsNull() || Until.IsNull()) {
513     Standard_ConstructionError::Raise();
514   }
515   if (!mySkface.IsNull()) {
516     if (From.IsSame(mySkface)) {
517       myJustGluer = Standard_True;
518       Perform(Until);
519       if (myJustGluer) return;
520     }
521     else if (Until.IsSame(mySkface)) {
522       myJustGluer = Standard_True;
523       myAxis.Reverse();
524       Perform(From);
525       if (myJustGluer) return;
526     }
527   }
528
529   myGluedF.Clear();
530   myPerfSelection = BRepFeat_SelectionFU;
531   PerfSelectionValid();
532
533   TopExp_Explorer exp(From, TopAbs_FACE);
534   if (!exp.More()) {
535     Standard_ConstructionError::Raise();
536   }
537   exp.Init(Until, TopAbs_FACE);
538   if (!exp.More()) {
539     Standard_ConstructionError::Raise();
540   }
541
542   mySFrom = From;
543   Standard_Boolean Trff = TransformShapeFU(0);
544   ShapeFromValid();
545   mySUntil = Until;
546   Standard_Boolean Trfu = TransformShapeFU(1);
547   ShapeUntilValid();  
548
549   if(Trfu != Trff) {
550     NotDone();
551     myStatusError = BRepFeat_IncTypes;
552     return;
553   }
554
555   LocOpe_Revol theRevol;
556   theRevol.Perform(myPbase, myAxis, 2*M_PI);
557   TopoDS_Shape VraiRevol = theRevol.Shape();
558
559   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
560
561   if(!Trff) {    
562     myGShape = VraiRevol;
563     GeneratedShapeValid();
564     GluedFacesValid();
565     //    VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
566
567     theRevol.Curves(myCurves);
568     myBCurve = theRevol.BarycCurve();
569     GlobalPerform();
570   }
571   else {
572     theRevol.Curves(myCurves);
573     myBCurve = theRevol.BarycCurve();    
574     TColGeom_SequenceOfCurve scur;
575     scur.Clear();    
576     scur.Append(myBCurve);
577     LocOpe_CSIntersector ASI1(mySUntil);
578     LocOpe_CSIntersector ASI2(mySFrom);
579     ASI1.Perform(scur);
580     ASI2.Perform(scur);
581     TopAbs_Orientation OrU, OrF;
582     TopoDS_Face FFrom, FUntil;
583     Standard_Real PrF, PrU;
584     if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
585       OrU = ASI1.Point(1,1).Orientation();
586       FUntil = ASI1.Point(1,1).Face();
587       PrU = ASI1.Point(1,1).Parameter();
588     }
589     else {
590       NotDone();
591       myStatusError = BRepFeat_NoIntersectU;
592       return;
593     }
594     if (ASI2.IsDone() && ASI2.NbPoints(1) >=1) {
595       Standard_Real pr1 = ASI2.Point(1,1).Parameter();
596       pr1 = ElCLib::InPeriod(pr1,PrU-2*M_PI,PrU);
597       Standard_Real pr2 = ASI2.Point(1,ASI2.NbPoints(1)).Parameter();
598       pr2 = ElCLib::InPeriod(pr2,PrU-2*M_PI,PrU);
599       //OrF = OrU;
600       OrF = TopAbs::Reverse(OrU);
601       FFrom = ASI2.Point(1,1).Face();
602       PrF = Max(pr1, pr2);
603     }
604     else {
605       NotDone();
606       myStatusError = BRepFeat_NoIntersectF;
607       return;
608     }
609     if(!(PrU > PrF)) {
610       NotDone();
611       myStatusError = BRepFeat_IncParameter;
612       return;
613     }
614     TopoDS_Shape Comp;
615     BRep_Builder B;
616     B.MakeCompound(TopoDS::Compound(Comp));
617     TopoDS_Solid SF = BRepFeat::Tool(mySFrom, FFrom, OrF);
618     if (!SF.IsNull()) B.Add(Comp,SF);
619     TopoDS_Solid SU = BRepFeat::Tool(mySUntil, FUntil, OrU);
620     if (!SU.IsNull()) B.Add(Comp,SU);
621     //modified by NIZNHY-PKV Thu Mar 21 18:18:54 2002 f
622     //BRepAlgo_Cut trP(VraiRevol,Comp);
623     BRepAlgoAPI_Cut trP(VraiRevol,Comp);
624     //modified by NIZNHY-PKV Thu Mar 21 18:18:57 2002 t
625     TopoDS_Shape Cutsh = trP.Shape();
626     TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
627     //    Standard_Real PrF = BRepFeat::ParametricBarycenter(mySFrom, myBCurve);
628     //    Standard_Real PrU = BRepFeat::ParametricBarycenter(mySUntil, myBCurve);
629     VraiRevol = ex.Current();
630     for(; ex.More(); ex.Next()) {
631       Standard_Real PrCur = BRepFeat::
632         ParametricBarycenter(ex.Current(), myBCurve);
633       if(PrF <= PrCur && PrU >= PrCur) {
634         VraiRevol = ex.Current();
635         break;
636       }
637     }
638     if(myFuse == 1 && !myJustFeat) {
639       //modified by NIZNHY-PKV Thu Mar 21 18:19:14 2002 f
640       //BRepAlgo_Fuse f(mySbase, VraiRevol);
641       //myShape = f.Shape();
642       //UpdateDescendants(f.Builder(), myShape, Standard_False);
643       BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
644       myShape = f.Shape();
645       UpdateDescendants(f, myShape, Standard_False);
646       //modified by NIZNHY-PKV Thu Mar 21 18:19:18 2002 t
647       Done();
648     }
649     else if(myFuse == 0 && !myJustFeat) {
650       //modified by NIZNHY-PKV Thu Mar 21 18:19:46 2002 f
651       //BRepAlgo_Cut c(mySbase, VraiRevol);
652       //myShape = c.Shape();
653       //UpdateDescendants(c.Builder(), myShape, Standard_False);
654       BRepAlgoAPI_Cut c(mySbase, VraiRevol);
655       myShape = c.Shape();
656       UpdateDescendants(c, myShape, Standard_False);
657       //modified by NIZNHY-PKV Thu Mar 21 18:19:50 2002 t
658       Done();
659     }
660     else {
661       myShape = VraiRevol;
662       Done();   
663     }
664   }
665 }
666
667
668 //=======================================================================
669 //function : PerformThruAll
670 //purpose  : feature throughout the initial shape
671 //=======================================================================
672
673 void BRepFeat_MakeRevol::PerformThruAll()
674 {
675 #ifdef OCCT_DEBUG
676   Standard_Boolean trc = BRepFeat_GettraceFEAT();
677   if (trc) cout << "BRepFeat_MakeRevol::PerformThruAll()" << endl;
678 #endif
679   Perform(2.*M_PI);
680 }
681
682 //=======================================================================
683 //function : PerformUntilAngle
684 //purpose  : feature till shape Until defined with the angle
685 //=======================================================================
686
687 void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until,
688   const Standard_Real Angle)
689 {
690 #ifdef OCCT_DEBUG
691   Standard_Boolean trc = BRepFeat_GettraceFEAT();
692   if (trc) cout << "BRepFeat_MakeRevol::PerformUntilAngle(Until,Angle)" << endl;
693 #endif
694   if (Until.IsNull()) {
695     Perform(Angle);
696   }
697   if(Angle == 0) {
698     Perform(Until);
699   }
700   TopExp_Explorer exp(Until, TopAbs_FACE);
701   if (!exp.More()) {
702     Standard_ConstructionError::Raise();
703   }
704   if (!mySkface.IsNull() && Until.IsSame(mySkface)) {
705     Perform(Angle);
706     return;
707   }
708   myGluedF.Clear();
709   myPerfSelection = BRepFeat_NoSelection;
710   PerfSelectionValid();
711   mySFrom.Nullify();
712   ShapeFromValid();
713   mySUntil = Until;
714   Standard_Boolean Trf = TransformShapeFU(1);
715   ShapeUntilValid();
716
717   // Produce systematicallt an almost complete revolution
718   //  BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular());
719   LocOpe_Revol theRevol;
720   theRevol.Perform(myPbase, myAxis, Angle);
721   TopoDS_Shape VraiRevol = theRevol.Shape();
722
723   MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
724
725   if(Trf) {
726     myGShape = VraiRevol;
727     GeneratedShapeValid();
728
729     TopoDS_Shape Base = theRevol.FirstShape();
730     exp.Init(Base, TopAbs_FACE);
731     TopoDS_Face theBase = TopoDS::Face(exp.Current());
732     exp.Next();
733     if(exp.More()) {
734       NotDone();
735       myStatusError = BRepFeat_InvFirstShape;
736       return;
737     }
738     GluedFacesValid();
739     //VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
740
741
742     theRevol.Curves(myCurves);
743     myBCurve = theRevol.BarycCurve();
744     GlobalPerform();
745   }
746   else {
747     TColGeom_SequenceOfCurve scur;
748     theRevol.Curves(myCurves);
749     myBCurve = theRevol.BarycCurve();    
750     scur.Clear();    
751     scur.Append(myBCurve);
752     LocOpe_CSIntersector ASI(mySUntil);
753     ASI.Perform(scur);
754     if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
755       TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
756       TopoDS_Face FUntil = ASI.Point(1,1).Face();
757       TopoDS_Shape Comp;
758       BRep_Builder B;
759       B.MakeCompound(TopoDS::Compound(Comp));
760       TopoDS_Solid S = BRepFeat::Tool(mySUntil, FUntil, Or);
761       if (!S.IsNull()) B.Add(Comp,S);
762       //modified by NIZNHY-PKV Thu Mar 21 18:20:14 2002 f
763       //BRepAlgo_Cut trP(VraiRevol,Comp);
764       BRepAlgoAPI_Cut trP(VraiRevol,Comp);
765       //modified by NIZNHY-PKV Thu Mar 21 18:20:19 2002 t
766       TopoDS_Shape Cutsh = trP.Shape();
767       TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
768       for(; ex.More(); ex.Next()) {
769         TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
770         for(; ex1.More(); ex1.Next()) {
771           const TopoDS_Face& fac = TopoDS::Face(ex1.Current());
772           if(fac.IsSame(myPbase)) {
773             VraiRevol = ex.Current();
774             break;
775           }
776         }
777       }
778       if(myFuse == 1) {
779         //modified by NIZNHY-PKV Thu Mar 21 18:20:36 2002 f
780         //BRepAlgo_Fuse f(mySbase, VraiRevol);
781         //myShape = f.Shape();
782         //UpdateDescendants(f.Builder(), myShape, Standard_False);
783         BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
784         myShape = f.Shape();
785         UpdateDescendants(f, myShape, Standard_False);
786         //modified by NIZNHY-PKV Thu Mar 21 18:20:40 2002 t
787         Done();
788       }
789       else if(myFuse == 0) {
790         //modified by NIZNHY-PKV Thu Mar 21 18:21:07 2002 f
791         //BRepAlgo_Cut c(mySbase, VraiRevol);
792         //myShape = c.Shape();
793         //UpdateDescendants(c.Builder(), myShape, Standard_False);
794         BRepAlgoAPI_Cut c(mySbase, VraiRevol);
795         myShape = c.Shape();
796         UpdateDescendants(c, myShape, Standard_False);
797         //modified by NIZNHY-PKV Thu Mar 21 18:21:26 2002 t
798         Done();
799       }
800       else {
801         myShape = VraiRevol;
802         Done(); 
803       }
804     }         
805   }
806 }
807 //=======================================================================
808 //function : Curves
809 //purpose  : circles parallel to the generating edge of revolution
810 //=======================================================================
811
812 void BRepFeat_MakeRevol::Curves(TColGeom_SequenceOfCurve& scur)
813 {
814   scur = myCurves;
815 }
816
817 //=======================================================================
818 //function : BarycCurve
819 //purpose  : pass through the center of mass of the primitive
820 //=======================================================================
821
822 Handle(Geom_Curve) BRepFeat_MakeRevol::BarycCurve()
823 {
824   return myBCurve;
825 }
826
827 //=======================================================================
828 //function : VerifGluedFaces
829 //purpose  : Check intersection Tool/theSkface = thePbase
830 //           if yes -> OK otherwise -> case without gluing
831 //=======================================================================
832
833 static void VerifGluedFaces(const TopoDS_Face& theSkface,
834   const TopoDS_Shape& thePbase,
835   Handle(Geom_Curve)& theBCurve,
836   TColGeom_SequenceOfCurve& theCurves,
837   LocOpe_Revol& theRevol,
838   TopTools_DataMapOfShapeShape& theMap)
839 {
840   Standard_Boolean GluedFaces = Standard_True;
841   TopoDS_Shape VraiRevol = theRevol.Shape();
842
843   TColGeom_SequenceOfCurve scur;
844   theRevol.Curves(theCurves);
845   theBCurve = theRevol.BarycCurve();    
846   scur.Clear();    
847   scur.Append(theBCurve);
848   LocOpe_CSIntersector ASI(theSkface);
849   ASI.Perform(scur);
850   if (ASI.IsDone() && ASI.NbPoints(1) >=1) {
851     TopAbs_Orientation Or = ASI.Point(1,1).Orientation();
852     TopoDS_Face FSk = ASI.Point(1,1).Face();
853     TopoDS_Shape Comp;
854     BRep_Builder B;
855     B.MakeCompound(TopoDS::Compound(Comp));
856     TopoDS_Solid S = BRepFeat::Tool(theSkface, FSk, Or);
857     if (!S.IsNull()) B.Add(Comp,S);
858     //modified by NIZNHY-PKV Thu Mar 21 18:21:54 2002 f
859     //BRepAlgo_Cut trP(VraiRevol,Comp);
860     BRepAlgoAPI_Cut trP(VraiRevol,Comp);
861     //modified by NIZNHY-PKV Thu Mar 21 18:21:58 2002 t
862     TopoDS_Shape Cutsh = trP.Shape();
863     TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
864     for(; ex.More(); ex.Next()) {
865       TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
866       for(; ex1.More(); ex1.Next()) {
867         const TopoDS_Face& fac1 = TopoDS::Face(ex1.Current());
868         TopExp_Explorer ex2(thePbase, TopAbs_FACE);
869         for(; ex2.More(); ex2.Next()) {
870           const TopoDS_Face& fac2 = TopoDS::Face(ex2.Current());
871           if(fac1.IsSame(fac2)) break;
872         }
873         if (ex2.More()) break;
874       }
875       if (ex1.More()) continue;
876       GluedFaces = Standard_False;
877       break;
878     }
879     if (!GluedFaces) {
880 #ifdef OCCT_DEBUG
881       Standard_Boolean trc = BRepFeat_GettraceFEAT();
882       if (trc) cout << " Intersection Revol/skface : no gluing" << endl;
883 #endif
884       theMap.Clear();
885     }
886   }
887 }
888
889 //=======================================================================
890 //function : MajMap
891 //purpose  : management of descendants
892 //=======================================================================
893
894 static void MajMap(const TopoDS_Shape& theB,
895   const LocOpe_Revol& theP,
896   TopTools_DataMapOfShapeListOfShape& theMap, // myMap
897   TopoDS_Shape& theFShape,  // myFShape
898   TopoDS_Shape& theLShape) // myLShape
899 {
900   TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
901   if (exp.More()) {
902     theFShape = exp.Current();
903     TopTools_ListOfShape thelist;
904     theMap.Bind(theFShape, thelist);
905     for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
906       theMap(theFShape).Append(exp.Current());
907     }
908   }
909
910   exp.Init(theP.LastShape(),TopAbs_WIRE);
911   if (exp.More()) {
912     theLShape = exp.Current();
913     TopTools_ListOfShape thelist1;
914     theMap.Bind(theLShape, thelist1);
915     for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
916       theMap(theLShape).Append(exp.Current());
917     }
918   }
919
920   for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
921     if (!theMap.IsBound(exp.Current())) {
922       TopTools_ListOfShape thelist2;
923       theMap.Bind(exp.Current(), thelist2);
924       theMap(exp.Current()) = theP.Shapes(exp.Current());
925     }
926   }
927 }
928
929
930
931 //=======================================================================
932 //function : ToFuse
933 //purpose  : two faces samedomaine or not
934 //=======================================================================
935
936 Standard_Boolean ToFuse(const TopoDS_Face& F1,
937   const TopoDS_Face& F2)
938 {
939   if (F1.IsNull() || F2.IsNull()) {
940     return Standard_False;
941   }
942
943   Handle(Geom_Surface) S1,S2;
944   TopLoc_Location loc1, loc2;
945   Handle(Standard_Type) typS1,typS2;
946   const Standard_Real tollin = Precision::Confusion();
947   const Standard_Real tolang = Precision::Angular();
948
949   S1 = BRep_Tool::Surface(F1,loc1);
950   S2 = BRep_Tool::Surface(F2,loc2);
951
952   typS1 = S1->DynamicType();
953   typS2 = S2->DynamicType();
954
955   if (typS1 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
956     S1 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S1)->BasisSurface();
957     typS1 = S1->DynamicType();
958   }
959
960   if (typS2 == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
961     S2 =  Handle(Geom_RectangularTrimmedSurface)::DownCast (S2)->BasisSurface();
962     typS2 = S2->DynamicType();
963   }
964
965   if (typS1 != typS2) {
966     return Standard_False;
967   }
968
969
970   Standard_Boolean ValRet = Standard_False;
971   if (typS1 == STANDARD_TYPE(Geom_Plane)) {
972     S1 = BRep_Tool::Surface(F1);  // to apply the location.
973     S2 = BRep_Tool::Surface(F2);
974     gp_Pln pl1( Handle(Geom_Plane)::DownCast (S1)->Pln());
975     gp_Pln pl2( Handle(Geom_Plane)::DownCast (S2)->Pln());
976
977     if (pl1.Position().IsCoplanar(pl2.Position(),tollin,tolang)) {
978       ValRet = Standard_True;
979     }
980   }
981
982   return ValRet;
983 }
984
985
986
987
988
989
990
991
992