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