0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / BRepPrim / BRepPrim_OneAxis.cxx
1 // Created on: 1991-07-24
2 // Created by: Christophe MARION
3 // Copyright (c) 1991-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 <BRepPrim_Builder.hxx>
19 #include <BRepPrim_Direction.hxx>
20 #include <BRepPrim_OneAxis.hxx>
21 #include <gp_Ax2.hxx>
22 #include <gp_Circ.hxx>
23 #include <gp_Circ2d.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Lin2d.hxx>
26 #include <gp_Pln.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <gp_Vec.hxx>
29 #include <Precision.hxx>
30 #include <Standard_DomainError.hxx>
31 #include <Standard_OutOfRange.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Shell.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopoDS_Wire.hxx>
37
38 #define NBVERTICES 6
39 #define VAXISTOP    0
40 #define VAXISBOT    1
41 #define VTOPSTART   2
42 #define VTOPEND     3
43 #define VBOTSTART   4
44 #define VBOTEND     5
45 #define NBEDGES    9
46 #define EAXIS       0
47 #define ESTART      1
48 #define EEND        2
49 #define ETOPSTART   3
50 #define ETOPEND     4
51 #define EBOTSTART   5
52 #define EBOTEND     6
53 #define ETOP        7
54 #define EBOTTOM     8
55 #define NBWIRES    9
56 #define WLATERAL    0
57 #define WLATERALSTART    0
58 #define WLATERALEND      1
59 #define WTOP             2
60 #define WBOTTOM          3
61 #define WSTART           5
62 #define WAXISSTART       6
63 #define WEND             7
64 #define WAXISEND         8
65 #define NBFACES    5
66 #define FLATERAL    0
67 #define FTOP        1
68 #define FBOTTOM     2
69 #define FSTART      3
70 #define FEND        4
71
72 //=======================================================================
73 //function : BRepPrim_OneAxis_Check
74 //purpose  : raise Standard_DomainError if something was built
75 //=======================================================================
76
77 static void BRepPrim_OneAxis_Check(const Standard_Boolean V[],
78                                      const Standard_Boolean E[],
79                                      const Standard_Boolean W[],
80                                      const Standard_Boolean F[])
81 {
82   Standard_Integer i;
83   for (i = 0; i < NBVERTICES; i++)
84     if (V[i]) throw Standard_DomainError();
85   for (i = 0; i < NBEDGES; i++)
86     if (E[i]) throw Standard_DomainError();
87   for (i = 0; i < NBWIRES; i++)
88     if (W[i]) throw Standard_DomainError();
89   for (i = 0; i < NBFACES; i++)
90     if (F[i]) throw Standard_DomainError();
91 }
92
93 //=======================================================================
94 //function : BRepPrim_OneAxis
95 //purpose  : 
96 //=======================================================================
97
98 BRepPrim_OneAxis::BRepPrim_OneAxis(const BRepPrim_Builder& B,
99                                        const gp_Ax2& A,
100                                        const Standard_Real VMin,
101                                        const Standard_Real VMax) :
102        myBuilder(B),
103        myAxes(A),
104        myAngle(2*M_PI),
105        myVMin(VMin),
106        myVMax(VMax),
107        myMeridianOffset(0)
108
109 {
110   // init Built flags
111   Standard_Integer i;
112   ShellBuilt = Standard_False;
113   for (i = 0; i < NBVERTICES; i++)
114     VerticesBuilt[i] = Standard_False;
115   for (i = 0; i < NBEDGES; i++)
116     EdgesBuilt[i] = Standard_False;
117   for (i = 0; i < NBWIRES; i++)
118     WiresBuilt[i] = Standard_False;
119   for (i = 0; i < NBFACES; i++)
120     FacesBuilt[i] = Standard_False;
121
122 }
123
124 //=======================================================================
125 //function : ~BRepPrim_OneAxis
126 //purpose  : Destructor
127 //=======================================================================
128
129 BRepPrim_OneAxis::~BRepPrim_OneAxis()
130 {
131 }
132
133 //=======================================================================
134 //function : SetMeridianOffset
135 //purpose  : 
136 //=======================================================================
137
138 void BRepPrim_OneAxis::SetMeridianOffset(const Standard_Real O)
139 {
140   myMeridianOffset = O;
141 }
142
143 //=======================================================================
144 //function : Axes, Angle, VMin, VMax
145 //purpose  : 
146 //=======================================================================
147
148 const gp_Ax2&  BRepPrim_OneAxis::Axes     () const 
149
150   return myAxes;
151 }
152
153 void BRepPrim_OneAxis::Axes     (const gp_Ax2& A)
154
155   BRepPrim_OneAxis_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
156   myAxes = A;
157 }
158
159 Standard_Real BRepPrim_OneAxis::Angle () const
160 {
161   return myAngle;
162 }
163
164 void BRepPrim_OneAxis::Angle (const Standard_Real A)
165 {
166   BRepPrim_OneAxis_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
167   myAngle = A;
168 }
169
170 Standard_Real BRepPrim_OneAxis::VMin () const
171 {
172   return myVMin;
173 }
174
175 void BRepPrim_OneAxis::VMin (const Standard_Real V)
176 {
177   BRepPrim_OneAxis_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
178   myVMin = V;
179 }
180
181 Standard_Real BRepPrim_OneAxis::VMax () const
182 {
183   return myVMax;
184 }
185
186 void BRepPrim_OneAxis::VMax (const Standard_Real V)
187 {
188   BRepPrim_OneAxis_Check(VerticesBuilt,EdgesBuilt,WiresBuilt,FacesBuilt);
189   myVMax = V;
190 }
191
192 //=======================================================================
193 //function : MeridianOnAxis
194 //purpose  : 
195 //=======================================================================
196
197 Standard_Boolean BRepPrim_OneAxis::MeridianOnAxis
198   (const Standard_Real V) const
199 {
200   return Abs(MeridianValue(V).X()) < Precision::Confusion();
201 }
202
203 //=======================================================================
204 //function : MeridianClosed
205 //purpose  : 
206 //=======================================================================
207
208 Standard_Boolean BRepPrim_OneAxis::MeridianClosed() const
209 {
210   if (VMaxInfinite()) return Standard_False;
211   if (VMinInfinite()) return Standard_False;
212   return MeridianValue(myVMin).IsEqual(MeridianValue(myVMax),
213                                        Precision::Confusion());
214 }
215
216 //=======================================================================
217 //function : VMaxInfinite
218 //purpose  : 
219 //=======================================================================
220
221 Standard_Boolean BRepPrim_OneAxis::VMaxInfinite() const
222 {
223   return Precision::IsPositiveInfinite(myVMax);
224 }
225
226 //=======================================================================
227 //function : VMinInfinite
228 //purpose  : 
229 //=======================================================================
230
231 Standard_Boolean BRepPrim_OneAxis::VMinInfinite() const
232 {
233   return Precision::IsNegativeInfinite(myVMin);
234 }
235
236 //=======================================================================
237 //function : HasTop
238 //purpose  : 
239 //=======================================================================
240
241 Standard_Boolean BRepPrim_OneAxis::HasTop() const
242 {
243   if (VMaxInfinite())         return Standard_False;
244   if (MeridianClosed())       return Standard_False;
245   if (MeridianOnAxis(myVMax)) return Standard_False;
246   return Standard_True;
247 }
248
249 //=======================================================================
250 //function : HasBottom
251 //purpose  : 
252 //=======================================================================
253
254 Standard_Boolean BRepPrim_OneAxis::HasBottom() const
255 {
256   if (VMinInfinite())         return Standard_False;
257   if (MeridianClosed())       return Standard_False;
258   if (MeridianOnAxis(myVMin)) return Standard_False;
259   return Standard_True;
260 }
261
262 //=======================================================================
263 //function : HasSides
264 //purpose  : 
265 //=======================================================================
266
267 Standard_Boolean BRepPrim_OneAxis::HasSides() const
268 {
269   return 2*M_PI - myAngle > Precision::Angular();
270 }
271
272 //=======================================================================
273 //function : Shell
274 //purpose  : 
275 //=======================================================================
276
277 const TopoDS_Shell& BRepPrim_OneAxis::Shell()
278 {
279   if (!ShellBuilt) {
280     myBuilder.MakeShell(myShell);
281
282     myBuilder.AddShellFace(myShell,LateralFace());
283     if (HasTop())
284       myBuilder.AddShellFace(myShell,TopFace());
285     if (HasBottom())
286       myBuilder.AddShellFace(myShell,BottomFace());
287     if (HasSides()) {
288       myBuilder.AddShellFace(myShell,StartFace());
289       myBuilder.AddShellFace(myShell,EndFace());
290     }
291
292     myShell.Closed (BRep_Tool::IsClosed (myShell));
293     myBuilder.CompleteShell(myShell);
294     ShellBuilt = Standard_True;
295   }
296   return myShell;
297 }
298
299 //=======================================================================
300 //function : LateralFace
301 //purpose  : build the lateral face
302 //=======================================================================
303
304 const TopoDS_Face& BRepPrim_OneAxis::LateralFace ()
305 {
306   // do it if not done
307   if (!FacesBuilt[FLATERAL]) {
308
309     // build an empty lateral face
310     myFaces[FLATERAL] = MakeEmptyLateralFace();
311
312     // add the wires
313     if (VMaxInfinite() && VMinInfinite()) {
314       myBuilder.AddFaceWire(myFaces[FLATERAL],LateralStartWire());
315       myBuilder.AddFaceWire(myFaces[FLATERAL],LateralEndWire());
316     }
317     else
318       myBuilder.AddFaceWire(myFaces[FLATERAL],LateralWire());
319
320     // put the parametric curves
321     if (MeridianClosed()) {
322       // closed edge
323       myBuilder.SetPCurve(myEdges[ETOP],myFaces[FLATERAL],
324                           gp_Lin2d(gp_Pnt2d(0,myVMin),gp_Dir2d(1,0)),
325                           gp_Lin2d(gp_Pnt2d(0,myVMax),gp_Dir2d(1,0)));
326     }    
327     else {
328       if (!VMaxInfinite()) {
329         myBuilder.SetPCurve(myEdges[ETOP],myFaces[FLATERAL],
330                             gp_Lin2d(gp_Pnt2d(0,myVMax),gp_Dir2d(1,0)));
331         if (!HasSides() || MeridianOnAxis(myVMax)) {
332           // closed edge set parameters
333           myBuilder.SetParameters(myEdges[ETOP],
334                                   TopEndVertex(),
335                                   0.,myAngle);
336         }
337       }
338       if (!VMinInfinite()) {
339         myBuilder.SetPCurve(myEdges[EBOTTOM],myFaces[FLATERAL],
340                             gp_Lin2d(gp_Pnt2d(0,myVMin),gp_Dir2d(1,0)));
341         if (!HasSides() || MeridianOnAxis(myVMin)) {
342           // closed edge set parameters
343           myBuilder.SetParameters(myEdges[EBOTTOM],
344                                   BottomEndVertex(),
345                                   0.,myAngle);
346         }
347       }
348     }
349     if (HasSides()) {
350       myBuilder.SetPCurve(myEdges[ESTART],myFaces[FLATERAL],
351                           gp_Lin2d(gp_Pnt2d(0,-myMeridianOffset),
352                                    gp_Dir2d(0,1)));
353       
354       myBuilder.SetPCurve(myEdges[EEND],myFaces[FLATERAL],
355                           gp_Lin2d(gp_Pnt2d(myAngle,-myMeridianOffset),
356                                    gp_Dir2d(0,1)));
357     }
358     else {
359       // closed edge
360       myBuilder.SetPCurve(myEdges[ESTART],myFaces[FLATERAL],
361                           gp_Lin2d(gp_Pnt2d(myAngle,-myMeridianOffset),
362                                    gp_Dir2d(0,1)),
363                           gp_Lin2d(gp_Pnt2d(0,-myMeridianOffset),
364                                    gp_Dir2d(0,1)));
365     }
366     myBuilder.CompleteFace(myFaces[FLATERAL]);
367     FacesBuilt[FLATERAL] = Standard_True;
368   }
369   return myFaces[FLATERAL];
370 }
371
372 //=======================================================================
373 //function : TopFace
374 //purpose  : build and return the TopFace
375 //=======================================================================
376
377 const TopoDS_Face& BRepPrim_OneAxis::TopFace ()
378 {
379   // do it if not done
380   if (!FacesBuilt[FTOP]) {
381
382     Standard_DomainError_Raise_if(!HasTop(),
383                                   "BRepPrim_OneAxis::TopFace:No top face");
384     
385     // make the empty face by translating the axes
386     Standard_Real z = MeridianValue(myVMax).Y();
387     gp_Vec V = myAxes.Direction();
388     V.Multiply(z);
389     myBuilder.MakeFace(myFaces[FTOP],gp_Pln(myAxes.Translated(V)));
390
391     myBuilder.AddFaceWire(myFaces[FTOP],TopWire());
392
393     // put the parametric curves
394     myBuilder.SetPCurve(myEdges[ETOP],myFaces[FTOP],
395                         gp_Circ2d(gp_Ax2d(gp_Pnt2d(0,0),gp_Dir2d(1,0)),
396                                   MeridianValue(myVMax).X()));
397     if (HasSides()) {
398       myBuilder.SetPCurve(myEdges[ETOPSTART],myFaces[FTOP],
399                           gp_Lin2d(gp_Pnt2d(0,0),gp_Dir2d(1,0)));
400       myBuilder.SetPCurve(myEdges[ETOPEND],myFaces[FTOP],
401                           gp_Lin2d(gp_Pnt2d(0,0),
402                                    gp_Dir2d(Cos(myAngle),Sin(myAngle))));
403     }
404     
405     myBuilder.CompleteFace(myFaces[FTOP]);
406     FacesBuilt[FTOP] = Standard_True;
407   }
408
409   return myFaces[FTOP];
410 }
411
412 //=======================================================================
413 //function : BottomFace
414 //purpose  : 
415 //=======================================================================
416
417 const TopoDS_Face& BRepPrim_OneAxis::BottomFace ()
418 {
419   // do it if not done
420   if (!FacesBuilt[FBOTTOM]) {
421
422     Standard_DomainError_Raise_if(!HasBottom(),
423                                   "BRepPrim_OneAxis::BottomFace:No bottom face");
424     
425     // make the empty face by translating the axes
426     Standard_Real z = MeridianValue(myVMin).Y();
427     gp_Vec V = myAxes.Direction();
428     V.Multiply(z);
429     gp_Ax2 axes = myAxes.Translated(V);
430     myBuilder.MakeFace(myFaces[FBOTTOM],gp_Pln(axes));
431     myBuilder.ReverseFace(myFaces[FBOTTOM]);
432     myBuilder.AddFaceWire(myFaces[FBOTTOM],BottomWire());
433
434     // put the parametric curves
435     myBuilder.SetPCurve(myEdges[EBOTTOM],myFaces[FBOTTOM],
436                         gp_Circ2d(gp_Ax2d(gp_Pnt2d(0,0),gp_Dir2d(1,0)),
437                                   MeridianValue(myVMin).X()));
438     if (HasSides()) {
439       myBuilder.SetPCurve(myEdges[EBOTSTART],myFaces[FBOTTOM],
440                           gp_Lin2d(gp_Pnt2d(0,0),gp_Dir2d(1,0)));
441       myBuilder.SetPCurve(myEdges[EBOTEND],myFaces[FBOTTOM],
442                           gp_Lin2d(gp_Pnt2d(0,0),
443                                    gp_Dir2d(Cos(myAngle),Sin(myAngle))));
444     }
445     
446     myBuilder.CompleteFace(myFaces[FBOTTOM]);
447     FacesBuilt[FBOTTOM] = Standard_True;
448   }
449
450   return myFaces[FBOTTOM];
451 }
452
453 //=======================================================================
454 //function : StartFace
455 //purpose  : 
456 //=======================================================================
457
458 const TopoDS_Face& BRepPrim_OneAxis::StartFace ()
459 {
460   // do it if not done
461   if (!FacesBuilt[FSTART]) {
462
463     Standard_DomainError_Raise_if(!HasSides(),
464                                   "BRepPrim_OneAxes::StartFace:No side faces");
465
466     // build the empty face, perpendicular to myTool.Axes()
467     gp_Ax2 axes(myAxes.Location(),myAxes.YDirection().Reversed(),myAxes.XDirection());
468     myBuilder.MakeFace(myFaces[FSTART],gp_Pln(axes));
469
470
471     if (VMaxInfinite() && VMinInfinite()) 
472       myBuilder.AddFaceWire(myFaces[FSTART],AxisStartWire());
473
474     myBuilder.AddFaceWire(myFaces[FSTART],StartWire());
475
476     // parametric curves
477     SetMeridianPCurve(myEdges[ESTART],myFaces[FSTART]);
478     if (EdgesBuilt[EAXIS])
479       myBuilder.SetPCurve(myEdges[EAXIS],myFaces[FSTART],
480                           gp_Lin2d(gp_Pnt2d(0,0),gp_Dir2d(0,1)));
481     if (EdgesBuilt[ETOPSTART])
482       myBuilder.SetPCurve(myEdges[ETOPSTART],myFaces[FSTART],
483                           gp_Lin2d(gp_Pnt2d(0,MeridianValue(myVMax).Y()),gp_Dir2d(1,0)));
484     if (EdgesBuilt[EBOTSTART])
485       myBuilder.SetPCurve(myEdges[EBOTSTART],myFaces[FSTART],
486                           gp_Lin2d(gp_Pnt2d(0,MeridianValue(myVMin).Y()),gp_Dir2d(1,0)));
487     
488
489     myBuilder.CompleteFace(myFaces[FSTART]);
490     FacesBuilt[FSTART] = Standard_True;
491   }
492
493   return myFaces[FSTART];
494 }
495
496 //=======================================================================
497 //function : EndFace
498 //purpose  : 
499 //=======================================================================
500
501 const TopoDS_Face& BRepPrim_OneAxis::EndFace ()
502 {
503   // do it if not done
504   if (!FacesBuilt[FEND]) {
505
506     Standard_DomainError_Raise_if(!HasSides(),
507                                   "BRepPrim_OneAxes::EndFace:No side faces");
508
509     // build the empty face, perpendicular to myTool.Axes()
510     gp_Ax2 axes(myAxes.Location(),myAxes.YDirection().Reversed(),myAxes.XDirection());
511     axes.Rotate(myAxes.Axis(),myAngle);
512     myBuilder.MakeFace(myFaces[FEND],gp_Pln(axes));
513     myBuilder.ReverseFace(myFaces[FEND]);
514
515     if (VMaxInfinite() && VMinInfinite())
516       myBuilder.AddFaceWire(myFaces[FEND],AxisEndWire());
517     myBuilder.AddFaceWire(myFaces[FEND],EndWire());
518
519     // parametric curves
520     SetMeridianPCurve(myEdges[EEND],myFaces[FEND]);
521     if (EdgesBuilt[EAXIS])
522       myBuilder.SetPCurve(myEdges[EAXIS],myFaces[FEND],
523                           gp_Lin2d(gp_Pnt2d(0,0),gp_Dir2d(0,1)));
524     if (EdgesBuilt[ETOPEND])
525       myBuilder.SetPCurve(myEdges[ETOPEND],myFaces[FEND],
526                           gp_Lin2d(gp_Pnt2d(0,MeridianValue(myVMax).Y()),
527                                    gp_Dir2d(1,0)));
528     if (EdgesBuilt[EBOTEND])
529       myBuilder.SetPCurve(myEdges[EBOTEND],myFaces[FEND],
530                           gp_Lin2d(gp_Pnt2d(0,MeridianValue(myVMin).Y()),
531                                    gp_Dir2d(1,0)));
532     
533     myBuilder.CompleteFace(myFaces[FEND]);
534     FacesBuilt[FEND] = Standard_True;
535   }
536
537   return myFaces[FEND];
538 }
539
540 //=======================================================================
541 //function : LateralWire
542 //purpose  : 
543 //=======================================================================
544
545 const TopoDS_Wire& BRepPrim_OneAxis::LateralWire ()
546 {
547   // do it if not done
548   if (!WiresBuilt[WLATERAL]) {
549
550     myBuilder.MakeWire(myWires[WLATERAL]);
551   
552     if (!VMaxInfinite())
553       myBuilder.AddWireEdge(myWires[WLATERAL],TopEdge()    ,Standard_False);
554     myBuilder.AddWireEdge(  myWires[WLATERAL],EndEdge()    ,Standard_True);
555     if (!VMinInfinite())
556       myBuilder.AddWireEdge(myWires[WLATERAL],BottomEdge() ,Standard_True);
557     myBuilder.AddWireEdge(  myWires[WLATERAL],StartEdge()  ,Standard_False);
558
559     myBuilder.CompleteWire(myWires[WLATERAL]);
560     WiresBuilt[WLATERAL] = Standard_True;
561   }
562   
563   return myWires[WLATERAL];
564 }
565
566
567 //=======================================================================
568 //function : LateralStartWire
569 //purpose  : 
570 //=======================================================================
571
572 const TopoDS_Wire& BRepPrim_OneAxis::LateralStartWire ()
573 {
574   // do it if not done
575   if (!WiresBuilt[WLATERALSTART]) {
576
577     myBuilder.MakeWire(myWires[WLATERALSTART]);
578   
579     myBuilder.AddWireEdge(myWires[WLATERALSTART],StartEdge(),Standard_False);
580
581     myBuilder.CompleteWire(myWires[WLATERALSTART]);
582     WiresBuilt[WLATERALSTART] = Standard_True;
583   }
584   
585   return myWires[WLATERALSTART];
586 }
587
588
589 //=======================================================================
590 //function : LateralEndWire
591 //purpose  : 
592 //=======================================================================
593
594 const TopoDS_Wire& BRepPrim_OneAxis::LateralEndWire ()
595 {
596   // do it if not done
597   if (!WiresBuilt[WLATERALEND]) {
598
599     myBuilder.MakeWire(myWires[WLATERALEND]);
600   
601     myBuilder.AddWireEdge(myWires[WLATERALEND],EndEdge(),Standard_True);
602
603     myBuilder.CompleteWire(myWires[WLATERALEND]);
604     WiresBuilt[WLATERALEND] = Standard_True;
605   }
606   
607   return myWires[WLATERALEND];
608 }
609
610 //=======================================================================
611 //function : TopWire
612 //purpose  : 
613 //=======================================================================
614
615 const TopoDS_Wire& BRepPrim_OneAxis::TopWire ()
616 {
617   // do it if not done
618   if (!WiresBuilt[WTOP]) {
619
620     Standard_DomainError_Raise_if(!HasTop(),
621                                   "BRepPrim_OneAxis::TopWire: no top");
622
623     myBuilder.MakeWire(myWires[WTOP]);
624   
625     myBuilder.AddWireEdge(myWires[WTOP],TopEdge()       ,Standard_True);
626     if (HasSides()) {
627       myBuilder.AddWireEdge(myWires[WTOP],StartTopEdge()  ,Standard_True);
628       myBuilder.AddWireEdge(myWires[WTOP],EndTopEdge()    ,Standard_False);
629     }
630     myBuilder.CompleteWire(myWires[WTOP]);
631     WiresBuilt[WTOP] = Standard_True;
632   }
633
634   return myWires[WTOP];
635 }
636
637 //=======================================================================
638 //function : BottomWire
639 //purpose  : 
640 //=======================================================================
641
642 const TopoDS_Wire& BRepPrim_OneAxis::BottomWire ()
643 {
644   // do it if not done
645   if (!WiresBuilt[WBOTTOM]) {
646
647     Standard_DomainError_Raise_if(!HasBottom(),
648                                   "BRepPrim_OneAxis::BottomWire: no bottom");
649
650     myBuilder.MakeWire(myWires[WBOTTOM]);
651   
652     myBuilder.AddWireEdge(myWires[WBOTTOM],BottomEdge()       ,Standard_False);
653     if (HasSides()) {
654       myBuilder.AddWireEdge(myWires[WBOTTOM],EndBottomEdge()  ,Standard_True);
655       myBuilder.AddWireEdge(myWires[WBOTTOM],StartBottomEdge(),Standard_False);
656     }
657
658     myBuilder.CompleteWire(myWires[WBOTTOM]);
659     WiresBuilt[WBOTTOM] = Standard_True;
660   }
661   
662   return myWires[WBOTTOM];
663 }
664
665 //=======================================================================
666 //function : StartWire
667 //purpose  : 
668 //=======================================================================
669
670 const TopoDS_Wire& BRepPrim_OneAxis::StartWire ()
671 {
672   // do it if not done
673   if (!WiresBuilt[WSTART]) {
674
675     Standard_DomainError_Raise_if(!HasSides(),
676                                   "BRepPrim_OneAxes::StartWire:no sides");
677   
678     myBuilder.MakeWire(myWires[WSTART]);
679   
680     if (HasBottom())
681       myBuilder.AddWireEdge(myWires[WSTART],StartBottomEdge() ,Standard_True);
682
683     if (!MeridianClosed()) {
684       if (!VMaxInfinite() || !VMinInfinite())
685         myBuilder.AddWireEdge(  myWires[WSTART],AxisEdge()    ,Standard_False);
686     }
687
688     if (HasTop())  
689       myBuilder.AddWireEdge(myWires[WSTART],StartTopEdge()    ,Standard_False);
690     myBuilder.AddWireEdge(  myWires[WSTART],StartEdge()       ,Standard_True);
691
692     myBuilder.CompleteWire(myWires[WSTART]);
693     WiresBuilt[WSTART] = Standard_True;
694   }
695
696   return myWires[WSTART];
697 }
698
699 //=======================================================================
700 //function : AxisStartWire
701 //purpose  : 
702 //=======================================================================
703
704 const TopoDS_Wire& BRepPrim_OneAxis::AxisStartWire ()
705 {
706   // do it if not done
707   if (!WiresBuilt[WAXISSTART]) {
708
709     Standard_DomainError_Raise_if
710       (!HasSides(),
711        "BRepPrim_OneAxes::AxisStartWire:no sides");
712   
713     Standard_DomainError_Raise_if
714       (!VMaxInfinite() || !VMinInfinite(),
715        "BRepPrim_OneAxes::AxisStartWire:not infinite");
716
717     Standard_DomainError_Raise_if
718       (MeridianClosed(),
719        "BRepPrim_OneAxes::AxisStartWire:meridian closed");
720   
721     myBuilder.MakeWire(myWires[WAXISSTART]);
722   
723     myBuilder.AddWireEdge(  myWires[WAXISSTART],AxisEdge()    ,Standard_False);
724
725     myBuilder.CompleteWire(myWires[WAXISSTART]);
726     WiresBuilt[WAXISSTART] = Standard_True;
727   }
728
729   return myWires[WAXISSTART];
730 }
731
732 //=======================================================================
733 //function : EndWire
734 //purpose  : 
735 //=======================================================================
736
737 const TopoDS_Wire& BRepPrim_OneAxis::EndWire ()
738 {
739   // do it if not done
740   if (!WiresBuilt[WEND]) {
741
742     Standard_DomainError_Raise_if(!HasSides(),
743                                   "BRepPrim_OneAxes::EndWire:no sides");
744   
745     myBuilder.MakeWire(myWires[WEND]);
746     
747     if (HasTop())
748       myBuilder.AddWireEdge(myWires[WEND],EndTopEdge(),    Standard_True);
749     if (!MeridianClosed()) {
750       if (!VMaxInfinite() || !VMinInfinite()) {
751         myBuilder.AddWireEdge( myWires[WEND],AxisEdge(),      Standard_True);
752       }
753     }
754     if (HasBottom()) 
755       myBuilder.AddWireEdge(myWires[WEND],EndBottomEdge(), Standard_False);
756     myBuilder.AddWireEdge(  myWires[WEND],EndEdge(),       Standard_False);
757
758     myBuilder.CompleteWire(myWires[WEND]);
759     WiresBuilt[WEND] = Standard_True;
760   }
761   return myWires[WEND];
762 }
763
764 //=======================================================================
765 //function : AxisEndWire
766 //purpose  : 
767 //=======================================================================
768
769 const TopoDS_Wire& BRepPrim_OneAxis::AxisEndWire ()
770 {
771   // do it if not done
772   if (!WiresBuilt[WAXISEND]) {
773
774     Standard_DomainError_Raise_if
775       (!HasSides(),
776        "BRepPrim_OneAxes::AxisEndWire:no sides");
777   
778     Standard_DomainError_Raise_if
779       (!VMaxInfinite() || !VMinInfinite(),
780        "BRepPrim_OneAxes::AxisEndWire:not infinite");
781
782     Standard_DomainError_Raise_if
783       (MeridianClosed(),
784        "BRepPrim_OneAxes::AxisEndWire:meridian closed");
785   
786     myBuilder.MakeWire(myWires[WAXISEND]);
787     
788     myBuilder.AddWireEdge( myWires[WAXISEND],AxisEdge(),      Standard_True);
789
790     myBuilder.CompleteWire(myWires[WAXISEND]);
791     WiresBuilt[WAXISEND] = Standard_True;
792   }
793   return myWires[WAXISEND];
794 }
795
796 //=======================================================================
797 //function : AxisEdge
798 //purpose  : make the edge on the axis, oriented +Z
799 //=======================================================================
800
801 const TopoDS_Edge& BRepPrim_OneAxis::AxisEdge ()
802 {
803   // do it if not done
804   if (!EdgesBuilt[EAXIS]) {
805
806     Standard_DomainError_Raise_if(!HasSides(),
807                                   "BRepPrim_OneAxis::AxisEdge:no sides");
808     Standard_DomainError_Raise_if(MeridianClosed(),
809                                   "BRepPrim_OneAxis::AxisEdge:closed");
810
811     // build the empty edge.
812     myBuilder.MakeEdge(myEdges[EAXIS],gp_Lin(myAxes.Axis()));
813     
814     if (!VMaxInfinite())
815       myBuilder.AddEdgeVertex(myEdges[EAXIS],AxisTopVertex(),
816                               MeridianValue(myVMax).Y(),Standard_False);
817     if (!VMinInfinite())
818       myBuilder.AddEdgeVertex(myEdges[EAXIS],AxisBottomVertex(),
819                               MeridianValue(myVMin).Y(),Standard_True);
820
821     myBuilder.CompleteEdge(myEdges[EAXIS]);
822     EdgesBuilt[EAXIS] = Standard_True;
823   }
824
825   return myEdges[EAXIS];
826 }
827
828 //=======================================================================
829 //function : StartEdge
830 //purpose  : 
831 //=======================================================================
832
833 const TopoDS_Edge& BRepPrim_OneAxis::StartEdge ()
834 {
835   // do it if not done
836   if (!EdgesBuilt[ESTART]) {
837
838     // is it shared with the EndEdge
839
840     if (!HasSides() && EdgesBuilt[EEND])
841       myEdges[ESTART] = myEdges[EEND];
842   
843     else {
844       // build the empty Edge
845       myEdges[ESTART] = MakeEmptyMeridianEdge(0.);
846       
847       if (MeridianClosed()) {
848         // Closed edge
849         myBuilder.AddEdgeVertex(myEdges[ESTART],
850                                 TopStartVertex(),
851                                 myVMin+myMeridianOffset,
852                                 myVMax+myMeridianOffset);
853       }
854       else {
855         if (!VMaxInfinite()) {
856           myBuilder.AddEdgeVertex(myEdges[ESTART],
857                                   TopStartVertex(),
858                                   myVMax+myMeridianOffset,
859                                   Standard_False);
860         }
861         if (!VMinInfinite()) {
862           myBuilder.AddEdgeVertex(myEdges[ESTART],
863                                   BottomStartVertex(),
864                                   myVMin+myMeridianOffset,
865                                   Standard_True);
866         }
867       }
868     }
869
870     myBuilder.CompleteEdge(myEdges[ESTART]);
871     EdgesBuilt[ESTART] = Standard_True;
872     
873   }
874
875   return myEdges[ESTART];
876 }
877
878 //=======================================================================
879 //function : EndEdge
880 //purpose  : 
881 //=======================================================================
882
883 const TopoDS_Edge& BRepPrim_OneAxis::EndEdge ()
884 {
885   // do it if not done
886   if (!EdgesBuilt[EEND]) {
887
888     // is it shared with the start edge
889     if (!HasSides() && EdgesBuilt[ESTART])
890       myEdges[EEND] = myEdges[ESTART];
891
892     else {
893       // build the empty Edge
894       myEdges[EEND] = MakeEmptyMeridianEdge(myAngle);
895       
896       
897       if (MeridianClosed()) {
898         // Closed edge
899         myBuilder.AddEdgeVertex(myEdges[EEND],
900                                 TopEndVertex(),
901                                 myVMin+myMeridianOffset,
902                                 myVMax+myMeridianOffset);
903       }
904       else {
905         if (!VMaxInfinite()) {
906           myBuilder.AddEdgeVertex(myEdges[EEND],
907                                   TopEndVertex(),
908                                   myVMax+myMeridianOffset,
909                                   Standard_False);
910         }
911         if (!VMinInfinite()) {
912           myBuilder.AddEdgeVertex(myEdges[EEND],
913                                   BottomEndVertex(),
914                                   myVMin+myMeridianOffset,
915                                   Standard_True);
916         }
917       }
918     }
919     
920     myBuilder.CompleteEdge(myEdges[EEND]);
921     EdgesBuilt[EEND] = Standard_True;
922     
923   }
924   
925   return myEdges[EEND];
926 }
927
928 //=======================================================================
929 //function : StartTopEdge
930 //purpose  : 
931 //=======================================================================
932
933 const TopoDS_Edge& BRepPrim_OneAxis::StartTopEdge ()
934 {
935   // do it if not done
936   if (!EdgesBuilt[ETOPSTART]) {
937
938     Standard_DomainError_Raise_if
939       (!HasTop() || !HasSides(),
940        "BRepPrim_OneAxis::StartTopEdge:no sides or no top");
941
942     // build the empty Edge
943     gp_Vec V = myAxes.Direction();
944     V.Multiply(MeridianValue(myVMax).Y());
945     gp_Pnt P = myAxes.Location().Translated(V);
946     myBuilder.MakeEdge(myEdges[ETOPSTART],gp_Lin(P,myAxes.XDirection()));
947
948     myBuilder.AddEdgeVertex(myEdges[ETOPSTART],AxisTopVertex(),
949                             0.,Standard_True);
950     myBuilder.AddEdgeVertex(myEdges[ETOPSTART],TopStartVertex(),
951                             MeridianValue(myVMax).X(),Standard_False);
952
953     myBuilder.CompleteEdge(myEdges[ETOPSTART]);
954     EdgesBuilt[ETOPSTART] = Standard_True;
955   }
956
957   return myEdges[ETOPSTART];
958 }
959
960 //=======================================================================
961 //function : StartBottomEdge
962 //purpose  : 
963 //=======================================================================
964
965 const TopoDS_Edge& BRepPrim_OneAxis::StartBottomEdge ()
966 {
967   // do it if not done
968   if (!EdgesBuilt[EBOTSTART]) {
969
970     Standard_DomainError_Raise_if
971       (!HasBottom() || !HasSides(),
972        "BRepPrim_OneAxis::StartBottomEdge:no sides or no top");
973
974     // build the empty Edge
975     gp_Vec V = myAxes.Direction();
976     V.Multiply(MeridianValue(myVMin).Y());
977     gp_Pnt P = myAxes.Location().Translated(V);
978     myBuilder.MakeEdge(myEdges[EBOTSTART],gp_Lin(P,myAxes.XDirection()));
979
980     myBuilder.AddEdgeVertex(myEdges[EBOTSTART],BottomStartVertex(),
981                             MeridianValue(myVMin).X(),Standard_False);
982     myBuilder.AddEdgeVertex(myEdges[EBOTSTART],AxisBottomVertex(),
983                             0.,Standard_True);
984
985     myBuilder.CompleteEdge(myEdges[EBOTSTART]);
986     EdgesBuilt[EBOTSTART] = Standard_True;
987   }
988
989   return myEdges[EBOTSTART];
990 }
991
992 //=======================================================================
993 //function : EndTopEdge
994 //purpose  : 
995 //=======================================================================
996
997 const TopoDS_Edge& BRepPrim_OneAxis::EndTopEdge ()
998 {
999   // do it if not done
1000   if (!EdgesBuilt[ETOPEND]) {
1001
1002     Standard_DomainError_Raise_if
1003       (!HasTop() || !HasSides(),
1004        "BRepPrim_OneAxis::EndTopEdge:no sides or no top");
1005
1006     // build the empty Edge
1007     gp_Vec V = myAxes.Direction();
1008     V.Multiply(MeridianValue(myVMax).Y());
1009     gp_Pnt P = myAxes.Location().Translated(V);
1010     gp_Lin L(P,myAxes.XDirection());
1011     L.Rotate(myAxes.Axis(),myAngle);
1012     myBuilder.MakeEdge(myEdges[ETOPEND],L);
1013
1014     myBuilder.AddEdgeVertex(myEdges[ETOPEND],AxisTopVertex(),
1015                             0.,Standard_True);
1016     myBuilder.AddEdgeVertex(myEdges[ETOPEND],TopEndVertex(),
1017                             MeridianValue(myVMax).X(),Standard_False);
1018
1019     myBuilder.CompleteEdge(myEdges[ETOPEND]);
1020     EdgesBuilt[ETOPEND] = Standard_True;
1021   }
1022
1023   return myEdges[ETOPEND];
1024 }
1025
1026 //=======================================================================
1027 //function : EndBottomEdge
1028 //purpose  : 
1029 //=======================================================================
1030
1031 const TopoDS_Edge& BRepPrim_OneAxis::EndBottomEdge ()
1032 {
1033   // do it if not done
1034   if (!EdgesBuilt[EBOTEND]) {
1035
1036
1037     Standard_DomainError_Raise_if
1038       (!HasBottom() || !HasSides(),
1039        "BRepPrim_OneAxis::EndBottomEdge:no sides or no bottom");
1040
1041     // build the empty Edge
1042     gp_Vec V = myAxes.Direction();
1043     V.Multiply(MeridianValue(myVMin).Y());
1044     gp_Pnt P = myAxes.Location().Translated(V);
1045     gp_Lin L(P,myAxes.XDirection());
1046     L.Rotate(myAxes.Axis(),myAngle);
1047     myBuilder.MakeEdge(myEdges[EBOTEND],L);
1048
1049     myBuilder.AddEdgeVertex(myEdges[EBOTEND],AxisBottomVertex(),
1050                             0.,Standard_True);
1051     myBuilder.AddEdgeVertex(myEdges[EBOTEND],BottomEndVertex(),
1052                             MeridianValue(myVMin).X(),Standard_False);
1053
1054     myBuilder.CompleteEdge(myEdges[EBOTEND]);
1055     EdgesBuilt[EBOTEND] = Standard_True;
1056   }
1057   
1058   return myEdges[EBOTEND];
1059 }
1060
1061 //=======================================================================
1062 //function : TopEdge
1063 //purpose  : 
1064 //=======================================================================
1065
1066 const TopoDS_Edge& BRepPrim_OneAxis::TopEdge ()
1067 {
1068   // do it if not done
1069   if (!EdgesBuilt[ETOP]) {
1070
1071     // Test if shared with bottom edge
1072     if (MeridianClosed() && EdgesBuilt[EBOTTOM]) {
1073       myEdges[ETOP] = myEdges[EBOTTOM];
1074     }
1075
1076     else {
1077
1078       // build the empty Edge
1079       if (!MeridianOnAxis(myVMax)) {
1080         gp_Pnt2d mp = MeridianValue(myVMax);
1081         gp_Vec V = myAxes.Direction();
1082         V.Multiply(mp.Y());
1083         gp_Pnt P = myAxes.Location().Translated(V);
1084         gp_Circ C(gp_Ax2(P,myAxes.Direction(),myAxes.XDirection()),mp.X());
1085         myBuilder.MakeEdge(myEdges[ETOP],C);
1086       }
1087       else
1088         myBuilder.MakeDegeneratedEdge(myEdges[ETOP]);
1089      
1090       if (!HasSides()) {
1091         // closed edge
1092         myBuilder.AddEdgeVertex(myEdges[ETOP],
1093                                 TopEndVertex(),
1094                                 0.,myAngle);
1095       }
1096       else {
1097         myBuilder.AddEdgeVertex(myEdges[ETOP],
1098                                 TopEndVertex(),
1099                                 myAngle,
1100                                 Standard_False);
1101         myBuilder.AddEdgeVertex(myEdges[ETOP],
1102                                 TopStartVertex(),
1103                                 0.,
1104                                 Standard_True);
1105       }
1106     }
1107
1108     myBuilder.CompleteEdge(myEdges[ETOP]);
1109     EdgesBuilt[ETOP] = Standard_True;
1110   }
1111
1112   return myEdges[ETOP];
1113 }
1114
1115 //=======================================================================
1116 //function : BottomEdge
1117 //purpose  : 
1118 //=======================================================================
1119
1120 const TopoDS_Edge& BRepPrim_OneAxis::BottomEdge ()
1121 {
1122   // do it if not done
1123   if (!EdgesBuilt[EBOTTOM]) {
1124
1125     // Test if shared with top edge
1126     if (MeridianClosed() && EdgesBuilt[ETOP]) {
1127       myEdges[EBOTTOM] = myEdges[ETOP];
1128     }
1129
1130     else {
1131
1132     // build the empty Edge
1133
1134       if (!MeridianOnAxis(myVMin)) {
1135         gp_Pnt2d mp = MeridianValue(myVMin);
1136         gp_Vec V = myAxes.Direction();
1137         V.Multiply(mp.Y());
1138         gp_Pnt P = myAxes.Location().Translated(V);
1139         gp_Circ C(gp_Ax2(P,myAxes.Direction(),myAxes.XDirection()),mp.X());
1140         myBuilder.MakeEdge(myEdges[EBOTTOM],C);
1141       }
1142       else
1143         myBuilder.MakeDegeneratedEdge(myEdges[EBOTTOM]);
1144       
1145       if (!HasSides()) {
1146         // closed edge
1147         myBuilder.AddEdgeVertex(myEdges[EBOTTOM],
1148                                 BottomEndVertex(),
1149                                 0.,myAngle);
1150       }
1151       else {
1152         myBuilder.AddEdgeVertex(myEdges[EBOTTOM],
1153                                 BottomEndVertex(),
1154                                 myAngle,
1155                                 Standard_False);
1156         myBuilder.AddEdgeVertex(myEdges[EBOTTOM],
1157                                 BottomStartVertex(),
1158                                 0.,
1159                                 Standard_True);
1160       }
1161     }
1162
1163     myBuilder.CompleteEdge(myEdges[EBOTTOM]);
1164     EdgesBuilt[EBOTTOM] = Standard_True;
1165   }
1166
1167   return myEdges[EBOTTOM];
1168 }
1169
1170 //=======================================================================
1171 //function : AxisTopVertex
1172 //purpose  : 
1173 //=======================================================================
1174
1175 const TopoDS_Vertex& BRepPrim_OneAxis::AxisTopVertex ()
1176 {
1177   // do it if not done
1178   if (!VerticesBuilt[VAXISTOP]) {
1179
1180     // deduct from others
1181     if (MeridianOnAxis(myVMax) && VerticesBuilt[VTOPSTART])
1182       myVertices[VAXISTOP] = myVertices[VTOPSTART];
1183     
1184     else if (MeridianOnAxis(myVMax) && VerticesBuilt[VTOPEND])
1185       myVertices[VAXISTOP] = myVertices[VTOPEND];
1186     
1187     else {
1188       Standard_DomainError_Raise_if(MeridianClosed(),
1189                                     "BRepPrim_OneAxis::AxisTopVertex");
1190       Standard_DomainError_Raise_if(VMaxInfinite(),
1191                                     "BRepPrim_OneAxis::AxisTopVertex");
1192       
1193       gp_Vec V = myAxes.Direction();
1194       V.Multiply(MeridianValue(myVMax).Y());
1195       gp_Pnt P = myAxes.Location().Translated(V);
1196       myBuilder.MakeVertex(myVertices[VAXISTOP],P);
1197     }
1198
1199     VerticesBuilt[VAXISTOP] = Standard_True;
1200   }
1201   
1202   return myVertices[VAXISTOP];
1203 }
1204
1205 //=======================================================================
1206 //function : AxisBottomVertex
1207 //purpose  : 
1208 //=======================================================================
1209
1210 const TopoDS_Vertex& BRepPrim_OneAxis::AxisBottomVertex ()
1211 {
1212   // do it if not done
1213   if (!VerticesBuilt[VAXISBOT]) {
1214     
1215     // deduct from others
1216     if (MeridianOnAxis(myVMin) && VerticesBuilt[VBOTSTART])
1217       myVertices[VAXISBOT] = myVertices[VBOTSTART];
1218     
1219     else if (MeridianOnAxis(myVMin) && VerticesBuilt[VBOTEND])
1220       myVertices[VAXISBOT] = myVertices[VBOTEND];
1221     
1222     else {
1223       Standard_DomainError_Raise_if(MeridianClosed(),
1224                                     "BRepPrim_OneAxis::AxisBottomVertex");
1225       Standard_DomainError_Raise_if(VMinInfinite(),
1226                                     "BRepPrim_OneAxis::AxisBottomVertex");
1227       
1228       gp_Vec V = myAxes.Direction();
1229       V.Multiply(MeridianValue(myVMin).Y());
1230       gp_Pnt P = myAxes.Location().Translated(V);
1231       myBuilder.MakeVertex(myVertices[VAXISBOT],P);
1232     }      
1233     
1234     VerticesBuilt[VAXISBOT] = Standard_True;
1235   }
1236   
1237   return myVertices[VAXISBOT];
1238 }
1239
1240 //=======================================================================
1241 //function : TopStartVertex
1242 //purpose  : 
1243 //=======================================================================
1244
1245 const TopoDS_Vertex& BRepPrim_OneAxis::TopStartVertex ()
1246 {
1247   // do it if not done
1248   if (!VerticesBuilt[VTOPSTART]) {
1249
1250     // deduct from others
1251     if (MeridianOnAxis(myVMax) && VerticesBuilt[VAXISTOP])
1252       myVertices[VTOPSTART] = myVertices[VAXISTOP];
1253     else if ((MeridianOnAxis(myVMax) || !HasSides()) && VerticesBuilt[VTOPEND])
1254       myVertices[VTOPSTART] = myVertices[VTOPEND];
1255     else if (MeridianClosed() && VerticesBuilt[VBOTSTART])
1256       myVertices[VTOPSTART] = myVertices[VBOTSTART];
1257     else if ((MeridianClosed() && !HasSides()) && VerticesBuilt[VBOTEND])
1258       myVertices[VTOPSTART] = myVertices[VBOTEND];
1259     
1260     else{
1261       gp_Pnt2d mp = MeridianValue(myVMax);
1262       gp_Vec V = myAxes.Direction();
1263       V.Multiply(mp.Y());
1264       gp_Pnt P = myAxes.Location().Translated(V);
1265       V = myAxes.XDirection();
1266       V.Multiply(mp.X());
1267       P.Translate(V);
1268       myBuilder.MakeVertex(myVertices[VTOPSTART],P);
1269     }
1270       
1271     VerticesBuilt[VTOPSTART] = Standard_True;
1272   }
1273   
1274   return myVertices[VTOPSTART];
1275 }
1276
1277 //=======================================================================
1278 //function : TopEndVertex
1279 //purpose  : 
1280 //=======================================================================
1281
1282 const TopoDS_Vertex& BRepPrim_OneAxis::TopEndVertex ()
1283 {
1284   // do it if not done
1285   if (!VerticesBuilt[VTOPEND]) {
1286     
1287
1288     // deduct from others
1289     if (MeridianOnAxis(myVMax) && VerticesBuilt[VAXISTOP])
1290       myVertices[VTOPEND] = myVertices[VAXISTOP];
1291     else if ((MeridianOnAxis(myVMax) || !HasSides()) && VerticesBuilt[VTOPSTART])
1292       myVertices[VTOPEND] = myVertices[VTOPSTART];
1293     else if (MeridianClosed() && VerticesBuilt[VBOTEND])
1294       myVertices[VTOPEND] = myVertices[VBOTEND];
1295     else if ((MeridianClosed() && !HasSides()) && VerticesBuilt[VBOTSTART])
1296       myVertices[VTOPEND] = myVertices[VBOTSTART];
1297
1298     else {
1299       gp_Pnt2d mp = MeridianValue(myVMax);
1300       gp_Vec V = myAxes.Direction();
1301       V.Multiply(mp.Y());
1302       gp_Pnt P = myAxes.Location().Translated(V);
1303       V = myAxes.XDirection();
1304       V.Multiply(mp.X());
1305       P.Translate(V);
1306       P.Rotate(myAxes.Axis(),myAngle);
1307       myBuilder.MakeVertex(myVertices[VTOPEND],P);
1308     }
1309     
1310     VerticesBuilt[VTOPEND] = Standard_True;
1311   }
1312
1313   return myVertices[VTOPEND];
1314 }
1315
1316 //=======================================================================
1317 //function : BottomStartVertex
1318 //purpose  : 
1319 //=======================================================================
1320
1321 const TopoDS_Vertex& BRepPrim_OneAxis::BottomStartVertex ()
1322 {
1323   // do it if not done
1324   if (!VerticesBuilt[VBOTSTART]) {
1325     
1326     // deduct from others
1327     if (MeridianOnAxis(myVMin) && VerticesBuilt[VAXISBOT])
1328       myVertices[VBOTSTART] = myVertices[VAXISBOT];
1329     else if ((MeridianOnAxis(myVMin) || !HasSides()) && VerticesBuilt[VBOTEND])
1330       myVertices[VBOTSTART] = myVertices[VBOTEND];
1331     else if (MeridianClosed() && VerticesBuilt[VTOPSTART])
1332       myVertices[VBOTSTART] = myVertices[VTOPSTART];
1333     else if ((MeridianClosed() && !HasSides()) && VerticesBuilt[VTOPEND])
1334       myVertices[VBOTSTART] = myVertices[VTOPEND];
1335
1336     else {
1337       gp_Pnt2d mp = MeridianValue(myVMin);
1338       gp_Vec V = myAxes.Direction();
1339       V.Multiply(mp.Y());
1340       gp_Pnt P = myAxes.Location().Translated(V);
1341       V = myAxes.XDirection();
1342       V.Multiply(mp.X());
1343       P.Translate(V);
1344       myBuilder.MakeVertex(myVertices[VBOTSTART],P);
1345     }
1346     
1347     VerticesBuilt[VBOTSTART] = Standard_True;
1348   }
1349
1350   return myVertices[VBOTSTART];
1351 }
1352
1353 //=======================================================================
1354 //function : BottomEndVertex
1355 //purpose  : 
1356 //=======================================================================
1357
1358 const TopoDS_Vertex& BRepPrim_OneAxis::BottomEndVertex ()
1359 {
1360   // do it if not done
1361   if (!VerticesBuilt[VBOTEND]) {
1362     
1363     // deduct from others
1364     if (MeridianOnAxis(myVMin) && VerticesBuilt[VAXISBOT])
1365       myVertices[VBOTEND] = myVertices[VAXISBOT];
1366     else if ((MeridianOnAxis(myVMin) || !HasSides()) && VerticesBuilt[VBOTSTART])
1367       myVertices[VBOTEND] = myVertices[VBOTSTART];
1368     else if (MeridianClosed() && VerticesBuilt[VTOPEND])
1369       myVertices[VBOTEND] = myVertices[VTOPEND];
1370     else if (MeridianClosed() && !HasSides() && VerticesBuilt[VTOPSTART])
1371       myVertices[VBOTEND] = myVertices[VTOPSTART];
1372
1373     else {
1374       gp_Pnt2d mp = MeridianValue(myVMin);
1375       gp_Vec V = myAxes.Direction();
1376       V.Multiply(mp.Y());
1377       gp_Pnt P = myAxes.Location().Translated(V);
1378       V = myAxes.XDirection();
1379       V.Multiply(mp.X());
1380       P.Translate(V);
1381       P.Rotate(myAxes.Axis(),myAngle);
1382       myBuilder.MakeVertex(myVertices[VBOTEND],P);
1383     }
1384     
1385     VerticesBuilt[VBOTEND] = Standard_True;
1386   }
1387
1388   return myVertices[VBOTEND];
1389 }