0024288: Provide flipping text for AIS_Dimensions
[occt.git] / src / AIS / AIS_AngleDimension.cxx
CommitLineData
b311480e 1// Created on: 1996-12-05
2// Created by: Arnaud BOUZY/Odile Olivier
3// Copyright (c) 1996-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
a6eb515f 21#include <AIS_AngleDimension.hxx>
7fd59977 22
23#include <AIS.hxx>
a6eb515f 24#include <AIS_Dimension.hxx>
7fd59977 25#include <AIS_DimensionOwner.hxx>
26#include <AIS_Drawer.hxx>
a6eb515f 27#include <BRep_Tool.hxx>
7fd59977 28#include <BRepBuilderAPI_MakeFace.hxx>
29#include <BRepAdaptor_Curve.hxx>
30#include <BRepAdaptor_Surface.hxx>
a6eb515f 31#include <BRepLib_MakeVertex.hxx>
7fd59977 32
33#include <DsgPrs.hxx>
34#include <DsgPrs_AnglePresentation.hxx>
35
36#include <ElCLib.hxx>
37#include <ElSLib.hxx>
38
a6eb515f 39#include <GC_MakeCircle.hxx>
40#include <GC_MakeConicalSurface.hxx>
41#include <gce_MakeLin.hxx>
42#include <gce_MakeLin2d.hxx>
43#include <gce_MakePln.hxx>
44#include <gce_MakeCirc.hxx>
45#include <gce_MakeCone.hxx>
7fd59977 46#include <Geom2d_Circle.hxx>
47#include <Geom2d_Curve.hxx>
48#include <Geom2d_Line.hxx>
a6eb515f 49#include <Geom2dAPI_ExtremaCurveCurve.hxx>
7fd59977 50#include <GeomAPI.hxx>
51#include <Geom_Circle.hxx>
52#include <Geom_Line.hxx>
53#include <Geom_Plane.hxx>
54#include <Geom_TrimmedCurve.hxx>
55#include <Geom_Surface.hxx>
56#include <Geom_CylindricalSurface.hxx>
57#include <Geom_ConicalSurface.hxx>
58#include <Geom_SurfaceOfRevolution.hxx>
59#include <Geom_SurfaceOfLinearExtrusion.hxx>
60#include <Geom_OffsetSurface.hxx>
a6eb515f 61#include <GeomAPI_ExtremaCurveCurve.hxx>
62#include <Graphic3d_ArrayOfSegments.hxx>
63#include <Graphic3d_AspectLine3d.hxx>
64#include <gp.hxx>
65#include <gp_Ax1.hxx>
66#include <gp_Lin.hxx>
67#include <gp_Cone.hxx>
68#include <gp_Pln.hxx>
69#include <gp_Pnt.hxx>
70#include <gp_Pnt2d.hxx>
71#include <gp_Vec.hxx>
72#include <gp_XYZ.hxx>
73#include <Graphic3d_Group.hxx>
74#include <Graphic3d_ArrayOfPrimitives.hxx>
75#include <Graphic3d_ArrayOfPolylines.hxx>
7fd59977 76
77#include <IntAna2d_AnaIntersection.hxx>
78#include <IntAna2d_IntPoint.hxx>
79#include <IntAna_QuadQuadGeo.hxx>
80#include <IntAna_ResultType.hxx>
a6eb515f 81#include <Poly_Polygon3D.hxx>
7fd59977 82#include <Precision.hxx>
7fd59977 83#include <ProjLib.hxx>
7fd59977 84#include <Prs3d_ArrowAspect.hxx>
a6eb515f 85#include <Prs3d_DimensionAspect.hxx>
7fd59977 86#include <Prs3d_Drawer.hxx>
a6eb515f 87#include <Prs3d_Root.hxx>
88#include <PrsMgr_PresentationManager3d.hxx>
7fd59977 89#include <Select3D_SensitiveCurve.hxx>
62b6361a 90#include <Select3D_SensitiveGroup.hxx>
7fd59977 91#include <Select3D_SensitiveSegment.hxx>
a6eb515f 92#include <SelectMgr_Selection.hxx>
93#include <Standard_NotImplemented.hxx>
94#include <Standard_Type.hxx>
95#include <Standard_Macro.hxx>
96#include <Standard_DefineHandle.hxx>
7fd59977 97
98#include <TColStd_Array1OfReal.hxx>
7fd59977 99#include <TopExp.hxx>
100#include <TopExp_Explorer.hxx>
101#include <TopoDS.hxx>
102#include <TopoDS_Shape.hxx>
103#include <TopoDS_Vertex.hxx>
7fd59977 104#include <UnitsAPI.hxx>
105
a6eb515f 106IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension)
107IMPLEMENT_STANDARD_RTTIEXT (AIS_AngleDimension, AIS_Dimension)
7fd59977 108
109//=======================================================================
a6eb515f 110//function : init
111//purpose : Private constructor for default initialization
7fd59977 112//=======================================================================
113
a6eb515f 114void AIS_AngleDimension::init()
7fd59977 115{
62b6361a 116 SetKindOfDimension (AIS_KOD_PLANEANGLE);
117 SetFlyout (15.0);
a6eb515f 118 // Default values of units
119 UnitsAPI::SetLocalSystem (UnitsAPI_SI);
120 SetUnitsQuantity ("PLANE ANGLE");
121 SetModelUnits ("rad");
122 SetDisplayUnits ("deg");
123 SetSpecialSymbol (0x00B0);
124 SetDisplaySpecialSymbol (AIS_DSS_After);
125 MakeUnitsDisplayed (Standard_False);
7fd59977 126}
127
128//=======================================================================
129//function : Constructor
a6eb515f 130//purpose : Two edges dimension
7fd59977 131//=======================================================================
132
a6eb515f 133AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
134 const TopoDS_Edge& theSecondEdge)
135: AIS_Dimension(),
62b6361a 136 myIsFlyoutLines (Standard_True)
7fd59977 137{
a6eb515f 138 init();
139 myShapesNumber = 2;
a6eb515f 140 myFirstShape = theFirstEdge;
141 mySecondShape = theSecondEdge;
7fd59977 142}
143
7fd59977 144//=======================================================================
145//function : Constructor
a6eb515f 146//purpose : Two edges dimension
147// <thePlane> is used in case of Angle=PI
7fd59977 148//=======================================================================
149
a6eb515f 150AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
151 const TopoDS_Edge& theSecondEdge,
152 const gp_Pln& thePlane)
153: AIS_Dimension(),
62b6361a 154 myIsFlyoutLines (Standard_True)
7fd59977 155{
a6eb515f 156 init();
157 myShapesNumber = 2;
a6eb515f 158 myFirstShape = theFirstEdge;
159 mySecondShape = theSecondEdge;
160 SetWorkingPlane (thePlane);
7fd59977 161}
162
163//=======================================================================
164//function : Constructor
a6eb515f 165//purpose : Two edges dimension with aspect
166// <thePlane> is used in case of Angle=PI
7fd59977 167//=======================================================================
168
a6eb515f 169AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
170 const TopoDS_Edge& theSecondEdge,
171 const gp_Pln& thePlane,
172 const Handle(Prs3d_DimensionAspect)& theDimensionAspect,
173 const Standard_Real theExtensionSize)
174: AIS_Dimension (theDimensionAspect,theExtensionSize),
62b6361a 175 myIsFlyoutLines (Standard_True)
7fd59977 176{
a6eb515f 177 myShapesNumber = 2;
a6eb515f 178 myFirstShape = theFirstEdge;
179 mySecondShape = theSecondEdge;
180 SetWorkingPlane (thePlane);
7fd59977 181}
182
183//=======================================================================
184//function : Constructor
a6eb515f 185//purpose : Three points dimension
7fd59977 186//=======================================================================
187
a6eb515f 188AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint,
189 const gp_Pnt& theSecondPoint,
190 const gp_Pnt& theThirdPoint)
191: AIS_Dimension(),
62b6361a 192 myIsFlyoutLines (Standard_True)
7fd59977 193{
a6eb515f 194 init();
195 myIsInitialized = Standard_True;
a6eb515f 196 myFirstPoint = theFirstPoint;
197 myCenter = theSecondPoint;
198 mySecondPoint = theThirdPoint;
199 myShapesNumber = 3;
7fd59977 200}
201
202//=======================================================================
203//function : Constructor
a6eb515f 204//purpose : Three points dimension
7fd59977 205//=======================================================================
206
a6eb515f 207AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint,
208 const gp_Pnt& theSecondPoint,
209 const gp_Pnt& theThirdPoint,
210 const Handle(Prs3d_DimensionAspect)& theDimensionAspect,
211 const Standard_Real theExtensionSize)
212: AIS_Dimension (theDimensionAspect,theExtensionSize),
62b6361a 213 myIsFlyoutLines (Standard_True)
7fd59977 214{
a6eb515f 215 myIsInitialized = Standard_True;
a6eb515f 216 myFirstPoint = theFirstPoint;
217 myCenter = theSecondPoint;
218 mySecondPoint = theThirdPoint;
219 myShapesNumber =3;
7fd59977 220}
221
7fd59977 222//=======================================================================
a6eb515f 223//function : Constructor
224//purpose : Cone dimension
7fd59977 225//=======================================================================
226
a6eb515f 227AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theCone)
228: AIS_Dimension(),
62b6361a 229 myIsFlyoutLines (Standard_True)
7fd59977 230{
a6eb515f 231 init();
232 myIsInitialized = Standard_False;
a6eb515f 233 myFirstShape = theCone;
234 myShapesNumber = 1;
7fd59977 235}
236
237//=======================================================================
a6eb515f 238//function : Constructor
239//purpose : Two faces dimension
7fd59977 240//=======================================================================
241
a6eb515f 242AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace,
243 const TopoDS_Face& theSecondFace,
244 const gp_Ax1& theAxis)
245: AIS_Dimension(),
62b6361a 246 myIsFlyoutLines (Standard_True)
7fd59977 247{
a6eb515f 248 init();
249 myIsInitialized = Standard_False;
a6eb515f 250 myFirstShape = theFirstFace;
251 mySecondShape = theSecondFace;
252 myShapesNumber = 2;
253 gp_Pln aPlane;
254 aPlane.SetAxis (theAxis);
255 SetWorkingPlane (aPlane);
7fd59977 256}
257
7fd59977 258//=======================================================================
a6eb515f 259//function : SetFirstShape
7fd59977 260//purpose :
261//=======================================================================
262
a6eb515f 263void AIS_AngleDimension::SetFirstShape (const TopoDS_Shape& theShape,
264 const Standard_Boolean isSingleShape /*= Standard_False*/)
7fd59977 265{
a6eb515f 266 AIS_Dimension::SetFirstShape (theShape);
267 if (isSingleShape)
268 myShapesNumber = 1;
7fd59977 269}
270
7fd59977 271//=======================================================================
a6eb515f 272//function : aboveInBelowCone
273//purpose : Returns 1 if <theC> center is above of <theCMin> center;
274// 0 if <theC> center is between <theCMin> and
275// <theCMax> centers;
276// -1 if <theC> center is below <theCMax> center.
7fd59977 277//=======================================================================
278
a6eb515f 279Standard_Integer AIS_AngleDimension::aboveInBelowCone (const gp_Circ &theCMax,
280 const gp_Circ &theCMin,
281 const gp_Circ &theC)
7fd59977 282{
a6eb515f 283 const Standard_Real aD = theCMax.Location().Distance (theCMin.Location());
284 const Standard_Real aD1 = theCMax.Location().Distance (theC.Location());
285 const Standard_Real aD2 = theCMin.Location().Distance (theC.Location());
286
287 if (aD >= aD1 && aD >= aD2) return 0;
288 if (aD < aD2 && aD1 < aD2) return -1;
289 if (aD < aD1 && aD2 < aD1) return 1;
290 return 0;
7fd59977 291}
292
293//=======================================================================
a6eb515f 294//function : initConeAngle
295//purpose : initialization of the cone angle
7fd59977 296//=======================================================================
297
a6eb515f 298Standard_Boolean AIS_AngleDimension::initConeAngle (const TopoDS_Face& theCone)
7fd59977 299{
a6eb515f 300 if (theCone.IsNull ())
301 return Standard_False;
7fd59977 302
a6eb515f 303 gp_Pln aPln;
304 gp_Cone aCone;
305 gp_Circ aCircle;
306 // A surface from the Face
307 Handle(Geom_Surface) aSurf;
308 Handle(Geom_OffsetSurface) aOffsetSurf;
309 Handle(Geom_ConicalSurface) aConicalSurf;
310 Handle(Geom_SurfaceOfRevolution) aRevSurf;
311 Handle(Geom_Line) aLine;
312 BRepAdaptor_Surface aConeAdaptor (theCone);
313 TopoDS_Face aFace;
314 AIS_KindOfSurface aSurfType;
315 Standard_Real anOffset = 0.;
316 Handle(Standard_Type) aType;
7fd59977 317
a6eb515f 318 Standard_Real aMaxV = aConeAdaptor.FirstVParameter();
319 Standard_Real aMinV = aConeAdaptor.LastVParameter();
7fd59977 320
a6eb515f 321 AIS::GetPlaneFromFace(theCone, aPln, aSurf, aSurfType, anOffset);
7fd59977 322
a6eb515f 323 if (aSurfType == AIS_KOS_Revolution)
324 {
325 // Surface of revolution
326 aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf);
327 gp_Lin aLin (aRevSurf->Axis());
328 Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve();
329 //Must be a part of line (basis curve should be linear)
330 if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line))
331 return Standard_False;
332
333 gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV);
334 gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV);
335 gp_Vec aVec1 (aFirst1, aLast1);
336
337 //Projection <aFirst> on <aLin>
338 gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin);
339 // Projection <aLast> on <aLin>
340 gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin);
341
342 gp_Vec aVec2 (aFirst2, aLast2);
343
344 // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle).
345 if (aVec1.IsParallel (aVec2, Precision::Angular())
346 || aVec1.IsNormal (aVec2,Precision::Angular()))
347 return Standard_False;
348
349 gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1);
350 aCone = aMkCone.Value();
351 myCenter = aCone.Apex();
352 }
353 else
354 {
355 aType = aSurf->DynamicType();
356 if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01)
7fd59977 357 {
a6eb515f 358 // Offset surface
359 aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset);
360 aSurf = aOffsetSurf->Surface();
361 BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion());
362 aMkFace.Build();
363 if (!aMkFace.IsDone())
364 return Standard_False;
365 aConeAdaptor.Initialize (aMkFace.Face());
7fd59977 366 }
a6eb515f 367 aCone = aConeAdaptor.Cone();
368 aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf);
369 myCenter = aConicalSurf->Apex();
7fd59977 370 }
7fd59977 371
a6eb515f 372 // A circle where the angle is drawn
373 Handle(Geom_Curve) aCurve;
374 Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5;
375 aCurve = aSurf->VIso (aMidV);
376 aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
7fd59977 377
a6eb515f 378 aCurve = aSurf->VIso(aMaxV);
379 gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
380 aCurve = aSurf->VIso(aMinV);
381 gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
7fd59977 382
7fd59977 383
a6eb515f 384 if (aCircVmax.Radius() < aCircVmin.Radius())
385 {
386 gp_Circ aTmpCirc = aCircVmax;
387 aCircVmax = aCircVmin;
388 aCircVmin = aTmpCirc;
389 }
7fd59977 390
a6eb515f 391 myFirstPoint = ElCLib::Value (0, aCircle);
392 mySecondPoint = ElCLib::Value (M_PI, aCircle);
393 return Standard_True;
7fd59977 394}
395
396//=======================================================================
a6eb515f 397//function : initTwoFacesAngle
398//purpose : initialization of angle dimension between two faces
7fd59977 399//=======================================================================
400
a6eb515f 401Standard_Boolean AIS_AngleDimension::initTwoFacesAngle ()
7fd59977 402{
a6eb515f 403 TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
404 TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
405 gp_Dir aFirstDir, aSecondDir;
406 gp_Pln aFirstPlane, aSecondPlane;
407 Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
408 AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
409 Standard_Real aFirstOffset, aSecondOffset;
7fd59977 410
a6eb515f 411 AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
412 aFirstBasisSurf,aFirstSurfType,aFirstOffset);
413 AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
414 aSecondBasisSurf, aSecondSurfType, aSecondOffset);
415
416 if (aFirstSurfType == AIS_KOS_Plane)
417 {
418 //Planar faces angle
419 AIS::ComputeAngleBetweenPlanarFaces (aFirstFace,
420 aSecondFace,
421 aSecondBasisSurf,
422 GetWorkingPlane().Axis(),
423 myValue,
424 Standard_True,
425 myGeom.myTextPosition,
426 myCenter,
427 myFirstPoint,
428 mySecondPoint,
429 aFirstDir,
430 aSecondDir);
7fd59977 431 }
a6eb515f 432 else
433 {
434 // Curvilinear faces angle
435 Handle(Geom_Plane) aPlane = new Geom_Plane (GetWorkingPlane());
436 AIS::ComputeAngleBetweenCurvilinearFaces (aFirstFace,
437 aSecondFace,
438 aFirstBasisSurf,
439 aSecondBasisSurf,
440 aFirstSurfType,
441 aSecondSurfType,
442 GetWorkingPlane().Axis(),
443 myValue,
444 Standard_True,
445 myGeom.myTextPosition,
446 myCenter,
447 myFirstPoint,
448 mySecondPoint,
449 aFirstDir,
450 aSecondDir,
451 aPlane);
452 SetWorkingPlane (aPlane->Pln());
7fd59977 453 }
a6eb515f 454 return Standard_True;
7fd59977 455}
456
7fd59977 457//=======================================================================
a6eb515f 458//function : countDefaultPlane
7fd59977 459//purpose :
460//=======================================================================
461
a6eb515f 462void AIS_AngleDimension::countDefaultPlane ()
7fd59977 463{
a6eb515f 464 if (!myIsInitialized)
465 return;
466 // Compute normal of the default plane.
467 gp_Vec aVec1(myCenter, myFirstPoint),
468 aVec2(myCenter, mySecondPoint);
469 myDefaultPlane = gp_Pln(myCenter, aVec1^aVec2);
470 // Set computed value to <myWorkingPlane>
471 ResetWorkingPlane ();
7fd59977 472}
473
474//=======================================================================
a6eb515f 475//function : computeValue
7fd59977 476//purpose :
477//=======================================================================
478
a6eb515f 479void AIS_AngleDimension::computeValue ()
7fd59977 480{
a6eb515f 481 gp_Vec aVec1 (myCenter, myFirstPoint),
482 aVec2 (myCenter, mySecondPoint);
483 myValue = aVec1.Angle (aVec2);
484 // To model units
485 AIS_Dimension::computeValue();
7fd59977 486}
487
7fd59977 488//=======================================================================
a6eb515f 489//function : initTwoEdgesAngle
490//purpose : Fill gp_Pnt fields for further presentation computation
491// If intersection between two edges doesn't exist
492// <myIsInitialized> is set to false
7fd59977 493//=======================================================================
494
a6eb515f 495Standard_Boolean AIS_AngleDimension::initTwoEdgesAngle ()
7fd59977 496{
a6eb515f 497 // Data initialization
498 TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape);
499 TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape);
500 BRepAdaptor_Curve aMakeFirstLine (aFirstEdge);
501 BRepAdaptor_Curve aMakeSecondLine (aSecondEdge);
7fd59977 502
a6eb515f 503 if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line)
504 {
505 return Standard_False;
7fd59977 506 }
507
a6eb515f 508 Handle(Geom_Line) aFirstLine = new Geom_Line (aMakeFirstLine.Line());
509 Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line());
7fd59977 510
a6eb515f 511 gp_Lin aFirstLin = aFirstLine->Lin ();
512 gp_Lin aSecondLin = aSecondLine->Lin ();
513 gp_Lin2d aFirstLin2d, aSecondLin2d;
514 Standard_Boolean isParallelLines = aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular());
515 Standard_Boolean isSameLines = isParallelLines && aFirstLin.Distance (aSecondLin.Location()) <= Precision::Confusion();
516 // In case where we can't compute plane automatically
517 if ((isParallelLines || isSameLines) && !myIsWorkingPlaneCustom)
518 {
519 return Standard_False;
7fd59977 520 }
521
a6eb515f 522 gp_Pln aPlane;
7fd59977 523
a6eb515f 524 /// PART 1 is for automatic plane computation from two edges if it is possible
525 // Build plane
526 if (!myIsWorkingPlaneCustom)
527 {
528 gp_Pnt aPoint = aFirstLine->Value (0.);
529 gp_Dir aNormal = isParallelLines
530 ? gp_Vec(aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction())
531 : gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction());
532 aPlane = gp_Pln (aPoint, aNormal);
533 resetWorkingPlane (aPlane);
7fd59977 534 }
a6eb515f 535 else
536 {
537 aPlane = GetWorkingPlane();
7fd59977 538 }
539
a6eb515f 540 // Compute geometry for this plane and edges
541 Standard_Boolean isInfinite1,isInfinite2;
542 gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2;
543 Standard_Integer anExtIndex = -1;
544 Handle(Geom_Curve) anExtCurve;
545 Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
546 if (!AIS::ComputeGeometry (aFirstEdge, aSecondEdge,
547 anExtIndex,
548 aFirstLine, aSecondLine,
549 aFirstPoint1, aLastPoint1,
550 aFirstPoint2, aLastPoint2,
551 anExtCurve,
552 isInfinite1, isInfinite2,
553 aGeomPlane))
554 {
555 return Standard_False;
7fd59977 556 }
557
a6eb515f 558 // Check if both edges are on this plane
559 if (!anExtCurve.IsNull())
560 {
561 if (anExtIndex == 1) // First curve is out of the plane
562 {
563 // Project curve on the plane
564 if (myIsWorkingPlaneCustom)
565 {
566 aFirstLin2d = ProjLib::Project (aPlane, aFirstLin);
567 aFirstLin = ElCLib::To3d (aPlane.Position().Ax2(), aFirstLin2d);
7fd59977 568 }
a6eb515f 569 else
570 {
571 aFirstLin.Translate (gp_Vec (aFirstLin.Location(), aSecondLin.Location()));
7fd59977 572 }
7fd59977 573
a6eb515f 574 aFirstLine = new Geom_Line (aFirstLin);
7fd59977 575 }
a6eb515f 576 else if (anExtIndex == 2) // Second curve is out of the plane
577 {
578 if (myIsWorkingPlaneCustom)
579 {
580 aSecondLin2d = ProjLib::Project (aPlane, aSecondLin);
581 aSecondLin = ElCLib::To3d (aPlane.Position().Ax2(), aSecondLin2d);
7fd59977 582 }
a6eb515f 583 else
584 {
585 aSecondLin.Translate (gp_Vec (aSecondLin.Location(), aFirstLin.Location()));
7fd59977 586 }
a6eb515f 587
588 aSecondLine = new Geom_Line (aSecondLin);
7fd59977 589 }
590 }
591
a6eb515f 592 /// PART 2 is for dimension computation using the working plane
7fd59977 593
a6eb515f 594 if (aFirstLin.Direction ().IsParallel (aSecondLin.Direction (), Precision::Angular ()))
595 {
596 // Parallel lines
597 isSameLines = aFirstLin.Distance(aSecondLin.Location()) <= Precision::Confusion();
598 if (!isSameLines)
599 return Standard_False;
600
601 myFirstPoint = aFirstLin.Location();
602 mySecondPoint = ElCLib::Value (ElCLib::Parameter (aFirstLin, myFirstPoint), aSecondLin);
603 if (mySecondPoint.Distance (mySecondPoint) <= Precision::Confusion ())
604 mySecondPoint.Translate (gp_Vec (aSecondLin.Direction ())*Abs(GetFlyout()));
605 myCenter.SetXYZ( (myFirstPoint.XYZ() + mySecondPoint.XYZ()) / 2. );
606 }
607 else
608 {
609 // Find intersection
610 aFirstLin2d = ProjLib::Project (aPlane, aFirstLin);
611 aSecondLin2d = ProjLib::Project (aPlane, aSecondLin);
7fd59977 612
a6eb515f 613 IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d);
614 gp_Pnt2d anIntersectPoint;
615 if (!anInt2d.IsDone() || anInt2d.IsEmpty())
7fd59977 616 {
a6eb515f 617 return Standard_False;
7fd59977 618 }
619
a6eb515f 620 anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value());
621 myCenter = ElCLib::To3d(aPlane.Position().Ax2(), anIntersectPoint);
7fd59977 622
a6eb515f 623 if (isInfinite1 || isInfinite2)
7fd59977 624 {
a6eb515f 625 myFirstPoint = myCenter.Translated (gp_Vec (aFirstLin.Direction())*Abs (GetFlyout()));
626 mySecondPoint = myCenter.Translated (gp_Vec (aSecondLin.Direction())*Abs (GetFlyout()));
627 return Standard_True;
7fd59977 628 }
629
a6eb515f 630 // |
631 // | <- dimension should be here
632 // *----
633 myFirstPoint = myCenter.Distance (aFirstPoint1) > myCenter.Distance (aLastPoint1) ? aFirstPoint1 : aLastPoint1;
634 mySecondPoint = myCenter.Distance (aFirstPoint2) > myCenter.Distance (aLastPoint2) ? aFirstPoint2 : aLastPoint2;
635 }
636 return Standard_True;
7fd59977 637}
638
639//=======================================================================
a6eb515f 640//function : canTextBeInCenter
641//purpose : Auxiliary method to arrange text and arrows
7fd59977 642//=======================================================================
643
a6eb515f 644Standard_Boolean AIS_AngleDimension::canTextBeInCenter (const gp_Pnt& theFirstAttach,
645 const gp_Pnt& theSecondAttach,
646 const Quantity_Length& theTextLength,
647 const Quantity_Length& theArrowLength)
7fd59977 648{
a6eb515f 649 gp_Vec anAttachVector (theFirstAttach, theSecondAttach);
650 Standard_Real aValue = anAttachVector.Magnitude();
651 return (aValue < theTextLength + 2.*theArrowLength) ? Standard_False : Standard_True;
652}
7fd59977 653
a6eb515f 654//=======================================================================
655//function: getCenterOnArc
656//purpose :
657//=======================================================================
658gp_Pnt AIS_AngleDimension::getCenterOnArc (const gp_Pnt& theFirstAttach,
659 const gp_Pnt& theSecondAttach)
660{
661 gp_Pnt2d aCenter2d = ProjLib::Project (GetWorkingPlane(), myCenter),
662 aFirstAttach2d = ProjLib::Project (GetWorkingPlane(), theFirstAttach),
663 aSecondAttach2d = ProjLib::Project (GetWorkingPlane(), theSecondAttach);
664 gp_Lin2d anAttachLine2d = gce_MakeLin2d (aFirstAttach2d, aSecondAttach2d);
665
666 // Getting text center
667 gp_Pnt2d aTextCenterPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) + ElCLib::Parameter (anAttachLine2d, aSecondAttach2d)) / 2., anAttachLine2d);
668 gp_Lin2d aCenterToTextCenterLin = gce_MakeLin2d (aCenter2d, aTextCenterPnt);
669
670 // Drawing circle
671 Standard_Real aRadius = theFirstAttach.Distance (myCenter);
672 gp_Circ2d aCircle (gp_Ax22d (aCenter2d, gp_Dir2d (1, 0)), aRadius);
673
674 // Getting text position in the center of arc
675 IntAna2d_AnaIntersection anInt2d (aCenterToTextCenterLin, aCircle);
676 gp_Pnt2d aTextCenterOnArc2d;
677 if (anInt2d.IsDone())
678 if (!anInt2d.IsEmpty())
679 aTextCenterOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
680 gp_Pnt aCenterOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextCenterOnArc2d);
681 return aCenterOnArc;
7fd59977 682}
a6eb515f 683
7fd59977 684//=======================================================================
a6eb515f 685//function: drawArcWithText
686//purpose :
7fd59977 687//=======================================================================
688
a6eb515f 689void AIS_AngleDimension::drawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
690 const gp_Pnt& theFirstAttach,
691 const gp_Pnt& theSecondAttach,
692 const TCollection_ExtendedString& theText,
693 const AIS_DimensionDisplayMode theMode)
7fd59977 694{
a6eb515f 695 gp_Pnt2d aCenter2d = ProjLib::Project (GetWorkingPlane(), myCenter),
696 aFirstAttach2d = ProjLib::Project (GetWorkingPlane(), theFirstAttach),
697 aSecondAttach2d = ProjLib::Project (GetWorkingPlane(), theSecondAttach);
698 gp_Lin2d anAttachLine2d = gce_MakeLin2d (aFirstAttach2d, aSecondAttach2d);
699
700 // Getting text center
701 gp_Pnt2d aTextCenterPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) + ElCLib::Parameter (anAttachLine2d, aSecondAttach2d)) / 2., anAttachLine2d);
702 gp_Lin2d aCenterToTextCenterLin = gce_MakeLin2d (aCenter2d, aTextCenterPnt);
703
704 // Drawing circle
705 Standard_Real aRadius = theFirstAttach.Distance (myCenter);
706 gp_Circ2d aCircle (gp_Ax22d (aCenter2d, gp_Dir2d (1, 0)), aRadius);
707
708 // Getting text position in the center of arc
709 IntAna2d_AnaIntersection anInt2d (aCenterToTextCenterLin, aCircle);
710 gp_Pnt2d aTextCenterOnArc2d;
711 if (anInt2d.IsDone())
712 if (!anInt2d.IsEmpty())
713 aTextCenterOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
714 myGeom.myTextPosition = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextCenterOnArc2d);
715
716 // Drawing text
717 gp_Vec aVec (theFirstAttach, theSecondAttach);
718 Standard_Real aTextWidth = drawText (thePresentation,
719 myIsTextReversed ? aVec.Reversed() : aVec,
720 theText,theMode);
721
722 // Getting text begin and end points
723 gp_Pnt2d aTextBeginPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) +
724 ElCLib::Parameter (anAttachLine2d, aSecondAttach2d) -
725 aTextWidth) / 2., anAttachLine2d),
726 aTextEndPnt = ElCLib::Value (ElCLib::Parameter (anAttachLine2d,aTextBeginPnt) + aTextWidth, anAttachLine2d);
727
728
729 gp_Lin2d aCenterToTextBeginLin = gce_MakeLin2d (aCenter2d, aTextBeginPnt),
730 aCenterToTextEndLin = gce_MakeLin2d (aCenter2d, aTextEndPnt);
731
732 // Text begin and end on the dimension arc
733 gp_Pnt2d aTextBeginOnArc2d, aTextEndOnArc2d;
734 anInt2d.Perform (aCenterToTextBeginLin, aCircle);
735 if (anInt2d.IsDone())
736 if (!anInt2d.IsEmpty())
737 aTextBeginOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
738
739 anInt2d.Perform (aCenterToTextEndLin, aCircle);
740 if (anInt2d.IsDone())
741 if (!anInt2d.IsEmpty())
742 aTextEndOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value());
743
744 gp_Pnt aTextBeginOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextBeginOnArc2d);
745 gp_Pnt aTextEndOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextEndOnArc2d);
746
747 // Drawing arcs
748 if (theMode != AIS_DDM_Text)
749 {
750 drawArc (thePresentation, theFirstAttach, aTextBeginOnArc, myCenter, aRadius, theMode);
751 drawArc (thePresentation, aTextEndOnArc, theSecondAttach, myCenter, aRadius, theMode);
7fd59977 752 }
7fd59977 753
a6eb515f 754}
7fd59977 755
a6eb515f 756//=======================================================================
757//function : drawArc
758//purpose : draws the arc between two attach points
759//=======================================================================
7fd59977 760
a6eb515f 761void AIS_AngleDimension::drawArc (const Handle(Prs3d_Presentation)& thePresentation,
762 const gp_Pnt& theFirstAttach,
763 const gp_Pnt& theSecondAttach,
764 const gp_Pnt& theCenter,
765 const Standard_Real theRadius,
766 const AIS_DimensionDisplayMode theMode)
767{
768 Handle(SelectMgr_EntityOwner) anEmptyOwner;
769 Prs3d_Root::CurrentGroup (thePresentation)->
770 SetPrimitivesAspect(myDrawer->DimensionAspect()->LineAspect()->Aspect());
771
772 gp_Vec aCenterToFirstVec (theCenter,theFirstAttach);
773 gp_Vec aCenterToSecondVec (theCenter,theSecondAttach);
774 gp_Dir aCenterToFirstDir (aCenterToFirstVec);
775 gp_Dir aPlaneNormal = GetWorkingPlane().Axis().Direction();
776 gp_Dir aCenterToSecondDir = aPlaneNormal.Crossed (aCenterToFirstDir);
777
778 const Standard_Real anAngle = aCenterToFirstVec.Angle(aCenterToSecondVec);
779 const Standard_Integer aPointsOnArc = Max (4 , Standard_Integer (50. * anAngle / M_PI));
780 const Standard_Real anAngleStep = anAngle / (aPointsOnArc - 1);
781 TColgp_Array1OfPnt aPointArray (0,aPointsOnArc-1);
782 Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aPointsOnArc,2);
783 aPrimSegments->AddVertex (theFirstAttach);
784 aPointArray.SetValue(0, theFirstAttach);
785 gp_Pnt aPoint = theFirstAttach;
786 gp_Vec aVector;
787
788 for (Standard_Integer anI = 1; anI < aPointsOnArc - 1; ++anI)
789 {
790 aVector = (gp_Vec(aCenterToFirstDir) * Cos ( (anI - 1) * anAngleStep) + gp_Vec(aCenterToSecondDir) * Sin ( (anI - 1) * anAngleStep)) * theRadius;
791 aPoint = theCenter.Translated(aVector);
792 aPrimSegments->AddVertex(aPoint);
793 aPointArray.SetValue (anI,aPoint);
7fd59977 794 }
a6eb515f 795 aPrimSegments->AddVertex (theSecondAttach);
796 aPointArray.SetValue (aPointsOnArc - 1,theSecondAttach);
7fd59977 797
a6eb515f 798 // Fill sensitive list
799 myGeom.mySensitiveSegments.Append(new Select3D_SensitiveCurve(anEmptyOwner,aPointArray));
7fd59977 800
a6eb515f 801 // Fill display presentation
802 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
803 {
804 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
7fd59977 805 }
a6eb515f 806 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
807 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
808 {
809 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
7fd59977 810 }
811}
812
7fd59977 813//=======================================================================
a6eb515f 814//function : Compute
815//purpose : Having three gp_Pnt points compute presentation
7fd59977 816//=======================================================================
7fd59977 817
a6eb515f 818void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
819 const Handle(Prs3d_Presentation)& thePresentation,
820 const Standard_Integer theMode)
821{
822 thePresentation->Clear();
823 myGeom.mySensitiveSegments.Clear();
824 Handle(SelectMgr_EntityOwner) anEmptyOwner;
7fd59977 825
a6eb515f 826 if (!myIsInitialized)
827 {
828 if (myShapesNumber == 1)
829 {
830 myIsInitialized = initConeAngle (TopoDS::Face (myFirstShape));
831 }
832 else if (myShapesNumber == 2)
833 {
834 switch (myFirstShape.ShapeType())
835 {
836 case TopAbs_FACE:
837 {
838 myIsInitialized = initTwoFacesAngle ();
839 }
840 break;
841 case TopAbs_EDGE:
842 {
843 myIsInitialized = initTwoEdgesAngle ();
844 }
845 break;
846 default:
847 return;
848 }
849 }
850 else
851 return;
7fd59977 852 }
853
a6eb515f 854 // If initialization failed
855 if (!myIsInitialized)
856 return;
7fd59977 857
a6eb515f 858 // Parameters for presentation
859 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
860 Prs3d_Root::CurrentGroup(thePresentation)->
861 SetPrimitivesAspect(aDimensionAspect->LineAspect()->Aspect());
862 Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
863 if (!myIsValueCustom)
864 computeValue ();
865 TCollection_ExtendedString aValueString;
866 Standard_Real aTextLength;
867 getTextWidthAndString (aTextLength, aValueString);
868 if (!myIsWorkingPlaneCustom)
869 countDefaultPlane();
870 gp_Pnt aFirstAttach = myCenter.Translated (gp_Vec(myCenter, myFirstPoint).Normalized() * GetFlyout());
871 gp_Pnt aSecondAttach = myCenter.Translated (gp_Vec(myCenter, mySecondPoint).Normalized() * GetFlyout());
872 // Attach points and radius
873 if (aDimensionAspect->HorizontalTextAlignment () == Prs3d_HTA_Center)
874 {
875 aDimensionAspect->SetArrowOrientation (Prs3d_DAO_Internal);
7fd59977 876
a6eb515f 877 if (!canTextBeInCenter (aFirstAttach, aSecondAttach, aTextLength, anArrowLength))
878 {
879 aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
880 aDimensionAspect->SetHorizontalTextAlignment (Prs3d_HTA_Left);
881 }
7fd59977 882 }
a6eb515f 883 else
884 aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
7fd59977 885
a6eb515f 886 //Arrows positions and directions
887 gp_Vec aFirstArrowVec = (gp_Vec(myCenter, aFirstAttach)^gp_Vec(GetWorkingPlane().Axis().Direction())).Normalized().Reversed()*anArrowLength;
888 gp_Vec aSecondArrowVec = (gp_Vec(myCenter, aSecondAttach)^gp_Vec(GetWorkingPlane().Axis().Direction())).Normalized()*anArrowLength;
7fd59977 889
a6eb515f 890 gp_Pnt aFirstArrowBegin,
891 aFirstArrowEnd,
892 aSecondArrowBegin,
893 aSecondArrowEnd;
7fd59977 894
a6eb515f 895 if (aDimensionAspect->GetArrowOrientation() == Prs3d_DAO_External)
896 {
897 aFirstArrowVec.Reverse();
898 aSecondArrowVec.Reverse();
7fd59977 899
a6eb515f 900 aFirstArrowBegin = aFirstAttach.Translated (aFirstArrowVec);
901 aFirstArrowEnd = aFirstAttach;
902 aSecondArrowBegin = aSecondAttach;
903 aSecondArrowEnd = aSecondAttach.Translated (aSecondArrowVec);
7fd59977 904 }
a6eb515f 905 else
906 {
907 aFirstArrowBegin = aFirstAttach;
908 aFirstArrowEnd = aFirstAttach.Translated (aFirstArrowVec);
909 aSecondArrowBegin = aSecondAttach.Translated (aSecondArrowVec);
910 aSecondArrowEnd = aSecondAttach;
7fd59977 911 }
b8ddfc2f 912
a6eb515f 913 // Fill presentation
914 Handle(Graphic3d_ArrayOfSegments) aPrimSegments;
915 Standard_Boolean isTextInCenter = aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Center;
916 if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Center)
b8ddfc2f 917 {
a6eb515f 918 // Important! Current implementation doesn't draw the extensions here
919 aPrimSegments = new Graphic3d_ArrayOfSegments (4);
920 // Get text begin and end positions (text is positioned in the center between two attach points)
921 gp_Pnt aTextBeginOnArc, aTextEndOnArc, anArcCenter;
922 if (isTextInCenter && aDimensionAspect->IsText3d())
923 {
924 drawArcWithText (thePresentation, aFirstAttach, aSecondAttach, aValueString, (AIS_DimensionDisplayMode)theMode);
925 }
926 else
927 {
928 gp_Vec aTextDir (aFirstArrowEnd, aSecondArrowBegin);
929 myGeom.myTextPosition = getCenterOnArc (aFirstArrowEnd, aSecondArrowBegin);
930 drawText (thePresentation,
931 myIsTextReversed ? aTextDir.Reversed() : aTextDir,
932 aValueString, (AIS_DimensionDisplayMode)theMode);
933 if (theMode != AIS_DDM_Text)
934 drawArc (thePresentation, aFirstArrowEnd, aSecondArrowBegin, myCenter, Abs (GetFlyout()), (AIS_DimensionDisplayMode)theMode);
935 }
7fd59977 936 }
a6eb515f 937 else
938 {
939 // Lines for extensions
940 gp_Lin aLeftExtension (aFirstAttach,gp_Dir(aFirstArrowVec));
941 gp_Lin aRightExtension (aSecondAttach, gp_Dir(aSecondArrowVec));
942 aPrimSegments = new Graphic3d_ArrayOfSegments (6);
943 gp_Pnt aStartPoint;
944 if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Left)
945 {
946 aStartPoint = aFirstArrowBegin;
947 // Short extension
948 aPrimSegments->AddVertex (aSecondArrowEnd);
949 aPrimSegments->AddVertex (aSecondArrowEnd.Translated(gp_Vec(aRightExtension.Direction())*anArrowLength));
950 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment(anEmptyOwner,
951 aSecondArrowEnd,
952 aSecondArrowEnd.Translated(gp_Vec(aRightExtension.Direction())*anArrowLength)));
953
954 // Long extension
955 drawExtensionWithText (thePresentation, aStartPoint, aLeftExtension, aValueString, (AIS_DimensionDisplayMode)theMode);
956 }
957 else // Prs3d_HTA_Right
958 {
959 aStartPoint = aSecondArrowEnd;
960 // Short extension
961 aPrimSegments->AddVertex (aFirstArrowBegin);
962 aPrimSegments->AddVertex (aFirstArrowBegin.Translated (gp_Vec (aLeftExtension.Direction()) * anArrowLength));
963 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment(anEmptyOwner,
964 aFirstArrowBegin,
965 aFirstArrowBegin.Translated (gp_Vec (aLeftExtension.Direction()) * anArrowLength)));
966
967 // Long extension
968 drawExtensionWithText (thePresentation, aStartPoint, aRightExtension, aValueString, (AIS_DimensionDisplayMode)theMode);
969 }
7fd59977 970
a6eb515f 971 if (theMode != AIS_DDM_Text)
972 {
973 // Draw main arc
974 drawArc (thePresentation, aFirstArrowEnd, aSecondArrowBegin, myCenter, Abs(GetFlyout ()), (AIS_DimensionDisplayMode)theMode);
975 }
976 }
7fd59977 977
a6eb515f 978 // Draw flyout lines and arrows in new group.
979 Prs3d_Root::NewGroup (thePresentation)
980 ->SetPrimitivesAspect (myDrawer->DimensionAspect()->LineAspect()->Aspect());
981 if (theMode == AIS_DDM_All && myIsFlyoutLines)
982 {
983 aPrimSegments->AddVertex (myCenter);
984 aPrimSegments->AddVertex (aFirstAttach);
985 aPrimSegments->AddVertex (myCenter);
986 aPrimSegments->AddVertex (aSecondAttach);
987 }
988 if (theMode != AIS_DDM_Text)
b8ddfc2f 989 {
a6eb515f 990 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
991 drawArrow (thePresentation, aFirstAttach, gp_Dir (aFirstArrowVec));
992 drawArrow (thePresentation, aSecondAttach, gp_Dir (aSecondArrowVec));
7fd59977 993 }
994
a6eb515f 995 setComputed (Standard_True);
7fd59977 996}
62b6361a 997
998//=======================================================================
999//function : computeFlyoutSelection
1000//purpose : computes selection for flyouts
1001//=======================================================================
1002
1003void AIS_AngleDimension::computeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
1004 const Handle(AIS_DimensionOwner)& theOwner)
1005{
1006 if (!myIsFlyoutLines)
1007 return;
1008
1009 gp_Pnt aFirstAttach = myCenter.Translated (gp_Vec (myCenter, myFirstPoint).Normalized() * GetFlyout());
1010 gp_Pnt aSecondAttach = myCenter.Translated (gp_Vec (myCenter, mySecondPoint).Normalized() * GetFlyout());
1011 Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner);
1012 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenter, aFirstAttach));
1013 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenter, aSecondAttach));
1014 theSelection->Add (aSensitiveEntity);
1015}