std::dynamic_pointer_cast<PlaneGCSSolver_EntityWrapper>(theArc);
std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anArcEnt->entity());
// Distances from center till start and end points are equal to radius
- anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
- anArc->center, anArc->start, anArc->rad)));
- anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
- anArc->center, anArc->end, anArc->rad)));
+ GCSConstraintPtr aNew = GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+ anArc->center, anArc->start, anArc->rad));
+// aNew->setTag((int)(++myConstraintLastID));
+ anArcConstraints.push_back(aNew);
+ aNew = GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+ anArc->center, anArc->end, anArc->rad));
+// aNew->setTag((int)myConstraintLastID);
+ anArcConstraints.push_back(aNew);
// Angles of start and end points should be equal to given angles
- anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
- anArc->center, anArc->start, anArc->startAngle)));
- anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
- anArc->center, anArc->end, anArc->endAngle)));
+ aNew = GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+ anArc->center, anArc->start, anArc->startAngle));
+// aNew->setTag((int)myConstraintLastID);
+ anArcConstraints.push_back(aNew);
+ aNew = GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+ anArc->center, anArc->end, anArc->endAngle));
+// aNew->setTag((int)myConstraintLastID);
+ anArcConstraints.push_back(aNew);
myArcConstraintMap[theArc] = anArcConstraints;
}
// which will conflict with all parameters fixed:
// 1. take center
getParametersToMove(*aSIt++, theParamList);
- // 2. take start point
- getParametersToMove(*aSIt++, theParamList);
- // 3. skip end point, radius and start angle, but take end angle parameter
+ // 2. skip start and end points
+ ++aSIt;
+ // 3. take radius, start angle and end angle parameters
+ getParametersToMove(*(++aSIt), theParamList);
+ getParametersToMove(*(++aSIt), theParamList);
getParametersToMove(*(++aSIt), theParamList);
} else {
for (; aSIt != aSubs.end(); ++aSIt)
#include "SketchSolver_Error.h"
#include <Events_Loop.h>
+
+#include <GeomDataAPI_Point2D.h>
+
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeRefList.h>
#include <ModelAPI_Data.h>
continue;
std::set<AttributePtr> aCoincidentPoints;
+ std::set<AttributePtr> aFixedPoints;
std::map<AttributePtr, std::set<FeaturePtr> > aPointOnLine;
std::list<std::set<AttributePtr> > aPointsInMultiConstraints;
int aDoF = 0;
}
}
if (aCoincPoint[0] && aCoincPoint[1]) {
+ bool isDoFDecreased = false;
// point-point coincidence
if (aCoincidentPoints.find(aCoincPoint[0]) == aCoincidentPoints.end() ||
- aCoincidentPoints.find(aCoincPoint[1]) == aCoincidentPoints.end())
+ aCoincidentPoints.find(aCoincPoint[1]) == aCoincidentPoints.end()) {
aDoF -= 2;
+ isDoFDecreased = true;
+ }
// check the coincident point is used in "multi" constraints
std::list<std::set<AttributePtr> >::const_iterator
aPtIt = aPointsInMultiConstraints.begin();
if (isFound[0] && isFound[1])
break;
}
+ // check both points are fixed => not need to decrease DoF
+ bool isFixed[2] = { aFixedPoints.find(aCoincPoint[0]) != aFixedPoints.end(),
+ aFixedPoints.find(aCoincPoint[1]) != aFixedPoints.end() };
+ if (isFixed[0] && isFixed[1] && isDoFDecreased)
+ aDoF += 2; // revert decrease of DoF
+ else if (isFixed[0] && !isFixed[1])
+ aFixedPoints.insert(aCoincPoint[1]);
+ else if (!isFixed[0] && isFixed[1])
+ aFixedPoints.insert(aCoincPoint[0]);
} else {
aDoF -= 1;
if (aCoincPoint[0] && aCoincLine) {
AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
aFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
assert(aRefAttr);
- if (!aRefAttr->isObject())
+ std::set<AttributePtr> aPoints;
+ if (!aRefAttr->isObject()) {
aDoF -= 2; // attribute is a point
- else {
+ aPoints.insert(aRefAttr->attr());
+ } else {
FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object());
if (anAttr)
aDoF -= aDoFDelta[anAttr->getKind()];
+ std::list<AttributePtr> aPtAttrs = anAttr->data()->attributes(GeomDataAPI_Point2D::typeId());
+ aPoints.insert(aPtAttrs.begin(), aPtAttrs.end());
+ }
+
+ // Check whether feature's points are already coincident with fixed points.
+ // In this case we need to revert decrease of DoF for these points.
+ // If the coordinates of fixed points are different, it will be processed by solver.
+ for (int k = 0; k < i; ++k) {
+ FeaturePtr aFeature = aSketch->subFeature(k);
+ if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
+ continue;
+ AttributePtr aCoincPoint[2] = {AttributePtr(), AttributePtr()};
+ for (int j = 0; j < 2; ++j) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aFeature->attribute(SketchPlugin_Constraint::ATTRIBUTE(j)));
+ if (!aRefAttr)
+ continue;
+ if (!aRefAttr->isObject())
+ aCoincPoint[j] = aRefAttr->attr();
+ else {
+ FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object());
+ if (anAttr && anAttr->getKind() == SketchPlugin_Point::ID())
+ aCoincPoint[j] = anAttr->attribute(SketchPlugin_Point::COORD_ID());
+ }
+ }
+ if (aCoincPoint[0] && aCoincPoint[1]) {
+ if ((aFixedPoints.find(aCoincPoint[0]) != aFixedPoints.end() &&
+ aPoints.find(aCoincPoint[1]) != aPoints.end()) ||
+ (aFixedPoints.find(aCoincPoint[1]) != aFixedPoints.end() &&
+ aPoints.find(aCoincPoint[0]) != aPoints.end()))
+ aDoF += 2; // point already fixed
+ }
}
+ // store fixed points
+ aFixedPoints.insert(aPoints.begin(), aPoints.end());
}
else if (aFeature->getKind() == SketchPlugin_ConstraintMirror::ID() ||
aFeature->getKind() == SketchPlugin_MultiRotation::ID() ||