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