X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintMirror.cpp;h=4f2c69b866f193dc1cdb189a215e3f1ff9dbe863;hb=d5b5ce2284869d8b97ce638502c58c810bbeb0c7;hp=12b009f6f9e0fe68ee5794367d21d99ccd9186b9;hpb=37c59d59b17e4a7e304588fb647488457a0c7283;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp index 12b009f6f..4f2c69b86 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp @@ -1,418 +1,206 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + #include #include -#include -////#include -////#include +#include +#include + +#include +#include #include -////#include -//// -////#include -////#include -//// -////#include +#include +#include + + +static void mirrorPoints(const std::shared_ptr& theMirrorLine, + const AttributePoint2DPtr& theOriginal, + const AttributePoint2DPtr& theMirrored); + +static void mirrorEntities(const std::shared_ptr& theMirrorLine, + const FeaturePtr& theOriginal, + const FeaturePtr& theMirrored); + + void SketchSolver_ConstraintMirror::getAttributes( - EntityWrapperPtr& theMirrorLine, - std::vector& theBaseEntities, - std::vector& theMirrorEntities) + EntityWrapperPtr&, + std::vector&) { - AttributeRefAttrPtr aMirLineAttr = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); - if (!aMirLineAttr || !aMirLineAttr->isInitialized() || !aMirLineAttr->isObject()) { + AttributeRefAttrPtr aMirLineRefAttr = + myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A()); + if (!aMirLineRefAttr || !aMirLineRefAttr->isInitialized() || !aMirLineRefAttr->isObject()) { myErrorMsg = SketchSolver_Error::NOT_INITIALIZED(); return; } + FeaturePtr aMirrorLine = ModelAPI_Feature::feature(aMirLineRefAttr->object()); + myFeatures.insert(aMirrorLine); + myType = TYPE(myBaseConstraint); - myStorage->update(aMirLineAttr, myGroupID); - theMirrorLine = myStorage->entity(aMirLineAttr); - - // Create SolveSpace entity for all features - AttributeRefListPtr aBaseRefList = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); - AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_C())); + myStorage->update(aMirrorLine); + + + AttributeRefListPtr aBaseRefList = + myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_B()); + AttributeRefListPtr aMirroredRefList = + myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_C()); myNumberOfObjects = aMirroredRefList->size(); if (!aBaseRefList || !aMirroredRefList) { myErrorMsg = SketchSolver_Error::INCORRECT_MIRROR_ATTRIBUTE(); return; } - std::list aBaseList = aBaseRefList->list(); - std::list aMirroredList = aMirroredRefList->list(); - - FeaturePtr aFeature; - for (int i = 0; i < 2; i++) { - std::list::iterator anIter = i == 0 ? aBaseList.begin() : aMirroredList.begin(); - std::list::iterator aEndIter = i == 0 ? aBaseList.end() : aMirroredList.end(); - std::vector* aList = i == 0 ? &theBaseEntities : & theMirrorEntities; - for ( ; anIter != aEndIter; anIter++) { - aFeature = ModelAPI_Feature::feature(*anIter); - if (!aFeature) - continue; - -//// anEntity = changeEntity(aFeature, aType); -//// // Sort entities by their type -//// std::vector::iterator anIt = aList->begin(); -//// for (; anIt != aList->end(); anIt++) -//// if (aType < anIt->type) -//// break; -////// aList->push_back(myStorage->getEntity(anEntity)); -//// aList->insert(anIt, myStorage->getEntity(anEntity)); - myStorage->update(aFeature, myGroupID); - aList->push_back(myStorage->entity(aFeature)); + // store only original entities because mirrored ones + // will be updated separately in adjustConstraint + std::list aList = aBaseRefList->list(); + std::list::iterator anIt = aList.begin(); + for (; anIt != aList.end(); ++anIt) { + FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + if (aFeature) { + myStorage->update(aFeature); + myFeatures.insert(aFeature); } } - - if (theBaseEntities.size() > theMirrorEntities.size()) - myErrorMsg = SketchSolver_Error::NOT_INITIALIZED(); + // add mirrored features to the list + aList = aMirroredRefList->list(); + for (anIt = aList.begin(); anIt != aList.end(); ++anIt) { + FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + if (aFeature) + myFeatures.insert(aFeature); + } } void SketchSolver_ConstraintMirror::process() { cleanErrorMsg(); - if (!myBaseConstraint || !myStorage || myGroupID == GID_UNKNOWN) { + if (!myBaseConstraint || !myStorage) { // Not enough parameters are assigned return; } -//// if (!mySlvsConstraints.empty()) // some data is changed, update constraint -//// update(myBaseConstraint); EntityWrapperPtr aMirrorLine; std::vector aBaseList; - std::vector aMirrorList; - getAttributes(aMirrorLine, aBaseList, aMirrorList); + getAttributes(aMirrorLine, aBaseList); if (!myErrorMsg.empty()) return; - if (aBaseList.size() != aMirrorList.size()) { - myErrorMsg = SketchSolver_Error::INCORRECT_MIRROR_ATTRIBUTE(); - return; - } - - std::list aNewConstraints; - SketchSolver_ConstraintType aConstrType = getType(); - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); - std::list aMirConstrList; - - std::vector::iterator aBIt = aBaseList.begin(); - std::vector::iterator aMIt = aMirrorList.begin(); - for (; aBIt != aBaseList.end(); ++aBIt, ++aMIt) { - if ((*aBIt)->type() == ENTITY_ARC) { - // add new points on arcs and mirror them - EntityWrapperPtr aBasePnt = myStorage->calculateMiddlePoint(*aBIt, 0.5); - EntityWrapperPtr aMirrPnt = myStorage->calculateMiddlePoint(*aMIt, 0.5); - // point on base arc - aNewConstraints = aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, - CONSTRAINT_PT_ON_CIRCLE, 0.0, aBasePnt, EntityWrapperPtr(), *aBIt); - aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end()); - // point on mirrored arc - aNewConstraints = aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, - CONSTRAINT_PT_ON_CIRCLE, 0.0, aMirrPnt, EntityWrapperPtr(), *aMIt); - aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end()); - // mirror these points - aNewConstraints = aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, - aConstrType, 0.0, aBasePnt, aMirrPnt, aMirrorLine); - aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end()); - } - aNewConstraints = aBuilder->createConstraint( - myBaseConstraint, myGroupID, mySketchID, aConstrType, - 0.0, *aBIt, *aMIt, aMirrorLine); - aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end()); - } - - myStorage->addConstraint(myBaseConstraint, aMirConstrList); + adjustConstraint(); + myStorage->subscribeUpdates(this, PlaneGCSSolver_UpdateFeature::GROUP()); } void SketchSolver_ConstraintMirror::update() { cleanErrorMsg(); - AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_C())); - if (aMirroredRefList->size() != myNumberOfObjects) { - remove(); - process(); - return; + remove(); + process(); +} + +void SketchSolver_ConstraintMirror::adjustConstraint() +{ + AttributeRefAttrPtr aMirrLineRefAttr = + myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A()); + std::shared_ptr aMirrorLine = + PlaneGCSSolver_Tools::line(ModelAPI_Feature::feature(aMirrLineRefAttr->object())); + + AttributeRefListPtr aBaseRefList = + myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_B()); + AttributeRefListPtr aMirroredRefList = + myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_C()); + + std::list aBaseList = aBaseRefList->list(); + std::list aMirroredList = aMirroredRefList->list(); + std::list::iterator aBIt, aMIt; + for (aBIt = aBaseList.begin(), aMIt = aMirroredList.begin(); + aBIt != aBaseList.end() && aMIt != aMirroredList.end(); + ++aBIt, ++aMIt) { + FeaturePtr aBase = ModelAPI_Feature::feature(*aBIt); + FeaturePtr aMirrored = ModelAPI_Feature::feature(*aMIt); + mirrorEntities(aMirrorLine, aBase, aMirrored); + + // update mirrored entity if it exists in the storage + if (myStorage->entity(aMirrored)) + myStorage->update(aMirrored); } - SketchSolver_Constraint::update(); } -////bool SketchSolver_ConstraintMirror::remove(ConstraintPtr theConstraint) -////{ -//// cleanErrorMsg(); -//// if (theConstraint && theConstraint != myBaseConstraint) -//// return false; -//// bool isFullyRemoved = true; -//// std::vector::iterator aCIter = mySlvsConstraints.begin(); -//// for (; aCIter != mySlvsConstraints.end(); aCIter++) -//// isFullyRemoved = myStorage->removeConstraint(*aCIter) && isFullyRemoved; -//// mySlvsConstraints.clear(); -//// -//// std::map::iterator aFeatIt = myFeatureMap.begin(); -//// for (; aFeatIt != myFeatureMap.end(); aFeatIt++) -//// myStorage->removeEntity(aFeatIt->second); -//// -//// if (isFullyRemoved) { -//// myFeatureMap.clear(); -//// myAttributeMap.clear(); -//// myValueMap.clear(); -//// } else -//// cleanRemovedEntities(); -//// return true; -////} -//// -////bool SketchSolver_ConstraintMirror::checkAttributesChanged(ConstraintPtr theConstraint) -////{ -//// // First of all, check the mirror line is changed. -//// // It may be changed to one of mirrored lines, which is already in this constraint -//// // (this case is not marked as attribute changing) -//// ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint; -//// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( -//// aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); -//// if (!aRefAttr || !aRefAttr->isObject() || !aRefAttr->object()) -//// return true; -//// FeaturePtr aMirrorLine = ModelAPI_Feature::feature(aRefAttr->object()); -//// if (!aMirrorLine) -//// return true; -//// -//// std::map::iterator aMirrorIter = myFeatureMap.find(aMirrorLine); -//// if (aMirrorIter == myFeatureMap.end()) -//// return true; -//// -//// // Check the entity is not used as mirror line -//// std::vector::iterator aCIter = mySlvsConstraints.begin(); -//// for (; aCIter != mySlvsConstraints.end(); aCIter++) { -//// Slvs_Constraint aMirrorConstr = myStorage->getConstraint(*aCIter); -//// if (aMirrorConstr.type != SLVS_C_SYMMETRIC_LINE) -//// continue; -//// if (aMirrorConstr.entityA != aMirrorIter->second) -//// return true; -//// else break; // check just one symmetric constraint -//// } -//// -//// // Base verification -//// return SketchSolver_Constraint::checkAttributesChanged(theConstraint); -////} - -////void SketchSolver_ConstraintMirror::makeMirrorEntity( -//// const Slvs_Entity& theBase, -//// const Slvs_Entity& theMirror, -//// const double theMirrorLine[]) const -////{ -//// Slvs_hEntity aBasePoint[4]; -//// Slvs_hEntity aMirrorPoint[4]; -//// for (int i = 0; i < 4; i++) { -//// aBasePoint[i] = theBase.point[i]; -//// aMirrorPoint[i] = theMirror.point[i]; -//// } -//// if (theBase.type == SLVS_E_ARC_OF_CIRCLE) { -//// Slvs_hEntity aTmp = aMirrorPoint[2]; -//// aMirrorPoint[2] = aMirrorPoint[1]; -//// aMirrorPoint[1] = aTmp; -//// adjustArcPoints(theBase); -//// } -//// if (theBase.type == SLVS_E_POINT_IN_2D || theBase.type == SLVS_E_POINT_IN_3D) { -//// aBasePoint[0] = theBase.h; -//// aMirrorPoint[0] = theMirror.h; -//// } -//// -//// // Mirror line parameters -//// std::shared_ptr aLinePoints[2]; -//// for (int i = 0; i < 2; i++) -//// aLinePoints[i] = std::shared_ptr( -//// new GeomAPI_XY(theMirrorLine[2*i], theMirrorLine[2*i+1])); -//// // direction of a mirror line -//// std::shared_ptr aDir = std::shared_ptr( -//// new GeomAPI_Dir2d(aLinePoints[1]->added(aLinePoints[0]->multiplied(-1.0)))); -//// // orthogonal direction -//// aDir = std::shared_ptr(new GeomAPI_Dir2d(aDir->y(), -aDir->x())); -//// -//// Slvs_hConstraint aFixed; // transient variable -//// for (int i = 0; i < 4; i++) { -//// if (aBasePoint[i] == SLVS_E_UNKNOWN || aMirrorPoint[i] == SLVS_E_UNKNOWN) -//// continue; -//// // check the mirror point is not fixed -//// if (myStorage->isPointFixed(aMirrorPoint[i], aFixed, true)) -//// continue; -//// -//// Slvs_Entity aPointEnt = myStorage->getEntity(aBasePoint[i]); -//// double aBaseX = myStorage->getParameter(aPointEnt.param[0]).val; -//// double aBaseY = myStorage->getParameter(aPointEnt.param[1]).val; -//// std::shared_ptr aPoint = std::shared_ptr(new GeomAPI_XY(aBaseX, aBaseY)); -//// -//// std::shared_ptr aVec = std::shared_ptr( -//// new GeomAPI_XY(aPoint->x() - aLinePoints[0]->x(), aPoint->y() - aLinePoints[0]->y())); -//// double aDist = aVec->dot(aDir->xy()); -//// aPoint = aPoint->added(aDir->xy()->multiplied(-2.0 * aDist)); -//// -//// Slvs_Entity aMirrorEnt = myStorage->getEntity(aMirrorPoint[i]); -//// Slvs_Param aParam = Slvs_MakeParam(aMirrorEnt.param[0], myGroup->getId(), aPoint->x()); -//// myStorage->updateParameter(aParam); -//// aParam = Slvs_MakeParam(aMirrorEnt.param[1], myGroup->getId(), aPoint->y()); -//// myStorage->updateParameter(aParam); -//// } -////} -//// -////void SketchSolver_ConstraintMirror::adjustArcPoints(const Slvs_Entity& theArc) const -////{ -//// Slvs_Param aParam; -//// Slvs_Entity aPoint; -//// double anArcParams[3][2]; -//// for (int i = 0; i < 3; i++) { -//// aPoint = myStorage->getEntity(theArc.point[i]); -//// for (int j = 0; j < 2; j++) { -//// aParam = myStorage->getParameter(aPoint.param[j]); -//// anArcParams[i][j] = aParam.val; -//// if (i > 0) -//// anArcParams[i][j] -= anArcParams[0][j]; -//// } -//// } -//// 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 (std::fabs(aRad2 - aDist2) < tolerance) -//// return; // nothing to update (last point already on the arc) -//// if (aDist2 < tolerance) -//// return; // unable to update -//// double aCoeff = std::sqrt(aRad2 / aDist2); -//// anArcParams[2][0] *= aCoeff; -//// anArcParams[2][1] *= aCoeff; -//// -//// // Update last point -//// aPoint = myStorage->getEntity(theArc.point[2]); -//// for (int i = 0; i < 2; i++) { -//// aParam = Slvs_MakeParam(aPoint.param[i], myGroup->getId(), -//// anArcParams[0][i] + anArcParams[2][i]); -//// myStorage->updateParameter(aParam); -//// } -////} +void SketchSolver_ConstraintMirror::notify(const FeaturePtr& theFeature, + PlaneGCSSolver_Update*) +{ + if (myFeatures.find(theFeature) == myFeatures.end()) + return; // the feature is not used by constraint => nothing to update + adjustConstraint(); +} -void SketchSolver_ConstraintMirror::adjustConstraint() +void SketchSolver_ConstraintMirror::blockEvents(bool isBlocked) +{ + std::set::iterator anIt = myFeatures.begin(); + for (; anIt != myFeatures.end(); ++anIt) + (*anIt)->data()->blockSendAttributeUpdated(isBlocked); + + SketchSolver_Constraint::blockEvents(isBlocked); +} + + + + +// ================= Auxiliary functions ================================== +void mirrorPoints(const std::shared_ptr& theMirrorLine, + const AttributePoint2DPtr& theOriginal, + const AttributePoint2DPtr& theMirrored) { - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); - - const std::list& aConstraints = myStorage->constraint(myBaseConstraint); - std::list::const_iterator aCIt = aConstraints.begin(); - for (; aCIt != aConstraints.end(); ++aCIt) - if ((*aCIt)->type() == CONSTRAINT_SYMMETRIC) - aBuilder->adjustConstraint(*aCIt); - -//// AttributeRefAttrPtr aMirLineAttr = std::dynamic_pointer_cast( -//// myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); -//// if (!aMirLineAttr || !aMirLineAttr->isInitialized() || !aMirLineAttr->isObject()) { -//// myErrorMsg = SketchSolver_Error::NOT_INITIALIZED(); -//// return; -//// } -//// ResultConstructionPtr aRC = -//// std::dynamic_pointer_cast(aMirLineAttr->object()); -//// FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) : -//// std::dynamic_pointer_cast(aMirLineAttr->object()); -//// std::map::iterator aMirLineIter = myFeatureMap.find(aFeature); -//// if (aMirLineIter == myFeatureMap.end()) -//// return; -//// Slvs_Entity aMirrorLine = myStorage->getEntity(aMirLineIter->second); -//// -//// Slvs_Constraint aMirror; -//// double aStartEnd[4]; -//// for (int i = 0; i < 2; i++) { -//// Slvs_Entity aPoint = myStorage->getEntity(aMirrorLine.point[i]); -//// for (int j = 0; j < 2; j++) -//// 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; -//// std::list aPonCirc = myStorage->getConstraintsByType(SLVS_C_PT_ON_CIRCLE); -//// std::vector::iterator aConstrIter = mySlvsConstraints.begin(); -//// for (; aConstrIter != mySlvsConstraints.end(); aConstrIter++) { -//// 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; -//// std::list::iterator aPtIter = aPonCirc.begin(); -//// for (; aPtIter != aPonCirc.end(); aPtIter++) { -//// if (aMirror.ptA == aPtIter->ptA) -//// aPonCircA = *aPtIter; -//// if (aMirror.ptB == aPtIter->ptA) -//// aPonCircB = *aPtIter; -//// } -//// if (aPonCircA.h == SLVS_E_UNKNOWN || aPonCircB.h == SLVS_E_UNKNOWN) -//// continue; -//// aMirrorPonCirc.push_back(aMirror); -//// // Store point IDs to avoid their recalculation twice -//// aPointsOnCircles[aPonCircA.ptA] = aPonCircA.entityA; -//// aPointsOnCircles[aPonCircB.ptA] = aPonCircB.entityA; -//// } -//// -//// // Recalculate positions of mirroring points -//// 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); -//// Slvs_Entity aMirror = myStorage->getEntity(aMirIter->ptB); -//// makeMirrorEntity(aBase, aMirror, aStartEnd); -//// } -//// -//// bool aNeedToResolve = myStorage->isNeedToResolve(); -//// for (aMirIter = aMirrorPonCirc.begin(); aMirIter != aMirrorPonCirc.end(); aMirIter++) { -//// // Make centers of arcs symmetric -//// Slvs_Entity aBaseArc = myStorage->getEntity(aPointsOnCircles[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); -//// 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); -//// } -//// // Restore previous value to avoid looped recalculations of sketch -//// myStorage->setNeedToResolve(aNeedToResolve); + std::shared_ptr anOriginal = theOriginal->pnt(); + std::shared_ptr aPtOnLine = theMirrorLine->project(anOriginal); + std::shared_ptr aPerp = aPtOnLine->xy()->decreased(anOriginal->xy()); + theMirrored->setValue(anOriginal->x() + aPerp->x() * 2.0, anOriginal->y() + aPerp->y() * 2.0); +} + +void mirrorEntities(const std::shared_ptr& theMirrorLine, + const FeaturePtr& theOriginal, + const FeaturePtr& theMirrored) +{ + std::list aPoints0 = + theOriginal->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list aPoints1 = + theMirrored->data()->attributes(GeomDataAPI_Point2D::typeId()); + + // process specific features + if (theOriginal->getKind() == SketchPlugin_Arc::ID()) { + // orientation of arc + theMirrored->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue( + !theOriginal->boolean(SketchPlugin_Arc::REVERSED_ID())->value()); + } else if (theOriginal->getKind() == SketchPlugin_Circle::ID()) { + // radius of the circle + theMirrored->real(SketchPlugin_Circle::RADIUS_ID())->setValue( + theOriginal->real(SketchPlugin_Circle::RADIUS_ID())->value()); + } + + // mirror all initialized points of features + std::list::iterator anIt0, anIt1; + for (anIt0 = aPoints0.begin(), anIt1 = aPoints1.begin(); + anIt0 != aPoints0.end() && anIt1 != aPoints1.end(); ++anIt0, ++anIt1) { + AttributePoint2DPtr aPt0 = std::dynamic_pointer_cast(*anIt0); + AttributePoint2DPtr aPt1 = std::dynamic_pointer_cast(*anIt1); + if (aPt0->isInitialized() && aPt1->isInitialized()) + mirrorPoints(theMirrorLine, aPt0, aPt1); + } }