X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintMirror.cpp;h=9d1477545f9d969234e7c7115d2fe04b16ab2d5f;hb=20d233731eaae06b9a75280a2ca675bc9a11cc72;hp=e76afd2ca40f34495c189481a0bf463e4b769343;hpb=3d063c74ca0ff72184f77d74df198c3bf0730aff;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp index e76afd2ca..9d1477545 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp @@ -10,6 +10,7 @@ #include #include +#include void SketchSolver_ConstraintMirror::getAttributes( Slvs_Entity& theMirrorLine, @@ -342,11 +343,11 @@ void SketchSolver_ConstraintMirror::adjustArcPoints(const Slvs_Entity& theArc) c } double aRad2 = anArcParams[1][0] * anArcParams[1][0] + anArcParams[1][1] * anArcParams[1][1]; double aDist2 = anArcParams[2][0] * anArcParams[2][0] + anArcParams[2][1] * anArcParams[2][1]; - if (fabs(aRad2 - aDist2) < tolerance) + if (std::fabs(aRad2 - aDist2) < tolerance) return; // nothing to update (last point already on the arc) if (aDist2 < tolerance) return; // unable to update - double aCoeff = sqrt(aRad2 / aDist2); + double aCoeff = std::sqrt(aRad2 / aDist2); anArcParams[2][0] *= aCoeff; anArcParams[2][1] *= aCoeff; @@ -384,6 +385,34 @@ void SketchSolver_ConstraintMirror::adjustConstraint() aStartEnd[2*i+j] = myStorage->getParameter(aPoint.param[j]).val; } + // Calculate length of the mirror line and create temporary constraint + double aLength = sqrt((aStartEnd[2] - aStartEnd[0]) * (aStartEnd[2] - aStartEnd[0]) + + (aStartEnd[3] - aStartEnd[1]) * (aStartEnd[3] - aStartEnd[1])); + if (aLength < tolerance) { + if (myMirrorLineLength < 1.0) + myMirrorLineLength = 1.0; + } else + myMirrorLineLength = aLength; + std::list aDist = myStorage->getConstraintsByType(SLVS_C_PT_PT_DISTANCE); + std::list::const_iterator aDIt = aDist.begin(); + for (; aDIt != aDist.end(); ++aDIt) + if ((aDIt->ptA == aMirrorLine.point[0] && aDIt->ptB == aMirrorLine.point[1]) || + (aDIt->ptA == aMirrorLine.point[1] && aDIt->ptB == aMirrorLine.point[0])) + break; // length of mirror line is already set + if (aDIt == aDist.end()) { + // check the points of mirror line is not fixed + Slvs_hConstraint aFixed; + if (!myStorage->isPointFixed(aMirrorLine.point[0], aFixed, true) || + !myStorage->isPointFixed(aMirrorLine.point[1], aFixed, true)) { + // Add length constraint + aMirror = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_PT_PT_DISTANCE, + myGroup->getWorkplaneId(), aLength, aMirrorLine.point[0], aMirrorLine.point[1], + SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); + aMirror.h = myStorage->addConstraint(aMirror); + myStorage->addTemporaryConstraint(aMirror.h); + } + } + // Search mirror between middle points on the arcs and recompute their coordinates std::map aPointsOnCircles; std::list aMirrorPonCirc; @@ -393,6 +422,8 @@ void SketchSolver_ConstraintMirror::adjustConstraint() aMirror = myStorage->getConstraint(*aConstrIter); if (aMirror.type != SLVS_C_SYMMETRIC_LINE) continue; + if (aMirror.entityA != aMirrorLine.h) + continue; // don't update another Mirror constraints Slvs_Constraint aPonCircA, aPonCircB; aPonCircA.h = SLVS_E_UNKNOWN; aPonCircB.h = SLVS_E_UNKNOWN; @@ -415,6 +446,8 @@ void SketchSolver_ConstraintMirror::adjustConstraint() std::list aMirrorList = myStorage->getConstraintsByType(SLVS_C_SYMMETRIC_LINE); std::list::iterator aMirIter = aMirrorList.begin(); for (; aMirIter != aMirrorList.end(); aMirIter++) { + if (aMirIter->entityA != aMirrorLine.h) + continue; // don't update another Mirror constraints if (aPointsOnCircles.find(aMirIter->ptA) != aPointsOnCircles.end()) continue; // Avoid mirroring points on circles Slvs_Entity aBase = myStorage->getEntity(aMirIter->ptA); @@ -424,25 +457,25 @@ void SketchSolver_ConstraintMirror::adjustConstraint() bool aNeedToResolve = myStorage->isNeedToResolve(); for (aMirIter = aMirrorPonCirc.begin(); aMirIter != aMirrorPonCirc.end(); aMirIter++) { - // Calculate middle point for base arc and mirrored point on mirror arc + // Make centers of arcs symmetric Slvs_Entity aBaseArc = myStorage->getEntity(aPointsOnCircles[aMirIter->ptA]); - Slvs_Entity aBasePoint = myStorage->getEntity(aMirIter->ptA); + Slvs_Entity aBasePoint = myStorage->getEntity(aBaseArc.point[0]); + Slvs_Entity aMirrorArc = myStorage->getEntity(aPointsOnCircles[aMirIter->ptB]); + Slvs_Entity aMirrorPoint = myStorage->getEntity(aMirrorArc.point[0]); + makeMirrorEntity(aBasePoint, aMirrorPoint, aStartEnd); + // Calculate middle point for base arc and mirrored point on mirror arc + aBasePoint = myStorage->getEntity(aMirIter->ptA); Slvs_Param aParamX = myStorage->getParameter(aBasePoint.param[0]); Slvs_Param aParamY = myStorage->getParameter(aBasePoint.param[1]); calculateMiddlePoint(aBaseArc, 0.5, aParamX.val, aParamY.val); myStorage->updateParameter(aParamX); myStorage->updateParameter(aParamY); - Slvs_Entity aMirrorArc = myStorage->getEntity(aPointsOnCircles[aMirIter->ptB]); - Slvs_Entity aMirrorPoint = myStorage->getEntity(aMirIter->ptB); + aMirrorPoint = myStorage->getEntity(aMirIter->ptB); aParamX = myStorage->getParameter(aMirrorPoint.param[0]); aParamY = myStorage->getParameter(aMirrorPoint.param[1]); calculateMiddlePoint(aMirrorArc, 0.5, aParamX.val, aParamY.val); myStorage->updateParameter(aParamX); myStorage->updateParameter(aParamY); - // make centers of arcs symmetric - aBasePoint = myStorage->getEntity(aBaseArc.point[0]); - aMirrorPoint = myStorage->getEntity(aMirrorArc.point[0]); - makeMirrorEntity(aBasePoint, aMirrorPoint, aStartEnd); } // Restore previous value to avoid looped recalculations of sketch myStorage->setNeedToResolve(aNeedToResolve);