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