1 // Created on: 1995-02-07
2 // Copyright (c) 1995-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 #include <Aspect_AspectMarker.hxx>
18 #include <Aspect_TypeOfLine.hxx>
19 #include <Aspect_TypeOfMarker.hxx>
21 #include <DsgPrs_AnglePresentation.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>
29 #include <gp_Circ.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>
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)
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() );
61 if ( D >= D1 && D >= D2 ) return 0;
62 if ( D < D2 && D1 < D2 ) return -1;
63 if ( D < D1 && D2 < D1 ) return 1;
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,
80 const gp_Circ& VminCircle,
81 const gp_Circ& VmaxCircle,
82 const Standard_Real aArrowSize)
84 Handle(Prs3d_DimensionAspect) aDimensionAspect = aDrawer->DimensionAspect();
86 TCollection_ExtendedString txt(aText);
88 const Standard_Real myArrowSize = ( aArrowSize == 0.0 )? (0.1 * aCircle.Radius()) : aArrowSize;
90 aDimensionAspect->ArrowAspect()->SetLength(myArrowSize);
91 aDrawer->ArrowAspect()->SetLength(myArrowSize);
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;
100 gp_Pnt P1 = ElCLib::Value(0., myCircle);
101 gp_Pnt P2 = ElCLib::Value(M_PI, myCircle);
103 gce_MakePln mkPln(P1, P2, Apex); // create a plane whitch defines plane for projection aPosition on it
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;
109 gp_Pnt aPnt = aPosition;
110 aPnt = aPnt.Translated( -Normal );
112 gp_Pnt tmpPnt = aPnt;
114 gp_Pnt AttachmentPnt, OppositePnt;
115 if( aPnt.Distance(P1) < aPnt.Distance(P2) ) {
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
128 GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt);
129 gp_Circ aCircle2 = mkCirc.Value()->Circ();
132 Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt); //must be equal to zero (look circle construction)
133 Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
135 while ( AttParam >= 2. * M_PI ) AttParam -= 2. * M_PI;
136 while ( OppParam >= 2. * M_PI ) OppParam -= 2. * M_PI;
138 //-------------------------- Compute angle ------------------------
139 if( txt.Length() == 0 ) {
140 Standard_Real angle = UnitsAPI::CurrentFromLS( Abs( OppParam ),"PLANE ANGLE");
142 sprintf(res, "%g", angle );
143 txt = TCollection_ExtendedString(res);
145 //-----------------------------------------------------------------
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
151 Standard_Real angle = OppParam - AttParam;
152 Standard_Real param = AttParam;
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) ) );
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 ) ) );
164 while ( angle > 2. * M_PI ) angle -= 2. * M_PI;
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);
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);
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
181 angle = 2. * M_PI - param ;
182 if( param > OppParam )
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);
191 if( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 1 && !IsConeTrimmed ) //above
193 aPrims = new Graphic3d_ArrayOfPolylines(3);
194 aPrims->AddVertex(AttachmentPnt);
195 aPrims->AddVertex(Apex);
196 aPrims->AddVertex(OppositePnt);
201 if ( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 0 ) return;
203 gp_Pnt P11 = ElCLib::Value( 0., VmaxCircle );
204 gp_Pnt P12 = ElCLib::Value( M_PI, VmaxCircle );
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);
212 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
216 //==========================================================================
217 // function : DsgPrs_AnglePresentation::Add
220 //==========================================================================
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,
231 const gp_Dir& axisdir,
232 const gp_Pnt& OffsetPoint)
235 sprintf(valcar,"%5.2f",theval);
237 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
238 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
240 gp_Ax2 ax(CenterPoint,axisdir,dir1);
241 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
243 vec1 *= cer.Radius();
245 vec2 *= cer.Radius();
246 gp_Pnt p2 = CenterPoint.Translated(vec2);
248 Standard_Real uc1 = 0.;
249 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
250 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
252 Standard_Real udeb = uc1;
253 Standard_Real ufin = uc2;
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) {
268 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
272 udeb = uco - 2.*M_PI;
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);
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));
285 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
287 Standard_Real length = LA->ArrowAspect()->Length();
288 if (length < Precision::Confusion()) length = 1.e-04;
292 ElCLib::D1(uc1,cer,ptarr,vecarr);
294 gp_Ax1 ax1(ptarr, axisdir);
295 gp_Dir dirarr(-vecarr);
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);
308 aPrims->AddVertex(AttachmentPoint1);
309 aPrims->AddVertex(ptarr);
311 ElCLib::D1(uc2,cer,ptarr,vecarr);
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);
319 aPrims->AddVertex(AttachmentPoint2);
320 aPrims->AddVertex(ptarr);
322 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
326 //==========================================================================
327 // function : DsgPrs_AnglePresentation::Add
328 // purpose : Adds prezentation of angle between two faces
329 //==========================================================================
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,
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 )
347 sprintf(valcar,"%5.2f",theval);
349 Handle( Prs3d_DimensionAspect ) LA = aDrawer->DimensionAspect();
350 Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
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(),
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())
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 );
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 ));
392 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
393 aPrims = new Graphic3d_ArrayOfSegments(4);
397 aPrims = new Graphic3d_ArrayOfSegments(6);
398 aPrims->AddVertex(OffsetPoint);
399 aPrims->AddVertex(EndOfArrow1);
402 // Add presentation of arrows
403 DsgPrs::ComputeSymbol( aPresentation, LA, EndOfArrow1, EndOfArrow2, DirOfArrow1, DirOfArrow2, ArrowPrs );
406 Prs3d_Text::Draw( aPresentation, LA->TextAspect(), aText, OffsetPoint );
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);
415 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
417 // Line or arc from AttachmentPoint2 to its "projection"
418 if (AttachmentPoint2.Distance( ProjAttachPoint2 ) > Precision::Confusion())
422 // Creating the line from AttachmentPoint2 to its projection
423 aPrims = new Graphic3d_ArrayOfSegments(2);
424 aPrims->AddVertex(AttachmentPoint2);
425 aPrims->AddVertex(ProjAttachPoint2);
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 );
434 aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber);
435 for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAttachCirc += delta)
436 aPrims->AddVertex(ElCLib::Value( FirstParAttachCirc, AttachCirc ));
438 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
443 //==========================================================================
444 // function : DsgPrs_AnglePresentation::Add
447 //==========================================================================
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,
458 const gp_Pnt& OffsetPoint)
461 sprintf(valcar,"%5.2f",theval);
463 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
464 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
467 if (!dir1.IsParallel(dir2, Precision::Angular())) {
468 Norm = dir1.Crossed(dir2);
471 gp_Dir dir2B = gp_Dir(gp_Vec(CenterPoint, OffsetPoint));
472 Norm = dir1.Crossed(dir2B);
475 if (Abs(theval) > M_PI) Norm.Reverse();
477 gp_Ax2 ax(CenterPoint,Norm,dir1);
478 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
480 vec1 *= cer.Radius();
482 vec2 *= cer.Radius();
483 gp_Pnt p2 = CenterPoint.Translated(vec2);
485 Standard_Real uc1 = 0.;
486 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
487 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
489 Standard_Real udeb = uc1;
490 Standard_Real ufin = uc2;
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) {
505 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
509 udeb = uco - 2.*M_PI;
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);
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));
522 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
524 Standard_Real length = LA->ArrowAspect()->Length();
525 if (length < Precision::Confusion()) length = 1.e-04;
529 ElCLib::D1(uc1,cer,ptarr,vecarr);
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);
544 aPrims->AddVertex(AttachmentPoint1);
545 aPrims->AddVertex(ptarr);
547 ElCLib::D1(uc2,cer,ptarr,vecarr);
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);
555 aPrims->AddVertex(AttachmentPoint2);
556 aPrims->AddVertex(ptarr);
558 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
562 //==========================================================================
563 // function : DsgPrs_AnglePresentation::Add
564 // purpose : It is possible to choose the symbol of extremities of the face (arrow, point...)
565 //==========================================================================
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,
576 const gp_Pnt& OffsetPoint,
577 const DsgPrs_ArrowSide ArrowPrs)
580 sprintf(valcar,"%5.2f",theval);
582 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
583 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
585 gp_Dir Norm = dir1.Crossed(dir2);
586 if (Abs(theval) > M_PI) Norm.Reverse();
588 gp_Ax2 ax(CenterPoint,Norm,dir1);
589 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
591 vec1 *= cer.Radius();
593 vec2 *= cer.Radius();
594 gp_Pnt p2 = CenterPoint.Translated(vec2);
596 Standard_Real uc1 = 0.;
597 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
598 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
600 Standard_Real udeb = uc1;
601 Standard_Real ufin = uc2;
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) {
616 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
620 udeb = uco - 2.*M_PI;
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);
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));
633 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
635 Standard_Real length = LA->ArrowAspect()->Length();
636 if (length < Precision::Confusion()) length = 1.e-04;
641 ElCLib::D1(uc1,cer,ptarr,vecarr);
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);
655 aPrims->AddVertex(AttachmentPoint1);
656 aPrims->AddVertex(ptarr);
660 ElCLib::D1(uc2,cer,ptarr1,vecarr1);
661 ax1.SetLocation(ptarr1);
662 gp_Dir dirarr2(vecarr1);
663 dirarr2.Rotate(ax1, - beta);
666 aPrims->AddVertex(AttachmentPoint2);
667 aPrims->AddVertex(ptarr1);
669 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
671 // One traces the arrows
672 DsgPrs::ComputeSymbol(aPresentation,LA,ptarr,ptarr1,dirarr,dirarr2,ArrowPrs);
676 //==========================================================================
677 // function : DsgPrs_AnglePresentation::Add
680 //==========================================================================
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,
690 const gp_Pnt& OffsetPoint)
693 sprintf(valcar,"%5.2f",theval);
695 TCollection_AsciiString valas(valcar);
696 TCollection_ExtendedString aText(valas);
698 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
699 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
701 gp_Dir Norm = dir1.Crossed(dir2);
702 if (Abs(theval) > M_PI) Norm.Reverse();
704 gp_Ax2 ax(CenterPoint,Norm,dir1);
705 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
707 vec1 *= cer.Radius();
709 vec2 *= cer.Radius();
710 gp_Pnt p2 = CenterPoint.Translated(vec2);
712 Standard_Real uc1 = 0.;
713 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
714 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
716 Standard_Real udeb = uc1;
717 Standard_Real ufin = uc2;
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) {
732 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
736 udeb = uco - 2.*M_PI;
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);
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));
749 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
751 Standard_Real length = LA->ArrowAspect()->Length();
752 if (length < Precision::Confusion()) length = 1.e-04;
756 ElCLib::D1(uc1,cer,ptarr,vecarr);
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);
769 Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr,LA->ArrowAspect()->Angle(),length);
772 aPrims->AddVertex(AttachmentPoint1);
773 aPrims->AddVertex(ptarr);
775 ElCLib::D1(uc2,cer,ptarr,vecarr);
776 ax1.SetLocation(ptarr);
777 gp_Dir dirarr2(vecarr);
778 dirarr2.Rotate(ax1, -beta);
780 Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr2,LA->ArrowAspect()->Angle(),length);
783 aPrims->AddVertex(AttachmentPoint2);
784 aPrims->AddVertex(ptarr);
786 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
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)
797 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
798 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
800 gp_Dir dir1(gp_Vec(CenterPoint, AttachmentPoint1));
801 gp_Ax2 ax(CenterPoint,theAxe.Direction(),dir1);
802 gp_Circ cer(ax,CenterPoint.Distance(AttachmentPoint1));
804 const Standard_Integer nbp = Max (4 , Standard_Integer (50. * theval / M_PI));
805 const Standard_Real dteta = theval/(nbp-1);
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);
812 Standard_Real uc1 = 0.;
813 Standard_Real uc2 = ElCLib::Parameter(cer,AttachmentPoint1.Rotated(theAxe,theval));
815 Standard_Real length = LA->ArrowAspect()->Length();
816 if (length < Precision::Confusion()) length = 1.e-04;
822 case DsgPrs_AS_FIRSTAR:
824 ElCLib::D1(uc1,cer,ptarr,vecarr);
825 Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(-vecarr),LA->ArrowAspect()->Angle(),length);
828 case DsgPrs_AS_LASTAR:
830 ElCLib::D1(uc2,cer,ptarr,vecarr);
831 Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(vecarr),LA->ArrowAspect()->Angle(),length);
834 case DsgPrs_AS_BOTHAR:
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);