From: vsv Date: Wed, 26 Jul 2017 13:47:20 +0000 (+0300) Subject: Issue #2208: Intermediate solution X-Git-Tag: V_2.9.0~23^2~20 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6cb668e4755916586a775a0334d7e192f04beb27;p=modules%2Fshaper.git Issue #2208: Intermediate solution --- diff --git a/src/SketcherPrs/SketcherPrs_PositionMgr.cpp b/src/SketcherPrs/SketcherPrs_PositionMgr.cpp index c92f1a0ab..219cc31cc 100644 --- a/src/SketcherPrs/SketcherPrs_PositionMgr.cpp +++ b/src/SketcherPrs/SketcherPrs_PositionMgr.cpp @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -40,8 +42,12 @@ #include #include +#include + static SketcherPrs_PositionMgr* MyPosMgr = NULL; +#define PI 3.1415926535897932 + // The class is implemented as a singlton SketcherPrs_PositionMgr* SketcherPrs_PositionMgr::get() { @@ -80,6 +86,103 @@ int SketcherPrs_PositionMgr::getPositionIndex(ObjectPtr theLine, } +bool SketcherPrs_PositionMgr::isPntConstraint(const std::string& theName) +{ + static std::list aConstraints; + if (aConstraints.size() == 0) { + aConstraints.push_back(SketchPlugin_ConstraintTangent::ID()); + aConstraints.push_back(SketchPlugin_ConstraintPerpendicular::ID()); + } + std::list::const_iterator aIt; + for (aIt = aConstraints.cbegin(); aIt != aConstraints.cend(); ++aIt) { + if ((*aIt) == theName) + return true; + } + return false; +} + +bool containsPoint(const FeaturePtr& theFeature, GeomPnt2dPtr thePnt2d, GeomPointPtr thePos) +{ + if (theFeature->getKind() == SketchPlugin_Line::ID()) { + AttributePoint2DPtr aSPnt1 = std::dynamic_pointer_cast( + theFeature->data()->attribute(SketchPlugin_Line::START_ID())); + AttributePoint2DPtr aSPnt2 = std::dynamic_pointer_cast( + theFeature->data()->attribute(SketchPlugin_Line::END_ID())); + + GeomPnt2dPtr aPnt1 = aSPnt1->pnt(); + GeomPnt2dPtr aPnt2 = aSPnt2->pnt(); + + if (aPnt1->isEqual(thePnt2d) || aPnt2->isEqual(thePnt2d)) + return true; + } else if ((theFeature->getKind() == SketchPlugin_Circle::ID()) || + (theFeature->getKind() == SketchPlugin_Arc::ID())) { + GeomCurvePtr aCurve; + ObjectPtr aResObj; + std::list aResults = theFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) { + GeomShapePtr aShp = SketcherPrs_Tools::getShape((*aIt)); + if (aShp->isEdge()) { + aResObj = (*aIt); + aCurve = std::shared_ptr(new GeomAPI_Curve(aShp)); + break; + } + } + if (aCurve.get()) { + double aStart = aCurve->startParam(); + double aEnd = aCurve->endParam(); + GeomCirclePtr aCircle = GeomCirclePtr(new GeomAPI_Circ(aCurve)); + double aParam; + if (aCircle->parameter(thePos, 1.e-4, aParam) && (aParam >= aStart) && (aParam <= aEnd)) + return true; + } + } + return false; +} + +int SketcherPrs_PositionMgr::getPositionIndex(GeomPointPtr thePos, const SketcherPrs_SymbolPrs* thePrs) +{ + if (myPntShapes.count(thePrs->feature()) == 0) { + // Renumerate positions around the specified constraint point for all constraints + GeomAx3Ptr aAx3 = thePrs->plane(); + ModelAPI_CompositeFeature* aOwner = thePrs->sketcher(); + GeomPnt2dPtr aPnt2d = thePos->to2D(aAx3->origin(), aAx3->dirX(), aAx3->dirY()); + + int aNbSubs = aOwner->numberOfSubs(); + int aId = 0; + for (int i = 0; i < aNbSubs; i++) { + FeaturePtr aFeature = aOwner->subFeature(i); + + if (myPntShapes.count(aFeature.get()) == 1) { + myPntShapes[aFeature.get()] = aId; + aId++; + } else { + if (isPntConstraint(aFeature->getKind())) { + DataPtr aData = aFeature->data(); + AttributeRefAttrPtr aObjRef = aData->refattr(SketchPlugin_Constraint::ENTITY_A()); + FeaturePtr aObj = ModelAPI_Feature::feature(aObjRef->object()); + bool aContains = false; + if (containsPoint(aObj, aPnt2d, thePos)) { + aContains = true; + } else { + aObjRef = aData->refattr(SketchPlugin_Constraint::ENTITY_B()); + aObj = ModelAPI_Feature::feature(aObjRef->object()); + if (containsPoint(aObj, aPnt2d, thePos)) { + aContains = true; + } + } + if (aContains) { + myPntShapes[aFeature.get()] = aId; + aId++; + } + } + } + } + } + return myPntShapes[thePrs->feature()]; +} + + gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP) { gp_Vec aVec; @@ -106,9 +209,8 @@ gp_Vec getVector(ObjectPtr theShape, GeomDirPtr theDir, gp_Pnt theP) } } } else { - double aMidParam = (aCurve->startParam() + aCurve->endParam()) / 2.; - GeomPointPtr aPnt1 = aCurve->getPoint((aMidParam + aCurve->endParam()) / 2.); - GeomPointPtr aPnt2 = aCurve->getPoint((aMidParam + aCurve->startParam()) / 2.); + GeomPointPtr aPnt1 = aCurve->getPoint(aCurve->endParam()); + GeomPointPtr aPnt2 = aCurve->getPoint(aCurve->startParam()); gp_Pnt aPn2 = aPnt2->impl(); if (aPn2.IsEqual(theP, Precision::Confusion())) @@ -199,6 +301,9 @@ std::list getCurves(const GeomPointPtr& thePnt, const SketcherPrs_Sym int aNbSubs = aOwner->numberOfSubs(); for (int i = 0; i < aNbSubs; i++) { FeaturePtr aFeature = aOwner->subFeature(i); + if (!aFeature->firstResult().get()) // There is no result + continue; + if (aFeature->getKind() == SketchPlugin_Line::ID()) { AttributePoint2DPtr aSPnt1 = std::dynamic_pointer_cast( aFeature->data()->attribute(SketchPlugin_Line::START_ID())); @@ -245,32 +350,73 @@ gp_Pnt SketcherPrs_PositionMgr::getPointPosition( ObjectPtr theLine, const SketcherPrs_SymbolPrs* thePrs, double theStep, GeomPointPtr thePnt) { - std::list aCurves = getCurves(thePnt, thePrs); - gp_Pnt aP = thePnt->impl(); - //gp_Vec aVec1 = getVector(theLine, thePrs->plane()->dirX(), aP); - std::list aVectors; + GeomDirPtr aNormal = thePrs->plane()->normal(); + gp_Dir aNormDir = aNormal->impl(); + + std::list aCurves = getCurves(thePnt, thePrs); std::list::const_iterator aItCurv; + std::list aVectorsList; + // Calculate all vectors for (aItCurv = aCurves.cbegin(); aItCurv != aCurves.cend(); aItCurv++) { - ObjectPtr aObject = (*aItCurv); - gp_Vec aVec = getVector(aObject, thePrs->plane()->dirX(), aP); - aVectors.push_back(aVec); + aVectorsList.push_back(getVector((*aItCurv), thePrs->plane()->dirX(), aP)); } - gp_Vec aBase = getVector(theLine, thePrs->plane()->dirX(), aP); - std::list aAngles; std::list::const_iterator aItVec; - for (aItVec = aVectors.cbegin(); aItVec != aVectors.cend(); aItVec++) { - gp_Vec aVec = (*aItVec); - double aAngle = aBase.Angle(aVec); - aAngles.push_back(aAngle); + std::map aAngVectors; + // 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; + double aMinAng = 0; + gp_Vec aVec = *aItVec; + for (aIt = aVectorsList.cbegin(); aIt != aVectorsList.cend(); aIt++) { + double aAng = aVec.AngleWithRef(*aIt, aNormDir); + if (aAng != 0) { + if (aAng < 0) + aAng = 2 * PI + aAng; + + if (aMinAng == 0) + aMinAng = aAng; + else if (aAng < aMinAng) { + aMinAng = aAng; + } + } + } + aAngVectors[aMinAng] = aVec; } - // Compute shifting vector for a one symbol - //gp_Vec aShift = aVec1.Crossed(thePrs->plane()->normal()->impl()); - //aShift.Normalize(); - //aShift.Multiply(theStep * 1.5); - //aP.Translate(aShift); - return aP; + + // 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 + 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; + 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); + } + aPosId += Nb; + } + } + gp_Vec aShift = aPrevVec.Rotated(aRotAx, aAngleStep); + aShift.Normalize(); + aShift.Multiply(theStep * 1.5); + return aP.Translated(aShift); } //***************************************************************** diff --git a/src/SketcherPrs/SketcherPrs_PositionMgr.h b/src/SketcherPrs/SketcherPrs_PositionMgr.h index 272092989..34529101a 100644 --- a/src/SketcherPrs/SketcherPrs_PositionMgr.h +++ b/src/SketcherPrs/SketcherPrs_PositionMgr.h @@ -61,17 +61,33 @@ private: /// \param thePrs a presentation of constraint int getPositionIndex(ObjectPtr theLine, const SketcherPrs_SymbolPrs* thePrs); + /// 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); + + /// Returns position of a constraint around a point + /// \param theLine a base object of the constraint + /// \param thePrs a presentation of the constraint symbol + /// \param theStep step from base point + /// \param thePnt a base point gp_Pnt getPointPosition(ObjectPtr theLine, const SketcherPrs_SymbolPrs* thePrs, double theStep, GeomPointPtr thePnt); + static bool isPntConstraint(const std::string& theName); + private: typedef std::map PositionsMap; + typedef std::map FeaturesMap; /// The map which contains position of presentation PositionsMap myIndexes; /// The map contains position index std::map myShapes; + + /// The map contains position of index for constraints around a point + FeaturesMap myPntShapes; }; #endif \ No newline at end of file