From 270e4178cb9832ee53cdd8e31bc4cdedd81e201c Mon Sep 17 00:00:00 2001 From: vsv Date: Thu, 27 Jul 2017 14:35:35 +0300 Subject: [PATCH] Issue #2208: Stable solution. --- src/SketcherPrs/SketcherPrs_PositionMgr.cpp | 89 +++++++++++++-------- src/SketcherPrs/SketcherPrs_PositionMgr.h | 6 +- src/SketcherPrs/SketcherPrs_Tangent.cpp | 19 +++-- 3 files changed, 74 insertions(+), 40 deletions(-) diff --git a/src/SketcherPrs/SketcherPrs_PositionMgr.cpp b/src/SketcherPrs/SketcherPrs_PositionMgr.cpp index 51796972c..65b1d0451 100644 --- a/src/SketcherPrs/SketcherPrs_PositionMgr.cpp +++ b/src/SketcherPrs/SketcherPrs_PositionMgr.cpp @@ -140,7 +140,7 @@ bool containsPoint(const FeaturePtr& theFeature, GeomPnt2dPtr thePnt2d, GeomPoin return false; } -int SketcherPrs_PositionMgr::getPositionIndex(GeomPointPtr thePos, +const std::array& SketcherPrs_PositionMgr::getPositionIndex(GeomPointPtr thePos, const SketcherPrs_SymbolPrs* thePrs) { if (myPntShapes.count(thePrs->feature()) == 0) { @@ -151,12 +151,14 @@ int SketcherPrs_PositionMgr::getPositionIndex(GeomPointPtr thePos, int aNbSubs = aOwner->numberOfSubs(); int aId = 0; + std::list aFeaList; for (int i = 0; i < aNbSubs; i++) { FeaturePtr aFeature = aOwner->subFeature(i); if (myPntShapes.count(aFeature.get()) == 1) { - myPntShapes[aFeature.get()] = aId; + myPntShapes[aFeature.get()][0] = aId; aId++; + aFeaList.push_back(aFeature.get()); } else { if (isPntConstraint(aFeature->getKind())) { DataPtr aData = aFeature->data(); @@ -173,17 +175,23 @@ int SketcherPrs_PositionMgr::getPositionIndex(GeomPointPtr thePos, } } if (aContains) { - myPntShapes[aFeature.get()] = aId; + myPntShapes[aFeature.get()][0] = aId; aId++; + aFeaList.push_back(aFeature.get()); } } } } + int aSize = (int) aFeaList.size(); + std::list::const_iterator aIt; + for (aIt = aFeaList.cbegin(); aIt != aFeaList.cend(); aIt++) { + myPntShapes[*aIt][1] = aSize; + } } return myPntShapes[thePrs->feature()]; } - +//***************************************************************** gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP) { gp_Vec aVec; @@ -225,6 +233,7 @@ gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP) return aVec; } +//***************************************************************** gp_Pnt SketcherPrs_PositionMgr::getPosition(ObjectPtr theShape, const SketcherPrs_SymbolPrs* thePrs, double theStep, GeomPointPtr thePnt) @@ -363,8 +372,15 @@ gp_Pnt SketcherPrs_PositionMgr::getPointPosition( aVectorsList.push_back(getVector((*aItCurv), thePrs->plane()->dirX(), aP)); } + // Position of the symbol + const std::array& aPos = getPositionIndex(thePnt, thePrs); + + // Angle size of a symbol + double aAngleStep = PI * 50./180.; + std::list::const_iterator aItVec; - std::map aAngVectors; + std::list aAngles; + std::list aVectors; // Select closest vectors and calculate angles between base vector and closest vector for (aItVec = aVectorsList.cbegin(); aItVec != aVectorsList.cend(); aItVec++) { std::list::const_iterator aIt; @@ -383,41 +399,48 @@ gp_Pnt SketcherPrs_PositionMgr::getPointPosition( } } } - aAngVectors[aMinAng] = aVec; + aVectors.push_back(aVec); + aAngles.push_back(aMinAng); } - // Angle size of a symbol for a first level - static const double aAngleStep = PI * 50./180.; - - // Position of the symbol - int aPos = getPositionIndex(thePnt, thePrs); - - //std::list::const_iterator aItAng; - gp_Ax1 aRotAx(aP, aNormDir); - int aPosId = 0; // Last used position + int aPosCount = 0; double aAng; - gp_Vec aPrevVec; - std::map::const_iterator aItAng; - for (aItAng = aAngVectors.cbegin(); aItAng != aAngVectors.cend(); ++aItAng) { - aAng = aItAng->first; - aPrevVec = aItAng->second; - if (aAng >= aAngleStep) { - gp_Vec aShift; + std::list::const_iterator aItAng; + + double aAngPos; + gp_Vec aVecPos; + bool aHasPlace = false; + int aIntId = 0; // a position inside a one sector + while (aPosCount < aPos[1]) { + for (aItAng = aAngles.cbegin(), aItVec = aVectors.cbegin(); + aItAng != aAngles.cend(); ++aItAng, ++aItVec) { + aAng = (*aItAng); int Nb = int(aAng / aAngleStep); - if ((aPos >= aPosId) && (aPos < (aPosId + Nb))) { - // rotate base vector on a necessary angle - aShift = aPrevVec.Rotated(aRotAx, aAngleStep + aAngleStep * (aPos - aPosId)); - aShift.Normalize(); - aShift.Multiply(theStep * 1.5); - return aP.Translated(aShift); + aPosCount += Nb; + + if ((!aHasPlace) && (aPosCount >= (aPos[0] + 1))) { + aHasPlace = true; + aAngPos = (*aItAng); + aVecPos = (*aItVec); + aIntId = aPos[0] - (aPosCount - Nb); } - aPosId += Nb; + } + if (aPosCount < aPos[1]) { + aAngleStep -= 0.1; + aHasPlace = false; + aPosCount = 0; } } - gp_Vec aShift = aPrevVec.Rotated(aRotAx, aAngleStep); - aShift.Normalize(); - aShift.Multiply(theStep * 1.5); - return aP.Translated(aShift); + + gp_Ax1 aRotAx(aP, aNormDir); + if (aHasPlace) { + // rotate base vector on a necessary angle + gp_Vec aShift = aVecPos.Rotated(aRotAx, aAngleStep + aAngleStep * aIntId); + aShift.Normalize(); + aShift.Multiply(theStep * 1.5); + return aP.Translated(aShift); + } + return aP; } //***************************************************************** diff --git a/src/SketcherPrs/SketcherPrs_PositionMgr.h b/src/SketcherPrs/SketcherPrs_PositionMgr.h index 34529101a..8695126b2 100644 --- a/src/SketcherPrs/SketcherPrs_PositionMgr.h +++ b/src/SketcherPrs/SketcherPrs_PositionMgr.h @@ -29,6 +29,7 @@ #include #include +#include /** * \ingroup GUI @@ -64,7 +65,8 @@ private: /// Returns position index of the given constraint around a point /// \param theLine constrained object /// \param thePrs a presentation of constraint - int getPositionIndex(GeomPointPtr thePos, const SketcherPrs_SymbolPrs* thePrs); + const std::array& getPositionIndex(GeomPointPtr thePos, + const SketcherPrs_SymbolPrs* thePrs); /// Returns position of a constraint around a point /// \param theLine a base object of the constraint @@ -78,7 +80,7 @@ private: private: typedef std::map PositionsMap; - typedef std::map FeaturesMap; + typedef std::map> FeaturesMap; /// The map which contains position of presentation PositionsMap myIndexes; diff --git a/src/SketcherPrs/SketcherPrs_Tangent.cpp b/src/SketcherPrs/SketcherPrs_Tangent.cpp index 8e10430b3..ae29e259d 100644 --- a/src/SketcherPrs/SketcherPrs_Tangent.cpp +++ b/src/SketcherPrs/SketcherPrs_Tangent.cpp @@ -98,14 +98,23 @@ bool SketcherPrs_Tangent::updateIfReadyToDisplay(double theStep, bool withColor) GeomPointPtr aPnt; if (aCircle->parameter(aPnt1, 1.e-4, aParam) && (aParam >= aFirst) && (aParam <= aLast)) aPnt = aPnt1; - else + else if (aCircle->parameter(aPnt2, 1.e-4, aParam) && (aParam >= aFirst) && (aParam <= aLast)) aPnt = aPnt2; // Compute points coordinates - SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get(); - gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep, aPnt); - myPntArray = new Graphic3d_ArrayOfPoints(1, withColor); - myPntArray->AddVertex(aP1); + if (aPnt.get()) { + SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get(); + gp_Pnt aP1 = aMgr->getPosition(aObj1, this, theStep, aPnt); + myPntArray = new Graphic3d_ArrayOfPoints(1, withColor); + myPntArray->AddVertex(aP1); + } else { + 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); + myPntArray->AddVertex(aP1); + myPntArray->AddVertex(aP2); + } return true; } -- 2.39.2