- BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
-
- const std::list<ConstraintWrapperPtr>& aConstraints = myStorage->constraint(myBaseConstraint);
- std::list<ConstraintWrapperPtr>::const_iterator aCIt = aConstraints.begin();
- for (; aCIt != aConstraints.end(); ++aCIt)
- if ((*aCIt)->type() == CONSTRAINT_SYMMETRIC)
- aBuilder->adjustConstraint(*aCIt);
-
-//// AttributeRefAttrPtr aMirLineAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-//// myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
-//// if (!aMirLineAttr || !aMirLineAttr->isInitialized() || !aMirLineAttr->isObject()) {
-//// myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
-//// return;
-//// }
-//// ResultConstructionPtr aRC =
-//// std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aMirLineAttr->object());
-//// FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
-//// std::dynamic_pointer_cast<ModelAPI_Feature>(aMirLineAttr->object());
-//// std::map<FeaturePtr, Slvs_hEntity>::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<Slvs_Constraint> aDist = myStorage->getConstraintsByType(SLVS_C_PT_PT_DISTANCE);
-//// std::list<Slvs_Constraint>::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<Slvs_hEntity, Slvs_hEntity> aPointsOnCircles;
-//// std::list<Slvs_Constraint> aMirrorPonCirc;
-//// std::list<Slvs_Constraint> aPonCirc = myStorage->getConstraintsByType(SLVS_C_PT_ON_CIRCLE);
-//// std::vector<Slvs_hConstraint>::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<Slvs_Constraint>::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<Slvs_Constraint> aMirrorList = myStorage->getConstraintsByType(SLVS_C_SYMMETRIC_LINE);
-//// std::list<Slvs_Constraint>::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<GeomAPI_Pnt2d> anOriginal = theOriginal->pnt();
+ std::shared_ptr<GeomAPI_Pnt2d> aPtOnLine = theMirrorLine->project(anOriginal);
+ std::shared_ptr<GeomAPI_XY> 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<GeomAPI_Lin2d>& theMirrorLine,
+ const FeaturePtr& theOriginal,
+ const FeaturePtr& theMirrored)
+{
+ std::list<AttributePtr> aPoints0 =
+ theOriginal->data()->attributes(GeomDataAPI_Point2D::typeId());
+ std::list<AttributePtr> 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<AttributePtr>::iterator anIt0, anIt1;
+ for (anIt0 = aPoints0.begin(), anIt1 = aPoints1.begin();
+ anIt0 != aPoints0.end() && anIt1 != aPoints1.end(); ++anIt0, ++anIt1) {
+ AttributePoint2DPtr aPt0 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt0);
+ AttributePoint2DPtr aPt1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt1);
+ if (aPt0->isInitialized() && aPt1->isInitialized())
+ mirrorPoints(theMirrorLine, aPt0, aPt1);
+ }