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