0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / DsgPrs / DsgPrs.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <DsgPrs.hxx>
16
17 #include <Aspect_TypeOfLine.hxx>
18 #include <Aspect_TypeOfMarker.hxx>
19 #include <ElCLib.hxx>
20 #include <gce_MakeLin.hxx>
21 #include <Geom_Circle.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Line.hxx>
24 #include <Geom_Surface.hxx>
25 #include <GeomAPI_ExtremaCurveCurve.hxx>
26 #include <GeomAPI_ProjectPointOnCurve.hxx>
27 #include <GeomAPI_ProjectPointOnSurf.hxx>
28 #include <gp_Ax1.hxx>
29 #include <gp_Circ.hxx>
30 #include <gp_Dir.hxx>
31 #include <gp_Elips.hxx>
32 #include <gp_Pln.hxx>
33 #include <gp_Pnt.hxx>
34 #include <gp_Vec.hxx>
35 #include <Graphic3d_ArrayOfPoints.hxx>
36 #include <Graphic3d_AspectLine3d.hxx>
37 #include <Graphic3d_AspectMarker3d.hxx>
38 #include <Graphic3d_Group.hxx>
39 #include <Precision.hxx>
40 #include <Prs3d_Arrow.hxx>
41 #include <Prs3d_ArrowAspect.hxx>
42 #include <Prs3d_DimensionAspect.hxx>
43 #include <Prs3d_LineAspect.hxx>
44 #include <Prs3d_Presentation.hxx>
45 #include <Prs3d_Root.hxx>
46 #include <Quantity_Color.hxx>
47 #include <TCollection_AsciiString.hxx>
48 #include <TCollection_ExtendedString.hxx>
49
50 void DsgPrs::ComputeSymbol (const Handle(Prs3d_Presentation)& aPresentation,
51                             const Handle(Prs3d_DimensionAspect)& LA,
52                             const gp_Pnt& pt1,
53                             const gp_Pnt& pt2,
54                             const gp_Dir& dir1,
55                             const gp_Dir& dir2,
56                             const DsgPrs_ArrowSide ArrowSide,
57                             const Standard_Boolean drawFromCenter) 
58 {
59   Handle(Graphic3d_Group) aGroup = aPresentation->NewGroup();
60
61   Quantity_Color aColor = LA->LineAspect()->Aspect()->Color();
62   Handle(Graphic3d_AspectMarker3d) aMarkerAsp = new Graphic3d_AspectMarker3d (Aspect_TOM_O, aColor, 1.0);
63   aGroup->SetGroupPrimitivesAspect (LA->LineAspect()->Aspect());
64
65   switch(ArrowSide) {
66   case DsgPrs_AS_NONE:
67     {
68       break;
69     }
70   case DsgPrs_AS_FIRSTAR:
71     {
72       Prs3d_Arrow::Draw (aGroup,
73                     pt1,
74                     dir1,
75                     LA->ArrowAspect()->Angle(),
76                     LA->ArrowAspect()->Length());  
77       break;
78     }
79   case DsgPrs_AS_LASTAR:
80     {
81
82       Prs3d_Arrow::Draw (aGroup,
83                     pt2,
84                     dir2,
85                     LA->ArrowAspect()->Angle(),
86                     LA->ArrowAspect()->Length());  
87       break;
88     }
89
90   case DsgPrs_AS_BOTHAR:
91     {
92       Prs3d_Arrow::Draw (aGroup,
93                     pt1,
94                     dir1,
95                     LA->ArrowAspect()->Angle(),
96                     LA->ArrowAspect()->Length());  
97       Prs3d_Arrow::Draw (aGroup,
98                     pt2,
99                     dir2,
100                     LA->ArrowAspect()->Angle(),
101                     LA->ArrowAspect()->Length());  
102
103       break;
104     }
105
106   case DsgPrs_AS_FIRSTPT:
107     {
108       if(drawFromCenter)
109       {
110         Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
111         anArrayOfPoints->AddVertex (pt1.X(), pt1.Y(), pt1.Z());
112         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints);
113       }
114       break;
115     }
116
117   case DsgPrs_AS_LASTPT:
118     {
119       // On dessine un rond 
120       Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
121       anArrayOfPoints->AddVertex (pt2.X(), pt2.Y(), pt2.Z());
122       Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints);
123       break;
124     }
125
126   case DsgPrs_AS_BOTHPT:
127     {
128       if(drawFromCenter)
129       {
130         Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints1 = new Graphic3d_ArrayOfPoints (2);
131         anArrayOfPoints1->AddVertex (pt1.X(), pt1.Y(), pt1.Z());
132         anArrayOfPoints1->AddVertex (pt2.X(), pt2.Y(), pt2.Z());
133         aGroup->SetGroupPrimitivesAspect (aMarkerAsp);
134         aGroup->AddPrimitiveArray (anArrayOfPoints1);
135       }
136       break;
137     }
138
139   case DsgPrs_AS_FIRSTAR_LASTPT:
140     {
141       // an Arrow
142       Prs3d_Arrow::Draw (aGroup,
143                         pt1,
144                         dir1,
145                         LA->ArrowAspect()->Angle(),
146                         LA->ArrowAspect()->Length());
147       // a Round
148       Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
149       anArrayOfPoints->AddVertex (pt2.X(), pt2.Y(), pt2.Z());
150       aGroup->SetPrimitivesAspect (aMarkerAsp);
151       aGroup->AddPrimitiveArray (anArrayOfPoints);
152       break;
153     }
154
155   case DsgPrs_AS_FIRSTPT_LASTAR:
156     {
157       // an Arrow
158       Prs3d_Arrow::Draw (aGroup,
159                         pt2,
160                         dir2,
161                         LA->ArrowAspect()->Angle(),
162                         LA->ArrowAspect()->Length());
163
164       // a Round
165       if (drawFromCenter)
166       {
167         Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
168         anArrayOfPoints->AddVertex (pt1.X(), pt1.Y(), pt1.Z());
169         aGroup->SetPrimitivesAspect (aMarkerAsp);
170         aGroup->AddPrimitiveArray (anArrayOfPoints);
171       }
172       break;
173     }
174   }
175 }
176
177
178 //=======================================================================
179 //function : ComputePlanarFacesLengthPresentation
180 //purpose  : 
181 //=======================================================================
182
183 void DsgPrs::ComputePlanarFacesLengthPresentation( const Standard_Real FirstArrowLength,
184                                                    const Standard_Real SecondArrowLength,
185                                                    const gp_Pnt& AttachmentPoint1,
186                                                    const gp_Pnt& AttachmentPoint2,
187                                                    const gp_Dir& DirAttach,
188                                                    const gp_Pnt& OffsetPoint,
189                                                    const gp_Pln& PlaneOfFaces,
190                                                    gp_Pnt &        EndOfArrow1,
191                                                    gp_Pnt &        EndOfArrow2,
192                                                    gp_Dir &        DirOfArrow1 )
193 {
194   gp_Lin FirstLin( AttachmentPoint1, DirAttach );  
195   gp_Lin SecondLin( AttachmentPoint2, DirAttach );  
196   
197   EndOfArrow1 = ElCLib::Value( ElCLib::Parameter( FirstLin, OffsetPoint ), FirstLin );
198   EndOfArrow2 = ElCLib::Value( ElCLib::Parameter( SecondLin, OffsetPoint ), SecondLin );
199  
200   if (EndOfArrow1.SquareDistance( EndOfArrow2 ) > Precision::SquareConfusion()) // not null length
201     {
202       gp_Dir LengthDir( gp_Vec( EndOfArrow1, EndOfArrow2 ) );
203       if ((FirstArrowLength + SecondArrowLength)*(FirstArrowLength + SecondArrowLength) < 
204           EndOfArrow1.SquareDistance( EndOfArrow2 ))
205         DirOfArrow1 = -LengthDir;
206       else
207         DirOfArrow1 = LengthDir;
208     }
209   else // null length
210     DirOfArrow1 = PlaneOfFaces.Axis().Direction();
211 }
212
213 //=======================================================================
214 //function : ComputeCurvilinearFacesLengthPresentation
215 //purpose  : 
216 //=======================================================================
217
218 void DsgPrs::ComputeCurvilinearFacesLengthPresentation( const Standard_Real FirstArrowLength,
219                                                         const Standard_Real SecondArrowLength,
220                                                         const Handle( Geom_Surface )& SecondSurf,
221                                                         const gp_Pnt& AttachmentPoint1,
222                                                         const gp_Pnt& AttachmentPoint2,
223                                                         const gp_Dir& DirAttach,
224                                                         gp_Pnt &        EndOfArrow2,
225                                                         gp_Dir &        DirOfArrow1,
226                                                         Handle( Geom_Curve )& VCurve,
227                                                         Handle( Geom_Curve )& UCurve,
228                                                         Standard_Real & FirstU,
229                                                         Standard_Real & deltaU,
230                                                         Standard_Real & FirstV,
231                                                         Standard_Real & deltaV )
232 {
233   GeomAPI_ProjectPointOnSurf ProjectorOnSurface;
234   GeomAPI_ProjectPointOnCurve ProjectorOnCurve;
235   Standard_Real U1, V1, U2, V2;
236   Standard_Real LastU, LastV;
237   Standard_Real SquareTolerance = Precision::SquareConfusion();
238
239   ProjectorOnSurface.Init( AttachmentPoint1, SecondSurf );
240   Standard_Integer Index(1);
241   Standard_Real MinDist = RealLast();
242   Standard_Real LocalU, LocalV;
243   gp_Vec D1U, D1V;
244   gp_Dir LocalDir;
245   for (Standard_Integer i = 1; i <= ProjectorOnSurface.NbPoints(); i++)
246     {
247       ProjectorOnSurface.Parameters( i, LocalU, LocalV );
248
249       SecondSurf->D1( LocalU, LocalV, EndOfArrow2, D1U, D1V );
250       if (D1U.SquareMagnitude() <= SquareTolerance || D1V.SquareMagnitude() <= SquareTolerance)
251         LocalDir = gp_Dir( gp_Vec( AttachmentPoint1, ProjectorOnSurface.Point( i ) ) );
252       else
253         LocalDir = gp_Dir( D1U ^ D1V );
254       if (DirAttach.IsParallel( LocalDir, Precision::Angular() ) && ProjectorOnSurface.Distance( i ) < MinDist)
255         {
256           Index = i;
257           MinDist = ProjectorOnSurface.Distance( i );
258         }
259     }
260   EndOfArrow2 = ProjectorOnSurface.Point( Index );
261   ProjectorOnSurface.Parameters( Index, U1, V1 );
262   
263   if ((FirstArrowLength + SecondArrowLength)*(FirstArrowLength + SecondArrowLength) <
264       AttachmentPoint1.SquareDistance( EndOfArrow2 ))
265     DirOfArrow1 = -DirAttach;
266   else
267     DirOfArrow1 = DirAttach;
268
269   if (EndOfArrow2.SquareDistance( AttachmentPoint2 ) > Precision::SquareConfusion())
270     {
271       VCurve = SecondSurf->VIso( V1 );
272       ProjectorOnCurve.Init( EndOfArrow2, VCurve );
273       FirstU = ProjectorOnCurve.LowerDistanceParameter();
274
275       ProjectorOnSurface.Init( AttachmentPoint2, SecondSurf );
276       ProjectorOnSurface.LowerDistanceParameters( U2, V2 );
277       UCurve = SecondSurf->UIso( U2 );
278       
279       ProjectorOnCurve.Init( AttachmentPoint2, UCurve );
280       LastV = ProjectorOnCurve.LowerDistanceParameter();
281
282       gp_Pnt Intersection = SecondSurf->Value( U2, V1 );
283       ProjectorOnCurve.Init( Intersection, VCurve );
284       LastU = ProjectorOnCurve.LowerDistanceParameter();
285       ProjectorOnCurve.Init( Intersection, UCurve );
286       FirstV = ProjectorOnCurve.LowerDistanceParameter();
287
288       deltaU = LastU - FirstU;
289       deltaV = LastV - FirstV;
290
291       if (VCurve->IsPeriodic() && Abs( deltaU ) > VCurve->Period()/2)
292         {
293           Standard_Real Sign = (deltaU > 0.0)? -1.0 : 1.0;
294           deltaU = VCurve->Period() - Abs( deltaU );
295           deltaU *= Sign;
296         }
297       if (UCurve->IsPeriodic() && Abs( deltaV ) > UCurve->Period()/2)
298         {
299           Standard_Real Sign = (deltaV > 0.0)? -1.0 : 1.0;
300           deltaV = UCurve->Period() - Abs( deltaV );
301           deltaV *= Sign;
302         }
303     }
304 }
305
306
307 //=======================================================================
308 //function : ComputeFacesAnglePresentation
309 //purpose  : 
310 //=======================================================================
311
312 void DsgPrs::ComputeFacesAnglePresentation( const Standard_Real ArrowLength,
313                                             const Standard_Real Value,
314                                             const gp_Pnt& CenterPoint,
315                                             const gp_Pnt& AttachmentPoint1,
316                                             const gp_Pnt& AttachmentPoint2,
317                                             const gp_Dir& dir1,
318                                             const gp_Dir& dir2,
319                                             const gp_Dir& axisdir,
320                                             const Standard_Boolean isPlane,
321                                             const gp_Ax1& AxisOfSurf,
322                                             const gp_Pnt& OffsetPoint,
323                                             gp_Circ &       AngleCirc,
324                                             Standard_Real & FirstParAngleCirc,
325                                             Standard_Real & LastParAngleCirc,
326                                             gp_Pnt &        EndOfArrow1,
327                                             gp_Pnt &        EndOfArrow2,
328                                             gp_Dir &        DirOfArrow1,
329                                             gp_Dir &        DirOfArrow2,
330                                             gp_Pnt &        ProjAttachPoint2,
331                                             gp_Circ &       AttachCirc,
332                                             Standard_Real & FirstParAttachCirc,
333                                             Standard_Real & LastParAttachCirc )
334 {
335   if (Value > Precision::Angular() && Abs( M_PI-Value ) > Precision::Angular())
336     {
337       // Computing presentation of angle's arc
338       gp_Ax2 ax( CenterPoint, axisdir, dir1 );
339       AngleCirc.SetPosition( ax );
340       AngleCirc.SetRadius( CenterPoint.Distance( OffsetPoint ) );
341       gp_Vec vec1( dir1 );
342       vec1 *= AngleCirc.Radius();
343       gp_Pnt p1 = CenterPoint.Translated( vec1 );
344       gp_Vec vec2( dir2 );
345       vec2 *= AngleCirc.Radius();
346       gp_Pnt p2 = CenterPoint.Translated( vec2 );
347       
348       Standard_Real Par1 = 0.;
349       Standard_Real Par2 = ElCLib::Parameter( AngleCirc, p2 );
350       Standard_Real Par0 = ElCLib::Parameter( AngleCirc, OffsetPoint );
351       
352       gp_Vec PosVec( CenterPoint, OffsetPoint );
353       gp_Vec NormalOfPlane = vec1 ^ vec2;
354       
355       gp_Vec Normal1 = NormalOfPlane ^ vec1;
356       gp_Vec Normal2 = NormalOfPlane ^ vec2;
357       Standard_Integer Sign1 = (PosVec * Normal1 >= 0)? 1 : -1;
358       Standard_Integer Sign2 = (PosVec * Normal2 >= 0)? 1 : -1;
359       if (Sign1 == 1 && Sign2 == -1)
360         {
361           FirstParAngleCirc = Par1;
362           LastParAngleCirc  = Par2;
363         }
364       else if (Sign1 == 1 && Sign2 == 1)
365         { 
366           FirstParAngleCirc = Par1;
367           LastParAngleCirc  = Par0;
368         }
369       else if (Sign1 == -1 && Sign2 == 1)
370         {
371           Par1 += M_PI;
372           Par2 += M_PI;
373           FirstParAngleCirc = Par1;
374           LastParAngleCirc  = Par2;
375         }
376       else //Sign1 == -1 && Sign2 == -1
377         {
378           AngleCirc.SetPosition( gp_Ax2( CenterPoint, axisdir, gp_Dir( PosVec ) ) );
379           Par0 = 0.;
380           Par1 = ElCLib::Parameter( AngleCirc, p1 );
381           Par2 = ElCLib::Parameter( AngleCirc, p2 );
382           FirstParAngleCirc = Par0;
383           LastParAngleCirc  = Par2;
384         }
385
386       // Computing presentation of arrows
387       EndOfArrow1 = ElCLib::Value( Par1, AngleCirc );
388       EndOfArrow2  = ElCLib::Value( Par2, AngleCirc );
389       Standard_Real beta = 0.;
390       if (AngleCirc.Radius() > Precision::Confusion())
391         beta = ArrowLength / AngleCirc.Radius();
392       gp_Pnt OriginOfArrow1 = ElCLib::Value( Par1 + beta, AngleCirc );
393       gp_Pnt OriginOfArrow2 = ElCLib::Value( Par2 - beta, AngleCirc );
394       DirOfArrow1 = gp_Dir( gp_Vec( OriginOfArrow1, EndOfArrow1 ) );
395       DirOfArrow2 = gp_Dir( gp_Vec( OriginOfArrow2, EndOfArrow2 ) );
396       if (EndOfArrow1.SquareDistance( EndOfArrow2 ) <= (ArrowLength + ArrowLength)*(ArrowLength + ArrowLength))
397         {
398           DirOfArrow1.Reverse();
399           DirOfArrow2.Reverse();
400         }
401     }
402   else // dir1 and dir2 are parallel
403     {
404       gp_Dir ArrowDir = axisdir ^ dir1;
405       DirOfArrow1 = ArrowDir;
406       DirOfArrow2 = -ArrowDir;
407       gp_Lin DirLine( AttachmentPoint1, dir1 );
408       EndOfArrow1 = ElCLib::Value( ElCLib::Parameter( DirLine, OffsetPoint ), DirLine );
409       EndOfArrow2 = EndOfArrow1;
410     }
411
412   // Line or arc from AttachmentPoint2 to its "projection"
413   gp_Lin SecondLin( CenterPoint, dir2 );
414   if (SecondLin.Contains( AttachmentPoint2, Precision::Confusion() ))
415     ProjAttachPoint2 = AttachmentPoint2;
416   else
417     {
418       if (isPlane)
419         ProjAttachPoint2 = ElCLib::Value( ElCLib::Parameter( SecondLin, AttachmentPoint2 ), SecondLin );
420       else
421         {
422           gp_Lin LineOfAxis( AxisOfSurf );
423           gp_Pnt CenterOfArc = ElCLib::Value( ElCLib::Parameter( LineOfAxis, AttachmentPoint2 ),
424                                               LineOfAxis );
425           
426           gp_Ax2 Ax2( CenterOfArc,
427                       AxisOfSurf.Direction(),
428                       gp_Dir( gp_Vec( CenterOfArc, AttachmentPoint2 ) ) );
429           AttachCirc.SetPosition( Ax2 );
430           AttachCirc.SetRadius( CenterOfArc.Distance( AttachmentPoint2 ) );
431           
432           GeomAPI_ExtremaCurveCurve Intersection( new Geom_Circle( AttachCirc ),
433                                                   new Geom_Line( SecondLin ) );
434           Intersection.NearestPoints( ProjAttachPoint2, ProjAttachPoint2 );
435           
436           Standard_Real U2 = ElCLib::Parameter( AttachCirc, ProjAttachPoint2 );
437           if (U2 <= M_PI)
438             {
439               FirstParAttachCirc = 0;
440               LastParAttachCirc  = U2;
441             }
442           else
443             {
444               FirstParAttachCirc = U2;
445               LastParAttachCirc  = 2*M_PI;
446             }
447         }
448     }
449 }
450
451
452
453 void DsgPrs::ComputeFilletRadiusPresentation( const Standard_Real /*ArrowLength*/,
454                                               const Standard_Real Value,
455                                               const gp_Pnt &      Position,
456                                               const gp_Dir &      NormalDir,
457                                               const gp_Pnt &      FirstPoint,
458                                               const gp_Pnt &      SecondPoint,
459                                               const gp_Pnt &      Center,
460                                               const gp_Pnt &      BasePnt,
461                                               const Standard_Boolean drawRevers,
462                                               Standard_Boolean &  SpecCase,
463                                               gp_Circ &           FilletCirc,
464                                               Standard_Real &     FirstParCirc,
465                                               Standard_Real &     LastParCirc,
466                                               gp_Pnt &            EndOfArrow,
467                                               gp_Dir &            DirOfArrow,
468                                               gp_Pnt &            DrawPosition)
469 {
470   gp_Dir dir1(gp_Vec(Center, FirstPoint));
471   gp_Dir dir2(gp_Vec(Center, SecondPoint));
472   Standard_Real Angle = dir1.Angle(dir2);
473   if(Angle <= Precision::Angular() || ( M_PI - Angle ) <= Precision::Angular() ||
474      Value <= Precision::Confusion()) SpecCase = Standard_True;
475   else SpecCase = Standard_False;
476   if ( !SpecCase )
477     {
478        // Computing presentation of fillet's arc
479       gp_Ax2 ax( Center, NormalDir, dir1 );
480       FilletCirc.SetPosition( ax );
481       FilletCirc.SetRadius( Center.Distance( FirstPoint ) ); //***
482       gp_Vec vec1( dir1 );
483       vec1 *= FilletCirc.Radius();
484       gp_Vec vec2( dir2 );
485       vec2 *= FilletCirc.Radius();
486       gp_Vec PosVec;
487       if(! Center.IsEqual( Position, Precision::Confusion() ))
488         PosVec.SetXYZ( gp_Vec(Center, Position).XYZ() );
489       else
490         PosVec.SetXYZ( (vec1.Added(vec2)).XYZ() );
491       gp_Vec NormalOfPlane = vec1 ^ vec2;      
492       gp_Vec Normal1 = NormalOfPlane ^ vec1;
493       gp_Vec Normal2 = NormalOfPlane ^ vec2;
494       Standard_Integer Sign1 = (PosVec * Normal1 >= 0)? 1 : -1;
495       Standard_Integer Sign2 = (PosVec * Normal2 >= 0)? 1 : -1;
496       gp_Lin L1( Center, dir1 );
497       gp_Lin L2( Center, dir2 );
498       if ( Sign1 != Sign2 )
499         {
500           DrawPosition = Position; //***
501           gp_Dir direction(PosVec) ;
502           Standard_Real angle = dir1.Angle(direction) ;
503           if (( dir1 ^ direction) * NormalDir < 0.0e0)   angle = -angle ;
504           if(Sign1 == -1) angle += M_PI;
505           EndOfArrow = ElCLib::Value(angle, FilletCirc); //***
506                    
507         }
508       else
509         {
510           if(L1.Distance(Position) < L2.Distance(Position))
511               {
512                 EndOfArrow = FirstPoint; //***
513                 DrawPosition =  ElCLib::Value(ElCLib::Parameter(L1, Position), L1);     
514               }
515           else
516             {
517               EndOfArrow = SecondPoint; //***
518               DrawPosition = ElCLib::Value(ElCLib::Parameter(L2, Position), L2);
519             }
520         }
521       if((dir1^dir2).IsOpposite(NormalDir, Precision::Angular()))
522         {
523           gp_Dir newdir = NormalDir.Reversed() ;
524           gp_Ax2 axnew( Center, newdir, dir1 );
525           FilletCirc.SetPosition( axnew );
526         }
527       FirstParCirc = ElCLib::Parameter( FilletCirc, FirstPoint );
528       LastParCirc  = ElCLib::Parameter( FilletCirc, SecondPoint );
529     }
530   else //Angle equal 0 or PI or R = 0
531     {
532       DrawPosition = Position;
533       EndOfArrow   = BasePnt;
534     }
535
536   if(drawRevers)
537     {
538       gp_Vec Vd(DrawPosition, EndOfArrow);
539       DrawPosition.Translate(Vd *2);
540     }
541   DirOfArrow.SetXYZ(gp_Dir(gp_Vec(DrawPosition, EndOfArrow)).XYZ());      
542 }
543
544 //=======================================================================
545 //function : ComputeRadiusLine
546 //purpose  : 
547 //=======================================================================
548
549 void DsgPrs::ComputeRadiusLine(const gp_Pnt & aCenter,
550                                const gp_Pnt & anEndOfArrow,
551                                const gp_Pnt & aPosition,
552                                const Standard_Boolean drawFromCenter,
553                                      gp_Pnt & aRadLineOrign,
554                                      gp_Pnt & aRadLineEnd)
555 {
556   if(drawFromCenter)
557     {
558       gp_Lin RadiusLine = gce_MakeLin( aCenter, anEndOfArrow );
559       Standard_Real PosParOnLine = ElCLib::Parameter( RadiusLine, aPosition );
560       Standard_Real EndOfArrowPar     = ElCLib::Parameter( RadiusLine, anEndOfArrow );
561       if (PosParOnLine < 0.0)
562         {
563           aRadLineOrign = aPosition;
564           aRadLineEnd   = anEndOfArrow;
565         }
566       else if (PosParOnLine > EndOfArrowPar)
567         {
568           aRadLineOrign = aPosition;
569           aRadLineEnd   = aCenter;
570         }
571       else
572         {
573           aRadLineOrign = aCenter;
574           aRadLineEnd   = anEndOfArrow;
575         }
576     }
577   else
578     {
579       aRadLineOrign = aPosition;
580       aRadLineEnd   = anEndOfArrow;
581     }
582 }
583
584
585 //=======================================================================
586 //function : DistanceFromApex
587 //purpose  : 
588 //=======================================================================
589
590 Standard_Real DsgPrs::DistanceFromApex(const gp_Elips & elips,
591                                        const gp_Pnt   & Apex,
592                                        const Standard_Real par)
593 {
594   Standard_Real dist;
595   Standard_Real parApex = ElCLib::Parameter ( elips, Apex );
596   if(parApex == 0.0 || parApex == M_PI) 
597     {//Major case
598       if(parApex == 0.0) //pos Apex
599         dist = (par < M_PI) ? par : (2*M_PI - par);
600       else //neg Apex
601         dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI );
602     }
603   else 
604     {// Minor case
605       if(parApex == M_PI / 2) //pos Apex
606         {
607           if(par <= parApex + M_PI && par > parApex )
608             dist = par - parApex;
609           else 
610             { 
611               if(par >  parApex + M_PI)
612                 dist = 2*M_PI - par + parApex;
613               else
614                 dist = parApex - par; // 0 < par < M_PI/2
615             }
616         }
617       else //neg Apex == 3/2 PI
618         {
619           if(par <= parApex && par >= M_PI/2) 
620             dist = parApex - par;
621           else
622             {
623               if(par >  parApex) 
624                 dist = par - parApex;
625               else
626                 dist = par + M_PI/2; // 0 < par < PI/2
627             }
628         }
629     }
630   return dist;
631 }