0027756: Visualization - add Draw() method taking Graphic3d_Group to tools Prs3d_Arro...
[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 (Prs3d_Root::CurrentGroup (aPresentation), aDimensionAspect->TextAspect(), txt, tmpPnt);
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   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPresentation);
234   aGroup->SetPrimitivesAspect(LA->LineAspect()->Aspect());
235
236   gp_Ax2 ax(CenterPoint,axisdir,dir1);
237   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
238   gp_Vec vec1(dir1);
239   vec1 *= cer.Radius();
240   gp_Vec vec2(dir2);
241   vec2 *= cer.Radius();
242   gp_Pnt p2 = CenterPoint.Translated(vec2);
243
244   Standard_Real uc1 = 0.;
245   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
246   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
247
248   Standard_Real udeb = uc1;
249   Standard_Real ufin = uc2;
250
251   if (uco > ufin) {
252     if (Abs(theval)<M_PI) {
253       // test if uco is in the opposite sector 
254       if (uco > udeb+M_PI && uco < ufin+M_PI) {
255         udeb += M_PI;
256         ufin += M_PI;
257         uc1 = udeb;
258         uc2 = ufin;
259       }
260     }
261   }
262
263   if (uco > ufin) {
264     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
265       ufin = uco;
266     }
267     else {
268       udeb = uco - 2.*M_PI;
269     }
270   }
271
272   const Standard_Real alpha = Abs(ufin-udeb);
273   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
274   const Standard_Real dteta = alpha/(nbp-1);
275
276   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
277   aPrims->AddBound(nbp);
278   for (Standard_Integer i = 1; i<=nbp; i++)
279     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
280
281   Prs3d_Text::Draw (aGroup, LA->TextAspect(), aText, OffsetPoint);
282   
283   Standard_Real length = LA->ArrowAspect()->Length();
284   if (length <  Precision::Confusion()) length = 1.e-04;
285
286   gp_Vec vecarr;
287   gp_Pnt ptarr;
288   ElCLib::D1(uc1,cer,ptarr,vecarr);
289
290   gp_Ax1 ax1(ptarr, axisdir);
291   gp_Dir dirarr(-vecarr);
292
293   //calculate angle of rotation
294   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
295   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
296   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
297   gp_Vec v1(ptarr,ptarr2);
298   gp_Vec v2(ptarr,ptarr3);
299   const Standard_Real beta = v1.Angle(v2);
300   dirarr.Rotate(ax1, beta);
301   Prs3d_Arrow::Draw (aGroup, ptarr, dirarr, LA->ArrowAspect()->Angle(), length);
302
303   aPrims->AddBound(2);
304   aPrims->AddVertex(AttachmentPoint1);
305   aPrims->AddVertex(ptarr);
306
307   ElCLib::D1(uc2,cer,ptarr,vecarr);
308
309   ax1.SetLocation(ptarr);
310   gp_Dir dirarr2(vecarr);
311   dirarr2.Rotate(ax1,-beta);
312   Prs3d_Arrow::Draw (aGroup, ptarr, dirarr2, LA->ArrowAspect()->Angle(), length);
313
314   aPrims->AddBound(2);
315   aPrims->AddVertex(AttachmentPoint2);
316   aPrims->AddVertex(ptarr);
317
318   aGroup->AddPrimitiveArray (aPrims);
319 }
320
321
322 //==========================================================================
323 // function : DsgPrs_AnglePresentation::Add
324 // purpose  : Adds prezentation of angle between two faces
325 //==========================================================================
326
327 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
328                                     const Handle(Prs3d_Drawer)& aDrawer,
329                                     const Standard_Real theval,
330                                     const TCollection_ExtendedString& aText,
331                                     const gp_Pnt& CenterPoint,
332                                     const gp_Pnt& AttachmentPoint1,
333                                     const gp_Pnt& AttachmentPoint2,
334                                     const gp_Dir& dir1,
335                                     const gp_Dir& dir2,
336                                     const gp_Dir& axisdir,
337                                     const Standard_Boolean isPlane,
338                                     const gp_Ax1& AxisOfSurf,
339                                     const gp_Pnt& OffsetPoint,
340                                     const DsgPrs_ArrowSide ArrowPrs )
341 {
342   char valcar[80];
343   sprintf(valcar,"%5.2f",theval);
344   
345   Handle( Prs3d_DimensionAspect ) LA = aDrawer->DimensionAspect();
346   Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
347
348   gp_Circ AngleCirc, AttachCirc;
349   Standard_Real FirstParAngleCirc, LastParAngleCirc, FirstParAttachCirc, LastParAttachCirc;
350   gp_Pnt EndOfArrow1, EndOfArrow2, ProjAttachPoint2;
351   gp_Dir DirOfArrow1, DirOfArrow2;
352   DsgPrs::ComputeFacesAnglePresentation( LA->ArrowAspect()->Length(),
353                                          theval,
354                                          CenterPoint,
355                                          AttachmentPoint1,
356                                          AttachmentPoint2,
357                                          dir1,
358                                          dir2,
359                                          axisdir,
360                                          isPlane,
361                                          AxisOfSurf,
362                                          OffsetPoint,
363                                          AngleCirc,
364                                          FirstParAngleCirc,
365                                          LastParAngleCirc,
366                                          EndOfArrow1,
367                                          EndOfArrow2,
368                                          DirOfArrow1,
369                                          DirOfArrow2,
370                                          ProjAttachPoint2,
371                                          AttachCirc,
372                                          FirstParAttachCirc,
373                                          LastParAttachCirc );
374                                       
375   // Creating the angle's arc or line if null angle
376   Handle(Graphic3d_ArrayOfPrimitives) aPrims;
377   if (theval > Precision::Angular() && Abs( M_PI-theval ) > Precision::Angular())
378   {
379     const Standard_Real Alpha  = Abs( LastParAngleCirc - FirstParAngleCirc );
380     const Standard_Integer NodeNumber = Max (4 , Standard_Integer (50. * Alpha / M_PI));
381     const Standard_Real delta = Alpha / (Standard_Real)( NodeNumber - 1 );
382
383     aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber+4,3);
384     aPrims->AddBound(NodeNumber);
385     for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAngleCirc += delta)
386       aPrims->AddVertex(ElCLib::Value( FirstParAngleCirc, AngleCirc ));
387
388     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
389     aPrims = new Graphic3d_ArrayOfSegments(4);
390   }
391   else // null angle
392   {
393     aPrims = new Graphic3d_ArrayOfSegments(6);
394     aPrims->AddVertex(OffsetPoint);
395     aPrims->AddVertex(EndOfArrow1);
396   }
397
398   // Add presentation of arrows
399   DsgPrs::ComputeSymbol( aPresentation, LA, EndOfArrow1, EndOfArrow2, DirOfArrow1, DirOfArrow2, ArrowPrs );
400   
401   // Drawing the text
402   Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, OffsetPoint);
403   
404   // Line from AttachmentPoint1 to end of Arrow1
405   aPrims->AddVertex(AttachmentPoint1);
406   aPrims->AddVertex(EndOfArrow1);
407   // Line from "projection" of AttachmentPoint2 to end of Arrow2
408   aPrims->AddVertex(ProjAttachPoint2);
409   aPrims->AddVertex(EndOfArrow2);
410
411   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
412
413   // Line or arc from AttachmentPoint2 to its "projection"
414   if (AttachmentPoint2.Distance( ProjAttachPoint2 ) > Precision::Confusion())
415   {
416     if (isPlane)
417         {
418           // Creating the line from AttachmentPoint2 to its projection
419       aPrims = new Graphic3d_ArrayOfSegments(2);
420       aPrims->AddVertex(AttachmentPoint2);
421       aPrims->AddVertex(ProjAttachPoint2);
422         }      
423     else
424         {
425           // Creating the arc from AttachmentPoint2 to its projection
426       const Standard_Real Alpha = Abs( LastParAttachCirc - FirstParAttachCirc );
427           const Standard_Integer NodeNumber = Max (4 , Standard_Integer (50. * Alpha / M_PI));
428       const Standard_Real delta = Alpha / (Standard_Real)( NodeNumber - 1 );
429
430       aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber);
431           for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAttachCirc += delta)
432         aPrims->AddVertex(ElCLib::Value( FirstParAttachCirc, AttachCirc ));
433         }
434     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
435   }
436 }
437
438
439 //==========================================================================
440 // function : DsgPrs_AnglePresentation::Add
441 // purpose  : 
442 //            
443 //==========================================================================
444
445 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
446                                     const Handle(Prs3d_Drawer)& aDrawer,
447                                     const Standard_Real theval,
448                                     const TCollection_ExtendedString& aText,
449                                     const gp_Pnt& CenterPoint,
450                                     const gp_Pnt& AttachmentPoint1,
451                                     const gp_Pnt& AttachmentPoint2,
452                                     const gp_Dir& dir1,
453                                     const gp_Dir& dir2,
454                                     const gp_Pnt& OffsetPoint)
455 {
456   char valcar[80];
457   sprintf(valcar,"%5.2f",theval);
458   
459   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
460   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
461
462   gp_Dir Norm;
463   if (!dir1.IsParallel(dir2, Precision::Angular())) {
464     Norm = dir1.Crossed(dir2);
465   }
466   else {
467     gp_Dir dir2B = gp_Dir(gp_Vec(CenterPoint, OffsetPoint));
468     Norm = dir1.Crossed(dir2B);
469   }
470
471   if (Abs(theval) > M_PI) Norm.Reverse();
472
473   gp_Ax2 ax(CenterPoint,Norm,dir1);
474   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
475   gp_Vec vec1(dir1);
476   vec1 *= cer.Radius();
477   gp_Vec vec2(dir2);
478   vec2 *= cer.Radius();
479   gp_Pnt p2 = CenterPoint.Translated(vec2);
480
481   Standard_Real uc1 = 0.;
482   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
483   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
484
485   Standard_Real udeb = uc1;
486   Standard_Real ufin = uc2;
487
488   if (uco > ufin) {
489     if (Abs(theval)<M_PI) {
490       // test if uco is in the opposite sector 
491       if (uco > udeb+M_PI && uco < ufin+M_PI) {
492         udeb += M_PI;
493         ufin += M_PI;
494         uc1 = udeb;
495         uc2 = ufin;
496       }
497     }
498   }
499
500   if (uco > ufin) {
501     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
502       ufin = uco;
503     }
504     else {
505       udeb = uco - 2.*M_PI;
506     }
507   }
508
509   const Standard_Real alpha = Abs(ufin-udeb);
510   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
511   const Standard_Real dteta = alpha/(nbp-1);
512
513   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
514   aPrims->AddBound(nbp);
515   for (Standard_Integer i = 1; i<=nbp; i++)
516     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
517   
518   Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText,OffsetPoint);
519   
520   Standard_Real length = LA->ArrowAspect()->Length();
521   if (length <  Precision::Confusion()) length = 1.e-04;
522
523   gp_Vec vecarr;
524   gp_Pnt ptarr;
525   ElCLib::D1(uc1,cer,ptarr,vecarr);
526
527   gp_Ax1 ax1(ptarr, Norm);
528   gp_Dir dirarr(-vecarr);
529   //calculate the angle of rotation
530   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
531   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
532   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
533   gp_Vec v1(ptarr,ptarr2);
534   gp_Vec v2(ptarr,ptarr3);
535   const Standard_Real beta = v1.Angle(v2);
536   dirarr.Rotate(ax1, beta);
537   Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr, LA->ArrowAspect()->Angle(), length);
538
539   aPrims->AddBound(2);
540   aPrims->AddVertex(AttachmentPoint1);
541   aPrims->AddVertex(ptarr);
542
543   ElCLib::D1(uc2,cer,ptarr,vecarr);
544
545   ax1.SetLocation(ptarr);
546   gp_Dir dirarr2(vecarr);
547   dirarr2.Rotate(ax1,  - beta);
548   Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr2, LA->ArrowAspect()->Angle(), length);
549   
550   aPrims->AddBound(2);
551   aPrims->AddVertex(AttachmentPoint2);
552   aPrims->AddVertex(ptarr);
553
554   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
555 }
556
557
558 //==========================================================================
559 // function : DsgPrs_AnglePresentation::Add
560 // purpose  : It is possible to choose the symbol of extremities of the face (arrow, point...)
561 //==========================================================================
562
563 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
564                                     const Handle(Prs3d_Drawer)& aDrawer,
565                                     const Standard_Real theval,
566                                     const TCollection_ExtendedString& aText,
567                                     const gp_Pnt& CenterPoint,
568                                     const gp_Pnt& AttachmentPoint1,
569                                     const gp_Pnt& AttachmentPoint2,
570                                     const gp_Dir& dir1,
571                                     const gp_Dir& dir2,
572                                     const gp_Pnt& OffsetPoint,
573                                     const DsgPrs_ArrowSide ArrowPrs)
574 {
575   char valcar[80];
576   sprintf(valcar,"%5.2f",theval);
577   
578   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
579   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
580
581   gp_Dir Norm = dir1.Crossed(dir2);
582   if (Abs(theval) > M_PI) Norm.Reverse();
583
584   gp_Ax2 ax(CenterPoint,Norm,dir1);
585   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
586   gp_Vec vec1(dir1);
587   vec1 *= cer.Radius();
588   gp_Vec vec2(dir2);
589   vec2 *= cer.Radius();
590   gp_Pnt p2 = CenterPoint.Translated(vec2);
591
592   Standard_Real uc1 = 0.;
593   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
594   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
595
596   Standard_Real udeb = uc1;
597   Standard_Real ufin = uc2;
598
599   if (uco > ufin) {
600     if (Abs(theval)<M_PI) {
601       // test if uco is in the opposite sector 
602       if (uco > udeb+M_PI && uco < ufin+M_PI) {
603         udeb += M_PI;
604         ufin += M_PI;
605         uc1 = udeb;
606         uc2 = ufin;
607       }
608     }
609   }
610
611   if (uco > ufin) {
612     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
613       ufin = uco;
614     }
615     else {
616       udeb = uco - 2.*M_PI;
617     }
618   }
619
620   const Standard_Real alpha = Abs(ufin-udeb);
621   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
622   const Standard_Real dteta = alpha/(nbp-1);
623
624   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
625   aPrims->AddBound(nbp);
626   for (Standard_Integer i = 1; i<=nbp; i++)
627     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
628
629   Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, OffsetPoint);
630   
631   Standard_Real length = LA->ArrowAspect()->Length();
632   if (length <  Precision::Confusion()) length = 1.e-04;
633
634   // Lines of recall
635   gp_Vec vecarr;
636   gp_Pnt ptarr;
637   ElCLib::D1(uc1,cer,ptarr,vecarr);
638
639   gp_Ax1 ax1(ptarr, Norm);
640   gp_Dir dirarr(-vecarr);
641   //calculate angle of rotation
642   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
643   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
644   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
645   gp_Vec v1(ptarr,ptarr2 );
646   gp_Vec v2(ptarr, ptarr3);
647   const Standard_Real beta = v1.Angle(v2);
648   dirarr.Rotate(ax1, beta);
649
650   aPrims->AddBound(2);
651   aPrims->AddVertex(AttachmentPoint1);
652   aPrims->AddVertex(ptarr);
653   
654   gp_Vec vecarr1;
655   gp_Pnt ptarr1;
656   ElCLib::D1(uc2,cer,ptarr1,vecarr1);
657   ax1.SetLocation(ptarr1);
658   gp_Dir dirarr2(vecarr1);
659   dirarr2.Rotate(ax1,  - beta);
660
661   aPrims->AddBound(2);
662   aPrims->AddVertex(AttachmentPoint2);
663   aPrims->AddVertex(ptarr1);
664
665   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
666
667   // One traces the arrows
668   DsgPrs::ComputeSymbol(aPresentation,LA,ptarr,ptarr1,dirarr,dirarr2,ArrowPrs);
669 }
670
671
672 //==========================================================================
673 // function : DsgPrs_AnglePresentation::Add
674 // purpose  : 
675 //            
676 //==========================================================================
677
678 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
679                                     const Handle(Prs3d_Drawer)& aDrawer,
680                                     const Standard_Real theval,
681                                     const gp_Pnt& CenterPoint,
682                                     const gp_Pnt& AttachmentPoint1,
683                                     const gp_Pnt& AttachmentPoint2,
684                                     const gp_Dir& dir1,
685                                     const gp_Dir& dir2,
686                                     const gp_Pnt& OffsetPoint)
687 {
688   char valcar[80];
689   sprintf(valcar,"%5.2f",theval);
690
691   TCollection_AsciiString valas(valcar);
692   TCollection_ExtendedString aText(valas);
693
694   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
695   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
696
697   gp_Dir Norm = dir1.Crossed(dir2);
698   if (Abs(theval) > M_PI) Norm.Reverse();
699
700   gp_Ax2 ax(CenterPoint,Norm,dir1);
701   gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
702   gp_Vec vec1(dir1);
703   vec1 *= cer.Radius();
704   gp_Vec vec2(dir2);
705   vec2 *= cer.Radius();
706   gp_Pnt p2 = CenterPoint.Translated(vec2);
707
708   Standard_Real uc1 = 0.;
709   Standard_Real uc2 = ElCLib::Parameter(cer,p2);
710   Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
711
712   Standard_Real udeb = uc1;
713   Standard_Real ufin = uc2;
714
715   if (uco > ufin) {
716     if (Abs(theval)<M_PI) {
717       // test if uco is in the opposite sector 
718       if (uco > udeb+M_PI && uco < ufin+M_PI) {
719         udeb += M_PI;
720         ufin += M_PI;
721         uc1 = udeb;
722         uc2 = ufin;
723       }
724     }
725   }
726
727   if (uco > ufin) {
728     if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
729       ufin = uco;
730     }
731     else {
732       udeb = uco - 2.*M_PI;
733     }
734   }
735
736   const Standard_Real alpha = Abs(ufin-udeb);
737   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
738   const Standard_Real dteta = alpha/(nbp-1);
739
740   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
741   aPrims->AddBound(nbp);
742   for (Standard_Integer i = 1; i<=nbp; i++)
743     aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
744
745   Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, OffsetPoint);
746
747   Standard_Real length = LA->ArrowAspect()->Length();
748   if (length <  Precision::Confusion()) length = 1.e-04;
749
750   gp_Vec vecarr;
751   gp_Pnt ptarr;
752   ElCLib::D1(uc1,cer,ptarr,vecarr);
753
754   gp_Ax1 ax1(ptarr, Norm);
755   gp_Dir dirarr(-vecarr);
756   //calculate the angle of rotation
757   gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
758   const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
759   gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
760   gp_Vec v1(ptarr,ptarr2 );
761   gp_Vec v2(ptarr, ptarr3);
762   const Standard_Real beta = v1.Angle(v2);
763   dirarr.Rotate(ax1, beta);
764
765   Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr, LA->ArrowAspect()->Angle(), length);
766
767   aPrims->AddBound(2);
768   aPrims->AddVertex(AttachmentPoint1);
769   aPrims->AddVertex(ptarr);
770
771   ElCLib::D1(uc2,cer,ptarr,vecarr);
772   ax1.SetLocation(ptarr);
773   gp_Dir dirarr2(vecarr);
774   dirarr2.Rotate(ax1, -beta);
775
776   Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr2, LA->ArrowAspect()->Angle(), length);
777   
778   aPrims->AddBound(2);
779   aPrims->AddVertex(AttachmentPoint2);
780   aPrims->AddVertex(ptarr);
781
782   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
783 }
784
785 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
786                                     const Handle(Prs3d_Drawer)& aDrawer,
787                                     const Standard_Real theval,
788                                     const gp_Pnt& CenterPoint,
789                                     const gp_Pnt& AttachmentPoint1,
790                                     const gp_Ax1& theAxe,
791                                     const DsgPrs_ArrowSide ArrowSide)
792 {
793   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
794   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
795   
796   gp_Dir dir1(gp_Vec(CenterPoint, AttachmentPoint1));
797   gp_Ax2 ax(CenterPoint,theAxe.Direction(),dir1);
798   gp_Circ cer(ax,CenterPoint.Distance(AttachmentPoint1));
799
800   const Standard_Integer nbp = Max (4 , Standard_Integer (50. * theval / M_PI));
801   const Standard_Real dteta = theval/(nbp-1);
802
803   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp);
804   for (Standard_Integer i = 1; i<=nbp; i++)
805     aPrims->AddVertex(ElCLib::Value(dteta*(i-1),cer));
806   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
807
808   Standard_Real uc1 = 0.;
809   Standard_Real uc2 = ElCLib::Parameter(cer,AttachmentPoint1.Rotated(theAxe,theval));
810
811   Standard_Real length = LA->ArrowAspect()->Length();
812   if (length < Precision::Confusion()) length = 1.e-04;
813
814   gp_Vec vecarr;
815   gp_Pnt ptarr;
816   switch(ArrowSide)
817   {
818     case DsgPrs_AS_FIRSTAR:
819     {
820       ElCLib::D1(uc1,cer,ptarr,vecarr);
821       Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(-vecarr), LA->ArrowAspect()->Angle(), length);
822       break;
823     }
824     case DsgPrs_AS_LASTAR:
825     {
826       ElCLib::D1(uc2,cer,ptarr,vecarr);
827       Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(vecarr), LA->ArrowAspect()->Angle(), length);
828       break;
829     }
830     case DsgPrs_AS_BOTHAR:
831     {
832       ElCLib::D1(uc1,cer,ptarr,vecarr);
833       Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(-vecarr), LA->ArrowAspect()->Angle(), length);
834       ElCLib::D1(uc2,cer,ptarr,vecarr);
835       Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(vecarr), LA->ArrowAspect()->Angle(), length);
836       break;
837     }
838     default: break;
839   }
840 }