+++ /dev/null
-// Created on: 1996-12-05
-// Created by: Arnaud BOUZY/Odile Olivier
-// Copyright (c) 1996-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <AIS_AngleDimension.hxx>
-
-#include <AIS.hxx>
-#include <BRepBuilderAPI_MakeFace.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepLib_MakeVertex.hxx>
-#include <BRep_Tool.hxx>
-#include <ElCLib.hxx>
-#include <GCPnts_UniformAbscissa.hxx>
-#include <GC_MakeArcOfCircle.hxx>
-#include <gce_MakeLin2d.hxx>
-#include <gce_MakeLin.hxx>
-#include <gce_MakeCirc.hxx>
-#include <gce_MakeCone.hxx>
-#include <gce_MakePln.hxx>
-#include <gce_MakeDir.hxx>
-#include <Geom_Circle.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom_ConicalSurface.hxx>
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <Geom_OffsetSurface.hxx>
-#include <Graphic3d_ArrayOfSegments.hxx>
-#include <Graphic3d_Group.hxx>
-#include <Graphic3d_ArrayOfPolylines.hxx>
-#include <IntAna2d_AnaIntersection.hxx>
-#include <ProjLib.hxx>
-#include <Prs3d_Root.hxx>
-#include <Prs3d_ShadingAspect.hxx>
-#include <PrsMgr_PresentationManager3d.hxx>
-#include <Select3D_SensitiveGroup.hxx>
-#include <Select3D_SensitiveSegment.hxx>
-#include <SelectMgr_Selection.hxx>
-#include <Standard_ProgramError.hxx>
-#include <UnitsAPI.hxx>
-
-IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension)
-IMPLEMENT_STANDARD_RTTIEXT (AIS_AngleDimension, AIS_Dimension)
-
-namespace
-{
- static const TCollection_ExtendedString THE_EMPTY_LABEL_STRING;
- static const Standard_Real THE_EMPTY_LABEL_WIDTH = 0.0;
- static const Standard_ExtCharacter THE_DEGREE_SYMBOL (0x00B0);
- static const Standard_Real THE_3D_TEXT_MARGIN = 0.1;
-};
-
-//=======================================================================
-//function : Constructor
-//purpose :
-//=======================================================================
-AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
- const TopoDS_Edge& theSecondEdge)
-: AIS_Dimension (AIS_KOD_PLANEANGLE)
-{
- Init();
- SetMeasuredGeometry (theFirstEdge, theSecondEdge);
-}
-
-//=======================================================================
-//function : Constructor
-//purpose :
-//=======================================================================
-AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint,
- const gp_Pnt& theSecondPoint,
- const gp_Pnt& theThirdPoint)
-: AIS_Dimension (AIS_KOD_PLANEANGLE)
-{
- Init();
- SetMeasuredGeometry (theFirstPoint, theSecondPoint, theThirdPoint);
-}
-
-//=======================================================================
-//function : Constructor
-//purpose :
-//=======================================================================
-AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Vertex& theFirstVertex,
- const TopoDS_Vertex& theSecondVertex,
- const TopoDS_Vertex& theThirdVertex)
-: AIS_Dimension (AIS_KOD_PLANEANGLE)
-{
- Init();
- SetMeasuredGeometry (theFirstVertex, theSecondVertex, theThirdVertex);
-}
-
-//=======================================================================
-//function : Constructor
-//purpose :
-//=======================================================================
-AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theCone)
-: AIS_Dimension (AIS_KOD_PLANEANGLE)
-{
- Init();
- SetMeasuredGeometry (theCone);
-}
-
-//=======================================================================
-//function : Constructor
-//purpose :
-//=======================================================================
-AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace)
-: AIS_Dimension (AIS_KOD_PLANEANGLE)
-{
- Init();
- SetMeasuredGeometry (theFirstFace, theSecondFace);
-}
-
-//=======================================================================
-//function : Constructor
-//purpose :
-//=======================================================================
-AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace,
- const gp_Pnt& thePoint)
-: AIS_Dimension (AIS_KOD_PLANEANGLE)
-{
- Init();
- SetMeasuredGeometry (theFirstFace, theSecondFace, thePoint);
-}
-
-//=======================================================================
-//function : SetMeasuredGeometry
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Edge& theFirstEdge,
- const TopoDS_Edge& theSecondEdge)
-{
- gp_Pln aComputedPlane;
-
- myFirstShape = theFirstEdge;
- mySecondShape = theSecondEdge;
- myThirdShape = TopoDS_Shape();
- myGeometryType = GeometryType_Edges;
- myIsGeometryValid = InitTwoEdgesAngle (aComputedPlane);
-
- if (myIsGeometryValid && !myIsPlaneCustom)
- {
- ComputePlane();
- }
-
- SetToUpdate();
-}
-
-//=======================================================================
-//function : SetMeasuredGeometry
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
- const gp_Pnt& theSecondPoint,
- const gp_Pnt& theThirdPoint)
-{
- myFirstPoint = theFirstPoint;
- myCenterPoint = theSecondPoint;
- mySecondPoint = theThirdPoint;
- myFirstShape = BRepLib_MakeVertex (myFirstPoint);
- mySecondShape = BRepLib_MakeVertex (myCenterPoint);
- myThirdShape = BRepLib_MakeVertex (mySecondPoint);
- myGeometryType = GeometryType_Points;
- myIsGeometryValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
-
- if (myIsGeometryValid && !myIsPlaneCustom)
- {
- ComputePlane();
- }
-
- SetToUpdate();
-}
-
-//=======================================================================
-//function : SetMeasuredGeometry
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Vertex& theFirstVertex,
- const TopoDS_Vertex& theSecondVertex,
- const TopoDS_Vertex& theThirdVertex)
-{
- myFirstShape = theFirstVertex;
- mySecondShape = theSecondVertex;
- myThirdShape = theThirdVertex;
- myFirstPoint = BRep_Tool::Pnt (theFirstVertex);
- myCenterPoint = BRep_Tool::Pnt (theSecondVertex);
- mySecondPoint = BRep_Tool::Pnt (theThirdVertex);
- myGeometryType = GeometryType_Points;
- myIsGeometryValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
-
- if (myIsGeometryValid && !myIsPlaneCustom)
- {
- ComputePlane();
- }
-
- SetToUpdate();
-}
-
-//=======================================================================
-//function : SetMeasuredGeometry
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theCone)
-{
- myFirstShape = theCone;
- mySecondShape = TopoDS_Shape();
- myThirdShape = TopoDS_Shape();
- myGeometryType = GeometryType_Face;
- myIsGeometryValid = InitConeAngle();
-
- if (myIsGeometryValid && !myIsPlaneCustom)
- {
- ComputePlane();
- }
-
- SetToUpdate();
-}
-
-//=======================================================================
-//function : SetMeasuredGeometry
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace)
-{
- myFirstShape = theFirstFace;
- mySecondShape = theSecondFace;
- myThirdShape = TopoDS_Shape();
- myGeometryType = GeometryType_Faces;
- myIsGeometryValid = InitTwoFacesAngle();
-
- if (myIsGeometryValid && !myIsPlaneCustom)
- {
- ComputePlane();
- }
-
- SetToUpdate();
-}
-
-//=======================================================================
-//function : SetMeasuredGeometry
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace,
- const gp_Pnt& thePoint)
-{
- myFirstShape = theFirstFace;
- mySecondShape = theSecondFace;
- myThirdShape = TopoDS_Shape();
- myGeometryType = GeometryType_Faces;
- myIsGeometryValid = InitTwoFacesAngle (thePoint);
-
- if (myIsGeometryValid && !myIsPlaneCustom)
- {
- ComputePlane();
- }
-
- SetToUpdate();
-}
-
-//=======================================================================
-//function : Init
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::Init()
-{
- SetAngleReversed (Standard_False);
- SetArrowVisible (Standard_True, Standard_True);
- SetSpecialSymbol (THE_DEGREE_SYMBOL);
- SetDisplaySpecialSymbol (AIS_DSS_After);
- SetFlyout (15.0);
-}
-
-//=======================================================================
-//function: GetCenterOnArc
-//purpose :
-//=======================================================================
-gp_Pnt AIS_AngleDimension::GetCenterOnArc (const gp_Pnt& theFirstAttach,
- const gp_Pnt& theSecondAttach,
- const gp_Pnt& theCenter) const
-{
- // construct plane where the circle and the arc are located
- gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
- if (!aConstructPlane.IsDone())
- {
- return gp::Origin();
- }
-
- gp_Pln aPlane = aConstructPlane.Value();
- if (myUseReverse) {
- gp_Ax1 anAxis = aPlane.Axis();
- gp_Dir aDir = anAxis.Direction();
- aDir.Reverse();
- aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
- }
-
- Standard_Real aRadius = theFirstAttach.Distance (theCenter);
-
- // construct circle forming the arc
- gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
- if (!aConstructCircle.IsDone())
- {
- return gp::Origin();
- }
-
- gp_Circ aCircle = aConstructCircle.Value();
-
- // compute angle parameters of arc end-points on circle
- Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
- Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
- ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
-
- return ElCLib::Value ((aParamBeg + aParamEnd) * 0.5, aCircle);
-}
-
-//=======================================================================
-//function : DrawArc
-//purpose : draws the arc between two attach points
-//=======================================================================
-void AIS_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentation,
- const gp_Pnt& theFirstAttach,
- const gp_Pnt& theSecondAttach,
- const gp_Pnt& theCenter,
- const Standard_Real theRadius,
- const Standard_Integer theMode)
-{
- // construct plane where the circle and the arc are located
- gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
- if (!aConstructPlane.IsDone())
- {
- return;
- }
-
- gp_Pln aPlane = aConstructPlane.Value();
- if (myUseReverse) {
- gp_Ax1 anAxis = aPlane.Axis();
- gp_Dir aDir = anAxis.Direction();
- aDir.Reverse();
- aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
- }
-
- // construct circle forming the arc
- gce_MakeCirc aConstructCircle (theCenter, aPlane, theRadius);
- if (!aConstructCircle.IsDone())
- {
- return;
- }
-
- gp_Circ aCircle = aConstructCircle.Value();
-
- // construct the arc
- GC_MakeArcOfCircle aConstructArc(aCircle, theFirstAttach, theSecondAttach, Standard_True);
- if (!aConstructArc.IsDone())
- {
- return;
- }
-
- // generate points with specified deflection
- const Handle(Geom_TrimmedCurve)& anArcCurve = aConstructArc.Value();
-
- GeomAdaptor_Curve anArcAdaptor (anArcCurve, anArcCurve->FirstParameter(), anArcCurve->LastParameter());
-
- // compute number of discretization elements in old-fanshioned way
- gp_Vec aCenterToFirstVec (theCenter, theFirstAttach);
- gp_Vec aCenterToSecondVec (theCenter, theSecondAttach);
-
- gp_Ax1 anAxis = aPlane.Axis();
- gp_Dir aDir = anAxis.Direction();
- gp_Vec aRefVec(aDir);
- Standard_Real anAngle = aCenterToFirstVec.AngleWithRef (aCenterToSecondVec, aRefVec);
- if (anAngle < 0)
- anAngle = 2.0 * M_PI + anAngle;
- const Standard_Integer aNbPoints = Max (4, Standard_Integer (50.0 * anAngle / M_PI));
-
- GCPnts_UniformAbscissa aMakePnts (anArcAdaptor, aNbPoints);
- if (!aMakePnts.IsDone())
- {
- return;
- }
-
- // init data arrays for graphical and selection primitives
- Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aNbPoints);
-
- SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
-
- // load data into arrays
- for (Standard_Integer aPntIt = 1; aPntIt <= aMakePnts.NbPoints(); ++aPntIt)
- {
- gp_Pnt aPnt = anArcAdaptor.Value (aMakePnts.Parameter (aPntIt));
-
- aPrimSegments->AddVertex (aPnt);
-
- aSensitiveCurve.Append (aPnt);
- }
-
- // add display presentation
- if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
- {
- Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
- }
- Handle(Graphic3d_AspectLine3d) aDimensionLineStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
- Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionLineStyle);
- Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
- if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
- {
- Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
- }
-}
-
-//=======================================================================
-//function: DrawArcWithText
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::DrawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
- const gp_Pnt& theFirstAttach,
- const gp_Pnt& theSecondAttach,
- const gp_Pnt& theCenter,
- const TCollection_ExtendedString& theText,
- const Standard_Real theTextWidth,
- const Standard_Integer theMode,
- const Standard_Integer theLabelPosition)
-{
- // construct plane where the circle and the arc are located
- gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
- if (!aConstructPlane.IsDone())
- {
- return;
- }
-
- gp_Pln aPlane = aConstructPlane.Value();
-
- Standard_Real aRadius = theFirstAttach.Distance (myCenterPoint);
-
- // construct circle forming the arc
- gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
- if (!aConstructCircle.IsDone())
- {
- return;
- }
-
- gp_Circ aCircle = aConstructCircle.Value();
-
- // compute angle parameters of arc end-points on circle
- Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
- Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
- ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
-
- // middle point of arc parameter on circle
- Standard_Real aParamMid = (aParamBeg + aParamEnd) * 0.5;
-
- // add text graphical primitives
- if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
- {
- gp_Pnt aTextPos = ElCLib::Value (aParamMid, aCircle);
- gp_Dir aTextDir = gce_MakeDir (theFirstAttach, theSecondAttach);
-
- // Drawing text
- DrawText (thePresentation,
- aTextPos,
- aTextDir,
- theText,
- theLabelPosition);
- }
-
- if (theMode != ComputeMode_All && theMode != ComputeMode_Line)
- {
- return;
- }
-
- Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
-
- Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
- && aDimensionAspect->IsText3d();
-
- if (isLineBreak)
- {
- // compute gap for label as parameteric size of sector on circle segment
- Standard_Real aSectorOnCircle = theTextWidth / aRadius;
-
- gp_Pnt aTextPntBeg = ElCLib::Value (aParamMid - aSectorOnCircle * 0.5, aCircle);
- gp_Pnt aTextPntEnd = ElCLib::Value (aParamMid + aSectorOnCircle * 0.5, aCircle);
-
- // Drawing arcs
- DrawArc (thePresentation, theFirstAttach, aTextPntBeg, theCenter, aRadius, theMode);
- DrawArc (thePresentation, theSecondAttach, aTextPntEnd, theCenter, aRadius, theMode);
- }
- else
- {
- DrawArc (thePresentation, theFirstAttach, theSecondAttach, theCenter, aRadius, theMode);
- }
-}
-
-//=======================================================================
-//function : CheckPlane
-//purpose :
-//=======================================================================
-Standard_Boolean AIS_AngleDimension::CheckPlane (const gp_Pln& thePlane)const
-{
- if (!thePlane.Contains (myFirstPoint, Precision::Confusion()) &&
- !thePlane.Contains (mySecondPoint, Precision::Confusion()) &&
- !thePlane.Contains (myCenterPoint, Precision::Confusion()))
- {
- return Standard_False;
- }
-
- return Standard_True;
-}
-
-//=======================================================================
-//function : ComputePlane
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::ComputePlane()
-{
- if (!myIsGeometryValid)
- {
- return;
- }
-
- gp_Vec aFirstVec = gp_Vec (myCenterPoint, myFirstPoint).Normalized();
- gp_Vec aSecondVec = gp_Vec (myCenterPoint, mySecondPoint).Normalized();
- gp_Vec aDirectionN = aSecondVec.Crossed (aFirstVec).Normalized();
- gp_Vec aDirectionY = (aFirstVec + aSecondVec).Normalized();
- gp_Vec aDirectionX = aDirectionY.Crossed (aDirectionN).Normalized();
-
- myPlane = gp_Pln (gp_Ax3 (myCenterPoint, gp_Dir (aDirectionN), gp_Dir (aDirectionX)));
-}
-
-//=======================================================================
-//function : GetModelUnits
-//purpose :
-//=======================================================================
-const TCollection_AsciiString& AIS_AngleDimension::GetModelUnits() const
-{
- return myDrawer->DimAngleModelUnits();
-}
-
-//=======================================================================
-//function : GetDisplayUnits
-//purpose :
-//=======================================================================
-const TCollection_AsciiString& AIS_AngleDimension::GetDisplayUnits() const
-{
- return myDrawer->DimAngleDisplayUnits();
-}
-
-//=======================================================================
-//function : SetModelUnits
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
-{
- myDrawer->SetDimAngleModelUnits (theUnits);
-}
-
-//=======================================================================
-//function : SetDisplayUnits
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
-{
- myDrawer->SetDimAngleDisplayUnits (theUnits);
-}
-
-//=======================================================================
-//function : ComputeValue
-//purpose :
-//=======================================================================
-Standard_Real AIS_AngleDimension::ComputeValue() const
-{
- if (!IsValid())
- {
- return 0.0;
- }
-
- gp_Vec aVec1 (myCenterPoint, myFirstPoint);
- gp_Vec aVec2 (myCenterPoint, mySecondPoint);
-
- Standard_Real anAngle = aVec2.AngleWithRef (aVec1, GetPlane().Axis().Direction());
-
- return anAngle > 0.0 ? anAngle : (2.0 * M_PI + anAngle);
-}
-
-//=======================================================================
-//function : Compute
-//purpose : Having three gp_Pnt points compute presentation
-//=======================================================================
-void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
- const Handle(Prs3d_Presentation)& thePresentation,
- const Standard_Integer theMode)
-{
- thePresentation->Clear();
- mySelectionGeom.Clear (theMode);
-
- if (!IsValid())
- {
- return;
- }
-
- // Parameters for presentation
- Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
-
- Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
-
- Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
-
- // prepare label string and compute its geometrical width
- Standard_Real aLabelWidth;
- TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
-
- // add margins to label width
- if (aDimensionAspect->IsText3d())
- {
- aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
- }
-
- // Get parameters from aspect or adjust it according with custom text position
- Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
- Prs3d_DimensionTextHorizontalPosition aHorisontalTextPos = aDimensionAspect->TextHorizontalPosition();
-
- if (IsTextPositionCustom())
- {
- AdjustParameters (myFixedTextPosition,anExtensionSize, aHorisontalTextPos, myFlyout);
- }
-
- // Handle user-defined and automatic arrow placement
- Standard_Boolean isArrowsExternal = Standard_False;
- Standard_Integer aLabelPosition = LabelPosition_None;
-
- FitTextAlignment (aHorisontalTextPos, aLabelPosition, isArrowsExternal);
-
- gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
- gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
-
- //Arrows positions and directions
- gp_Vec aWPDir = gp_Vec (GetPlane().Axis().Direction());
-
- gp_Dir aFirstExtensionDir = aWPDir ^ gp_Vec (myCenterPoint, aFirstAttach);
- gp_Dir aSecondExtensionDir = aWPDir.Reversed() ^ gp_Vec (myCenterPoint, aSecondAttach);
-
- gp_Vec aFirstArrowVec = gp_Vec (aFirstExtensionDir) * anArrowLength;
- gp_Vec aSecondArrowVec = gp_Vec (aSecondExtensionDir) * anArrowLength;
-
- gp_Pnt aFirstArrowBegin (0.0, 0.0, 0.0);
- gp_Pnt aFirstArrowEnd (0.0, 0.0, 0.0);
- gp_Pnt aSecondArrowBegin (0.0, 0.0, 0.0);
- gp_Pnt aSecondArrowEnd (0.0, 0.0, 0.0);
-
- if (isArrowsExternal)
- {
- aFirstArrowVec.Reverse();
- aSecondArrowVec.Reverse();
- }
-
- aFirstArrowBegin = aFirstAttach;
- aSecondArrowBegin = aSecondAttach;
- aFirstArrowEnd = aFirstAttach.Translated (-aFirstArrowVec);
- aSecondArrowEnd = aSecondAttach.Translated (-aSecondArrowVec);
-
- // Group1: stenciling text and the angle dimension arc
- Prs3d_Root::NewGroup (thePresentation);
-
- Standard_Integer aHPosition = aLabelPosition & LabelPosition_HMask;
-
- // draw text label
- switch (aHPosition)
- {
- case LabelPosition_HCenter :
- {
- Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
- && aDimensionAspect->IsText3d();
-
- if (isLineBreak)
- {
- DrawArcWithText (thePresentation,
- aFirstAttach,
- aSecondAttach,
- myCenterPoint,
- aLabelString,
- aLabelWidth,
- theMode,
- aLabelPosition);
- break;
- }
-
- // compute text primitives
- if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
- {
- gp_Vec aDimensionDir (aFirstAttach, aSecondAttach);
- gp_Pnt aTextPos = IsTextPositionCustom() ? myFixedTextPosition
- : GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
- gp_Dir aTextDir = aDimensionDir;
-
- DrawText (thePresentation,
- aTextPos,
- aTextDir,
- aLabelString,
- aLabelPosition);
- }
-
- if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
- {
- DrawArc (thePresentation,
- (isArrowsExternal || !myFirstArrowVisible) ? aFirstAttach : aFirstArrowEnd,
- (isArrowsExternal || !mySecondArrowVisible) ? aSecondAttach : aSecondArrowEnd,
- myCenterPoint,
- Abs (GetFlyout()),
- theMode);
- }
- }
- break;
-
- case LabelPosition_Left :
- {
- DrawExtension (thePresentation,
- anExtensionSize,
- (isArrowsExternal && myFirstArrowVisible) ? aFirstArrowEnd : aFirstAttach,
- aFirstExtensionDir,
- aLabelString,
- aLabelWidth,
- theMode,
- aLabelPosition);
- }
- break;
-
- case LabelPosition_Right :
- {
- DrawExtension (thePresentation,
- anExtensionSize,
- (isArrowsExternal && mySecondArrowVisible) ? aSecondArrowEnd : aSecondAttach,
- aSecondExtensionDir,
- aLabelString,
- aLabelWidth,
- theMode,
- aLabelPosition);
- }
- break;
- }
-
- // dimension arc without text
- if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && aHPosition != LabelPosition_HCenter)
- {
- Prs3d_Root::NewGroup (thePresentation);
-
- DrawArc (thePresentation,
- (isArrowsExternal || !myFirstArrowVisible) ? aFirstAttach : aFirstArrowEnd,
- (isArrowsExternal || !mySecondArrowVisible) ? aSecondAttach : aSecondArrowEnd,
- myCenterPoint,
- Abs(GetFlyout ()),
- theMode);
- }
-
- // arrows and arrow extensions
- if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
- {
- Prs3d_Root::NewGroup (thePresentation);
-
- if (myFirstArrowVisible)
- DrawArrow (thePresentation, aFirstArrowBegin, gp_Dir (aFirstArrowVec));
- if (mySecondArrowVisible)
- DrawArrow (thePresentation, aSecondArrowBegin, gp_Dir (aSecondArrowVec));
- }
-
- if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && isArrowsExternal)
- {
- Prs3d_Root::NewGroup (thePresentation);
-
- if (aHPosition != LabelPosition_Left && myFirstArrowVisible)
- {
- DrawExtension (thePresentation,
- aDimensionAspect->ArrowTailSize(),
- aFirstArrowEnd,
- aFirstExtensionDir,
- THE_EMPTY_LABEL_STRING,
- THE_EMPTY_LABEL_WIDTH,
- theMode,
- LabelPosition_None);
- }
-
- if (aHPosition != LabelPosition_Right && mySecondArrowVisible)
- {
- DrawExtension (thePresentation,
- aDimensionAspect->ArrowTailSize(),
- aSecondArrowEnd,
- aSecondExtensionDir,
- THE_EMPTY_LABEL_STRING,
- THE_EMPTY_LABEL_WIDTH,
- theMode,
- LabelPosition_None);
- }
- }
-
- // flyouts
- if (theMode == ComputeMode_All)
- {
- Prs3d_Root::NewGroup (thePresentation);
-
- Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (4);
- aPrimSegments->AddVertex (myCenterPoint);
- aPrimSegments->AddVertex (aFirstAttach);
- aPrimSegments->AddVertex (myCenterPoint);
- aPrimSegments->AddVertex (aSecondAttach);
-
- Handle(Graphic3d_AspectLine3d) aFlyoutStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
- Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aFlyoutStyle);
- Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
- }
-
- mySelectionGeom.IsComputed = Standard_True;
-}
-
-//=======================================================================
-//function : ComputeFlyoutSelection
-//purpose : computes selection for flyouts
-//=======================================================================
-void AIS_AngleDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
- const Handle(SelectMgr_EntityOwner)& theOwner)
-{
- gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
- gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
-
- Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner);
- aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aFirstAttach));
- aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aSecondAttach));
-
- theSelection->Add (aSensitiveEntity);
-}
-
-//=======================================================================
-//function : InitTwoEdgesAngle
-//purpose :
-//=======================================================================
-Standard_Boolean AIS_AngleDimension::InitTwoEdgesAngle (gp_Pln& theComputedPlane)
-{
- TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape);
- TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape);
-
- BRepAdaptor_Curve aMakeFirstLine (aFirstEdge);
- BRepAdaptor_Curve aMakeSecondLine (aSecondEdge);
-
- if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line)
- {
- return Standard_False;
- }
-
- Handle(Geom_Line) aFirstLine = new Geom_Line (aMakeFirstLine.Line());
- Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line());
-
- gp_Lin aFirstLin = aFirstLine->Lin();
- gp_Lin aSecondLin = aSecondLine->Lin();
-
- Standard_Boolean isParallelLines = Abs (aFirstLin.Angle (aSecondLin) - M_PI) <= Precision::Angular();
-
- gp_Pnt aPoint = aFirstLine->Value (0.0);
- gp_Dir aNormal = isParallelLines
- ? gp_Vec (aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction())
- : gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction());
-
- theComputedPlane = gp_Pln (aPoint, aNormal);
-
- // Compute geometry for this plane and edges
- Standard_Boolean isInfinite1,isInfinite2;
- gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2;
- gp_Lin2d aFirstLin2d, aSecondLin2d;
-
- if (!AIS::ComputeGeometry (aFirstEdge, aSecondEdge,
- aFirstLine, aSecondLine,
- aFirstPoint1, aLastPoint1,
- aFirstPoint2, aLastPoint2,
- isInfinite1, isInfinite2))
- {
- return Standard_False;
- }
-
- if (aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular()))
- {
- myFirstPoint = aFirstLin.Location();
- mySecondPoint = ElCLib::Value (ElCLib::Parameter (aFirstLin, myFirstPoint), aSecondLin);
-
- if (mySecondPoint.Distance (myFirstPoint) <= Precision::Confusion())
- {
- mySecondPoint.Translate (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout()));
- }
-
- myCenterPoint.SetXYZ ((myFirstPoint.XYZ() + mySecondPoint.XYZ()) / 2.0);
- }
- else
- {
- // Find intersection
- gp_Lin2d aFirstLin2d = ProjLib::Project (theComputedPlane, aFirstLin);
- gp_Lin2d aSecondLin2d = ProjLib::Project (theComputedPlane, aSecondLin);
-
- IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d);
- gp_Pnt2d anIntersectPoint;
- if (!anInt2d.IsDone() || anInt2d.IsEmpty())
- {
- return Standard_False;
- }
-
- anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value());
- myCenterPoint = ElCLib::To3d (theComputedPlane.Position().Ax2(), anIntersectPoint);
-
- if (isInfinite1 || isInfinite2)
- {
- myFirstPoint = myCenterPoint.Translated (gp_Vec (aFirstLin.Direction()) * Abs (GetFlyout()));
- mySecondPoint = myCenterPoint.Translated (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout()));
-
- return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
- }
-
- // |
- // | <- dimension should be here
- // *----
- myFirstPoint = !myCenterPoint.IsEqual(aFirstPoint1, Precision::Confusion())
- ? aFirstPoint1
- : aLastPoint1;
- mySecondPoint = !myCenterPoint.IsEqual(aFirstPoint2, Precision::Confusion())
- ? aFirstPoint2
- : aLastPoint2;
- }
-
- return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
-}
-
-//=======================================================================
-//function : InitTwoFacesAngle
-//purpose : initialization of angle dimension between two faces
-//=======================================================================
-Standard_Boolean AIS_AngleDimension::InitTwoFacesAngle()
-{
- TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
- TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
-
- gp_Dir aFirstDir, aSecondDir;
- gp_Pln aFirstPlane, aSecondPlane;
- Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
- AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
- Standard_Real aFirstOffset, aSecondOffset;
-
- AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
- aFirstBasisSurf,aFirstSurfType,aFirstOffset);
-
- AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
- aSecondBasisSurf, aSecondSurfType, aSecondOffset);
-
- if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane)
- {
- //Planar faces angle
- Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
- Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
- return AIS::InitAngleBetweenPlanarFaces (aFirstFace,
- aSecondFace,
- myCenterPoint,
- myFirstPoint,
- mySecondPoint)
- && IsValidPoints (myFirstPoint,
- myCenterPoint,
- mySecondPoint);
- }
- else
- {
- // Curvilinear faces angle
- return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace,
- aSecondFace,
- aFirstSurfType,
- aSecondSurfType,
- myCenterPoint,
- myFirstPoint,
- mySecondPoint)
- && IsValidPoints (myFirstPoint,
- myCenterPoint,
- mySecondPoint);
- }
-}
-
-//=======================================================================
-//function : InitTwoFacesAngle
-//purpose : initialization of angle dimension between two faces
-//=======================================================================
-Standard_Boolean AIS_AngleDimension::InitTwoFacesAngle (const gp_Pnt thePointOnFirstFace)
-{
- TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
- TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
-
- gp_Dir aFirstDir, aSecondDir;
- gp_Pln aFirstPlane, aSecondPlane;
- Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
- AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
- Standard_Real aFirstOffset, aSecondOffset;
-
- AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
- aFirstBasisSurf,aFirstSurfType,aFirstOffset);
-
- AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
- aSecondBasisSurf, aSecondSurfType, aSecondOffset);
-
- myFirstPoint = thePointOnFirstFace;
- if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane)
- {
- //Planar faces angle
- Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
- Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
- return AIS::InitAngleBetweenPlanarFaces (aFirstFace,
- aSecondFace,
- myCenterPoint,
- myFirstPoint,
- mySecondPoint,
- Standard_True)
- && IsValidPoints (myFirstPoint,
- myCenterPoint,
- mySecondPoint);
- }
- else
- {
- // Curvilinear faces angle
- return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace,
- aSecondFace,
- aFirstSurfType,
- aSecondSurfType,
- myCenterPoint,
- myFirstPoint,
- mySecondPoint,
- Standard_True)
- && IsValidPoints (myFirstPoint,
- myCenterPoint,
- mySecondPoint);
- }
-}
-
-//=======================================================================
-//function : InitConeAngle
-//purpose : initialization of the cone angle
-//=======================================================================
-Standard_Boolean AIS_AngleDimension::InitConeAngle()
-{
- if (myFirstShape.IsNull())
- {
- return Standard_False;
- }
-
- TopoDS_Face aConeShape = TopoDS::Face (myFirstShape);
- gp_Pln aPln;
- gp_Cone aCone;
- gp_Circ aCircle;
- // A surface from the Face
- Handle(Geom_Surface) aSurf;
- Handle(Geom_OffsetSurface) aOffsetSurf;
- Handle(Geom_ConicalSurface) aConicalSurf;
- Handle(Geom_SurfaceOfRevolution) aRevSurf;
- Handle(Geom_Line) aLine;
- BRepAdaptor_Surface aConeAdaptor (aConeShape);
- TopoDS_Face aFace;
- AIS_KindOfSurface aSurfType;
- Standard_Real anOffset = 0.;
- Handle(Standard_Type) aType;
-
- Standard_Real aMaxV = aConeAdaptor.FirstVParameter();
- Standard_Real aMinV = aConeAdaptor.LastVParameter();
-
- AIS::GetPlaneFromFace (aConeShape, aPln, aSurf, aSurfType, anOffset);
-
- if (aSurfType == AIS_KOS_Revolution)
- {
- // Surface of revolution
- aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf);
- gp_Lin aLin (aRevSurf->Axis());
- Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve();
- //Must be a part of line (basis curve should be linear)
- if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line))
- return Standard_False;
-
- gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV);
- gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV);
- gp_Vec aVec1 (aFirst1, aLast1);
-
- //Projection <aFirst> on <aLin>
- gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin);
- // Projection <aLast> on <aLin>
- gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin);
-
- gp_Vec aVec2 (aFirst2, aLast2);
-
- // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle).
- if (aVec1.IsParallel (aVec2, Precision::Angular())
- || aVec1.IsNormal (aVec2,Precision::Angular()))
- return Standard_False;
-
- gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1);
- aCone = aMkCone.Value();
- myCenterPoint = aCone.Apex();
- }
- else
- {
- aType = aSurf->DynamicType();
- if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01)
- {
- // Offset surface
- aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset);
- aSurf = aOffsetSurf->Surface();
- BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion());
- aMkFace.Build();
- if (!aMkFace.IsDone())
- return Standard_False;
- aConeAdaptor.Initialize (aMkFace.Face());
- }
- aCone = aConeAdaptor.Cone();
- aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf);
- myCenterPoint = aConicalSurf->Apex();
- }
-
- // A circle where the angle is drawn
- Handle(Geom_Curve) aCurve;
- Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5;
- aCurve = aSurf->VIso (aMidV);
- aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
-
- aCurve = aSurf->VIso(aMaxV);
- gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
- aCurve = aSurf->VIso(aMinV);
- gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
-
- if (aCircVmax.Radius() < aCircVmin.Radius())
- {
- gp_Circ aTmpCirc = aCircVmax;
- aCircVmax = aCircVmin;
- aCircVmin = aTmpCirc;
- }
-
- myFirstPoint = ElCLib::Value (0, aCircle);
- mySecondPoint = ElCLib::Value (M_PI, aCircle);
- return Standard_True;
-}
-
-//=======================================================================
-//function : IsValidPoints
-//purpose :
-//=======================================================================
-Standard_Boolean AIS_AngleDimension::IsValidPoints (const gp_Pnt& theFirstPoint,
- const gp_Pnt& theCenterPoint,
- const gp_Pnt& theSecondPoint) const
-{
- return theFirstPoint.Distance (theCenterPoint) > Precision::Confusion()
- && theSecondPoint.Distance (theCenterPoint) > Precision::Confusion()
- && gp_Vec (theCenterPoint, theFirstPoint).Angle (
- gp_Vec (theCenterPoint, theSecondPoint)) > Precision::Angular();
-}
-
-//=======================================================================
-//function : GetTextPosition
-//purpose :
-//=======================================================================
-const gp_Pnt AIS_AngleDimension::GetTextPosition() const
-{
- if (!IsValid())
- {
- return gp::Origin();
- }
-
- if (IsTextPositionCustom())
- {
- return myFixedTextPosition;
- }
-
- // Counts text position according to the dimension parameters
- gp_Pnt aTextPosition (gp::Origin());
-
- Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
-
- // Prepare label string and compute its geometrical width
- Standard_Real aLabelWidth;
- TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
-
- gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
- gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
-
- // Handle user-defined and automatic arrow placement
- Standard_Boolean isArrowsExternal = Standard_False;
- Standard_Integer aLabelPosition = LabelPosition_None;
- FitTextAlignment (aDimensionAspect->TextHorizontalPosition(),
- aLabelPosition, isArrowsExternal);
-
- // Get text position
- switch (aLabelPosition & LabelPosition_HMask)
- {
- case LabelPosition_HCenter:
- {
- aTextPosition = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
- }
- break;
- case LabelPosition_Left:
- {
- gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
- gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aFirstAttach);
- Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
- Standard_Real anOffset = isArrowsExternal
- ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
- : anExtensionSize;
- gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * -anOffset;
- aTextPosition = aFirstAttach.Translated (anExtensionVec);
- }
- break;
- case LabelPosition_Right:
- {
- gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
- gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aSecondAttach);
- Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
- Standard_Real anOffset = isArrowsExternal
- ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
- : anExtensionSize;
- gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * anOffset;
- aTextPosition = aSecondAttach.Translated (anExtensionVec);
- }
- break;
- }
-
- return aTextPosition;
-}
-
-//=======================================================================
-//function : SetTextPosition
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetTextPosition (const gp_Pnt& theTextPos)
-{
- if (!IsValid())
- {
- return;
- }
-
- // The text position point for angle dimension should belong to the working plane.
- if (!GetPlane().Contains (theTextPos, Precision::Confusion()))
- {
- Standard_ProgramError::Raise ("The text position point for angle dimension doesn't belong to the working plane.");
- }
-
- myIsTextPositionFixed = Standard_True;
- myFixedTextPosition = theTextPos;
-}
-
-//=======================================================================
-//function : SetAngleReversed
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetAngleReversed(const Standard_Boolean& theUseReverse)
-{
- myUseReverse = theUseReverse;
-}
-
-//=======================================================================
-//function : SetArrowVisible
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::SetArrowVisible(const Standard_Boolean& theFirstArrowVisible,
- const Standard_Boolean& theSecondArrowVisible)
-{
- myFirstArrowVisible = theFirstArrowVisible;
- mySecondArrowVisible = theSecondArrowVisible;
-}
-
-//=======================================================================
-//function : AdjustParameters
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::AdjustParameters (const gp_Pnt& theTextPos,
- Standard_Real& theExtensionSize,
- Prs3d_DimensionTextHorizontalPosition& theAlignment,
- Standard_Real& theFlyout) const
-{
- Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
- Standard_Real anArrowLength = aDimensionAspect->ArrowAspect()->Length();
-
- // Build circle with radius that is equal to distance from text position to the center point.
- Standard_Real aRadius = gp_Vec (myCenterPoint, theTextPos).Magnitude();
-
- // Set attach points in positive direction of the flyout.
- gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * aRadius);
- gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * aRadius);
-
- gce_MakeCirc aConstructCircle (myCenterPoint, GetPlane(), aRadius);
- if (!aConstructCircle.IsDone())
- {
- return;
- }
- gp_Circ aCircle = aConstructCircle.Value();
-
- // Default values
- theExtensionSize = aDimensionAspect->ArrowAspect()->Length();
- theAlignment = Prs3d_DTHP_Center;
-
- Standard_Real aParamBeg = ElCLib::Parameter (aCircle, aFirstAttach);
- Standard_Real aParamEnd = ElCLib::Parameter (aCircle, aSecondAttach);
- if (aParamEnd < aParamBeg)
- {
- Standard_Real aParam = aParamEnd;
- aParamEnd = aParamBeg;
- aParamBeg = aParam;
- }
-
- ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
- Standard_Real aTextPar = ElCLib::Parameter (aCircle , theTextPos);
-
- // Horizontal center
- if (aTextPar > aParamBeg && aTextPar < aParamEnd)
- {
- theFlyout = aRadius;
- return;
- }
-
- aParamBeg += M_PI;
- aParamEnd += M_PI;
- ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
-
- if (aTextPar > aParamBeg && aTextPar < aParamEnd)
- {
- theFlyout = -aRadius;
- return;
- }
-
- // Text on the extensions
- gp_Lin aFirstLine = gce_MakeLin (myCenterPoint, myFirstPoint);
- gp_Lin aSecondLine = gce_MakeLin (myCenterPoint, mySecondPoint);
- gp_Pnt aFirstTextProj = AIS::Nearest (aFirstLine, theTextPos);
- gp_Pnt aSecondTextProj = AIS::Nearest (aSecondLine, theTextPos);
- Standard_Real aFirstDist = aFirstTextProj.Distance (theTextPos);
- Standard_Real aSecondDist = aSecondTextProj.Distance (theTextPos);
-
- if (aFirstDist <= aSecondDist)
- {
- aRadius = myCenterPoint.Distance (aFirstTextProj);
- Standard_Real aNewExtensionSize = aFirstDist - anArrowLength;
- theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize;
-
- theAlignment = Prs3d_DTHP_Left;
-
- gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, myFirstPoint).Normalized().Scaled (aRadius);
-
- theFlyout = aFirstTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion()
- ? -aRadius : aRadius;
- }
- else
- {
- aRadius = myCenterPoint.Distance (aSecondTextProj);
-
- Standard_Real aNewExtensionSize = aSecondDist - anArrowLength;
-
- theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize;
-
- theAlignment = Prs3d_DTHP_Right;
-
- gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, mySecondPoint).Normalized().Scaled (aRadius);
-
- theFlyout = aSecondTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion()
- ? -aRadius : aRadius;
- }
-}
-
-//=======================================================================
-//function : FitTextAlignment
-//purpose :
-//=======================================================================
-void AIS_AngleDimension::FitTextAlignment (const Prs3d_DimensionTextHorizontalPosition& theHorizontalTextPos,
- Standard_Integer& theLabelPosition,
- Standard_Boolean& theIsArrowsExternal) const
-{
- Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
-
- Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
-
- // Prepare label string and compute its geometrical width
- Standard_Real aLabelWidth;
- TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
-
- // add margins to label width
- if (aDimensionAspect->IsText3d())
- {
- aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
- }
-
- gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
- gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
-
- // Handle user-defined and automatic arrow placement
- switch (aDimensionAspect->ArrowOrientation())
- {
- case Prs3d_DAO_External: theIsArrowsExternal = true; break;
- case Prs3d_DAO_Internal: theIsArrowsExternal = false; break;
- case Prs3d_DAO_Fit:
- {
- gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
- Standard_Real aDimensionWidth = anAttachVector.Magnitude();
-
- // Add margin to ensure a small tail between text and arrow
- Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
- ? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
- : 0.0;
-
- Standard_Real anArrowsWidth = (anArrowLength + anArrowMargin) * 2.0;
-
- theIsArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
- break;
- }
- }
-
- // Handle user-defined and automatic text placement
- switch (theHorizontalTextPos)
- {
- case Prs3d_DTHP_Left : theLabelPosition |= LabelPosition_Left; break;
- case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break;
- case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break;
- case Prs3d_DTHP_Fit:
- {
- gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
- Standard_Real aDimensionWidth = anAttachVector.Magnitude();
- Standard_Real anArrowsWidth = anArrowLength * 2.0;
- Standard_Real aContentWidth = theIsArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
-
- theLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
- break;
- }
- }
-
- switch (aDimensionAspect->TextVerticalPosition())
- {
- case Prs3d_DTVP_Above : theLabelPosition |= LabelPosition_Above; break;
- case Prs3d_DTVP_Below : theLabelPosition |= LabelPosition_Below; break;
- case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break;
- }
-}
+++ /dev/null
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2013 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _AIS_AngleDimension_HeaderFile
-#define _AIS_AngleDimension_HeaderFile
-
-#include <AIS_Dimension.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_Line.hxx>
-#include <Geom_Transformation.hxx>
-#include <gp.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <Prs3d_DimensionAspect.hxx>
-#include <Prs3d_Projector.hxx>
-#include <Prs3d_Presentation.hxx>
-#include <Standard.hxx>
-#include <Standard_Macro.hxx>
-#include <Standard_DefineHandle.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Vertex.hxx>
-
-DEFINE_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension)
-
-//! Angle dimension. Can be constructed:
-//! - on two intersected edges.
-//! - on three points or vertices.
-//! - on conical face.
-//! - between two intersected faces.
-//!
-//! In case of three points or two intersected edges the dimension plane
-//! (on which dimension presentation is built) can be computed uniquely
-//! as through three defined points can be built only one plane.
-//! Therefore, if user-defined plane differs from this one, the dimension can't be built.
-//!
-//! In cases of two planes automatic plane by default is built on point of the
-//! origin of parametric space of the first face (the basis surface) so, that
-//! the working plane and two faces intersection forms minimal angle between the faces.
-//! User can define the other point which the dimension plane should pass through
-//! using the appropriate constructor. This point can lay on the one of the faces or not.
-//! Also user can define his own plane but it should pass through the three points
-//! computed on the geometry initialization step (when the constructor or SetMeasuredGeometry() method
-//! is called).
-//!
-//! In case of the conical face the center point of the angle is the apex of the conical surface.
-//! The attachment points are points of the first and the last parameter of the basis circle of the cone.
-//!
-class AIS_AngleDimension : public AIS_Dimension
-{
-public:
-
- //! Constructs minimum angle dimension between two linear edges (where possible).
- //! These two edges should be intersected by each other. Otherwise the geometry is not valid.
- //! @param theFirstEdge [in] the first edge.
- //! @param theSecondEdge [in] the second edge.
- //! the maximum distanced point of edges from the presentation center
- Standard_EXPORT AIS_AngleDimension (const TopoDS_Edge& theFirstEdge,
- const TopoDS_Edge& theSecondEdge);
-
- //! Constructs the angle display object defined by three points.
- //! @param theFirstPoint [in] the first point (point on first angle flyout).
- //! @param theSecondPoint [in] the center point of angle dimension.
- //! @param theThirdPoint [in] the second point (point on second angle flyout).
- Standard_EXPORT AIS_AngleDimension (const gp_Pnt& theFirstPoint,
- const gp_Pnt& theSecondPoint,
- const gp_Pnt& theThirdPoint);
-
- //! Constructs the angle display object defined by three vertices.
- //! @param theFirstVertex [in] the first vertex (vertex for first angle flyout).
- //! @param theSecondVertex [in] the center vertex of angle dimension.
- //! @param theThirdPoint [in] the second vertex (vertex for second angle flyout).
- Standard_EXPORT AIS_AngleDimension (const TopoDS_Vertex& theFirstVertex,
- const TopoDS_Vertex& theSecondVertex,
- const TopoDS_Vertex& theThirdVertex);
-
- //! Constructs angle dimension for the cone face.
- //! @param theCone [in] the conical face.
- Standard_EXPORT AIS_AngleDimension (const TopoDS_Face& theCone);
-
- //! Constructs angle dimension between two planar faces.
- //! @param theFirstFace [in] the first face.
- //! @param theSecondFace [in] the second face.
- Standard_EXPORT AIS_AngleDimension (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace);
-
- //! Constructs angle dimension between two planar faces.
- //! @param theFirstFace [in] the first face.
- //! @param theSecondFace [in] the second face.
- //! @param thePoint [in] the point which the dimension plane should pass through.
- //! This point can lay on the one of the faces or not.
- Standard_EXPORT AIS_AngleDimension (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace,
- const gp_Pnt& thePoint);
-
-public:
-
- //! @return first point forming the angle.
- const gp_Pnt& FirstPoint() const
- {
- return myFirstPoint;
- }
-
- //! @return second point forming the angle.
- const gp_Pnt& SecondPoint() const
- {
- return mySecondPoint;
- }
-
- //! @return center point forming the angle.
- const gp_Pnt& CenterPoint() const
- {
- return myCenterPoint;
- }
-
- //! @return first argument shape.
- const TopoDS_Shape& FirstShape() const
- {
- return myFirstShape;
- }
-
- //! @return second argument shape.
- const TopoDS_Shape& SecondShape() const
- {
- return mySecondShape;
- }
-
- //! @return third argument shape.
- const TopoDS_Shape& ThirdShape() const
- {
- return myThirdShape;
- }
-
-public:
-
- //! Measures minimum angle dimension between two linear edges.
- //! These two edges should be intersected by each other. Otherwise the geometry is not valid.
- //! @param theFirstEdge [in] the first edge.
- //! @param theSecondEdge [in] the second edge.
- //! the maximum distanced point of edges from the presentation center
- Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Edge& theFirstEdge,
- const TopoDS_Edge& theSecondEdge);
-
- //! Measures angle defined by three points.
- //! @param theFirstPoint [in] the first point (point on first angle flyout).
- //! @param theSecondPoint [in] the center point of angle dimension.
- //! @param theThirdPoint [in] the second point (point on second angle flyout).
- Standard_EXPORT void SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
- const gp_Pnt& theSecondPoint,
- const gp_Pnt& theThridPoint);
-
- //! Measures angle defined by three vertices.
- //! @param theFirstVertex [in] the first vertex (vertex for first angle flyout).
- //! @param theSecondVertex [in] the center vertex of angle dimension.
- //! @param theThirdPoint [in] the second vertex (vertex for second angle flyout).
- Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Vertex& theFirstVertex,
- const TopoDS_Vertex& theSecondVertex,
- const TopoDS_Vertex& theThirdVertex);
-
- //! Measures angle of conical face.
- //! @param theCone [in] the shape to measure.
- Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Face& theCone);
-
- //! Measures angle between two planar faces.
- //! @param theFirstFace [in] the first face.
- //! @param theSecondFace [in] the second face..
- Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace);
-
- //! Measures angle between two planar faces.
- //! @param theFirstFace [in] the first face.
- //! @param theSecondFace [in] the second face.
- //! @param thePoint [in] the point which the dimension plane should pass through.
- //! This point can lay on the one of the faces or not.
- Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
- const TopoDS_Face& theSecondFace,
- const gp_Pnt& thePoint);
-
- //! @return the display units string.
- Standard_EXPORT virtual const TCollection_AsciiString& GetDisplayUnits() const;
-
- //! @return the model units string.
- Standard_EXPORT virtual const TCollection_AsciiString& GetModelUnits() const;
-
- Standard_EXPORT virtual void SetDisplayUnits (const TCollection_AsciiString& theUnits);
-
- Standard_EXPORT virtual void SetModelUnits (const TCollection_AsciiString& theUnits);
-
- //! Principle of horizontal text alignment settings:
- //! - divide circle into two halves according to attachment points
- //! - if aTextPos is between attach points -> Center + positive flyout
- //! - if aTextPos is not between attach points but in this half -> Left or Right + positive flyout
- //! - if aTextPos is between reflections of attach points -> Center + negative flyout
- //! - if aTextPos is not between reflections of attach points -> Left or Right + negative flyout
- Standard_EXPORT virtual void SetTextPosition (const gp_Pnt& theTextPos);
-
- Standard_EXPORT virtual const gp_Pnt GetTextPosition () const;
-
- //! Sets state if the angle arc should be built reversing to the presentation plane.
- //! Default state is not reversed
- //! @param theUseReverse [in] the boolean state.
- void SetAngleReversed(const Standard_Boolean& theUseReverse);
-
- //! Sets visible state of angle arrows. Default value is true for both
- //! @param theFirstArrowVisible [in] the visibility of the first arrow.
- //! @param theSecondArrowVisible [in] the visibility of the second arrow.
- void SetArrowVisible(const Standard_Boolean& theFirstArrowVisible,
- const Standard_Boolean& theSecondArrowVisible);
-
-public:
-
- DEFINE_STANDARD_RTTI (AIS_AngleDimension)
-
-protected:
-
- //! Initialization of fields that is common to all constructors.
- Standard_EXPORT void Init();
-
- //! @param theFirstAttach [in] the first attachment point.
- //! @param theSecondAttach [in] the second attachment point.
- //! @param theCenter [in] the center point (center point of the angle).
- //! @return the center of the dimension arc (the main dimension line in case of angle).
- Standard_EXPORT gp_Pnt GetCenterOnArc (const gp_Pnt& theFirstAttach,
- const gp_Pnt& theSecondAttach,
- const gp_Pnt& theCenter) const;
-
- //! Draws main dimension line (arc).
- //! @param thePresentation [in] the dimension presentation.
- //! @param theFirstAttach [in] the first attachment point.
- //! @param theSecondAttach [in] the second attachment point.
- //! @param theCenter [in] the center point (center point of the angle).
- //! @param theRadius [in] the radius of the dimension arc.
- //! @param theMode [in] the display mode.
- Standard_EXPORT void DrawArc (const Handle(Prs3d_Presentation)& thePresentation,
- const gp_Pnt& theFirstAttach,
- const gp_Pnt& theSecondAttach,
- const gp_Pnt& theCenter,
- const Standard_Real theRadius,
- const Standard_Integer theMode);
-
- //! Draws main dimension line (arc) with text.
- //! @param thePresentation [in] the dimension presentation.
- //! @param theFirstAttach [in] the first attachment point.
- //! @param theSecondAttach [in] the second attachment point.
- //! @param theCenter [in] the center point (center point of the angle).
- //! @param theText [in] the text label string.
- //! @param theTextWidth [in] the text label width.
- //! @param theMode [in] the display mode.
- //! @param theLabelPosition [in] the text label vertical and horizontal positioning option
- //! respectively to the main dimension line.
- Standard_EXPORT void DrawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
- const gp_Pnt& theFirstAttach,
- const gp_Pnt& theSecondAttach,
- const gp_Pnt& theCenter,
- const TCollection_ExtendedString& theText,
- const Standard_Real theTextWidth,
- const Standard_Integer theMode,
- const Standard_Integer theLabelPosition);
-
- //! Fits text alignment relatively to the dimension line;
- //! it computes the value of label position and arrow orientation
- //! according set in the aspect and dimension properties.
- //! @param theHorizontalTextPos [in] the horizontal alignment for text position.
- //! @param theLabelPosition [out] the label position, contains bits that defines
- //! vertical and horizontal alignment. (for internal usage in count text position).
- //! @param theIsArrowExternal [out] is the arrows external,
- //! if arrow orientation in the dimension aspect is Prs3d_DAO_Fit, it fits arrow
- //! orientation automatically.
- Standard_EXPORT void FitTextAlignment (const Prs3d_DimensionTextHorizontalPosition& theHorizontalTextPos,
- Standard_Integer& theLabelPosition,
- Standard_Boolean& theIsArrowsExternal) const;
-
- //! Adjusts aspect parameters according the text position:
- //! extension size, vertical text alignment and flyout.
- //! @param theTextPos [in] the user defined 3d point of text position.
- //! @param theExtensionSize [out] the adjusted extension size.
- //! @param theAlignment [out] the horizontal label alignment.
- //! @param theFlyout [out] the adjusted value of flyout.
- Standard_EXPORT void AdjustParameters (const gp_Pnt& theTextPos,
- Standard_Real& theExtensionSize,
- Prs3d_DimensionTextHorizontalPosition& theAlignment,
- Standard_Real& theFlyout) const;
-
-protected:
-
- Standard_EXPORT virtual void ComputePlane();
-
- //! Checks if the plane includes three angle points to build dimension.
- Standard_EXPORT virtual Standard_Boolean CheckPlane (const gp_Pln& thePlane) const;
-
- Standard_EXPORT virtual Standard_Real ComputeValue() const;
-
- Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePM,
- const Handle(Prs3d_Presentation)& thePresentation,
- const Standard_Integer theMode = 0);
-
- Standard_EXPORT virtual void ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
- const Handle(SelectMgr_EntityOwner)& theOwner);
-
-protected:
-
- //! Init angular dimension to measure angle between two linear edges.
- //! the maximum distanced point of edges from the presentation center
- //! @return TRUE if the angular dimension can be constructured
- //! for the passed edges.
- Standard_EXPORT Standard_Boolean InitTwoEdgesAngle (gp_Pln& theComputedPlane);
-
- //! Init angular dimension to measure angle between two planar faces.
- //! there is no user-defined poisitoning. So attach points are set
- //! according to faces geometry (in origin of the first face basis surface).
- //! @return TRUE if the angular dimension can be constructed
- //! for the passed faces.
- Standard_EXPORT Standard_Boolean InitTwoFacesAngle();
-
- //! Init angular dimension to measure angle between two planar faces.
- //! @param thePointOnFirstFace [in] the point which the dimension plane should pass through.
- //! This point can lay on the one of the faces or not.
- //! It will be projected on the first face and this point will be set
- //! as the first point attach point.
- //! It defines some kind of dimension positioning over the faces.
- //! @return TRUE if the angular dimension can be constructed
- //! for the passed faces.
- Standard_EXPORT Standard_Boolean InitTwoFacesAngle (const gp_Pnt thePointOnFirstFace);
-
- //! Init angular dimension to measure cone face.
- //! @return TRUE if the angular dimension can be constructed
- //! for the passed cone.
- Standard_EXPORT Standard_Boolean InitConeAngle();
-
- //! Check that the points forming angle are valid.
- //! @return TRUE if the points met the following requirements:
- //! The (P1, Center), (P2, Center) can be built.
- //! The angle between the vectors > Precision::Angular().
- Standard_EXPORT Standard_Boolean IsValidPoints (const gp_Pnt& theFirstPoint,
- const gp_Pnt& theCenterPoint,
- const gp_Pnt& theSecondPoint) const;
-
-private:
- Standard_Boolean myUseReverse;
-
- Standard_Boolean myFirstArrowVisible;
- Standard_Boolean mySecondArrowVisible;
-
- gp_Pnt myFirstPoint;
- gp_Pnt mySecondPoint;
- gp_Pnt myCenterPoint;
- TopoDS_Shape myFirstShape;
- TopoDS_Shape mySecondShape;
- TopoDS_Shape myThirdShape;
-};
-
-#endif // _AIS_AngleDimension_HeaderFile
--- /dev/null
+// Created on: 1996-12-05
+// Created by: Arnaud BOUZY/Odile Olivier
+// Copyright (c) 1996-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <AIS_AngleDimension_.hxx>
+
+#include <AIS.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRep_Tool.hxx>
+#include <ElCLib.hxx>
+#include <GCPnts_UniformAbscissa.hxx>
+#include <GC_MakeArcOfCircle.hxx>
+#include <gce_MakeLin2d.hxx>
+#include <gce_MakeLin.hxx>
+#include <gce_MakeCirc.hxx>
+#include <gce_MakeCone.hxx>
+#include <gce_MakePln.hxx>
+#include <gce_MakeDir.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Geom_SurfaceOfRevolution.hxx>
+#include <Geom_OffsetSurface.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_Group.hxx>
+#include <Graphic3d_ArrayOfPolylines.hxx>
+#include <IntAna2d_AnaIntersection.hxx>
+#include <ProjLib.hxx>
+#include <Prs3d_Root.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+#include <PrsMgr_PresentationManager3d.hxx>
+#include <Select3D_SensitiveGroup.hxx>
+#include <Select3D_SensitiveSegment.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <Standard_ProgramError.hxx>
+#include <UnitsAPI.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension_, AIS_Dimension)
+IMPLEMENT_STANDARD_RTTIEXT (AIS_AngleDimension_, AIS_Dimension)
+
+namespace
+{
+ static const TCollection_ExtendedString THE_EMPTY_LABEL_STRING;
+ static const Standard_Real THE_EMPTY_LABEL_WIDTH = 0.0;
+ static const Standard_ExtCharacter THE_DEGREE_SYMBOL (0x00B0);
+ static const Standard_Real THE_3D_TEXT_MARGIN = 0.1;
+};
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+AIS_AngleDimension_::AIS_AngleDimension_ (const TopoDS_Edge& theFirstEdge,
+ const TopoDS_Edge& theSecondEdge)
+: AIS_Dimension (AIS_KOD_PLANEANGLE)
+{
+ Init();
+ SetMeasuredGeometry (theFirstEdge, theSecondEdge);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+AIS_AngleDimension_::AIS_AngleDimension_ (const gp_Pnt& theFirstPoint,
+ const gp_Pnt& theSecondPoint,
+ const gp_Pnt& theThirdPoint)
+: AIS_Dimension (AIS_KOD_PLANEANGLE)
+{
+ Init();
+ SetMeasuredGeometry (theFirstPoint, theSecondPoint, theThirdPoint);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+AIS_AngleDimension_::AIS_AngleDimension_ (const TopoDS_Vertex& theFirstVertex,
+ const TopoDS_Vertex& theSecondVertex,
+ const TopoDS_Vertex& theThirdVertex)
+: AIS_Dimension (AIS_KOD_PLANEANGLE)
+{
+ Init();
+ SetMeasuredGeometry (theFirstVertex, theSecondVertex, theThirdVertex);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+AIS_AngleDimension_::AIS_AngleDimension_ (const TopoDS_Face& theCone)
+: AIS_Dimension (AIS_KOD_PLANEANGLE)
+{
+ Init();
+ SetMeasuredGeometry (theCone);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+AIS_AngleDimension_::AIS_AngleDimension_ (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace)
+: AIS_Dimension (AIS_KOD_PLANEANGLE)
+{
+ Init();
+ SetMeasuredGeometry (theFirstFace, theSecondFace);
+}
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+AIS_AngleDimension_::AIS_AngleDimension_ (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace,
+ const gp_Pnt& thePoint)
+: AIS_Dimension (AIS_KOD_PLANEANGLE)
+{
+ Init();
+ SetMeasuredGeometry (theFirstFace, theSecondFace, thePoint);
+}
+
+//=======================================================================
+//function : SetMeasuredGeometry
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetMeasuredGeometry (const TopoDS_Edge& theFirstEdge,
+ const TopoDS_Edge& theSecondEdge)
+{
+ gp_Pln aComputedPlane;
+
+ myFirstShape = theFirstEdge;
+ mySecondShape = theSecondEdge;
+ myThirdShape = TopoDS_Shape();
+ myGeometryType = GeometryType_Edges;
+ myIsGeometryValid = InitTwoEdgesAngle (aComputedPlane);
+
+ if (myIsGeometryValid && !myIsPlaneCustom)
+ {
+ ComputePlane();
+ }
+
+ SetToUpdate();
+}
+
+//=======================================================================
+//function : SetMeasuredGeometry
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
+ const gp_Pnt& theSecondPoint,
+ const gp_Pnt& theThirdPoint)
+{
+ myFirstPoint = theFirstPoint;
+ myCenterPoint = theSecondPoint;
+ mySecondPoint = theThirdPoint;
+ myFirstShape = BRepLib_MakeVertex (myFirstPoint);
+ mySecondShape = BRepLib_MakeVertex (myCenterPoint);
+ myThirdShape = BRepLib_MakeVertex (mySecondPoint);
+ myGeometryType = GeometryType_Points;
+ myIsGeometryValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
+
+ if (myIsGeometryValid && !myIsPlaneCustom)
+ {
+ ComputePlane();
+ }
+
+ SetToUpdate();
+}
+
+//=======================================================================
+//function : SetMeasuredGeometry
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetMeasuredGeometry (const TopoDS_Vertex& theFirstVertex,
+ const TopoDS_Vertex& theSecondVertex,
+ const TopoDS_Vertex& theThirdVertex)
+{
+ myFirstShape = theFirstVertex;
+ mySecondShape = theSecondVertex;
+ myThirdShape = theThirdVertex;
+ myFirstPoint = BRep_Tool::Pnt (theFirstVertex);
+ myCenterPoint = BRep_Tool::Pnt (theSecondVertex);
+ mySecondPoint = BRep_Tool::Pnt (theThirdVertex);
+ myGeometryType = GeometryType_Points;
+ myIsGeometryValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
+
+ if (myIsGeometryValid && !myIsPlaneCustom)
+ {
+ ComputePlane();
+ }
+
+ SetToUpdate();
+}
+
+//=======================================================================
+//function : SetMeasuredGeometry
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetMeasuredGeometry (const TopoDS_Face& theCone)
+{
+ myFirstShape = theCone;
+ mySecondShape = TopoDS_Shape();
+ myThirdShape = TopoDS_Shape();
+ myGeometryType = GeometryType_Face;
+ myIsGeometryValid = InitConeAngle();
+
+ if (myIsGeometryValid && !myIsPlaneCustom)
+ {
+ ComputePlane();
+ }
+
+ SetToUpdate();
+}
+
+//=======================================================================
+//function : SetMeasuredGeometry
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace)
+{
+ myFirstShape = theFirstFace;
+ mySecondShape = theSecondFace;
+ myThirdShape = TopoDS_Shape();
+ myGeometryType = GeometryType_Faces;
+ myIsGeometryValid = InitTwoFacesAngle();
+
+ if (myIsGeometryValid && !myIsPlaneCustom)
+ {
+ ComputePlane();
+ }
+
+ SetToUpdate();
+}
+
+//=======================================================================
+//function : SetMeasuredGeometry
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace,
+ const gp_Pnt& thePoint)
+{
+ myFirstShape = theFirstFace;
+ mySecondShape = theSecondFace;
+ myThirdShape = TopoDS_Shape();
+ myGeometryType = GeometryType_Faces;
+ myIsGeometryValid = InitTwoFacesAngle (thePoint);
+
+ if (myIsGeometryValid && !myIsPlaneCustom)
+ {
+ ComputePlane();
+ }
+
+ SetToUpdate();
+}
+
+//=======================================================================
+//function : Init
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::Init()
+{
+ SetAngleReversed (Standard_False);
+ SetArrowVisible (Standard_True, Standard_True);
+ SetSpecialSymbol (THE_DEGREE_SYMBOL);
+ SetDisplaySpecialSymbol (AIS_DSS_After);
+ SetFlyout (15.0);
+}
+
+//=======================================================================
+//function: GetCenterOnArc
+//purpose :
+//=======================================================================
+gp_Pnt AIS_AngleDimension_::GetCenterOnArc (const gp_Pnt& theFirstAttach,
+ const gp_Pnt& theSecondAttach,
+ const gp_Pnt& theCenter) const
+{
+ // construct plane where the circle and the arc are located
+ gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
+ if (!aConstructPlane.IsDone())
+ {
+ return gp::Origin();
+ }
+
+ gp_Pln aPlane = aConstructPlane.Value();
+ if (myUseReverse) {
+ gp_Ax1 anAxis = aPlane.Axis();
+ gp_Dir aDir = anAxis.Direction();
+ aDir.Reverse();
+ aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
+ }
+
+ Standard_Real aRadius = theFirstAttach.Distance (theCenter);
+
+ // construct circle forming the arc
+ gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
+ if (!aConstructCircle.IsDone())
+ {
+ return gp::Origin();
+ }
+
+ gp_Circ aCircle = aConstructCircle.Value();
+
+ // compute angle parameters of arc end-points on circle
+ Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
+ Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
+ ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
+
+ return ElCLib::Value ((aParamBeg + aParamEnd) * 0.5, aCircle);
+}
+
+//=======================================================================
+//function : DrawArc
+//purpose : draws the arc between two attach points
+//=======================================================================
+void AIS_AngleDimension_::DrawArc (const Handle(Prs3d_Presentation)& thePresentation,
+ const gp_Pnt& theFirstAttach,
+ const gp_Pnt& theSecondAttach,
+ const gp_Pnt& theCenter,
+ const Standard_Real theRadius,
+ const Standard_Integer theMode)
+{
+ // construct plane where the circle and the arc are located
+ gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
+ if (!aConstructPlane.IsDone())
+ {
+ return;
+ }
+
+ gp_Pln aPlane = aConstructPlane.Value();
+ if (myUseReverse) {
+ gp_Ax1 anAxis = aPlane.Axis();
+ gp_Dir aDir = anAxis.Direction();
+ aDir.Reverse();
+ aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir));
+ }
+
+ // construct circle forming the arc
+ gce_MakeCirc aConstructCircle (theCenter, aPlane, theRadius);
+ if (!aConstructCircle.IsDone())
+ {
+ return;
+ }
+
+ gp_Circ aCircle = aConstructCircle.Value();
+
+ // construct the arc
+ GC_MakeArcOfCircle aConstructArc(aCircle, theFirstAttach, theSecondAttach, Standard_True);
+ if (!aConstructArc.IsDone())
+ {
+ return;
+ }
+
+ // generate points with specified deflection
+ const Handle(Geom_TrimmedCurve)& anArcCurve = aConstructArc.Value();
+
+ GeomAdaptor_Curve anArcAdaptor (anArcCurve, anArcCurve->FirstParameter(), anArcCurve->LastParameter());
+
+ // compute number of discretization elements in old-fanshioned way
+ gp_Vec aCenterToFirstVec (theCenter, theFirstAttach);
+ gp_Vec aCenterToSecondVec (theCenter, theSecondAttach);
+
+ gp_Ax1 anAxis = aPlane.Axis();
+ gp_Dir aDir = anAxis.Direction();
+ gp_Vec aRefVec(aDir);
+ Standard_Real anAngle = aCenterToFirstVec.AngleWithRef (aCenterToSecondVec, aRefVec);
+ if (anAngle < 0)
+ anAngle = 2.0 * M_PI + anAngle;
+ const Standard_Integer aNbPoints = Max (4, Standard_Integer (50.0 * anAngle / M_PI));
+
+ GCPnts_UniformAbscissa aMakePnts (anArcAdaptor, aNbPoints);
+ if (!aMakePnts.IsDone())
+ {
+ return;
+ }
+
+ // init data arrays for graphical and selection primitives
+ Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aNbPoints);
+
+ SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve();
+
+ // load data into arrays
+ for (Standard_Integer aPntIt = 1; aPntIt <= aMakePnts.NbPoints(); ++aPntIt)
+ {
+ gp_Pnt aPnt = anArcAdaptor.Value (aMakePnts.Parameter (aPntIt));
+
+ aPrimSegments->AddVertex (aPnt);
+
+ aSensitiveCurve.Append (aPnt);
+ }
+
+ // add display presentation
+ if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
+ {
+ Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
+ }
+ Handle(Graphic3d_AspectLine3d) aDimensionLineStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
+ Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionLineStyle);
+ Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+ if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All)
+ {
+ Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
+ }
+}
+
+//=======================================================================
+//function: DrawArcWithText
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::DrawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
+ const gp_Pnt& theFirstAttach,
+ const gp_Pnt& theSecondAttach,
+ const gp_Pnt& theCenter,
+ const TCollection_ExtendedString& theText,
+ const Standard_Real theTextWidth,
+ const Standard_Integer theMode,
+ const Standard_Integer theLabelPosition)
+{
+ // construct plane where the circle and the arc are located
+ gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter);
+ if (!aConstructPlane.IsDone())
+ {
+ return;
+ }
+
+ gp_Pln aPlane = aConstructPlane.Value();
+
+ Standard_Real aRadius = theFirstAttach.Distance (myCenterPoint);
+
+ // construct circle forming the arc
+ gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius);
+ if (!aConstructCircle.IsDone())
+ {
+ return;
+ }
+
+ gp_Circ aCircle = aConstructCircle.Value();
+
+ // compute angle parameters of arc end-points on circle
+ Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach);
+ Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach);
+ ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
+
+ // middle point of arc parameter on circle
+ Standard_Real aParamMid = (aParamBeg + aParamEnd) * 0.5;
+
+ // add text graphical primitives
+ if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
+ {
+ gp_Pnt aTextPos = ElCLib::Value (aParamMid, aCircle);
+ gp_Dir aTextDir = gce_MakeDir (theFirstAttach, theSecondAttach);
+
+ // Drawing text
+ DrawText (thePresentation,
+ aTextPos,
+ aTextDir,
+ theText,
+ theLabelPosition);
+ }
+
+ if (theMode != ComputeMode_All && theMode != ComputeMode_Line)
+ {
+ return;
+ }
+
+ Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+
+ Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
+ && aDimensionAspect->IsText3d();
+
+ if (isLineBreak)
+ {
+ // compute gap for label as parameteric size of sector on circle segment
+ Standard_Real aSectorOnCircle = theTextWidth / aRadius;
+
+ gp_Pnt aTextPntBeg = ElCLib::Value (aParamMid - aSectorOnCircle * 0.5, aCircle);
+ gp_Pnt aTextPntEnd = ElCLib::Value (aParamMid + aSectorOnCircle * 0.5, aCircle);
+
+ // Drawing arcs
+ DrawArc (thePresentation, theFirstAttach, aTextPntBeg, theCenter, aRadius, theMode);
+ DrawArc (thePresentation, theSecondAttach, aTextPntEnd, theCenter, aRadius, theMode);
+ }
+ else
+ {
+ DrawArc (thePresentation, theFirstAttach, theSecondAttach, theCenter, aRadius, theMode);
+ }
+}
+
+//=======================================================================
+//function : CheckPlane
+//purpose :
+//=======================================================================
+Standard_Boolean AIS_AngleDimension_::CheckPlane (const gp_Pln& thePlane)const
+{
+ if (!thePlane.Contains (myFirstPoint, Precision::Confusion()) &&
+ !thePlane.Contains (mySecondPoint, Precision::Confusion()) &&
+ !thePlane.Contains (myCenterPoint, Precision::Confusion()))
+ {
+ return Standard_False;
+ }
+
+ return Standard_True;
+}
+
+//=======================================================================
+//function : ComputePlane
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::ComputePlane()
+{
+ if (!myIsGeometryValid)
+ {
+ return;
+ }
+
+ gp_Vec aFirstVec = gp_Vec (myCenterPoint, myFirstPoint).Normalized();
+ gp_Vec aSecondVec = gp_Vec (myCenterPoint, mySecondPoint).Normalized();
+ gp_Vec aDirectionN = aSecondVec.Crossed (aFirstVec).Normalized();
+ gp_Vec aDirectionY = (aFirstVec + aSecondVec).Normalized();
+ gp_Vec aDirectionX = aDirectionY.Crossed (aDirectionN).Normalized();
+
+ myPlane = gp_Pln (gp_Ax3 (myCenterPoint, gp_Dir (aDirectionN), gp_Dir (aDirectionX)));
+}
+
+//=======================================================================
+//function : GetModelUnits
+//purpose :
+//=======================================================================
+const TCollection_AsciiString& AIS_AngleDimension_::GetModelUnits() const
+{
+ return myDrawer->DimAngleModelUnits();
+}
+
+//=======================================================================
+//function : GetDisplayUnits
+//purpose :
+//=======================================================================
+const TCollection_AsciiString& AIS_AngleDimension_::GetDisplayUnits() const
+{
+ return myDrawer->DimAngleDisplayUnits();
+}
+
+//=======================================================================
+//function : SetModelUnits
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetModelUnits (const TCollection_AsciiString& theUnits)
+{
+ myDrawer->SetDimAngleModelUnits (theUnits);
+}
+
+//=======================================================================
+//function : SetDisplayUnits
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetDisplayUnits (const TCollection_AsciiString& theUnits)
+{
+ myDrawer->SetDimAngleDisplayUnits (theUnits);
+}
+
+//=======================================================================
+//function : ComputeValue
+//purpose :
+//=======================================================================
+Standard_Real AIS_AngleDimension_::ComputeValue() const
+{
+ if (!IsValid())
+ {
+ return 0.0;
+ }
+
+ gp_Vec aVec1 (myCenterPoint, myFirstPoint);
+ gp_Vec aVec2 (myCenterPoint, mySecondPoint);
+
+ Standard_Real anAngle = aVec2.AngleWithRef (aVec1, GetPlane().Axis().Direction());
+
+ return anAngle > 0.0 ? anAngle : (2.0 * M_PI + anAngle);
+}
+
+//=======================================================================
+//function : Compute
+//purpose : Having three gp_Pnt points compute presentation
+//=======================================================================
+void AIS_AngleDimension_::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
+ const Handle(Prs3d_Presentation)& thePresentation,
+ const Standard_Integer theMode)
+{
+ thePresentation->Clear();
+ mySelectionGeom.Clear (theMode);
+
+ if (!IsValid())
+ {
+ return;
+ }
+
+ // Parameters for presentation
+ Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+
+ Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
+
+ Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
+
+ // prepare label string and compute its geometrical width
+ Standard_Real aLabelWidth;
+ TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+
+ // add margins to label width
+ if (aDimensionAspect->IsText3d())
+ {
+ aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
+ }
+
+ // Get parameters from aspect or adjust it according with custom text position
+ Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
+ Prs3d_DimensionTextHorizontalPosition aHorisontalTextPos = aDimensionAspect->TextHorizontalPosition();
+
+ if (IsTextPositionCustom())
+ {
+ AdjustParameters (myFixedTextPosition,anExtensionSize, aHorisontalTextPos, myFlyout);
+ }
+
+ // Handle user-defined and automatic arrow placement
+ Standard_Boolean isArrowsExternal = Standard_False;
+ Standard_Integer aLabelPosition = LabelPosition_None;
+
+ FitTextAlignment (aHorisontalTextPos, aLabelPosition, isArrowsExternal);
+
+ gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
+ gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
+
+ //Arrows positions and directions
+ gp_Vec aWPDir = gp_Vec (GetPlane().Axis().Direction());
+
+ gp_Dir aFirstExtensionDir = aWPDir ^ gp_Vec (myCenterPoint, aFirstAttach);
+ gp_Dir aSecondExtensionDir = aWPDir.Reversed() ^ gp_Vec (myCenterPoint, aSecondAttach);
+
+ gp_Vec aFirstArrowVec = gp_Vec (aFirstExtensionDir) * anArrowLength;
+ gp_Vec aSecondArrowVec = gp_Vec (aSecondExtensionDir) * anArrowLength;
+
+ gp_Pnt aFirstArrowBegin (0.0, 0.0, 0.0);
+ gp_Pnt aFirstArrowEnd (0.0, 0.0, 0.0);
+ gp_Pnt aSecondArrowBegin (0.0, 0.0, 0.0);
+ gp_Pnt aSecondArrowEnd (0.0, 0.0, 0.0);
+
+ if (isArrowsExternal)
+ {
+ aFirstArrowVec.Reverse();
+ aSecondArrowVec.Reverse();
+ }
+
+ aFirstArrowBegin = aFirstAttach;
+ aSecondArrowBegin = aSecondAttach;
+ aFirstArrowEnd = aFirstAttach.Translated (-aFirstArrowVec);
+ aSecondArrowEnd = aSecondAttach.Translated (-aSecondArrowVec);
+
+ // Group1: stenciling text and the angle dimension arc
+ Prs3d_Root::NewGroup (thePresentation);
+
+ Standard_Integer aHPosition = aLabelPosition & LabelPosition_HMask;
+
+ // draw text label
+ switch (aHPosition)
+ {
+ case LabelPosition_HCenter :
+ {
+ Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
+ && aDimensionAspect->IsText3d();
+
+ if (isLineBreak)
+ {
+ DrawArcWithText (thePresentation,
+ aFirstAttach,
+ aSecondAttach,
+ myCenterPoint,
+ aLabelString,
+ aLabelWidth,
+ theMode,
+ aLabelPosition);
+ break;
+ }
+
+ // compute text primitives
+ if (theMode == ComputeMode_All || theMode == ComputeMode_Text)
+ {
+ gp_Vec aDimensionDir (aFirstAttach, aSecondAttach);
+ gp_Pnt aTextPos = IsTextPositionCustom() ? myFixedTextPosition
+ : GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
+ gp_Dir aTextDir = aDimensionDir;
+
+ DrawText (thePresentation,
+ aTextPos,
+ aTextDir,
+ aLabelString,
+ aLabelPosition);
+ }
+
+ if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
+ {
+ DrawArc (thePresentation,
+ (isArrowsExternal || !myFirstArrowVisible) ? aFirstAttach : aFirstArrowEnd,
+ (isArrowsExternal || !mySecondArrowVisible) ? aSecondAttach : aSecondArrowEnd,
+ myCenterPoint,
+ Abs (GetFlyout()),
+ theMode);
+ }
+ }
+ break;
+
+ case LabelPosition_Left :
+ {
+ DrawExtension (thePresentation,
+ anExtensionSize,
+ (isArrowsExternal && myFirstArrowVisible) ? aFirstArrowEnd : aFirstAttach,
+ aFirstExtensionDir,
+ aLabelString,
+ aLabelWidth,
+ theMode,
+ aLabelPosition);
+ }
+ break;
+
+ case LabelPosition_Right :
+ {
+ DrawExtension (thePresentation,
+ anExtensionSize,
+ (isArrowsExternal && mySecondArrowVisible) ? aSecondArrowEnd : aSecondAttach,
+ aSecondExtensionDir,
+ aLabelString,
+ aLabelWidth,
+ theMode,
+ aLabelPosition);
+ }
+ break;
+ }
+
+ // dimension arc without text
+ if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && aHPosition != LabelPosition_HCenter)
+ {
+ Prs3d_Root::NewGroup (thePresentation);
+
+ DrawArc (thePresentation,
+ (isArrowsExternal || !myFirstArrowVisible) ? aFirstAttach : aFirstArrowEnd,
+ (isArrowsExternal || !mySecondArrowVisible) ? aSecondAttach : aSecondArrowEnd,
+ myCenterPoint,
+ Abs(GetFlyout ()),
+ theMode);
+ }
+
+ // arrows and arrow extensions
+ if (theMode == ComputeMode_All || theMode == ComputeMode_Line)
+ {
+ Prs3d_Root::NewGroup (thePresentation);
+
+ if (myFirstArrowVisible)
+ DrawArrow (thePresentation, aFirstArrowBegin, gp_Dir (aFirstArrowVec));
+ if (mySecondArrowVisible)
+ DrawArrow (thePresentation, aSecondArrowBegin, gp_Dir (aSecondArrowVec));
+ }
+
+ if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && isArrowsExternal)
+ {
+ Prs3d_Root::NewGroup (thePresentation);
+
+ if (aHPosition != LabelPosition_Left && myFirstArrowVisible)
+ {
+ DrawExtension (thePresentation,
+ aDimensionAspect->ArrowTailSize(),
+ aFirstArrowEnd,
+ aFirstExtensionDir,
+ THE_EMPTY_LABEL_STRING,
+ THE_EMPTY_LABEL_WIDTH,
+ theMode,
+ LabelPosition_None);
+ }
+
+ if (aHPosition != LabelPosition_Right && mySecondArrowVisible)
+ {
+ DrawExtension (thePresentation,
+ aDimensionAspect->ArrowTailSize(),
+ aSecondArrowEnd,
+ aSecondExtensionDir,
+ THE_EMPTY_LABEL_STRING,
+ THE_EMPTY_LABEL_WIDTH,
+ theMode,
+ LabelPosition_None);
+ }
+ }
+
+ // flyouts
+ if (theMode == ComputeMode_All)
+ {
+ Prs3d_Root::NewGroup (thePresentation);
+
+ Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (4);
+ aPrimSegments->AddVertex (myCenterPoint);
+ aPrimSegments->AddVertex (aFirstAttach);
+ aPrimSegments->AddVertex (myCenterPoint);
+ aPrimSegments->AddVertex (aSecondAttach);
+
+ Handle(Graphic3d_AspectLine3d) aFlyoutStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
+ Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aFlyoutStyle);
+ Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
+ }
+
+ mySelectionGeom.IsComputed = Standard_True;
+}
+
+//=======================================================================
+//function : ComputeFlyoutSelection
+//purpose : computes selection for flyouts
+//=======================================================================
+void AIS_AngleDimension_::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
+ const Handle(SelectMgr_EntityOwner)& theOwner)
+{
+ gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
+ gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
+
+ Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner);
+ aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aFirstAttach));
+ aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aSecondAttach));
+
+ theSelection->Add (aSensitiveEntity);
+}
+
+//=======================================================================
+//function : InitTwoEdgesAngle
+//purpose :
+//=======================================================================
+Standard_Boolean AIS_AngleDimension_::InitTwoEdgesAngle (gp_Pln& theComputedPlane)
+{
+ TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape);
+ TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape);
+
+ BRepAdaptor_Curve aMakeFirstLine (aFirstEdge);
+ BRepAdaptor_Curve aMakeSecondLine (aSecondEdge);
+
+ if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line)
+ {
+ return Standard_False;
+ }
+
+ Handle(Geom_Line) aFirstLine = new Geom_Line (aMakeFirstLine.Line());
+ Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line());
+
+ gp_Lin aFirstLin = aFirstLine->Lin();
+ gp_Lin aSecondLin = aSecondLine->Lin();
+
+ Standard_Boolean isParallelLines = Abs (aFirstLin.Angle (aSecondLin) - M_PI) <= Precision::Angular();
+
+ gp_Pnt aPoint = aFirstLine->Value (0.0);
+ gp_Dir aNormal = isParallelLines
+ ? gp_Vec (aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction())
+ : gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction());
+
+ theComputedPlane = gp_Pln (aPoint, aNormal);
+
+ // Compute geometry for this plane and edges
+ Standard_Boolean isInfinite1,isInfinite2;
+ gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2;
+ gp_Lin2d aFirstLin2d, aSecondLin2d;
+
+ if (!AIS::ComputeGeometry (aFirstEdge, aSecondEdge,
+ aFirstLine, aSecondLine,
+ aFirstPoint1, aLastPoint1,
+ aFirstPoint2, aLastPoint2,
+ isInfinite1, isInfinite2))
+ {
+ return Standard_False;
+ }
+
+ if (aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular()))
+ {
+ myFirstPoint = aFirstLin.Location();
+ mySecondPoint = ElCLib::Value (ElCLib::Parameter (aFirstLin, myFirstPoint), aSecondLin);
+
+ if (mySecondPoint.Distance (myFirstPoint) <= Precision::Confusion())
+ {
+ mySecondPoint.Translate (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout()));
+ }
+
+ myCenterPoint.SetXYZ ((myFirstPoint.XYZ() + mySecondPoint.XYZ()) / 2.0);
+ }
+ else
+ {
+ // Find intersection
+ gp_Lin2d aFirstLin2d = ProjLib::Project (theComputedPlane, aFirstLin);
+ gp_Lin2d aSecondLin2d = ProjLib::Project (theComputedPlane, aSecondLin);
+
+ IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d);
+ gp_Pnt2d anIntersectPoint;
+ if (!anInt2d.IsDone() || anInt2d.IsEmpty())
+ {
+ return Standard_False;
+ }
+
+ anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value());
+ myCenterPoint = ElCLib::To3d (theComputedPlane.Position().Ax2(), anIntersectPoint);
+
+ if (isInfinite1 || isInfinite2)
+ {
+ myFirstPoint = myCenterPoint.Translated (gp_Vec (aFirstLin.Direction()) * Abs (GetFlyout()));
+ mySecondPoint = myCenterPoint.Translated (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout()));
+
+ return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
+ }
+
+ // |
+ // | <- dimension should be here
+ // *----
+ myFirstPoint = !myCenterPoint.IsEqual(aFirstPoint1, Precision::Confusion())
+ ? aFirstPoint1
+ : aLastPoint1;
+ mySecondPoint = !myCenterPoint.IsEqual(aFirstPoint2, Precision::Confusion())
+ ? aFirstPoint2
+ : aLastPoint2;
+ }
+
+ return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint);
+}
+
+//=======================================================================
+//function : InitTwoFacesAngle
+//purpose : initialization of angle dimension between two faces
+//=======================================================================
+Standard_Boolean AIS_AngleDimension_::InitTwoFacesAngle()
+{
+ TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
+ TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
+
+ gp_Dir aFirstDir, aSecondDir;
+ gp_Pln aFirstPlane, aSecondPlane;
+ Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
+ AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
+ Standard_Real aFirstOffset, aSecondOffset;
+
+ AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
+ aFirstBasisSurf,aFirstSurfType,aFirstOffset);
+
+ AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
+ aSecondBasisSurf, aSecondSurfType, aSecondOffset);
+
+ if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane)
+ {
+ //Planar faces angle
+ Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
+ Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
+ return AIS::InitAngleBetweenPlanarFaces (aFirstFace,
+ aSecondFace,
+ myCenterPoint,
+ myFirstPoint,
+ mySecondPoint)
+ && IsValidPoints (myFirstPoint,
+ myCenterPoint,
+ mySecondPoint);
+ }
+ else
+ {
+ // Curvilinear faces angle
+ return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace,
+ aSecondFace,
+ aFirstSurfType,
+ aSecondSurfType,
+ myCenterPoint,
+ myFirstPoint,
+ mySecondPoint)
+ && IsValidPoints (myFirstPoint,
+ myCenterPoint,
+ mySecondPoint);
+ }
+}
+
+//=======================================================================
+//function : InitTwoFacesAngle
+//purpose : initialization of angle dimension between two faces
+//=======================================================================
+Standard_Boolean AIS_AngleDimension_::InitTwoFacesAngle (const gp_Pnt thePointOnFirstFace)
+{
+ TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape);
+ TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape);
+
+ gp_Dir aFirstDir, aSecondDir;
+ gp_Pln aFirstPlane, aSecondPlane;
+ Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf;
+ AIS_KindOfSurface aFirstSurfType, aSecondSurfType;
+ Standard_Real aFirstOffset, aSecondOffset;
+
+ AIS::GetPlaneFromFace (aFirstFace, aFirstPlane,
+ aFirstBasisSurf,aFirstSurfType,aFirstOffset);
+
+ AIS::GetPlaneFromFace (aSecondFace, aSecondPlane,
+ aSecondBasisSurf, aSecondSurfType, aSecondOffset);
+
+ myFirstPoint = thePointOnFirstFace;
+ if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane)
+ {
+ //Planar faces angle
+ Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf);
+ Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf);
+ return AIS::InitAngleBetweenPlanarFaces (aFirstFace,
+ aSecondFace,
+ myCenterPoint,
+ myFirstPoint,
+ mySecondPoint,
+ Standard_True)
+ && IsValidPoints (myFirstPoint,
+ myCenterPoint,
+ mySecondPoint);
+ }
+ else
+ {
+ // Curvilinear faces angle
+ return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace,
+ aSecondFace,
+ aFirstSurfType,
+ aSecondSurfType,
+ myCenterPoint,
+ myFirstPoint,
+ mySecondPoint,
+ Standard_True)
+ && IsValidPoints (myFirstPoint,
+ myCenterPoint,
+ mySecondPoint);
+ }
+}
+
+//=======================================================================
+//function : InitConeAngle
+//purpose : initialization of the cone angle
+//=======================================================================
+Standard_Boolean AIS_AngleDimension_::InitConeAngle()
+{
+ if (myFirstShape.IsNull())
+ {
+ return Standard_False;
+ }
+
+ TopoDS_Face aConeShape = TopoDS::Face (myFirstShape);
+ gp_Pln aPln;
+ gp_Cone aCone;
+ gp_Circ aCircle;
+ // A surface from the Face
+ Handle(Geom_Surface) aSurf;
+ Handle(Geom_OffsetSurface) aOffsetSurf;
+ Handle(Geom_ConicalSurface) aConicalSurf;
+ Handle(Geom_SurfaceOfRevolution) aRevSurf;
+ Handle(Geom_Line) aLine;
+ BRepAdaptor_Surface aConeAdaptor (aConeShape);
+ TopoDS_Face aFace;
+ AIS_KindOfSurface aSurfType;
+ Standard_Real anOffset = 0.;
+ Handle(Standard_Type) aType;
+
+ Standard_Real aMaxV = aConeAdaptor.FirstVParameter();
+ Standard_Real aMinV = aConeAdaptor.LastVParameter();
+
+ AIS::GetPlaneFromFace (aConeShape, aPln, aSurf, aSurfType, anOffset);
+
+ if (aSurfType == AIS_KOS_Revolution)
+ {
+ // Surface of revolution
+ aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf);
+ gp_Lin aLin (aRevSurf->Axis());
+ Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve();
+ //Must be a part of line (basis curve should be linear)
+ if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line))
+ return Standard_False;
+
+ gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV);
+ gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV);
+ gp_Vec aVec1 (aFirst1, aLast1);
+
+ //Projection <aFirst> on <aLin>
+ gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin);
+ // Projection <aLast> on <aLin>
+ gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin);
+
+ gp_Vec aVec2 (aFirst2, aLast2);
+
+ // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle).
+ if (aVec1.IsParallel (aVec2, Precision::Angular())
+ || aVec1.IsNormal (aVec2,Precision::Angular()))
+ return Standard_False;
+
+ gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1);
+ aCone = aMkCone.Value();
+ myCenterPoint = aCone.Apex();
+ }
+ else
+ {
+ aType = aSurf->DynamicType();
+ if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01)
+ {
+ // Offset surface
+ aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset);
+ aSurf = aOffsetSurf->Surface();
+ BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion());
+ aMkFace.Build();
+ if (!aMkFace.IsDone())
+ return Standard_False;
+ aConeAdaptor.Initialize (aMkFace.Face());
+ }
+ aCone = aConeAdaptor.Cone();
+ aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf);
+ myCenterPoint = aConicalSurf->Apex();
+ }
+
+ // A circle where the angle is drawn
+ Handle(Geom_Curve) aCurve;
+ Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5;
+ aCurve = aSurf->VIso (aMidV);
+ aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
+
+ aCurve = aSurf->VIso(aMaxV);
+ gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
+ aCurve = aSurf->VIso(aMinV);
+ gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
+
+ if (aCircVmax.Radius() < aCircVmin.Radius())
+ {
+ gp_Circ aTmpCirc = aCircVmax;
+ aCircVmax = aCircVmin;
+ aCircVmin = aTmpCirc;
+ }
+
+ myFirstPoint = ElCLib::Value (0, aCircle);
+ mySecondPoint = ElCLib::Value (M_PI, aCircle);
+ return Standard_True;
+}
+
+//=======================================================================
+//function : IsValidPoints
+//purpose :
+//=======================================================================
+Standard_Boolean AIS_AngleDimension_::IsValidPoints (const gp_Pnt& theFirstPoint,
+ const gp_Pnt& theCenterPoint,
+ const gp_Pnt& theSecondPoint) const
+{
+ return theFirstPoint.Distance (theCenterPoint) > Precision::Confusion()
+ && theSecondPoint.Distance (theCenterPoint) > Precision::Confusion()
+ && gp_Vec (theCenterPoint, theFirstPoint).Angle (
+ gp_Vec (theCenterPoint, theSecondPoint)) > Precision::Angular();
+}
+
+//=======================================================================
+//function : GetTextPosition
+//purpose :
+//=======================================================================
+const gp_Pnt AIS_AngleDimension_::GetTextPosition() const
+{
+ if (!IsValid())
+ {
+ return gp::Origin();
+ }
+
+ if (IsTextPositionCustom())
+ {
+ return myFixedTextPosition;
+ }
+
+ // Counts text position according to the dimension parameters
+ gp_Pnt aTextPosition (gp::Origin());
+
+ Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+
+ // Prepare label string and compute its geometrical width
+ Standard_Real aLabelWidth;
+ TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+
+ gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
+ gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
+
+ // Handle user-defined and automatic arrow placement
+ Standard_Boolean isArrowsExternal = Standard_False;
+ Standard_Integer aLabelPosition = LabelPosition_None;
+ FitTextAlignment (aDimensionAspect->TextHorizontalPosition(),
+ aLabelPosition, isArrowsExternal);
+
+ // Get text position
+ switch (aLabelPosition & LabelPosition_HMask)
+ {
+ case LabelPosition_HCenter:
+ {
+ aTextPosition = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint);
+ }
+ break;
+ case LabelPosition_Left:
+ {
+ gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
+ gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aFirstAttach);
+ Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
+ Standard_Real anOffset = isArrowsExternal
+ ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
+ : anExtensionSize;
+ gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * -anOffset;
+ aTextPosition = aFirstAttach.Translated (anExtensionVec);
+ }
+ break;
+ case LabelPosition_Right:
+ {
+ gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach);
+ gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aSecondAttach);
+ Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
+ Standard_Real anOffset = isArrowsExternal
+ ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length()
+ : anExtensionSize;
+ gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * anOffset;
+ aTextPosition = aSecondAttach.Translated (anExtensionVec);
+ }
+ break;
+ }
+
+ return aTextPosition;
+}
+
+//=======================================================================
+//function : SetTextPosition
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetTextPosition (const gp_Pnt& theTextPos)
+{
+ if (!IsValid())
+ {
+ return;
+ }
+
+ // The text position point for angle dimension should belong to the working plane.
+ if (!GetPlane().Contains (theTextPos, Precision::Confusion()))
+ {
+ Standard_ProgramError::Raise ("The text position point for angle dimension doesn't belong to the working plane.");
+ }
+
+ myIsTextPositionFixed = Standard_True;
+ myFixedTextPosition = theTextPos;
+}
+
+//=======================================================================
+//function : SetAngleReversed
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetAngleReversed(const Standard_Boolean& theUseReverse)
+{
+ myUseReverse = theUseReverse;
+}
+
+//=======================================================================
+//function : SetArrowVisible
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::SetArrowVisible(const Standard_Boolean& theFirstArrowVisible,
+ const Standard_Boolean& theSecondArrowVisible)
+{
+ myFirstArrowVisible = theFirstArrowVisible;
+ mySecondArrowVisible = theSecondArrowVisible;
+}
+
+//=======================================================================
+//function : AdjustParameters
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::AdjustParameters (const gp_Pnt& theTextPos,
+ Standard_Real& theExtensionSize,
+ Prs3d_DimensionTextHorizontalPosition& theAlignment,
+ Standard_Real& theFlyout) const
+{
+ Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+ Standard_Real anArrowLength = aDimensionAspect->ArrowAspect()->Length();
+
+ // Build circle with radius that is equal to distance from text position to the center point.
+ Standard_Real aRadius = gp_Vec (myCenterPoint, theTextPos).Magnitude();
+
+ // Set attach points in positive direction of the flyout.
+ gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * aRadius);
+ gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * aRadius);
+
+ gce_MakeCirc aConstructCircle (myCenterPoint, GetPlane(), aRadius);
+ if (!aConstructCircle.IsDone())
+ {
+ return;
+ }
+ gp_Circ aCircle = aConstructCircle.Value();
+
+ // Default values
+ theExtensionSize = aDimensionAspect->ArrowAspect()->Length();
+ theAlignment = Prs3d_DTHP_Center;
+
+ Standard_Real aParamBeg = ElCLib::Parameter (aCircle, aFirstAttach);
+ Standard_Real aParamEnd = ElCLib::Parameter (aCircle, aSecondAttach);
+ if (aParamEnd < aParamBeg)
+ {
+ Standard_Real aParam = aParamEnd;
+ aParamEnd = aParamBeg;
+ aParamBeg = aParam;
+ }
+
+ ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
+ Standard_Real aTextPar = ElCLib::Parameter (aCircle , theTextPos);
+
+ // Horizontal center
+ if (aTextPar > aParamBeg && aTextPar < aParamEnd)
+ {
+ theFlyout = aRadius;
+ return;
+ }
+
+ aParamBeg += M_PI;
+ aParamEnd += M_PI;
+ ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd);
+
+ if (aTextPar > aParamBeg && aTextPar < aParamEnd)
+ {
+ theFlyout = -aRadius;
+ return;
+ }
+
+ // Text on the extensions
+ gp_Lin aFirstLine = gce_MakeLin (myCenterPoint, myFirstPoint);
+ gp_Lin aSecondLine = gce_MakeLin (myCenterPoint, mySecondPoint);
+ gp_Pnt aFirstTextProj = AIS::Nearest (aFirstLine, theTextPos);
+ gp_Pnt aSecondTextProj = AIS::Nearest (aSecondLine, theTextPos);
+ Standard_Real aFirstDist = aFirstTextProj.Distance (theTextPos);
+ Standard_Real aSecondDist = aSecondTextProj.Distance (theTextPos);
+
+ if (aFirstDist <= aSecondDist)
+ {
+ aRadius = myCenterPoint.Distance (aFirstTextProj);
+ Standard_Real aNewExtensionSize = aFirstDist - anArrowLength;
+ theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize;
+
+ theAlignment = Prs3d_DTHP_Left;
+
+ gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, myFirstPoint).Normalized().Scaled (aRadius);
+
+ theFlyout = aFirstTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion()
+ ? -aRadius : aRadius;
+ }
+ else
+ {
+ aRadius = myCenterPoint.Distance (aSecondTextProj);
+
+ Standard_Real aNewExtensionSize = aSecondDist - anArrowLength;
+
+ theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize;
+
+ theAlignment = Prs3d_DTHP_Right;
+
+ gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, mySecondPoint).Normalized().Scaled (aRadius);
+
+ theFlyout = aSecondTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion()
+ ? -aRadius : aRadius;
+ }
+}
+
+//=======================================================================
+//function : FitTextAlignment
+//purpose :
+//=======================================================================
+void AIS_AngleDimension_::FitTextAlignment (const Prs3d_DimensionTextHorizontalPosition& theHorizontalTextPos,
+ Standard_Integer& theLabelPosition,
+ Standard_Boolean& theIsArrowsExternal) const
+{
+ Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
+
+ Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
+
+ // Prepare label string and compute its geometrical width
+ Standard_Real aLabelWidth;
+ TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth);
+
+ // add margins to label width
+ if (aDimensionAspect->IsText3d())
+ {
+ aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0;
+ }
+
+ gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout());
+ gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout());
+
+ // Handle user-defined and automatic arrow placement
+ switch (aDimensionAspect->ArrowOrientation())
+ {
+ case Prs3d_DAO_External: theIsArrowsExternal = true; break;
+ case Prs3d_DAO_Internal: theIsArrowsExternal = false; break;
+ case Prs3d_DAO_Fit:
+ {
+ gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
+ Standard_Real aDimensionWidth = anAttachVector.Magnitude();
+
+ // Add margin to ensure a small tail between text and arrow
+ Standard_Real anArrowMargin = aDimensionAspect->IsText3d()
+ ? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN
+ : 0.0;
+
+ Standard_Real anArrowsWidth = (anArrowLength + anArrowMargin) * 2.0;
+
+ theIsArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth;
+ break;
+ }
+ }
+
+ // Handle user-defined and automatic text placement
+ switch (theHorizontalTextPos)
+ {
+ case Prs3d_DTHP_Left : theLabelPosition |= LabelPosition_Left; break;
+ case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break;
+ case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break;
+ case Prs3d_DTHP_Fit:
+ {
+ gp_Vec anAttachVector (aFirstAttach, aSecondAttach);
+ Standard_Real aDimensionWidth = anAttachVector.Magnitude();
+ Standard_Real anArrowsWidth = anArrowLength * 2.0;
+ Standard_Real aContentWidth = theIsArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth;
+
+ theLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
+ break;
+ }
+ }
+
+ switch (aDimensionAspect->TextVerticalPosition())
+ {
+ case Prs3d_DTVP_Above : theLabelPosition |= LabelPosition_Above; break;
+ case Prs3d_DTVP_Below : theLabelPosition |= LabelPosition_Below; break;
+ case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break;
+ }
+}
--- /dev/null
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2013 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _AIS_AngleDimension_HeaderFile
+#define _AIS_AngleDimension_HeaderFile
+
+#include <AIS_Dimension.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Transformation.hxx>
+#include <gp.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pnt.hxx>
+#include <Prs3d_DimensionAspect.hxx>
+#include <Prs3d_Projector.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <Standard.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+
+DEFINE_STANDARD_HANDLE (AIS_AngleDimension_, AIS_Dimension)
+
+//! Angle dimension. Can be constructed:
+//! - on two intersected edges.
+//! - on three points or vertices.
+//! - on conical face.
+//! - between two intersected faces.
+//!
+//! In case of three points or two intersected edges the dimension plane
+//! (on which dimension presentation is built) can be computed uniquely
+//! as through three defined points can be built only one plane.
+//! Therefore, if user-defined plane differs from this one, the dimension can't be built.
+//!
+//! In cases of two planes automatic plane by default is built on point of the
+//! origin of parametric space of the first face (the basis surface) so, that
+//! the working plane and two faces intersection forms minimal angle between the faces.
+//! User can define the other point which the dimension plane should pass through
+//! using the appropriate constructor. This point can lay on the one of the faces or not.
+//! Also user can define his own plane but it should pass through the three points
+//! computed on the geometry initialization step (when the constructor or SetMeasuredGeometry() method
+//! is called).
+//!
+//! In case of the conical face the center point of the angle is the apex of the conical surface.
+//! The attachment points are points of the first and the last parameter of the basis circle of the cone.
+//!
+class AIS_AngleDimension_ : public AIS_Dimension
+{
+public:
+
+ //! Constructs minimum angle dimension between two linear edges (where possible).
+ //! These two edges should be intersected by each other. Otherwise the geometry is not valid.
+ //! @param theFirstEdge [in] the first edge.
+ //! @param theSecondEdge [in] the second edge.
+ //! the maximum distanced point of edges from the presentation center
+ Standard_EXPORT AIS_AngleDimension_ (const TopoDS_Edge& theFirstEdge,
+ const TopoDS_Edge& theSecondEdge);
+
+ //! Constructs the angle display object defined by three points.
+ //! @param theFirstPoint [in] the first point (point on first angle flyout).
+ //! @param theSecondPoint [in] the center point of angle dimension.
+ //! @param theThirdPoint [in] the second point (point on second angle flyout).
+ Standard_EXPORT AIS_AngleDimension_ (const gp_Pnt& theFirstPoint,
+ const gp_Pnt& theSecondPoint,
+ const gp_Pnt& theThirdPoint);
+
+ //! Constructs the angle display object defined by three vertices.
+ //! @param theFirstVertex [in] the first vertex (vertex for first angle flyout).
+ //! @param theSecondVertex [in] the center vertex of angle dimension.
+ //! @param theThirdPoint [in] the second vertex (vertex for second angle flyout).
+ Standard_EXPORT AIS_AngleDimension_ (const TopoDS_Vertex& theFirstVertex,
+ const TopoDS_Vertex& theSecondVertex,
+ const TopoDS_Vertex& theThirdVertex);
+
+ //! Constructs angle dimension for the cone face.
+ //! @param theCone [in] the conical face.
+ Standard_EXPORT AIS_AngleDimension_ (const TopoDS_Face& theCone);
+
+ //! Constructs angle dimension between two planar faces.
+ //! @param theFirstFace [in] the first face.
+ //! @param theSecondFace [in] the second face.
+ Standard_EXPORT AIS_AngleDimension_ (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace);
+
+ //! Constructs angle dimension between two planar faces.
+ //! @param theFirstFace [in] the first face.
+ //! @param theSecondFace [in] the second face.
+ //! @param thePoint [in] the point which the dimension plane should pass through.
+ //! This point can lay on the one of the faces or not.
+ Standard_EXPORT AIS_AngleDimension_ (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace,
+ const gp_Pnt& thePoint);
+
+public:
+
+ //! @return first point forming the angle.
+ const gp_Pnt& FirstPoint() const
+ {
+ return myFirstPoint;
+ }
+
+ //! @return second point forming the angle.
+ const gp_Pnt& SecondPoint() const
+ {
+ return mySecondPoint;
+ }
+
+ //! @return center point forming the angle.
+ const gp_Pnt& CenterPoint() const
+ {
+ return myCenterPoint;
+ }
+
+ //! @return first argument shape.
+ const TopoDS_Shape& FirstShape() const
+ {
+ return myFirstShape;
+ }
+
+ //! @return second argument shape.
+ const TopoDS_Shape& SecondShape() const
+ {
+ return mySecondShape;
+ }
+
+ //! @return third argument shape.
+ const TopoDS_Shape& ThirdShape() const
+ {
+ return myThirdShape;
+ }
+
+public:
+
+ //! Measures minimum angle dimension between two linear edges.
+ //! These two edges should be intersected by each other. Otherwise the geometry is not valid.
+ //! @param theFirstEdge [in] the first edge.
+ //! @param theSecondEdge [in] the second edge.
+ //! the maximum distanced point of edges from the presentation center
+ Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Edge& theFirstEdge,
+ const TopoDS_Edge& theSecondEdge);
+
+ //! Measures angle defined by three points.
+ //! @param theFirstPoint [in] the first point (point on first angle flyout).
+ //! @param theSecondPoint [in] the center point of angle dimension.
+ //! @param theThirdPoint [in] the second point (point on second angle flyout).
+ Standard_EXPORT void SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
+ const gp_Pnt& theSecondPoint,
+ const gp_Pnt& theThridPoint);
+
+ //! Measures angle defined by three vertices.
+ //! @param theFirstVertex [in] the first vertex (vertex for first angle flyout).
+ //! @param theSecondVertex [in] the center vertex of angle dimension.
+ //! @param theThirdPoint [in] the second vertex (vertex for second angle flyout).
+ Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Vertex& theFirstVertex,
+ const TopoDS_Vertex& theSecondVertex,
+ const TopoDS_Vertex& theThirdVertex);
+
+ //! Measures angle of conical face.
+ //! @param theCone [in] the shape to measure.
+ Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Face& theCone);
+
+ //! Measures angle between two planar faces.
+ //! @param theFirstFace [in] the first face.
+ //! @param theSecondFace [in] the second face..
+ Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace);
+
+ //! Measures angle between two planar faces.
+ //! @param theFirstFace [in] the first face.
+ //! @param theSecondFace [in] the second face.
+ //! @param thePoint [in] the point which the dimension plane should pass through.
+ //! This point can lay on the one of the faces or not.
+ Standard_EXPORT void SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
+ const TopoDS_Face& theSecondFace,
+ const gp_Pnt& thePoint);
+
+ //! @return the display units string.
+ Standard_EXPORT virtual const TCollection_AsciiString& GetDisplayUnits() const;
+
+ //! @return the model units string.
+ Standard_EXPORT virtual const TCollection_AsciiString& GetModelUnits() const;
+
+ Standard_EXPORT virtual void SetDisplayUnits (const TCollection_AsciiString& theUnits);
+
+ Standard_EXPORT virtual void SetModelUnits (const TCollection_AsciiString& theUnits);
+
+ //! Principle of horizontal text alignment settings:
+ //! - divide circle into two halves according to attachment points
+ //! - if aTextPos is between attach points -> Center + positive flyout
+ //! - if aTextPos is not between attach points but in this half -> Left or Right + positive flyout
+ //! - if aTextPos is between reflections of attach points -> Center + negative flyout
+ //! - if aTextPos is not between reflections of attach points -> Left or Right + negative flyout
+ Standard_EXPORT virtual void SetTextPosition (const gp_Pnt& theTextPos);
+
+ Standard_EXPORT virtual const gp_Pnt GetTextPosition () const;
+
+ //! Sets state if the angle arc should be built reversing to the presentation plane.
+ //! Default state is not reversed
+ //! @param theUseReverse [in] the boolean state.
+ void SetAngleReversed(const Standard_Boolean& theUseReverse);
+
+ //! Sets visible state of angle arrows. Default value is true for both
+ //! @param theFirstArrowVisible [in] the visibility of the first arrow.
+ //! @param theSecondArrowVisible [in] the visibility of the second arrow.
+ void SetArrowVisible(const Standard_Boolean& theFirstArrowVisible,
+ const Standard_Boolean& theSecondArrowVisible);
+
+public:
+
+ DEFINE_STANDARD_RTTI (AIS_AngleDimension_)
+
+protected:
+
+ //! Initialization of fields that is common to all constructors.
+ Standard_EXPORT void Init();
+
+ //! @param theFirstAttach [in] the first attachment point.
+ //! @param theSecondAttach [in] the second attachment point.
+ //! @param theCenter [in] the center point (center point of the angle).
+ //! @return the center of the dimension arc (the main dimension line in case of angle).
+ Standard_EXPORT gp_Pnt GetCenterOnArc (const gp_Pnt& theFirstAttach,
+ const gp_Pnt& theSecondAttach,
+ const gp_Pnt& theCenter) const;
+
+ //! Draws main dimension line (arc).
+ //! @param thePresentation [in] the dimension presentation.
+ //! @param theFirstAttach [in] the first attachment point.
+ //! @param theSecondAttach [in] the second attachment point.
+ //! @param theCenter [in] the center point (center point of the angle).
+ //! @param theRadius [in] the radius of the dimension arc.
+ //! @param theMode [in] the display mode.
+ Standard_EXPORT void DrawArc (const Handle(Prs3d_Presentation)& thePresentation,
+ const gp_Pnt& theFirstAttach,
+ const gp_Pnt& theSecondAttach,
+ const gp_Pnt& theCenter,
+ const Standard_Real theRadius,
+ const Standard_Integer theMode);
+
+ //! Draws main dimension line (arc) with text.
+ //! @param thePresentation [in] the dimension presentation.
+ //! @param theFirstAttach [in] the first attachment point.
+ //! @param theSecondAttach [in] the second attachment point.
+ //! @param theCenter [in] the center point (center point of the angle).
+ //! @param theText [in] the text label string.
+ //! @param theTextWidth [in] the text label width.
+ //! @param theMode [in] the display mode.
+ //! @param theLabelPosition [in] the text label vertical and horizontal positioning option
+ //! respectively to the main dimension line.
+ Standard_EXPORT void DrawArcWithText (const Handle(Prs3d_Presentation)& thePresentation,
+ const gp_Pnt& theFirstAttach,
+ const gp_Pnt& theSecondAttach,
+ const gp_Pnt& theCenter,
+ const TCollection_ExtendedString& theText,
+ const Standard_Real theTextWidth,
+ const Standard_Integer theMode,
+ const Standard_Integer theLabelPosition);
+
+ //! Fits text alignment relatively to the dimension line;
+ //! it computes the value of label position and arrow orientation
+ //! according set in the aspect and dimension properties.
+ //! @param theHorizontalTextPos [in] the horizontal alignment for text position.
+ //! @param theLabelPosition [out] the label position, contains bits that defines
+ //! vertical and horizontal alignment. (for internal usage in count text position).
+ //! @param theIsArrowExternal [out] is the arrows external,
+ //! if arrow orientation in the dimension aspect is Prs3d_DAO_Fit, it fits arrow
+ //! orientation automatically.
+ Standard_EXPORT void FitTextAlignment (const Prs3d_DimensionTextHorizontalPosition& theHorizontalTextPos,
+ Standard_Integer& theLabelPosition,
+ Standard_Boolean& theIsArrowsExternal) const;
+
+ //! Adjusts aspect parameters according the text position:
+ //! extension size, vertical text alignment and flyout.
+ //! @param theTextPos [in] the user defined 3d point of text position.
+ //! @param theExtensionSize [out] the adjusted extension size.
+ //! @param theAlignment [out] the horizontal label alignment.
+ //! @param theFlyout [out] the adjusted value of flyout.
+ Standard_EXPORT void AdjustParameters (const gp_Pnt& theTextPos,
+ Standard_Real& theExtensionSize,
+ Prs3d_DimensionTextHorizontalPosition& theAlignment,
+ Standard_Real& theFlyout) const;
+
+protected:
+
+ Standard_EXPORT virtual void ComputePlane();
+
+ //! Checks if the plane includes three angle points to build dimension.
+ Standard_EXPORT virtual Standard_Boolean CheckPlane (const gp_Pln& thePlane) const;
+
+ Standard_EXPORT virtual Standard_Real ComputeValue() const;
+
+ Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePM,
+ const Handle(Prs3d_Presentation)& thePresentation,
+ const Standard_Integer theMode = 0);
+
+ Standard_EXPORT virtual void ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
+ const Handle(SelectMgr_EntityOwner)& theOwner);
+
+protected:
+
+ //! Init angular dimension to measure angle between two linear edges.
+ //! the maximum distanced point of edges from the presentation center
+ //! @return TRUE if the angular dimension can be constructured
+ //! for the passed edges.
+ Standard_EXPORT Standard_Boolean InitTwoEdgesAngle (gp_Pln& theComputedPlane);
+
+ //! Init angular dimension to measure angle between two planar faces.
+ //! there is no user-defined poisitoning. So attach points are set
+ //! according to faces geometry (in origin of the first face basis surface).
+ //! @return TRUE if the angular dimension can be constructed
+ //! for the passed faces.
+ Standard_EXPORT Standard_Boolean InitTwoFacesAngle();
+
+ //! Init angular dimension to measure angle between two planar faces.
+ //! @param thePointOnFirstFace [in] the point which the dimension plane should pass through.
+ //! This point can lay on the one of the faces or not.
+ //! It will be projected on the first face and this point will be set
+ //! as the first point attach point.
+ //! It defines some kind of dimension positioning over the faces.
+ //! @return TRUE if the angular dimension can be constructed
+ //! for the passed faces.
+ Standard_EXPORT Standard_Boolean InitTwoFacesAngle (const gp_Pnt thePointOnFirstFace);
+
+ //! Init angular dimension to measure cone face.
+ //! @return TRUE if the angular dimension can be constructed
+ //! for the passed cone.
+ Standard_EXPORT Standard_Boolean InitConeAngle();
+
+ //! Check that the points forming angle are valid.
+ //! @return TRUE if the points met the following requirements:
+ //! The (P1, Center), (P2, Center) can be built.
+ //! The angle between the vectors > Precision::Angular().
+ Standard_EXPORT Standard_Boolean IsValidPoints (const gp_Pnt& theFirstPoint,
+ const gp_Pnt& theCenterPoint,
+ const gp_Pnt& theSecondPoint) const;
+
+private:
+ Standard_Boolean myUseReverse;
+
+ Standard_Boolean myFirstArrowVisible;
+ Standard_Boolean mySecondArrowVisible;
+
+ gp_Pnt myFirstPoint;
+ gp_Pnt mySecondPoint;
+ gp_Pnt myCenterPoint;
+ TopoDS_Shape myFirstShape;
+ TopoDS_Shape mySecondShape;
+ TopoDS_Shape myThirdShape;
+};
+
+#endif // _AIS_AngleDimension_HeaderFile
SketcherPrs_Mirror.h
SketcherPrs_Transformation.h
SketcherPrs_Angle.h
- AIS_AngleDimension.hxx
+ AIS_AngleDimension_.hxx
)
SET(PROJECT_SOURCES
SketcherPrs_Mirror.cpp
SketcherPrs_Transformation.cpp
SketcherPrs_Angle.cpp
- AIS_AngleDimension.cxx
+ AIS_AngleDimension_.cxx
)
SET(PROJECT_LIBRARIES
#define PI 3.1415926535897932
-IMPLEMENT_STANDARD_HANDLE(SketcherPrs_Angle, AIS_AngleDimension);
-IMPLEMENT_STANDARD_RTTIEXT(SketcherPrs_Angle, AIS_AngleDimension);
+IMPLEMENT_STANDARD_HANDLE(SketcherPrs_Angle, AIS_AngleDimension_);
+IMPLEMENT_STANDARD_RTTIEXT(SketcherPrs_Angle, AIS_AngleDimension_);
SketcherPrs_Angle::SketcherPrs_Angle(ModelAPI_Feature* theConstraint,
const std::shared_ptr<GeomAPI_Ax3>& thePlane)
-: AIS_AngleDimension(gp_Pnt(0,0,0), gp_Pnt(1,0,0), gp_Pnt(0,1,0)), myConstraint(theConstraint),
+: AIS_AngleDimension_(gp_Pnt(0,0,0), gp_Pnt(1,0,0), gp_Pnt(0,1,0)), myConstraint(theConstraint),
mySketcherPlane(thePlane),
myFirstPoint(gp_Pnt(0,0,0)), myCenterPoint(gp_Pnt(1,0,0)), mySecondPoint(gp_Pnt(0,1,0)),
myAngle(90), myValue("90"), myFlyOutPoint(0, 0.5, 0)
// Update text visualization: parameter value or parameter text
myStyleListener->updateDimensions(this, myHasParameters, myValue);
- AIS_AngleDimension::Compute(thePresentationManager, thePresentation, theMode);
+ AIS_AngleDimension_::Compute(thePresentationManager, thePresentation, theMode);
if (!aReadyToDisplay)
SketcherPrs_Tools::sendEmptyPresentationError(myConstraint,
return;
}
}
- AIS_AngleDimension::ComputeSelection(aSelection, aMode);
+ AIS_AngleDimension_::ComputeSelection(aSelection, aMode);
}
bool SketcherPrs_Angle::isAnglePlaneReversedToSketchPlane()
#include <GeomAPI_Ax3.h>
#include <ModelAPI_Feature.h>
-#include <AIS_AngleDimension.hxx>
+#include <AIS_AngleDimension_.hxx>
#include <Standard_DefineHandle.hxx>
class SketcherPrs_DimensionStyleListener;
-DEFINE_STANDARD_HANDLE(SketcherPrs_Angle, AIS_AngleDimension)
+DEFINE_STANDARD_HANDLE(SketcherPrs_Angle, AIS_AngleDimension_)
/**
* \ingroup GUI
* A class for representation of angle constraint
*/
-class SketcherPrs_Angle : public AIS_AngleDimension
+class SketcherPrs_Angle : public AIS_AngleDimension_
{
public:
/// Constructor