0026016: BRepPrimAPI_MakeRevol crash
[occt.git] / src / BRepSweep / BRepSweep_Rotation.cxx
1 // Created on: 1993-02-15
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1993-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 <BRepSweep_Rotation.ixx>
18 #include <BRepTools_Quilt.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepTools.hxx>
23 #include <TopoDS.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopExp.hxx>
27 #include <ElSLib.hxx>
28 #include <ElCLib.hxx>
29 #include <GeomAdaptor_Curve.hxx>
30 #include <GeomAdaptor_Surface.hxx>
31 #include <Adaptor3d_SurfaceOfRevolution.hxx>
32 #include <Geom_SurfaceOfRevolution.hxx>
33 #include <Geom_CylindricalSurface.hxx>
34 #include <Geom_ConicalSurface.hxx>
35 #include <Geom_SphericalSurface.hxx>
36 #include <Geom_ToroidalSurface.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_Circle.hxx>
39 #include <Geom_Line.hxx>
40 #include <Geom2d_Circle.hxx>
41 #include <Geom2d_Line.hxx>
42 #include <gp.hxx>
43 #include <gp_Trsf.hxx>
44 #include <gp_Circ2d.hxx>
45 #include <gp_Dir.hxx>
46 #include <gp_Dir2d.hxx>
47 #include <gp_Lin.hxx>
48 #include <gp_Lin2d.hxx>
49 #include <gp_Pnt.hxx>
50 #include <gp_Pnt2d.hxx>
51 #include <gp_Ax22d.hxx>
52 #include <gp_Cylinder.hxx>
53 #include <gp_Pln.hxx>
54 #include <gp_Cone.hxx>
55 #include <gp_Sphere.hxx>
56 #include <gp_Torus.hxx>
57 #include <gp_Ax3.hxx>
58 #include <Precision.hxx>
59 #include <Standard_ConstructionError.hxx>
60
61 #include <GeomAdaptor_HCurve.hxx>
62 #include <Geom_TrimmedCurve.hxx>
63
64 static Standard_Real ComputeTolerance(TopoDS_Edge& E,
65                                       const TopoDS_Face& F,
66                                       const Handle(Geom2d_Curve)& C)
67
68 {
69   if(BRep_Tool::Degenerated(E)) return BRep_Tool::Tolerance(E);
70
71   Standard_Real first,last;
72   
73   Handle(Geom_Surface) surf = BRep_Tool::Surface(F);
74   Handle(Geom_Curve)   c3d  = BRep_Tool::Curve(E,first,last);
75   
76   Standard_Real d2 = 0.;
77   Standard_Integer nn = 23;
78   Standard_Real unsurnn = 1./nn;
79   for(Standard_Integer i = 0; i <= nn; i++){
80     Standard_Real t = unsurnn*i;
81     Standard_Real u = first*(1.-t) + last*t;
82     gp_Pnt Pc3d  = c3d->Value(u);
83     gp_Pnt2d UV  = C->Value(u);
84     gp_Pnt Pcons = surf->Value(UV.X(),UV.Y());
85     if (Precision::IsInfinite(Pcons.X()) ||
86         Precision::IsInfinite(Pcons.Y()) ||
87         Precision::IsInfinite(Pcons.Z())) {
88       d2=Precision::Infinite();
89       break;
90     }
91     Standard_Real temp = Pc3d.SquareDistance(Pcons);
92     if(temp > d2) d2 = temp;
93   }
94   d2 = 1.5*sqrt(d2);
95   if(d2<1.e-7) d2 = 1.e-7;
96   return d2;
97 }
98
99 static void SetThePCurve(const BRep_Builder& B,
100                          TopoDS_Edge& E,
101                          const TopoDS_Face& F,
102                          const TopAbs_Orientation O,
103                          const Handle(Geom2d_Curve)& C)
104 {
105   // check if there is already a pcurve
106   Standard_Real f,l;
107   Handle(Geom2d_Curve) OC;
108   TopLoc_Location SL;
109   Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
110   if (GP.IsNull())
111     OC = BRep_Tool::CurveOnSurface(E,F,f,l);
112   if (OC.IsNull()) 
113     B.UpdateEdge(E,C,F,ComputeTolerance(E,F,C));
114   else {
115     if (O == TopAbs_REVERSED) 
116       B.UpdateEdge(E,OC,C,F,ComputeTolerance(E,F,C));
117     else 
118       B.UpdateEdge(E,C,OC,F,ComputeTolerance(E,F,C));
119   }
120 }
121
122 //=======================================================================
123 //function : BRepSweep_Rotation
124 //purpose  : 
125 //=======================================================================
126
127 BRepSweep_Rotation::BRepSweep_Rotation(const TopoDS_Shape& S, 
128                                        const Sweep_NumShape& N,
129                                        const TopLoc_Location& L,
130                                        const gp_Ax1& A,
131                                        const Standard_Real D,
132                                        const Standard_Boolean C):
133        BRepSweep_Trsf(BRep_Builder(),S,N,L,C),
134        myAng(D),
135        myAxe(A)
136      
137 {
138   Standard_ConstructionError_Raise_if(D < Precision::Angular(),
139                                       "BRepSweep_Rotation::Constructor");
140   Init();
141 }
142
143
144 //=======================================================================
145 //function : MakeEmptyVertex
146 //purpose  : 
147 //=======================================================================
148
149 TopoDS_Shape  BRepSweep_Rotation::MakeEmptyVertex
150   (const TopoDS_Shape& aGenV, 
151    const Sweep_NumShape& aDirV)
152 {
153   //call only in construction mode with copy.
154   Standard_ConstructionError_Raise_if
155     (!myCopy,"BRepSweep_Translation::MakeEmptyVertex");
156   gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aGenV));
157   TopoDS_Vertex V;
158   if (aDirV.Index()==2) P.Transform(myLocation.Transformation());
159   ////// modified by jgv, 1.10.01, for buc61005 //////
160   //myBuilder.Builder().MakeVertex(V,P,Precision::Confusion());
161   myBuilder.Builder().MakeVertex( V, P, BRep_Tool::Tolerance(TopoDS::Vertex(aGenV)) );
162   ////////////////////////////////////////////////////
163   if (aDirV.Index() == 1 && 
164       IsInvariant(aGenV) && 
165       myDirShapeTool.NbShapes() == 3) {
166     myBuiltShapes(myGenShapeTool.Index(aGenV),3) = Standard_True;
167     myShapes(myGenShapeTool.Index(aGenV),3) = V;
168   }    
169   return V;
170 }
171
172
173 //=======================================================================
174 //function : MakeEmptyDirectingEdge
175 //purpose  : 
176 //=======================================================================
177
178 TopoDS_Shape  BRepSweep_Rotation::MakeEmptyDirectingEdge
179   (const TopoDS_Shape& aGenV, 
180    const Sweep_NumShape&)
181 {
182   TopoDS_Edge E;
183   gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aGenV));
184   gp_Dir Dirz(myAxe.Direction());
185   gp_Vec V(Dirz);
186   gp_Pnt O(myAxe.Location());
187   O.Translate(V.Dot(gp_Vec(O,P)) * V);
188   if (O.IsEqual(P,Precision::Confusion())) {
189     // make a degenerated edge
190     // temporary make 3D curve null so that 
191     // parameters should be registered.
192     // myBuilder.Builder().MakeEdge(E);
193     gp_Ax2 Axis(O,Dirz);
194     Handle(Geom_Circle) GC = new Geom_Circle(Axis,0.);
195     myBuilder.Builder().
196       MakeEdge(E,GC,BRep_Tool::Tolerance(TopoDS::Vertex(aGenV)));
197     myBuilder.Builder().Degenerated(E,Standard_True);
198   }
199   else {
200     gp_Ax2 Axis(O,Dirz,gp_Dir(gp_Vec(O,P)));
201     Handle(Geom_Circle) GC = new Geom_Circle(Axis,O.Distance(P));
202     Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Vertex(aGenV));
203     myBuilder.Builder().MakeEdge(E, GC, tol);
204   }
205   return E;
206 }
207
208
209 //=======================================================================
210 //function : MakeEmptyGeneratingEdge
211 //purpose  : 
212 //=======================================================================
213
214 TopoDS_Shape  BRepSweep_Rotation::MakeEmptyGeneratingEdge
215   (const TopoDS_Shape& aGenE, 
216    const Sweep_NumShape& aDirV)
217 {
218   //call in case of construction with copy, or only when meridian touches myaxe.
219   Standard_Real First,Last;
220   TopLoc_Location Loc;
221   Handle(Geom_Curve) C = Handle(Geom_Curve)::DownCast
222     (BRep_Tool::Curve(TopoDS::Edge(aGenE),Loc,First,Last)->Copy());
223   C->Transform(Loc.Transformation());
224   TopoDS_Edge E;
225   if(aDirV.Index() == 2) C->Transform(myLocation.Transformation()); 
226   myBuilder.Builder().MakeEdge(E,C,BRep_Tool::Tolerance(TopoDS::Edge(aGenE)));
227   if (aDirV.Index() == 1 && 
228       IsInvariant(aGenE) && 
229       myDirShapeTool.NbShapes() == 3) {
230     myBuiltShapes(myGenShapeTool.Index(aGenE),3) = Standard_True;
231     myShapes(myGenShapeTool.Index(aGenE),3) = E;
232   }
233   return E;
234 }
235
236
237 //=======================================================================
238 //function : SetParameters
239 //purpose  : 
240 //=======================================================================
241
242 void  BRepSweep_Rotation::SetParameters
243   (const TopoDS_Shape& aNewFace, 
244    TopoDS_Shape& aNewVertex, 
245    const TopoDS_Shape& aGenF, 
246    const TopoDS_Shape& aGenV, 
247    const Sweep_NumShape&)
248 {
249   //Glue the parameter of vertices directly included in cap faces.
250   gp_Pnt2d pnt2d = BRep_Tool::Parameters(TopoDS::Vertex(aGenV),
251                                          TopoDS::Face(aGenF));
252   myBuilder.Builder().UpdateVertex
253     (TopoDS::Vertex(aNewVertex),pnt2d.X(),pnt2d.Y(),
254      TopoDS::Face(aNewFace),Precision::PConfusion());
255 }
256
257 //=======================================================================
258 //function : SetDirectingParameter
259 //purpose  : 
260 //=======================================================================
261
262 void  BRepSweep_Rotation::SetDirectingParameter
263   (const TopoDS_Shape& aNewEdge, 
264    TopoDS_Shape& aNewVertex, 
265    const TopoDS_Shape&, 
266    const Sweep_NumShape&, 
267    const Sweep_NumShape& aDirV)
268 {
269   Standard_Real param = 0;
270   TopAbs_Orientation ori = TopAbs_FORWARD;
271   if (aDirV.Index() == 2) {
272     param = myAng;
273     ori = TopAbs_REVERSED;
274   }
275   TopoDS_Vertex V_wnt = TopoDS::Vertex(aNewVertex);
276   V_wnt.Orientation(ori);
277   myBuilder.Builder().UpdateVertex(V_wnt,
278                                    param,TopoDS::Edge(aNewEdge),
279                                    Precision::PConfusion());
280 }
281
282
283 //=======================================================================
284 //function : SetGeneratingParameter
285 //purpose  : 
286 //=======================================================================
287
288 void  BRepSweep_Rotation::SetGeneratingParameter
289   (const TopoDS_Shape& aNewEdge, 
290    TopoDS_Shape& aNewVertex, 
291    const TopoDS_Shape& aGenE, 
292    const TopoDS_Shape& aGenV, 
293    const Sweep_NumShape&)
294 {
295   TopoDS_Vertex vbid = TopoDS::Vertex(aNewVertex); 
296   vbid.Orientation(aGenV.Orientation());
297   myBuilder.Builder().UpdateVertex
298     (vbid,
299      BRep_Tool::Parameter(TopoDS::Vertex(aGenV),TopoDS::Edge(aGenE)),
300      TopoDS::Edge(aNewEdge),Precision::PConfusion());
301 }
302
303
304 //=======================================================================
305 //function : MakeEmptyFace
306 //purpose  : 
307 //=======================================================================
308
309 TopoDS_Shape  BRepSweep_Rotation::MakeEmptyFace
310   (const TopoDS_Shape& aGenS, 
311    const Sweep_NumShape& aDirS)
312 {
313   Standard_Real toler;
314   TopoDS_Face F;
315   Handle(Geom_Surface) S;
316   if(aGenS.ShapeType()==TopAbs_EDGE){
317     TopLoc_Location L;
318     Standard_Real First,Last;
319     Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(aGenS),L,First,Last);
320     toler = BRep_Tool::Tolerance(TopoDS::Edge(aGenS));
321     gp_Trsf Tr = L.Transformation();
322     C = Handle(Geom_Curve)::DownCast(C->Copy());
323     //// modified by jgv, 9.12.03 ////
324     C = new Geom_TrimmedCurve( C, First, Last );
325     //////////////////////////////////
326     C->Transform(Tr);
327
328     Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
329     HC->ChangeCurve().Load(C,First,Last);
330     Adaptor3d_SurfaceOfRevolution AS(HC,myAxe);
331     switch(AS.GetType()){
332     case GeomAbs_Plane :
333       {
334         Handle(Geom_Plane) Pl = new Geom_Plane(AS.Plane());
335         S = Pl;
336       }
337       break;
338     case GeomAbs_Cylinder :
339       {
340         Handle(Geom_CylindricalSurface) Cy = 
341           new Geom_CylindricalSurface(AS.Cylinder());
342         S = Cy;
343       }
344       break;
345     case GeomAbs_Sphere :
346       {
347         Handle(Geom_SphericalSurface) Sp = 
348           new Geom_SphericalSurface(AS.Sphere());
349         S = Sp;
350       }
351       break;
352     case GeomAbs_Cone :
353       {
354         Handle(Geom_ConicalSurface) Co = 
355           new Geom_ConicalSurface(AS.Cone());
356         S = Co;
357       }
358       break;
359     case GeomAbs_Torus :
360       {
361         Handle(Geom_ToroidalSurface) To = 
362           new Geom_ToroidalSurface(AS.Torus());
363         S = To;
364       }
365       break;
366     default :
367       {
368         Handle(Geom_SurfaceOfRevolution) Se = 
369           new Geom_SurfaceOfRevolution(C,myAxe);
370         S = Se;
371       }
372       break;
373     }
374   }
375   else{
376     TopLoc_Location L;
377     S = BRep_Tool::Surface(TopoDS::Face(aGenS),L);
378     toler = BRep_Tool::Tolerance(TopoDS::Face(aGenS));
379     gp_Trsf Tr = L.Transformation();
380     S = Handle(Geom_Surface)::DownCast(S->Copy());
381     S->Transform(Tr);
382     if (aDirS.Index()==2) S->Transform(myLocation.Transformation());
383   }
384   myBuilder.Builder().MakeFace(F,S,toler);
385   return F;
386 }
387
388
389 //=======================================================================
390 //function : SetPCurve
391 //purpose  : 
392 //=======================================================================
393
394 void  BRepSweep_Rotation::SetPCurve
395   (const TopoDS_Shape& aNewFace, 
396    TopoDS_Shape& aNewEdge, 
397    const TopoDS_Shape& aGenF, 
398    const TopoDS_Shape& aGenE, 
399    const Sweep_NumShape&,
400    const TopAbs_Orientation orien)
401 {
402   //Set on edges of cap faces the same pcurves as 
403   //on edges of the generator face.
404   Standard_Real First,Last;
405   SetThePCurve(myBuilder.Builder(),
406                TopoDS::Edge(aNewEdge),
407                TopoDS::Face(aNewFace),
408                orien,
409                BRep_Tool::CurveOnSurface
410                (TopoDS::Edge(aGenE),TopoDS::Face(aGenF),First,Last));
411 }
412
413
414 //=======================================================================
415 //function : SetGeneratingPCurve
416 //purpose  : 
417 //=======================================================================
418
419 void  BRepSweep_Rotation::SetGeneratingPCurve
420   (const TopoDS_Shape& aNewFace, 
421    TopoDS_Shape& aNewEdge, 
422    const TopoDS_Shape&, 
423    const Sweep_NumShape&, 
424    const Sweep_NumShape& aDirV,
425    const TopAbs_Orientation orien)
426 {
427   TopLoc_Location Loc;
428   GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewFace),Loc));
429   Standard_Real First,Last;
430   Standard_Real u,v;
431   gp_Pnt point;
432   gp_Pnt2d pnt2d;
433   gp_Dir2d dir2d;
434   gp_Lin2d L;
435   if (AS.GetType()==GeomAbs_Plane){
436     gp_Pln pln = AS.Plane();
437     gp_Ax3 ax3 = pln.Position();
438     Handle(Geom_Curve) aC = BRep_Tool::Curve(TopoDS::Edge(aNewEdge),Loc,First,Last);
439     Handle(Geom_Line) GL = Handle(Geom_Line)::DownCast(aC);
440     if (GL.IsNull()) {
441       Handle(Geom_TrimmedCurve) aTrimmedCurve = Handle(Geom_TrimmedCurve)::DownCast(aC);
442       if (!aTrimmedCurve.IsNull()) {
443         GL = Handle(Geom_Line)::DownCast(aTrimmedCurve->BasisCurve());
444         if (GL.IsNull()) {
445             Standard_ConstructionError::Raise("BRepSweep_Rotation::SetGeneratingPCurve");
446         }
447       }
448     }
449     gp_Lin gl = GL->Lin();
450     gl.Transform(Loc.Transformation());
451     point = gl.Location();
452     gp_Dir dir = gl.Direction();
453     ElSLib::PlaneParameters(ax3,point,u,v);
454     pnt2d.SetCoord(u,v);
455     dir2d.SetCoord(dir.Dot(ax3.XDirection()),dir.Dot(ax3.YDirection()));
456     L.SetLocation(pnt2d);
457     L.SetDirection(dir2d);
458   }
459   else if (AS.GetType()==GeomAbs_Torus){
460     gp_Torus tor = AS.Torus();
461     BRepAdaptor_Curve BC(TopoDS::Edge(aNewEdge));
462     Standard_Real U = BC.FirstParameter();
463     point = BC.Value(U);
464     if (point.Distance(tor.Location()) < Precision::Confusion()) {
465       v = M_PI;
466 //  modified by NIZHNY-EAP Wed Mar  1 17:49:29 2000 ___BEGIN___
467       u = 0.;
468     }
469     else {
470       ElSLib::TorusParameters(tor.Position(),tor.MajorRadius(),
471                               tor.MinorRadius(),point,u,v);
472     }
473 //    u = 0.;
474     v = ElCLib::InPeriod(v,0.,2*M_PI);
475     if((2*M_PI - v) <= Precision::PConfusion()) v -= 2*M_PI;
476     if (aDirV.Index() == 2) {
477       Standard_Real uLeft = u-myAng;
478       ElCLib::AdjustPeriodic(-M_PI,M_PI,Precision::PConfusion(),uLeft,u);
479     }
480     else {
481       Standard_Real uRight = u+myAng;
482       ElCLib::AdjustPeriodic(-M_PI,M_PI,Precision::PConfusion(),u,uRight);
483     }
484 //  modified by NIZHNY-EAP Wed Mar  1 17:49:32 2000 ___END___
485     pnt2d.SetCoord(u,v-U);
486     L.SetLocation(pnt2d);
487     L.SetDirection(gp::DY2d());
488   }
489   else if (AS.GetType()==GeomAbs_Sphere){
490     gp_Sphere sph = AS.Sphere();
491     BRepAdaptor_Curve BC(TopoDS::Edge(aNewEdge));
492     Standard_Real U = BC.FirstParameter();
493     point = BC.Value(U);
494     ElSLib::SphereParameters(sph.Position(),sph.Radius(),point,u,v);
495     u = 0.;
496     if (aDirV.Index() == 2) u = myAng;
497     pnt2d.SetCoord(u,v-U);
498     L.SetLocation(pnt2d);
499     L.SetDirection(gp::DY2d());
500   }
501   else{
502     Standard_Real u = 0;
503     if (aDirV.Index() == 2) u = myAng;
504     L.SetLocation(gp_Pnt2d(u,0));
505     L.SetDirection(gp::DY2d());
506   }
507   Handle(Geom2d_Line) GL = new Geom2d_Line(L);
508   SetThePCurve(myBuilder.Builder(),
509                TopoDS::Edge(aNewEdge),
510                TopoDS::Face(aNewFace),
511                orien,
512                GL);
513 }
514
515
516 //=======================================================================
517 //function : SetDirectingPCurve
518 //purpose  : 
519 //=======================================================================
520
521 void  BRepSweep_Rotation::SetDirectingPCurve
522   (const TopoDS_Shape& aNewFace, 
523    TopoDS_Shape& aNewEdge, 
524    const TopoDS_Shape& aGenE, 
525    const TopoDS_Shape& aGenV, 
526    const Sweep_NumShape&,
527    const TopAbs_Orientation orien)
528 {
529   TopLoc_Location Loc;
530   GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewFace),Loc));
531   Standard_Real 
532     par = BRep_Tool::Parameter(TopoDS::Vertex(aGenV),TopoDS::Edge(aGenE));
533   gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(aGenV));
534   gp_Pnt2d p22d;
535   Standard_Real u,v;
536   Handle(Geom2d_Curve) thePCurve;
537
538   switch(AS.GetType()){
539
540   case GeomAbs_Plane : 
541     {
542       gp_Pln pln = AS.Plane();
543       gp_Ax3 ax3 = pln.Position();
544       gp_Pnt p1 = pln.Location();
545       Standard_Real R = p1.Distance(p2);
546       ElSLib::PlaneParameters(ax3,p2,u,v);
547       gp_Dir2d dx2d(u,v);
548       gp_Ax22d axe(gp::Origin2d(),dx2d,gp::DY2d());
549       gp_Circ2d C(axe,R);
550       Handle(Geom2d_Circle) GC = new Geom2d_Circle(C);
551       thePCurve = GC;
552     }
553     break;
554
555   case GeomAbs_Cone : 
556     {
557       gp_Cone cone = AS.Cone();
558       ElSLib::ConeParameters(cone.Position(),cone.RefRadius(),
559                              cone.SemiAngle(),p2,u,v);
560       p22d.SetCoord(0.,v);
561       gp_Lin2d L(p22d,gp::DX2d());
562       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
563       thePCurve = GL;
564     }
565     break;
566
567   case GeomAbs_Sphere : 
568     {
569       gp_Sphere sph = AS.Sphere();
570       ElSLib::SphereParameters(sph.Position(),sph.Radius(),p2,u,v);
571       p22d.SetCoord(0.,v);
572       gp_Lin2d L(p22d,gp::DX2d());
573       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
574       thePCurve = GL;
575     }
576     break;
577
578   case GeomAbs_Torus : 
579     {
580       gp_Pnt p1;
581       Standard_Real u1,u2,v1,v2;
582       gp_Torus tor = AS.Torus();
583       BRepAdaptor_Curve BC(TopoDS::Edge(aGenE));
584       p1 = BC.Value(BC.FirstParameter());
585       if (p1.Distance(tor.Location()) < Precision::Confusion()){
586         v1 = M_PI;
587 //  modified by NIZHNY-EAP Thu Mar  2 09:43:26 2000 ___BEGIN___
588         u1 = 0.;
589 //  modified by NIZHNY-EAP Thu Mar  2 15:28:59 2000 ___END___
590       }
591       else {
592         ElSLib::TorusParameters(tor.Position(),tor.MajorRadius(),
593                                 tor.MinorRadius(),p1,u1,v1);
594       }
595       p2 = BC.Value(BC.LastParameter());
596       if (p2.Distance(tor.Location()) < Precision::Confusion()){
597         v2 = M_PI;
598       }
599       else {
600         ElSLib::TorusParameters(tor.Position(),tor.MajorRadius(),
601                                 tor.MinorRadius(),p2,u2,v2);
602       }
603       ElCLib::AdjustPeriodic(0.,2*M_PI,Precision::PConfusion(),v1,v2);
604 //  modified by NIZHNY-EAP Thu Mar  2 15:29:04 2000 ___BEGIN___
605       u2 = u1 + myAng;
606       ElCLib::AdjustPeriodic(-M_PI,M_PI,Precision::PConfusion(),u1,u2);
607       if (aGenV.Orientation()==TopAbs_FORWARD){
608         p22d.SetCoord(u1,v1);
609       }
610       else {
611         p22d.SetCoord(u1,v2);
612 //  modified by NIZHNY-EAP Thu Mar  2 09:43:32 2000 ___END___
613       }
614       gp_Lin2d L(p22d,gp::DX2d());
615       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
616       thePCurve = GL;
617     }
618     break;
619
620   default :
621     {
622       p22d.SetCoord(0.,par);
623       gp_Lin2d L(p22d,gp::DX2d());
624       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
625       thePCurve = GL;
626     }
627     break;
628   }
629   SetThePCurve(myBuilder.Builder(),
630                TopoDS::Edge(aNewEdge),
631                TopoDS::Face(aNewFace),
632                orien,
633                thePCurve);
634 }
635
636 //modified by NIZNHY-PKV Tue Jun 14 08:33:55 2011f
637 //=======================================================================
638 //function : DirectSolid
639 //purpose  : 
640 //=======================================================================
641 TopAbs_Orientation 
642   BRepSweep_Rotation::DirectSolid (const TopoDS_Shape& aGenS,
643                                    const Sweep_NumShape&)
644 {  // compare the face normal and the direction
645   Standard_Real aU1, aU2, aV1, aV2, aUx, aVx, aX, aMV2, aTol2, aTx;
646   TopAbs_Orientation aOr;
647   gp_Pnt aP;
648   gp_Vec du,dv;
649   BRepAdaptor_Surface surf(TopoDS::Face(aGenS));
650   //
651   aTol2=Precision::Confusion();
652   aTol2=aTol2*aTol2;
653   //
654   const gp_Pnt& aPAxeLoc=myAxe.Location();
655   const gp_Dir& aPAxeDir=myAxe.Direction();
656   //
657   aU1=surf.FirstUParameter();
658   aU2=surf.LastUParameter();
659   aV1=surf.FirstVParameter();
660   aV2=surf.LastVParameter();
661   //
662   aTx=0.5;
663   aUx=aTx*(aU1+aU2);
664   aVx=aTx*(aV1+aV2);
665   surf.D1(aUx, aVx, aP, du, dv);
666   //
667   gp_Vec aV(aPAxeLoc, aP);
668   aV.Cross(aPAxeDir);
669   aMV2=aV.SquareMagnitude();
670   if (aMV2<aTol2) {
671     aTx=0.43213918;
672     aUx=aU1*(1.-aTx)+aU2*aTx;
673     aVx=aV1*(1.-aTx)+aV2*aTx;
674     surf.D1(aUx, aVx, aP, du, dv);
675     aV.SetXYZ(aP.XYZ()-aPAxeLoc.XYZ());
676     aV.Cross(aPAxeDir);
677   }
678   //
679   aX = aV.DotCross(du, dv);
680   aOr = (aX > 0.) ? TopAbs_FORWARD : TopAbs_REVERSED;
681   return aOr;
682 }
683 /*
684 //=======================================================================
685 //function : DirectSolid
686 //purpose  : 
687 //=======================================================================
688 TopAbs_Orientation 
689   BRepSweep_Rotation::DirectSolid (const TopoDS_Shape& aGenS,
690                                    const Sweep_NumShape&)
691 {
692   // compare the face normal and the direction
693   BRepAdaptor_Surface surf(TopoDS::Face(aGenS));
694   gp_Pnt P;
695   gp_Vec du,dv;
696   surf.D1((surf.FirstUParameter() + surf.LastUParameter()) / 2.,
697           (surf.FirstVParameter() + surf.LastVParameter()) / 2.,
698           P,du,dv);
699     
700   gp_Vec V(myAxe.Location(),P);
701   V.Cross(myAxe.Direction());
702   Standard_Real x = V.DotCross(du,dv);
703   TopAbs_Orientation orient = (x > 0) ? TopAbs_FORWARD : TopAbs_REVERSED;
704   return orient;
705 }
706 */
707 //modified by NIZNHY-PKV Tue Jun 14 08:33:59 2011t
708
709 //=======================================================================
710 //function : GGDShapeIsToAdd
711 //purpose  : 
712 //=======================================================================
713
714 Standard_Boolean BRepSweep_Rotation::GGDShapeIsToAdd
715   (const TopoDS_Shape& aNewShape,
716    const TopoDS_Shape& aNewSubShape,
717    const TopoDS_Shape& aGenS,
718    const TopoDS_Shape& aSubGenS,
719    const Sweep_NumShape& aDirS )const
720 {
721   if (aNewShape.ShapeType()==TopAbs_FACE &&
722       aNewSubShape.ShapeType()==TopAbs_EDGE &&
723       aGenS.ShapeType()==TopAbs_EDGE &&
724       aSubGenS.ShapeType()==TopAbs_VERTEX &&
725       aDirS.Type()==TopAbs_EDGE){
726     TopLoc_Location Loc;
727     GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewShape),Loc));
728     if (AS.GetType()==GeomAbs_Plane){
729       return (!IsInvariant(aSubGenS));
730     }
731     else{
732       return Standard_True;
733     }
734   }
735   else{
736     return Standard_True;
737   }
738 }
739
740
741 //=======================================================================
742 //function : GDDShapeIsToAdd
743 //purpose  : 
744 //=======================================================================
745
746 Standard_Boolean BRepSweep_Rotation::GDDShapeIsToAdd
747   (const TopoDS_Shape& aNewShape,
748    const TopoDS_Shape& aNewSubShape,
749    const TopoDS_Shape& aGenS,
750    const Sweep_NumShape& aDirS,
751    const Sweep_NumShape& aSubDirS )const
752 {
753   if ( aNewShape.ShapeType() == TopAbs_SOLID &&
754        aNewSubShape.ShapeType() == TopAbs_FACE &&
755        aGenS.ShapeType() == TopAbs_FACE &&
756        aDirS.Type() == TopAbs_EDGE &&
757        aSubDirS.Type() == TopAbs_VERTEX ){
758     return ( Abs(myAng - 2 * M_PI) > Precision::Angular() );
759   }
760   else if ( aNewShape.ShapeType() == TopAbs_FACE &&
761        aNewSubShape.ShapeType() == TopAbs_EDGE &&
762        aGenS.ShapeType() == TopAbs_EDGE &&
763        aDirS.Type() == TopAbs_EDGE &&
764        aSubDirS.Type() == TopAbs_VERTEX ){
765     TopLoc_Location Loc;
766     GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewShape),Loc));
767     if (AS.GetType()==GeomAbs_Plane){
768       return ( Abs(myAng - 2 * M_PI) > Precision::Angular() );
769     }
770     else {
771       return Standard_True;
772     }
773   }
774   else {
775     return Standard_True;
776   }
777 }
778
779
780 //=======================================================================
781 //function : SeparatedWires
782 //purpose  : 
783 //=======================================================================
784
785 Standard_Boolean BRepSweep_Rotation::SeparatedWires
786   (const TopoDS_Shape& aNewShape,
787    const TopoDS_Shape& aNewSubShape,
788    const TopoDS_Shape& aGenS,
789    const TopoDS_Shape& aSubGenS,
790    const Sweep_NumShape& aDirS )const
791 {
792   if (aNewShape.ShapeType()==TopAbs_FACE &&
793       aNewSubShape.ShapeType()==TopAbs_EDGE &&
794       aGenS.ShapeType()==TopAbs_EDGE &&
795       aSubGenS.ShapeType()==TopAbs_VERTEX &&
796       aDirS.Type()==TopAbs_EDGE){
797     TopLoc_Location Loc;
798     GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewShape),Loc));
799     if (AS.GetType()==GeomAbs_Plane){
800       return (Abs(myAng-2*M_PI) <= Precision::Angular());
801     }
802     else{
803       return Standard_False;
804     }
805   }
806   else{
807     return Standard_False;
808   }
809 }
810
811 //=======================================================================
812 //function : SplitShell
813 //purpose  : 
814 //=======================================================================
815
816 TopoDS_Shape BRepSweep_Rotation::SplitShell(const TopoDS_Shape& aNewShape)const
817 {
818   BRepTools_Quilt Q;
819   Q.Add(aNewShape);
820   return Q.Shells();
821 }
822
823 //=======================================================================
824 //function : HasShape
825 //purpose  : 
826 //=======================================================================
827
828 Standard_Boolean  BRepSweep_Rotation::HasShape
829   (const TopoDS_Shape& aGenS, 
830    const Sweep_NumShape& aDirS)const 
831 {
832   if(aDirS.Type()==TopAbs_EDGE&&
833      aGenS.ShapeType()==TopAbs_EDGE){
834     // Verify that the edge has entrails
835     const TopoDS_Edge& anEdge = TopoDS::Edge(aGenS);
836     Standard_Boolean hasGeom = !BRep_Tool::Degenerated(anEdge);
837     if (hasGeom)
838     { // The edge is not degenerated. Check if it has no curve
839       Standard_Real aPFirst, aPLast;
840       TopLoc_Location aLoc;
841       Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aLoc, aPFirst, aPLast);
842       hasGeom = !aCurve.IsNull();
843     }
844     return hasGeom && !IsInvariant(aGenS);
845   }
846   else{
847     return Standard_True;
848   }
849 }
850
851
852 //=======================================================================
853 //function : IsInvariant
854 //purpose  : 
855 //=======================================================================
856
857 Standard_Boolean  BRepSweep_Rotation::IsInvariant 
858   (const TopoDS_Shape& aGenS)const
859 {
860   if(aGenS.ShapeType()==TopAbs_EDGE){
861     TopLoc_Location Loc;
862     Standard_Real First,Last;
863     Handle(Geom_Curve) 
864       C = BRep_Tool::Curve(TopoDS::Edge(aGenS),Loc,First,Last);
865     if (C.IsNull() || C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
866       TopoDS_Vertex V1, V2;
867       TopExp::Vertices(TopoDS::Edge(aGenS), V1, V2);
868       return ( IsInvariant(V1) && IsInvariant(V2));
869     }
870     else{
871       return Standard_False;
872     }
873   }
874   else if(aGenS.ShapeType()==TopAbs_VERTEX){
875     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aGenS));
876     gp_Lin Lin (myAxe.Location(), myAxe.Direction());
877     return ( Lin.Distance(P) <= BRep_Tool::Tolerance(TopoDS::Vertex(aGenS))); 
878   }
879   else
880     return Standard_False;
881 }
882
883 //=======================================================================
884 //function : Angle
885 //purpose  : 
886 //=======================================================================
887
888 Standard_Real BRepSweep_Rotation::Angle()const 
889 {
890   return myAng;
891 }
892
893 //=======================================================================
894 //function : Axe
895 //purpose  : 
896 //=======================================================================
897
898 gp_Ax1 BRepSweep_Rotation::Axe()const 
899 {
900   return myAxe;
901 }
902