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