From f9d0d44c905c059bec472760bc436e06149c92ac Mon Sep 17 00:00:00 2001 From: azv Date: Wed, 1 Mar 2017 14:49:10 +0300 Subject: [PATCH] Update constraint Tangent to process non-connected features. Improve corresponding test case. Add test case for removing sketch. --- src/ModelAPI/ModelAPI.i | 1 + src/SketchPlugin/CMakeLists.txt | 3 +- src/SketchPlugin/SketchPlugin_Arc.cpp | 5 + src/SketchPlugin/SketchPlugin_Validators.cpp | 75 +------ .../Test/TestConstraintTangent.py | 198 ++++++++++++------ src/SketchPlugin/Test/TestRemoveSketch.py | 42 ++++ .../PlaneGCSSolver/PlaneGCSSolver_Tools.cpp | 5 +- .../SketchSolver_ConstraintTangent.cpp | 24 +-- src/SketchSolver/SketchSolver_Group.cpp | 2 +- .../SketchSolver_IConstraintWrapper.h | 3 +- 10 files changed, 203 insertions(+), 155 deletions(-) create mode 100644 src/SketchPlugin/Test/TestRemoveSketch.py diff --git a/src/ModelAPI/ModelAPI.i b/src/ModelAPI/ModelAPI.i index 29c049f7a..7f3b0c19b 100644 --- a/src/ModelAPI/ModelAPI.i +++ b/src/ModelAPI/ModelAPI.i @@ -139,6 +139,7 @@ %template(DocumentList) std::list >; // std::set -> [] %template(AttributeSet) std::set >; +%template(FeatureSet) std::set >; // std::dynamic_pointer_cast template std::shared_ptr shared_ptr_cast(std::shared_ptr theObject); diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index c72d4ef9e..58d79f847 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -145,4 +145,5 @@ ADD_UNIT_TESTS(TestSketchPointLine.py TestSnowflake.py TestArcBehavior.py Test1061.py - Test1924.py ) + Test1924.py + TestRemoveSketch.py ) diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 3b7e41349..c800c58f6 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -164,6 +164,11 @@ void SketchPlugin_Arc::execute() aConstr2->setIsInHistory(false); setResult(aConstr2, 1); } + + if (!hasResult && string(ARC_TYPE())->value() == ARC_TYPE_TANGENT()) { + // constraints for tangent arc have not been prepared yet, do them + tangencyArcConstraints(); + } } } diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 98c9ee9fc..51d0b8fc1 100755 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -108,57 +108,6 @@ bool SketchPlugin_DistanceAttrValidator::isValid(const AttributePtr& theAttribut return true; } -static bool isCoincident(FeaturePtr theFeature1, FeaturePtr theFeature2) -{ - AttributePtr aFeature1PointAttr[2]; - if(theFeature1->getKind() == SketchPlugin_Line::ID()) { - aFeature1PointAttr[0] = theFeature1->attribute(SketchPlugin_Line::START_ID()); - aFeature1PointAttr[1] = theFeature1->attribute(SketchPlugin_Line::END_ID()); - } else if(theFeature1->getKind() == SketchPlugin_Arc::ID()) { - aFeature1PointAttr[0] = theFeature1->attribute(SketchPlugin_Arc::START_ID()); - aFeature1PointAttr[1] = theFeature1->attribute(SketchPlugin_Arc::END_ID()); - } - - std::set aRefsList = theFeature1->data()->refsToMe(); - for(std::set::const_iterator aRefIt = aRefsList.begin(); - aRefIt != aRefsList.end(); - ++aRefIt) { - // Find constraint - FeaturePtr aRefFeature = std::dynamic_pointer_cast((*aRefIt)->owner()); - if(aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID()) - continue; - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*aRefIt); - AttributePtr anAttr = aRefAttr->attr(); - if(anAttr != aFeature1PointAttr[0] && anAttr != aFeature1PointAttr[1]) - continue; - - // Get coincides from constraint. - std::set aCoinsides; - SketchPlugin_Tools::findCoincidences(aRefFeature, - SketchPlugin_ConstraintCoincidence::ENTITY_A(), - aCoinsides); - SketchPlugin_Tools::findCoincidences(aRefFeature, - SketchPlugin_ConstraintCoincidence::ENTITY_B(), - aCoinsides); - - if(aCoinsides.find(theFeature2) != aCoinsides.end()) { - return true; - } - } - - return false; -} - -static bool hasCoincidentPoint(FeaturePtr theFeature1, FeaturePtr theFeature2) -{ - if(theFeature1->getKind() == SketchPlugin_Circle::ID() || - theFeature2->getKind() == SketchPlugin_Circle::ID()) { - return false; - } - - return (isCoincident(theFeature1, theFeature2) && isCoincident(theFeature2, theFeature1)); -} - bool SketchPlugin_TangentAttrValidator::isValid(const AttributePtr& theAttribute, const std::list& theArguments, Events_InfoMessage& theError) const @@ -190,11 +139,6 @@ bool SketchPlugin_TangentAttrValidator::isValid(const AttributePtr& theAttribute if (!aOtherFea) return true; - if ((aRefFea->getKind() == SketchPlugin_Arc::ID() || - aOtherFea->getKind() == SketchPlugin_Arc::ID()) && - !hasCoincidentPoint(aRefFea, aOtherFea)) - return false; - if (aRefFea->getKind() == SketchPlugin_Line::ID()) { if (aOtherFea->getKind() != SketchPlugin_Arc::ID() && aOtherFea->getKind() != SketchPlugin_Circle::ID()) { @@ -204,20 +148,15 @@ bool SketchPlugin_TangentAttrValidator::isValid(const AttributePtr& theAttribute return false; } } - else if (aRefFea->getKind() == SketchPlugin_Arc::ID()) { + else if (aRefFea->getKind() == SketchPlugin_Arc::ID() || + aRefFea->getKind() == SketchPlugin_Circle::ID()) { if (aOtherFea->getKind() != SketchPlugin_Line::ID() && - aOtherFea->getKind() != SketchPlugin_Arc::ID()) { - theError = "It refers to an %1, but %2 is not a %3 or an %4"; + aOtherFea->getKind() != SketchPlugin_Arc::ID() && + aOtherFea->getKind() != SketchPlugin_Circle::ID()) { + theError = "It refers to an %1, but %2 is not a %3 or an %4 or a %5"; theError.arg(SketchPlugin_Arc::ID()).arg(aParamA) - .arg(SketchPlugin_Line::ID()).arg(SketchPlugin_Arc::ID()); - return false; - } - } - else if (aRefFea->getKind() == SketchPlugin_Circle::ID()) { - if (aOtherFea->getKind() != SketchPlugin_Line::ID()) { - theError = "It refers to an %1, but %2 is not a %3"; - theError.arg(SketchPlugin_Circle::ID()).arg(aParamA) - .arg(SketchPlugin_Line::ID()); + .arg(SketchPlugin_Line::ID()).arg(SketchPlugin_Arc::ID()) + .arg(SketchPlugin_Circle::ID()); return false; } } diff --git a/src/SketchPlugin/Test/TestConstraintTangent.py b/src/SketchPlugin/Test/TestConstraintTangent.py index 03c9334f3..7b37ce0f3 100644 --- a/src/SketchPlugin/Test/TestConstraintTangent.py +++ b/src/SketchPlugin/Test/TestConstraintTangent.py @@ -20,6 +20,14 @@ from salome.shaper import model __updated__ = "2015-03-17" +def distancePointPoint(thePoint1, thePoint2): + """ + subroutine to calculate distance between two points + result of calculated distance is has 10**-5 precision + """ + aDist = math.sqrt((thePoint1.x()-thePoint2.x())**2 + (thePoint1.y()-thePoint2.y())**2) + return round(aDist, 5) + def distancePointLine(point, line): """ subroutine to calculate distance between point and line @@ -37,6 +45,42 @@ def distancePointLine(point, line): aVecY = point.y() - aStartPoint.y() return round(math.fabs(aVecX * aDirX + aVecY * aDirY), 5) +def checkArcLineTangency(theArc, theLine): + """ + subroutine to check that the line is tangent to arc/circle + """ + if (theArc.getKind() == "SketchCircle"): + aCenter = geomDataAPI_Point2D(theArc.attribute("CircleCenter")) + aRadius = theArc.real("CircleRadius").value() + else: + aCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter")) + aStartPnt = geomDataAPI_Point2D(theArc.attribute("ArcStartPoint")) + aRadius = distancePointPoint(aStartPnt, aCenter) + aDist = distancePointLine(aCenter, theLine) + assert math.fabs(aDist - aRadius) < 2.e-5, "aDist = {0}, aRadius = {1}".format(aDist, aRadius) + +def checkArcArcTangency(theArc1, theArc2): + """ + subroutine to check that arcs/circles arc tangent + """ + anArcs = [theArc1, theArc2] + aCenters = [] + aRadii = [] + for anArc in anArcs: + if (anArc.getKind() == "SketchCircle"): + aCenter = geomDataAPI_Point2D(anArc.attribute("CircleCenter")) + aRadius = anArc.real("CircleRadius").value() + else: + aCenter = geomDataAPI_Point2D(anArc.attribute("ArcCenter")) + aStartPnt = geomDataAPI_Point2D(anArc.attribute("ArcStartPoint")) + aRadius = distancePointPoint(aStartPnt, aCenter) + aCenters.append(aCenter) + aRadii.append(aRadius) + aDist = distancePointPoint(aCenters[0], aCenters[1]) + aRSum = aRadii[0] + aRadii[1] + aRDiff = math.fabs(aRadii[0] - aRadii[1]) + assert math.fabs(aDist - aRSum) < 2.e-5 or math.fabs(aDist - aRDiff) < 2.e-5, "aDist = {0}, aRSum = {1}, aRDiff = {2}".format(aDist, aRSum, aRDiff) + aSession = ModelAPI_Session.get() aDocument = aSession.moduleDocument() @@ -113,21 +157,14 @@ aTangency = aSketchFeature.addFeature("SketchConstraintTangent") aRefObjectA = aTangency.refattr("ConstraintEntityA") aRefObjectB = aTangency.refattr("ConstraintEntityB") anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult()) -anObjectB = modelAPI_ResultConstruction(aSketchLine1.firstResult()) +anObjectB = modelAPI_ResultConstruction(aSketchLine1.lastResult()) assert (anObjectA is not None) assert (anObjectB is not None) aRefObjectA.setObject(anObjectA) aRefObjectB.setObject(anObjectB) aTangency.execute() aSession.finishOperation() -anArcVecX = anArcStartPoint.x() - anArcCentr.x() -anArcVecY = anArcStartPoint.y() - anArcCentr.y() -aLen = math.sqrt(anArcVecX**2 + anArcVecY**2) -aLineVecX = aLine1EndPoint.x() - aLine1StartPoint.x() -aLineVecY = aLine1EndPoint.y() - aLine1StartPoint.y() -aLen = aLen * math.sqrt(aLineVecX**2 + aLineVecY**2) -aDot = anArcVecX * aLineVecX + anArcVecY * aLineVecY -assert math.fabs(aDot) <= 2.e-6 * aLen, "Observed dot product: {0}".format(aDot) +checkArcLineTangency(aSketchArc1, aSketchLine1) assert (model.dof(aSketchFeature) == 8) #========================================================================= # Add tangency constraint for arc and second line and check correctness @@ -137,21 +174,14 @@ aTangency = aSketchFeature.addFeature("SketchConstraintTangent") aRefObjectA = aTangency.refattr("ConstraintEntityA") aRefObjectB = aTangency.refattr("ConstraintEntityB") anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult()) -anObjectB = modelAPI_ResultConstruction(aSketchLine2.firstResult()) +anObjectB = modelAPI_ResultConstruction(aSketchLine2.lastResult()) assert (anObjectA is not None) assert (anObjectB is not None) aRefObjectA.setObject(anObjectA) aRefObjectB.setObject(anObjectB) aTangency.execute() aSession.finishOperation() -anArcVecX = anArcEndPoint.x() - anArcCentr.x() -anArcVecY = anArcEndPoint.y() - anArcCentr.y() -aLen = math.sqrt(anArcVecX**2 + anArcVecY**2) -aLineVecX = aLine2EndPoint.x() - aLine2StartPoint.x() -aLineVecY = aLine2EndPoint.y() - aLine2StartPoint.y() -aLen = aLen * math.sqrt(aLineVecX**2 + aLineVecY**2) -aDot = anArcVecX * aLineVecX + anArcVecY * aLineVecY -assert math.fabs(aDot) <= 2.e-6 * aLen, "Observed dot product: {0}".format(aDot) +checkArcLineTangency(aSketchArc1, aSketchLine2) assert (model.dof(aSketchFeature) == 7) #========================================================================= @@ -209,57 +239,95 @@ aRefObjectA.setObject(anObjectA) aRefObjectB.setObject(anObjectB) aTangency.execute() aSession.finishOperation() -anArc1VecX = anArc1EndPoint.x() - anArc1Centr.x() -anArc1VecY = anArc1EndPoint.y() - anArc1Centr.y() -aLen = math.sqrt(anArc1VecX**2 + anArc1VecY**2) -anArc2VecX = anArc2StartPoint.x() - anArc2Centr.x() -anArc2VecY = anArc2StartPoint.y() - anArc2Centr.y() -aLen = aLen * math.sqrt(anArc2VecX**2 + anArc2VecY**2) -aCross = anArc1VecX * anArc2VecY - anArc1VecY * anArc2VecX -assert math.fabs(aCross) <= 2.e-6 * aLen, "Observed cross product: {0}".format(aCross) +checkArcArcTangency(aSketchArc1, aSketchArc2) assert (model.dof(aSketchFeature) == 14) #========================================================================= -# TEST 3. Tangency between non-connected objects should be wrong -#========================================================================= -# Store data -aLine2StartPointPrev = (aLine2StartPoint.x(), aLine2StartPoint.y()) -aLine2EndPointPrev = (aLine2EndPoint.x(), aLine2EndPoint.y()) -anArc2CenterPrev = (anArc2Centr.x(), anArc2Centr.y()) -anArc2StartPointPrev = (anArc2StartPoint.x(), anArc2StartPoint.y()) -anArc2EndPointPrev = (anArc2EndPoint.x(), anArc2EndPoint.y()) -#========================================================================= -# Add tangency between arc2 and line2 +# TEST 3. Tangency between non-connected objects should work #========================================================================= +# 3.1 tangency between arc2 and line2 aSession.startOperation() aTangency = aSketchFeature.addFeature("SketchConstraintTangent") aRefObjectA = aTangency.refattr("ConstraintEntityA") aRefObjectB = aTangency.refattr("ConstraintEntityB") anObjectA = modelAPI_ResultConstruction(aSketchArc2.lastResult()) -anObjectB = modelAPI_ResultConstruction(aSketchLine2.firstResult()) +anObjectB = modelAPI_ResultConstruction(aSketchLine2.lastResult()) assert (anObjectA is not None) assert (anObjectB is not None) aRefObjectA.setObject(anObjectA) aRefObjectB.setObject(anObjectB) aTangency.execute() aSession.finishOperation() -# Check that nothing is changed -aLine2StartPointNew = (aLine2StartPoint.x(), aLine2StartPoint.y()) -aLine2EndPointNew = (aLine2EndPoint.x(), aLine2EndPoint.y()) -anArc2CenterNew = (anArc2Centr.x(), anArc2Centr.y()) -anArc2StartPointNew = (anArc2StartPoint.x(), anArc2StartPoint.y()) -anArc2EndPointNew = (anArc2EndPoint.x(), anArc2EndPoint.y()) -assert(aLine2StartPointNew == aLine2StartPointPrev) -assert(aLine2EndPointNew == aLine2EndPointPrev) -assert(anArc2CenterNew == anArc2CenterPrev) -assert(anArc2StartPointNew == anArc2StartPointPrev) -assert(anArc2EndPointNew == anArc2EndPointPrev) +checkArcLineTangency(aSketchArc2, aSketchLine2) +assert (model.dof(aSketchFeature) == 13) + +aSession.startOperation() +aDocument.removeFeature(aTangency) +aSession.finishOperation() assert (model.dof(aSketchFeature) == 14) + +# 3.2 tangency between non-connected arcs +aSession.startOperation() +aSketchArc3 = aSketchFeature.addFeature("SketchArc") +anArc3Centr = geomDataAPI_Point2D(aSketchArc3.attribute("ArcCenter")) +anArc3Centr.setValue(100., -10.) +anArc3StartPoint = geomDataAPI_Point2D(aSketchArc3.attribute("ArcStartPoint")) +anArc3StartPoint.setValue(70., -10.) +anArc3EndPoint = geomDataAPI_Point2D(aSketchArc3.attribute("ArcEndPoint")) +anArc3EndPoint.setValue(100., 20.) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 19) + +aSession.startOperation() +aTangency = aSketchFeature.addFeature("SketchConstraintTangent") +aTangency.refattr("ConstraintEntityA").setObject(modelAPI_ResultConstruction(aSketchArc2.lastResult())) +aTangency.refattr("ConstraintEntityB").setObject(modelAPI_ResultConstruction(aSketchArc3.lastResult())) +aSession.finishOperation() +checkArcArcTangency(aSketchArc2, aSketchArc3) +assert (model.dof(aSketchFeature) == 18) + aSession.startOperation() +aDocument.removeFeature(aSketchArc3) aDocument.removeFeature(aTangency) aSession.finishOperation() assert (model.dof(aSketchFeature) == 14) +# 3.3 tangency between arc and circle +aSession.startOperation() +aCircle1 = aSketchFeature.addFeature("SketchCircle") +aCircleCenter = geomDataAPI_Point2D(aCircle1.attribute("CircleCenter")) +aCircleRadius = aCircle1.real("CircleRadius") +aCircleCenter.setValue(150., 100.) +aCircleRadius.setValue(50.) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 17) + +aSession.startOperation() +aTangency1 = aSketchFeature.addFeature("SketchConstraintTangent") +aTangency1.refattr("ConstraintEntityA").setObject(modelAPI_ResultConstruction(aSketchArc2.lastResult())) +aTangency1.refattr("ConstraintEntityB").setObject(modelAPI_ResultConstruction(aCircle1.lastResult())) +aSession.finishOperation() +checkArcArcTangency(aSketchArc2, aCircle1) +assert (model.dof(aSketchFeature) == 16) + +# 3.4 tangency between two circles +aSession.startOperation() +aCircle2 = aSketchFeature.addFeature("SketchCircle") +aCircleCenter = geomDataAPI_Point2D(aCircle2.attribute("CircleCenter")) +aCircleRadius = aCircle2.real("CircleRadius") +aCircleCenter.setValue(120., 70.) +aCircleRadius.setValue(20.) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 19) + +aSession.startOperation() +aTangency2 = aSketchFeature.addFeature("SketchConstraintTangent") +aTangency2.refattr("ConstraintEntityA").setObject(modelAPI_ResultConstruction(aCircle1.lastResult())) +aTangency2.refattr("ConstraintEntityB").setObject(modelAPI_ResultConstruction(aCircle2.lastResult())) +aSession.finishOperation() +checkArcArcTangency(aCircle1, aCircle2) +assert (model.dof(aSketchFeature) == 18) + #========================================================================= # TEST 4. Creating of tangency arc by the option of the SketchArc feature #========================================================================= @@ -269,20 +337,22 @@ aSketchArc3.string("ArcType").setValue("Tangent") anArc3Start = aSketchArc3.refattr("ArcTangentPoint") anArc3Start.setAttr(anArc1StartPoint) anArc3EndPoint = geomDataAPI_Point2D(aSketchArc3.attribute("ArcEndPoint")) -anArc3EndPoint.setValue(100., 0.) +anArc3EndPoint.setValue(anArc1StartPoint.x()-5, anArc1StartPoint.y()-30) aSession.finishOperation() -anArc3Center = geomDataAPI_Point2D(aSketchArc2.attribute("ArcCenter")) -anArc3StartPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcStartPoint")) - -anArc1VecX = anArc1EndPoint.x() - anArc1Centr.x() -anArc1VecY = anArc1EndPoint.y() - anArc1Centr.y() -aLen = math.sqrt(anArc1VecX**2 + anArc1VecY**2) -anArc3VecX = anArc3StartPoint.x() - anArc3Center.x() -anArc3VecY = anArc3StartPoint.y() - anArc3Center.y() -aLen = aLen * math.sqrt(anArc3VecX**2 + anArc3VecY**2) -aCross = anArc1VecX * anArc3VecY - anArc1VecY * anArc3VecX -assert math.fabs(aCross) <= 2.e-6 * aLen, "Observed cross product: {0}".format(aCross) -assert (model.dof(aSketchFeature) == 19) +checkArcArcTangency(aSketchArc1, aSketchArc3) +# freeze radius of tangent arc +aSession.startOperation() +aConstraintRadius = aSketchFeature.addFeature("SketchConstraintRadius") +aConstraintRadius.refattr("ConstraintEntityA").setObject(modelAPI_ResultConstruction(aSketchArc3.lastResult())) +aConstraintRadius.real("ConstraintValue").setValue(30.) +aSession.finishOperation() +checkArcArcTangency(aSketchArc1, aSketchArc3) +# do not check DoF here because it is unstable for tangent arcs, +# remove tangent arc to avoid instability while dumping +aSession.startOperation() +ModelAPI.removeFeaturesAndReferences(FeatureSet([aSketchArc3])) +aSession.finishOperation() +assert (model.dof(aSketchFeature) == 18) #========================================================================= # TEST 5. Creating of tangency between line and circle @@ -299,7 +369,7 @@ aCircleRadius = aCircle.real("CircleRadius") aCircleCenter.setValue(150., 100.) aCircleRadius.setValue(20.) aSession.finishOperation() -assert (model.dof(aSketchFeature) == 26) +assert (model.dof(aSketchFeature) == 25) aSession.startOperation() aTangency = aSketchFeature.addFeature("SketchConstraintTangent") @@ -314,8 +384,8 @@ aRefObjectB.setObject(anObjectB) aTangency.execute() aSession.finishOperation() -assert(math.fabs(distancePointLine(aCircleCenter, aLine) - round(aCircleRadius.value(), 5)) < 1.e-10) -assert (model.dof(aSketchFeature) == 25) +checkArcLineTangency(aCircle, aLine) +assert (model.dof(aSketchFeature) == 24) #========================================================================= # End of test #========================================================================= diff --git a/src/SketchPlugin/Test/TestRemoveSketch.py b/src/SketchPlugin/Test/TestRemoveSketch.py new file mode 100644 index 000000000..3b5a69e8e --- /dev/null +++ b/src/SketchPlugin/Test/TestRemoveSketch.py @@ -0,0 +1,42 @@ +""" + TestRemoveSketch.py +""" +from GeomDataAPI import * +from ModelAPI import * + +#========================================================================= +# Initialization of the test +#========================================================================= +__updated__ = "2017-02-01" + +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() + +# create a sketch +aSession.startOperation() +aSketchFeature = featureToCompositeFeature(aDocument.addFeature("Sketch")) +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin")) +origin.setValue(0, 0, 0) +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX")) +dirx.setValue(1, 0, 0) +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm")) +norm.setValue(0, 0, 1) +aSession.finishOperation() + +# create a line +aSession.startOperation() +aSketchLine = aSketchFeature.addFeature("SketchLine") +aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint")) +aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint")) +aLineStartPoint.setValue(50., 0.) +aLineEndPoint.setValue(100., 25.) +aSession.finishOperation() + +# remove sketch +aSession.startOperation() +aDocument.removeFeature(aSketchFeature) +aSession.finishOperation() + +#========================================================================= +# End of test +#========================================================================= diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp index 5f10b68e1..fcac0cb47 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp @@ -204,9 +204,8 @@ ConstraintWrapperPtr PlaneGCSSolver_Tools::createConstraint( GCS_ENTITY_WRAPPER(theEntity2), anIntermediate); break; - case CONSTRAINT_TANGENT_ARC_LINE: case CONSTRAINT_TANGENT_CIRCLE_LINE: - case CONSTRAINT_TANGENT_ARC_ARC: + case CONSTRAINT_TANGENT_CIRCLE_CIRCLE: aResult = createConstraintTangent(theType, GCS_ENTITY_WRAPPER(theEntity1), GCS_ENTITY_WRAPPER(theEntity2)); @@ -498,7 +497,7 @@ ConstraintWrapperPtr createConstraintTangent( std::shared_ptr theEntity2) { GCSConstraintPtr aNewConstr; - if (theType == CONSTRAINT_TANGENT_ARC_LINE || theType == CONSTRAINT_TANGENT_CIRCLE_LINE) { + if (theType == CONSTRAINT_TANGENT_CIRCLE_LINE) { std::shared_ptr aCirc = std::dynamic_pointer_cast(theEntity1->entity()); std::shared_ptr aLine = diff --git a/src/SketchSolver/SketchSolver_ConstraintTangent.cpp b/src/SketchSolver/SketchSolver_ConstraintTangent.cpp index ab4a27ea7..2551c2074 100644 --- a/src/SketchSolver/SketchSolver_ConstraintTangent.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintTangent.cpp @@ -47,35 +47,27 @@ void SketchSolver_ConstraintTangent::getAttributes( // Check the quantity of entities of each type and their order (arcs first) int aNbLines = 0; - int aNbArcs = 0; int aNbCircles = 0; bool isSwap = false; // whether need to swap arguments (arc goes before line) std::vector::iterator anEntIt = theAttributes.begin() + 2; for (; anEntIt != theAttributes.end(); ++anEntIt) { if ((*anEntIt)->type() == ENTITY_LINE) ++aNbLines; - else if ((*anEntIt)->type() == ENTITY_ARC) { - ++aNbArcs; - isSwap = aNbLines > 0; - } - else if ((*anEntIt)->type() == ENTITY_CIRCLE) { + else if ((*anEntIt)->type() == ENTITY_ARC || (*anEntIt)->type() == ENTITY_CIRCLE) { ++aNbCircles; isSwap = aNbLines > 0; } } - if (aNbArcs < 1 && aNbCircles < 1) { + if (aNbCircles < 1) { myErrorMsg = SketchSolver_Error::INCORRECT_TANGENCY_ATTRIBUTE(); return; } - if (aNbLines == 1) { - if (aNbArcs == 1) - myType = CONSTRAINT_TANGENT_ARC_LINE; - else if (aNbCircles == 1) - myType = CONSTRAINT_TANGENT_CIRCLE_LINE; + if (aNbLines == 1 && aNbCircles == 1) { + myType = CONSTRAINT_TANGENT_CIRCLE_LINE; } - else if (aNbArcs == 2) { - myType = CONSTRAINT_TANGENT_ARC_ARC; + else if (aNbCircles == 2) { + myType = CONSTRAINT_TANGENT_CIRCLE_CIRCLE; isArcArcInternal = PlaneGCSSolver_Tools::isArcArcTangencyInternal(theAttributes[2], theAttributes[3]); } @@ -84,7 +76,7 @@ void SketchSolver_ConstraintTangent::getAttributes( return; } - if (myType == CONSTRAINT_TANGENT_ARC_LINE) { + if (myType == CONSTRAINT_TANGENT_CIRCLE_LINE) { AttributeRefAttrPtr aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A()); FeaturePtr aFeature1 = ModelAPI_Feature::feature(aRefAttr->object()); aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_B()); @@ -103,7 +95,7 @@ void SketchSolver_ConstraintTangent::getAttributes( void SketchSolver_ConstraintTangent::adjustConstraint() { - if (myType == CONSTRAINT_TANGENT_ARC_ARC) { + if (myType == CONSTRAINT_TANGENT_CIRCLE_CIRCLE) { EntityWrapperPtr anEntity1 = myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); EntityWrapperPtr anEntity2 = diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index ce576cdbf..1360e1b6a 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -198,7 +198,7 @@ bool SketchSolver_Group::resolveConstraints() } if (aCIt == myConstraints.end()) myStorage->refresh(); - } else if (isGroupEmpty) + } else if (isGroupEmpty && isWorkplaneValid()) computeDoF(); removeTemporaryConstraints(); myStorage->setNeedToResolve(false); diff --git a/src/SketchSolver/SketchSolver_IConstraintWrapper.h b/src/SketchSolver/SketchSolver_IConstraintWrapper.h index 3fa42f14d..52157057e 100644 --- a/src/SketchSolver/SketchSolver_IConstraintWrapper.h +++ b/src/SketchSolver/SketchSolver_IConstraintWrapper.h @@ -38,9 +38,8 @@ enum SketchSolver_ConstraintType { CONSTRAINT_EQUAL_LINE_ARC, CONSTRAINT_EQUAL_RADIUS, CONSTRAINT_TANGENT, // base tangency if we don't know the measured objects yet - CONSTRAINT_TANGENT_ARC_LINE, CONSTRAINT_TANGENT_CIRCLE_LINE, - CONSTRAINT_TANGENT_ARC_ARC, + CONSTRAINT_TANGENT_CIRCLE_CIRCLE, CONSTRAINT_COLLINEAR, CONSTRAINT_MULTI_TRANSLATION, CONSTRAINT_MULTI_ROTATION -- 2.39.2