From cc2901b0a31e8e718ce04afaabde5d2d381feb7a Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 14 Dec 2016 14:44:58 +0300 Subject: [PATCH] Fix for some problems in the arc inversion and added a unit test for it --- src/ModelAPI/ModelAPI.i | 3 + src/SketchPlugin/CMakeLists.txt | 3 +- src/SketchPlugin/SketchPlugin_Arc.cpp | 16 ++- src/SketchPlugin/Test/TestArcBehavior.py | 133 +++++++++++++++++++++++ 4 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 src/SketchPlugin/Test/TestArcBehavior.py diff --git a/src/ModelAPI/ModelAPI.i b/src/ModelAPI/ModelAPI.i index 6fd73dedb..29c049f7a 100644 --- a/src/ModelAPI/ModelAPI.i +++ b/src/ModelAPI/ModelAPI.i @@ -172,3 +172,6 @@ template std::shared_ptr shared_ptr_cast(std::shared_ptr %template(modelAPI_AttributeRefList) shared_ptr_cast; %template(modelAPI_AttributeRefAttrList) shared_ptr_cast; %template(modelAPI_AttributeTables) shared_ptr_cast; + +// Geometry casts +%template(shapeToEdge) shared_ptr_cast; diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index c0d06f3bf..dd373fe5a 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -142,4 +142,5 @@ ADD_UNIT_TESTS(TestSketchPointLine.py TestProjection.py TestSplit.py TestHighload.py - TestSnowflake.py) + TestSnowflake.py + TestArcBehavior.py ) diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 90801362d..be7ad7dc7 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -442,14 +442,12 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) std::shared_ptr aCircleForArc(new GeomAPI_Circ2d(aCenter, aStart)); data()->blockSendAttributeUpdated(true); - if (theID == END_ID() && isStable()) { - // The arc is under construction, so its end point projected - // on the circle formed by center and start points - std::shared_ptr aProjection = aCircleForArc->project(anEnd); - if (aProjection && anEnd->distance(aProjection) > tolerance) { - anEndAttr->setValue(aProjection); - anEnd = aProjection; - } + // The Arc end point is projected + // on the circle formed by center and start points + std::shared_ptr aProjection = aCircleForArc->project(anEnd); + if (aProjection && anEnd->distance(aProjection) > tolerance) { + anEndAttr->setValue(aProjection); + anEnd = aProjection; } // update all other attributes due to the base attributes values if (aTypeAttr->value() == ARC_TYPE_THREE_POINTS()) { @@ -518,7 +516,7 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) AttributeBooleanPtr isInversed = std::dynamic_pointer_cast(attribute(INVERSED_ID())); double aParameterNew = aEndParam - aStartParam; - if (0 <= myParamBefore && myParamBefore <= PI / 2.0 && + if (((0 <= myParamBefore && myParamBefore <= PI / 2.0) || myParamBefore == PI * 2.0) && PI * 1.5 <= aParameterNew && aParameterNew <= PI * 2.0) isInversed->setValue(true); else if (PI * 1.5 <= myParamBefore && myParamBefore <= PI * 2.0 && diff --git a/src/SketchPlugin/Test/TestArcBehavior.py b/src/SketchPlugin/Test/TestArcBehavior.py new file mode 100644 index 000000000..7498a37d5 --- /dev/null +++ b/src/SketchPlugin/Test/TestArcBehavior.py @@ -0,0 +1,133 @@ +""" + TestArcBehavior.py + + It tests behavior of the arc during the changing of parameters to avoid + regressions in this complicated part. + +""" + +#========================================================================= +# of the test +#========================================================================= +from GeomDataAPI import * +from ModelAPI import * +import math + +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() +#========================================================================= +# Creation of a sketch +#========================================================================= +aSession.startOperation() +#aSketchFeature = aDocument.addFeature("Sketch") +aSketchCommonFeature = aDocument.addFeature("Sketch") +aSketchFeature = featureToCompositeFeature(aSketchCommonFeature) +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() +#========================================================================= +# Test creation of arc and movements (of mouse coursor) of end point near to the start point: +# edge must be the minimal length. +#========================================================================= +aSession.startOperation() +aSketchArc = aSketchFeature.addFeature("SketchArc") +anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter")) +anArcCentr.setValue(0., 0.) +anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint")) +anArcStartPoint.setValue(0., 10.) +anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint")) +anArcEndPoint.setValue(1., 10.) +aSession.finishOperation() +# the arc must be small, not near to the whole circle +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 2. +# move to the half-circle +aSession.startOperation() +anArcEndPoint.setValue(10., 0.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 16. +aSession.startOperation() +anArcEndPoint.setValue(0., -10.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 31. +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 32. +aSession.startOperation() +anArcEndPoint.setValue(-10., 0.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 47. +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 48. +aSession.startOperation() +anArcEndPoint.setValue(-1., 10.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 60. +# move to the initial point at the right side: the edge must reset to the initial one +aSession.startOperation() +anArcEndPoint.setValue(1., 10.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 2. +# move to the counterclockwise direction +aSession.startOperation() +anArcEndPoint.setValue(-1., 10.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 2. +aSession.startOperation() +anArcEndPoint.setValue(-10., 0.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 16. +aSession.startOperation() +anArcEndPoint.setValue(0., -10.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 31. +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 32. +aSession.startOperation() +anArcEndPoint.setValue(10., 0.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 47. +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 48. +aSession.startOperation() +anArcEndPoint.setValue(1., 10.) +aSession.finishOperation() +assert shapeToEdge(aSketchArc.lastResult().shape()).length() > 60. +# check from the scratch that from initial state to counterclockwise position also works +aSession.startOperation() +aSketchArc = aSketchFeature.addFeature("SketchArc") +anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter")) +anArcCentr.setValue(0., 0.) +anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint")) +anArcStartPoint.setValue(0., 10.) +anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint")) +anArcEndPoint.setValue(-1., 10.) +aSession.finishOperation() +# the arc must be small, not near to the whole circle +assert shapeToEdge(aSketchArc.lastResult().shape()).length() < 2. +#========================================================================= +# Test that movement of the center of arc does not change the orientation of the arc +#========================================================================= +aSession.startOperation() +aSketchArc = aSketchFeature.addFeature("SketchArc") +anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter")) +anArcCentr.setValue(0., 0.) +anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint")) +anArcStartPoint.setValue(0., 10.) +anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint")) +anArcEndPoint.setValue(10, 0.) +aSession.finishOperation() +anInversed = aSketchArc.boolean("InversedArc").value() +for aCenterCoords in range(1, 20): + aSession.startOperation() + anArcCentr.setValue(aCenterCoords, aCenterCoords/2) # move center + aSession.finishOperation() + assert aSketchArc.boolean("InversedArc").value() == anInversed +for aCenterCoords in range(20, -20, -1): + aSession.startOperation() + anArcCentr.setValue(aCenterCoords, aCenterCoords/2) # move center + aSession.finishOperation() + assert aSketchArc.boolean("InversedArc").value() == anInversed +for aCenterCoords in range(-20, 20): + aSession.startOperation() + anArcCentr.setValue(aCenterCoords, aCenterCoords/2) # move center + aSession.finishOperation() + assert aSketchArc.boolean("InversedArc").value() == anInversed -- 2.39.2