0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / PrsDim / PrsDim_AngleDimension.cxx
CommitLineData
b311480e 1// Created on: 1996-12-05
2// Created by: Arnaud BOUZY/Odile Olivier
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
787ff240 17#include <PrsDim_AngleDimension.hxx>
7fd59977 18
787ff240 19#include <PrsDim.hxx>
7fd59977 20#include <BRepBuilderAPI_MakeFace.hxx>
21#include <BRepAdaptor_Curve.hxx>
22#include <BRepAdaptor_Surface.hxx>
60bf98ae 23#include <BRepLib_MakeVertex.hxx>
24#include <BRep_Tool.hxx>
7fd59977 25#include <ElCLib.hxx>
60bf98ae 26#include <GCPnts_UniformAbscissa.hxx>
27#include <GC_MakeArcOfCircle.hxx>
a6eb515f 28#include <gce_MakeLin2d.hxx>
60bf98ae 29#include <gce_MakeLin.hxx>
30#include <gce_MakeCirc.hxx>
a6eb515f 31#include <gce_MakeCone.hxx>
fe83e1ea 32#include <gce_MakePln.hxx>
fe83e1ea 33#include <gce_MakeDir.hxx>
7fd59977 34#include <Geom_Circle.hxx>
60bf98ae 35#include <Geom_TrimmedCurve.hxx>
7fd59977 36#include <Geom_ConicalSurface.hxx>
37#include <Geom_SurfaceOfRevolution.hxx>
7fd59977 38#include <Geom_OffsetSurface.hxx>
a6eb515f 39#include <Graphic3d_ArrayOfSegments.hxx>
a6eb515f 40#include <Graphic3d_Group.hxx>
a6eb515f 41#include <Graphic3d_ArrayOfPolylines.hxx>
7fd59977 42#include <IntAna2d_AnaIntersection.hxx>
7fd59977 43#include <ProjLib.hxx>
a6eb515f 44#include <Prs3d_Root.hxx>
d7bffd44 45#include <Prs3d_ShadingAspect.hxx>
a6eb515f 46#include <PrsMgr_PresentationManager3d.hxx>
62b6361a 47#include <Select3D_SensitiveGroup.hxx>
7fd59977 48#include <Select3D_SensitiveSegment.hxx>
a6eb515f 49#include <SelectMgr_Selection.hxx>
af203d54 50#include <Standard_ProgramError.hxx>
7fd59977 51#include <UnitsAPI.hxx>
ec357c5c 52#include <Geom_Line.hxx>
53#include <Geom_Plane.hxx>
7fd59977 54
787ff240 55IMPLEMENT_STANDARD_RTTIEXT(PrsDim_AngleDimension, PrsDim_Dimension)
92efcf78 56
d7bffd44 57namespace
58{
fe83e1ea 59 static const TCollection_ExtendedString THE_EMPTY_LABEL_STRING;
60 static const Standard_Real THE_EMPTY_LABEL_WIDTH = 0.0;
61 static const Standard_ExtCharacter THE_DEGREE_SYMBOL (0x00B0);
62 static const Standard_Real THE_3D_TEXT_MARGIN = 0.1;
0f0f0c06 63
64 //! Returns true if the given points lie on a same line.
65 static Standard_Boolean isSameLine (const gp_Pnt& theFirstPoint,
66 const gp_Pnt& theCenterPoint,
67 const gp_Pnt& theSecondPoint)
68 {
69 gp_Vec aVec1 (theFirstPoint, theCenterPoint);
70 gp_Vec aVec2 (theCenterPoint, theSecondPoint);
71
72 return aVec1.IsParallel (aVec2, Precision::Angular());
73 }
a3f6f591 74}
d7bffd44 75
7fd59977 76//=======================================================================
77//function : Constructor
60bf98ae 78//purpose :
7fd59977 79//=======================================================================
787ff240 80PrsDim_AngleDimension::PrsDim_AngleDimension (const TopoDS_Edge& theFirstEdge,
81 const TopoDS_Edge& theSecondEdge)
82: PrsDim_Dimension (PrsDim_KOD_PLANEANGLE)
7fd59977 83{
60bf98ae 84 Init();
85 SetMeasuredGeometry (theFirstEdge, theSecondEdge);
7fd59977 86}
87
7fd59977 88//=======================================================================
89//function : Constructor
60bf98ae 90//purpose :
7fd59977 91//=======================================================================
787ff240 92PrsDim_AngleDimension::PrsDim_AngleDimension (const gp_Pnt& theFirstPoint,
93 const gp_Pnt& theSecondPoint,
94 const gp_Pnt& theThirdPoint)
95: PrsDim_Dimension (PrsDim_KOD_PLANEANGLE)
7fd59977 96{
60bf98ae 97 Init();
98 SetMeasuredGeometry (theFirstPoint, theSecondPoint, theThirdPoint);
7fd59977 99}
100
101//=======================================================================
102//function : Constructor
60bf98ae 103//purpose :
7fd59977 104//=======================================================================
787ff240 105PrsDim_AngleDimension::PrsDim_AngleDimension (const TopoDS_Vertex& theFirstVertex,
106 const TopoDS_Vertex& theSecondVertex,
107 const TopoDS_Vertex& theThirdVertex)
108: PrsDim_Dimension (PrsDim_KOD_PLANEANGLE)
7fd59977 109{
60bf98ae 110 Init();
111 SetMeasuredGeometry (theFirstVertex, theSecondVertex, theThirdVertex);
7fd59977 112}
113
7fd59977 114//=======================================================================
a6eb515f 115//function : Constructor
60bf98ae 116//purpose :
7fd59977 117//=======================================================================
787ff240 118PrsDim_AngleDimension::PrsDim_AngleDimension (const TopoDS_Face& theCone)
119: PrsDim_Dimension (PrsDim_KOD_PLANEANGLE)
7fd59977 120{
60bf98ae 121 Init();
122 SetMeasuredGeometry (theCone);
7fd59977 123}
124
125//=======================================================================
a6eb515f 126//function : Constructor
60bf98ae 127//purpose :
7fd59977 128//=======================================================================
787ff240 129PrsDim_AngleDimension::PrsDim_AngleDimension (const TopoDS_Face& theFirstFace,
130 const TopoDS_Face& theSecondFace)
131: PrsDim_Dimension (PrsDim_KOD_PLANEANGLE)
7fd59977 132{
60bf98ae 133 Init();
134 SetMeasuredGeometry (theFirstFace, theSecondFace);
7fd59977 135}
136
7fd59977 137//=======================================================================
60bf98ae 138//function : Constructor
7fd59977 139//purpose :
140//=======================================================================
787ff240 141PrsDim_AngleDimension::PrsDim_AngleDimension (const TopoDS_Face& theFirstFace,
142 const TopoDS_Face& theSecondFace,
143 const gp_Pnt& thePoint)
144: PrsDim_Dimension (PrsDim_KOD_PLANEANGLE)
7fd59977 145{
60bf98ae 146 Init();
147 SetMeasuredGeometry (theFirstFace, theSecondFace, thePoint);
7fd59977 148}
149
7fd59977 150//=======================================================================
60bf98ae 151//function : SetMeasuredGeometry
152//purpose :
7fd59977 153//=======================================================================
787ff240 154void PrsDim_AngleDimension::SetMeasuredGeometry (const TopoDS_Edge& theFirstEdge,
155 const TopoDS_Edge& theSecondEdge)
7fd59977 156{
60bf98ae 157 gp_Pln aComputedPlane;
158
91b16a64 159 myFirstShape = theFirstEdge;
160 mySecondShape = theSecondEdge;
161 myThirdShape = TopoDS_Shape();
162 myGeometryType = GeometryType_Edges;
163 myIsGeometryValid = InitTwoEdgesAngle (aComputedPlane);
60bf98ae 164
91b16a64 165 if (myIsGeometryValid && !myIsPlaneCustom)
60bf98ae 166 {
4d147bf2 167 myPlane = aComputedPlane;
60bf98ae 168 }
169
60bf98ae 170 SetToUpdate();
7fd59977 171}
172
173//=======================================================================
60bf98ae 174//function : SetMeasuredGeometry
175//purpose :
7fd59977 176//=======================================================================
787ff240 177void PrsDim_AngleDimension::SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
178 const gp_Pnt& theSecondPoint,
179 const gp_Pnt& theThirdPoint)
7fd59977 180{
60bf98ae 181 myFirstPoint = theFirstPoint;
182 myCenterPoint = theSecondPoint;
183 mySecondPoint = theThirdPoint;
184 myFirstShape = BRepLib_MakeVertex (myFirstPoint);
185 mySecondShape = BRepLib_MakeVertex (myCenterPoint);
186 myThirdShape = BRepLib_MakeVertex (mySecondPoint);
187 myGeometryType = GeometryType_Points;
91b16a64 188 myIsGeometryValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
7fd59977 189
0f0f0c06 190 Standard_Boolean anIsSameLine = isSameLine (myFirstPoint, myCenterPoint, mySecondPoint);
191 if (myIsGeometryValid && !myIsPlaneCustom && !anIsSameLine)
a6eb515f 192 {
60bf98ae 193 ComputePlane();
194 }
a6eb515f 195
60bf98ae 196 SetToUpdate();
197}
a6eb515f 198
60bf98ae 199//=======================================================================
200//function : SetMeasuredGeometry
201//purpose :
202//=======================================================================
787ff240 203void PrsDim_AngleDimension::SetMeasuredGeometry (const TopoDS_Vertex& theFirstVertex,
204 const TopoDS_Vertex& theSecondVertex,
205 const TopoDS_Vertex& theThirdVertex)
60bf98ae 206{
91b16a64 207 myFirstShape = theFirstVertex;
208 mySecondShape = theSecondVertex;
209 myThirdShape = theThirdVertex;
210 myFirstPoint = BRep_Tool::Pnt (theFirstVertex);
211 myCenterPoint = BRep_Tool::Pnt (theSecondVertex);
212 mySecondPoint = BRep_Tool::Pnt (theThirdVertex);
213 myGeometryType = GeometryType_Points;
214 myIsGeometryValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
215
0f0f0c06 216 Standard_Boolean anIsSameLine = isSameLine (myFirstPoint, myCenterPoint, mySecondPoint);
217 if (myIsGeometryValid && !myIsPlaneCustom && !anIsSameLine)
a6eb515f 218 {
60bf98ae 219 ComputePlane();
7fd59977 220 }
7fd59977 221
60bf98ae 222 SetToUpdate();
223}
7fd59977 224
60bf98ae 225//=======================================================================
226//function : SetMeasuredGeometry
227//purpose :
228//=======================================================================
787ff240 229void PrsDim_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theCone)
60bf98ae 230{
91b16a64 231 myFirstShape = theCone;
232 mySecondShape = TopoDS_Shape();
233 myThirdShape = TopoDS_Shape();
234 myGeometryType = GeometryType_Face;
235 myIsGeometryValid = InitConeAngle();
7fd59977 236
91b16a64 237 if (myIsGeometryValid && !myIsPlaneCustom)
a6eb515f 238 {
60bf98ae 239 ComputePlane();
a6eb515f 240 }
7fd59977 241
60bf98ae 242 SetToUpdate();
7fd59977 243}
244
245//=======================================================================
60bf98ae 246//function : SetMeasuredGeometry
247//purpose :
7fd59977 248//=======================================================================
787ff240 249void PrsDim_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
250 const TopoDS_Face& theSecondFace)
7fd59977 251{
91b16a64 252 myFirstShape = theFirstFace;
253 mySecondShape = theSecondFace;
254 myThirdShape = TopoDS_Shape();
255 myGeometryType = GeometryType_Faces;
256 myIsGeometryValid = InitTwoFacesAngle();
a6eb515f 257
91b16a64 258 if (myIsGeometryValid && !myIsPlaneCustom)
a6eb515f 259 {
60bf98ae 260 ComputePlane();
7fd59977 261 }
60bf98ae 262
60bf98ae 263 SetToUpdate();
7fd59977 264}
265
7fd59977 266//=======================================================================
60bf98ae 267//function : SetMeasuredGeometry
7fd59977 268//purpose :
269//=======================================================================
787ff240 270void PrsDim_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
271 const TopoDS_Face& theSecondFace,
272 const gp_Pnt& thePoint)
7fd59977 273{
91b16a64 274 myFirstShape = theFirstFace;
275 mySecondShape = theSecondFace;
276 myThirdShape = TopoDS_Shape();
277 myGeometryType = GeometryType_Faces;
278 myIsGeometryValid = InitTwoFacesAngle (thePoint);
60bf98ae 279
91b16a64 280 if (myIsGeometryValid && !myIsPlaneCustom)
60bf98ae 281 {
282 ComputePlane();
283 }
284
60bf98ae 285 SetToUpdate();
7fd59977 286}
287
288//=======================================================================
60bf98ae 289//function : Init
7fd59977 290//purpose :
291//=======================================================================
787ff240 292void PrsDim_AngleDimension::Init()
7fd59977 293{
787ff240 294 SetType (PrsDim_TypeOfAngle_Interior);
295 SetArrowsVisibility (PrsDim_TypeOfAngleArrowVisibility_Both);
60bf98ae 296 SetSpecialSymbol (THE_DEGREE_SYMBOL);
787ff240 297 SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_After);
60bf98ae 298 SetFlyout (15.0);
7fd59977 299}
300
7fd59977 301//=======================================================================
60bf98ae 302//function: GetCenterOnArc
303//purpose :
7fd59977 304//=======================================================================
787ff240 305gp_Pnt PrsDim_AngleDimension::GetCenterOnArc (const gp_Pnt& theFirstAttach,
306 const gp_Pnt& theSecondAttach,
307 const gp_Pnt& theCenter) const
7fd59977 308{
60bf98ae 309 // construct plane where the circle and the arc are located
310 gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
311 if (!aConstructPlane.IsDone())
a6eb515f 312 {
60bf98ae 313 return gp::Origin();
7fd59977 314 }
60bf98ae 315
316 gp_Pln aPlane = aConstructPlane.Value();
ee905e84 317 // to have an exterior angle presentation, a plane for further constructed circle should be reversed
787ff240 318 if (myType == PrsDim_TypeOfAngle_Exterior)
ee905e84 319 {
320 gp_Ax1 anAxis = aPlane.Axis();
321 gp_Dir aDir = anAxis.Direction();
322 aDir.Reverse();
323 aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
324 }
7fd59977 325
60bf98ae 326 Standard_Real aRadius = theFirstAttach.Distance (theCenter);
7fd59977 327
60bf98ae 328 // construct circle forming the arc
329 gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
330 if (!aConstructCircle.IsDone())
a6eb515f 331 {
60bf98ae 332 return gp::Origin();
7fd59977 333 }
334
60bf98ae 335 gp_Circ aCircle = aConstructCircle.Value();
336
337 // compute angle parameters of arc end-points on circle
338 Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
339 Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
340 ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
7fd59977 341
60bf98ae 342 return ElCLib::Value ((aParamBeg + aParamEnd) * 0.5, aCircle);
343}
344
4d147bf2 345//=======================================================================
346//function : GetNormalForMinAngle
347//purpose :
348//=======================================================================
787ff240 349gp_Dir PrsDim_AngleDimension::GetNormalForMinAngle() const
4d147bf2 350{
351 const gp_Dir& aNormal = myPlane.Axis().Direction();
352 gp_Dir aFirst (gp_Vec (myCenterPoint, myFirstPoint) );
353 gp_Dir aSecond (gp_Vec (myCenterPoint, mySecondPoint) );
354
355 return aFirst.AngleWithRef (aSecond, aNormal) < 0.0
356 ? aNormal.Reversed()
357 : aNormal;
358}
359
60bf98ae 360//=======================================================================
361//function : DrawArc
362//purpose : draws the arc between two attach points
363//=======================================================================
787ff240 364void PrsDim_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentation,
365 const gp_Pnt& theFirstAttach,
366 const gp_Pnt& theSecondAttach,
367 const gp_Pnt& theCenter,
368 const Standard_Real theRadius,
369 const Standard_Integer theMode)
60bf98ae 370{
4d147bf2 371 gp_Pln aPlane (myCenterPoint, GetNormalForMinAngle());
60bf98ae 372
ee905e84 373 // to have an exterior angle presentation, a plane for further constructed circle should be reversed
787ff240 374 if (myType == PrsDim_TypeOfAngle_Exterior)
ee905e84 375 {
376 gp_Ax1 anAxis = aPlane.Axis();
377 gp_Dir aDir = anAxis.Direction();
378 aDir.Reverse();
379 aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
380 }
381
60bf98ae 382 // construct circle forming the arc
383 gce_MakeCirc aConstructCircle (theCenter, aPlane, theRadius);
384 if (!aConstructCircle.IsDone())
a6eb515f 385 {
60bf98ae 386 return;
7fd59977 387 }
388
60bf98ae 389 gp_Circ aCircle = aConstructCircle.Value();
390
391 // construct the arc
392 GC_MakeArcOfCircle aConstructArc (aCircle, theFirstAttach, theSecondAttach, Standard_True);
393 if (!aConstructArc.IsDone())
a6eb515f 394 {
60bf98ae 395 return;
7fd59977 396 }
397
60bf98ae 398 // generate points with specified deflection
399 const Handle(Geom_TrimmedCurve)& anArcCurve = aConstructArc.Value();
400
401 GeomAdaptor_Curve anArcAdaptor (anArcCurve, anArcCurve->FirstParameter(), anArcCurve->LastParameter());
7fd59977 402
60bf98ae 403 // compute number of discretization elements in old-fanshioned way
404 gp_Vec aCenterToFirstVec (theCenter, theFirstAttach);
405 gp_Vec aCenterToSecondVec (theCenter, theSecondAttach);
ee905e84 406 Standard_Real anAngle = aCenterToFirstVec.Angle (aCenterToSecondVec);
787ff240 407 if (myType == PrsDim_TypeOfAngle_Exterior)
ee905e84 408 anAngle = 2.0 * M_PI - anAngle;
409 // it sets 50 points on PI, and a part of points if angle is less
60bf98ae 410 const Standard_Integer aNbPoints = Max (4, Standard_Integer (50.0 * anAngle / M_PI));
a6eb515f 411
60bf98ae 412 GCPnts_UniformAbscissa aMakePnts (anArcAdaptor, aNbPoints);
413 if (!aMakePnts.IsDone())
414 {
415 return;
7fd59977 416 }
417
60bf98ae 418 // init data arrays for graphical and selection primitives
419 Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aNbPoints);
7fd59977 420
60bf98ae 421 SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
a6eb515f 422
60bf98ae 423 // load data into arrays
424 for (Standard_Integer aPntIt = 1; aPntIt <= aMakePnts.NbPoints(); ++aPntIt)
a6eb515f 425 {
60bf98ae 426 gp_Pnt aPnt = anArcAdaptor.Value (aMakePnts.Parameter (aPntIt));
7fd59977 427
60bf98ae 428 aPrimSegments->AddVertex (aPnt);
7fd59977 429
60bf98ae 430 aSensitiveCurve.Append (aPnt);
a6eb515f 431 }
7fd59977 432
60bf98ae 433 // add display presentation
434 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
435 {
436 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
437 }
438 Handle(Graphic3d_AspectLine3d) aDimensionLineStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
439 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionLineStyle);
440 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
441 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
442 {
443 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
444 }
7fd59977 445}
a6eb515f 446
7fd59977 447//=======================================================================
60bf98ae 448//function: DrawArcWithText
a6eb515f 449//purpose :
7fd59977 450//=======================================================================
787ff240 451void PrsDim_AngleDimension::DrawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
452 const gp_Pnt& theFirstAttach,
453 const gp_Pnt& theSecondAttach,
454 const gp_Pnt& theCenter,
455 const TCollection_ExtendedString& theText,
456 const Standard_Real theTextWidth,
457 const Standard_Integer theMode,
458 const Standard_Integer theLabelPosition)
7fd59977 459{
4d147bf2 460 gp_Pln aPlane (myCenterPoint, GetNormalForMinAngle());
461
60bf98ae 462 Standard_Real aRadius = theFirstAttach.Distance (myCenterPoint);
a6eb515f 463
fe83e1ea 464 // construct circle forming the arc
60bf98ae 465 gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
fe83e1ea 466 if (!aConstructCircle.IsDone())
467 {
468 return;
469 }
a6eb515f 470
fe83e1ea 471 gp_Circ aCircle = aConstructCircle.Value();
a6eb515f 472
fe83e1ea 473 // compute angle parameters of arc end-points on circle
474 Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
475 Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
60bf98ae 476 ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
a6eb515f 477
fe83e1ea 478 // middle point of arc parameter on circle
479 Standard_Real aParamMid = (aParamBeg + aParamEnd) * 0.5;
a6eb515f 480
fe83e1ea 481 // add text graphical primitives
482 if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
483 {
484 gp_Pnt aTextPos = ElCLib::Value (aParamMid, aCircle);
60bf98ae 485 gp_Dir aTextDir = gce_MakeDir (theFirstAttach, theSecondAttach);
fe83e1ea 486
487 // Drawing text
7c65581d 488 drawText (thePresentation,
fe83e1ea 489 aTextPos,
490 aTextDir,
491 theText,
492 theLabelPosition);
493 }
a6eb515f 494
fe83e1ea 495 if (theMode != ComputeMode_All && theMode != ComputeMode_Line)
496 {
497 return;
498 }
a6eb515f 499
fe83e1ea 500 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
a6eb515f 501
fe83e1ea 502 Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
503 && aDimensionAspect->IsText3d();
a6eb515f 504
fe83e1ea 505 if (isLineBreak)
a6eb515f 506 {
fe83e1ea 507 // compute gap for label as parameteric size of sector on circle segment
4d147bf2 508 Standard_Real aSectorOfText = theTextWidth / aRadius;
509 Standard_Real aTextBegin = aParamMid - aSectorOfText * 0.5;
510 Standard_Real aTextEnd = aParamMid + aSectorOfText * 0.5;
511 gp_Pnt aTextPntBeg = ElCLib::Value (aTextBegin, aCircle);
512 gp_Pnt aTextPntEnd = ElCLib::Value (aTextEnd, aCircle);
fe83e1ea 513
514 // Drawing arcs
4d147bf2 515 if (aTextBegin > aParamBeg)
516 {
517 DrawArc (thePresentation, theFirstAttach, aTextPntBeg, theCenter, aRadius, theMode);
518 }
519 if (aTextEnd < aParamEnd)
520 {
521 DrawArc (thePresentation, aTextPntEnd, theSecondAttach, theCenter, aRadius, theMode);
522 }
fe83e1ea 523 }
524 else
525 {
60bf98ae 526 DrawArc (thePresentation, theFirstAttach, theSecondAttach, theCenter, aRadius, theMode);
7fd59977 527 }
a6eb515f 528}
7fd59977 529
a6eb515f 530//=======================================================================
60bf98ae 531//function : CheckPlane
532//purpose :
a6eb515f 533//=======================================================================
787ff240 534Standard_Boolean PrsDim_AngleDimension::CheckPlane (const gp_Pln& thePlane)const
a6eb515f 535{
60bf98ae 536 if (!thePlane.Contains (myFirstPoint, Precision::Confusion()) &&
537 !thePlane.Contains (mySecondPoint, Precision::Confusion()) &&
538 !thePlane.Contains (myCenterPoint, Precision::Confusion()))
fe83e1ea 539 {
60bf98ae 540 return Standard_False;
fe83e1ea 541 }
542
60bf98ae 543 return Standard_True;
544}
a6eb515f 545
60bf98ae 546//=======================================================================
547//function : ComputePlane
548//purpose :
549//=======================================================================
787ff240 550void PrsDim_AngleDimension::ComputePlane()
60bf98ae 551{
91b16a64 552 if (!myIsGeometryValid)
a6eb515f 553 {
fe83e1ea 554 return;
7fd59977 555 }
7fd59977 556
4d147bf2 557 // Compute working plane so that Y axis is codirectional
558 // with Y axis of text coordinate system (necessary for text alignment)
559 gp_Vec aFirstVec = gp_Vec (myCenterPoint, myFirstPoint);
560 gp_Vec aSecondVec = gp_Vec (myCenterPoint, mySecondPoint);
561 gp_Vec aDirectionN = aSecondVec ^ aFirstVec;
562 gp_Vec aDirectionY = aFirstVec + aSecondVec;
563 gp_Vec aDirectionX = aDirectionY ^ aDirectionN;
fe83e1ea 564
60bf98ae 565 myPlane = gp_Pln (gp_Ax3 (myCenterPoint, gp_Dir (aDirectionN), gp_Dir (aDirectionX)));
566}
7fd59977 567
60bf98ae 568//=======================================================================
569//function : GetModelUnits
570//purpose :
571//=======================================================================
787ff240 572const TCollection_AsciiString& PrsDim_AngleDimension::GetModelUnits() const
60bf98ae 573{
574 return myDrawer->DimAngleModelUnits();
575}
fe83e1ea 576
60bf98ae 577//=======================================================================
578//function : GetDisplayUnits
579//purpose :
580//=======================================================================
787ff240 581const TCollection_AsciiString& PrsDim_AngleDimension::GetDisplayUnits() const
60bf98ae 582{
583 return myDrawer->DimAngleDisplayUnits();
584}
fe83e1ea 585
60bf98ae 586//=======================================================================
587//function : SetModelUnits
588//purpose :
589//=======================================================================
787ff240 590void PrsDim_AngleDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
60bf98ae 591{
592 myDrawer->SetDimAngleModelUnits (theUnits);
593}
fe83e1ea 594
60bf98ae 595//=======================================================================
596//function : SetDisplayUnits
597//purpose :
598//=======================================================================
787ff240 599void PrsDim_AngleDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
60bf98ae 600{
601 myDrawer->SetDimAngleDisplayUnits (theUnits);
602}
603
604//=======================================================================
605//function : ComputeValue
606//purpose :
607//=======================================================================
787ff240 608Standard_Real PrsDim_AngleDimension::ComputeValue() const
60bf98ae 609{
610 if (!IsValid())
a6eb515f 611 {
60bf98ae 612 return 0.0;
7fd59977 613 }
60bf98ae 614
615 gp_Vec aVec1 (myCenterPoint, myFirstPoint);
616 gp_Vec aVec2 (myCenterPoint, mySecondPoint);
617
4d147bf2 618 Standard_Real anAngle = aVec1.AngleWithRef (aVec2, GetNormalForMinAngle());
60bf98ae 619
af203d54 620 return anAngle > 0.0 ? anAngle : (2.0 * M_PI + anAngle);
7fd59977 621}
622
7fd59977 623//=======================================================================
a6eb515f 624//function : Compute
625//purpose : Having three gp_Pnt points compute presentation
7fd59977 626//=======================================================================
787ff240 627void PrsDim_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
628 const Handle(Prs3d_Presentation)& thePresentation,
629 const Standard_Integer theMode)
a6eb515f 630{
fe83e1ea 631 mySelectionGeom.Clear (theMode);
7fd59977 632
60bf98ae 633 if (!IsValid())
a6eb515f 634 {
a6eb515f 635 return;
60bf98ae 636 }
7fd59977 637
a6eb515f 638 // Parameters for presentation
639 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
d7bffd44 640
60bf98ae 641 Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
d7bffd44 642
ee2be2a8 643 Standard_Real anArrowLength = aDimensionAspect->ArrowAspect()->Length();
d7bffd44 644
60bf98ae 645 // prepare label string and compute its geometrical width
646 Standard_Real aLabelWidth;
647 TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
d7bffd44 648
fe83e1ea 649 // add margins to label width
650 if (aDimensionAspect->IsText3d())
651 {
60bf98ae 652 aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
d7bffd44 653 }
654
af203d54 655 // Get parameters from aspect or adjust it according with custom text position
656 Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
657 Prs3d_DimensionTextHorizontalPosition aHorisontalTextPos = aDimensionAspect->TextHorizontalPosition();
7fd59977 658
af203d54 659 if (IsTextPositionCustom())
d7bffd44 660 {
91b16a64 661 AdjustParameters (myFixedTextPosition,anExtensionSize, aHorisontalTextPos, myFlyout);
af203d54 662 }
fe83e1ea 663
af203d54 664 // Handle user-defined and automatic arrow placement
665 Standard_Boolean isArrowsExternal = Standard_False;
666 Standard_Integer aLabelPosition = LabelPosition_None;
fe83e1ea 667
af203d54 668 FitTextAlignment (aHorisontalTextPos, aLabelPosition, isArrowsExternal);
d7bffd44 669
af203d54 670 gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
671 gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
7fd59977 672
a6eb515f 673 //Arrows positions and directions
4d147bf2 674 gp_Vec aWorkingPlaneDir (GetNormalForMinAngle());
d7bffd44 675
4d147bf2 676 gp_Dir aFirstExtensionDir = aWorkingPlaneDir.Reversed() ^ gp_Vec (myCenterPoint, aFirstAttach);
677 gp_Dir aSecondExtensionDir = aWorkingPlaneDir ^ gp_Vec (myCenterPoint, aSecondAttach);
7fd59977 678
d7bffd44 679 gp_Vec aFirstArrowVec = gp_Vec (aFirstExtensionDir) * anArrowLength;
680 gp_Vec aSecondArrowVec = gp_Vec (aSecondExtensionDir) * anArrowLength;
7fd59977 681
d7bffd44 682 if (isArrowsExternal)
a6eb515f 683 {
684 aFirstArrowVec.Reverse();
685 aSecondArrowVec.Reverse();
d7bffd44 686 }
687
4d147bf2 688 gp_Pnt aFirstArrowBegin (0.0, 0.0, 0.0);
689 gp_Pnt aFirstArrowEnd (0.0, 0.0, 0.0);
690 gp_Pnt aSecondArrowBegin (0.0, 0.0, 0.0);
691 gp_Pnt aSecondArrowEnd (0.0, 0.0, 0.0);
692
d7bffd44 693 aFirstArrowBegin = aFirstAttach;
694 aSecondArrowBegin = aSecondAttach;
695 aFirstArrowEnd = aFirstAttach.Translated (-aFirstArrowVec);
696 aSecondArrowEnd = aSecondAttach.Translated (-aSecondArrowVec);
697
d7bffd44 698 // Group1: stenciling text and the angle dimension arc
699 Prs3d_Root::NewGroup (thePresentation);
700
d7bffd44 701 Standard_Integer aHPosition = aLabelPosition & LabelPosition_HMask;
702
703 // draw text label
704 switch (aHPosition)
b8ddfc2f 705 {
d7bffd44 706 case LabelPosition_HCenter :
a6eb515f 707 {
d7bffd44 708 Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
709 && aDimensionAspect->IsText3d();
710
711 if (isLineBreak)
712 {
60bf98ae 713 DrawArcWithText (thePresentation,
d7bffd44 714 aFirstAttach,
715 aSecondAttach,
60bf98ae 716 myCenterPoint,
717 aLabelString,
718 aLabelWidth,
fe83e1ea 719 theMode,
d7bffd44 720 aLabelPosition);
721 break;
722 }
723
fe83e1ea 724 // compute text primitives
725 if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
d7bffd44 726 {
60bf98ae 727 gp_Vec aDimensionDir (aFirstAttach, aSecondAttach);
af203d54 728 gp_Pnt aTextPos = IsTextPositionCustom() ? myFixedTextPosition
729 : GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
60bf98ae 730 gp_Dir aTextDir = aDimensionDir;
fe83e1ea 731
7c65581d 732 drawText (thePresentation,
fe83e1ea 733 aTextPos,
734 aTextDir,
60bf98ae 735 aLabelString,
fe83e1ea 736 aLabelPosition);
d7bffd44 737 }
738
fe83e1ea 739 if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
740 {
60bf98ae 741 DrawArc (thePresentation,
787ff240 742 (isArrowsExternal || !isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_First)) ? aFirstAttach : aFirstArrowEnd,
743 (isArrowsExternal || !isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_Second)) ? aSecondAttach : aSecondArrowEnd,
60bf98ae 744 myCenterPoint,
fe83e1ea 745 Abs (GetFlyout()),
746 theMode);
747 }
a6eb515f 748 }
d7bffd44 749 break;
750
751 case LabelPosition_Left :
a6eb515f 752 {
60bf98ae 753 DrawExtension (thePresentation,
d7bffd44 754 anExtensionSize,
787ff240 755 (isArrowsExternal && isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_First)) ? aFirstArrowEnd : aFirstAttach,
d7bffd44 756 aFirstExtensionDir,
60bf98ae 757 aLabelString,
758 aLabelWidth,
fe83e1ea 759 theMode,
d7bffd44 760 aLabelPosition);
a6eb515f 761 }
d7bffd44 762 break;
763
764 case LabelPosition_Right :
a6eb515f 765 {
60bf98ae 766 DrawExtension (thePresentation,
d7bffd44 767 anExtensionSize,
787ff240 768 (isArrowsExternal && isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_Second)) ? aSecondArrowEnd : aSecondAttach,
d7bffd44 769 aSecondExtensionDir,
60bf98ae 770 aLabelString,
771 aLabelWidth,
fe83e1ea 772 theMode,
d7bffd44 773 aLabelPosition);
a6eb515f 774 }
d7bffd44 775 break;
776 }
777
778 // dimension arc without text
fe83e1ea 779 if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && aHPosition != LabelPosition_HCenter)
d7bffd44 780 {
781 Prs3d_Root::NewGroup (thePresentation);
782
60bf98ae 783 DrawArc (thePresentation,
787ff240 784 (isArrowsExternal || !isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_First)) ? aFirstAttach : aFirstArrowEnd,
785 (isArrowsExternal || !isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_Second)) ? aSecondAttach : aSecondArrowEnd,
60bf98ae 786 myCenterPoint,
d7bffd44 787 Abs(GetFlyout ()),
fe83e1ea 788 theMode);
d7bffd44 789 }
7fd59977 790
d7bffd44 791 // arrows and arrow extensions
fe83e1ea 792 if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
d7bffd44 793 {
794 Prs3d_Root::NewGroup (thePresentation);
795
787ff240 796 if (isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_First))
ee905e84 797 DrawArrow (thePresentation, aFirstArrowBegin, gp_Dir (aFirstArrowVec));
787ff240 798 if (isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_Second))
ee905e84 799 DrawArrow (thePresentation, aSecondArrowBegin, gp_Dir (aSecondArrowVec));
d7bffd44 800 }
801
fe83e1ea 802 if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && isArrowsExternal)
d7bffd44 803 {
804 Prs3d_Root::NewGroup (thePresentation);
805
787ff240 806 if (aHPosition != LabelPosition_Left && isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_First))
d7bffd44 807 {
60bf98ae 808 DrawExtension (thePresentation,
af203d54 809 aDimensionAspect->ArrowTailSize(),
d7bffd44 810 aFirstArrowEnd,
811 aFirstExtensionDir,
fe83e1ea 812 THE_EMPTY_LABEL_STRING,
813 THE_EMPTY_LABEL_WIDTH,
814 theMode,
d7bffd44 815 LabelPosition_None);
816 }
817
787ff240 818 if (aHPosition != LabelPosition_Right && isArrowVisible(PrsDim_TypeOfAngleArrowVisibility_Second))
a6eb515f 819 {
60bf98ae 820 DrawExtension (thePresentation,
af203d54 821 aDimensionAspect->ArrowTailSize(),
d7bffd44 822 aSecondArrowEnd,
823 aSecondExtensionDir,
fe83e1ea 824 THE_EMPTY_LABEL_STRING,
825 THE_EMPTY_LABEL_WIDTH,
826 theMode,
d7bffd44 827 LabelPosition_None);
a6eb515f 828 }
829 }
7fd59977 830
d7bffd44 831 // flyouts
60bf98ae 832 if (theMode == ComputeMode_All)
a6eb515f 833 {
d7bffd44 834 Prs3d_Root::NewGroup (thePresentation);
835
836 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (4);
60bf98ae 837 aPrimSegments->AddVertex (myCenterPoint);
a6eb515f 838 aPrimSegments->AddVertex (aFirstAttach);
60bf98ae 839 aPrimSegments->AddVertex (myCenterPoint);
a6eb515f 840 aPrimSegments->AddVertex (aSecondAttach);
d7bffd44 841
842 Handle(Graphic3d_AspectLine3d) aFlyoutStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
843 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aFlyoutStyle);
a6eb515f 844 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
7fd59977 845 }
846
91b16a64 847 mySelectionGeom.IsComputed = Standard_True;
7fd59977 848}
62b6361a 849
850//=======================================================================
60bf98ae 851//function : ComputeFlyoutSelection
62b6361a 852//purpose : computes selection for flyouts
853//=======================================================================
787ff240 854void PrsDim_AngleDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
855 const Handle(SelectMgr_EntityOwner)& theOwner)
62b6361a 856{
60bf98ae 857 gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
858 gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
859
860 Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner);
861 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aFirstAttach));
862 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aSecondAttach));
863
864 theSelection->Add (aSensitiveEntity);
865}
866
867//=======================================================================
868//function : InitTwoEdgesAngle
869//purpose :
870//=======================================================================
787ff240 871Standard_Boolean PrsDim_AngleDimension::InitTwoEdgesAngle (gp_Pln& theComputedPlane)
60bf98ae 872{
873 TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape);
874 TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape);
875
876 BRepAdaptor_Curve aMakeFirstLine (aFirstEdge);
877 BRepAdaptor_Curve aMakeSecondLine (aSecondEdge);
878
879 if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line)
fe83e1ea 880 {
60bf98ae 881 return Standard_False;
fe83e1ea 882 }
883
60bf98ae 884 Handle(Geom_Line) aFirstLine = new Geom_Line (aMakeFirstLine.Line());
885 Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line());
fe83e1ea 886
60bf98ae 887 gp_Lin aFirstLin = aFirstLine->Lin();
888 gp_Lin aSecondLin = aSecondLine->Lin();
fe83e1ea 889
4d147bf2 890 Standard_Boolean isParallelLines = aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular());
60bf98ae 891
4d147bf2 892 theComputedPlane = isParallelLines ? gp_Pln(gp::XOY())
893 : gp_Pln (aSecondLin.Location(), gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction()));
60bf98ae 894
4d147bf2 895 // Compute geometry for this plane and edges
60bf98ae 896 Standard_Boolean isInfinite1,isInfinite2;
897 gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2;
aa00364d 898 Handle(Geom_Curve) aFirstCurve = aFirstLine, aSecondCurve = aSecondLine;
787ff240 899 if (!PrsDim::ComputeGeometry (aFirstEdge, aSecondEdge,
900 aFirstCurve, aSecondCurve,
901 aFirstPoint1, aLastPoint1,
902 aFirstPoint2, aLastPoint2,
903 isInfinite1, isInfinite2))
60bf98ae 904 {
905 return Standard_False;
906 }
907
4d147bf2 908 Standard_Boolean isSameLines = aFirstLin.Direction().IsEqual (aSecondLin.Direction(), Precision::Angular())
909 && aFirstLin.Location().IsEqual (aSecondLin.Location(),Precision::Confusion());
910
911 // It can be the same gp_Lin geometry but the different begin and end parameters
912 Standard_Boolean isSameEdges =
913 (aFirstPoint1.IsEqual (aFirstPoint2, Precision::Confusion()) && aLastPoint1.IsEqual (aLastPoint2, Precision::Confusion()))
914 || (aFirstPoint1.IsEqual (aLastPoint2, Precision::Confusion()) && aLastPoint1.IsEqual (aFirstPoint2, Precision::Confusion()));
60bf98ae 915
4d147bf2 916 if (isParallelLines)
917 {
918 // Zero angle, it could not handle this geometry
919 if (isSameLines && isSameEdges)
60bf98ae 920 {
4d147bf2 921 return Standard_False;
60bf98ae 922 }
923
4d147bf2 924 // Handle the case of Pi angle
925 const Standard_Real aParam11 = ElCLib::Parameter (aFirstLin, aFirstPoint1);
926 const Standard_Real aParam12 = ElCLib::Parameter (aFirstLin, aLastPoint1);
927 const Standard_Real aParam21 = ElCLib::Parameter (aFirstLin, aFirstPoint2);
928 const Standard_Real aParam22 = ElCLib::Parameter (aFirstLin, aLastPoint2);
929 myCenterPoint = ElCLib::Value ( (Min (aParam11, aParam12) + Max (aParam21, aParam22)) * 0.5, aFirstLin);
930 myFirstPoint = myCenterPoint.Translated (gp_Vec (aFirstLin.Direction()) * Abs (GetFlyout()));
931 mySecondPoint = myCenterPoint.XYZ() + (aFirstLin.Direction().IsEqual (aSecondLin.Direction(), Precision::Angular())
932 ? aFirstLin.Direction().Reversed().XYZ() * Abs (GetFlyout())
933 : aSecondLin.Direction().XYZ() * Abs (GetFlyout()));
60bf98ae 934 }
935 else
936 {
937 // Find intersection
938 gp_Lin2d aFirstLin2d = ProjLib::Project (theComputedPlane, aFirstLin);
939 gp_Lin2d aSecondLin2d = ProjLib::Project (theComputedPlane, aSecondLin);
940
941 IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d);
942 gp_Pnt2d anIntersectPoint;
943 if (!anInt2d.IsDone() || anInt2d.IsEmpty())
944 {
945 return Standard_False;
946 }
947
948 anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value());
949 myCenterPoint = ElCLib::To3d (theComputedPlane.Position().Ax2(), anIntersectPoint);
950
951 if (isInfinite1 || isInfinite2)
952 {
953 myFirstPoint = myCenterPoint.Translated (gp_Vec (aFirstLin.Direction()) * Abs (GetFlyout()));
954 mySecondPoint = myCenterPoint.Translated (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout()));
955
956 return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
957 }
958
959 // |
960 // | <- dimension should be here
961 // *----
962 myFirstPoint = myCenterPoint.Distance (aFirstPoint1) > myCenterPoint.Distance (aLastPoint1)
963 ? aFirstPoint1
964 : aLastPoint1;
965
966 mySecondPoint = myCenterPoint.Distance (aFirstPoint2) > myCenterPoint.Distance (aLastPoint2)
967 ? aFirstPoint2
968 : aLastPoint2;
969 }
970
971 return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
972}
973
974//=======================================================================
975//function : InitTwoFacesAngle
976//purpose : initialization of angle dimension between two faces
977//=======================================================================
787ff240 978Standard_Boolean PrsDim_AngleDimension::InitTwoFacesAngle()
60bf98ae 979{
980 TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
981 TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
982
983 gp_Dir aFirstDir, aSecondDir;
51740958 984 gp_Pln aFirstPln, aSecondPln;
60bf98ae 985 Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
787ff240 986 PrsDim_KindOfSurface aFirstSurfType, aSecondSurfType;
60bf98ae 987 Standard_Real aFirstOffset, aSecondOffset;
988
787ff240 989 PrsDim::GetPlaneFromFace (aFirstFace, aFirstPln,
990 aFirstBasisSurf,aFirstSurfType,aFirstOffset);
60bf98ae 991
787ff240 992 PrsDim::GetPlaneFromFace (aSecondFace, aSecondPln,
993 aSecondBasisSurf, aSecondSurfType, aSecondOffset);
60bf98ae 994
787ff240 995 if (aFirstSurfType == PrsDim_KOS_Plane && aSecondSurfType == PrsDim_KOS_Plane)
60bf98ae 996 {
997 //Planar faces angle
998 Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
999 Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
787ff240 1000 return PrsDim::InitAngleBetweenPlanarFaces (aFirstFace, aSecondFace,
1001 myCenterPoint, myFirstPoint, mySecondPoint)
1002 && IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
60bf98ae 1003 }
1004 else
1005 {
1006 // Curvilinear faces angle
787ff240 1007 return PrsDim::InitAngleBetweenCurvilinearFaces (aFirstFace, aSecondFace,
1008 aFirstSurfType, aSecondSurfType,
1009 myCenterPoint, myFirstPoint, mySecondPoint)
1010 && IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
60bf98ae 1011 }
1012}
1013
1014//=======================================================================
1015//function : InitTwoFacesAngle
1016//purpose : initialization of angle dimension between two faces
1017//=======================================================================
787ff240 1018Standard_Boolean PrsDim_AngleDimension::InitTwoFacesAngle (const gp_Pnt& thePointOnFirstFace)
60bf98ae 1019{
1020 TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
1021 TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
1022
1023 gp_Dir aFirstDir, aSecondDir;
51740958 1024 gp_Pln aFirstPln, aSecondPln;
60bf98ae 1025 Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
787ff240 1026 PrsDim_KindOfSurface aFirstSurfType, aSecondSurfType;
60bf98ae 1027 Standard_Real aFirstOffset, aSecondOffset;
1028
787ff240 1029 PrsDim::GetPlaneFromFace (aFirstFace, aFirstPln,
1030 aFirstBasisSurf,aFirstSurfType,aFirstOffset);
60bf98ae 1031
787ff240 1032 PrsDim::GetPlaneFromFace (aSecondFace, aSecondPln,
1033 aSecondBasisSurf, aSecondSurfType, aSecondOffset);
60bf98ae 1034
1035 myFirstPoint = thePointOnFirstFace;
787ff240 1036 if (aFirstSurfType == PrsDim_KOS_Plane && aSecondSurfType == PrsDim_KOS_Plane)
60bf98ae 1037 {
1038 //Planar faces angle
1039 Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
1040 Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
787ff240 1041 return PrsDim::InitAngleBetweenPlanarFaces (aFirstFace, aSecondFace,
1042 myCenterPoint, myFirstPoint, mySecondPoint,
1043 Standard_True)
1044 && IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
60bf98ae 1045 }
1046 else
1047 {
1048 // Curvilinear faces angle
787ff240 1049 return PrsDim::InitAngleBetweenCurvilinearFaces (aFirstFace, aSecondFace,
1050 aFirstSurfType, aSecondSurfType,
1051 myCenterPoint, myFirstPoint, mySecondPoint,
1052 Standard_True)
1053 && IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
60bf98ae 1054 }
1055}
1056
1057//=======================================================================
1058//function : InitConeAngle
1059//purpose : initialization of the cone angle
1060//=======================================================================
787ff240 1061Standard_Boolean PrsDim_AngleDimension::InitConeAngle()
60bf98ae 1062{
1063 if (myFirstShape.IsNull())
1064 {
1065 return Standard_False;
1066 }
1067
1068 TopoDS_Face aConeShape = TopoDS::Face (myFirstShape);
1069 gp_Pln aPln;
1070 gp_Cone aCone;
1071 gp_Circ aCircle;
1072 // A surface from the Face
1073 Handle(Geom_Surface) aSurf;
1074 Handle(Geom_OffsetSurface) aOffsetSurf;
1075 Handle(Geom_ConicalSurface) aConicalSurf;
1076 Handle(Geom_SurfaceOfRevolution) aRevSurf;
1077 Handle(Geom_Line) aLine;
1078 BRepAdaptor_Surface aConeAdaptor (aConeShape);
1079 TopoDS_Face aFace;
787ff240 1080 PrsDim_KindOfSurface aSurfType;
60bf98ae 1081 Standard_Real anOffset = 0.;
1082 Handle(Standard_Type) aType;
1083
787ff240 1084 const Standard_Real aMaxV = aConeAdaptor.FirstVParameter();
1085 const Standard_Real aMinV = aConeAdaptor.LastVParameter();
1086 PrsDim::GetPlaneFromFace (aConeShape, aPln, aSurf, aSurfType, anOffset);
1087 if (aSurfType == PrsDim_KOS_Revolution)
60bf98ae 1088 {
1089 // Surface of revolution
1090 aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf);
1091 gp_Lin aLin (aRevSurf->Axis());
1092 Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve();
1093 //Must be a part of line (basis curve should be linear)
1094 if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line))
1095 return Standard_False;
1096
1097 gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV);
1098 gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV);
1099 gp_Vec aVec1 (aFirst1, aLast1);
1100
1101 //Projection <aFirst> on <aLin>
1102 gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin);
1103 // Projection <aLast> on <aLin>
1104 gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin);
1105
1106 gp_Vec aVec2 (aFirst2, aLast2);
1107
1108 // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle).
1109 if (aVec1.IsParallel (aVec2, Precision::Angular())
1110 || aVec1.IsNormal (aVec2,Precision::Angular()))
1111 return Standard_False;
1112
1113 gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1);
1114 aCone = aMkCone.Value();
1115 myCenterPoint = aCone.Apex();
1116 }
1117 else
1118 {
1119 aType = aSurf->DynamicType();
1120 if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01)
1121 {
1122 // Offset surface
1123 aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset);
1124 aSurf = aOffsetSurf->Surface();
1125 BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion());
1126 aMkFace.Build();
1127 if (!aMkFace.IsDone())
1128 return Standard_False;
1129 aConeAdaptor.Initialize (aMkFace.Face());
1130 }
1131 aCone = aConeAdaptor.Cone();
1132 aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf);
1133 myCenterPoint = aConicalSurf->Apex();
1134 }
1135
1136 // A circle where the angle is drawn
1137 Handle(Geom_Curve) aCurve;
1138 Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5;
1139 aCurve = aSurf->VIso (aMidV);
1140 aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
1141
1142 aCurve = aSurf->VIso(aMaxV);
1143 gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1144 aCurve = aSurf->VIso(aMinV);
1145 gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1146
1147 if (aCircVmax.Radius() < aCircVmin.Radius())
1148 {
1149 gp_Circ aTmpCirc = aCircVmax;
1150 aCircVmax = aCircVmin;
1151 aCircVmin = aTmpCirc;
1152 }
1153
1154 myFirstPoint = ElCLib::Value (0, aCircle);
1155 mySecondPoint = ElCLib::Value (M_PI, aCircle);
1156 return Standard_True;
1157}
1158
1159//=======================================================================
1160//function : IsValidPoints
1161//purpose :
1162//=======================================================================
787ff240 1163Standard_Boolean PrsDim_AngleDimension::IsValidPoints (const gp_Pnt& theFirstPoint,
1164 const gp_Pnt& theCenterPoint,
1165 const gp_Pnt& theSecondPoint) const
60bf98ae 1166{
1167 return theFirstPoint.Distance (theCenterPoint) > Precision::Confusion()
1168 && theSecondPoint.Distance (theCenterPoint) > Precision::Confusion()
1169 && gp_Vec (theCenterPoint, theFirstPoint).Angle (
1170 gp_Vec (theCenterPoint, theSecondPoint)) > Precision::Angular();
d7bffd44 1171}
af203d54 1172
ee905e84 1173//=======================================================================
1174//function : isArrowVisible
1175//purpose : compares given and internal arrows types, returns true if the the type should be shown
1176//=======================================================================
787ff240 1177Standard_Boolean PrsDim_AngleDimension::isArrowVisible(const PrsDim_TypeOfAngleArrowVisibility theArrowType) const
ee905e84 1178{
1179 switch (theArrowType)
1180 {
787ff240 1181 case PrsDim_TypeOfAngleArrowVisibility_Both:
1182 return myArrowsVisibility == PrsDim_TypeOfAngleArrowVisibility_Both;
1183 case PrsDim_TypeOfAngleArrowVisibility_First:
1184 return myArrowsVisibility == PrsDim_TypeOfAngleArrowVisibility_Both || myArrowsVisibility == PrsDim_TypeOfAngleArrowVisibility_First;
1185 case PrsDim_TypeOfAngleArrowVisibility_Second:
1186 return myArrowsVisibility == PrsDim_TypeOfAngleArrowVisibility_Both || myArrowsVisibility == PrsDim_TypeOfAngleArrowVisibility_Second;
1187 case PrsDim_TypeOfAngleArrowVisibility_None:
ee905e84 1188 return false;
1189 }
1190 return false;
1191}
1192
af203d54 1193//=======================================================================
1194//function : GetTextPosition
1195//purpose :
1196//=======================================================================
787ff240 1197gp_Pnt PrsDim_AngleDimension::GetTextPosition() const
af203d54 1198{
1199 if (!IsValid())
1200 {
1201 return gp::Origin();
1202 }
1203
1204 if (IsTextPositionCustom())
1205 {
1206 return myFixedTextPosition;
1207 }
1208
1209 // Counts text position according to the dimension parameters
1210 gp_Pnt aTextPosition (gp::Origin());
1211
1212 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
1213
1214 // Prepare label string and compute its geometrical width
1215 Standard_Real aLabelWidth;
1216 TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
1217
1218 gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
1219 gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
1220
1221 // Handle user-defined and automatic arrow placement
1222 Standard_Boolean isArrowsExternal = Standard_False;
1223 Standard_Integer aLabelPosition = LabelPosition_None;
1224 FitTextAlignment (aDimensionAspect->TextHorizontalPosition(),
1225 aLabelPosition, isArrowsExternal);
1226
1227 // Get text position
1228 switch (aLabelPosition & LabelPosition_HMask)
1229 {
1230 case LabelPosition_HCenter:
1231 {
1232 aTextPosition = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
1233 }
1234 break;
1235 case LabelPosition_Left:
1236 {
1237 gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
1238 gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aFirstAttach);
1239 Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
1240 Standard_Real anOffset = isArrowsExternal
1241 ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
1242 : anExtensionSize;
1243 gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * -anOffset;
1244 aTextPosition = aFirstAttach.Translated (anExtensionVec);
1245 }
1246 break;
1247 case LabelPosition_Right:
1248 {
1249 gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
1250 gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aSecondAttach);
1251 Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
1252 Standard_Real anOffset = isArrowsExternal
1253 ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
1254 : anExtensionSize;
1255 gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * anOffset;
1256 aTextPosition = aSecondAttach.Translated (anExtensionVec);
1257 }
1258 break;
1259 }
1260
1261 return aTextPosition;
1262}
1263
1264//=======================================================================
1265//function : SetTextPosition
1266//purpose :
1267//=======================================================================
787ff240 1268void PrsDim_AngleDimension::SetTextPosition (const gp_Pnt& theTextPos)
af203d54 1269{
1270 if (!IsValid())
1271 {
1272 return;
1273 }
1274
1275 // The text position point for angle dimension should belong to the working plane.
1276 if (!GetPlane().Contains (theTextPos, Precision::Confusion()))
1277 {
9775fa61 1278 throw Standard_ProgramError("The text position point for angle dimension doesn't belong to the working plane.");
af203d54 1279 }
1280
1281 myIsTextPositionFixed = Standard_True;
1282 myFixedTextPosition = theTextPos;
1283}
1284
1285//=======================================================================
91b16a64 1286//function : AdjustParameters
af203d54 1287//purpose :
1288//=======================================================================
787ff240 1289void PrsDim_AngleDimension::AdjustParameters (const gp_Pnt& theTextPos,
1290 Standard_Real& theExtensionSize,
1291 Prs3d_DimensionTextHorizontalPosition& theAlignment,
1292 Standard_Real& theFlyout) const
af203d54 1293{
1294 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
1295 Standard_Real anArrowLength = aDimensionAspect->ArrowAspect()->Length();
1296
af203d54 1297 // Build circle with radius that is equal to distance from text position to the center point.
1298 Standard_Real aRadius = gp_Vec (myCenterPoint, theTextPos).Magnitude();
1299
1300 // Set attach points in positive direction of the flyout.
1301 gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * aRadius);
1302 gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * aRadius);
1303
1304 gce_MakeCirc aConstructCircle (myCenterPoint, GetPlane(), aRadius);
1305 if (!aConstructCircle.IsDone())
1306 {
1307 return;
1308 }
1309 gp_Circ aCircle = aConstructCircle.Value();
1310
1311 // Default values
1312 theExtensionSize = aDimensionAspect->ArrowAspect()->Length();
1313 theAlignment = Prs3d_DTHP_Center;
1314
1315 Standard_Real aParamBeg = ElCLib::Parameter (aCircle, aFirstAttach);
1316 Standard_Real aParamEnd = ElCLib::Parameter (aCircle, aSecondAttach);
1317 if (aParamEnd < aParamBeg)
1318 {
1319 Standard_Real aParam = aParamEnd;
1320 aParamEnd = aParamBeg;
1321 aParamBeg = aParam;
1322 }
1323
1324 ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
1325 Standard_Real aTextPar = ElCLib::Parameter (aCircle , theTextPos);
1326
1327 // Horizontal center
1328 if (aTextPar > aParamBeg && aTextPar < aParamEnd)
1329 {
91b16a64 1330 theFlyout = aRadius;
af203d54 1331 return;
1332 }
1333
1334 aParamBeg += M_PI;
1335 aParamEnd += M_PI;
1336 ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
1337
1338 if (aTextPar > aParamBeg && aTextPar < aParamEnd)
1339 {
91b16a64 1340 theFlyout = -aRadius;
af203d54 1341 return;
1342 }
1343
1344 // Text on the extensions
1345 gp_Lin aFirstLine = gce_MakeLin (myCenterPoint, myFirstPoint);
1346 gp_Lin aSecondLine = gce_MakeLin (myCenterPoint, mySecondPoint);
787ff240 1347 gp_Pnt aFirstTextProj = PrsDim::Nearest (aFirstLine, theTextPos);
1348 gp_Pnt aSecondTextProj = PrsDim::Nearest (aSecondLine, theTextPos);
af203d54 1349 Standard_Real aFirstDist = aFirstTextProj.Distance (theTextPos);
1350 Standard_Real aSecondDist = aSecondTextProj.Distance (theTextPos);
1351
1352 if (aFirstDist <= aSecondDist)
1353 {
1354 aRadius = myCenterPoint.Distance (aFirstTextProj);
1355 Standard_Real aNewExtensionSize = aFirstDist - anArrowLength;
1356 theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize;
1357
1358 theAlignment = Prs3d_DTHP_Left;
1359
1360 gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, myFirstPoint).Normalized().Scaled (aRadius);
1361
91b16a64 1362 theFlyout = aFirstTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion()
af203d54 1363 ? -aRadius : aRadius;
1364 }
1365 else
1366 {
1367 aRadius = myCenterPoint.Distance (aSecondTextProj);
1368
1369 Standard_Real aNewExtensionSize = aSecondDist - anArrowLength;
1370
1371 theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize;
1372
1373 theAlignment = Prs3d_DTHP_Right;
1374
1375 gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, mySecondPoint).Normalized().Scaled (aRadius);
1376
91b16a64 1377 theFlyout = aSecondTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion()
af203d54 1378 ? -aRadius : aRadius;
1379 }
1380}
1381
1382//=======================================================================
1383//function : FitTextAlignment
1384//purpose :
1385//=======================================================================
787ff240 1386void PrsDim_AngleDimension::FitTextAlignment (const Prs3d_DimensionTextHorizontalPosition& theHorizontalTextPos,
1387 Standard_Integer& theLabelPosition,
1388 Standard_Boolean& theIsArrowsExternal) const
af203d54 1389{
1390 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
1391
ee2be2a8 1392 Standard_Real anArrowLength = aDimensionAspect->ArrowAspect()->Length();
af203d54 1393
1394 // Prepare label string and compute its geometrical width
1395 Standard_Real aLabelWidth;
1396 TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
1397
1398 // add margins to label width
1399 if (aDimensionAspect->IsText3d())
1400 {
1401 aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
1402 }
1403
1404 gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
1405 gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
1406
1407 // Handle user-defined and automatic arrow placement
1408 switch (aDimensionAspect->ArrowOrientation())
1409 {
1410 case Prs3d_DAO_External: theIsArrowsExternal = true; break;
1411 case Prs3d_DAO_Internal: theIsArrowsExternal = false; break;
1412 case Prs3d_DAO_Fit:
1413 {
1414 gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
1415 Standard_Real aDimensionWidth = anAttachVector.Magnitude();
1416
1417 // Add margin to ensure a small tail between text and arrow
1418 Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
1419 ? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
1420 : 0.0;
1421
1422 Standard_Real anArrowsWidth = (anArrowLength + anArrowMargin) * 2.0;
1423
1424 theIsArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
1425 break;
1426 }
1427 }
1428
1429 // Handle user-defined and automatic text placement
1430 switch (theHorizontalTextPos)
1431 {
1432 case Prs3d_DTHP_Left : theLabelPosition |= LabelPosition_Left; break;
1433 case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break;
1434 case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break;
1435 case Prs3d_DTHP_Fit:
1436 {
1437 gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
1438 Standard_Real aDimensionWidth = anAttachVector.Magnitude();
1439 Standard_Real anArrowsWidth = anArrowLength * 2.0;
1440 Standard_Real aContentWidth = theIsArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
1441
1442 theLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
1443 break;
1444 }
1445 }
1446
1447 switch (aDimensionAspect->TextVerticalPosition())
1448 {
1449 case Prs3d_DTVP_Above : theLabelPosition |= LabelPosition_Above; break;
1450 case Prs3d_DTVP_Below : theLabelPosition |= LabelPosition_Below; break;
1451 case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break;
1452 }
1453}