0023404: Create SquareConfusion function in Precision package for speed and convenience
[occt.git] / src / DsgPrs / DsgPrs.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <DsgPrs.ixx>
20
21 #include <TCollection_AsciiString.hxx>
22 #include <TCollection_ExtendedString.hxx>
23 #include <Prs3d_Arrow.hxx>
24 #include <Prs3d_Root.hxx>
25 #include <Prs3d_LineAspect.hxx>
26 #include <Prs3d_ArrowAspect.hxx>
27
28 #include <Graphic3d_Group.hxx>
29 #include <Graphic3d_Vertex.hxx>
30 #include <Graphic3d_AspectMarker3d.hxx>
31 #include <Graphic3d_AspectLine3d.hxx>
32 #include <Aspect_TypeOfLine.hxx>
33 #include <Aspect_TypeOfMarker.hxx>
34 #include <Aspect_AspectMarker.hxx>
35 #include <Quantity_Color.hxx>
36
37 #include <Precision.hxx>
38 #include <ElCLib.hxx>
39
40 #include <gp_Vec.hxx>
41 #include <Geom_Line.hxx>
42 #include <Geom_Circle.hxx>
43 #include <GeomAPI_ExtremaCurveCurve.hxx>
44 #include <GeomAPI_ProjectPointOnSurf.hxx>
45 #include <GeomAPI_ProjectPointOnCurve.hxx>
46
47 #include <gce_MakeLin.hxx>
48
49
50 void DsgPrs::ComputeSymbol (const Handle(Prs3d_Presentation)& aPresentation,
51                             const Handle(Prs3d_AngleAspect)& 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 {
58   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
59   
60   Handle(Graphic3d_AspectMarker3d) MarkerAsp = new Graphic3d_AspectMarker3d();
61   MarkerAsp->SetType(Aspect_TOM_BALL);
62   MarkerAsp->SetScale(0.8);
63   Quantity_Color acolor;
64   Aspect_TypeOfLine atype;
65   Standard_Real awidth;
66   LA->LineAspect()->Aspect()->Values(acolor, atype, awidth);
67   MarkerAsp->SetColor(acolor);
68   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(MarkerAsp);
69
70   // symbols aux extremites de la cote
71 //  Graphic3d_Vertex V3d,V3d1,V3d2;
72   Graphic3d_Vertex V3d,V3d1;
73
74   switch(ArrowSide) {
75   case DsgPrs_AS_NONE:
76     {
77       break;
78     }
79   case DsgPrs_AS_FIRSTAR:
80     {
81
82       Prs3d_Arrow::Draw(aPresentation,
83                     pt1,
84                     dir1,
85                     LA->ArrowAspect()->Angle(),
86                     LA->ArrowAspect()->Length());  
87       break;
88     }
89   case DsgPrs_AS_LASTAR:
90     {
91
92       Prs3d_Arrow::Draw(aPresentation,
93                     pt2,
94                     dir2,
95                     LA->ArrowAspect()->Angle(),
96                     LA->ArrowAspect()->Length());  
97       break;
98     }
99
100   case DsgPrs_AS_BOTHAR:
101     {
102       Prs3d_Arrow::Draw(aPresentation,
103                     pt1,
104                     dir1,
105                     LA->ArrowAspect()->Angle(),
106                     LA->ArrowAspect()->Length());  
107       Prs3d_Arrow::Draw(aPresentation,
108                     pt2,
109                     dir2,
110                     LA->ArrowAspect()->Angle(),
111                     LA->ArrowAspect()->Length());  
112
113       break;
114     }
115
116   case DsgPrs_AS_FIRSTPT:
117     {
118       V3d = Graphic3d_Vertex (pt1.X(), pt1.Y(), pt1.Z());
119       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
120
121       break;
122     }
123
124   case DsgPrs_AS_LASTPT:
125     {
126       // On dessine un rond 
127       V3d = Graphic3d_Vertex (pt2.X(), pt2.Y(), pt2.Z());
128       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
129
130       break;
131     }
132
133   case DsgPrs_AS_BOTHPT:
134     {
135       V3d1 = Graphic3d_Vertex (pt1.X(), pt1.Y(), pt1.Z());
136       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d1);
137       Graphic3d_Vertex V3d2(pt2.X(), pt2.Y(), pt2.Z());
138       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d2);
139
140       break;
141     }
142
143   case DsgPrs_AS_FIRSTAR_LASTPT:
144     {
145       // an Arrow
146       Prs3d_Arrow::Draw(aPresentation,
147                         pt1,
148                         dir1,
149                         LA->ArrowAspect()->Angle(),
150                         LA->ArrowAspect()->Length());
151       // a Round
152       V3d = Graphic3d_Vertex (pt2.X(), pt2.Y(), pt2.Z());
153       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
154       
155       break;
156     }
157
158   case DsgPrs_AS_FIRSTPT_LASTAR:
159     {
160       // a Round
161       V3d = Graphic3d_Vertex (pt1.X(), pt1.Y(), pt1.Z());
162       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
163
164       // an Arrow
165       Prs3d_Arrow::Draw(aPresentation,
166                         pt2,
167                         dir2,
168                         LA->ArrowAspect()->Angle(),
169                         LA->ArrowAspect()->Length());  
170    
171       break;
172     }
173   }
174 }
175
176 void DsgPrs::ComputeSymbol (const Handle(Prs3d_Presentation)& aPresentation,
177                             const Handle(Prs3d_LengthAspect)& LA,
178                             const gp_Pnt& pt1,
179                             const gp_Pnt& pt2,
180                             const gp_Dir& dir1,
181                             const gp_Dir& dir2,
182                             const DsgPrs_ArrowSide ArrowSide,
183                             const Standard_Boolean drawFromCenter) 
184 {
185   Quantity_Color acolor;
186   Aspect_TypeOfLine atype;
187   Standard_Real awidth;
188   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
189   LA->LineAspect()->Aspect()->Values(acolor, atype, awidth);
190   Handle(Graphic3d_AspectMarker3d) MarkerAsp = new Graphic3d_AspectMarker3d();
191   MarkerAsp->SetType(Aspect_TOM_BALL);
192   MarkerAsp->SetScale(0.8);
193   MarkerAsp->SetColor(acolor);
194   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(MarkerAsp);
195   // symbols aux extremites de la cote
196 //  Graphic3d_Vertex V3d,V3d1,V3d2;
197   Graphic3d_Vertex V3d,V3d1;
198
199   switch(ArrowSide) {
200   case DsgPrs_AS_NONE:
201     {
202       break;
203     }
204   case DsgPrs_AS_FIRSTAR:
205     {
206
207       Prs3d_Arrow::Draw(aPresentation,
208                     pt1,
209                     dir1,
210                     LA->Arrow1Aspect()->Angle(),
211                     LA->Arrow1Aspect()->Length());  
212       break;
213     }
214   case DsgPrs_AS_LASTAR:
215     {
216
217       Prs3d_Arrow::Draw(aPresentation,
218                     pt2,
219                     dir2,
220                     LA->Arrow1Aspect()->Angle(),
221                     LA->Arrow1Aspect()->Length());  
222       break;
223     }
224
225   case DsgPrs_AS_BOTHAR:
226     {
227       Prs3d_Arrow::Draw(aPresentation,
228                     pt1,
229                     dir1,
230                     LA->Arrow1Aspect()->Angle(),
231                     LA->Arrow1Aspect()->Length());  
232       Prs3d_Arrow::Draw(aPresentation,
233                     pt2,
234                     dir2,
235                     LA->Arrow1Aspect()->Angle(),
236                     LA->Arrow1Aspect()->Length());  
237
238       break;
239     }
240
241   case DsgPrs_AS_FIRSTPT:
242     {
243       V3d = Graphic3d_Vertex (pt1.X(), pt1.Y(), pt1.Z());
244       if(drawFromCenter)
245         Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
246
247       break;
248     }
249
250   case DsgPrs_AS_LASTPT:
251     {
252       // On dessine un rond 
253       V3d = Graphic3d_Vertex (pt2.X(), pt2.Y(), pt2.Z());
254       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
255
256       break;
257     }
258
259   case DsgPrs_AS_BOTHPT:
260     {
261       V3d1 = Graphic3d_Vertex (pt1.X(), pt1.Y(), pt1.Z());
262       if(drawFromCenter)
263         Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d1);
264       Graphic3d_Vertex V3d2(pt2.X(), pt2.Y(), pt2.Z());
265       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d2);
266       
267       break;
268     }
269
270   case DsgPrs_AS_FIRSTAR_LASTPT:
271     {
272       // an Arrow
273       Prs3d_Arrow::Draw (aPresentation,
274                          pt1,
275                          dir1,
276                          LA->Arrow1Aspect()->Angle(),
277                          LA->Arrow1Aspect()->Length());
278       // a Round
279       V3d = Graphic3d_Vertex (pt2.X(), pt2.Y(), pt2.Z());
280       Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
281       
282       break;
283     }
284
285   case DsgPrs_AS_FIRSTPT_LASTAR:
286     {
287       // a Round
288       V3d = Graphic3d_Vertex (pt1.X(), pt1.Y(), pt1.Z());
289       if(drawFromCenter)
290         Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
291       // an Arrow
292       Prs3d_Arrow::Draw (aPresentation,
293                          pt2,
294                          dir2,
295                          LA->Arrow1Aspect()->Angle(),
296                          LA->Arrow1Aspect()->Length());  
297       break;
298     }
299   }
300 }
301
302
303 //=======================================================================
304 //function : ComputePlanarFacesLengthPresentation
305 //purpose  : 
306 //=======================================================================
307
308 void DsgPrs::ComputePlanarFacesLengthPresentation( const Standard_Real FirstArrowLength,
309                                                    const Standard_Real SecondArrowLength,
310                                                    const gp_Pnt& AttachmentPoint1,
311                                                    const gp_Pnt& AttachmentPoint2,
312                                                    const gp_Dir& DirAttach,
313                                                    const gp_Pnt& OffsetPoint,
314                                                    const gp_Pln& PlaneOfFaces,
315                                                    gp_Pnt &        EndOfArrow1,
316                                                    gp_Pnt &        EndOfArrow2,
317                                                    gp_Dir &        DirOfArrow1 )
318 {
319   gp_Lin FirstLin( AttachmentPoint1, DirAttach );  
320   gp_Lin SecondLin( AttachmentPoint2, DirAttach );  
321   
322   EndOfArrow1 = ElCLib::Value( ElCLib::Parameter( FirstLin, OffsetPoint ), FirstLin );
323   EndOfArrow2 = ElCLib::Value( ElCLib::Parameter( SecondLin, OffsetPoint ), SecondLin );
324  
325   if (EndOfArrow1.SquareDistance( EndOfArrow2 ) > Precision::SquareConfusion()) // not null length
326     {
327       gp_Dir LengthDir( gp_Vec( EndOfArrow1, EndOfArrow2 ) );
328       if ((FirstArrowLength + SecondArrowLength)*(FirstArrowLength + SecondArrowLength) < 
329           EndOfArrow1.SquareDistance( EndOfArrow2 ))
330         DirOfArrow1 = -LengthDir;
331       else
332         DirOfArrow1 = LengthDir;
333     }
334   else // null length
335     DirOfArrow1 = PlaneOfFaces.Axis().Direction();
336 }
337
338 //=======================================================================
339 //function : ComputeCurvilinearFacesLengthPresentation
340 //purpose  : 
341 //=======================================================================
342
343 void DsgPrs::ComputeCurvilinearFacesLengthPresentation( const Standard_Real FirstArrowLength,
344                                                         const Standard_Real SecondArrowLength,
345                                                         const Handle( Geom_Surface )& SecondSurf,
346                                                         const gp_Pnt& AttachmentPoint1,
347                                                         const gp_Pnt& AttachmentPoint2,
348                                                         const gp_Dir& DirAttach,
349                                                         gp_Pnt &        EndOfArrow2,
350                                                         gp_Dir &        DirOfArrow1,
351                                                         Handle( Geom_Curve )& VCurve,
352                                                         Handle( Geom_Curve )& UCurve,
353                                                         Standard_Real & FirstU,
354                                                         Standard_Real & deltaU,
355                                                         Standard_Real & FirstV,
356                                                         Standard_Real & deltaV )
357 {
358   GeomAPI_ProjectPointOnSurf ProjectorOnSurface;
359   GeomAPI_ProjectPointOnCurve ProjectorOnCurve;
360   Quantity_Parameter U1, V1, U2, V2;
361   Standard_Real LastU, LastV;
362   Standard_Real SquareTolerance = Precision::SquareConfusion();
363
364   ProjectorOnSurface.Init( AttachmentPoint1, SecondSurf );
365   Standard_Integer Index(1);
366   Quantity_Length MinDist = RealLast();
367   Quantity_Parameter LocalU, LocalV;
368   gp_Vec D1U, D1V;
369   gp_Dir LocalDir;
370   for (Standard_Integer i = 1; i <= ProjectorOnSurface.NbPoints(); i++)
371     {
372       ProjectorOnSurface.Parameters( i, LocalU, LocalV );
373
374       SecondSurf->D1( LocalU, LocalV, EndOfArrow2, D1U, D1V );
375       if (D1U.SquareMagnitude() <= SquareTolerance || D1V.SquareMagnitude() <= SquareTolerance)
376         LocalDir = gp_Dir( gp_Vec( AttachmentPoint1, ProjectorOnSurface.Point( i ) ) );
377       else
378         LocalDir = gp_Dir( D1U ^ D1V );
379       if (DirAttach.IsParallel( LocalDir, Precision::Angular() ) && ProjectorOnSurface.Distance( i ) < MinDist)
380         {
381           Index = i;
382           MinDist = ProjectorOnSurface.Distance( i );
383         }
384     }
385   EndOfArrow2 = ProjectorOnSurface.Point( Index );
386   ProjectorOnSurface.Parameters( Index, U1, V1 );
387   
388   if ((FirstArrowLength + SecondArrowLength)*(FirstArrowLength + SecondArrowLength) <
389       AttachmentPoint1.SquareDistance( EndOfArrow2 ))
390     DirOfArrow1 = -DirAttach;
391   else
392     DirOfArrow1 = DirAttach;
393
394   if (EndOfArrow2.SquareDistance( AttachmentPoint2 ) > Precision::SquareConfusion())
395     {
396       VCurve = SecondSurf->VIso( V1 );
397       ProjectorOnCurve.Init( EndOfArrow2, VCurve );
398       FirstU = ProjectorOnCurve.LowerDistanceParameter();
399
400       ProjectorOnSurface.Init( AttachmentPoint2, SecondSurf );
401       ProjectorOnSurface.LowerDistanceParameters( U2, V2 );
402       UCurve = SecondSurf->UIso( U2 );
403       
404       ProjectorOnCurve.Init( AttachmentPoint2, UCurve );
405       LastV = ProjectorOnCurve.LowerDistanceParameter();
406
407       gp_Pnt Intersection = SecondSurf->Value( U2, V1 );
408       ProjectorOnCurve.Init( Intersection, VCurve );
409       LastU = ProjectorOnCurve.LowerDistanceParameter();
410       ProjectorOnCurve.Init( Intersection, UCurve );
411       FirstV = ProjectorOnCurve.LowerDistanceParameter();
412
413       deltaU = LastU - FirstU;
414       deltaV = LastV - FirstV;
415
416       if (VCurve->IsPeriodic() && Abs( deltaU ) > VCurve->Period()/2)
417         {
418           Standard_Real Sign = (deltaU > 0.0)? -1.0 : 1.0;
419           deltaU = VCurve->Period() - Abs( deltaU );
420           deltaU *= Sign;
421         }
422       if (UCurve->IsPeriodic() && Abs( deltaV ) > UCurve->Period()/2)
423         {
424           Standard_Real Sign = (deltaV > 0.0)? -1.0 : 1.0;
425           deltaV = UCurve->Period() - Abs( deltaV );
426           deltaV *= Sign;
427         }
428     }
429 }
430
431
432 //=======================================================================
433 //function : ComputeFacesAnglePresentation
434 //purpose  : 
435 //=======================================================================
436
437 void DsgPrs::ComputeFacesAnglePresentation( const Standard_Real ArrowLength,
438                                             const Standard_Real Value,
439                                             const gp_Pnt& CenterPoint,
440                                             const gp_Pnt& AttachmentPoint1,
441                                             const gp_Pnt& AttachmentPoint2,
442                                             const gp_Dir& dir1,
443                                             const gp_Dir& dir2,
444                                             const gp_Dir& axisdir,
445                                             const Standard_Boolean isPlane,
446                                             const gp_Ax1& AxisOfSurf,
447                                             const gp_Pnt& OffsetPoint,
448                                             gp_Circ &       AngleCirc,
449                                             Standard_Real & FirstParAngleCirc,
450                                             Standard_Real & LastParAngleCirc,
451                                             gp_Pnt &        EndOfArrow1,
452                                             gp_Pnt &        EndOfArrow2,
453                                             gp_Dir &        DirOfArrow1,
454                                             gp_Dir &        DirOfArrow2,
455                                             gp_Pnt &        ProjAttachPoint2,
456                                             gp_Circ &       AttachCirc,
457                                             Standard_Real & FirstParAttachCirc,
458                                             Standard_Real & LastParAttachCirc )
459 {
460   if (Value > Precision::Angular() && Abs( M_PI-Value ) > Precision::Angular())
461     {
462       // Computing presentation of angle's arc
463       gp_Ax2 ax( CenterPoint, axisdir, dir1 );
464       AngleCirc.SetPosition( ax );
465       AngleCirc.SetRadius( CenterPoint.Distance( OffsetPoint ) );
466       gp_Vec vec1( dir1 );
467       vec1 *= AngleCirc.Radius();
468       gp_Pnt p1 = CenterPoint.Translated( vec1 );
469       gp_Vec vec2( dir2 );
470       vec2 *= AngleCirc.Radius();
471       gp_Pnt p2 = CenterPoint.Translated( vec2 );
472       
473       Standard_Real Par1 = 0.;
474       Standard_Real Par2 = ElCLib::Parameter( AngleCirc, p2 );
475       Standard_Real Par0 = ElCLib::Parameter( AngleCirc, OffsetPoint );
476       
477       gp_Vec PosVec( CenterPoint, OffsetPoint );
478       gp_Vec NormalOfPlane = vec1 ^ vec2;
479       
480       gp_Vec Normal1 = NormalOfPlane ^ vec1;
481       gp_Vec Normal2 = NormalOfPlane ^ vec2;
482       Standard_Integer Sign1 = (PosVec * Normal1 >= 0)? 1 : -1;
483       Standard_Integer Sign2 = (PosVec * Normal2 >= 0)? 1 : -1;
484       if (Sign1 == 1 && Sign2 == -1)
485         {
486           FirstParAngleCirc = Par1;
487           LastParAngleCirc  = Par2;
488         }
489       else if (Sign1 == 1 && Sign2 == 1)
490         { 
491           FirstParAngleCirc = Par1;
492           LastParAngleCirc  = Par0;
493         }
494       else if (Sign1 == -1 && Sign2 == 1)
495         {
496           Par1 += M_PI;
497           Par2 += M_PI;
498           FirstParAngleCirc = Par1;
499           LastParAngleCirc  = Par2;
500         }
501       else //Sign1 == -1 && Sign2 == -1
502         {
503           AngleCirc.SetPosition( gp_Ax2( CenterPoint, axisdir, gp_Dir( PosVec ) ) );
504           Par0 = 0.;
505           Par1 = ElCLib::Parameter( AngleCirc, p1 );
506           Par2 = ElCLib::Parameter( AngleCirc, p2 );
507           FirstParAngleCirc = Par0;
508           LastParAngleCirc  = Par2;
509         }
510
511       // Computing presentation of arrows
512       EndOfArrow1 = ElCLib::Value( Par1, AngleCirc );
513       EndOfArrow2  = ElCLib::Value( Par2, AngleCirc );
514       Standard_Real beta = 0.;
515       if (AngleCirc.Radius() > Precision::Confusion())
516         beta = ArrowLength / AngleCirc.Radius();
517       gp_Pnt OriginOfArrow1 = ElCLib::Value( Par1 + beta, AngleCirc );
518       gp_Pnt OriginOfArrow2 = ElCLib::Value( Par2 - beta, AngleCirc );
519       DirOfArrow1 = gp_Dir( gp_Vec( OriginOfArrow1, EndOfArrow1 ) );
520       DirOfArrow2 = gp_Dir( gp_Vec( OriginOfArrow2, EndOfArrow2 ) );
521       if (EndOfArrow1.SquareDistance( EndOfArrow2 ) <= (ArrowLength + ArrowLength)*(ArrowLength + ArrowLength))
522         {
523           DirOfArrow1.Reverse();
524           DirOfArrow2.Reverse();
525         }
526     }
527   else // dir1 and dir2 are parallel
528     {
529       gp_Dir ArrowDir = axisdir ^ dir1;
530       DirOfArrow1 = ArrowDir;
531       DirOfArrow2 = -ArrowDir;
532       gp_Lin DirLine( AttachmentPoint1, dir1 );
533       EndOfArrow1 = ElCLib::Value( ElCLib::Parameter( DirLine, OffsetPoint ), DirLine );
534       EndOfArrow2 = EndOfArrow1;
535     }
536
537   // Line or arc from AttachmentPoint2 to its "projection"
538   gp_Lin SecondLin( CenterPoint, dir2 );
539   if (SecondLin.Contains( AttachmentPoint2, Precision::Confusion() ))
540     ProjAttachPoint2 = AttachmentPoint2;
541   else
542     {
543       if (isPlane)
544         ProjAttachPoint2 = ElCLib::Value( ElCLib::Parameter( SecondLin, AttachmentPoint2 ), SecondLin );
545       else
546         {
547           gp_Lin LineOfAxis( AxisOfSurf );
548           gp_Pnt CenterOfArc = ElCLib::Value( ElCLib::Parameter( LineOfAxis, AttachmentPoint2 ),
549                                               LineOfAxis );
550           
551           gp_Ax2 Ax2( CenterOfArc,
552                       AxisOfSurf.Direction(),
553                       gp_Dir( gp_Vec( CenterOfArc, AttachmentPoint2 ) ) );
554           AttachCirc.SetPosition( Ax2 );
555           AttachCirc.SetRadius( CenterOfArc.Distance( AttachmentPoint2 ) );
556           
557           GeomAPI_ExtremaCurveCurve Intersection( new Geom_Circle( AttachCirc ),
558                                                   new Geom_Line( SecondLin ) );
559           Intersection.NearestPoints( ProjAttachPoint2, ProjAttachPoint2 );
560           
561           Standard_Real U2 = ElCLib::Parameter( AttachCirc, ProjAttachPoint2 );
562           if (U2 <= M_PI)
563             {
564               FirstParAttachCirc = 0;
565               LastParAttachCirc  = U2;
566             }
567           else
568             {
569               FirstParAttachCirc = U2;
570               LastParAttachCirc  = 2*M_PI;
571             }
572         }
573     }
574 }
575
576
577
578 void DsgPrs::ComputeFilletRadiusPresentation( const Standard_Real ArrowLength,
579                                               const Standard_Real Value,
580                                               const gp_Pnt &      Position,
581                                               const gp_Dir &      NormalDir,
582                                               const gp_Pnt &      FirstPoint,
583                                               const gp_Pnt &      SecondPoint,
584                                               const gp_Pnt &      Center,
585                                               const gp_Pnt &      BasePnt,
586                                               const Standard_Boolean drawRevers,
587                                               Standard_Boolean &  SpecCase,
588                                               gp_Circ &           FilletCirc,
589                                               Standard_Real &     FirstParCirc,
590                                               Standard_Real &     LastParCirc,
591                                               gp_Pnt &            EndOfArrow,
592                                               gp_Dir &            DirOfArrow,
593                                               gp_Pnt &            DrawPosition)
594 {
595   gp_Dir dir1(gp_Vec(Center, FirstPoint));
596   gp_Dir dir2(gp_Vec(Center, SecondPoint));
597   Standard_Real Angle = dir1.Angle(dir2);
598   if(Angle <= Precision::Angular() || ( M_PI - Angle ) <= Precision::Angular() ||
599      Value <= Precision::Confusion()) SpecCase = Standard_True;
600   else SpecCase = Standard_False;
601   if ( !SpecCase )
602     {
603        // Computing presentation of fillet's arc
604       gp_Ax2 ax( Center, NormalDir, dir1 );
605       FilletCirc.SetPosition( ax );
606       FilletCirc.SetRadius( Center.Distance( FirstPoint ) ); //***
607       gp_Vec vec1( dir1 );
608       vec1 *= FilletCirc.Radius();
609 #ifdef DEB
610       gp_Pnt p1 =
611 #endif
612                   Center.Translated( vec1 );
613       gp_Vec vec2( dir2 );
614       vec2 *= FilletCirc.Radius();
615 #ifdef DEB
616       gp_Pnt p2 =
617 #endif
618                   Center.Translated( vec2 );
619       gp_Vec PosVec;
620       if(! Center.IsEqual( Position, Precision::Confusion() ))
621         PosVec.SetXYZ( gp_Vec(Center, Position).XYZ() );
622       else
623         PosVec.SetXYZ( (vec1.Added(vec2)).XYZ() );
624       gp_Vec NormalOfPlane = vec1 ^ vec2;      
625       gp_Vec Normal1 = NormalOfPlane ^ vec1;
626       gp_Vec Normal2 = NormalOfPlane ^ vec2;
627       Standard_Integer Sign1 = (PosVec * Normal1 >= 0)? 1 : -1;
628       Standard_Integer Sign2 = (PosVec * Normal2 >= 0)? 1 : -1;
629       gp_Lin L1( Center, dir1 );
630       gp_Lin L2( Center, dir2 );
631       if ( Sign1 != Sign2 )
632         {
633           DrawPosition = Position; //***
634           gp_Dir direction(PosVec) ;
635           Standard_Real angle = dir1.Angle(direction) ;
636           if (( dir1 ^ direction) * NormalDir < 0.0e0)   angle = -angle ;
637           if(Sign1 == -1) angle += M_PI;
638           EndOfArrow = ElCLib::Value(angle, FilletCirc); //***
639                    
640         }
641       else
642         {
643           if(L1.Distance(Position) < L2.Distance(Position))
644               {
645                 EndOfArrow = FirstPoint; //***
646                 DrawPosition =  ElCLib::Value(ElCLib::Parameter(L1, Position), L1);     
647               }
648           else
649             {
650               EndOfArrow = SecondPoint; //***
651               DrawPosition = ElCLib::Value(ElCLib::Parameter(L2, Position), L2);
652             }
653         }
654       if((dir1^dir2).IsOpposite(NormalDir, Precision::Angular()))
655         {
656           gp_Dir newdir = NormalDir.Reversed() ;
657           gp_Ax2 axnew( Center, newdir, dir1 );
658           FilletCirc.SetPosition( axnew );
659         }
660       FirstParCirc = ElCLib::Parameter( FilletCirc, FirstPoint );
661       LastParCirc  = ElCLib::Parameter( FilletCirc, SecondPoint );
662
663 #ifdef DEB
664 #endif
665     }
666   else //Angle equal 0 or PI or R = 0
667     {
668       DrawPosition = Position;
669       EndOfArrow   = BasePnt;
670     }
671
672
673   if(drawRevers)
674     {
675       gp_Vec Vd(DrawPosition, EndOfArrow);
676       DrawPosition.Translate(Vd *2);
677     }
678   DirOfArrow.SetXYZ(gp_Dir(gp_Vec(DrawPosition, EndOfArrow)).XYZ());      
679 }
680
681 //=======================================================================
682 //function : ComputeRadiusLine
683 //purpose  : 
684 //=======================================================================
685
686 void DsgPrs::ComputeRadiusLine(const gp_Pnt & aCenter,
687                                const gp_Pnt & anEndOfArrow,
688                                const gp_Pnt & aPosition,
689                                const Standard_Boolean drawFromCenter,
690                                      gp_Pnt & aRadLineOrign,
691                                      gp_Pnt & aRadLineEnd)
692 {
693   if(drawFromCenter)
694     {
695       gp_Lin RadiusLine = gce_MakeLin( aCenter, anEndOfArrow );
696       Standard_Real PosParOnLine = ElCLib::Parameter( RadiusLine, aPosition );
697       Standard_Real EndOfArrowPar     = ElCLib::Parameter( RadiusLine, anEndOfArrow );
698       if (PosParOnLine < 0.0)
699         {
700           aRadLineOrign = aPosition;
701           aRadLineEnd   = anEndOfArrow;
702         }
703       else if (PosParOnLine > EndOfArrowPar)
704         {
705           aRadLineOrign = aPosition;
706           aRadLineEnd   = aCenter;
707         }
708       else
709         {
710           aRadLineOrign = aCenter;
711           aRadLineEnd   = anEndOfArrow;
712         }
713     }
714   else
715     {
716       aRadLineOrign = aPosition;
717       aRadLineEnd   = anEndOfArrow;
718     }
719 }
720
721
722 //=======================================================================
723 //function : DistanceFromApex
724 //purpose  : 
725 //=======================================================================
726
727 Standard_Real DsgPrs::DistanceFromApex(const gp_Elips & elips,
728                                        const gp_Pnt   & Apex,
729                                        const Standard_Real par)
730 {
731   Standard_Real dist;
732   Standard_Real parApex = ElCLib::Parameter ( elips, Apex );
733   if(parApex == 0.0 || parApex == M_PI) 
734     {//Major case
735       if(parApex == 0.0) //pos Apex
736         dist = (par < M_PI) ? par : (2*M_PI - par);
737       else //neg Apex
738         dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI );
739     }
740   else 
741     {// Minor case
742       if(parApex == M_PI / 2) //pos Apex
743         {
744           if(par <= parApex + M_PI && par > parApex )
745             dist = par - parApex;
746           else 
747             { 
748               if(par >  parApex + M_PI)
749                 dist = 2*M_PI - par + parApex;
750               else
751                 dist = parApex - par; // 0 < par < M_PI/2
752             }
753         }
754       else //neg Apex == 3/2 PI
755         {
756           if(par <= parApex && par >= M_PI/2) 
757             dist = parApex - par;
758           else
759             {
760               if(par >  parApex) 
761                 dist = par - parApex;
762               else
763                 dist = par + M_PI/2; // 0 < par < PI/2
764             }
765         }
766     }
767   return dist;
768 }