From 066d35261d20a2d10910172a20882e9f0ef24fc3 Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 11 Jul 2016 14:33:17 +0300 Subject: [PATCH] Issue #1608 : Dimension in sketcher is not always correctly updated --- src/SketcherPrs/AIS_AngleDimension_.cxx | 1441 ----------------- src/SketcherPrs/AIS_AngleDimension_.hxx | 365 ----- src/SketcherPrs/CMakeLists.txt | 4 +- src/SketcherPrs/SketcherPrs_Angle.cpp | 26 +- src/SketcherPrs/SketcherPrs_Angle.h | 13 +- .../SketcherPrs_DimensionStyleListener.cpp | 64 +- .../SketcherPrs_DimensionStyleListener.h | 32 +- .../SketcherPrs_LengthDimension.cpp | 14 +- src/SketcherPrs/SketcherPrs_LengthDimension.h | 6 +- src/SketcherPrs/SketcherPrs_Radius.cpp | 42 +- src/SketcherPrs/SketcherPrs_Radius.h | 11 +- src/SketcherPrs/SketcherPrs_Tools.cpp | 32 - src/SketcherPrs/SketcherPrs_Tools.h | 14 - 13 files changed, 129 insertions(+), 1935 deletions(-) delete mode 100755 src/SketcherPrs/AIS_AngleDimension_.cxx delete mode 100755 src/SketcherPrs/AIS_AngleDimension_.hxx diff --git a/src/SketcherPrs/AIS_AngleDimension_.cxx b/src/SketcherPrs/AIS_AngleDimension_.cxx deleted file mode 100755 index c4d6ab40f..000000000 --- a/src/SketcherPrs/AIS_AngleDimension_.cxx +++ /dev/null @@ -1,1441 +0,0 @@ -// 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 on - gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin); - // Projection on - 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; - } -} diff --git a/src/SketcherPrs/AIS_AngleDimension_.hxx b/src/SketcherPrs/AIS_AngleDimension_.hxx deleted file mode 100755 index 0a800f018..000000000 --- a/src/SketcherPrs/AIS_AngleDimension_.hxx +++ /dev/null @@ -1,365 +0,0 @@ -// 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 diff --git a/src/SketcherPrs/CMakeLists.txt b/src/SketcherPrs/CMakeLists.txt index 3d1cadba6..236833f24 100644 --- a/src/SketcherPrs/CMakeLists.txt +++ b/src/SketcherPrs/CMakeLists.txt @@ -27,7 +27,6 @@ SET(PROJECT_HEADERS SketcherPrs_Mirror.h SketcherPrs_Transformation.h SketcherPrs_Angle.h - AIS_AngleDimension_.hxx ) SET(PROJECT_SOURCES @@ -51,7 +50,6 @@ SET(PROJECT_SOURCES SketcherPrs_Mirror.cpp SketcherPrs_Transformation.cpp SketcherPrs_Angle.cpp - AIS_AngleDimension_.cxx ) SET(PROJECT_LIBRARIES @@ -91,7 +89,7 @@ SET(PROJECT_PICTURES icons/translate.png ) -ADD_DEFINITIONS(-DSKETCHERPRS_EXPORTS ${CAS_DEFINITIONS}) +ADD_DEFINITIONS(-DSKETCHERPRS_EXPORTS ${CAS_DEFINITIONS} -D_CRT_SECURE_NO_WARNINGS) ADD_LIBRARY(SketcherPrs SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) INCLUDE_DIRECTORIES( diff --git a/src/SketcherPrs/SketcherPrs_Angle.cpp b/src/SketcherPrs/SketcherPrs_Angle.cpp index bbca46d50..99ac0c247 100644 --- a/src/SketcherPrs/SketcherPrs_Angle.cpp +++ b/src/SketcherPrs/SketcherPrs_Angle.cpp @@ -27,15 +27,15 @@ #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& 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) + myValue(90., false, ""), myFlyOutPoint(0, 0.5, 0) { myAspect = new Prs3d_DimensionAspect(); myAspect->MakeArrows3d(false); @@ -143,11 +143,8 @@ void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& theP myCenterPoint = aCenterPoint; DataPtr aData = myConstraint->data(); - AttributeDoublePtr aVal = aData->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()); - myAngle = aVal->value(); - myValue = aVal->text(); - - myHasParameters = aVal->usedParameters().size() > 0; + AttributeDoublePtr anAttributeValue = aData->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID()); + myValue.init(anAttributeValue); std::shared_ptr aFlyoutAttr = std::dynamic_pointer_cast @@ -193,16 +190,13 @@ void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& theP aDist = calculateDistanceToFlyoutPoint(); SetFlyout(aDist); - // Angle value is in degrees - SetCustomValue(myAngle); + // Update text visualization: parameter value or parameter text + myStyleListener->updateDimensions(this, myValue); myAspect->SetExtensionSize(myAspect->ArrowAspect()->Length()); myAspect->SetArrowTailSize(myAspect->ArrowAspect()->Length()); - // 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, @@ -232,7 +226,7 @@ void SketcherPrs_Angle::ComputeSelection(const Handle(SelectMgr_Selection)& aSel return; } } - AIS_AngleDimension_::ComputeSelection(aSelection, aMode); + AIS_AngleDimension::ComputeSelection(aSelection, aMode); } bool SketcherPrs_Angle::isAnglePlaneReversedToSketchPlane() diff --git a/src/SketcherPrs/SketcherPrs_Angle.h b/src/SketcherPrs/SketcherPrs_Angle.h index 09167273c..7749848e4 100644 --- a/src/SketcherPrs/SketcherPrs_Angle.h +++ b/src/SketcherPrs/SketcherPrs_Angle.h @@ -11,18 +11,18 @@ #include #include -#include +#include #include -class SketcherPrs_DimensionStyleListener; +#include -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 @@ -84,9 +84,8 @@ private: gp_Pnt mySecondPoint; ///< the dimension second point for measured geometry gp_Pnt myCenterPoint; ///< the dimension center point for measured geometry gp_Pnt myFlyOutPoint; ///< the dimension fly out point for measured geometry - double myAngle; ///< the angle value to be shown as custom value of presentation - bool myHasParameters; ///< true if the atrribute value has used parameters - std::string myValue; ///< the angle value depending on angle type + + SketcherPrs_DimensionStyleListener::DimensionValue myValue; /// the structure filled by constraint }; diff --git a/src/SketcherPrs/SketcherPrs_DimensionStyleListener.cpp b/src/SketcherPrs/SketcherPrs_DimensionStyleListener.cpp index 4977b3f28..4cab4c9d7 100755 --- a/src/SketcherPrs/SketcherPrs_DimensionStyleListener.cpp +++ b/src/SketcherPrs/SketcherPrs_DimensionStyleListener.cpp @@ -9,6 +9,30 @@ #include +#include +#include + +// it is not possible to use 0x2211 as summ symbol because it is not supported by +// debian Linux platform +static const Standard_ExtCharacter MyEmptySymbol(' '); +static const Standard_ExtCharacter MySigmaSymbol('=');//0x03A3); // using equal instead of sigma + +SketcherPrs_DimensionStyleListener::DimensionValue::DimensionValue(double theDoubleValue, + bool theHasParameters, const std::string& theTextValue) +: myDoubleValue(theDoubleValue), + myHasParameters(theHasParameters), + myTextValue(theTextValue) +{ +} + +void SketcherPrs_DimensionStyleListener::DimensionValue::init( + const AttributeDoublePtr& theAttributeValue) +{ + myDoubleValue = theAttributeValue->value(); + myHasParameters = theAttributeValue->usedParameters().size() > 0; + myTextValue = theAttributeValue->text(); +} + SketcherPrs_DimensionStyleListener::SketcherPrs_DimensionStyleListener() { Events_Loop* aLoop = Events_Loop::loop(); @@ -34,29 +58,49 @@ void SketcherPrs_DimensionStyleListener::processEvent(const std::shared_ptrusedParameters().size() > 0, - theAttributeValue->text()); + updateDimensions(theDimension, theDimensionValue.myHasParameters, + theDimensionValue.myTextValue, theDimensionValue.myDoubleValue); } void SketcherPrs_DimensionStyleListener::updateDimensions(AIS_Dimension* theDimension, const bool theHasParameters, - const std::string& theValue) + const std::string& theTextValue, + const double theDoubleValue) { if (!theDimension) return; + /// do not show special symbols of dimension: previous implementation did not allow to unite them + theDimension->SetSpecialSymbol(MyEmptySymbol); + theDimension->SetDisplaySpecialSymbol(AIS_DSS_No); + + TCollection_ExtendedString aCustomValue; if (theHasParameters) { - bool isParameterValueStyle = myStyle == SketcherPrs_ParameterStyleMessage::ParameterValue; - SketcherPrs_Tools::setDisplaySpecialSymbol(theDimension, isParameterValueStyle); - SketcherPrs_Tools::setDisplayParameter(theDimension, theValue, !isParameterValueStyle); + bool isParameterTextStyle = myStyle == SketcherPrs_ParameterStyleMessage::ParameterText; + + if (isParameterTextStyle) + aCustomValue = theTextValue.c_str(); + else { + // format value string using "sprintf" + TCollection_AsciiString aFormatStr = theDimension->Attributes()->DimensionAspect()->ValueStringFormat(); + char aFmtBuffer[256]; + sprintf (aFmtBuffer, aFormatStr.ToCString(), theDoubleValue); + aCustomValue = TCollection_ExtendedString (aFmtBuffer); + + aCustomValue.Insert (1, MySigmaSymbol); + } } else { - SketcherPrs_Tools::setDisplaySpecialSymbol(theDimension, false); - SketcherPrs_Tools::setDisplayParameter(theDimension, theValue, false); + // format value string using "sprintf" + TCollection_AsciiString aFormatStr = theDimension->Attributes()->DimensionAspect()->ValueStringFormat(); + char aFmtBuffer[256]; + sprintf (aFmtBuffer, aFormatStr.ToCString(), theDoubleValue); + aCustomValue = TCollection_ExtendedString (aFmtBuffer); } + theDimension->SetCustomValue(aCustomValue); } diff --git a/src/SketcherPrs/SketcherPrs_DimensionStyleListener.h b/src/SketcherPrs/SketcherPrs_DimensionStyleListener.h index cc00b23ac..17a39b466 100755 --- a/src/SketcherPrs/SketcherPrs_DimensionStyleListener.h +++ b/src/SketcherPrs/SketcherPrs_DimensionStyleListener.h @@ -24,6 +24,20 @@ */ class SketcherPrs_DimensionStyleListener : public Events_Listener { +public: + class DimensionValue { + public: + DimensionValue(double theDoubleValue, bool theHasParameters, const std::string& theTextValue); + /// Fills internal fields by the given attribute + /// \param theAttributeValue a model attribute + void init(const AttributeDoublePtr& theAttributeValue); + + public: + double myDoubleValue; ///< the angle value to be shown as custom value of presentation + bool myHasParameters; ///< true if the atrribute value has used parameters + std::string myTextValue; ///< the angle value depending on angle type + }; + public: /// Constructor Standard_EXPORT SketcherPrs_DimensionStyleListener(); @@ -35,18 +49,22 @@ public: /// from the message with origin and planes virtual void processEvent(const std::shared_ptr& theMessage); - /// Redefinition of virtual function + /// Visualizes the dimension text or dimension value depending on the has parameters state + /// \param theDimension a modified dimension + /// \param theDimensionValue container filled by the model double attribute Standard_EXPORT void updateDimensions(AIS_Dimension* theDimension, - const AttributeDoublePtr& theAttributeValue); + const DimensionValue& theDimensionValue); +private: /// Visualizes the dimension text or dimension value depending on the has parameters state /// \param theDimension a modified dimension /// \param theHasParameters if true, the text is shown, else digit - /// \param theValue a dimension value - Standard_EXPORT void updateDimensions(AIS_Dimension* theDimension, - const bool theHasParameters, - const std::string& theValue); - + /// \param theTextValue a dimension text value + /// \param theDoubleValue a dimension digit value + void updateDimensions(AIS_Dimension* theDimension, + const bool theHasParameters, + const std::string& theTextValue, + const double theDoubleValue); private: /// Style how the parameter of dimension should be visualized SketcherPrs_ParameterStyleMessage::ParameterStyle myStyle; diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp index fd4ba79e1..3253d2716 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.cpp +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.cpp @@ -42,9 +42,8 @@ SketcherPrs_LengthDimension::SketcherPrs_LengthDimension(ModelAPI_Feature* theCo myFirstPoint(MyDefStart), mySecondPoint(MyDefEnd), myPlane(MyDefPln), - myHasParameters(false), - myValue(""), - myDistance(1) + myDistance(1), + myValue(0., false, "") { SetDimensionAspect(SketcherPrs_Tools::createDimensionAspect()); SetSelToleranceForText2d(SketcherPrs_Tools::getTextHeight()); @@ -77,10 +76,9 @@ void SketcherPrs_LengthDimension::Compute(const Handle(PrsMgr_PresentationManage myDistance = SketcherPrs_Tools::getFlyoutDistance(myConstraint); myPlane = gp_Pln(mySketcherPlane->impl()); - AttributeDoublePtr anAttributeValue = myConstraint->data()->real(SketchPlugin_Constraint::VALUE()); - - myHasParameters = anAttributeValue->usedParameters().size() > 0; - myValue = anAttributeValue->text(); + DataPtr aData = myConstraint->data(); + AttributeDoublePtr anAttributeValue = aData->real(SketchPlugin_Constraint::VALUE()); + myValue.init(anAttributeValue); } // compute flyout distance @@ -93,7 +91,7 @@ void SketcherPrs_LengthDimension::Compute(const Handle(PrsMgr_PresentationManage SketcherPrs_Tools::updateArrows(DimensionAspect(), GetValue(), aTextSize); // Update text visualization: parameter value or parameter text - myStyleListener->updateDimensions(this, myHasParameters, myValue); + myStyleListener->updateDimensions(this, myValue); AIS_LengthDimension::Compute(thePresentationManager, thePresentation, theMode); diff --git a/src/SketcherPrs/SketcherPrs_LengthDimension.h b/src/SketcherPrs/SketcherPrs_LengthDimension.h index a4b161de1..f505e7fff 100644 --- a/src/SketcherPrs/SketcherPrs_LengthDimension.h +++ b/src/SketcherPrs/SketcherPrs_LengthDimension.h @@ -17,7 +17,7 @@ #include #include -class SketcherPrs_DimensionStyleListener; +#include DEFINE_STANDARD_HANDLE(SketcherPrs_LengthDimension, AIS_LengthDimension) @@ -75,9 +75,9 @@ private: gp_Pnt myFirstPoint; ///< the dimension first point for measured geometry gp_Pnt mySecondPoint; ///< the dimension first point for measured geometry gp_Pln myPlane; ///< the plane(plane of the sketch) for measured geometry - bool myHasParameters; ///< true if the atrribute value has used parameters - std::string myValue; ///< dimension value double myDistance; ///< the flyout distance + + SketcherPrs_DimensionStyleListener::DimensionValue myValue; /// the structure filled by constraint }; #endif \ No newline at end of file diff --git a/src/SketcherPrs/SketcherPrs_Radius.cpp b/src/SketcherPrs/SketcherPrs_Radius.cpp index 9e7e61b65..46391212e 100644 --- a/src/SketcherPrs/SketcherPrs_Radius.cpp +++ b/src/SketcherPrs/SketcherPrs_Radius.cpp @@ -31,9 +31,7 @@ SketcherPrs_Radius::SketcherPrs_Radius(ModelAPI_Feature* theConstraint, : AIS_RadiusDimension(MyDefCirc), myConstraint(theConstraint), mySketcherPlane(thePlane), myCircle(MyDefCirc), myAnchorPoint(gp_Pnt(0, 0, 2)), - myHasParameters(false), - myValue(""), - myRadius(1) + myValue(1, false, "") { SetDimensionAspect(SketcherPrs_Tools::createDimensionAspect()); SetSelToleranceForText2d(SketcherPrs_Tools::getDefaultTextHeight()); @@ -51,14 +49,12 @@ bool SketcherPrs_Radius::IsReadyToDisplay(ModelAPI_Feature* theConstraint, { gp_Circ aCircle; gp_Pnt anAnchorPoint; - double aRadius; - return readyToDisplay(theConstraint, thePlane, aCircle, anAnchorPoint, aRadius); + return readyToDisplay(theConstraint, thePlane, aCircle, anAnchorPoint); } bool SketcherPrs_Radius::readyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane, - gp_Circ& theCircle, gp_Pnt& theAnchorPoint, - double& theRadius) + gp_Circ& theCircle, gp_Pnt& theAnchorPoint) { bool aReadyToDisplay = false; @@ -80,7 +76,8 @@ bool SketcherPrs_Radius::readyToDisplay(ModelAPI_Feature* theConstraint, return aReadyToDisplay; std::shared_ptr aCyrcFeature = ModelAPI_Feature::feature(anAttr->object()); - theRadius = 1; + //theRadius = 1; + double aRadius = 1; std::shared_ptr aCenterAttr; // it is possible that circle result becomes zero, in this case the presentation should disappear // for example, it happens when circle radius is set to zero @@ -92,19 +89,23 @@ bool SketcherPrs_Radius::readyToDisplay(ModelAPI_Feature* theConstraint, AttributeDoublePtr aCircRadius = std::dynamic_pointer_cast( aCyrcFeature->data()->attribute(SketchPlugin_Circle::RADIUS_ID())); - theRadius = aCircRadius->value(); + aRadius = aCircRadius->value(); } else { // arc aCenterAttr = std::dynamic_pointer_cast( aCyrcFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID())); - std::shared_ptr aStartAttr = - std::dynamic_pointer_cast - (aCyrcFeature->data()->attribute(SketchPlugin_Arc::START_ID())); - theRadius = aCenterAttr->pnt()->distance(aStartAttr->pnt()); + //std::shared_ptr aStartAttr = + // std::dynamic_pointer_cast + // (aCyrcFeature->data()->attribute(SketchPlugin_Arc::START_ID())); + //theRadius = aCenterAttr->pnt()->distance(aStartAttr->pnt()); + AttributeDoublePtr aCircRadius = + std::dynamic_pointer_cast( + aCyrcFeature->data()->attribute(SketchPlugin_Arc::RADIUS_ID())); + aRadius = aCircRadius->value(); } std::shared_ptr aCenter = thePlane->to3D(aCenterAttr->x(), aCenterAttr->y()); std::shared_ptr aNormal = thePlane->normal(); - GeomAPI_Circ aCircle(aCenter, aNormal, theRadius); + GeomAPI_Circ aCircle(aCenter, aNormal, aRadius); std::shared_ptr anAnchor = SketcherPrs_Tools::getAnchorPoint(theConstraint, thePlane); theCircle = aCircle.impl(); @@ -121,27 +122,24 @@ void SketcherPrs_Radius::Compute(const Handle(PrsMgr_PresentationManager3d)& the { gp_Circ aCircle; gp_Pnt anAnchorPoint; - double aRadius; - bool aReadyToDisplay = readyToDisplay(myConstraint, mySketcherPlane, aCircle, anAnchorPoint, aRadius); + bool aReadyToDisplay = readyToDisplay(myConstraint, mySketcherPlane, aCircle, anAnchorPoint); if (aReadyToDisplay) { myCircle = aCircle; myAnchorPoint = anAnchorPoint; - myRadius = aRadius; - AttributeDoublePtr anAttributeValue = myConstraint->data()->real(SketchPlugin_Constraint::VALUE()); - myHasParameters = anAttributeValue->usedParameters().size() > 0; - myValue = anAttributeValue->text(); + DataPtr aData = myConstraint->data(); + AttributeDoublePtr anAttributeValue = aData->real(SketchPlugin_Constraint::VALUE()); + myValue.init(anAttributeValue); } SetMeasuredGeometry(myCircle, myAnchorPoint); - SetCustomValue(myRadius); + myStyleListener->updateDimensions(this, myValue); // Update variable aspect parameters (depending on viewer scale) double aTextSize = 0.0; GetValueString(aTextSize); SketcherPrs_Tools::updateArrows(DimensionAspect(), GetValue(), aTextSize); - myStyleListener->updateDimensions(this, myHasParameters, myValue); AIS_RadiusDimension::Compute(thePresentationManager, thePresentation, theMode); diff --git a/src/SketcherPrs/SketcherPrs_Radius.h b/src/SketcherPrs/SketcherPrs_Radius.h index 386fc01c1..ee3cbe929 100644 --- a/src/SketcherPrs/SketcherPrs_Radius.h +++ b/src/SketcherPrs/SketcherPrs_Radius.h @@ -14,7 +14,7 @@ #include #include -class SketcherPrs_DimensionStyleListener; +#include DEFINE_STANDARD_HANDLE(SketcherPrs_Radius, AIS_RadiusDimension) @@ -48,12 +48,10 @@ private: /// \param thePlane a coordinate plane of current sketch /// \param theCircle a circle build on the constraint values /// \param thePoint an anchor point to show text value - /// \param theRadius a circle custom radius value to be visualized /// \return boolean result value static bool readyToDisplay(ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane, - gp_Circ& theCircle, gp_Pnt& theAnchorPoint, - double& theRadius); + gp_Circ& theCircle, gp_Pnt& theAnchorPoint); protected: /// Redefinition of virtual function Standard_EXPORT virtual void Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, @@ -76,9 +74,8 @@ private: /// container of values obtained from the constraint, which are necessary to fill the presentation gp_Circ myCircle; ///< the radius circle gp_Pnt myAnchorPoint; ///< an ancor for the radius value visualization - bool myHasParameters; ///< true if the atrribute value has used parameters - std::string myValue; ///< dimension value - double myRadius; ///< the radius custom value + + SketcherPrs_DimensionStyleListener::DimensionValue myValue; /// the structure filled by constraint }; #endif \ No newline at end of file diff --git a/src/SketcherPrs/SketcherPrs_Tools.cpp b/src/SketcherPrs/SketcherPrs_Tools.cpp index 7947c38a2..45f4eaaf9 100644 --- a/src/SketcherPrs/SketcherPrs_Tools.cpp +++ b/src/SketcherPrs/SketcherPrs_Tools.cpp @@ -33,11 +33,6 @@ #include -// it is not possible to use 0x2211 as summ symbol because it is not supported by -// debian Linux platform -static const Standard_ExtCharacter MyEmptySymbol(' '); -static const Standard_ExtCharacter MySigmaSymbol('=');//0x03A3); // using equal instead of sigma - namespace SketcherPrs_Tools { AttributePtr getAttribute(ModelAPI_Feature* theFeature, const std::string& theAttrName) @@ -304,33 +299,6 @@ std::shared_ptr getAnchorPoint(const ModelAPI_Feature* theConstrain return thePlane->to3D(aFlyoutPnt->x(), aFlyoutPnt->y()); } -void setDisplaySpecialSymbol(AIS_Dimension* theDimension, const bool& theToDisplay) -{ - if (theToDisplay) { - theDimension->SetSpecialSymbol(MySigmaSymbol); - theDimension->SetDisplaySpecialSymbol(AIS_DSS_Before); - } - else { - theDimension->SetSpecialSymbol(MyEmptySymbol); - theDimension->SetDisplaySpecialSymbol(AIS_DSS_No); - } -} - -void setDisplayParameter(AIS_Dimension* theDimension, const std::string& theParameter, - const bool& theToDisplay) -{ - if (theToDisplay) { - theDimension->DimensionAspect()->MakeUnitsDisplayed(true); - theDimension->SetDisplayUnits(TCollection_AsciiString(theParameter.c_str())); - theDimension->DimensionAspect()->SetValueStringFormat(""); - } - else { - theDimension->DimensionAspect()->MakeUnitsDisplayed(false); - theDimension->SetDisplayUnits(TCollection_AsciiString()); // THE_UNDEFINED_UNITS in AIS_Dimension - theDimension->DimensionAspect()->SetValueStringFormat("%g"); - } -} - void sendExpressionShownEvent(const bool& theState) { static Events_ID anId = SketcherPrs_ParameterStyleMessage::eventId(); diff --git a/src/SketcherPrs/SketcherPrs_Tools.h b/src/SketcherPrs/SketcherPrs_Tools.h index 04db3704c..97c196c50 100644 --- a/src/SketcherPrs/SketcherPrs_Tools.h +++ b/src/SketcherPrs/SketcherPrs_Tools.h @@ -163,20 +163,6 @@ namespace SketcherPrs_Tools { const ModelAPI_Feature* theConstraint, const std::shared_ptr& thePlane); - /// Display/hide sigma symbol in the dimension presentation - /// \param theDimension a dimension constraint - /// \param theToDisplay a boolean value - SKETCHERPRS_EXPORT void setDisplaySpecialSymbol(AIS_Dimension* theDimension, - const bool& theToDisplay); - - /// Display the parameter value instead of dimention digit - /// \param theDimension a dimension constraint - /// \param theParameter a parameter value - /// \param theToDisplay a boolean value - SKETCHERPRS_EXPORT void setDisplayParameter(AIS_Dimension* theDimension, - const std::string& theParameter, - const bool& theToDisplay); - /// Sends event about expression visualization type is changed for dimension presentations /// Sends event to redisplay all sub-features of composite feature /// \param theState a new state -- 2.39.2