0024547: Convertation of the generic classes to the non-generic (math).
[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
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//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public version 2.1 as published
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
a6eb515f 17#include <AIS_AngleDimension.hxx>
7fd59977 18
19#include <AIS.hxx>
7fd59977 20#include <AIS_Drawer.hxx>
7fd59977 21#include <BRepBuilderAPI_MakeFace.hxx>
22#include <BRepAdaptor_Curve.hxx>
23#include <BRepAdaptor_Surface.hxx>
60bf98ae 24#include <BRepLib_MakeVertex.hxx>
25#include <BRep_Tool.hxx>
7fd59977 26#include <ElCLib.hxx>
60bf98ae 27#include <GCPnts_UniformAbscissa.hxx>
28#include <GC_MakeArcOfCircle.hxx>
a6eb515f 29#include <gce_MakeLin2d.hxx>
60bf98ae 30#include <gce_MakeLin.hxx>
31#include <gce_MakeCirc.hxx>
a6eb515f 32#include <gce_MakeCone.hxx>
fe83e1ea 33#include <gce_MakePln.hxx>
fe83e1ea 34#include <gce_MakeDir.hxx>
7fd59977 35#include <Geom_Circle.hxx>
60bf98ae 36#include <Geom_TrimmedCurve.hxx>
7fd59977 37#include <Geom_ConicalSurface.hxx>
38#include <Geom_SurfaceOfRevolution.hxx>
7fd59977 39#include <Geom_OffsetSurface.hxx>
a6eb515f 40#include <Graphic3d_ArrayOfSegments.hxx>
a6eb515f 41#include <Graphic3d_Group.hxx>
a6eb515f 42#include <Graphic3d_ArrayOfPolylines.hxx>
7fd59977 43#include <IntAna2d_AnaIntersection.hxx>
7fd59977 44#include <ProjLib.hxx>
a6eb515f 45#include <Prs3d_Root.hxx>
d7bffd44 46#include <Prs3d_ShadingAspect.hxx>
a6eb515f 47#include <PrsMgr_PresentationManager3d.hxx>
62b6361a 48#include <Select3D_SensitiveGroup.hxx>
7fd59977 49#include <Select3D_SensitiveSegment.hxx>
a6eb515f 50#include <SelectMgr_Selection.hxx>
7fd59977 51#include <UnitsAPI.hxx>
52
a6eb515f 53IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension)
54IMPLEMENT_STANDARD_RTTIEXT (AIS_AngleDimension, AIS_Dimension)
7fd59977 55
d7bffd44 56namespace
57{
fe83e1ea 58 static const TCollection_ExtendedString THE_EMPTY_LABEL_STRING;
59 static const Standard_Real THE_EMPTY_LABEL_WIDTH = 0.0;
60 static const Standard_ExtCharacter THE_DEGREE_SYMBOL (0x00B0);
61 static const Standard_Real THE_3D_TEXT_MARGIN = 0.1;
d7bffd44 62};
63
7fd59977 64//=======================================================================
7fd59977 65//function : Constructor
60bf98ae 66//purpose :
7fd59977 67//=======================================================================
a6eb515f 68AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
69 const TopoDS_Edge& theSecondEdge)
60bf98ae 70: AIS_Dimension (AIS_KOD_PLANEANGLE)
7fd59977 71{
60bf98ae 72 Init();
73 SetMeasuredGeometry (theFirstEdge, theSecondEdge);
7fd59977 74}
75
7fd59977 76//=======================================================================
77//function : Constructor
60bf98ae 78//purpose :
7fd59977 79//=======================================================================
60bf98ae 80AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint,
81 const gp_Pnt& theSecondPoint,
82 const gp_Pnt& theThirdPoint)
83: AIS_Dimension (AIS_KOD_PLANEANGLE)
7fd59977 84{
60bf98ae 85 Init();
86 SetMeasuredGeometry (theFirstPoint, theSecondPoint, theThirdPoint);
7fd59977 87}
88
89//=======================================================================
90//function : Constructor
60bf98ae 91//purpose :
7fd59977 92//=======================================================================
60bf98ae 93AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Vertex& theFirstVertex,
94 const TopoDS_Vertex& theSecondVertex,
95 const TopoDS_Vertex& theThirdVertex)
96: AIS_Dimension (AIS_KOD_PLANEANGLE)
7fd59977 97{
60bf98ae 98 Init();
99 SetMeasuredGeometry (theFirstVertex, theSecondVertex, theThirdVertex);
7fd59977 100}
101
7fd59977 102//=======================================================================
a6eb515f 103//function : Constructor
60bf98ae 104//purpose :
7fd59977 105//=======================================================================
a6eb515f 106AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theCone)
60bf98ae 107: AIS_Dimension (AIS_KOD_PLANEANGLE)
7fd59977 108{
60bf98ae 109 Init();
110 SetMeasuredGeometry (theCone);
7fd59977 111}
112
113//=======================================================================
a6eb515f 114//function : Constructor
60bf98ae 115//purpose :
7fd59977 116//=======================================================================
a6eb515f 117AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace,
60bf98ae 118 const TopoDS_Face& theSecondFace)
119: AIS_Dimension (AIS_KOD_PLANEANGLE)
7fd59977 120{
60bf98ae 121 Init();
122 SetMeasuredGeometry (theFirstFace, theSecondFace);
7fd59977 123}
124
7fd59977 125//=======================================================================
60bf98ae 126//function : Constructor
7fd59977 127//purpose :
128//=======================================================================
60bf98ae 129AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace,
130 const TopoDS_Face& theSecondFace,
131 const gp_Pnt& thePoint)
132: AIS_Dimension (AIS_KOD_PLANEANGLE)
7fd59977 133{
60bf98ae 134 Init();
135 SetMeasuredGeometry (theFirstFace, theSecondFace, thePoint);
7fd59977 136}
137
7fd59977 138//=======================================================================
60bf98ae 139//function : SetMeasuredGeometry
140//purpose :
7fd59977 141//=======================================================================
60bf98ae 142void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Edge& theFirstEdge,
143 const TopoDS_Edge& theSecondEdge)
7fd59977 144{
60bf98ae 145 gp_Pln aComputedPlane;
146
147 myFirstShape = theFirstEdge;
148 mySecondShape = theSecondEdge;
149 myThirdShape = TopoDS_Shape();
150 myGeometryType = GeometryType_Edges;
151 myIsValid = InitTwoEdgesAngle (aComputedPlane);
152
153 if (myIsValid && !myIsPlaneCustom)
154 {
155 myPlane = aComputedPlane;
156 }
157
158 myIsValid &= CheckPlane (myPlane);
159
160 SetToUpdate();
7fd59977 161}
162
163//=======================================================================
60bf98ae 164//function : SetMeasuredGeometry
165//purpose :
7fd59977 166//=======================================================================
60bf98ae 167void AIS_AngleDimension::SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
168 const gp_Pnt& theSecondPoint,
169 const gp_Pnt& theThirdPoint)
7fd59977 170{
60bf98ae 171 myFirstPoint = theFirstPoint;
172 myCenterPoint = theSecondPoint;
173 mySecondPoint = theThirdPoint;
174 myFirstShape = BRepLib_MakeVertex (myFirstPoint);
175 mySecondShape = BRepLib_MakeVertex (myCenterPoint);
176 myThirdShape = BRepLib_MakeVertex (mySecondPoint);
177 myGeometryType = GeometryType_Points;
178 myIsValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
7fd59977 179
60bf98ae 180 if (myIsValid && !myIsPlaneCustom)
a6eb515f 181 {
60bf98ae 182 ComputePlane();
183 }
a6eb515f 184
60bf98ae 185 myIsValid &= CheckPlane (myPlane);
a6eb515f 186
60bf98ae 187 SetToUpdate();
188}
a6eb515f 189
60bf98ae 190//=======================================================================
191//function : SetMeasuredGeometry
192//purpose :
193//=======================================================================
194void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Vertex& theFirstVertex,
195 const TopoDS_Vertex& theSecondVertex,
196 const TopoDS_Vertex& theThirdVertex)
197{
198 myFirstShape = theFirstVertex;
199 mySecondShape = theSecondVertex;
200 myThirdShape = theThirdVertex;
201 myFirstPoint = BRep_Tool::Pnt (theFirstVertex);
202 myCenterPoint = BRep_Tool::Pnt (theSecondVertex);
203 mySecondPoint = BRep_Tool::Pnt (theThirdVertex);
204 myGeometryType = GeometryType_Points;
205 myIsValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
206
207 if (myIsValid && !myIsPlaneCustom)
a6eb515f 208 {
60bf98ae 209 ComputePlane();
7fd59977 210 }
7fd59977 211
60bf98ae 212 myIsValid &= CheckPlane (myPlane);
7fd59977 213
60bf98ae 214 SetToUpdate();
215}
7fd59977 216
60bf98ae 217//=======================================================================
218//function : SetMeasuredGeometry
219//purpose :
220//=======================================================================
221void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theCone)
222{
223 myFirstShape = theCone;
224 mySecondShape = TopoDS_Shape();
225 myThirdShape = TopoDS_Shape();
226 myGeometryType = GeometryType_Face;
227 myIsValid = InitConeAngle();
7fd59977 228
60bf98ae 229 if (myIsValid && !myIsPlaneCustom)
a6eb515f 230 {
60bf98ae 231 ComputePlane();
a6eb515f 232 }
7fd59977 233
60bf98ae 234 myIsValid &= CheckPlane (myPlane);
235
236 SetToUpdate();
7fd59977 237}
238
239//=======================================================================
60bf98ae 240//function : SetMeasuredGeometry
241//purpose :
7fd59977 242//=======================================================================
60bf98ae 243void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
244 const TopoDS_Face& theSecondFace)
7fd59977 245{
60bf98ae 246 myFirstShape = theFirstFace;
247 mySecondShape = theSecondFace;
248 myThirdShape = TopoDS_Shape();
249 myGeometryType = GeometryType_Faces;
250 myIsValid = InitTwoFacesAngle();
a6eb515f 251
60bf98ae 252 if (myIsValid && !myIsPlaneCustom)
a6eb515f 253 {
60bf98ae 254 ComputePlane();
7fd59977 255 }
60bf98ae 256
257 myIsValid &= CheckPlane (myPlane);
258
259 SetToUpdate();
7fd59977 260}
261
7fd59977 262//=======================================================================
60bf98ae 263//function : SetMeasuredGeometry
7fd59977 264//purpose :
265//=======================================================================
60bf98ae 266void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
267 const TopoDS_Face& theSecondFace,
268 const gp_Pnt& thePoint)
7fd59977 269{
60bf98ae 270 myFirstShape = theFirstFace;
271 mySecondShape = theSecondFace;
272 myThirdShape = TopoDS_Shape();
273 myGeometryType = GeometryType_Faces;
274 myIsValid = InitTwoFacesAngle (thePoint);
275
276 if (myIsValid && !myIsPlaneCustom)
277 {
278 ComputePlane();
279 }
280
281 myIsValid &= CheckPlane (myPlane);
282
283 SetToUpdate();
7fd59977 284}
285
286//=======================================================================
60bf98ae 287//function : Init
7fd59977 288//purpose :
289//=======================================================================
60bf98ae 290void AIS_AngleDimension::Init()
7fd59977 291{
60bf98ae 292 SetSpecialSymbol (THE_DEGREE_SYMBOL);
293 SetDisplaySpecialSymbol (AIS_DSS_After);
294 SetFlyout (15.0);
7fd59977 295}
296
7fd59977 297//=======================================================================
60bf98ae 298//function: GetCenterOnArc
299//purpose :
7fd59977 300//=======================================================================
60bf98ae 301gp_Pnt AIS_AngleDimension::GetCenterOnArc (const gp_Pnt& theFirstAttach,
302 const gp_Pnt& theSecondAttach,
303 const gp_Pnt& theCenter)
7fd59977 304{
60bf98ae 305 // construct plane where the circle and the arc are located
306 gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
307 if (!aConstructPlane.IsDone())
a6eb515f 308 {
60bf98ae 309 return gp::Origin();
7fd59977 310 }
60bf98ae 311
312 gp_Pln aPlane = aConstructPlane.Value();
7fd59977 313
60bf98ae 314 Standard_Real aRadius = theFirstAttach.Distance (theCenter);
7fd59977 315
60bf98ae 316 // construct circle forming the arc
317 gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
318 if (!aConstructCircle.IsDone())
a6eb515f 319 {
60bf98ae 320 return gp::Origin();
7fd59977 321 }
322
60bf98ae 323 gp_Circ aCircle = aConstructCircle.Value();
324
325 // compute angle parameters of arc end-points on circle
326 Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
327 Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
328 ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
7fd59977 329
60bf98ae 330 return ElCLib::Value ((aParamBeg + aParamEnd) * 0.5, aCircle);
331}
332
333//=======================================================================
334//function : DrawArc
335//purpose : draws the arc between two attach points
336//=======================================================================
337void AIS_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentation,
338 const gp_Pnt& theFirstAttach,
339 const gp_Pnt& theSecondAttach,
340 const gp_Pnt& theCenter,
341 const Standard_Real theRadius,
342 const Standard_Integer theMode)
343{
344 // construct plane where the circle and the arc are located
345 gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
346 if (!aConstructPlane.IsDone())
a6eb515f 347 {
60bf98ae 348 return;
7fd59977 349 }
60bf98ae 350
351 gp_Pln aPlane = aConstructPlane.Value();
352
353 // construct circle forming the arc
354 gce_MakeCirc aConstructCircle (theCenter, aPlane, theRadius);
355 if (!aConstructCircle.IsDone())
a6eb515f 356 {
60bf98ae 357 return;
7fd59977 358 }
359
60bf98ae 360 gp_Circ aCircle = aConstructCircle.Value();
361
362 // construct the arc
363 GC_MakeArcOfCircle aConstructArc (aCircle, theFirstAttach, theSecondAttach, Standard_True);
364 if (!aConstructArc.IsDone())
a6eb515f 365 {
60bf98ae 366 return;
7fd59977 367 }
368
60bf98ae 369 // generate points with specified deflection
370 const Handle(Geom_TrimmedCurve)& anArcCurve = aConstructArc.Value();
371
372 GeomAdaptor_Curve anArcAdaptor (anArcCurve, anArcCurve->FirstParameter(), anArcCurve->LastParameter());
7fd59977 373
60bf98ae 374 // compute number of discretization elements in old-fanshioned way
375 gp_Vec aCenterToFirstVec (theCenter, theFirstAttach);
376 gp_Vec aCenterToSecondVec (theCenter, theSecondAttach);
377 const Standard_Real anAngle = aCenterToFirstVec.Angle (aCenterToSecondVec);
378 const Standard_Integer aNbPoints = Max (4, Standard_Integer (50.0 * anAngle / M_PI));
a6eb515f 379
60bf98ae 380 GCPnts_UniformAbscissa aMakePnts (anArcAdaptor, aNbPoints);
381 if (!aMakePnts.IsDone())
382 {
383 return;
7fd59977 384 }
385
60bf98ae 386 // init data arrays for graphical and selection primitives
387 Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aNbPoints);
7fd59977 388
60bf98ae 389 SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
a6eb515f 390
60bf98ae 391 // load data into arrays
392 for (Standard_Integer aPntIt = 1; aPntIt <= aMakePnts.NbPoints(); ++aPntIt)
a6eb515f 393 {
60bf98ae 394 gp_Pnt aPnt = anArcAdaptor.Value (aMakePnts.Parameter (aPntIt));
7fd59977 395
60bf98ae 396 aPrimSegments->AddVertex (aPnt);
7fd59977 397
60bf98ae 398 aSensitiveCurve.Append (aPnt);
a6eb515f 399 }
7fd59977 400
60bf98ae 401 // add display presentation
402 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
403 {
404 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
405 }
406 Handle(Graphic3d_AspectLine3d) aDimensionLineStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
407 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionLineStyle);
408 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
409 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
410 {
411 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
412 }
7fd59977 413}
a6eb515f 414
7fd59977 415//=======================================================================
60bf98ae 416//function: DrawArcWithText
a6eb515f 417//purpose :
7fd59977 418//=======================================================================
60bf98ae 419void AIS_AngleDimension::DrawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
a6eb515f 420 const gp_Pnt& theFirstAttach,
421 const gp_Pnt& theSecondAttach,
60bf98ae 422 const gp_Pnt& theCenter,
a6eb515f 423 const TCollection_ExtendedString& theText,
fe83e1ea 424 const Standard_Real theTextWidth,
425 const Standard_Integer theMode,
d7bffd44 426 const Standard_Integer theLabelPosition)
7fd59977 427{
fe83e1ea 428 // construct plane where the circle and the arc are located
60bf98ae 429 gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
fe83e1ea 430 if (!aConstructPlane.IsDone())
431 {
432 return;
433 }
60bf98ae 434
fe83e1ea 435 gp_Pln aPlane = aConstructPlane.Value();
a6eb515f 436
60bf98ae 437 Standard_Real aRadius = theFirstAttach.Distance (myCenterPoint);
a6eb515f 438
fe83e1ea 439 // construct circle forming the arc
60bf98ae 440 gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
fe83e1ea 441 if (!aConstructCircle.IsDone())
442 {
443 return;
444 }
a6eb515f 445
fe83e1ea 446 gp_Circ aCircle = aConstructCircle.Value();
a6eb515f 447
fe83e1ea 448 // compute angle parameters of arc end-points on circle
449 Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
450 Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
60bf98ae 451 ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
a6eb515f 452
fe83e1ea 453 // middle point of arc parameter on circle
454 Standard_Real aParamMid = (aParamBeg + aParamEnd) * 0.5;
a6eb515f 455
fe83e1ea 456 // add text graphical primitives
457 if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
458 {
459 gp_Pnt aTextPos = ElCLib::Value (aParamMid, aCircle);
60bf98ae 460 gp_Dir aTextDir = gce_MakeDir (theFirstAttach, theSecondAttach);
fe83e1ea 461
462 // Drawing text
60bf98ae 463 DrawText (thePresentation,
fe83e1ea 464 aTextPos,
465 aTextDir,
466 theText,
467 theLabelPosition);
468 }
a6eb515f 469
fe83e1ea 470 if (theMode != ComputeMode_All && theMode != ComputeMode_Line)
471 {
472 return;
473 }
a6eb515f 474
fe83e1ea 475 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
a6eb515f 476
fe83e1ea 477 Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
478 && aDimensionAspect->IsText3d();
a6eb515f 479
fe83e1ea 480 if (isLineBreak)
a6eb515f 481 {
fe83e1ea 482 // compute gap for label as parameteric size of sector on circle segment
483 Standard_Real aSectorOnCircle = theTextWidth / aRadius;
484
485 gp_Pnt aTextPntBeg = ElCLib::Value (aParamMid - aSectorOnCircle * 0.5, aCircle);
486 gp_Pnt aTextPntEnd = ElCLib::Value (aParamMid + aSectorOnCircle * 0.5, aCircle);
487
488 // Drawing arcs
60bf98ae 489 DrawArc (thePresentation, theFirstAttach, aTextPntBeg, theCenter, aRadius, theMode);
490 DrawArc (thePresentation, theSecondAttach, aTextPntEnd, theCenter, aRadius, theMode);
fe83e1ea 491 }
492 else
493 {
60bf98ae 494 DrawArc (thePresentation, theFirstAttach, theSecondAttach, theCenter, aRadius, theMode);
7fd59977 495 }
a6eb515f 496}
7fd59977 497
a6eb515f 498//=======================================================================
60bf98ae 499//function : CheckPlane
500//purpose :
a6eb515f 501//=======================================================================
60bf98ae 502Standard_Boolean AIS_AngleDimension::CheckPlane (const gp_Pln& thePlane)const
a6eb515f 503{
60bf98ae 504 if (!thePlane.Contains (myFirstPoint, Precision::Confusion()) &&
505 !thePlane.Contains (mySecondPoint, Precision::Confusion()) &&
506 !thePlane.Contains (myCenterPoint, Precision::Confusion()))
fe83e1ea 507 {
60bf98ae 508 return Standard_False;
fe83e1ea 509 }
510
60bf98ae 511 return Standard_True;
512}
a6eb515f 513
60bf98ae 514//=======================================================================
515//function : ComputePlane
516//purpose :
517//=======================================================================
518void AIS_AngleDimension::ComputePlane()
519{
520 if (!IsValid())
a6eb515f 521 {
fe83e1ea 522 return;
7fd59977 523 }
7fd59977 524
60bf98ae 525 gp_Vec aFirstVec = gp_Vec (myCenterPoint, myFirstPoint).Normalized();
526 gp_Vec aSecondVec = gp_Vec (myCenterPoint, mySecondPoint).Normalized();
527 gp_Vec aDirectionN = aSecondVec.Crossed (aFirstVec).Normalized();
528 gp_Vec aDirectionY = (aFirstVec + aSecondVec).Normalized();
529 gp_Vec aDirectionX = aDirectionY.Crossed (aDirectionN).Normalized();
fe83e1ea 530
60bf98ae 531 myPlane = gp_Pln (gp_Ax3 (myCenterPoint, gp_Dir (aDirectionN), gp_Dir (aDirectionX)));
532}
7fd59977 533
60bf98ae 534//=======================================================================
535//function : GetModelUnits
536//purpose :
537//=======================================================================
538const TCollection_AsciiString& AIS_AngleDimension::GetModelUnits() const
539{
540 return myDrawer->DimAngleModelUnits();
541}
fe83e1ea 542
60bf98ae 543//=======================================================================
544//function : GetDisplayUnits
545//purpose :
546//=======================================================================
547const TCollection_AsciiString& AIS_AngleDimension::GetDisplayUnits() const
548{
549 return myDrawer->DimAngleDisplayUnits();
550}
fe83e1ea 551
60bf98ae 552//=======================================================================
553//function : SetModelUnits
554//purpose :
555//=======================================================================
556void AIS_AngleDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
557{
558 myDrawer->SetDimAngleModelUnits (theUnits);
559}
fe83e1ea 560
60bf98ae 561//=======================================================================
562//function : SetDisplayUnits
563//purpose :
564//=======================================================================
565void AIS_AngleDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
566{
567 myDrawer->SetDimAngleDisplayUnits (theUnits);
568}
569
570//=======================================================================
571//function : ComputeValue
572//purpose :
573//=======================================================================
574Standard_Real AIS_AngleDimension::ComputeValue() const
575{
576 if (!IsValid())
a6eb515f 577 {
60bf98ae 578 return 0.0;
7fd59977 579 }
60bf98ae 580
581 gp_Vec aVec1 (myCenterPoint, myFirstPoint);
582 gp_Vec aVec2 (myCenterPoint, mySecondPoint);
583
584 Standard_Real anAngle = aVec2.AngleWithRef (aVec1, GetPlane().Axis().Direction());
585
586 return anAngle > 0.0 ? anAngle : (2.0 * M_PI - anAngle);
7fd59977 587}
588
7fd59977 589//=======================================================================
a6eb515f 590//function : Compute
591//purpose : Having three gp_Pnt points compute presentation
7fd59977 592//=======================================================================
a6eb515f 593void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
594 const Handle(Prs3d_Presentation)& thePresentation,
595 const Standard_Integer theMode)
596{
597 thePresentation->Clear();
fe83e1ea 598 mySelectionGeom.Clear (theMode);
7fd59977 599
60bf98ae 600 if (!IsValid())
a6eb515f 601 {
a6eb515f 602 return;
60bf98ae 603 }
7fd59977 604
a6eb515f 605 // Parameters for presentation
606 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
d7bffd44 607
60bf98ae 608 Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
d7bffd44 609
a6eb515f 610 Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
d7bffd44 611
60bf98ae 612 // prepare label string and compute its geometrical width
613 Standard_Real aLabelWidth;
614 TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
d7bffd44 615
fe83e1ea 616 // add margins to label width
617 if (aDimensionAspect->IsText3d())
618 {
60bf98ae 619 aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
d7bffd44 620 }
621
60bf98ae 622 gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
623 gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
7fd59977 624
d7bffd44 625 // Handle user-defined and automatic arrow placement
626 bool isArrowsExternal = false;
627 switch (aDimensionAspect->ArrowOrientation())
628 {
629 case Prs3d_DAO_External: isArrowsExternal = true; break;
630 case Prs3d_DAO_Internal: isArrowsExternal = false; break;
631 case Prs3d_DAO_Fit:
a6eb515f 632 {
d7bffd44 633 gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
634 Standard_Real aDimensionWidth = anAttachVector.Magnitude();
fe83e1ea 635
636 // add margin to ensure a small tail between text and arrow
637 Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
638 ? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
639 : 0.0;
640
641 Standard_Real anArrowsWidth = (anArrowLength + anArrowMargin) * 2.0;
d7bffd44 642
60bf98ae 643 isArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
d7bffd44 644 break;
a6eb515f 645 }
7fd59977 646 }
7fd59977 647
a6eb515f 648 //Arrows positions and directions
60bf98ae 649 gp_Vec aWPDir = gp_Vec (GetPlane().Axis().Direction());
d7bffd44 650
60bf98ae 651 gp_Dir aFirstExtensionDir = aWPDir ^ gp_Vec (myCenterPoint, aFirstAttach);
652 gp_Dir aSecondExtensionDir = aWPDir.Reversed() ^ gp_Vec (myCenterPoint, aSecondAttach);
7fd59977 653
d7bffd44 654 gp_Vec aFirstArrowVec = gp_Vec (aFirstExtensionDir) * anArrowLength;
655 gp_Vec aSecondArrowVec = gp_Vec (aSecondExtensionDir) * anArrowLength;
7fd59977 656
d7bffd44 657 gp_Pnt aFirstArrowBegin (0.0, 0.0, 0.0);
658 gp_Pnt aFirstArrowEnd (0.0, 0.0, 0.0);
659 gp_Pnt aSecondArrowBegin (0.0, 0.0, 0.0);
660 gp_Pnt aSecondArrowEnd (0.0, 0.0, 0.0);
661
662 if (isArrowsExternal)
a6eb515f 663 {
664 aFirstArrowVec.Reverse();
665 aSecondArrowVec.Reverse();
d7bffd44 666 }
667
668 aFirstArrowBegin = aFirstAttach;
669 aSecondArrowBegin = aSecondAttach;
670 aFirstArrowEnd = aFirstAttach.Translated (-aFirstArrowVec);
671 aSecondArrowEnd = aSecondAttach.Translated (-aSecondArrowVec);
672
673 Standard_Integer aLabelPosition = LabelPosition_None;
674
675 // Handle user-defined and automatic text placement
676 switch (aDimensionAspect->TextHorizontalPosition())
677 {
678 case Prs3d_DTHP_Left : aLabelPosition |= LabelPosition_Left; break;
679 case Prs3d_DTHP_Right : aLabelPosition |= LabelPosition_Right; break;
680 case Prs3d_DTHP_Center: aLabelPosition |= LabelPosition_HCenter; break;
681 case Prs3d_DTHP_Fit:
682 {
683 gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
684 Standard_Real aDimensionWidth = anAttachVector.Magnitude();
685 Standard_Real anArrowsWidth = anArrowLength * 2.0;
60bf98ae 686 Standard_Real aContentWidth = isArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
7fd59977 687
d7bffd44 688 aLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
689 break;
690 }
7fd59977 691 }
d7bffd44 692
693 switch (aDimensionAspect->TextVerticalPosition())
a6eb515f 694 {
d7bffd44 695 case Prs3d_DTVP_Above : aLabelPosition |= LabelPosition_Above; break;
696 case Prs3d_DTVP_Below : aLabelPosition |= LabelPosition_Below; break;
697 case Prs3d_DTVP_Center : aLabelPosition |= LabelPosition_VCenter; break;
7fd59977 698 }
b8ddfc2f 699
d7bffd44 700 // Group1: stenciling text and the angle dimension arc
701 Prs3d_Root::NewGroup (thePresentation);
702
703 Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
704
705 Standard_Integer aHPosition = aLabelPosition & LabelPosition_HMask;
706
707 // draw text label
708 switch (aHPosition)
b8ddfc2f 709 {
d7bffd44 710 case LabelPosition_HCenter :
a6eb515f 711 {
d7bffd44 712 Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
713 && aDimensionAspect->IsText3d();
714
715 if (isLineBreak)
716 {
60bf98ae 717 DrawArcWithText (thePresentation,
d7bffd44 718 aFirstAttach,
719 aSecondAttach,
60bf98ae 720 myCenterPoint,
721 aLabelString,
722 aLabelWidth,
fe83e1ea 723 theMode,
d7bffd44 724 aLabelPosition);
725 break;
726 }
727
fe83e1ea 728 // compute text primitives
729 if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
d7bffd44 730 {
60bf98ae 731 gp_Vec aDimensionDir (aFirstAttach, aSecondAttach);
732 gp_Pnt aTextPos = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
733 gp_Dir aTextDir = aDimensionDir;
fe83e1ea 734
60bf98ae 735 DrawText (thePresentation,
fe83e1ea 736 aTextPos,
737 aTextDir,
60bf98ae 738 aLabelString,
fe83e1ea 739 aLabelPosition);
d7bffd44 740 }
741
fe83e1ea 742 if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
743 {
60bf98ae 744 DrawArc (thePresentation,
fe83e1ea 745 isArrowsExternal ? aFirstAttach : aFirstArrowEnd,
746 isArrowsExternal ? aSecondAttach : aSecondArrowEnd,
60bf98ae 747 myCenterPoint,
fe83e1ea 748 Abs (GetFlyout()),
749 theMode);
750 }
a6eb515f 751 }
d7bffd44 752 break;
753
754 case LabelPosition_Left :
a6eb515f 755 {
60bf98ae 756 DrawExtension (thePresentation,
d7bffd44 757 anExtensionSize,
758 isArrowsExternal ? aFirstArrowEnd : aFirstAttach,
759 aFirstExtensionDir,
60bf98ae 760 aLabelString,
761 aLabelWidth,
fe83e1ea 762 theMode,
d7bffd44 763 aLabelPosition);
a6eb515f 764 }
d7bffd44 765 break;
766
767 case LabelPosition_Right :
a6eb515f 768 {
60bf98ae 769 DrawExtension (thePresentation,
d7bffd44 770 anExtensionSize,
771 isArrowsExternal ? aSecondArrowEnd : aSecondAttach,
772 aSecondExtensionDir,
60bf98ae 773 aLabelString,
774 aLabelWidth,
fe83e1ea 775 theMode,
d7bffd44 776 aLabelPosition);
a6eb515f 777 }
d7bffd44 778 break;
779 }
780
781 // dimension arc without text
fe83e1ea 782 if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && aHPosition != LabelPosition_HCenter)
d7bffd44 783 {
784 Prs3d_Root::NewGroup (thePresentation);
785
60bf98ae 786 DrawArc (thePresentation,
d7bffd44 787 isArrowsExternal ? aFirstAttach : aFirstArrowEnd,
788 isArrowsExternal ? aSecondAttach : aSecondArrowEnd,
60bf98ae 789 myCenterPoint,
d7bffd44 790 Abs(GetFlyout ()),
fe83e1ea 791 theMode);
d7bffd44 792 }
7fd59977 793
d7bffd44 794 // arrows and arrow extensions
fe83e1ea 795 if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
d7bffd44 796 {
797 Prs3d_Root::NewGroup (thePresentation);
798
60bf98ae 799 DrawArrow (thePresentation, aFirstArrowBegin, gp_Dir (aFirstArrowVec));
800 DrawArrow (thePresentation, aSecondArrowBegin, gp_Dir (aSecondArrowVec));
d7bffd44 801 }
802
fe83e1ea 803 if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && isArrowsExternal)
d7bffd44 804 {
805 Prs3d_Root::NewGroup (thePresentation);
806
807 if (aHPosition != LabelPosition_Left)
808 {
60bf98ae 809 DrawExtension (thePresentation,
d7bffd44 810 anExtensionSize,
811 aFirstArrowEnd,
812 aFirstExtensionDir,
fe83e1ea 813 THE_EMPTY_LABEL_STRING,
814 THE_EMPTY_LABEL_WIDTH,
815 theMode,
d7bffd44 816 LabelPosition_None);
817 }
818
819 if (aHPosition != LabelPosition_Right)
a6eb515f 820 {
60bf98ae 821 DrawExtension (thePresentation,
d7bffd44 822 anExtensionSize,
823 aSecondArrowEnd,
824 aSecondExtensionDir,
fe83e1ea 825 THE_EMPTY_LABEL_STRING,
826 THE_EMPTY_LABEL_WIDTH,
827 theMode,
d7bffd44 828 LabelPosition_None);
a6eb515f 829 }
830 }
7fd59977 831
d7bffd44 832 // flyouts
60bf98ae 833 if (theMode == ComputeMode_All)
a6eb515f 834 {
d7bffd44 835 Prs3d_Root::NewGroup (thePresentation);
836
837 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (4);
60bf98ae 838 aPrimSegments->AddVertex (myCenterPoint);
a6eb515f 839 aPrimSegments->AddVertex (aFirstAttach);
60bf98ae 840 aPrimSegments->AddVertex (myCenterPoint);
a6eb515f 841 aPrimSegments->AddVertex (aSecondAttach);
d7bffd44 842
843 Handle(Graphic3d_AspectLine3d) aFlyoutStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
844 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aFlyoutStyle);
a6eb515f 845 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
7fd59977 846 }
847
60bf98ae 848 myIsComputed = Standard_True;
7fd59977 849}
62b6361a 850
851//=======================================================================
60bf98ae 852//function : ComputeFlyoutSelection
62b6361a 853//purpose : computes selection for flyouts
854//=======================================================================
60bf98ae 855void AIS_AngleDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
fe83e1ea 856 const Handle(SelectMgr_EntityOwner)& theOwner)
62b6361a 857{
60bf98ae 858 gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
859 gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
860
861 Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner);
862 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aFirstAttach));
863 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aSecondAttach));
864
865 theSelection->Add (aSensitiveEntity);
866}
867
868//=======================================================================
869//function : InitTwoEdgesAngle
870//purpose :
871//=======================================================================
872Standard_Boolean AIS_AngleDimension::InitTwoEdgesAngle (gp_Pln& theComputedPlane)
873{
874 TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape);
875 TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape);
876
877 BRepAdaptor_Curve aMakeFirstLine (aFirstEdge);
878 BRepAdaptor_Curve aMakeSecondLine (aSecondEdge);
879
880 if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line)
fe83e1ea 881 {
60bf98ae 882 return Standard_False;
fe83e1ea 883 }
884
60bf98ae 885 Handle(Geom_Line) aFirstLine = new Geom_Line (aMakeFirstLine.Line());
886 Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line());
fe83e1ea 887
60bf98ae 888 gp_Lin aFirstLin = aFirstLine->Lin();
889 gp_Lin aSecondLin = aSecondLine->Lin();
fe83e1ea 890
60bf98ae 891 Standard_Boolean isParallelLines = Abs (aFirstLin.Angle (aSecondLin) - M_PI) <= Precision::Angular();
892
893 gp_Pnt aPoint = aFirstLine->Value (0.0);
894 gp_Dir aNormal = isParallelLines
895 ? gp_Vec (aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction())
896 : gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction());
897
898 theComputedPlane = gp_Pln (aPoint, aNormal);
899
900 // Compute geometry for this plane and edges
901 Standard_Boolean isInfinite1,isInfinite2;
902 gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2;
903 gp_Lin2d aFirstLin2d, aSecondLin2d;
904
905 if (!AIS::ComputeGeometry (aFirstEdge, aSecondEdge,
906 aFirstLine, aSecondLine,
907 aFirstPoint1, aLastPoint1,
908 aFirstPoint2, aLastPoint2,
909 isInfinite1, isInfinite2))
910 {
911 return Standard_False;
912 }
913
914 if (aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular()))
915 {
916 myFirstPoint = aFirstLin.Location();
917 mySecondPoint = ElCLib::Value (ElCLib::Parameter (aFirstLin, myFirstPoint), aSecondLin);
918
919 if (mySecondPoint.Distance (myFirstPoint) <= Precision::Confusion())
920 {
921 mySecondPoint.Translate (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout()));
922 }
923
924 myCenterPoint.SetXYZ ((myFirstPoint.XYZ() + mySecondPoint.XYZ()) / 2.0);
925 }
926 else
927 {
928 // Find intersection
929 gp_Lin2d aFirstLin2d = ProjLib::Project (theComputedPlane, aFirstLin);
930 gp_Lin2d aSecondLin2d = ProjLib::Project (theComputedPlane, aSecondLin);
931
932 IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d);
933 gp_Pnt2d anIntersectPoint;
934 if (!anInt2d.IsDone() || anInt2d.IsEmpty())
935 {
936 return Standard_False;
937 }
938
939 anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value());
940 myCenterPoint = ElCLib::To3d (theComputedPlane.Position().Ax2(), anIntersectPoint);
941
942 if (isInfinite1 || isInfinite2)
943 {
944 myFirstPoint = myCenterPoint.Translated (gp_Vec (aFirstLin.Direction()) * Abs (GetFlyout()));
945 mySecondPoint = myCenterPoint.Translated (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout()));
946
947 return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
948 }
949
950 // |
951 // | <- dimension should be here
952 // *----
953 myFirstPoint = myCenterPoint.Distance (aFirstPoint1) > myCenterPoint.Distance (aLastPoint1)
954 ? aFirstPoint1
955 : aLastPoint1;
956
957 mySecondPoint = myCenterPoint.Distance (aFirstPoint2) > myCenterPoint.Distance (aLastPoint2)
958 ? aFirstPoint2
959 : aLastPoint2;
960 }
961
962 return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
963}
964
965//=======================================================================
966//function : InitTwoFacesAngle
967//purpose : initialization of angle dimension between two faces
968//=======================================================================
969Standard_Boolean AIS_AngleDimension::InitTwoFacesAngle()
970{
971 TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
972 TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
973
974 gp_Dir aFirstDir, aSecondDir;
975 gp_Pln aFirstPlane, aSecondPlane;
976 Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
977 AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
978 Standard_Real aFirstOffset, aSecondOffset;
979
980 AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
981 aFirstBasisSurf,aFirstSurfType,aFirstOffset);
982
983 AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
984 aSecondBasisSurf, aSecondSurfType, aSecondOffset);
985
986 if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane)
987 {
988 //Planar faces angle
989 Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
990 Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
991 return AIS::InitAngleBetweenPlanarFaces (aFirstFace,
992 aSecondFace,
993 myCenterPoint,
994 myFirstPoint,
995 mySecondPoint)
996 && IsValidPoints (myFirstPoint,
997 myCenterPoint,
998 mySecondPoint);
999 }
1000 else
1001 {
1002 // Curvilinear faces angle
1003 return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace,
1004 aSecondFace,
1005 aFirstSurfType,
1006 aSecondSurfType,
1007 myCenterPoint,
1008 myFirstPoint,
1009 mySecondPoint)
1010 && IsValidPoints (myFirstPoint,
1011 myCenterPoint,
1012 mySecondPoint);
1013 }
1014}
1015
1016//=======================================================================
1017//function : InitTwoFacesAngle
1018//purpose : initialization of angle dimension between two faces
1019//=======================================================================
1020Standard_Boolean AIS_AngleDimension::InitTwoFacesAngle (const gp_Pnt thePointOnFirstFace)
1021{
1022 TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
1023 TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
1024
1025 gp_Dir aFirstDir, aSecondDir;
1026 gp_Pln aFirstPlane, aSecondPlane;
1027 Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
1028 AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
1029 Standard_Real aFirstOffset, aSecondOffset;
1030
1031 AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
1032 aFirstBasisSurf,aFirstSurfType,aFirstOffset);
1033
1034 AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
1035 aSecondBasisSurf, aSecondSurfType, aSecondOffset);
1036
1037 myFirstPoint = thePointOnFirstFace;
1038 if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane)
1039 {
1040 //Planar faces angle
1041 Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
1042 Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
1043 return AIS::InitAngleBetweenPlanarFaces (aFirstFace,
1044 aSecondFace,
1045 myCenterPoint,
1046 myFirstPoint,
1047 mySecondPoint,
1048 Standard_True)
1049 && IsValidPoints (myFirstPoint,
1050 myCenterPoint,
1051 mySecondPoint);
1052 }
1053 else
1054 {
1055 // Curvilinear faces angle
1056 return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace,
1057 aSecondFace,
1058 aFirstSurfType,
1059 aSecondSurfType,
1060 myCenterPoint,
1061 myFirstPoint,
1062 mySecondPoint,
1063 Standard_True)
1064 && IsValidPoints (myFirstPoint,
1065 myCenterPoint,
1066 mySecondPoint);
1067 }
1068}
1069
1070//=======================================================================
1071//function : InitConeAngle
1072//purpose : initialization of the cone angle
1073//=======================================================================
1074Standard_Boolean AIS_AngleDimension::InitConeAngle()
1075{
1076 if (myFirstShape.IsNull())
1077 {
1078 return Standard_False;
1079 }
1080
1081 TopoDS_Face aConeShape = TopoDS::Face (myFirstShape);
1082 gp_Pln aPln;
1083 gp_Cone aCone;
1084 gp_Circ aCircle;
1085 // A surface from the Face
1086 Handle(Geom_Surface) aSurf;
1087 Handle(Geom_OffsetSurface) aOffsetSurf;
1088 Handle(Geom_ConicalSurface) aConicalSurf;
1089 Handle(Geom_SurfaceOfRevolution) aRevSurf;
1090 Handle(Geom_Line) aLine;
1091 BRepAdaptor_Surface aConeAdaptor (aConeShape);
1092 TopoDS_Face aFace;
1093 AIS_KindOfSurface aSurfType;
1094 Standard_Real anOffset = 0.;
1095 Handle(Standard_Type) aType;
1096
1097 Standard_Real aMaxV = aConeAdaptor.FirstVParameter();
1098 Standard_Real aMinV = aConeAdaptor.LastVParameter();
1099
1100 AIS::GetPlaneFromFace (aConeShape, aPln, aSurf, aSurfType, anOffset);
1101
1102 if (aSurfType == AIS_KOS_Revolution)
1103 {
1104 // Surface of revolution
1105 aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf);
1106 gp_Lin aLin (aRevSurf->Axis());
1107 Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve();
1108 //Must be a part of line (basis curve should be linear)
1109 if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line))
1110 return Standard_False;
1111
1112 gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV);
1113 gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV);
1114 gp_Vec aVec1 (aFirst1, aLast1);
1115
1116 //Projection <aFirst> on <aLin>
1117 gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin);
1118 // Projection <aLast> on <aLin>
1119 gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin);
1120
1121 gp_Vec aVec2 (aFirst2, aLast2);
1122
1123 // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle).
1124 if (aVec1.IsParallel (aVec2, Precision::Angular())
1125 || aVec1.IsNormal (aVec2,Precision::Angular()))
1126 return Standard_False;
1127
1128 gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1);
1129 aCone = aMkCone.Value();
1130 myCenterPoint = aCone.Apex();
1131 }
1132 else
1133 {
1134 aType = aSurf->DynamicType();
1135 if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01)
1136 {
1137 // Offset surface
1138 aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset);
1139 aSurf = aOffsetSurf->Surface();
1140 BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion());
1141 aMkFace.Build();
1142 if (!aMkFace.IsDone())
1143 return Standard_False;
1144 aConeAdaptor.Initialize (aMkFace.Face());
1145 }
1146 aCone = aConeAdaptor.Cone();
1147 aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf);
1148 myCenterPoint = aConicalSurf->Apex();
1149 }
1150
1151 // A circle where the angle is drawn
1152 Handle(Geom_Curve) aCurve;
1153 Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5;
1154 aCurve = aSurf->VIso (aMidV);
1155 aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
1156
1157 aCurve = aSurf->VIso(aMaxV);
1158 gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1159 aCurve = aSurf->VIso(aMinV);
1160 gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1161
1162 if (aCircVmax.Radius() < aCircVmin.Radius())
1163 {
1164 gp_Circ aTmpCirc = aCircVmax;
1165 aCircVmax = aCircVmin;
1166 aCircVmin = aTmpCirc;
1167 }
1168
1169 myFirstPoint = ElCLib::Value (0, aCircle);
1170 mySecondPoint = ElCLib::Value (M_PI, aCircle);
1171 return Standard_True;
1172}
1173
1174//=======================================================================
1175//function : IsValidPoints
1176//purpose :
1177//=======================================================================
1178Standard_Boolean AIS_AngleDimension::IsValidPoints (const gp_Pnt& theFirstPoint,
1179 const gp_Pnt& theCenterPoint,
1180 const gp_Pnt& theSecondPoint) const
1181{
1182 return theFirstPoint.Distance (theCenterPoint) > Precision::Confusion()
1183 && theSecondPoint.Distance (theCenterPoint) > Precision::Confusion()
1184 && gp_Vec (theCenterPoint, theFirstPoint).Angle (
1185 gp_Vec (theCenterPoint, theSecondPoint)) > Precision::Angular();
d7bffd44 1186}