From 091f03f2d26b8532c7e8038471cc0f8684b9a770 Mon Sep 17 00:00:00 2001 From: nds Date: Fri, 8 Apr 2016 08:56:05 +0300 Subject: [PATCH] Issue 1299 angle constraint: final correction to calculate reverse state in SketcherPrs by product of scalar. Providing corresponded method in AIS_AngleDimension. It is ready to be integrated as a patch for OCCT. --- .../SketchPlugin_ConstraintAngle.cpp | 10 +- src/SketcherPrs/AIS_AngleDimension.cxx | 43 ++++----- src/SketcherPrs/AIS_AngleDimension.hxx | 9 +- src/SketcherPrs/SketcherPrs_Angle.cpp | 93 ++++++++++++------- src/SketcherPrs/SketcherPrs_Angle.h | 11 +++ 5 files changed, 97 insertions(+), 69 deletions(-) diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp index 7b60a594c..712d436af 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp @@ -199,23 +199,19 @@ double SketchPlugin_ConstraintAngle::getAngleForType(double theAngle) { double anAngle = theAngle; - std::shared_ptr aPlane = SketchPlugin_Sketch::plane(sketch()); - std::shared_ptr aNormal = aPlane->normal(); - bool aPositiveNormal = !(aNormal->x() < 0 || aNormal->y() < 0 || aNormal->z() < 0); - std::shared_ptr aData = data(); std::shared_ptr aTypeAttr = std::dynamic_pointer_cast< ModelAPI_AttributeInteger>(aData->attribute(SketchPlugin_ConstraintAngle::TYPE_ID())); SketcherPrs_Tools::AngleType anAngleType = (SketcherPrs_Tools::AngleType)(aTypeAttr->value()); switch (anAngleType) { case SketcherPrs_Tools::ANGLE_DIRECT: - anAngle = aPositiveNormal ? theAngle : 360 - theAngle; + anAngle = theAngle; break; case SketcherPrs_Tools::ANGLE_COMPLEMENTARY: - anAngle = fabs(180 - theAngle); + anAngle = fabs(180.0 - theAngle); break; case SketcherPrs_Tools::ANGLE_BACKWARD: - anAngle = aPositiveNormal ? 360 - theAngle : theAngle; + anAngle = 360.0 - theAngle; break; default: break; diff --git a/src/SketcherPrs/AIS_AngleDimension.cxx b/src/SketcherPrs/AIS_AngleDimension.cxx index 492dabbba..ba7fdb5b4 100755 --- a/src/SketcherPrs/AIS_AngleDimension.cxx +++ b/src/SketcherPrs/AIS_AngleDimension.cxx @@ -277,8 +277,8 @@ void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace, //======================================================================= void AIS_AngleDimension::Init() { - SetGeometryOrientedAngle (Standard_False, Standard_False); - SetArrowVisible(Standard_True, Standard_True); + SetAngleReversed (Standard_False); + SetArrowVisible (Standard_True, Standard_True); SetSpecialSymbol (THE_DEGREE_SYMBOL); SetDisplaySpecialSymbol (AIS_DSS_After); SetFlyout (15.0); @@ -339,23 +339,11 @@ void AIS_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentat } gp_Pln aPlane = aConstructPlane.Value(); - if (myGeometryOrientedAngle) { - gp_Dir aCPlaneDir = GetPlane().Axis().Direction(); - bool aCPlaneDirToReverse = !(aCPlaneDir.X() < 0 || aCPlaneDir.Y() < 0 || aCPlaneDir.Z() < 0); - // have similar direction for all cases - if (!aCPlaneDirToReverse && myUseReverse) { - gp_Ax1 anAxis = aPlane.Axis(); - gp_Dir aDir = anAxis.Direction(); - aDir.Reverse(); - aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir)); - } - - if (aCPlaneDirToReverse && !myUseReverse) { - gp_Ax1 anAxis = aPlane.Axis(); - gp_Dir aDir = anAxis.Direction(); - aDir.Reverse(); - aPlane.SetAxis(gp_Ax1(anAxis.Location(), aDir)); - } + 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 @@ -382,9 +370,14 @@ void AIS_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentat // compute number of discretization elements in old-fanshioned way gp_Vec aCenterToFirstVec (theCenter, theFirstAttach); gp_Vec aCenterToSecondVec (theCenter, theSecondAttach); - const Standard_Real anAngle = aCenterToFirstVec.Angle (aCenterToSecondVec); - const Standard_Integer aNbPoints = myGeometryOrientedAngle ? 40 : - Max (4, Standard_Integer (50.0 * anAngle / M_PI)); + + 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()) @@ -1253,13 +1246,11 @@ void AIS_AngleDimension::SetTextPosition (const gp_Pnt& theTextPos) } //======================================================================= -//function : SetGeometryOrientedAngle +//function : SetAngleReversed //purpose : //======================================================================= -void AIS_AngleDimension::SetGeometryOrientedAngle(const Standard_Boolean& theState, - const Standard_Boolean& theUseReverse) +void AIS_AngleDimension::SetAngleReversed(const Standard_Boolean& theUseReverse) { - myGeometryOrientedAngle = theState; myUseReverse = theUseReverse; } diff --git a/src/SketcherPrs/AIS_AngleDimension.hxx b/src/SketcherPrs/AIS_AngleDimension.hxx index acf4299a7..beb32a47a 100755 --- a/src/SketcherPrs/AIS_AngleDimension.hxx +++ b/src/SketcherPrs/AIS_AngleDimension.hxx @@ -207,10 +207,10 @@ public: Standard_EXPORT virtual const gp_Pnt GetTextPosition () const; - //! Sets state if the create arc should be built depending on the input geometry orientation - //! or to be always oriented in [0,0,1]. The last case propose angles more than 180 degree. - //! @param theSecondAttach [in] the second attachment point. - void SetGeometryOrientedAngle(const Standard_Boolean& theState, const Standard_Boolean& theUseReverse); + //! 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. @@ -346,7 +346,6 @@ protected: const gp_Pnt& theSecondPoint) const; private: - Standard_Boolean myGeometryOrientedAngle; Standard_Boolean myUseReverse; Standard_Boolean myFirstArrowVisible; diff --git a/src/SketcherPrs/SketcherPrs_Angle.cpp b/src/SketcherPrs/SketcherPrs_Angle.cpp index cbc4b9f82..98493c043 100644 --- a/src/SketcherPrs/SketcherPrs_Angle.cpp +++ b/src/SketcherPrs/SketcherPrs_Angle.cpp @@ -100,12 +100,6 @@ void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& theP ModelAPI_AttributeInteger>(aData->attribute(SketchPlugin_ConstraintAngle::TYPE_ID())); SketcherPrs_Tools::AngleType anAngleType = (SketcherPrs_Tools::AngleType)(aTypeAttr->value()); - // Flyout point - std::shared_ptr aFlyoutAttr = - std::dynamic_pointer_cast - (aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); - std::shared_ptr aFlyoutPnt = myPlane->to3D(aFlyoutAttr->x(), aFlyoutAttr->y()); - AttributeRefAttrPtr anAttr1 = aData->refattr(SketchPlugin_Constraint::ENTITY_A()); AttributeRefAttrPtr anAttr2 = aData->refattr(SketchPlugin_Constraint::ENTITY_B()); @@ -122,48 +116,50 @@ void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& theP TopoDS_Edge aEdge1 = TopoDS::Edge(aTEdge1); TopoDS_Edge aEdge2 = TopoDS::Edge(aTEdge2); + double aDist = -1; + switch (anAngleType) { case SketcherPrs_Tools::ANGLE_DIRECT: { - SetGeometryOrientedAngle(true, false); - SetArrowVisible(Standard_False, Standard_True); + SetArrowVisible(Standard_False/*first*/, Standard_True/*second*/); + SetMeasuredGeometry(aEdge1, aEdge2); + bool isReversedPlanes = isAnglePlaneReversedToSketchPlane(); + SetAngleReversed(!isReversedPlanes); } break; case SketcherPrs_Tools::ANGLE_COMPLEMENTARY: { + SetArrowVisible(Standard_True/*first*/, Standard_False/*second*/); // to calculate center, first and end points - SetGeometryOrientedAngle(false, false); + SetAngleReversed(false); SetMeasuredGeometry(aEdge1, aEdge2); - gp_Pnt aCenterPnt = CenterPoint(); - gp_Pnt aFirstPnt = FirstPoint(); - gp_Pnt aSecondPnt = SecondPoint(); - double anEdge2Length = aCenterPnt.Distance(aSecondPnt); - aSecondPnt = aCenterPnt.Translated (gp_Vec(aCenterPnt, aSecondPnt).Normalized() * (-anEdge2Length)); - SetArrowVisible(Standard_True, Standard_False); - SetMeasuredGeometry(aFirstPnt, aCenterPnt, aSecondPnt); + /// the first point will be moved, so it is necessary to find distance + /// after applying initial parameters of geometry but before correcting them + /// for the current type of angle(complementary) + aDist = calculateDistanceToFlyoutPoint(); + /// invert the first edge according to the angle center + gp_Pnt aCenter = CenterPoint(); + gp_Pnt aFirst = FirstPoint(); + gp_Pnt aSecond = SecondPoint(); + double anEdge1Length = aCenter.Distance(aFirst); + aFirst = aCenter.Translated (gp_Vec(aCenter, aFirst).Normalized() * (-anEdge1Length)); + anEdge1Length = aCenter.Distance(aFirst); + + SetMeasuredGeometry(aFirst, aCenter, aSecond); } break; case SketcherPrs_Tools::ANGLE_BACKWARD: { - SetGeometryOrientedAngle(true, true); - SetArrowVisible(Standard_False, Standard_True); + SetArrowVisible(Standard_False/*first*/, Standard_True/*second*/); + SetMeasuredGeometry(aEdge1, aEdge2); + bool isReversedPlanes = isAnglePlaneReversedToSketchPlane(); + SetAngleReversed(isReversedPlanes); } break; default: break; } - - - const gp_Pnt& aCenter = CenterPoint(); - const gp_Pnt& aFirst = FirstPoint(); - const gp_Pnt& aSecond = SecondPoint(); - - gp_Dir aBisector((aFirst.XYZ() + aSecond.XYZ()) * 0.5 - aCenter.XYZ()); - - gp_Pnt aFlyPnt(aFlyoutPnt->x(), aFlyoutPnt->y(), aFlyoutPnt->z()); - gp_XYZ aFlyDir = aFlyPnt.XYZ() - aCenter.XYZ(); - double aDist = aFlyDir.Dot(aBisector.XYZ()); - // make a positive distance in order to AIS angle presentation is not reversed - aDist = fabs(aDist); + if (aDist < 0) /// it was not calculated yet + aDist = calculateDistanceToFlyoutPoint(); SetFlyout(aDist); // Angle value is in degrees @@ -204,3 +200,38 @@ void SketcherPrs_Angle::ComputeSelection(const Handle(SelectMgr_Selection)& aSel } AIS_AngleDimension::ComputeSelection(aSelection, aMode); } + +bool SketcherPrs_Angle::isAnglePlaneReversedToSketchPlane() +{ + bool aReversed = false; + if (!myPlane.get()) + return aReversed; + + gp_Pln aPlane = GetPlane(); + gp_Dir aDir = aPlane.Axis().Direction(); + double aDot = myPlane->normal()->dot( + std::shared_ptr(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()))); + return aDot < 0; +} + +double SketcherPrs_Angle::calculateDistanceToFlyoutPoint() +{ + const gp_Pnt& aCenter = CenterPoint(); + const gp_Pnt& aFirst = FirstPoint(); + const gp_Pnt& aSecond = SecondPoint(); + + // Flyout point + DataPtr aData = myConstraint->data(); + std::shared_ptr aFlyoutAttr = + std::dynamic_pointer_cast + (aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); + std::shared_ptr aFlyoutPnt = myPlane->to3D(aFlyoutAttr->x(), aFlyoutAttr->y()); + + gp_Dir aBisector((aFirst.XYZ() + aSecond.XYZ()) * 0.5 - aCenter.XYZ()); + gp_Pnt aFlyPnt(aFlyoutPnt->x(), aFlyoutPnt->y(), aFlyoutPnt->z()); + gp_XYZ aFlyDir = aFlyPnt.XYZ() - aCenter.XYZ(); + double aDistance = aFlyDir.Dot(aBisector.XYZ()); + // make a positive distance in order to AIS angle presentation is not reversed + aDistance = fabs(aDistance); + return aDistance; +} diff --git a/src/SketcherPrs/SketcherPrs_Angle.h b/src/SketcherPrs/SketcherPrs_Angle.h index e178a1b8c..d2f4c3c35 100644 --- a/src/SketcherPrs/SketcherPrs_Angle.h +++ b/src/SketcherPrs/SketcherPrs_Angle.h @@ -51,6 +51,17 @@ protected: Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, const Standard_Integer aMode); + /// Checks is the angle plane has inverted direction of normal to the plane of current sketcher + /// Returns true if crossed product is negative. + /// \return bolean value + bool isAnglePlaneReversedToSketchPlane(); + + /// Calculates a distance between center of the angle presentation and the value of flyout point + /// attribute. It should be used after setting measured geometry for the angle presentation as + /// it uses calculated center/first/second point coordinates + /// \return real value + double calculateDistanceToFlyoutPoint(); + private: /// Constraint feature ModelAPI_Feature* myConstraint; -- 2.39.2