From e28d4f868ffa8add2b9226f3edea697ad0fa2f1b Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 26 Mar 2015 16:14:20 +0300 Subject: [PATCH] Make Mirror constraint visible in GUI --- .../SketchPlugin_ConstraintMirror.cpp | 96 +++++- .../SketchPlugin_ConstraintMirror.h | 7 + src/SketchPlugin/plugin-Sketch.xml | 15 +- .../SketchSolver_ConstraintGroup.cpp | 291 +++++++++++------- .../SketchSolver_ConstraintGroup.h | 14 + 5 files changed, 299 insertions(+), 124 deletions(-) diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp b/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp index f0da5515f..fde907d81 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include #include #include @@ -28,33 +30,96 @@ void SketchPlugin_ConstraintMirror::initAttributes() data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId()); + AttributeSelectionListPtr aSelection = + std::dynamic_pointer_cast(data()->addAttribute( + SketchPlugin_ConstraintMirror::MIRROR_LIST_ID(), ModelAPI_AttributeSelectionList::typeId())); + aSelection->setSelectionType("EDGE"); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_C()); } void SketchPlugin_ConstraintMirror::execute() { - // Objects to be mirrored will be created here + AttributeSelectionListPtr aMirrorObjectRefs = + selectionList(SketchPlugin_ConstraintMirror::MIRROR_LIST_ID()); + if (!aMirrorObjectRefs->isInitialized()) + return; + std::shared_ptr aData = data(); AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Constraint::ENTITY_B())); - if (!aRefListOfShapes->isInitialized()) - return ; - AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Constraint::ENTITY_C())); - // Check consistency of initial list and mirrored list std::list anInitialList = aRefListOfShapes->list(); std::list aMirroredList = aRefListOfMirrored->list(); + std::vector isUsed(anInitialList.size(), false); + // add new items to the list + for(int anInd = 0; anInd < aMirrorObjectRefs->size(); anInd++) { + std::shared_ptr aSelect = aMirrorObjectRefs->value(anInd); + std::list::const_iterator anIt = anInitialList.begin(); + std::vector::iterator aUsedIt = isUsed.begin(); + for (; anIt != anInitialList.end(); anIt++, aUsedIt++) + if (*anIt == aSelect->context()) { + *aUsedIt = true; + break; + } + if (anIt == anInitialList.end()) + aRefListOfShapes->append(aSelect->context()); + } + // remove unused items std::list::iterator anInitIter = anInitialList.begin(); std::list::iterator aMirrorIter = aMirroredList.begin(); + std::vector::iterator aUsedIter = isUsed.begin(); + for (; aUsedIter != isUsed.end(); aUsedIter++) { + if (!(*aUsedIter)) { + aRefListOfShapes->remove(*anInitIter); + if (aMirrorIter != aMirroredList.end()) { + aRefListOfMirrored->remove(*aMirrorIter); + // remove the corresponding feature from the sketch + ResultConstructionPtr aRC = + std::dynamic_pointer_cast(*aMirrorIter); + DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr(); + FeaturePtr aFeature = aDoc ? std::dynamic_pointer_cast( + aDoc->feature(aRC)) : FeaturePtr(); + if (aFeature) + aDoc->removeFeature(aFeature); + } + } + if (anInitIter != anInitialList.end()) + anInitIter++; + if (aMirrorIter != aMirroredList.end()) + aMirrorIter++; + } + + // Check consistency of initial list and mirrored list + anInitialList = aRefListOfShapes->list(); + anInitIter = anInitialList.begin(); + aMirrorIter = aMirroredList.begin(); int indFirstWrong = 0; // index of element starts difference in the lists std::set anInvalidInd; // list of indices of removed features std::shared_ptr aFeatureIn, aFeatureOut; for ( ; anInitIter != anInitialList.end(); anInitIter++, indFirstWrong++) { // Add features and store indices of objects to remove aFeatureIn = std::dynamic_pointer_cast(*anInitIter); - aFeatureOut = aMirrorIter != aMirroredList.end() ? - std::dynamic_pointer_cast(*aMirrorIter) : - std::shared_ptr(); + ResultConstructionPtr aRCIn; + if (!aFeatureIn) { + aRCIn = std::dynamic_pointer_cast(*anInitIter); + if (aRCIn) + aFeatureIn = std::dynamic_pointer_cast( + aRCIn->document()->feature(aRCIn)); + } + if (aMirrorIter == aMirroredList.end()) + aFeatureOut = std::shared_ptr(); + else { + aFeatureOut = std::dynamic_pointer_cast(*aMirrorIter); + if (!aFeatureOut) { + ResultConstructionPtr aRC = + std::dynamic_pointer_cast(*anInitIter); + if (aRC) + aFeatureOut = std::dynamic_pointer_cast( + aRC->document()->feature(aRC)); + } + } if (!aFeatureIn) { if (aFeatureOut) break; // the lists are inconsistent @@ -66,7 +131,20 @@ void SketchPlugin_ConstraintMirror::execute() // There is no mirrored object yet, create it FeaturePtr aNewFeature = sketch()->addFeature(aFeatureIn->getKind()); aFeatureIn->data()->copyTo(aNewFeature->data()); - aRefListOfMirrored->append(aNewFeature); + aNewFeature->execute(); + + std::shared_ptr aShapeIn = aRCIn->shape(); + const std::list& aResults = aNewFeature->results(); + std::list::const_iterator anIt = aResults.begin(); + for (; anIt != aResults.end(); anIt++) { + ResultConstructionPtr aRC = std::dynamic_pointer_cast(*anIt); + if (!aRC) continue; + std::shared_ptr aShapeOut = aRC->shape(); + if ((aShapeIn->isVertex() && aShapeOut->isVertex()) || + (aShapeIn->isEdge() && aShapeOut->isEdge()) || + (aShapeIn->isFace() && aShapeOut->isFace())) + aRefListOfMirrored->append(aRC); + } continue; } if (aFeatureIn->getKind() != aFeatureOut->getKind()) diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMirror.h b/src/SketchPlugin/SketchPlugin_ConstraintMirror.h index 841f11abd..69a26ea8f 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintMirror.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintMirror.h @@ -38,6 +38,13 @@ class SketchPlugin_ConstraintMirror : public SketchPlugin_ConstraintBase return MY_KIND; } + /// List of objects to be mirrored + inline static const std::string& MIRROR_LIST_ID() + { + static const std::string MY_MIRROR_LIST_ID("ConstraintMirrorList"); + return MY_MIRROR_LIST_ID; + } + /// \brief Creates a new part document if needed SKETCHPLUGIN_EXPORT virtual void execute(); diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 391738b8c..114692336 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -5,7 +5,7 @@ + tooltip="Create constraint, mirroring group of objects"> + + + + + + diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp index 776be57bd..d7f2409d1 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp @@ -616,9 +616,11 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint( // Search this constraint in the current group to update it ConstraintMap::const_iterator aConstrMapIter = myConstraintMap.find(theConstraint); std::vector::iterator aConstrIter; + bool isExists = false; if (aConstrMapIter != myConstraintMap.end()) { int aConstrPos = Search(aConstrMapIter->second.front(), myConstraints); aConstrIter = myConstraints.begin() + aConstrPos; + isExists = true; } // Get constraint type and verify the constraint parameters are correct @@ -648,128 +650,155 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint( aMirrorLineEnt = aConstrAttr->isObject() ? changeEntityFeature(aMirrorLineFeat) : changeEntity(aConstrAttr->attr()); - if (aConstrMapIter == myConstraintMap.end()) { // Add new constraint - // Append symmetric constraint for each point of mirroring features - AttributeRefListPtr aBaseRefList = std::dynamic_pointer_cast( - aConstrData->attribute(aConstraintAttributes[1])); - AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast( - aConstrData->attribute(aConstraintAttributes[2])); - if (!aBaseRefList || !aMirroredRefList) - return false; - - std::list aBaseList = aBaseRefList->list(); - std::list aMirroredList = aMirroredRefList->list(); - if (aBaseList.size() != aMirroredList.size()) - return false; + // Append symmetric constraint for each point of mirroring features + AttributeRefListPtr aBaseRefList = std::dynamic_pointer_cast( + aConstrData->attribute(aConstraintAttributes[1])); + AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast( + aConstrData->attribute(aConstraintAttributes[2])); + if (!aBaseRefList || !aMirroredRefList) + return false; - myConstraintMap[theConstraint] = std::vector(); + std::list aBaseList = aBaseRefList->list(); + std::list aMirroredList = aMirroredRefList->list(); + if (aBaseList.empty() || aBaseList.size() != aMirroredList.size()) + return false; - FeaturePtr aBaseFeature, aMirrorFeature; - ResultConstructionPtr aRC; - std::list::iterator aBaseIter = aBaseList.begin(); - std::list::iterator aMirIter = aMirroredList.begin(); - for ( ; aBaseIter != aBaseList.end(); aBaseIter++, aMirIter++) { - aRC = std::dynamic_pointer_cast(*aBaseIter); - aBaseFeature = aRC ? aRC->document()->feature(aRC) : - std::dynamic_pointer_cast(*aBaseIter); - aRC = std::dynamic_pointer_cast(*aMirIter); - aMirrorFeature = aRC ? aRC->document()->feature(aRC) : - std::dynamic_pointer_cast(*aMirIter); + std::vector aNewConstraints; + // Fill the list of already mirrored points + std::vector anOldConstraints; + std::map aMirroredPoints; + if (isExists) { + std::vector::const_iterator aCIter = aConstrMapIter->second.begin(); + for (; aCIter != aConstrMapIter->second.end(); aCIter++) { + int anInd = Search(*aCIter, myConstraints); + if (myConstraints[anInd].type != aConstrType) + continue; + aMirroredPoints[myConstraints[anInd].ptA] = myConstraints[anInd].ptB; + anOldConstraints.push_back(myConstraints[anInd]); + } + } - if (!aBaseFeature || !aMirrorFeature || - aBaseFeature->getKind() != aMirrorFeature->getKind()) - return false; - Slvs_hEntity aBaseEnt = changeEntityFeature(aBaseFeature); - Slvs_hEntity aMirrorEnt = changeEntityFeature(aMirrorFeature); - // Make aMirrorEnt parameters to be symmetric with aBaseEnt - makeMirrorEntity(aBaseEnt, aMirrorEnt, aMirrorLineEnt); - - if (aBaseFeature->getKind() == SketchPlugin_Point::ID()) { - Slvs_Constraint aConstraint = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType, - myWorkplane.h, 0.0, aBaseEnt, aMirrorEnt, aMirrorLineEnt, SLVS_E_UNKNOWN); - myConstraints.push_back(aConstraint); - myConstraintMap[theConstraint].push_back(aConstraint.h); - } else { - int aBasePos = Search(aBaseEnt, myEntities); - int aMirrorPos = Search(aMirrorEnt, myEntities); - if (aBaseFeature->getKind() == SketchPlugin_Line::ID()) { - for (int ind = 0; ind < 2; ind++) { - Slvs_Constraint aConstraint = Slvs_MakeConstraint( - ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0, - myEntities[aBasePos].point[ind], myEntities[aMirrorPos].point[ind], - aMirrorLineEnt, SLVS_E_UNKNOWN); - myConstraints.push_back(aConstraint); - myConstraintMap[theConstraint].push_back(aConstraint.h); - } - } else if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) { - Slvs_Constraint aConstraint = Slvs_MakeConstraint( - ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0, - myEntities[aBasePos].point[0], myEntities[aMirrorPos].point[0], - aMirrorLineEnt, SLVS_E_UNKNOWN); - myConstraints.push_back(aConstraint); - myConstraintMap[theConstraint].push_back(aConstraint.h); - // Additional constraint for equal radii - Slvs_Constraint anEqRadConstr = Slvs_MakeConstraint( - ++myConstrMaxID, myID, SLVS_C_EQUAL_RADIUS, myWorkplane.h, 0.0, - SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aBaseEnt, aMirrorEnt); - myConstraints.push_back(anEqRadConstr); - myConstraintMap[theConstraint].push_back(anEqRadConstr.h); - } else if (aBaseFeature->getKind() == SketchPlugin_Arc::ID()) { - // Workaround to avoid problems in SolveSpace. - // The symmetry of two arcs will be done using symmetry of three points on these arcs: - // start point, end point, and any other point on the arc - Slvs_hEntity aBaseArcPoints[3] = { - myEntities[aBasePos].point[1], - myEntities[aBasePos].point[2], - SLVS_E_UNKNOWN}; - Slvs_hEntity aMirrorArcPoints[3] = { // indices of points of arc, center corresponds center, first point corresponds last point - myEntities[aMirrorPos].point[2], - myEntities[aMirrorPos].point[1], - SLVS_E_UNKNOWN}; - Slvs_hEntity aBothArcs[2] = {aBaseEnt, aMirrorEnt}; - Slvs_hEntity aBothMiddlePoints[2]; - for (int i = 0; i < 2; i++) { - double x, y; - calculateMiddlePoint(aBothArcs[i], x, y); - std::vector::iterator aParamIter = myParams.end(); - Slvs_hParam u = changeParameter(x, aParamIter); - Slvs_hParam v = changeParameter(y, aParamIter); - Slvs_Entity aPoint = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, u, v); - myEntities.push_back(aPoint); - aBothMiddlePoints[i] = aPoint.h; - // additional constraint point-on-curve - Slvs_Constraint aPonCircConstr = Slvs_MakeConstraint( - ++myConstrMaxID, myID, SLVS_C_PT_ON_CIRCLE, myWorkplane.h, 0.0, - aPoint.h, SLVS_E_UNKNOWN, aBothArcs[i], SLVS_E_UNKNOWN); - myConstraints.push_back(aPonCircConstr); - myConstraintMap[theConstraint].push_back(aPonCircConstr.h); - } + FeaturePtr aBaseFeature, aMirrorFeature; + ResultConstructionPtr aRC; + std::list::iterator aBaseIter = aBaseList.begin(); + std::list::iterator aMirIter = aMirroredList.begin(); + for ( ; aBaseIter != aBaseList.end(); aBaseIter++, aMirIter++) { + aRC = std::dynamic_pointer_cast(*aBaseIter); + aBaseFeature = aRC ? aRC->document()->feature(aRC) : + std::dynamic_pointer_cast(*aBaseIter); + aRC = std::dynamic_pointer_cast(*aMirIter); + aMirrorFeature = aRC ? aRC->document()->feature(aRC) : + std::dynamic_pointer_cast(*aMirIter); + + if (!aBaseFeature || !aMirrorFeature || + aBaseFeature->getKind() != aMirrorFeature->getKind()) + return false; + Slvs_hEntity aBaseEnt = changeEntityFeature(aBaseFeature); + Slvs_hEntity aMirrorEnt = changeEntityFeature(aMirrorFeature); + // Make aMirrorEnt parameters to be symmetric with aBaseEnt + makeMirrorEntity(aBaseEnt, aMirrorEnt, aMirrorLineEnt); + + if (aBaseFeature->getKind() == SketchPlugin_Point::ID()) { + Slvs_hConstraint anID = changeMirrorPoints(aBaseEnt, aMirrorEnt, + aMirrorLineEnt, anOldConstraints, aMirroredPoints); + aNewConstraints.push_back(anID); + } else { + int aBasePos = Search(aBaseEnt, myEntities); + int aMirrorPos = Search(aMirrorEnt, myEntities); + if (aBaseFeature->getKind() == SketchPlugin_Line::ID()) { + for (int ind = 0; ind < 2; ind++) { + Slvs_hConstraint anID = changeMirrorPoints(myEntities[aBasePos].point[ind], + myEntities[aMirrorPos].point[ind], aMirrorLineEnt, anOldConstraints, aMirroredPoints); + aNewConstraints.push_back(anID); + } + } else if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) { + Slvs_hConstraint anID = changeMirrorPoints(myEntities[aBasePos].point[0], + myEntities[aMirrorPos].point[0], aMirrorLineEnt, anOldConstraints, aMirroredPoints); + aNewConstraints.push_back(anID); + // Additional constraint for equal radii + Slvs_Constraint anEqRadConstr = Slvs_MakeConstraint( + ++myConstrMaxID, myID, SLVS_C_EQUAL_RADIUS, myWorkplane.h, 0.0, + SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aBaseEnt, aMirrorEnt); + myConstraints.push_back(anEqRadConstr); + myConstraintMap[theConstraint].push_back(anEqRadConstr.h); + } else if (aBaseFeature->getKind() == SketchPlugin_Arc::ID()) { + // Workaround to avoid problems in SolveSpace. + // The symmetry of two arcs will be done using symmetry of three points on these arcs: + // start point, end point, and any other point on the arc + Slvs_hEntity aBaseArcPoints[3] = { + myEntities[aBasePos].point[1], + myEntities[aBasePos].point[2], + SLVS_E_UNKNOWN}; + Slvs_hEntity aMirrorArcPoints[3] = { // indices of points of arc, center corresponds center, first point corresponds last point + myEntities[aMirrorPos].point[2], + myEntities[aMirrorPos].point[1], + SLVS_E_UNKNOWN}; + Slvs_hEntity aBothArcs[2] = {aBaseEnt, aMirrorEnt}; + Slvs_hEntity aBothMiddlePoints[2]; + for (int i = 0; i < 2; i++) { + double x, y; + calculateMiddlePoint(aBothArcs[i], x, y); + std::vector::iterator aParamIter = myParams.end(); + Slvs_hParam u = changeParameter(x, aParamIter); + Slvs_hParam v = changeParameter(y, aParamIter); + Slvs_Entity aPoint = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, u, v); + myEntities.push_back(aPoint); + aBothMiddlePoints[i] = aPoint.h; + // additional constraint point-on-curve + Slvs_Constraint aPonCircConstr = Slvs_MakeConstraint( + ++myConstrMaxID, myID, SLVS_C_PT_ON_CIRCLE, myWorkplane.h, 0.0, + aPoint.h, SLVS_E_UNKNOWN, aBothArcs[i], SLVS_E_UNKNOWN); + myConstraints.push_back(aPonCircConstr); + myConstraintMap[theConstraint].push_back(aPonCircConstr.h); + } - aBaseArcPoints[2] = aBothMiddlePoints[0]; - aMirrorArcPoints[2] = aBothMiddlePoints[1]; - for (int ind = 0; ind < 3; ind++) { - Slvs_Constraint aConstraint = Slvs_MakeConstraint( - ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0, - aBaseArcPoints[ind], aMirrorArcPoints[ind], aMirrorLineEnt, SLVS_E_UNKNOWN); - myConstraints.push_back(aConstraint); - myConstraintMap[theConstraint].push_back(aConstraint.h); - } + aBaseArcPoints[2] = aBothMiddlePoints[0]; + aMirrorArcPoints[2] = aBothMiddlePoints[1]; + for (int ind = 0; ind < 3; ind++) { + Slvs_hConstraint anID = changeMirrorPoints(aBaseArcPoints[ind], aMirrorArcPoints[ind], + aMirrorLineEnt, anOldConstraints, aMirroredPoints); + aNewConstraints.push_back(anID); } } } + } + // Remove unused constraints + std::vector::const_iterator anOldCIter = anOldConstraints.begin(); + for (; anOldCIter != anOldConstraints.end(); anOldCIter++) { + int anInd = Search(anOldCIter->h, myConstraints); + myConstraints.erase(myConstraints.begin() + anInd); + } + myConstraintMap[theConstraint] = aNewConstraints; + + if (!isExists) { // Set the mirror line unchanged during constraint recalculation int aMirrorLinePos = Search(aMirrorLineEnt, myEntities); - Slvs_Constraint aRigidStart = Slvs_MakeConstraint( - ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0, - myEntities[aMirrorLinePos].point[0], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); - myConstraints.push_back(aRigidStart); - myConstraintMap[theConstraint].push_back(aRigidStart.h); - Slvs_Constraint aRigidEnd = Slvs_MakeConstraint( - ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0, - myEntities[aMirrorLinePos].point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); - myConstraints.push_back(aRigidEnd); - myConstraintMap[theConstraint].push_back(aRigidEnd.h); + // firstly check the line is not fixed yet + bool isFixed[2] = {false, false}; + std::vector::const_iterator aConstrIter = myConstraints.begin(); + for (; aConstrIter != myConstraints.end() && !(isFixed[0] && isFixed[1]); aConstrIter++) + if (aConstrIter->type == SLVS_C_WHERE_DRAGGED) { + if (aConstrIter->ptA == myEntities[aMirrorLinePos].point[0]) + isFixed[0] = true; + else if (aConstrIter->ptA == myEntities[aMirrorLinePos].point[1]) + isFixed[1] = true; + } + // add new rigid constraints + if (!isFixed[0]) { + Slvs_Constraint aRigidStart = Slvs_MakeConstraint( + ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0, + myEntities[aMirrorLinePos].point[0], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); + myConstraints.push_back(aRigidStart); + myConstraintMap[theConstraint].push_back(aRigidStart.h); + } + if (!isFixed[1]) { + Slvs_Constraint aRigidEnd = Slvs_MakeConstraint( + ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0, + myEntities[aMirrorLinePos].point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); + myConstraints.push_back(aRigidEnd); + myConstraintMap[theConstraint].push_back(aRigidEnd.h); + } // Add temporary constraints for initial objects to be unchanged for (aBaseIter = aBaseList.begin(); aBaseIter != aBaseList.end(); aBaseIter++) { @@ -2146,6 +2175,44 @@ void SketchSolver_ConstraintGroup::makeMirrorEntity(const Slvs_hEntity& theBase, } } +// ============================================================================ +// Function: changeMirrorPoints +// Class: SketchSolver_ConstraintGroup +// Purpose: creates/updates mirror constraint for two points +// ============================================================================ +Slvs_hConstraint SketchSolver_ConstraintGroup::changeMirrorPoints( + const Slvs_hEntity& theBasePoint, + const Slvs_hEntity& theMirrorPoint, + const Slvs_hEntity& theMirrorLine, + std::vector& thePrevConstr, + std::map& thePrevMirror) +{ + std::map::iterator aMapIter = thePrevMirror.find(theBasePoint); + if (aMapIter != thePrevMirror.end()) { + thePrevMirror.erase(aMapIter); + std::vector::const_iterator anIter = thePrevConstr.begin(); + for (; anIter != thePrevConstr.end(); anIter++) + if (anIter->ptA == theBasePoint) { + if (anIter->ptB != theMirrorPoint) { + int aConstrInd = Search(anIter->h, myConstraints); + myConstraints[aConstrInd].ptB = theMirrorPoint; + myConstraints[aConstrInd].entityA = theMirrorLine; + } + Slvs_hConstraint aResult = anIter->h; + thePrevConstr.erase(anIter); + return aResult; + } + } + + // Newly created constraint + Slvs_Constraint aConstraint = Slvs_MakeConstraint( + ++myConstrMaxID, myID, SLVS_C_SYMMETRIC_LINE, myWorkplane.h, 0.0, + theBasePoint, theMirrorPoint, theMirrorLine, SLVS_E_UNKNOWN); + myConstraints.push_back(aConstraint); + return aConstraint.h; +} + + // ============================================================================ // Function: calculateMiddlePoint // Class: SketchSolver_ConstraintGroup diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.h b/src/SketchSolver/SketchSolver_ConstraintGroup.h index e24d93a7d..73dc23d63 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.h +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.h @@ -237,6 +237,20 @@ protected: const Slvs_hEntity& theMirror, const Slvs_hEntity& theMirrorLine); + /** \brief Creates/updates mirror constraint for two points + * \param[in] theBasePoint ID of initial point + * \param[in] theMirrorPoint ID of the mirroring point + * \param[in] theMirrorLine ID of the mirror line + * \param[in] thePrevConstr list of previous constraints (the items will be deleted from the list if they are updated) + * \param[in,out] thePrevMirror list of previously mirrored points (the items will be deleted from the list if they are updated) + * \return ID of created/updated constraint + */ + Slvs_hConstraint changeMirrorPoints(const Slvs_hEntity& theBasePoint, + const Slvs_hEntity& theMirrorPoint, + const Slvs_hEntity& theMirrorLine, + std::vector& thePrevConstr, + std::map& thePrevMirror); + /** \brief Calculates middle point on line or arc * \param[in] theEntity identifier of line or arc * \param[out] theX X value of middle point -- 2.39.2