From d27cd93c5e727aae763ce665849b735bc18611ee Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 5 Jul 2016 15:03:37 +0300 Subject: [PATCH] Middle point decrease 2 DoF (issue #1625) --- .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 2 + src/SketchSolver/SketchSolver_Manager.cpp | 52 ++++++++++++++++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 08bddb275..d20e4cdc6 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -76,6 +76,8 @@ bool PlaneGCSSolver_Storage::update(ConstraintWrapperPtr theConstraint) anIt = myConstraintMap.begin(); for (; anIt != myConstraintMap.end(); ++anIt) { EntityWrapperPtr aPoint, aLine; + if (anIt->second.empty()) + continue; ConstraintWrapperPtr aCurrentConstr = anIt->second.front(); if (aCurrentConstr->type() != CONSTRAINT_PT_ON_LINE) continue; diff --git a/src/SketchSolver/SketchSolver_Manager.cpp b/src/SketchSolver/SketchSolver_Manager.cpp index 839f97736..c83f544f2 100644 --- a/src/SketchSolver/SketchSolver_Manager.cpp +++ b/src/SketchSolver/SketchSolver_Manager.cpp @@ -557,7 +557,6 @@ void SketchSolver_Manager::degreesOfFreedom() aDoFDelta[SketchPlugin_ConstraintEqual::ID()] = -1; aDoFDelta[SketchPlugin_ConstraintHorizontal::ID()] = -1; aDoFDelta[SketchPlugin_ConstraintLength::ID()] = -1; - aDoFDelta[SketchPlugin_ConstraintMiddle::ID()] = -1; aDoFDelta[SketchPlugin_ConstraintParallel::ID()] = -1; aDoFDelta[SketchPlugin_ConstraintPerpendicular::ID()] = -1; aDoFDelta[SketchPlugin_ConstraintRadius::ID()] = -1; @@ -593,6 +592,7 @@ void SketchSolver_Manager::degreesOfFreedom() continue; std::set aCoincidentPoints; + std::map > aPointOnLine; std::list > aPointsInMultiConstraints; int aDoF = 0; int aNbSubs = aSketch->numberOfSubs(); @@ -608,19 +608,22 @@ void SketchSolver_Manager::degreesOfFreedom() // DoF delta in specific cases if (aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { AttributePtr aCoincPoint[2] = {AttributePtr(), AttributePtr()}; + FeaturePtr aCoincLine; for (int j = 0; j < 2; ++j) { AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( aFeature->attribute(SketchPlugin_Constraint::ATTRIBUTE(j))); if (!aRefAttr) continue; - bool isPoint = !aRefAttr->isObject(); - if (isPoint) + if (!aRefAttr->isObject()) aCoincPoint[j] = aRefAttr->attr(); else { FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object()); - isPoint = anAttr && anAttr->getKind() == SketchPlugin_Point::ID(); - if (isPoint) + if (!anAttr) + continue; + if (anAttr->getKind() == SketchPlugin_Point::ID()) aCoincPoint[j] = anAttr->attribute(SketchPlugin_Point::COORD_ID()); + else if (anAttr->getKind() == SketchPlugin_Line::ID()) + aCoincLine = anAttr; } } if (aCoincPoint[0] && aCoincPoint[1]) { @@ -639,12 +642,49 @@ void SketchSolver_Manager::degreesOfFreedom() if (isFound[0] && isFound[1]) break; } - } else + } else { aDoF -= 1; + if (aCoincPoint[0] && aCoincLine) { + // if the point is already coincident to a line (by middle point constraint), do not decrease DoF + std::map >::iterator + aPtFound = aPointOnLine.find(aCoincPoint[0]); + if (aPtFound != aPointOnLine.end() && + aPtFound->second.find(aCoincLine) != aPtFound->second.end()) + aDoF += 1; // restore value decreased above + else + aPointOnLine[aCoincPoint[0]].insert(aCoincLine); + } + } for (int j = 0; j < 2; ++j) if (aCoincPoint[j]) aCoincidentPoints.insert(aCoincPoint[j]); } + else if (aFeature->getKind() == SketchPlugin_ConstraintMiddle::ID()) { + AttributePtr aPoint; + FeaturePtr aLine; + for (int j = 0; j < 2; ++j) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_Constraint::ATTRIBUTE(j))); + if (!aRefAttr) + continue; + if (aRefAttr->isObject()) + aLine = ModelAPI_Feature::feature(aRefAttr->object()); + else + aPoint = aRefAttr->attr(); + } + if (aPoint && aLine) { + // if the point is already on the line, decrease 1 DoF, instead decrease 2 DoF + std::map >::iterator + aPtFound = aPointOnLine.find(aPoint); + if (aPtFound != aPointOnLine.end() && + aPtFound->second.find(aLine) != aPtFound->second.end()) + aDoF -= 1; + else { + aDoF -= 2; + aPointOnLine[aPoint].insert(aLine); + } + } + } else if (aFeature->getKind() == SketchPlugin_ConstraintRigid::ID()) { AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( aFeature->attribute(SketchPlugin_Constraint::ENTITY_A())); -- 2.30.2