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