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