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.
16 #include <DsgPrs_AnglePresentation.hxx>
20 #include <GC_MakeCircle.hxx>
21 #include <gce_MakePln.hxx>
22 #include <Geom_Circle.hxx>
23 #include <Geom_Line.hxx>
24 #include <GeomAPI_ExtremaCurveCurve.hxx>
26 #include <gp_Circ.hxx>
30 #include <Graphic3d_ArrayOfPolylines.hxx>
31 #include <Graphic3d_ArrayOfSegments.hxx>
32 #include <Graphic3d_AspectLine3d.hxx>
33 #include <Graphic3d_AspectMarker3d.hxx>
34 #include <Graphic3d_Group.hxx>
35 #include <Precision.hxx>
36 #include <Prs3d_Arrow.hxx>
37 #include <Prs3d_ArrowAspect.hxx>
38 #include <Prs3d_DimensionAspect.hxx>
39 #include <Prs3d_LineAspect.hxx>
40 #include <Prs3d_Presentation.hxx>
41 #include <Prs3d_Text.hxx>
42 #include <TCollection_AsciiString.hxx>
43 #include <TCollection_ExtendedString.hxx>
44 #include <UnitsAPI.hxx>
47 //------------------------------------------------------------------------------------------------------------------
48 // Returns 1 if C is above of CMin; 0 if C is bitween CMin and CMax; -1 if C is Below CMax
49 //-----------------------------------------------------------------------------------------------------------------
50 static Standard_Integer AboveInBelowCone(const gp_Circ &CMax, const gp_Circ &CMin, const gp_Circ &C)
52 const Standard_Real D = CMax.Location().Distance( CMin.Location() );
53 const Standard_Real D1 = CMax.Location().Distance( C.Location() );
54 const Standard_Real D2 = CMin.Location().Distance( C.Location() );
56 if ( D >= D1 && D >= D2 ) return 0;
57 if ( D < D2 && D1 < D2 ) return -1;
58 if ( D < D1 && D2 < D1 ) return 1;
64 //==========================================================================
65 // function : DsgPrs_AnglePresentation::Add
66 // purpose : draws the presentation of the cone's angle;
67 //==========================================================================
68 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
69 const Handle(Prs3d_Drawer)& aDrawer,
70 const Standard_Real /*aVal*/,
71 const TCollection_ExtendedString& aText,
72 const gp_Circ& aCircle,
73 const gp_Pnt& aPosition,
75 const gp_Circ& VminCircle,
76 const gp_Circ& VmaxCircle,
77 const Standard_Real aArrowSize)
79 Handle(Prs3d_DimensionAspect) aDimensionAspect = aDrawer->DimensionAspect();
81 TCollection_ExtendedString txt(aText);
83 const Standard_Real myArrowSize = ( aArrowSize == 0.0 )? (0.1 * aCircle.Radius()) : aArrowSize;
85 aDimensionAspect->ArrowAspect()->SetLength(myArrowSize);
86 aDrawer->ArrowAspect()->SetLength(myArrowSize);
88 Standard_Boolean IsConeTrimmed = Standard_False;
89 gp_Circ myCircle = aCircle;
90 if( VminCircle.Radius() > 0.01 ) {
91 IsConeTrimmed = Standard_True;
92 if( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 1 ) myCircle = VminCircle;
95 gp_Pnt P1 = ElCLib::Value(0., myCircle);
96 gp_Pnt P2 = ElCLib::Value(M_PI, myCircle);
98 gce_MakePln mkPln(P1, P2, Apex); // create a plane whitch defines plane for projection aPosition on it
100 gp_Vec aVector( mkPln.Value().Location(), aPosition ); //project aPosition on a plane
101 gp_Vec Normal = mkPln.Value().Axis().Direction();
102 Normal = (aVector * Normal) * Normal;
104 gp_Pnt aPnt = aPosition;
105 aPnt = aPnt.Translated( -Normal );
107 gp_Pnt tmpPnt = aPnt;
109 gp_Pnt AttachmentPnt, OppositePnt;
110 if( aPnt.Distance(P1) < aPnt.Distance(P2) ) {
119 aPnt = AttachmentPnt ; // Creating of circle whitch defines a plane for a dimension arc
120 gp_Vec Vec(AttachmentPnt, Apex); // Dimension arc is a part of the circle
123 GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt);
124 gp_Circ aCircle2 = mkCirc.Value()->Circ();
127 Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt); //must be equal to zero (look circle construction)
128 Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
130 while ( AttParam >= 2. * M_PI ) AttParam -= 2. * M_PI;
131 while ( OppParam >= 2. * M_PI ) OppParam -= 2. * M_PI;
133 //-------------------------- Compute angle ------------------------
134 if( txt.Length() == 0 ) {
135 Standard_Real angle = UnitsAPI::CurrentFromLS( Abs( OppParam ),"PLANE ANGLE");
137 sprintf(res, "%g", angle );
138 txt = TCollection_ExtendedString(res);
140 //-----------------------------------------------------------------
142 Standard_Boolean IsArrowOut = Standard_True; //Is arrows inside or outside of the cone
143 if( ElCLib::Parameter(aCircle2, tmpPnt) < OppParam )
144 if( 2. * myCircle.Radius() > 4. * myArrowSize ) IsArrowOut = Standard_False; //four times more than an arrow size
146 Standard_Real angle = OppParam - AttParam;
147 Standard_Real param = AttParam;
151 aDir = gp_Dir( ( gp_Vec( ElCLib::Value( AttParam - M_PI / 12., aCircle2 ), AttachmentPnt) ) );
152 aDir2 = gp_Dir( ( gp_Vec( ElCLib::Value( OppParam + M_PI / 12., aCircle2 ), OppositePnt) ) );
155 aDir = gp_Dir( ( gp_Vec( ElCLib::Value( AttParam + M_PI / 12., aCircle2 ), AttachmentPnt ) ) );
156 aDir2 = gp_Dir( ( gp_Vec( ElCLib::Value( OppParam - M_PI / 12., aCircle2 ), OppositePnt ) ) );
159 while ( angle > 2. * M_PI ) angle -= 2. * M_PI;
161 Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(12);
162 for( i = 0; i <= 11; i++ )
163 aPrims->AddVertex(ElCLib::Value(param + angle/11 * i, aCircle2));
164 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
166 DsgPrs::ComputeSymbol(aPresentation, aDimensionAspect, AttachmentPnt,
167 AttachmentPnt, aDir, aDir, DsgPrs_AS_LASTAR);
168 DsgPrs::ComputeSymbol(aPresentation, aDimensionAspect, OppositePnt,
169 OppositePnt, aDir2, aDir2, DsgPrs_AS_LASTAR);
171 param = ElCLib::Parameter(aCircle2, tmpPnt);
172 tmpPnt = ElCLib::Value(param, aCircle2);
173 tmpPnt = tmpPnt.Translated(gp_Vec(0, 0, -2));
174 Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), aDimensionAspect->TextAspect(), txt, tmpPnt);
176 angle = 2. * M_PI - param ;
177 if( param > OppParam )
179 while ( angle > 2. * M_PI ) angle -= 2. * M_PI;
180 aPrims = new Graphic3d_ArrayOfPolylines(12);
181 for( i = 11; i >= 0; i-- )
182 aPrims->AddVertex(ElCLib::Value(-angle/11 * i, aCircle2));
183 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
186 if( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 1 && !IsConeTrimmed ) //above
188 aPrims = new Graphic3d_ArrayOfPolylines(3);
189 aPrims->AddVertex(AttachmentPnt);
190 aPrims->AddVertex(Apex);
191 aPrims->AddVertex(OppositePnt);
196 if ( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 0 ) return;
198 gp_Pnt P11 = ElCLib::Value( 0., VmaxCircle );
199 gp_Pnt P12 = ElCLib::Value( M_PI, VmaxCircle );
201 aPrims = new Graphic3d_ArrayOfSegments(4);
202 aPrims->AddVertex(AttachmentPnt);
203 aPrims->AddVertex(( aPnt.Distance(P1) < aPnt.Distance(P2) )? P12 : P11);
204 aPrims->AddVertex(OppositePnt);
205 aPrims->AddVertex(( aPnt.Distance(P1) < aPnt.Distance(P2) )? P11 : P12);
207 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
211 //==========================================================================
212 // function : DsgPrs_AnglePresentation::Add
215 //==========================================================================
217 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
218 const Handle(Prs3d_Drawer)& aDrawer,
219 const Standard_Real theval,
220 const TCollection_ExtendedString& aText,
221 const gp_Pnt& CenterPoint,
222 const gp_Pnt& AttachmentPoint1,
223 const gp_Pnt& AttachmentPoint2,
226 const gp_Dir& axisdir,
227 const gp_Pnt& OffsetPoint)
230 sprintf(valcar,"%5.2f",theval);
232 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
233 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPresentation);
234 aGroup->SetPrimitivesAspect(LA->LineAspect()->Aspect());
236 gp_Ax2 ax(CenterPoint,axisdir,dir1);
237 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
239 vec1 *= cer.Radius();
241 vec2 *= cer.Radius();
242 gp_Pnt p2 = CenterPoint.Translated(vec2);
244 Standard_Real uc1 = 0.;
245 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
246 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
248 Standard_Real udeb = uc1;
249 Standard_Real ufin = uc2;
252 if (Abs(theval)<M_PI) {
253 // test if uco is in the opposite sector
254 if (uco > udeb+M_PI && uco < ufin+M_PI) {
264 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
268 udeb = uco - 2.*M_PI;
272 const Standard_Real alpha = Abs(ufin-udeb);
273 const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
274 const Standard_Real dteta = alpha/(nbp-1);
276 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
277 aPrims->AddBound(nbp);
278 for (Standard_Integer i = 1; i<=nbp; i++)
279 aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
281 Prs3d_Text::Draw (aGroup, LA->TextAspect(), aText, OffsetPoint);
283 Standard_Real length = LA->ArrowAspect()->Length();
284 if (length < Precision::Confusion()) length = 1.e-04;
288 ElCLib::D1(uc1,cer,ptarr,vecarr);
290 gp_Ax1 ax1(ptarr, axisdir);
291 gp_Dir dirarr(-vecarr);
293 //calculate angle of rotation
294 gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
295 const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
296 gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
297 gp_Vec v1(ptarr,ptarr2);
298 gp_Vec v2(ptarr,ptarr3);
299 const Standard_Real beta = v1.Angle(v2);
300 dirarr.Rotate(ax1, beta);
301 Prs3d_Arrow::Draw (aGroup, ptarr, dirarr, LA->ArrowAspect()->Angle(), length);
304 aPrims->AddVertex(AttachmentPoint1);
305 aPrims->AddVertex(ptarr);
307 ElCLib::D1(uc2,cer,ptarr,vecarr);
309 ax1.SetLocation(ptarr);
310 gp_Dir dirarr2(vecarr);
311 dirarr2.Rotate(ax1,-beta);
312 Prs3d_Arrow::Draw (aGroup, ptarr, dirarr2, LA->ArrowAspect()->Angle(), length);
315 aPrims->AddVertex(AttachmentPoint2);
316 aPrims->AddVertex(ptarr);
318 aGroup->AddPrimitiveArray (aPrims);
322 //==========================================================================
323 // function : DsgPrs_AnglePresentation::Add
324 // purpose : Adds prezentation of angle between two faces
325 //==========================================================================
327 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
328 const Handle(Prs3d_Drawer)& aDrawer,
329 const Standard_Real theval,
330 const TCollection_ExtendedString& aText,
331 const gp_Pnt& CenterPoint,
332 const gp_Pnt& AttachmentPoint1,
333 const gp_Pnt& AttachmentPoint2,
336 const gp_Dir& axisdir,
337 const Standard_Boolean isPlane,
338 const gp_Ax1& AxisOfSurf,
339 const gp_Pnt& OffsetPoint,
340 const DsgPrs_ArrowSide ArrowPrs )
343 sprintf(valcar,"%5.2f",theval);
345 Handle( Prs3d_DimensionAspect ) LA = aDrawer->DimensionAspect();
346 Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
348 gp_Circ AngleCirc, AttachCirc;
349 Standard_Real FirstParAngleCirc, LastParAngleCirc, FirstParAttachCirc, LastParAttachCirc;
350 gp_Pnt EndOfArrow1, EndOfArrow2, ProjAttachPoint2;
351 gp_Dir DirOfArrow1, DirOfArrow2;
352 DsgPrs::ComputeFacesAnglePresentation( LA->ArrowAspect()->Length(),
375 // Creating the angle's arc or line if null angle
376 Handle(Graphic3d_ArrayOfPrimitives) aPrims;
377 if (theval > Precision::Angular() && Abs( M_PI-theval ) > Precision::Angular())
379 const Standard_Real Alpha = Abs( LastParAngleCirc - FirstParAngleCirc );
380 const Standard_Integer NodeNumber = Max (4 , Standard_Integer (50. * Alpha / M_PI));
381 const Standard_Real delta = Alpha / (Standard_Real)( NodeNumber - 1 );
383 aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber+4,3);
384 aPrims->AddBound(NodeNumber);
385 for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAngleCirc += delta)
386 aPrims->AddVertex(ElCLib::Value( FirstParAngleCirc, AngleCirc ));
388 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
389 aPrims = new Graphic3d_ArrayOfSegments(4);
393 aPrims = new Graphic3d_ArrayOfSegments(6);
394 aPrims->AddVertex(OffsetPoint);
395 aPrims->AddVertex(EndOfArrow1);
398 // Add presentation of arrows
399 DsgPrs::ComputeSymbol( aPresentation, LA, EndOfArrow1, EndOfArrow2, DirOfArrow1, DirOfArrow2, ArrowPrs );
402 Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, OffsetPoint);
404 // Line from AttachmentPoint1 to end of Arrow1
405 aPrims->AddVertex(AttachmentPoint1);
406 aPrims->AddVertex(EndOfArrow1);
407 // Line from "projection" of AttachmentPoint2 to end of Arrow2
408 aPrims->AddVertex(ProjAttachPoint2);
409 aPrims->AddVertex(EndOfArrow2);
411 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
413 // Line or arc from AttachmentPoint2 to its "projection"
414 if (AttachmentPoint2.Distance( ProjAttachPoint2 ) > Precision::Confusion())
418 // Creating the line from AttachmentPoint2 to its projection
419 aPrims = new Graphic3d_ArrayOfSegments(2);
420 aPrims->AddVertex(AttachmentPoint2);
421 aPrims->AddVertex(ProjAttachPoint2);
425 // Creating the arc from AttachmentPoint2 to its projection
426 const Standard_Real Alpha = Abs( LastParAttachCirc - FirstParAttachCirc );
427 const Standard_Integer NodeNumber = Max (4 , Standard_Integer (50. * Alpha / M_PI));
428 const Standard_Real delta = Alpha / (Standard_Real)( NodeNumber - 1 );
430 aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber);
431 for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAttachCirc += delta)
432 aPrims->AddVertex(ElCLib::Value( FirstParAttachCirc, AttachCirc ));
434 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
439 //==========================================================================
440 // function : DsgPrs_AnglePresentation::Add
443 //==========================================================================
445 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
446 const Handle(Prs3d_Drawer)& aDrawer,
447 const Standard_Real theval,
448 const TCollection_ExtendedString& aText,
449 const gp_Pnt& CenterPoint,
450 const gp_Pnt& AttachmentPoint1,
451 const gp_Pnt& AttachmentPoint2,
454 const gp_Pnt& OffsetPoint)
457 sprintf(valcar,"%5.2f",theval);
459 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
460 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
463 if (!dir1.IsParallel(dir2, Precision::Angular())) {
464 Norm = dir1.Crossed(dir2);
467 gp_Dir dir2B = gp_Dir(gp_Vec(CenterPoint, OffsetPoint));
468 Norm = dir1.Crossed(dir2B);
471 if (Abs(theval) > M_PI) Norm.Reverse();
473 gp_Ax2 ax(CenterPoint,Norm,dir1);
474 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
476 vec1 *= cer.Radius();
478 vec2 *= cer.Radius();
479 gp_Pnt p2 = CenterPoint.Translated(vec2);
481 Standard_Real uc1 = 0.;
482 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
483 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
485 Standard_Real udeb = uc1;
486 Standard_Real ufin = uc2;
489 if (Abs(theval)<M_PI) {
490 // test if uco is in the opposite sector
491 if (uco > udeb+M_PI && uco < ufin+M_PI) {
501 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
505 udeb = uco - 2.*M_PI;
509 const Standard_Real alpha = Abs(ufin-udeb);
510 const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
511 const Standard_Real dteta = alpha/(nbp-1);
513 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
514 aPrims->AddBound(nbp);
515 for (Standard_Integer i = 1; i<=nbp; i++)
516 aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
518 Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText,OffsetPoint);
520 Standard_Real length = LA->ArrowAspect()->Length();
521 if (length < Precision::Confusion()) length = 1.e-04;
525 ElCLib::D1(uc1,cer,ptarr,vecarr);
527 gp_Ax1 ax1(ptarr, Norm);
528 gp_Dir dirarr(-vecarr);
529 //calculate the angle of rotation
530 gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
531 const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
532 gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
533 gp_Vec v1(ptarr,ptarr2);
534 gp_Vec v2(ptarr,ptarr3);
535 const Standard_Real beta = v1.Angle(v2);
536 dirarr.Rotate(ax1, beta);
537 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr, LA->ArrowAspect()->Angle(), length);
540 aPrims->AddVertex(AttachmentPoint1);
541 aPrims->AddVertex(ptarr);
543 ElCLib::D1(uc2,cer,ptarr,vecarr);
545 ax1.SetLocation(ptarr);
546 gp_Dir dirarr2(vecarr);
547 dirarr2.Rotate(ax1, - beta);
548 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr2, LA->ArrowAspect()->Angle(), length);
551 aPrims->AddVertex(AttachmentPoint2);
552 aPrims->AddVertex(ptarr);
554 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
558 //==========================================================================
559 // function : DsgPrs_AnglePresentation::Add
560 // purpose : It is possible to choose the symbol of extremities of the face (arrow, point...)
561 //==========================================================================
563 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
564 const Handle(Prs3d_Drawer)& aDrawer,
565 const Standard_Real theval,
566 const TCollection_ExtendedString& aText,
567 const gp_Pnt& CenterPoint,
568 const gp_Pnt& AttachmentPoint1,
569 const gp_Pnt& AttachmentPoint2,
572 const gp_Pnt& OffsetPoint,
573 const DsgPrs_ArrowSide ArrowPrs)
576 sprintf(valcar,"%5.2f",theval);
578 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
579 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
581 gp_Dir Norm = dir1.Crossed(dir2);
582 if (Abs(theval) > M_PI) Norm.Reverse();
584 gp_Ax2 ax(CenterPoint,Norm,dir1);
585 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
587 vec1 *= cer.Radius();
589 vec2 *= cer.Radius();
590 gp_Pnt p2 = CenterPoint.Translated(vec2);
592 Standard_Real uc1 = 0.;
593 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
594 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
596 Standard_Real udeb = uc1;
597 Standard_Real ufin = uc2;
600 if (Abs(theval)<M_PI) {
601 // test if uco is in the opposite sector
602 if (uco > udeb+M_PI && uco < ufin+M_PI) {
612 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
616 udeb = uco - 2.*M_PI;
620 const Standard_Real alpha = Abs(ufin-udeb);
621 const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
622 const Standard_Real dteta = alpha/(nbp-1);
624 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
625 aPrims->AddBound(nbp);
626 for (Standard_Integer i = 1; i<=nbp; i++)
627 aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
629 Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, OffsetPoint);
631 Standard_Real length = LA->ArrowAspect()->Length();
632 if (length < Precision::Confusion()) length = 1.e-04;
637 ElCLib::D1(uc1,cer,ptarr,vecarr);
639 gp_Ax1 ax1(ptarr, Norm);
640 gp_Dir dirarr(-vecarr);
641 //calculate angle of rotation
642 gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
643 const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
644 gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
645 gp_Vec v1(ptarr,ptarr2 );
646 gp_Vec v2(ptarr, ptarr3);
647 const Standard_Real beta = v1.Angle(v2);
648 dirarr.Rotate(ax1, beta);
651 aPrims->AddVertex(AttachmentPoint1);
652 aPrims->AddVertex(ptarr);
656 ElCLib::D1(uc2,cer,ptarr1,vecarr1);
657 ax1.SetLocation(ptarr1);
658 gp_Dir dirarr2(vecarr1);
659 dirarr2.Rotate(ax1, - beta);
662 aPrims->AddVertex(AttachmentPoint2);
663 aPrims->AddVertex(ptarr1);
665 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
667 // One traces the arrows
668 DsgPrs::ComputeSymbol(aPresentation,LA,ptarr,ptarr1,dirarr,dirarr2,ArrowPrs);
672 //==========================================================================
673 // function : DsgPrs_AnglePresentation::Add
676 //==========================================================================
678 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
679 const Handle(Prs3d_Drawer)& aDrawer,
680 const Standard_Real theval,
681 const gp_Pnt& CenterPoint,
682 const gp_Pnt& AttachmentPoint1,
683 const gp_Pnt& AttachmentPoint2,
686 const gp_Pnt& OffsetPoint)
689 sprintf(valcar,"%5.2f",theval);
691 TCollection_AsciiString valas(valcar);
692 TCollection_ExtendedString aText(valas);
694 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
695 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
697 gp_Dir Norm = dir1.Crossed(dir2);
698 if (Abs(theval) > M_PI) Norm.Reverse();
700 gp_Ax2 ax(CenterPoint,Norm,dir1);
701 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
703 vec1 *= cer.Radius();
705 vec2 *= cer.Radius();
706 gp_Pnt p2 = CenterPoint.Translated(vec2);
708 Standard_Real uc1 = 0.;
709 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
710 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
712 Standard_Real udeb = uc1;
713 Standard_Real ufin = uc2;
716 if (Abs(theval)<M_PI) {
717 // test if uco is in the opposite sector
718 if (uco > udeb+M_PI && uco < ufin+M_PI) {
728 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
732 udeb = uco - 2.*M_PI;
736 const Standard_Real alpha = Abs(ufin-udeb);
737 const Standard_Integer nbp = Max (4 , Standard_Integer (50. * alpha / M_PI));
738 const Standard_Real dteta = alpha/(nbp-1);
740 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+4,3);
741 aPrims->AddBound(nbp);
742 for (Standard_Integer i = 1; i<=nbp; i++)
743 aPrims->AddVertex(ElCLib::Value(udeb+ dteta*(i-1),cer));
745 Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, OffsetPoint);
747 Standard_Real length = LA->ArrowAspect()->Length();
748 if (length < Precision::Confusion()) length = 1.e-04;
752 ElCLib::D1(uc1,cer,ptarr,vecarr);
754 gp_Ax1 ax1(ptarr, Norm);
755 gp_Dir dirarr(-vecarr);
756 //calculate the angle of rotation
757 gp_Pnt ptarr2(ptarr.XYZ() + length*dirarr.XYZ());
758 const Standard_Real parcir = ElCLib::Parameter(cer, ptarr2);
759 gp_Pnt ptarr3 = ElCLib::Value(parcir, cer);
760 gp_Vec v1(ptarr,ptarr2 );
761 gp_Vec v2(ptarr, ptarr3);
762 const Standard_Real beta = v1.Angle(v2);
763 dirarr.Rotate(ax1, beta);
765 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr, LA->ArrowAspect()->Angle(), length);
768 aPrims->AddVertex(AttachmentPoint1);
769 aPrims->AddVertex(ptarr);
771 ElCLib::D1(uc2,cer,ptarr,vecarr);
772 ax1.SetLocation(ptarr);
773 gp_Dir dirarr2(vecarr);
774 dirarr2.Rotate(ax1, -beta);
776 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, dirarr2, LA->ArrowAspect()->Angle(), length);
779 aPrims->AddVertex(AttachmentPoint2);
780 aPrims->AddVertex(ptarr);
782 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
785 void DsgPrs_AnglePresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
786 const Handle(Prs3d_Drawer)& aDrawer,
787 const Standard_Real theval,
788 const gp_Pnt& CenterPoint,
789 const gp_Pnt& AttachmentPoint1,
790 const gp_Ax1& theAxe,
791 const DsgPrs_ArrowSide ArrowSide)
793 Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
794 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
796 gp_Dir dir1(gp_Vec(CenterPoint, AttachmentPoint1));
797 gp_Ax2 ax(CenterPoint,theAxe.Direction(),dir1);
798 gp_Circ cer(ax,CenterPoint.Distance(AttachmentPoint1));
800 const Standard_Integer nbp = Max (4 , Standard_Integer (50. * theval / M_PI));
801 const Standard_Real dteta = theval/(nbp-1);
803 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp);
804 for (Standard_Integer i = 1; i<=nbp; i++)
805 aPrims->AddVertex(ElCLib::Value(dteta*(i-1),cer));
806 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
808 Standard_Real uc1 = 0.;
809 Standard_Real uc2 = ElCLib::Parameter(cer,AttachmentPoint1.Rotated(theAxe,theval));
811 Standard_Real length = LA->ArrowAspect()->Length();
812 if (length < Precision::Confusion()) length = 1.e-04;
818 case DsgPrs_AS_FIRSTAR:
820 ElCLib::D1(uc1,cer,ptarr,vecarr);
821 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(-vecarr), LA->ArrowAspect()->Angle(), length);
824 case DsgPrs_AS_LASTAR:
826 ElCLib::D1(uc2,cer,ptarr,vecarr);
827 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(vecarr), LA->ArrowAspect()->Angle(), length);
830 case DsgPrs_AS_BOTHAR:
832 ElCLib::D1(uc1,cer,ptarr,vecarr);
833 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(-vecarr), LA->ArrowAspect()->Angle(), length);
834 ElCLib::D1(uc2,cer,ptarr,vecarr);
835 Prs3d_Arrow::Draw (Prs3d_Root::CurrentGroup (aPresentation), ptarr, gp_Dir(vecarr), LA->ArrowAspect()->Angle(), length);