X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Fillet.cpp;h=cb856fdc8bc03e6dde57bf87f887cf754ca6a2f6;hb=b5893b0a30fac08134c24de4565cb513a43affa6;hp=6456d7b8c922bd28ab388062375b28de8c43a38b;hpb=61f1e2eb9bd37376d587b5cb2aa317586e89a261;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Fillet.cpp b/src/SketchPlugin/SketchPlugin_Fillet.cpp index 6456d7b8c..cb856fdc8 100644 --- a/src/SketchPlugin/SketchPlugin_Fillet.cpp +++ b/src/SketchPlugin/SketchPlugin_Fillet.cpp @@ -13,6 +13,7 @@ #include "SketchPlugin_ConstraintEqual.h" #include "SketchPlugin_ConstraintCoincidence.h" #include "SketchPlugin_ConstraintLength.h" +#include "SketchPlugin_ConstraintMiddle.h" #include "SketchPlugin_ConstraintTangent.h" #include "SketchPlugin_ConstraintRadius.h" #include "SketchPlugin_Tools.h" @@ -24,6 +25,7 @@ #include #include +#include #include #include @@ -46,22 +48,19 @@ const double PI = 3.141592653589793238463; static void recalculateAttributes(FeaturePtr theNewArc, const std::string& theNewArcAttribute, FeaturePtr theFeature, const std::string& theFeatureAttribute); + +/// \brief Calculate radius of a fillet. +/// It should not be greater than 1/3 of shortest edge length. +static double calculateFilletRadius(FeaturePtr theFilletFeatures[2]); + /// \brief Calculates center of fillet arc and coordinates of tangency points -static void calculateFilletCenter(FeaturePtr theFeatureA, FeaturePtr theFeatureB, - double theRadius, bool theNotInversed[2], +static void calculateFilletCenter(FeaturePtr theFilletFeatures[2], + double theFilletRadius, + const std::shared_ptr& theSketchPlane, std::shared_ptr& theCenter, std::shared_ptr& theTangentA, std::shared_ptr& theTangentB); -/// Get point on 1/3 length of edge from fillet point -static void getPointOnEdge(const FeaturePtr theFeature, - const std::shared_ptr theFilletPoint, - std::shared_ptr& thePoint); - -/// Get distance from point to feature -static double getProjectionDistance(const FeaturePtr theFeature, - const std::shared_ptr thePoint); - /// Get coincide edges for fillet static std::set getCoincides(const FeaturePtr& theConstraintCoincidence); @@ -86,6 +85,9 @@ void SketchPlugin_Fillet::execute() if (isUpdateFlushed) Events_Loop::loop()->setFlushed(anUpdateEvent, false); + // set flag here to avoid building Fillet presentation if "Redisplay" event appears + myFilletCreated = true; + // Calculate Fillet parameters if does not yet if (!myBaseFeatures[0] || !myBaseFeatures[1]) calculateFilletParameters(); @@ -180,8 +182,6 @@ void SketchPlugin_Fillet::execute() if(isUpdateFlushed) { Events_Loop::loop()->setFlushed(anUpdateEvent, true); } - - myFilletCreated = true; } AISObjectPtr SketchPlugin_Fillet::getAISObject(AISObjectPtr thePrevious) @@ -233,18 +233,8 @@ bool SketchPlugin_Fillet::calculateFilletParameters() return false; } - // Getting points located at 1/3 of edge length from fillet point. std::shared_ptr aFilletPnt2d = aFilletPoint2D->pnt(); - std::shared_ptr aPnt1, aPnt2; - getPointOnEdge(myBaseFeatures[0], aFilletPnt2d, aPnt1); - getPointOnEdge(myBaseFeatures[1], aFilletPnt2d, aPnt2); - - /// Getting distances. - double aDistance1 = getProjectionDistance(myBaseFeatures[1], aPnt1); - double aDistance2 = getProjectionDistance(myBaseFeatures[0], aPnt2); - - // Calculate radius value for fillet. - double aRadius = aDistance1 < aDistance2 ? aDistance1 / 2.0 : aDistance2 / 2.0; + double aRadius = calculateFilletRadius(myBaseFeatures); // Calculate arc attributes. static const int aNbFeatures = 2; @@ -277,8 +267,9 @@ bool SketchPlugin_Fillet::calculateFilletParameters() } } - calculateFilletCenter(myBaseFeatures[0], myBaseFeatures[1], aRadius, - myIsNotInversed, myCenterXY, myTangentXY1, myTangentXY2); + std::shared_ptr aSketchPlane = SketchPlugin_Sketch::plane(sketch()); + calculateFilletCenter(myBaseFeatures, aRadius, aSketchPlane, + myCenterXY, myTangentXY1, myTangentXY2); // Tangent directions of the features in coincident point. std::shared_ptr aTangentDir[aNbFeatures]; @@ -376,351 +367,88 @@ void recalculateAttributes(FeaturePtr theNewArc, const std::string& theNewArcAt theFeature->attribute(theFeatureAttribute))->setValue(anArcPoint->x(), anArcPoint->y()); } -/// \brief Find intersections of lines shifted along normal direction -void possibleFilletCenterLineLine( - std::shared_ptr thePointA, std::shared_ptr theDirA, - std::shared_ptr thePointB, std::shared_ptr theDirB, - double theRadius, std::list< std::shared_ptr >& theCenters) +static std::shared_ptr toPoint(const AttributePtr& theAttribute) { - std::shared_ptr aDirAT(new GeomAPI_Dir2d(-theDirA->y(), theDirA->x())); - std::shared_ptr aDirBT(new GeomAPI_Dir2d(-theDirB->y(), theDirB->x())); - std::shared_ptr aPntA, aPntB; - double aDet = theDirA->cross(theDirB); - for (double aStepA = -1.0; aStepA <= 1.0; aStepA += 2.0) { - aPntA = thePointA->added(aDirAT->xy()->multiplied(aStepA * theRadius)); - for (double aStepB = -1.0; aStepB <= 1.0; aStepB += 2.0) { - aPntB = thePointB->added(aDirBT->xy()->multiplied(aStepB * theRadius)); - double aVX = aDirAT->xy()->dot(aPntA); - double aVY = aDirBT->xy()->dot(aPntB); - std::shared_ptr aPoint(new GeomAPI_XY( - (theDirB->x() * aVX - theDirA->x() * aVY) / aDet, - (theDirB->y() * aVX - theDirA->y() * aVY) / aDet)); - theCenters.push_back(aPoint); - } - } + std::shared_ptr aPoint; + AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast(theAttribute); + if (aPointAttr) + aPoint = aPointAttr->pnt(); + return aPoint; } -/// \brief Find intersections of line shifted along normal direction in both sides -/// and a circle with extended radius -void possibleFilletCenterLineArc( - std::shared_ptr theStartLine, std::shared_ptr theDirLine, - std::shared_ptr theCenterArc, double theRadiusArc, - double theRadius, std::list< std::shared_ptr >& theCenters) +static std::shared_ptr toLine(const FeaturePtr& theFeature) { - std::shared_ptr aDirT(new GeomAPI_Dir2d(-theDirLine->y(), theDirLine->x())); - std::shared_ptr aPnt; - double aDirNorm2 = theDirLine->dot(theDirLine); - double aRad = 0.0; - double aDirX = theDirLine->x(); - double aDirX2 = theDirLine->x() * theDirLine->x(); - double aDirY2 = theDirLine->y() * theDirLine->y(); - double aDirXY = theDirLine->x() * theDirLine->y(); - for (double aStepA = -1.0; aStepA <= 1.0; aStepA += 2.0) { - aPnt = theStartLine->added(aDirT->xy()->multiplied(aStepA * theRadius)); - double aCoeff = aDirT->xy()->dot(aPnt->decreased(theCenterArc)); - double aCoeff2 = aCoeff * aCoeff; - for (double aStepB = -1.0; aStepB <= 1.0; aStepB += 2.0) { - aRad = theRadiusArc + aStepB * theRadius; - double aD = aRad * aRad * aDirNorm2 - aCoeff2; - if (aD < 0.0) - continue; - double aDs = sqrt(aD); - double x1 = theCenterArc->x() + (aCoeff * aDirT->x() - aDirT->y() * aDs) / aDirNorm2; - double x2 = theCenterArc->x() + (aCoeff * aDirT->x() + aDirT->y() * aDs) / aDirNorm2; - double y1 = (aDirX2 * aPnt->y() + aDirY2 * theCenterArc->y() - - aDirXY * (aPnt->x() - theCenterArc->x()) - theDirLine->y() * aDs) / aDirNorm2; - double y2 = (aDirX2 * aPnt->y() + aDirY2 * theCenterArc->y() - - aDirXY * (aPnt->x() - theCenterArc->x()) + theDirLine->y() * aDs) / aDirNorm2; - - std::shared_ptr aPoint1(new GeomAPI_XY(x1, y1)); - theCenters.push_back(aPoint1); - std::shared_ptr aPoint2(new GeomAPI_XY(x2, y2)); - theCenters.push_back(aPoint2); - } + std::shared_ptr aLine; + if (theFeature->getKind() == SketchPlugin_Line::ID()) { + std::shared_ptr aStart = + toPoint( theFeature->attribute(SketchPlugin_Line::START_ID()) ); + std::shared_ptr aEnd = + toPoint( theFeature->attribute(SketchPlugin_Line::END_ID()) ); + aLine = std::shared_ptr(new GeomAPI_Lin2d(aStart, aEnd)); } + return aLine; } -/// \brief Find intersections of two circles with extended radii -void possibleFilletCenterArcArc( - std::shared_ptr theCenterA, double theRadiusA, - std::shared_ptr theCenterB, double theRadiusB, - double theRadius, std::list< std::shared_ptr >& theCenters) +static std::shared_ptr toCircle(const FeaturePtr& theFeature) { - std::shared_ptr aCenterDir = theCenterB->decreased(theCenterA); - double aCenterDist2 = aCenterDir->dot(aCenterDir); - double aCenterDist = sqrt(aCenterDist2); - - double aRadA, aRadB; - for (double aStepA = -1.0; aStepA <= 1.0; aStepA += 2.0) { - aRadA = theRadiusA + aStepA * theRadius; - for (double aStepB = -1.0; aStepB <= 1.0; aStepB += 2.0) { - aRadB = theRadiusB + aStepB * theRadius; - if (aRadA + aRadB < aCenterDist || fabs(aRadA - aRadB) > aCenterDist) - continue; // there is no intersections - - double aMedDist = (aRadA * aRadA - aRadB * aRadB + aCenterDist2) / (2.0 * aCenterDist); - double aHeight = sqrt(aRadA * aRadA - aMedDist * aMedDist); - - double x1 = theCenterA->x() + - (aMedDist * aCenterDir->x() + aCenterDir->y() * aHeight) / aCenterDist; - double y1 = theCenterA->y() + - (aMedDist * aCenterDir->y() - aCenterDir->x() * aHeight) / aCenterDist; - - double x2 = theCenterA->x() + - (aMedDist * aCenterDir->x() - aCenterDir->y() * aHeight) / aCenterDist; - double y2 = theCenterA->y() + - (aMedDist * aCenterDir->y() + aCenterDir->x() * aHeight) / aCenterDist; - - std::shared_ptr aPoint1(new GeomAPI_XY(x1, y1)); - theCenters.push_back(aPoint1); - std::shared_ptr aPoint2(new GeomAPI_XY(x2, y2)); - theCenters.push_back(aPoint2); - } + std::shared_ptr aCircle; + if (theFeature->getKind() == SketchPlugin_Arc::ID()) { + std::shared_ptr aCenter = + toPoint( theFeature->attribute(SketchPlugin_Arc::CENTER_ID()) ); + std::shared_ptr aStart = + toPoint( theFeature->attribute(SketchPlugin_Arc::START_ID()) ); + aCircle = std::shared_ptr(new GeomAPI_Circ2d(aCenter, aStart)); } + return aCircle; } -void calculateFilletCenter(FeaturePtr theFeatureA, FeaturePtr theFeatureB, - double theRadius, bool theNotInversed[2], + +void calculateFilletCenter(FeaturePtr theFilletFeatures[2], + double theFilletRadius, + const std::shared_ptr& theSketchPlane, std::shared_ptr& theCenter, std::shared_ptr& theTangentA, std::shared_ptr& theTangentB) { - static const int aNbFeatures = 2; - FeaturePtr aFeature[aNbFeatures] = {theFeatureA, theFeatureB}; - std::shared_ptr aStart[aNbFeatures], aEnd[aNbFeatures], aCenter[aNbFeatures]; - std::shared_ptr aStartPoint, aEndPoint; - - for (int i = 0; i < aNbFeatures; i++) { - if (aFeature[i]->getKind() == SketchPlugin_Line::ID()) { - aStartPoint = std::dynamic_pointer_cast( - aFeature[i]->attribute(SketchPlugin_Line::START_ID())); - aEndPoint = std::dynamic_pointer_cast( - aFeature[i]->attribute(SketchPlugin_Line::END_ID())); - } else if (aFeature[i]->getKind() == SketchPlugin_Arc::ID()) { - aStartPoint = std::dynamic_pointer_cast( - aFeature[i]->attribute(SketchPlugin_Arc::START_ID())); - aEndPoint = std::dynamic_pointer_cast( - aFeature[i]->attribute(SketchPlugin_Arc::END_ID())); - aCenter[i] = std::dynamic_pointer_cast( - aFeature[i]->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt()->xy(); - } else - return; - aStart[i] = std::shared_ptr(theNotInversed[i] ? - new GeomAPI_XY(aStartPoint->x(), aStartPoint->y()) : - new GeomAPI_XY(aEndPoint->x(), aEndPoint->y())); - aEnd[i] = std::shared_ptr(theNotInversed[i] ? - new GeomAPI_XY(aEndPoint->x(), aEndPoint->y()) : - new GeomAPI_XY(aStartPoint->x(), aStartPoint->y())); - } - - if (theFeatureA->getKind() == SketchPlugin_Line::ID() && - theFeatureB->getKind() == SketchPlugin_Line::ID()) { - std::shared_ptr aDir[2]; - std::shared_ptr aDirT[2]; - for (int i = 0; i < aNbFeatures; i++) { - aDir[i] = std::shared_ptr(new GeomAPI_Dir2d(aEnd[i]->decreased(aStart[i]))); - aDirT[i] = std::shared_ptr(new GeomAPI_Dir2d(-aDir[i]->y(), aDir[i]->x())); - } - - // get and filter possible centers - std::list< std::shared_ptr > aSuspectCenters; - possibleFilletCenterLineLine(aStart[0], aDir[0], aStart[1], aDir[1], - theRadius, aSuspectCenters); - double aDot = 0.0; - std::list< std::shared_ptr >::iterator anIt = aSuspectCenters.begin(); - for (; anIt != aSuspectCenters.end(); anIt++) { - aDot = aDirT[0]->xy()->dot(aStart[0]->decreased(*anIt)); - theTangentA = (*anIt)->added(aDirT[0]->xy()->multiplied(aDot)); - if (theTangentA->decreased(aStart[0])->dot(aDir[0]->xy()) < 0.0) - continue; // incorrect position - aDot = aDirT[1]->xy()->dot(aStart[1]->decreased(*anIt)); - theTangentB = (*anIt)->added(aDirT[1]->xy()->multiplied(aDot)); - if (theTangentB->decreased(aStart[1])->dot(aDir[1]->xy()) < 0.0) - continue; // incorrect position - // the center is found, stop searching - theCenter = *anIt; - return; - } - } else if ((theFeatureA->getKind() == SketchPlugin_Arc::ID() && - theFeatureB->getKind() == SketchPlugin_Line::ID()) || - (theFeatureA->getKind() == SketchPlugin_Line::ID() && - theFeatureB->getKind() == SketchPlugin_Arc::ID())) { - int aLineInd = theFeatureA->getKind() == SketchPlugin_Line::ID() ? 0 : 1; - double anArcRadius = aStart[1-aLineInd]->distance(aCenter[1-aLineInd]); - std::shared_ptr aDirLine = std::shared_ptr( - new GeomAPI_Dir2d(aEnd[aLineInd]->decreased(aStart[aLineInd]))); - std::shared_ptr aDirT = std::shared_ptr( - new GeomAPI_Dir2d(-aDirLine->y(), aDirLine->x())); - - std::shared_ptr aStartArcDir = std::shared_ptr( - new GeomAPI_Dir2d(aStart[1-aLineInd]->decreased(aCenter[1-aLineInd]))); - std::shared_ptr aEndArcDir = std::shared_ptr( - new GeomAPI_Dir2d(aEnd[1-aLineInd]->decreased(aCenter[1-aLineInd]))); - double anArcAngle = aStartArcDir->angle(aEndArcDir); - if (anArcAngle < 0.0) - anArcAngle += 2.0 * PI; - - // get possible centers and filter them - std::list< std::shared_ptr > aSuspectCenters; - possibleFilletCenterLineArc(aStart[aLineInd], aDirLine, aCenter[1-aLineInd], - anArcRadius, theRadius, aSuspectCenters); - double aDot = 0.0; - // the line is forward into the arc - double innerArc = aCenter[1-aLineInd]->decreased(aStart[aLineInd])->dot(aDirLine->xy()); - std::shared_ptr aLineTgPoint, anArcTgPoint; - // The possible centers are ranged by their positions. - // If the point is not satisfy one of criteria, the weight is decreased with penalty. - int aBestWeight = 0; - std::list< std::shared_ptr >::iterator anIt = aSuspectCenters.begin(); - for (; anIt != aSuspectCenters.end(); anIt++) { - int aWeight = 2; - aDot = aDirT->xy()->dot(aStart[aLineInd]->decreased(*anIt)); - aLineTgPoint = (*anIt)->added(aDirT->xy()->multiplied(aDot)); - // Check the point is placed on the correct arc (penalty if false) - if (aCenter[1-aLineInd]->distance(*anIt) * innerArc > anArcRadius * innerArc) - aWeight -= 1; - std::shared_ptr aCurDir = std::shared_ptr( - new GeomAPI_Dir2d((*anIt)->decreased(aCenter[1-aLineInd]))); - double aCurAngle = aStartArcDir->angle(aCurDir); - if (aCurAngle < 0.0) - aCurAngle += 2.0 * PI; - if (aCurAngle < 0.0 || aCurAngle > anArcAngle) - continue; - if (aWeight > aBestWeight) - aBestWeight = aWeight; - else if (aWeight < aBestWeight || - aStart[aLineInd]->distance(*anIt) > - aStart[aLineInd]->distance(theCenter)) // <-- take closer point - continue; - // the center is found, stop searching - theCenter = *anIt; - anArcTgPoint = aCenter[1-aLineInd]->added(aCurDir->xy()->multiplied(anArcRadius)); - if (theFeatureA->getKind() == SketchPlugin_Line::ID()) { - theTangentA = aLineTgPoint; - theTangentB = anArcTgPoint; - } else { - theTangentA = anArcTgPoint; - theTangentB = aLineTgPoint; - } - //return; - } - } else if (theFeatureA->getKind() == SketchPlugin_Arc::ID() && - theFeatureB->getKind() == SketchPlugin_Arc::ID()) { - double anArcRadius[aNbFeatures]; - double anArcAngle[aNbFeatures]; - std::shared_ptr aStartArcDir[aNbFeatures]; - for (int i = 0; i < aNbFeatures; i++) { - anArcRadius[i] = aStart[i]->distance(aCenter[i]); - aStartArcDir[i] = std::shared_ptr( - new GeomAPI_Dir2d(aStart[i]->decreased(aCenter[i]))); - std::shared_ptr aEndArcDir = std::shared_ptr( - new GeomAPI_Dir2d(aEnd[i]->decreased(aCenter[i]))); - anArcAngle[i] = aStartArcDir[i]->angle(aEndArcDir); - if (anArcAngle[i] < 0.0) - anArcAngle[i] += 2.0 * PI; - } - - // get and filter possible centers - std::list< std::shared_ptr > aSuspectCenters; - possibleFilletCenterArcArc(aCenter[0], anArcRadius[0], aCenter[1], - anArcRadius[1], theRadius, aSuspectCenters); - double aDot = 0.0; - std::shared_ptr aLineTgPoint, anArcTgPoint; - std::list< std::shared_ptr >::iterator anIt = aSuspectCenters.begin(); - for (; anIt != aSuspectCenters.end(); anIt++) { - std::shared_ptr aCurDir = std::shared_ptr( - new GeomAPI_Dir2d((*anIt)->decreased(aCenter[0]))); - double aCurAngle = aStartArcDir[0]->angle(aCurDir); - if (aCurAngle < 0.0) - aCurAngle += 2.0 * PI; - if (aCurAngle < 0.0 || aCurAngle > anArcAngle[0]) - continue; // incorrect position - theTangentA = aCenter[0]->added(aCurDir->xy()->multiplied(anArcRadius[0])); - - aCurDir = std::shared_ptr(new GeomAPI_Dir2d((*anIt)->decreased(aCenter[1]))); - aCurAngle = aStartArcDir[1]->angle(aCurDir); - if (aCurAngle < 0.0) - aCurAngle += 2.0 * PI; - if (aCurAngle < 0.0 || aCurAngle > anArcAngle[1]) - continue; // incorrect position - theTangentB = aCenter[1]->added(aCurDir->xy()->multiplied(anArcRadius[1])); - - // the center is found, stop searching - theCenter = *anIt; - return; + GeomShapePtr aShapeA = theFilletFeatures[0]->lastResult()->shape(); + GeomShapePtr aShapeB = theFilletFeatures[1]->lastResult()->shape(); + + GeomAlgoAPI_Circ2dBuilder aCircBuilder(theSketchPlane); + aCircBuilder.addTangentCurve(aShapeA); + aCircBuilder.addTangentCurve(aShapeB); + aCircBuilder.setRadius(theFilletRadius); + + std::shared_ptr aFilletCircle = aCircBuilder.circle(); + if (!aFilletCircle) + return; + + theCenter = aFilletCircle->center()->xy(); + // tangent points + std::shared_ptr aTgPoints[2]; + for (int i = 0; i < 2; ++i) { + std::shared_ptr aCircle = toCircle(theFilletFeatures[i]); + if (aCircle) + aTgPoints[i] = aCircle->project(aFilletCircle->center()); + else { + std::shared_ptr aLine = toLine(theFilletFeatures[i]); + if (aLine) + aTgPoints[i] = aLine->project(aFilletCircle->center()); } } + theTangentA = aTgPoints[0]->xy(); + theTangentB = aTgPoints[1]->xy(); } -void getPointOnEdge(const FeaturePtr theFeature, - const std::shared_ptr theFilletPoint, - std::shared_ptr& thePoint) { - if(theFeature->getKind() == SketchPlugin_Line::ID()) { - std::shared_ptr aPntStart = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Line::START_ID()))->pnt(); - std::shared_ptr aPntEnd = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Line::END_ID()))->pnt(); - if(aPntStart->distance(theFilletPoint) > 1.e-7) { - aPntStart = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Line::END_ID()))->pnt(); - aPntEnd = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Line::START_ID()))->pnt(); - } - thePoint.reset( - new GeomAPI_Pnt2d(aPntStart->xy()->added( - aPntEnd->xy()->decreased( aPntStart->xy() )->multiplied(1.0 / 3.0) ) ) ); - } else { - std::shared_ptr aPntTemp; - std::shared_ptr aPntStart = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt(); - std::shared_ptr aPntEnd = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt(); - if(theFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value()) { - aPntTemp = aPntStart; - aPntStart = aPntEnd; - aPntEnd = aPntTemp; - } - std::shared_ptr aCenterPnt = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt(); - std::shared_ptr aCirc(new GeomAPI_Circ2d(aCenterPnt, aPntStart)); - double aStartParameter(0), anEndParameter(0); - aCirc->parameter(aPntStart, paramTolerance, aStartParameter); - aCirc->parameter(aPntEnd, paramTolerance, anEndParameter); - if(aPntStart->distance(theFilletPoint) > tolerance) { - double aTmpParameter = aStartParameter; - aStartParameter = anEndParameter; - anEndParameter = aTmpParameter; - } - double aPntParameter = aStartParameter + (anEndParameter - aStartParameter) / 3.0; - aCirc->D0(aPntParameter, thePoint); - } -} - -double getProjectionDistance(const FeaturePtr theFeature, - const std::shared_ptr thePoint) +double calculateFilletRadius(FeaturePtr theFilletFeatures[2]) { - std::shared_ptr aProjectPnt; - if(theFeature->getKind() == SketchPlugin_Line::ID()) { - std::shared_ptr aPntStart = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Line::START_ID()))->pnt(); - std::shared_ptr aPntEnd = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Line::END_ID()))->pnt(); - std::shared_ptr aLin(new GeomAPI_Lin2d(aPntStart, aPntEnd)); - aProjectPnt = aLin->project(thePoint); - } else { - std::shared_ptr aPntStart = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt(); - std::shared_ptr aPntEnd = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt(); - std::shared_ptr aCenterPnt = std::dynamic_pointer_cast( - theFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt(); - std::shared_ptr aCirc(new GeomAPI_Circ2d(aCenterPnt, aPntStart)); - aProjectPnt = aCirc->project(thePoint); - } - if(aProjectPnt.get()) { - return aProjectPnt->distance(thePoint); + double aLengths[2] = { 0, 0 }; + for (int i = 0; i < 2; ++i) { + GeomShapePtr aShape = theFilletFeatures[i]->lastResult()->shape(); + std::shared_ptr anEdge = std::dynamic_pointer_cast(aShape); + if (anEdge) + aLengths[i] = anEdge->length(); } - return -1; + return std::min(aLengths[0], aLengths[1]) / 6.0; } std::set getCoincides(const FeaturePtr& theConstraintCoincidence) @@ -795,7 +523,8 @@ std::set findFeaturesToRemove(const FeaturePtr theFeature, continue; } if(aFeature->getKind() == SketchPlugin_ConstraintLength::ID() - || aFeature->getKind() == SketchPlugin_ConstraintEqual::ID()) { + || aFeature->getKind() == SketchPlugin_ConstraintEqual::ID() + || aFeature->getKind() == SketchPlugin_ConstraintMiddle::ID()) { aFeaturesToBeRemoved.insert(aFeature); } else { std::list anAttrs =