From 8d14c96c91e8f603be755b9502793f35970c2bdc Mon Sep 17 00:00:00 2001 From: azv Date: Wed, 1 Apr 2015 12:40:16 +0300 Subject: [PATCH] Issue #424: Mirror is done wrong Additional verification of arcs in mirror constraint is implemented --- .../SketchSolver_ConstraintGroup.cpp | 62 ++++++++++++++++--- .../SketchSolver_ConstraintManager.cpp | 2 +- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp index 9b0ae4325..49437e464 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp @@ -745,6 +745,7 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint( Slvs_hParam v = changeParameter(y, aParamIter); Slvs_Entity aPoint = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, u, v); myEntities.push_back(aPoint); + myEntOfConstr.push_back(true); aBothMiddlePoints[i] = aPoint.h; // additional constraint point-on-curve Slvs_Constraint aPonCircConstr = Slvs_MakeConstraint( @@ -752,6 +753,7 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint( aPoint.h, SLVS_E_UNKNOWN, aBothArcs[i], SLVS_E_UNKNOWN); myConstraints.push_back(aPonCircConstr); myConstraintMap[theConstraint].push_back(aPonCircConstr.h); + aNewConstraints.push_back(aPonCircConstr.h); } aBaseArcPoints[2] = aBothMiddlePoints[0]; @@ -809,13 +811,48 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint( std::dynamic_pointer_cast(*aBaseIter); if (!aBaseFeature) continue; std::list aPoints = aBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::list::iterator anIt = aPoints.begin(); - for ( ; anIt != aPoints.end(); anIt++) { + if (aBaseFeature->getKind() != SketchPlugin_Arc::ID()) { + std::list::iterator anIt = aPoints.begin(); + for ( ; anIt != aPoints.end(); anIt++) { + addTemporaryConstraintWhereDragged(*anIt); + } + } else { // Arcs are fixed by center and start points only (to avoid solving errors in SolveSpace) - if (aBaseFeature->getKind() == SketchPlugin_Arc::ID() && - (*anIt)->id() == SketchPlugin_Arc::END_ID()) - continue; - addTemporaryConstraintWhereDragged(*anIt); + AttributePtr aCenterAttr = aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()); + std::map::iterator aFound = myEntityAttrMap.find(aCenterAttr); + Slvs_hEntity anArcPoints[3] = {aFound->second, 0, 0}; + AttributePtr aStartAttr = aBaseFeature->attribute(SketchPlugin_Arc::START_ID()); + aFound = myEntityAttrMap.find(aStartAttr); + anArcPoints[1] = aFound->second; + AttributePtr aEndAttr = aBaseFeature->attribute(SketchPlugin_Arc::END_ID()); + aFound = myEntityAttrMap.find(aEndAttr); + anArcPoints[2] = aFound->second; + + bool isFixed[3] = {false, false, false}; + int aNbFixed = 0; // number of already fixed points on the arc + for (int i = 0; i < 3; i++) { + std::vector >::iterator aCoPtIter = myCoincidentPoints.begin(); + for (; aCoPtIter != myCoincidentPoints.end() && !isFixed[i]; aCoPtIter++) { + if (aCoPtIter->find(anArcPoints[i]) == aCoPtIter->end()) + continue; // the entity was not found in current set + + // Find one of already created SLVS_C_WHERE_DRAGGED constraints in current set of coincident points + std::vector::iterator aConstrIter = myConstraints.begin(); + for (; aConstrIter != myConstraints.end(); aConstrIter++) + if (aConstrIter->type == SLVS_C_WHERE_DRAGGED && + aCoPtIter->find(aConstrIter->ptA) != aCoPtIter->end()) { + isFixed[i] = true; + aNbFixed++; + break; // the SLVS_C_WHERE_DRAGGED constraint already exists + } + } + } + if (aNbFixed < 2) { // append constraints + if (!isFixed[0]) + addTemporaryConstraintWhereDragged(aCenterAttr); + if (!isFixed[1] && (isFixed[0] || aNbFixed == 0)) + addTemporaryConstraintWhereDragged(aStartAttr); + } } } } @@ -2143,9 +2180,16 @@ void SketchSolver_ConstraintGroup::makeMirrorEntity(const Slvs_hEntity& theBase, Slvs_Entity aBase = myEntities[Search(theBase, myEntities)]; Slvs_Entity aMirror = myEntities[Search(theMirror, myEntities)]; int i = 0; - while (aBase.point[i] != 0 && aMirror.point[i] != 0) { - makeMirrorEntity(aBase.point[i], aMirror.point[i], theMirrorLine); - i++; + if (aBase.type != SLVS_E_ARC_OF_CIRCLE) { + while (aBase.point[i] != 0 && aMirror.point[i] != 0) { + makeMirrorEntity(aBase.point[i], aMirror.point[i], theMirrorLine); + i++; + } + } else { + // swap mirroring first and last points of an arc + makeMirrorEntity(aBase.point[0], aMirror.point[0], theMirrorLine); + makeMirrorEntity(aBase.point[1], aMirror.point[2], theMirrorLine); + makeMirrorEntity(aBase.point[2], aMirror.point[1], theMirrorLine); } if (aBase.param[0] != 0 && aMirror.param[0] != 0) { // this is a point, copy it Slvs_Entity aMirrorLine = myEntities[Search(theMirrorLine, myEntities)]; diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index 1fafcf506..bd346fb35 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -117,7 +117,7 @@ void SketchSolver_ConstraintManager::processEvent( for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { std::shared_ptr aFeature = std::dynamic_pointer_cast(*aFeatIter); - if (!aFeature || aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) + if (!aFeature /*|| aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()*/) continue; changeConstraintOrEntity(aFeature); } -- 2.39.2