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