0025656: Specification of semantic of Closed flag of an edge
[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_Line) GL = Handle(Geom_Line)::DownCast
439       (BRep_Tool::Curve(TopoDS::Edge(aNewEdge),Loc,First,Last));
440     gp_Lin gl = GL->Lin();
441     gl.Transform(Loc.Transformation());
442     point = gl.Location();
443     gp_Dir dir = gl.Direction();
444     ElSLib::PlaneParameters(ax3,point,u,v);
445     pnt2d.SetCoord(u,v);
446     dir2d.SetCoord(dir.Dot(ax3.XDirection()),dir.Dot(ax3.YDirection()));
447     L.SetLocation(pnt2d);
448     L.SetDirection(dir2d);
449   }
450   else if (AS.GetType()==GeomAbs_Torus){
451     gp_Torus tor = AS.Torus();
452     BRepAdaptor_Curve BC(TopoDS::Edge(aNewEdge));
453     Standard_Real U = BC.FirstParameter();
454     point = BC.Value(U);
455     if (point.Distance(tor.Location()) < Precision::Confusion()) {
456       v = M_PI;
457 //  modified by NIZHNY-EAP Wed Mar  1 17:49:29 2000 ___BEGIN___
458       u = 0.;
459     }
460     else {
461       ElSLib::TorusParameters(tor.Position(),tor.MajorRadius(),
462                               tor.MinorRadius(),point,u,v);
463     }
464 //    u = 0.;
465     v = ElCLib::InPeriod(v,0.,2*M_PI);
466     if((2*M_PI - v) <= Precision::PConfusion()) v -= 2*M_PI;
467     if (aDirV.Index() == 2) {
468       Standard_Real uLeft = u-myAng;
469       ElCLib::AdjustPeriodic(-M_PI,M_PI,Precision::PConfusion(),uLeft,u);
470     }
471     else {
472       Standard_Real uRight = u+myAng;
473       ElCLib::AdjustPeriodic(-M_PI,M_PI,Precision::PConfusion(),u,uRight);
474     }
475 //  modified by NIZHNY-EAP Wed Mar  1 17:49:32 2000 ___END___
476     pnt2d.SetCoord(u,v-U);
477     L.SetLocation(pnt2d);
478     L.SetDirection(gp::DY2d());
479   }
480   else if (AS.GetType()==GeomAbs_Sphere){
481     gp_Sphere sph = AS.Sphere();
482     BRepAdaptor_Curve BC(TopoDS::Edge(aNewEdge));
483     Standard_Real U = BC.FirstParameter();
484     point = BC.Value(U);
485     ElSLib::SphereParameters(sph.Position(),sph.Radius(),point,u,v);
486     u = 0.;
487     if (aDirV.Index() == 2) u = myAng;
488     pnt2d.SetCoord(u,v-U);
489     L.SetLocation(pnt2d);
490     L.SetDirection(gp::DY2d());
491   }
492   else{
493     Standard_Real u = 0;
494     if (aDirV.Index() == 2) u = myAng;
495     L.SetLocation(gp_Pnt2d(u,0));
496     L.SetDirection(gp::DY2d());
497   }
498   Handle(Geom2d_Line) GL = new Geom2d_Line(L);
499   SetThePCurve(myBuilder.Builder(),
500                TopoDS::Edge(aNewEdge),
501                TopoDS::Face(aNewFace),
502                orien,
503                GL);
504 }
505
506
507 //=======================================================================
508 //function : SetDirectingPCurve
509 //purpose  : 
510 //=======================================================================
511
512 void  BRepSweep_Rotation::SetDirectingPCurve
513   (const TopoDS_Shape& aNewFace, 
514    TopoDS_Shape& aNewEdge, 
515    const TopoDS_Shape& aGenE, 
516    const TopoDS_Shape& aGenV, 
517    const Sweep_NumShape&,
518    const TopAbs_Orientation orien)
519 {
520   TopLoc_Location Loc;
521   GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewFace),Loc));
522   Standard_Real 
523     par = BRep_Tool::Parameter(TopoDS::Vertex(aGenV),TopoDS::Edge(aGenE));
524   gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(aGenV));
525   gp_Pnt2d p22d;
526   Standard_Real u,v;
527   Handle(Geom2d_Curve) thePCurve;
528
529   switch(AS.GetType()){
530
531   case GeomAbs_Plane : 
532     {
533       gp_Pln pln = AS.Plane();
534       gp_Ax3 ax3 = pln.Position();
535       gp_Pnt p1 = pln.Location();
536       Standard_Real R = p1.Distance(p2);
537       ElSLib::PlaneParameters(ax3,p2,u,v);
538       gp_Dir2d dx2d(u,v);
539       gp_Ax22d axe(gp::Origin2d(),dx2d,gp::DY2d());
540       gp_Circ2d C(axe,R);
541       Handle(Geom2d_Circle) GC = new Geom2d_Circle(C);
542       thePCurve = GC;
543     }
544     break;
545
546   case GeomAbs_Cone : 
547     {
548       gp_Cone cone = AS.Cone();
549       ElSLib::ConeParameters(cone.Position(),cone.RefRadius(),
550                              cone.SemiAngle(),p2,u,v);
551       p22d.SetCoord(0.,v);
552       gp_Lin2d L(p22d,gp::DX2d());
553       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
554       thePCurve = GL;
555     }
556     break;
557
558   case GeomAbs_Sphere : 
559     {
560       gp_Sphere sph = AS.Sphere();
561       ElSLib::SphereParameters(sph.Position(),sph.Radius(),p2,u,v);
562       p22d.SetCoord(0.,v);
563       gp_Lin2d L(p22d,gp::DX2d());
564       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
565       thePCurve = GL;
566     }
567     break;
568
569   case GeomAbs_Torus : 
570     {
571       gp_Pnt p1;
572       Standard_Real u1,u2,v1,v2;
573       gp_Torus tor = AS.Torus();
574       BRepAdaptor_Curve BC(TopoDS::Edge(aGenE));
575       p1 = BC.Value(BC.FirstParameter());
576       if (p1.Distance(tor.Location()) < Precision::Confusion()){
577         v1 = M_PI;
578 //  modified by NIZHNY-EAP Thu Mar  2 09:43:26 2000 ___BEGIN___
579         u1 = 0.;
580 //  modified by NIZHNY-EAP Thu Mar  2 15:28:59 2000 ___END___
581       }
582       else {
583         ElSLib::TorusParameters(tor.Position(),tor.MajorRadius(),
584                                 tor.MinorRadius(),p1,u1,v1);
585       }
586       p2 = BC.Value(BC.LastParameter());
587       if (p2.Distance(tor.Location()) < Precision::Confusion()){
588         v2 = M_PI;
589       }
590       else {
591         ElSLib::TorusParameters(tor.Position(),tor.MajorRadius(),
592                                 tor.MinorRadius(),p2,u2,v2);
593       }
594       ElCLib::AdjustPeriodic(0.,2*M_PI,Precision::PConfusion(),v1,v2);
595 //  modified by NIZHNY-EAP Thu Mar  2 15:29:04 2000 ___BEGIN___
596       u2 = u1 + myAng;
597       ElCLib::AdjustPeriodic(-M_PI,M_PI,Precision::PConfusion(),u1,u2);
598       if (aGenV.Orientation()==TopAbs_FORWARD){
599         p22d.SetCoord(u1,v1);
600       }
601       else {
602         p22d.SetCoord(u1,v2);
603 //  modified by NIZHNY-EAP Thu Mar  2 09:43:32 2000 ___END___
604       }
605       gp_Lin2d L(p22d,gp::DX2d());
606       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
607       thePCurve = GL;
608     }
609     break;
610
611   default :
612     {
613       p22d.SetCoord(0.,par);
614       gp_Lin2d L(p22d,gp::DX2d());
615       Handle(Geom2d_Line) GL = new Geom2d_Line(L);
616       thePCurve = GL;
617     }
618     break;
619   }
620   SetThePCurve(myBuilder.Builder(),
621                TopoDS::Edge(aNewEdge),
622                TopoDS::Face(aNewFace),
623                orien,
624                thePCurve);
625 }
626
627 //modified by NIZNHY-PKV Tue Jun 14 08:33:55 2011f
628 //=======================================================================
629 //function : DirectSolid
630 //purpose  : 
631 //=======================================================================
632 TopAbs_Orientation 
633   BRepSweep_Rotation::DirectSolid (const TopoDS_Shape& aGenS,
634                                    const Sweep_NumShape&)
635 {  // compare the face normal and the direction
636   Standard_Real aU1, aU2, aV1, aV2, aUx, aVx, aX, aMV2, aTol2, aTx;
637   TopAbs_Orientation aOr;
638   gp_Pnt aP;
639   gp_Vec du,dv;
640   BRepAdaptor_Surface surf(TopoDS::Face(aGenS));
641   //
642   aTol2=Precision::Confusion();
643   aTol2=aTol2*aTol2;
644   //
645   const gp_Pnt& aPAxeLoc=myAxe.Location();
646   const gp_Dir& aPAxeDir=myAxe.Direction();
647   //
648   aU1=surf.FirstUParameter();
649   aU2=surf.LastUParameter();
650   aV1=surf.FirstVParameter();
651   aV2=surf.LastVParameter();
652   //
653   aTx=0.5;
654   aUx=aTx*(aU1+aU2);
655   aVx=aTx*(aV1+aV2);
656   surf.D1(aUx, aVx, aP, du, dv);
657   //
658   gp_Vec aV(aPAxeLoc, aP);
659   aV.Cross(aPAxeDir);
660   aMV2=aV.SquareMagnitude();
661   if (aMV2<aTol2) {
662     aTx=0.43213918;
663     aUx=aU1*(1.-aTx)+aU2*aTx;
664     aVx=aV1*(1.-aTx)+aV2*aTx;
665     surf.D1(aUx, aVx, aP, du, dv);
666     aV.SetXYZ(aP.XYZ()-aPAxeLoc.XYZ());
667     aV.Cross(aPAxeDir);
668   }
669   //
670   aX = aV.DotCross(du, dv);
671   aOr = (aX > 0.) ? TopAbs_FORWARD : TopAbs_REVERSED;
672   return aOr;
673 }
674 /*
675 //=======================================================================
676 //function : DirectSolid
677 //purpose  : 
678 //=======================================================================
679 TopAbs_Orientation 
680   BRepSweep_Rotation::DirectSolid (const TopoDS_Shape& aGenS,
681                                    const Sweep_NumShape&)
682 {
683   // compare the face normal and the direction
684   BRepAdaptor_Surface surf(TopoDS::Face(aGenS));
685   gp_Pnt P;
686   gp_Vec du,dv;
687   surf.D1((surf.FirstUParameter() + surf.LastUParameter()) / 2.,
688           (surf.FirstVParameter() + surf.LastVParameter()) / 2.,
689           P,du,dv);
690     
691   gp_Vec V(myAxe.Location(),P);
692   V.Cross(myAxe.Direction());
693   Standard_Real x = V.DotCross(du,dv);
694   TopAbs_Orientation orient = (x > 0) ? TopAbs_FORWARD : TopAbs_REVERSED;
695   return orient;
696 }
697 */
698 //modified by NIZNHY-PKV Tue Jun 14 08:33:59 2011t
699
700 //=======================================================================
701 //function : GGDShapeIsToAdd
702 //purpose  : 
703 //=======================================================================
704
705 Standard_Boolean BRepSweep_Rotation::GGDShapeIsToAdd
706   (const TopoDS_Shape& aNewShape,
707    const TopoDS_Shape& aNewSubShape,
708    const TopoDS_Shape& aGenS,
709    const TopoDS_Shape& aSubGenS,
710    const Sweep_NumShape& aDirS )const
711 {
712   if (aNewShape.ShapeType()==TopAbs_FACE &&
713       aNewSubShape.ShapeType()==TopAbs_EDGE &&
714       aGenS.ShapeType()==TopAbs_EDGE &&
715       aSubGenS.ShapeType()==TopAbs_VERTEX &&
716       aDirS.Type()==TopAbs_EDGE){
717     TopLoc_Location Loc;
718     GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewShape),Loc));
719     if (AS.GetType()==GeomAbs_Plane){
720       return (!IsInvariant(aSubGenS));
721     }
722     else{
723       return Standard_True;
724     }
725   }
726   else{
727     return Standard_True;
728   }
729 }
730
731
732 //=======================================================================
733 //function : GDDShapeIsToAdd
734 //purpose  : 
735 //=======================================================================
736
737 Standard_Boolean BRepSweep_Rotation::GDDShapeIsToAdd
738   (const TopoDS_Shape& aNewShape,
739    const TopoDS_Shape& aNewSubShape,
740    const TopoDS_Shape& aGenS,
741    const Sweep_NumShape& aDirS,
742    const Sweep_NumShape& aSubDirS )const
743 {
744   if ( aNewShape.ShapeType() == TopAbs_SOLID &&
745        aNewSubShape.ShapeType() == TopAbs_FACE &&
746        aGenS.ShapeType() == TopAbs_FACE &&
747        aDirS.Type() == TopAbs_EDGE &&
748        aSubDirS.Type() == TopAbs_VERTEX ){
749     return ( Abs(myAng - 2 * M_PI) > Precision::Angular() );
750   }
751   else if ( aNewShape.ShapeType() == TopAbs_FACE &&
752        aNewSubShape.ShapeType() == TopAbs_EDGE &&
753        aGenS.ShapeType() == TopAbs_EDGE &&
754        aDirS.Type() == TopAbs_EDGE &&
755        aSubDirS.Type() == TopAbs_VERTEX ){
756     TopLoc_Location Loc;
757     GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewShape),Loc));
758     if (AS.GetType()==GeomAbs_Plane){
759       return ( Abs(myAng - 2 * M_PI) > Precision::Angular() );
760     }
761     else {
762       return Standard_True;
763     }
764   }
765   else {
766     return Standard_True;
767   }
768 }
769
770
771 //=======================================================================
772 //function : SeparatedWires
773 //purpose  : 
774 //=======================================================================
775
776 Standard_Boolean BRepSweep_Rotation::SeparatedWires
777   (const TopoDS_Shape& aNewShape,
778    const TopoDS_Shape& aNewSubShape,
779    const TopoDS_Shape& aGenS,
780    const TopoDS_Shape& aSubGenS,
781    const Sweep_NumShape& aDirS )const
782 {
783   if (aNewShape.ShapeType()==TopAbs_FACE &&
784       aNewSubShape.ShapeType()==TopAbs_EDGE &&
785       aGenS.ShapeType()==TopAbs_EDGE &&
786       aSubGenS.ShapeType()==TopAbs_VERTEX &&
787       aDirS.Type()==TopAbs_EDGE){
788     TopLoc_Location Loc;
789     GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewShape),Loc));
790     if (AS.GetType()==GeomAbs_Plane){
791       return (Abs(myAng-2*M_PI) <= Precision::Angular());
792     }
793     else{
794       return Standard_False;
795     }
796   }
797   else{
798     return Standard_False;
799   }
800 }
801
802 //=======================================================================
803 //function : SplitShell
804 //purpose  : 
805 //=======================================================================
806
807 TopoDS_Shape BRepSweep_Rotation::SplitShell(const TopoDS_Shape& aNewShape)const
808 {
809   BRepTools_Quilt Q;
810   Q.Add(aNewShape);
811   return Q.Shells();
812 }
813
814 //=======================================================================
815 //function : HasShape
816 //purpose  : 
817 //=======================================================================
818
819 Standard_Boolean  BRepSweep_Rotation::HasShape
820   (const TopoDS_Shape& aGenS, 
821    const Sweep_NumShape& aDirS)const 
822 {
823   if(aDirS.Type()==TopAbs_EDGE&&
824      aGenS.ShapeType()==TopAbs_EDGE){
825     return !IsInvariant(aGenS);
826   }
827   else{
828     return Standard_True;
829   }
830 }
831
832
833 //=======================================================================
834 //function : IsInvariant
835 //purpose  : 
836 //=======================================================================
837
838 Standard_Boolean  BRepSweep_Rotation::IsInvariant 
839   (const TopoDS_Shape& aGenS)const
840 {
841   if(aGenS.ShapeType()==TopAbs_EDGE){
842     TopLoc_Location Loc;
843     Standard_Real First,Last;
844     Handle(Geom_Curve) 
845       C = BRep_Tool::Curve(TopoDS::Edge(aGenS),Loc,First,Last);
846     Handle(Standard_Type) TheType = C->DynamicType();
847     if ( TheType == STANDARD_TYPE(Geom_Line)) {
848       TopoDS_Vertex V1, V2;
849       TopExp::Vertices(TopoDS::Edge(aGenS), V1, V2);
850       return ( IsInvariant(V1) && IsInvariant(V2));
851     }
852     else{
853       return Standard_False;
854     }
855   }
856   else if(aGenS.ShapeType()==TopAbs_VERTEX){
857     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aGenS));
858     gp_Lin Lin (myAxe.Location(), myAxe.Direction());
859     return ( Lin.Distance(P) <= BRep_Tool::Tolerance(TopoDS::Vertex(aGenS))); 
860   }
861   else
862     return Standard_False;
863 }
864
865 //=======================================================================
866 //function : Angle
867 //purpose  : 
868 //=======================================================================
869
870 Standard_Real BRepSweep_Rotation::Angle()const 
871 {
872   return myAng;
873 }
874
875 //=======================================================================
876 //function : Axe
877 //purpose  : 
878 //=======================================================================
879
880 gp_Ax1 BRepSweep_Rotation::Axe()const 
881 {
882   return myAxe;
883 }
884