d85b2046eccbf9c962ffc074ff4fe32527fe34c3
[occt.git] / src / DsgPrs / DsgPrs_AnglePresentation.cxx
1 // Created on: 1995-02-07
2 // Copyright (c) 1995-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <DsgPrs_AnglePresentation.hxx>
17
18 #include <DsgPrs.hxx>
19 #include <ElCLib.hxx>
20 #include <GC_MakeCircle.hxx>
21 #include <gce_MakePln.hxx>
22 #include <Geom_Circle.hxx>
23 #include <Geom_Line.hxx>
24 #include <GeomAPI_ExtremaCurveCurve.hxx>
25 #include <gp_Ax1.hxx>
26 #include <gp_Circ.hxx>
27 #include <gp_Dir.hxx>
28 #include <gp_Lin.hxx>
29 #include <gp_Pnt.hxx>
30 #include <Graphic3d_ArrayOfPolylines.hxx>
31 #include <Graphic3d_ArrayOfSegments.hxx>
32 #include <Graphic3d_AspectLine3d.hxx>
33 #include <Graphic3d_AspectMarker3d.hxx>
34 #include <Graphic3d_Group.hxx>
35 #include <Precision.hxx>
36 #include <Prs3d_Arrow.hxx>
37 #include <Prs3d_ArrowAspect.hxx>
38 #include <Prs3d_DimensionAspect.hxx>
39 #include <Prs3d_LineAspect.hxx>
40 #include <Prs3d_Presentation.hxx>
41 #include <Prs3d_Text.hxx>
42 #include <TCollection_AsciiString.hxx>
43 #include <TCollection_ExtendedString.hxx>
44 #include <UnitsAPI.hxx>
45
46 #include <stdio.h>
47 //------------------------------------------------------------------------------------------------------------------
48 // Returns 1 if C is above of CMin; 0 if C is bitween CMin and CMax; -1 if C is Below CMax   
49 //-----------------------------------------------------------------------------------------------------------------
50 static Standard_Integer AboveInBelowCone(const gp_Circ &CMax, const gp_Circ &CMin, const gp_Circ &C)
51 {
52   const Standard_Real D = CMax.Location().Distance( CMin.Location() );
53   const Standard_Real D1 = CMax.Location().Distance( C.Location() );
54   const Standard_Real D2 = CMin.Location().Distance( C.Location() );
55
56   if ( D >= D1 && D >= D2 ) return 0;
57   if ( D < D2 && D1 < D2 ) return -1;
58   if ( D < D1 && D2 < D1 ) return 1;
59
60   return 0;
61 }
62
63
64 //==========================================================================
65 // function : DsgPrs_AnglePresentation::Add
66 // purpose  : draws the presentation of the cone's angle;
67 //==========================================================================
68 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
69                                     const Handle(Prs3d_Drawer)& aDrawer,
70                                     const Standard_Real /*aVal*/,
71                                     const TCollection_ExtendedString& aText,
72                                     const gp_Circ& aCircle,
73                                     const gp_Pnt& aPosition,
74                                     const gp_Pnt& Apex,
75                                     const gp_Circ& VminCircle,
76                                     const gp_Circ& VmaxCircle,
77                                     const Standard_Real aArrowSize) 
78 {
79   Handle(Prs3d_DimensionAspect) aDimensionAspect = aDrawer->DimensionAspect();
80
81   TCollection_ExtendedString txt(aText);
82
83   const Standard_Real myArrowSize = ( aArrowSize == 0.0 )? (0.1 * aCircle.Radius()) : aArrowSize;
84
85   aDimensionAspect->ArrowAspect()->SetLength(myArrowSize);
86   aDrawer->ArrowAspect()->SetLength(myArrowSize);
87
88   Standard_Boolean IsConeTrimmed = Standard_False; 
89   gp_Circ myCircle = aCircle;
90   if( VminCircle.Radius() > 0.01 ) {
91     IsConeTrimmed = Standard_True;
92     if( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 1 ) myCircle = VminCircle;
93   }
94  
95   gp_Pnt P1 = ElCLib::Value(0., myCircle);
96   gp_Pnt P2 = ElCLib::Value(M_PI, myCircle);
97
98   gce_MakePln mkPln(P1, P2, Apex); // create a plane whitch defines plane for projection aPosition on it
99
100   gp_Vec aVector( mkPln.Value().Location(), aPosition );     //project aPosition on a plane
101   gp_Vec Normal = mkPln.Value().Axis().Direction(); 
102   Normal = (aVector * Normal) * Normal;
103
104   gp_Pnt aPnt = aPosition;
105   aPnt = aPnt.Translated( -Normal );
106   
107   gp_Pnt tmpPnt = aPnt;
108
109   gp_Pnt AttachmentPnt, OppositePnt;
110   if( aPnt.Distance(P1) <  aPnt.Distance(P2) ) {
111     AttachmentPnt = P1; 
112     OppositePnt = P2; 
113   }
114   else {
115     AttachmentPnt = P2; 
116     OppositePnt = P1;
117   }
118
119   aPnt = AttachmentPnt ;                          // Creating of circle whitch defines a plane for a dimension arc
120   gp_Vec Vec(AttachmentPnt, Apex);                // Dimension arc is a part of the circle 
121   Vec.Scale(2.);
122   aPnt.Translate(Vec);
123   GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt); 
124   gp_Circ aCircle2 = mkCirc.Value()->Circ();
125
126   Standard_Integer i;
127   Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt);  //must be equal to zero (look circle construction)
128   Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);    
129   
130   while ( AttParam >= 2. * M_PI ) AttParam -= 2. * M_PI;
131   while ( OppParam >= 2. * M_PI ) OppParam -= 2. * M_PI;
132
133   //-------------------------- Compute angle ------------------------
134   if( txt.Length() == 0 ) {
135     Standard_Real angle = UnitsAPI::CurrentFromLS( Abs( OppParam ),"PLANE ANGLE");
136     char res[80]; 
137     sprintf(res, "%g", angle );
138     txt = TCollection_ExtendedString(res);
139   }
140   //-----------------------------------------------------------------
141
142   Standard_Boolean IsArrowOut = Standard_True;    //Is arrows inside or outside of the cone
143   if( ElCLib::Parameter(aCircle2, tmpPnt) < OppParam )
144     if( 2. * myCircle.Radius() > 4. * myArrowSize ) IsArrowOut = Standard_False;  //four times more than an arrow size
145
146   Standard_Real angle = OppParam - AttParam;
147   Standard_Real param = AttParam;
148
149   gp_Dir aDir, aDir2;
150   if(IsArrowOut) {
151     aDir = gp_Dir( ( gp_Vec( ElCLib::Value( AttParam - M_PI / 12., aCircle2 ), AttachmentPnt) ) );
152     aDir2 = gp_Dir( ( gp_Vec( ElCLib::Value( OppParam + M_PI / 12., aCircle2 ), OppositePnt) ) );
153   }
154   else {
155     aDir = gp_Dir( ( gp_Vec( ElCLib::Value( AttParam + M_PI / 12., aCircle2 ), AttachmentPnt ) ) );
156     aDir2 = gp_Dir( ( gp_Vec( ElCLib::Value( OppParam - M_PI / 12., aCircle2 ), OppositePnt ) ) );
157   }
158
159   while ( angle > 2. * M_PI ) angle -= 2. * M_PI;
160
161   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(12);
162   for( i = 0; i <= 11; i++ )
163     aPrims->AddVertex(ElCLib::Value(param + angle/11 * i, aCircle2));
164   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
165
166   DsgPrs::ComputeSymbol(aPresentation, aDimensionAspect, AttachmentPnt,
167                         AttachmentPnt, aDir, aDir, DsgPrs_AS_LASTAR);
168   DsgPrs::ComputeSymbol(aPresentation, aDimensionAspect, OppositePnt, 
169                         OppositePnt, aDir2, aDir2, DsgPrs_AS_LASTAR);
170
171   param = ElCLib::Parameter(aCircle2, tmpPnt);
172   tmpPnt = ElCLib::Value(param, aCircle2);
173   tmpPnt = tmpPnt.Translated(gp_Vec(0, 0, -2));
174   Prs3d_Text::Draw(aPresentation, aDimensionAspect->TextAspect(), txt, tmpPnt);   //add the TCollection_ExtendedString
175
176   angle = 2. * M_PI - param ; 
177   if( param > OppParam )
178   {
179     while ( angle > 2. * M_PI ) angle -= 2. * M_PI;
180     aPrims = new Graphic3d_ArrayOfPolylines(12);
181     for( i = 11; i >= 0; i-- )
182       aPrims->AddVertex(ElCLib::Value(-angle/11 * i, aCircle2));
183     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
184   }
185
186   if( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 1 && !IsConeTrimmed )         //above
187   {
188     aPrims = new Graphic3d_ArrayOfPolylines(3);
189     aPrims->AddVertex(AttachmentPnt);
190     aPrims->AddVertex(Apex);
191     aPrims->AddVertex(OppositePnt);
192   }
193   else
194   {
195     aPnt = OppositePnt ;
196     if ( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 0 ) return;
197
198     gp_Pnt P11 = ElCLib::Value( 0., VmaxCircle );
199     gp_Pnt P12 = ElCLib::Value( M_PI, VmaxCircle );
200
201     aPrims = new Graphic3d_ArrayOfSegments(4);
202     aPrims->AddVertex(AttachmentPnt);
203     aPrims->AddVertex(( aPnt.Distance(P1) < aPnt.Distance(P2) )? P12 : P11);
204     aPrims->AddVertex(OppositePnt);
205     aPrims->AddVertex(( aPnt.Distance(P1) < aPnt.Distance(P2) )? P11 : P12);
206   }
207   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
208 }
209
210
211 //==========================================================================
212 // function : DsgPrs_AnglePresentation::Add
213 // purpose  : 
214 //            
215 //==========================================================================
216
217 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
218                                     const Handle(Prs3d_Drawer)& aDrawer,
219                                     const Standard_Real theval,
220                                     const TCollection_ExtendedString& aText,
221                                     const gp_Pnt& CenterPoint,
222                                     const gp_Pnt& AttachmentPoint1,
223                                     const gp_Pnt& AttachmentPoint2,
224                                     const gp_Dir& dir1,
225                                     const gp_Dir& dir2,
226                                     const gp_Dir& axisdir,
227                                     const gp_Pnt& OffsetPoint)
228 {
229   char valcar[80];
230   sprintf(valcar,"%5.2f",theval);
231
232   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
233   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
234
235   gp_Ax2 ax(CenterPoint,axisdir,dir1);
236   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
237   gp_Vec vec1(dir1);
238   vec1 *= cer.Radius();
239   gp_Vec vec2(dir2);
240   vec2 *= cer.Radius();
241   gp_Pnt p2 = CenterPoint.Translated(vec2);
242
243   Standard_Real uc1 = 0.;
244   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
245   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
246
247   Standard_Real udeb = uc1;
248   Standard_Real ufin = uc2;
249
250   if (uco > ufin) {
251     if (Abs(theval)<M_PI) {
252       // test if uco is in the opposite sector 
253       if (uco > udeb+M_PI && uco < ufin+M_PI) {
254         udeb += M_PI;
255         ufin += M_PI;
256         uc1 = udeb;
257         uc2 = ufin;
258       }
259     }
260   }
261
262   if (uco > ufin) {
263     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
264       ufin = uco;
265     }
266     else {
267       udeb = uco - 2.*M_PI;
268     }
269   }
270
271   const Standard_Real alpha = Abs(ufin-udeb);
272   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
273   const Standard_Real dteta = alpha/(nbp-1);
274
275   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
276   aPrims->AddBound(nbp);
277   for (Standard_Integer i = 1; i<=nbp; i++)
278     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
279
280   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
281   
282   Standard_Real length = LA->ArrowAspect()->Length();
283   if (length <  Precision::Confusion()) length = 1.e-04;
284
285   gp_Vec vecarr;
286   gp_Pnt ptarr;
287   ElCLib::D1(uc1,cer,ptarr,vecarr);
288
289   gp_Ax1 ax1(ptarr, axisdir);
290   gp_Dir dirarr(-vecarr);
291
292   //calculate angle of rotation
293   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
294   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
295   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
296   gp_Vec v1(ptarr,ptarr2);
297   gp_Vec v2(ptarr,ptarr3);
298   const Standard_Real beta = v1.Angle(v2);
299   dirarr.Rotate(ax1, beta);
300   Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr,LA->ArrowAspect()->Angle(),length);
301
302   aPrims->AddBound(2);
303   aPrims->AddVertex(AttachmentPoint1);
304   aPrims->AddVertex(ptarr);
305
306   ElCLib::D1(uc2,cer,ptarr,vecarr);
307
308   ax1.SetLocation(ptarr);
309   gp_Dir dirarr2(vecarr);
310   dirarr2.Rotate(ax1,-beta);
311   Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr2,LA->ArrowAspect()->Angle(),length);
312
313   aPrims->AddBound(2);
314   aPrims->AddVertex(AttachmentPoint2);
315   aPrims->AddVertex(ptarr);
316
317   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
318 }
319
320
321 //==========================================================================
322 // function : DsgPrs_AnglePresentation::Add
323 // purpose  : Adds prezentation of angle between two faces
324 //==========================================================================
325
326 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
327                                     const Handle(Prs3d_Drawer)& aDrawer,
328                                     const Standard_Real theval,
329                                     const TCollection_ExtendedString& aText,
330                                     const gp_Pnt& CenterPoint,
331                                     const gp_Pnt& AttachmentPoint1,
332                                     const gp_Pnt& AttachmentPoint2,
333                                     const gp_Dir& dir1,
334                                     const gp_Dir& dir2,
335                                     const gp_Dir& axisdir,
336                                     const Standard_Boolean isPlane,
337                                     const gp_Ax1& AxisOfSurf,
338                                     const gp_Pnt& OffsetPoint,
339                                     const DsgPrs_ArrowSide ArrowPrs )
340 {
341   char valcar[80];
342   sprintf(valcar,"%5.2f",theval);
343   
344   Handle( Prs3d_DimensionAspect ) LA = aDrawer->DimensionAspect();
345   Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
346
347   gp_Circ AngleCirc, AttachCirc;
348   Standard_Real FirstParAngleCirc, LastParAngleCirc, FirstParAttachCirc, LastParAttachCirc;
349   gp_Pnt EndOfArrow1, EndOfArrow2, ProjAttachPoint2;
350   gp_Dir DirOfArrow1, DirOfArrow2;
351   DsgPrs::ComputeFacesAnglePresentation( LA->ArrowAspect()->Length(),
352                                          theval,
353                                          CenterPoint,
354                                          AttachmentPoint1,
355                                          AttachmentPoint2,
356                                          dir1,
357                                          dir2,
358                                          axisdir,
359                                          isPlane,
360                                          AxisOfSurf,
361                                          OffsetPoint,
362                                          AngleCirc,
363                                          FirstParAngleCirc,
364                                          LastParAngleCirc,
365                                          EndOfArrow1,
366                                          EndOfArrow2,
367                                          DirOfArrow1,
368                                          DirOfArrow2,
369                                          ProjAttachPoint2,
370                                          AttachCirc,
371                                          FirstParAttachCirc,
372                                          LastParAttachCirc );
373                                       
374   // Creating the angle's arc or line if null angle
375   Handle(Graphic3d_ArrayOfPrimitives) aPrims;
376   if (theval > Precision::Angular() && Abs( M_PI-theval ) > Precision::Angular())
377   {
378     const Standard_Real Alpha  = Abs( LastParAngleCirc - FirstParAngleCirc );
379     const Standard_Integer NodeNumber = Max (4 , Standard_Integer (50. * Alpha / M_PI));
380     const Standard_Real delta = Alpha / (Standard_Real)( NodeNumber - 1 );
381
382     aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber+4,3);
383     aPrims->AddBound(NodeNumber);
384     for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAngleCirc += delta)
385       aPrims->AddVertex(ElCLib::Value( FirstParAngleCirc, AngleCirc ));
386
387     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
388     aPrims = new Graphic3d_ArrayOfSegments(4);
389   }
390   else // null angle
391   {
392     aPrims = new Graphic3d_ArrayOfSegments(6);
393     aPrims->AddVertex(OffsetPoint);
394     aPrims->AddVertex(EndOfArrow1);
395   }
396
397   // Add presentation of arrows
398   DsgPrs::ComputeSymbol( aPresentation, LA, EndOfArrow1, EndOfArrow2, DirOfArrow1, DirOfArrow2, ArrowPrs );
399   
400   // Drawing the text
401   Prs3d_Text::Draw( aPresentation, LA->TextAspect(), aText, OffsetPoint );
402   
403   // Line from AttachmentPoint1 to end of Arrow1
404   aPrims->AddVertex(AttachmentPoint1);
405   aPrims->AddVertex(EndOfArrow1);
406   // Line from "projection" of AttachmentPoint2 to end of Arrow2
407   aPrims->AddVertex(ProjAttachPoint2);
408   aPrims->AddVertex(EndOfArrow2);
409
410   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
411
412   // Line or arc from AttachmentPoint2 to its "projection"
413   if (AttachmentPoint2.Distance( ProjAttachPoint2 ) > Precision::Confusion())
414   {
415     if (isPlane)
416         {
417           // Creating the line from AttachmentPoint2 to its projection
418       aPrims = new Graphic3d_ArrayOfSegments(2);
419       aPrims->AddVertex(AttachmentPoint2);
420       aPrims->AddVertex(ProjAttachPoint2);
421         }      
422     else
423         {
424           // Creating the arc from AttachmentPoint2 to its projection
425       const Standard_Real Alpha = Abs( LastParAttachCirc - FirstParAttachCirc );
426           const Standard_Integer NodeNumber = Max (4 , Standard_Integer (50. * Alpha / M_PI));
427       const Standard_Real delta = Alpha / (Standard_Real)( NodeNumber - 1 );
428
429       aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber);
430           for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAttachCirc += delta)
431         aPrims->AddVertex(ElCLib::Value( FirstParAttachCirc, AttachCirc ));
432         }
433     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
434   }
435 }
436
437
438 //==========================================================================
439 // function : DsgPrs_AnglePresentation::Add
440 // purpose  : 
441 //            
442 //==========================================================================
443
444 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
445                                     const Handle(Prs3d_Drawer)& aDrawer,
446                                     const Standard_Real theval,
447                                     const TCollection_ExtendedString& aText,
448                                     const gp_Pnt& CenterPoint,
449                                     const gp_Pnt& AttachmentPoint1,
450                                     const gp_Pnt& AttachmentPoint2,
451                                     const gp_Dir& dir1,
452                                     const gp_Dir& dir2,
453                                     const gp_Pnt& OffsetPoint)
454 {
455   char valcar[80];
456   sprintf(valcar,"%5.2f",theval);
457   
458   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
459   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
460
461   gp_Dir Norm;
462   if (!dir1.IsParallel(dir2, Precision::Angular())) {
463     Norm = dir1.Crossed(dir2);
464   }
465   else {
466     gp_Dir dir2B = gp_Dir(gp_Vec(CenterPoint, OffsetPoint));
467     Norm = dir1.Crossed(dir2B);
468   }
469
470   if (Abs(theval) > M_PI) Norm.Reverse();
471
472   gp_Ax2 ax(CenterPoint,Norm,dir1);
473   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
474   gp_Vec vec1(dir1);
475   vec1 *= cer.Radius();
476   gp_Vec vec2(dir2);
477   vec2 *= cer.Radius();
478   gp_Pnt p2 = CenterPoint.Translated(vec2);
479
480   Standard_Real uc1 = 0.;
481   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
482   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
483
484   Standard_Real udeb = uc1;
485   Standard_Real ufin = uc2;
486
487   if (uco > ufin) {
488     if (Abs(theval)<M_PI) {
489       // test if uco is in the opposite sector 
490       if (uco > udeb+M_PI && uco < ufin+M_PI) {
491         udeb += M_PI;
492         ufin += M_PI;
493         uc1 = udeb;
494         uc2 = ufin;
495       }
496     }
497   }
498
499   if (uco > ufin) {
500     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
501       ufin = uco;
502     }
503     else {
504       udeb = uco - 2.*M_PI;
505     }
506   }
507
508   const Standard_Real alpha = Abs(ufin-udeb);
509   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
510   const Standard_Real dteta = alpha/(nbp-1);
511
512   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
513   aPrims->AddBound(nbp);
514   for (Standard_Integer i = 1; i<=nbp; i++)
515     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
516   
517   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
518   
519   Standard_Real length = LA->ArrowAspect()->Length();
520   if (length <  Precision::Confusion()) length = 1.e-04;
521
522   gp_Vec vecarr;
523   gp_Pnt ptarr;
524   ElCLib::D1(uc1,cer,ptarr,vecarr);
525
526   gp_Ax1 ax1(ptarr, Norm);
527   gp_Dir dirarr(-vecarr);
528   //calculate the angle of rotation
529   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
530   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
531   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
532   gp_Vec v1(ptarr,ptarr2);
533   gp_Vec v2(ptarr,ptarr3);
534   const Standard_Real beta = v1.Angle(v2);
535   dirarr.Rotate(ax1, beta);
536   Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr,LA->ArrowAspect()->Angle(),length);
537
538   aPrims->AddBound(2);
539   aPrims->AddVertex(AttachmentPoint1);
540   aPrims->AddVertex(ptarr);
541
542   ElCLib::D1(uc2,cer,ptarr,vecarr);
543
544   ax1.SetLocation(ptarr);
545   gp_Dir dirarr2(vecarr);
546   dirarr2.Rotate(ax1,  - beta);
547   Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr2,LA->ArrowAspect()->Angle(),length);  
548   
549   aPrims->AddBound(2);
550   aPrims->AddVertex(AttachmentPoint2);
551   aPrims->AddVertex(ptarr);
552
553   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
554 }
555
556
557 //==========================================================================
558 // function : DsgPrs_AnglePresentation::Add
559 // purpose  : It is possible to choose the symbol of extremities of the face (arrow, point...)
560 //==========================================================================
561
562 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
563                                     const Handle(Prs3d_Drawer)& aDrawer,
564                                     const Standard_Real theval,
565                                     const TCollection_ExtendedString& aText,
566                                     const gp_Pnt& CenterPoint,
567                                     const gp_Pnt& AttachmentPoint1,
568                                     const gp_Pnt& AttachmentPoint2,
569                                     const gp_Dir& dir1,
570                                     const gp_Dir& dir2,
571                                     const gp_Pnt& OffsetPoint,
572                                     const DsgPrs_ArrowSide ArrowPrs)
573 {
574   char valcar[80];
575   sprintf(valcar,"%5.2f",theval);
576   
577   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
578   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
579
580   gp_Dir Norm = dir1.Crossed(dir2);
581   if (Abs(theval) > M_PI) Norm.Reverse();
582
583   gp_Ax2 ax(CenterPoint,Norm,dir1);
584   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
585   gp_Vec vec1(dir1);
586   vec1 *= cer.Radius();
587   gp_Vec vec2(dir2);
588   vec2 *= cer.Radius();
589   gp_Pnt p2 = CenterPoint.Translated(vec2);
590
591   Standard_Real uc1 = 0.;
592   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
593   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
594
595   Standard_Real udeb = uc1;
596   Standard_Real ufin = uc2;
597
598   if (uco > ufin) {
599     if (Abs(theval)<M_PI) {
600       // test if uco is in the opposite sector 
601       if (uco > udeb+M_PI && uco < ufin+M_PI) {
602         udeb += M_PI;
603         ufin += M_PI;
604         uc1 = udeb;
605         uc2 = ufin;
606       }
607     }
608   }
609
610   if (uco > ufin) {
611     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
612       ufin = uco;
613     }
614     else {
615       udeb = uco - 2.*M_PI;
616     }
617   }
618
619   const Standard_Real alpha = Abs(ufin-udeb);
620   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
621   const Standard_Real dteta = alpha/(nbp-1);
622
623   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
624   aPrims->AddBound(nbp);
625   for (Standard_Integer i = 1; i<=nbp; i++)
626     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
627
628   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
629   
630   Standard_Real length = LA->ArrowAspect()->Length();
631   if (length <  Precision::Confusion()) length = 1.e-04;
632
633   // Lines of recall
634   gp_Vec vecarr;
635   gp_Pnt ptarr;
636   ElCLib::D1(uc1,cer,ptarr,vecarr);
637
638   gp_Ax1 ax1(ptarr, Norm);
639   gp_Dir dirarr(-vecarr);
640   //calculate angle of rotation
641   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
642   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
643   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
644   gp_Vec v1(ptarr,ptarr2 );
645   gp_Vec v2(ptarr, ptarr3);
646   const Standard_Real beta = v1.Angle(v2);
647   dirarr.Rotate(ax1, beta);
648
649   aPrims->AddBound(2);
650   aPrims->AddVertex(AttachmentPoint1);
651   aPrims->AddVertex(ptarr);
652   
653   gp_Vec vecarr1;
654   gp_Pnt ptarr1;
655   ElCLib::D1(uc2,cer,ptarr1,vecarr1);
656   ax1.SetLocation(ptarr1);
657   gp_Dir dirarr2(vecarr1);
658   dirarr2.Rotate(ax1,  - beta);
659
660   aPrims->AddBound(2);
661   aPrims->AddVertex(AttachmentPoint2);
662   aPrims->AddVertex(ptarr1);
663
664   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
665
666   // One traces the arrows
667   DsgPrs::ComputeSymbol(aPresentation,LA,ptarr,ptarr1,dirarr,dirarr2,ArrowPrs);
668 }
669
670
671 //==========================================================================
672 // function : DsgPrs_AnglePresentation::Add
673 // purpose  : 
674 //            
675 //==========================================================================
676
677 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
678                                     const Handle(Prs3d_Drawer)& aDrawer,
679                                     const Standard_Real theval,
680                                     const gp_Pnt& CenterPoint,
681                                     const gp_Pnt& AttachmentPoint1,
682                                     const gp_Pnt& AttachmentPoint2,
683                                     const gp_Dir& dir1,
684                                     const gp_Dir& dir2,
685                                     const gp_Pnt& OffsetPoint)
686 {
687   char valcar[80];
688   sprintf(valcar,"%5.2f",theval);
689
690   TCollection_AsciiString valas(valcar);
691   TCollection_ExtendedString aText(valas);
692
693   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
694   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
695
696   gp_Dir Norm = dir1.Crossed(dir2);
697   if (Abs(theval) > M_PI) Norm.Reverse();
698
699   gp_Ax2 ax(CenterPoint,Norm,dir1);
700   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
701   gp_Vec vec1(dir1);
702   vec1 *= cer.Radius();
703   gp_Vec vec2(dir2);
704   vec2 *= cer.Radius();
705   gp_Pnt p2 = CenterPoint.Translated(vec2);
706
707   Standard_Real uc1 = 0.;
708   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
709   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
710
711   Standard_Real udeb = uc1;
712   Standard_Real ufin = uc2;
713
714   if (uco > ufin) {
715     if (Abs(theval)<M_PI) {
716       // test if uco is in the opposite sector 
717       if (uco > udeb+M_PI && uco < ufin+M_PI) {
718         udeb += M_PI;
719         ufin += M_PI;
720         uc1 = udeb;
721         uc2 = ufin;
722       }
723     }
724   }
725
726   if (uco > ufin) {
727     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
728       ufin = uco;
729     }
730     else {
731       udeb = uco - 2.*M_PI;
732     }
733   }
734
735   const Standard_Real alpha = Abs(ufin-udeb);
736   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
737   const Standard_Real dteta = alpha/(nbp-1);
738
739   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
740   aPrims->AddBound(nbp);
741   for (Standard_Integer i = 1; i<=nbp; i++)
742     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
743
744   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
745
746   Standard_Real length = LA->ArrowAspect()->Length();
747   if (length <  Precision::Confusion()) length = 1.e-04;
748
749   gp_Vec vecarr;
750   gp_Pnt ptarr;
751   ElCLib::D1(uc1,cer,ptarr,vecarr);
752
753   gp_Ax1 ax1(ptarr, Norm);
754   gp_Dir dirarr(-vecarr);
755   //calculate the angle of rotation
756   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
757   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
758   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
759   gp_Vec v1(ptarr,ptarr2 );
760   gp_Vec v2(ptarr, ptarr3);
761   const Standard_Real beta = v1.Angle(v2);
762   dirarr.Rotate(ax1, beta);
763
764   Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr,LA->ArrowAspect()->Angle(),length);
765
766   aPrims->AddBound(2);
767   aPrims->AddVertex(AttachmentPoint1);
768   aPrims->AddVertex(ptarr);
769
770   ElCLib::D1(uc2,cer,ptarr,vecarr);
771   ax1.SetLocation(ptarr);
772   gp_Dir dirarr2(vecarr);
773   dirarr2.Rotate(ax1, -beta);
774
775   Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr2,LA->ArrowAspect()->Angle(),length);
776   
777   aPrims->AddBound(2);
778   aPrims->AddVertex(AttachmentPoint2);
779   aPrims->AddVertex(ptarr);
780
781   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
782 }
783
784 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
785                                     const Handle(Prs3d_Drawer)& aDrawer,
786                                     const Standard_Real theval,
787                                     const gp_Pnt& CenterPoint,
788                                     const gp_Pnt& AttachmentPoint1,
789                                     const gp_Ax1& theAxe,
790                                     const DsgPrs_ArrowSide ArrowSide)
791 {
792   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
793   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
794   
795   gp_Dir dir1(gp_Vec(CenterPoint, AttachmentPoint1));
796   gp_Ax2 ax(CenterPoint,theAxe.Direction(),dir1);
797   gp_Circ cer(ax,CenterPoint.Distance(AttachmentPoint1));
798
799   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * theval / M_PI));
800   const Standard_Real dteta = theval/(nbp-1);
801
802   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp);
803   for (Standard_Integer i = 1; i<=nbp; i++)
804     aPrims->AddVertex(ElCLib::Value(dteta*(i-1),cer));
805   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
806
807   Standard_Real uc1 = 0.;
808   Standard_Real uc2 = ElCLib::Parameter(cer,AttachmentPoint1.Rotated(theAxe,theval));
809
810   Standard_Real length = LA->ArrowAspect()->Length();
811   if (length < Precision::Confusion()) length = 1.e-04;
812
813   gp_Vec vecarr;
814   gp_Pnt ptarr;
815   switch(ArrowSide)
816   {
817     case DsgPrs_AS_FIRSTAR:
818     {
819       ElCLib::D1(uc1,cer,ptarr,vecarr);
820       Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(-vecarr),LA->ArrowAspect()->Angle(),length);
821       break;
822     }
823     case DsgPrs_AS_LASTAR:
824     {
825       ElCLib::D1(uc2,cer,ptarr,vecarr);
826       Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(vecarr),LA->ArrowAspect()->Angle(),length);
827       break;
828     }
829     case DsgPrs_AS_BOTHAR:
830     {
831       ElCLib::D1(uc1,cer,ptarr,vecarr);
832       Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(-vecarr),LA->ArrowAspect()->Angle(),length);
833       ElCLib::D1(uc2,cer,ptarr,vecarr);
834       Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(vecarr),LA->ArrowAspect()->Angle(),length);
835       break;
836     }
837     default: break;
838   }
839 }