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