From 1ded0e810dc406dc9bc3abe7f470d06f0d74ff0e Mon Sep 17 00:00:00 2001 From: vsv Date: Wed, 5 Jul 2017 19:44:47 +0300 Subject: [PATCH] Issue #2208: Tangent constraint position implementation --- src/GeomAPI/GeomAPI_Curve.h | 3 + src/SketcherPrs/SketcherPrs_PositionMgr.cpp | 90 ++++++++++++++------- src/SketcherPrs/SketcherPrs_PositionMgr.h | 4 +- src/SketcherPrs/SketcherPrs_Tangent.cpp | 24 +++++- 4 files changed, 85 insertions(+), 36 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Curve.h b/src/GeomAPI/GeomAPI_Curve.h index 2d942dd7c..70bafd829 100644 --- a/src/GeomAPI/GeomAPI_Curve.h +++ b/src/GeomAPI/GeomAPI_Curve.h @@ -72,4 +72,7 @@ private: double myEnd; }; +//! Pointer on the object +typedef std::shared_ptr GeomCurvePtr; + #endif diff --git a/src/SketcherPrs/SketcherPrs_PositionMgr.cpp b/src/SketcherPrs/SketcherPrs_PositionMgr.cpp index d77e03013..1dbe75116 100644 --- a/src/SketcherPrs/SketcherPrs_PositionMgr.cpp +++ b/src/SketcherPrs/SketcherPrs_PositionMgr.cpp @@ -26,6 +26,10 @@ #include #include +#include +#include +#include + static SketcherPrs_PositionMgr* MyPosMgr = NULL; // The class is implemented as a singlton @@ -65,54 +69,78 @@ int SketcherPrs_PositionMgr::getPositionIndex(ObjectPtr theLine, } } -gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape, - const SketcherPrs_SymbolPrs* thePrs, - double theStep) + +gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP) { + gp_Vec aVec; std::shared_ptr aShape = SketcherPrs_Tools::getShape(theShape); - gp_Pnt aP; // Central point - gp_Vec aVec1; // main vector if (aShape->isEdge()) { std::shared_ptr aCurve = std::shared_ptr(new GeomAPI_Curve(aShape)); - std::shared_ptr aPnt1; // Start point of main vector - std::shared_ptr aPnt2; // End point of main vector - if (aCurve->isLine()) { - std::shared_ptr aEdge = - std::shared_ptr(new GeomAPI_Edge(aShape)); - aPnt1 = aEdge->firstPoint(); - aPnt2 = aEdge->lastPoint(); + if (aCurve->isCircle()) { + GeomEdgePtr aEdgePtr(new GeomAPI_Edge(aShape)); + GeomVertexPtr aVertexPtr(new GeomAPI_Vertex(theP.X(), theP.Y(), theP.Z())); + BRepExtrema_ExtPC aExtrema(aVertexPtr->impl(), + aEdgePtr->impl()); + int aNb = aExtrema.NbExt(); + if (aNb > 0) { + for (int i = 1; i <= aNb; i++) { + if (aExtrema.IsMin(i)) { + double aParam = aExtrema.Parameter(i); + Handle(Geom_Curve) aCurv = aCurve->impl(); + gp_Pnt aP; + aCurv->D1(aParam, aP, aVec); + break; + } + } + } + } else { + double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.; + GeomPointPtr aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.); + GeomPointPtr aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.); - // Find the middle point - aP = gp_Pnt((aPnt1->x() + aPnt2->x())/2., - (aPnt1->y() + aPnt2->y())/2., - (aPnt1->z() + aPnt2->z())/2.); + aVec = gp_Vec(aPnt1->impl(), aPnt2->impl()); + } + } else { + aVec = gp_Vec(theDir->impl()); + } + return aVec; +} - } else { +gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape, + const SketcherPrs_SymbolPrs* thePrs, + double theStep, GeomPointPtr thePnt) +{ + std::shared_ptr aShape = SketcherPrs_Tools::getShape(theShape); + gp_Pnt aP; // Central point + + if (thePnt.get()) { + aP = thePnt->impl(); + } else { + if (aShape->isEdge()) { + std::shared_ptr aCurve = + std::shared_ptr(new GeomAPI_Curve(aShape)); // this is a circle or arc double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.; std::shared_ptr aPnt = aCurve->getPoint(aMidParam); aP = aPnt->impl(); - - aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.); - aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.); + } else { + // This is a point + std::shared_ptr aVertex = + std::shared_ptr(new GeomAPI_Vertex(aShape)); + std::shared_ptr aPnt = aVertex->point(); + aP = aPnt->impl(); } - aVec1 = gp_Vec(aPnt1->impl(), aPnt2->impl()); - } else { - // This is a point - std::shared_ptr aVertex = - std::shared_ptr(new GeomAPI_Vertex(aShape)); - std::shared_ptr aPnt = aVertex->point(); - aP = aPnt->impl(); - - std::shared_ptr aDir = thePrs->plane()->dirX(); - aVec1 = gp_Vec(aDir->impl()); } + // main vector + gp_Vec aVec1 = getVector(theShape, thePrs->plane()->dirX(), aP); + // Compute shifting vector for a one symbol gp_Vec aShift = aVec1.Crossed(thePrs->plane()->normal()->impl()); aShift.Normalize(); - aShift.Multiply(theStep * 0.8); + // For point based symbols step = 1.2, for line based = 0.8 + aShift.Multiply(theStep * (thePnt.get()? 1.2 : 0.8)); // Shift the position coordinate according to position index int aPos = getPositionIndex(theShape, thePrs); diff --git a/src/SketcherPrs/SketcherPrs_PositionMgr.h b/src/SketcherPrs/SketcherPrs_PositionMgr.h index d9bb444ee..8de0204b4 100644 --- a/src/SketcherPrs/SketcherPrs_PositionMgr.h +++ b/src/SketcherPrs/SketcherPrs_PositionMgr.h @@ -24,6 +24,7 @@ #include "SketcherPrs_SymbolPrs.h" #include +#include #include #include @@ -44,7 +45,8 @@ public: /// \param theLine constrained object /// \param thePrs a presentation of constraint /// \param theStep step between symbols - gp_Pnt getPosition(ObjectPtr theLine, const SketcherPrs_SymbolPrs* thePrs, double theStep = 20); + gp_Pnt getPosition(ObjectPtr theLine, const SketcherPrs_SymbolPrs* thePrs, + double theStep = 20, GeomPointPtr thePnt = GeomPointPtr()); /// Deletes constraint object from internal structures. Has to be called on constraint delete. /// \param thePrs a constraint presentation diff --git a/src/SketcherPrs/SketcherPrs_Tangent.cpp b/src/SketcherPrs/SketcherPrs_Tangent.cpp index 5a7d2a538..74ee2ed69 100644 --- a/src/SketcherPrs/SketcherPrs_Tangent.cpp +++ b/src/SketcherPrs/SketcherPrs_Tangent.cpp @@ -68,13 +68,29 @@ bool SketcherPrs_Tangent::updateIfReadyToDisplay(double theStep, bool withColor) ObjectPtr aObj2 = SketcherPrs_Tools::getResult(myConstraint, SketchPlugin_Constraint::ENTITY_B()); + GeomShapePtr aShp1 = SketcherPrs_Tools::getShape(aObj1); + GeomShapePtr aShp2 = SketcherPrs_Tools::getShape(aObj2); + + GeomCurvePtr aCurv1 = std::shared_ptr(new GeomAPI_Curve(aShp1)); + GeomCurvePtr aCurv2 = std::shared_ptr(new GeomAPI_Curve(aShp2)); + + GeomPointPtr aPnt1_1 = aCurv1->getPoint(aCurv1->startParam()); + GeomPointPtr aPnt1_2 = aCurv1->getPoint(aCurv1->endParam()); + + GeomPointPtr aPnt2_1 = aCurv2->getPoint(aCurv2->startParam()); + GeomPointPtr aPnt2_2 = aCurv2->getPoint(aCurv2->endParam()); + + GeomPointPtr aPnt; + if (aPnt1_1->isEqual(aPnt2_1) || aPnt1_1->isEqual(aPnt2_2)) + aPnt = aPnt1_1; + else if (aPnt1_2->isEqual(aPnt2_1) || aPnt1_2->isEqual(aPnt2_2)) + aPnt = aPnt1_2; + // Compute points coordinates SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get(); - gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep); - gp_Pnt aP2 = aMgr->getPosition(aObj2, this, theStep); - myPntArray = new Graphic3d_ArrayOfPoints(2, withColor); + gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep, aPnt); + myPntArray = new Graphic3d_ArrayOfPoints(1, withColor); myPntArray->AddVertex(aP1); - myPntArray->AddVertex(aP2); return true; } -- 2.30.2