1 // Created on: 1995-02-07
2 // Copyright (c) 1995-1999 Matra Datavision
3 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
20 #include <DsgPrs_AnglePresentation.ixx>
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>
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>
46 #include <Precision.hxx>
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>
54 #include <UnitsAPI.hxx>
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)
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() );
67 if ( D >= D1 && D >= D2 ) return 0;
68 if ( D < D2 && D1 < D2 ) return -1;
69 if ( D < D1 && D2 < D1 ) return 1;
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,
86 const gp_Circ& VminCircle,
87 const gp_Circ& VmaxCircle,
88 const Standard_Real aArrowSize)
90 Handle(Prs3d_AngleAspect) anAngleAspect = aDrawer->AngleAspect();
91 Handle(Prs3d_LengthAspect) aLengthAspect = aDrawer->LengthAspect();
93 TCollection_ExtendedString txt(aText);
95 const Standard_Real myArrowSize = ( aArrowSize == 0.0 )? (0.1 * aCircle.Radius()) : aArrowSize;
97 anAngleAspect->ArrowAspect()->SetLength(myArrowSize);
98 aDrawer->ArrowAspect()->SetLength(myArrowSize);
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;
107 gp_Pnt P1 = ElCLib::Value(0., myCircle);
108 gp_Pnt P2 = ElCLib::Value(M_PI, myCircle);
110 gce_MakePln mkPln(P1, P2, Apex); // create a plane whitch defines plane for projection aPosition on it
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;
116 gp_Pnt aPnt = aPosition;
117 aPnt = aPnt.Translated( -Normal );
119 gp_Pnt tmpPnt = aPnt;
121 gp_Pnt AttachmentPnt, OppositePnt;
122 if( aPnt.Distance(P1) < aPnt.Distance(P2) ) {
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
135 GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt);
136 gp_Circ aCircle2 = mkCirc.Value()->Circ();
139 Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt); //must be equal to zero (look circle construction)
140 Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
142 while ( AttParam >= 2. * M_PI ) AttParam -= 2. * M_PI;
143 while ( OppParam >= 2. * M_PI ) OppParam -= 2. * M_PI;
145 //-------------------------- Compute angle ------------------------
146 if( txt.Length() == 0 ) {
147 Standard_Real angle = UnitsAPI::CurrentFromLS( Abs( OppParam ),"PLANE ANGLE");
149 sprintf(res, "%g", angle );
150 txt = TCollection_ExtendedString(res);
152 //-----------------------------------------------------------------
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
158 Standard_Real angle = OppParam - AttParam;
159 Standard_Real param = AttParam;
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) ) );
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 ) ) );
171 while ( angle > 2. * M_PI ) angle -= 2. * M_PI;
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);
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);
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
188 angle = 2. * M_PI - param ;
189 if( param > OppParam )
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);
198 if( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 1 && !IsConeTrimmed ) //above
200 aPrims = new Graphic3d_ArrayOfPolylines(3);
201 aPrims->AddVertex(AttachmentPnt);
202 aPrims->AddVertex(Apex);
203 aPrims->AddVertex(OppositePnt);
208 if ( AboveInBelowCone( VmaxCircle, VminCircle, myCircle ) == 0 ) return;
210 gp_Pnt P11 = ElCLib::Value( 0., VmaxCircle );
211 gp_Pnt P12 = ElCLib::Value( M_PI, VmaxCircle );
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);
219 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
223 //==========================================================================
224 // function : DsgPrs_AnglePresentation::Add
227 //==========================================================================
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,
238 const gp_Dir& axisdir,
239 const gp_Pnt& OffsetPoint)
242 sprintf(valcar,"%5.2f",theval);
244 Handle(Prs3d_AngleAspect) LA = aDrawer->AngleAspect();
245 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
247 gp_Ax2 ax(CenterPoint,axisdir,dir1);
248 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
250 vec1 *= cer.Radius();
252 vec2 *= cer.Radius();
253 gp_Pnt p2 = CenterPoint.Translated(vec2);
255 Standard_Real uc1 = 0.;
256 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
257 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
259 Standard_Real udeb = uc1;
260 Standard_Real ufin = uc2;
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) {
275 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
279 udeb = uco - 2.*M_PI;
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);
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));
292 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
294 Standard_Real length = LA->ArrowAspect()->Length();
295 if (length < Precision::Confusion()) length = 1.e-04;
299 ElCLib::D1(uc1,cer,ptarr,vecarr);
301 gp_Ax1 ax1(ptarr, axisdir);
302 gp_Dir dirarr(-vecarr);
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);
315 aPrims->AddVertex(AttachmentPoint1);
316 aPrims->AddVertex(ptarr);
318 ElCLib::D1(uc2,cer,ptarr,vecarr);
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);
326 aPrims->AddVertex(AttachmentPoint2);
327 aPrims->AddVertex(ptarr);
329 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
333 //==========================================================================
334 // function : DsgPrs_AnglePresentation::Add
335 // purpose : Adds prezentation of angle between two faces
336 //==========================================================================
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,
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 )
354 sprintf(valcar,"%5.2f",theval);
356 Handle( Prs3d_AngleAspect ) LA = aDrawer->AngleAspect();
357 Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
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(),
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())
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 );
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 ));
399 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
400 aPrims = new Graphic3d_ArrayOfSegments(4);
404 aPrims = new Graphic3d_ArrayOfSegments(6);
405 aPrims->AddVertex(OffsetPoint);
406 aPrims->AddVertex(EndOfArrow1);
409 // Add presentation of arrows
410 DsgPrs::ComputeSymbol( aPresentation, LA, EndOfArrow1, EndOfArrow2, DirOfArrow1, DirOfArrow2, ArrowPrs );
413 Prs3d_Text::Draw( aPresentation, LA->TextAspect(), aText, OffsetPoint );
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);
422 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
424 // Line or arc from AttachmentPoint2 to its "projection"
425 if (AttachmentPoint2.Distance( ProjAttachPoint2 ) > Precision::Confusion())
429 // Creating the line from AttachmentPoint2 to its projection
430 aPrims = new Graphic3d_ArrayOfSegments(2);
431 aPrims->AddVertex(AttachmentPoint2);
432 aPrims->AddVertex(ProjAttachPoint2);
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 );
441 aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber);
442 for (Standard_Integer i = 0; i < NodeNumber; i++, FirstParAttachCirc += delta)
443 aPrims->AddVertex(ElCLib::Value( FirstParAttachCirc, AttachCirc ));
445 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
450 //==========================================================================
451 // function : DsgPrs_AnglePresentation::Add
454 //==========================================================================
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,
465 const gp_Pnt& OffsetPoint)
468 sprintf(valcar,"%5.2f",theval);
470 Handle(Prs3d_AngleAspect) LA = aDrawer->AngleAspect();
471 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
474 if (!dir1.IsParallel(dir2, Precision::Angular())) {
475 Norm = dir1.Crossed(dir2);
478 gp_Dir dir2B = gp_Dir(gp_Vec(CenterPoint, OffsetPoint));
479 Norm = dir1.Crossed(dir2B);
482 if (Abs(theval) > M_PI) Norm.Reverse();
484 gp_Ax2 ax(CenterPoint,Norm,dir1);
485 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
487 vec1 *= cer.Radius();
489 vec2 *= cer.Radius();
490 gp_Pnt p2 = CenterPoint.Translated(vec2);
492 Standard_Real uc1 = 0.;
493 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
494 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
496 Standard_Real udeb = uc1;
497 Standard_Real ufin = uc2;
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) {
512 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
516 udeb = uco - 2.*M_PI;
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);
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));
529 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
531 Standard_Real length = LA->ArrowAspect()->Length();
532 if (length < Precision::Confusion()) length = 1.e-04;
536 ElCLib::D1(uc1,cer,ptarr,vecarr);
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);
551 aPrims->AddVertex(AttachmentPoint1);
552 aPrims->AddVertex(ptarr);
554 ElCLib::D1(uc2,cer,ptarr,vecarr);
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);
562 aPrims->AddVertex(AttachmentPoint2);
563 aPrims->AddVertex(ptarr);
565 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
569 //==========================================================================
570 // function : DsgPrs_AnglePresentation::Add
571 // purpose : It is possible to choose the symbol of extremities of the face (arrow, point...)
572 //==========================================================================
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,
583 const gp_Pnt& OffsetPoint,
584 const DsgPrs_ArrowSide ArrowPrs)
587 sprintf(valcar,"%5.2f",theval);
589 Handle(Prs3d_AngleAspect) LA = aDrawer->AngleAspect();
590 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
592 gp_Dir Norm = dir1.Crossed(dir2);
593 if (Abs(theval) > M_PI) Norm.Reverse();
595 gp_Ax2 ax(CenterPoint,Norm,dir1);
596 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
598 vec1 *= cer.Radius();
600 vec2 *= cer.Radius();
601 gp_Pnt p2 = CenterPoint.Translated(vec2);
603 Standard_Real uc1 = 0.;
604 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
605 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
607 Standard_Real udeb = uc1;
608 Standard_Real ufin = uc2;
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) {
623 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
627 udeb = uco - 2.*M_PI;
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);
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));
640 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
642 Standard_Real length = LA->ArrowAspect()->Length();
643 if (length < Precision::Confusion()) length = 1.e-04;
648 ElCLib::D1(uc1,cer,ptarr,vecarr);
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);
662 aPrims->AddVertex(AttachmentPoint1);
663 aPrims->AddVertex(ptarr);
667 ElCLib::D1(uc2,cer,ptarr1,vecarr1);
668 ax1.SetLocation(ptarr1);
669 gp_Dir dirarr2(vecarr1);
670 dirarr2.Rotate(ax1, - beta);
673 aPrims->AddVertex(AttachmentPoint2);
674 aPrims->AddVertex(ptarr1);
676 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
678 // One traces the arrows
679 DsgPrs::ComputeSymbol(aPresentation,LA,ptarr,ptarr1,dirarr,dirarr2,ArrowPrs);
683 //==========================================================================
684 // function : DsgPrs_AnglePresentation::Add
687 //==========================================================================
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,
697 const gp_Pnt& OffsetPoint)
700 sprintf(valcar,"%5.2f",theval);
702 TCollection_AsciiString valas(valcar);
703 TCollection_ExtendedString aText(valas);
705 Handle(Prs3d_AngleAspect) LA = aDrawer->AngleAspect();
706 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
708 gp_Dir Norm = dir1.Crossed(dir2);
709 if (Abs(theval) > M_PI) Norm.Reverse();
711 gp_Ax2 ax(CenterPoint,Norm,dir1);
712 gp_Circ cer(ax,CenterPoint.Distance(OffsetPoint));
714 vec1 *= cer.Radius();
716 vec2 *= cer.Radius();
717 gp_Pnt p2 = CenterPoint.Translated(vec2);
719 Standard_Real uc1 = 0.;
720 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
721 Standard_Real uco = ElCLib::Parameter(cer,OffsetPoint);
723 Standard_Real udeb = uc1;
724 Standard_Real ufin = uc2;
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) {
739 if ((uco-uc2) < (uc1-uco+(2.*M_PI))) {
743 udeb = uco - 2.*M_PI;
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);
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));
756 Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,OffsetPoint);
758 Standard_Real length = LA->ArrowAspect()->Length();
759 if (length < Precision::Confusion()) length = 1.e-04;
763 ElCLib::D1(uc1,cer,ptarr,vecarr);
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);
776 Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr,LA->ArrowAspect()->Angle(),length);
779 aPrims->AddVertex(AttachmentPoint1);
780 aPrims->AddVertex(ptarr);
782 ElCLib::D1(uc2,cer,ptarr,vecarr);
783 ax1.SetLocation(ptarr);
784 gp_Dir dirarr2(vecarr);
785 dirarr2.Rotate(ax1, -beta);
787 Prs3d_Arrow::Draw(aPresentation,ptarr,dirarr2,LA->ArrowAspect()->Angle(),length);
790 aPrims->AddVertex(AttachmentPoint2);
791 aPrims->AddVertex(ptarr);
793 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
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)
804 Handle(Prs3d_AngleAspect) LA = aDrawer->AngleAspect();
805 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
807 gp_Dir dir1(gp_Vec(CenterPoint, AttachmentPoint1));
808 gp_Ax2 ax(CenterPoint,theAxe.Direction(),dir1);
809 gp_Circ cer(ax,CenterPoint.Distance(AttachmentPoint1));
811 const Standard_Integer nbp = Max (4 , Standard_Integer (50. * theval / M_PI));
812 const Standard_Real dteta = theval/(nbp-1);
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);
819 Standard_Real uc1 = 0.;
820 Standard_Real uc2 = ElCLib::Parameter(cer,AttachmentPoint1.Rotated(theAxe,theval));
822 Standard_Real length = LA->ArrowAspect()->Length();
823 if (length < Precision::Confusion()) length = 1.e-04;
829 case DsgPrs_AS_FIRSTAR:
831 ElCLib::D1(uc1,cer,ptarr,vecarr);
832 Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(-vecarr),LA->ArrowAspect()->Angle(),length);
835 case DsgPrs_AS_LASTAR:
837 ElCLib::D1(uc2,cer,ptarr,vecarr);
838 Prs3d_Arrow::Draw(aPresentation,ptarr,gp_Dir(vecarr),LA->ArrowAspect()->Angle(),length);
841 case DsgPrs_AS_BOTHAR:
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);