From ed721b9f1a622ab9134f908883a191fd34e4edc6 Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 18 Jan 2016 10:55:25 +0300 Subject: [PATCH] Update sketcher unit tests for code coverage --- .../Test/TestConstraintConcidence.py | 2 +- .../Test/TestConstraintDistance.py | 81 +++++++++++-- src/SketchPlugin/Test/TestConstraintMirror.py | 5 +- src/SketchPlugin/Test/TestFillet.py | 111 ++++++++++++++++-- src/SketchPlugin/Test/TestMultiRotation.py | 58 ++++++++- src/SketchPlugin/Test/TestMultiTranslation.py | 60 +++++++++- .../SketchSolver_ConstraintMulti.cpp | 37 +++++- .../SketchSolver_ConstraintMulti.h | 6 + src/SketchSolver/SketchSolver_Group.cpp | 27 ----- src/SketchSolver/SketchSolver_Group.h | 4 - 10 files changed, 325 insertions(+), 66 deletions(-) diff --git a/src/SketchPlugin/Test/TestConstraintConcidence.py b/src/SketchPlugin/Test/TestConstraintConcidence.py index 43ef29837..81e34ef70 100644 --- a/src/SketchPlugin/Test/TestConstraintConcidence.py +++ b/src/SketchPlugin/Test/TestConstraintConcidence.py @@ -133,7 +133,7 @@ aSession.startOperation() aDocument.removeFeature(aConstraint) aSession.finishOperation() aSession.startOperation() -aLineStartPoint.setValue(70., 0.) +aLineStartPoint.setValue(50., 0.) aSession.finishOperation() assert (anArcEndPoint.x() != aLineStartPoint.x() or anArcEndPoint.y() != aLineStartPoint.y()) diff --git a/src/SketchPlugin/Test/TestConstraintDistance.py b/src/SketchPlugin/Test/TestConstraintDistance.py index 1e0880e68..f1fa087b1 100644 --- a/src/SketchPlugin/Test/TestConstraintDistance.py +++ b/src/SketchPlugin/Test/TestConstraintDistance.py @@ -29,7 +29,7 @@ import math __updated__ = "2014-10-28" -def distance(pointA, pointB): +def distancePointPoint(pointA, pointB): """ subroutine to calculate distance between two points result of calculated distance is has 10**-5 precision @@ -38,6 +38,23 @@ def distance(pointA, pointB): ydiff = math.pow((pointA.y() - pointB.y()), 2) return round(math.sqrt(xdiff + ydiff), 5) +def distancePointLine(point, line): + """ + subroutine to calculate distance between point and line + result of calculated distance is has 10**-5 precision + """ + aStartPoint = geomDataAPI_Point2D(line.attribute("StartPoint")) + aEndPoint = geomDataAPI_Point2D(line.attribute("EndPoint")) + # orthogonal direction + aDirX = -(aEndPoint.y() - aStartPoint.y()) + aDirY = (aEndPoint.x() - aStartPoint.x()) + aLen = math.sqrt(aDirX**2 + aDirY**2) + aDirX = aDirX / aLen + aDirY = aDirY / aLen + aVecX = point.x() - aStartPoint.x() + aVecY = point.y() - aStartPoint.y() + return round(math.fabs(aVecX * aDirX + aVecY * aDirY), 5) + aSession = ModelAPI_Session.get() aDocument = aSession.moduleDocument() #========================================================================= @@ -70,7 +87,9 @@ aSession.finishOperation() #========================================================================= # Make a constraint to keep the distance #========================================================================= -assert (distance(aSketchPointCoords, aLineAStartPoint) != 25.) +PT_PT_DIST = 25. +aDist = distancePointPoint(aSketchPointCoords, aLineAStartPoint); +assert (aDist != PT_PT_DIST) aSession.startOperation() aConstraint = aSketchFeature.addFeature("SketchConstraintDistance") aDistance = aConstraint.real("ConstraintValue") @@ -79,32 +98,70 @@ refattrB = aConstraint.refattr("ConstraintEntityB") assert (not aDistance.isInitialized()) assert (not refattrA.isInitialized()) assert (not refattrB.isInitialized()) -aDistance.setValue(25.) aLineResult = aSketchLine.firstResult() assert (aLineResult is not None) refattrA.setAttr(aSketchPointCoords) refattrB.setAttr(aLineAStartPoint) aSession.finishOperation() -assert (aDistance.isInitialized()) assert (refattrA.isInitialized()) assert (refattrB.isInitialized()) +assert (aDistance.isInitialized()) +assert math.fabs(aDistance.value() - aDist) < 1.e-4, "Distance values are different: {0} != {1}".format(aDistance.value(), aDist) +#========================================================================= +# Change distance value +#========================================================================= +aSession.startOperation() +aDistance.setValue(PT_PT_DIST) +aSession.finishOperation() +assert (distancePointPoint(aSketchPointCoords, aLineAStartPoint) == PT_PT_DIST) #========================================================================= # Move line, check that distance is constant #========================================================================= -assert (distance(aSketchPointCoords, aLineAStartPoint) == 25.) aSession.startOperation() aLineAStartPoint.setValue(0., 40.) aLineAEndPoint.setValue(100., 40.) aSession.finishOperation() -assert (distance(aSketchPointCoords, aLineAStartPoint) == 25.) +assert (distancePointPoint(aSketchPointCoords, aLineAStartPoint) == PT_PT_DIST) #========================================================================= -# TODO: improve test -# 1. remove constraint, move line's start point to -# check that constraint are not applied -# 2. check constrained distance between: -# * point and line -# * two lines +# Remove constraint, check the points are unconstrained now #========================================================================= +aSession.startOperation() +aDocument.removeFeature(aConstraint) +aSession.finishOperation() +aSession.startOperation() +aSketchPointCoords.setValue(0., 0.) +aSession.finishOperation() +assert (distancePointPoint(aSketchPointCoords, aLineAStartPoint) != PT_PT_DIST) + +#========================================================================= +# Add distance between point and line +#========================================================================= +PT_LINE_DIST = 50. +aDist = distancePointLine(aSketchPointCoords, aSketchLine) +aSession.startOperation() +aConstraint = aSketchFeature.addFeature("SketchConstraintDistance") +aDistance = aConstraint.real("ConstraintValue") +refattrA = aConstraint.refattr("ConstraintEntityA") +refattrB = aConstraint.refattr("ConstraintEntityB") +assert (not aDistance.isInitialized()) +assert (not refattrA.isInitialized()) +assert (not refattrB.isInitialized()) +aLineResult = aSketchLine.firstResult() +assert (aLineResult is not None) +refattrA.setObject(aLineResult) +refattrB.setAttr(aSketchPointCoords) +aSession.finishOperation() +assert (refattrA.isInitialized()) +assert (refattrB.isInitialized()) +assert (aDistance.isInitialized()) +assert math.fabs(aDistance.value() - aDist) < 1.e-4, "Distance values are different: {0} != {1}".format(aDistance.value(), aDist) +#========================================================================= +# Change distance value +#========================================================================= +aSession.startOperation() +aDistance.setValue(PT_LINE_DIST) +aSession.finishOperation() +assert (distancePointLine(aSketchPointCoords, aSketchLine) == PT_LINE_DIST) #========================================================================= # End of test #========================================================================= diff --git a/src/SketchPlugin/Test/TestConstraintMirror.py b/src/SketchPlugin/Test/TestConstraintMirror.py index 319a725d6..6c3678970 100644 --- a/src/SketchPlugin/Test/TestConstraintMirror.py +++ b/src/SketchPlugin/Test/TestConstraintMirror.py @@ -22,7 +22,6 @@ __updated__ = "2015-03-17" # Auxiliary functions #========================================================================= def checkMirror(theListInit, theListMirr, theMirrorLine): - TOL = 1.e-8 aListSize = theListInit.size() aLineStartPoint = geomDataAPI_Point2D(theMirrorLine.attribute("StartPoint")) @@ -49,11 +48,11 @@ def checkMirror(theListInit, theListMirr, theMirrorLine): aDirX = aPointC.x() - aPointB.x() aDirY = aPointC.y() - aPointB.y() aDot = aLineDirX * aDirX + aLineDirY * aDirY - assert math.fabs(aDot) < TOL, "aDot = {0}".format(aDot) + assert(math.fabs(aDot) < 1.e-10) aDirX = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x()) aDirY = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y()) aCross = aLineDirX * aDirY - aLineDirY * aDirX - assert math.fabs(aCross) < TOL, "aCross = {0}".format(aCross) + assert(math.fabs(aCross) < 1.e-10) #========================================================================= diff --git a/src/SketchPlugin/Test/TestFillet.py b/src/SketchPlugin/Test/TestFillet.py index 72bf010eb..b4f648693 100644 --- a/src/SketchPlugin/Test/TestFillet.py +++ b/src/SketchPlugin/Test/TestFillet.py @@ -19,7 +19,7 @@ import math #========================================================================= aStartPoint1 = [] -def createSketch(theSketch): +def createSketch1(theSketch): global aStartPoint1 # Initialize sketch by two lines with coincident boundary allFeatures = [] @@ -44,9 +44,39 @@ def createSketch(theSketch): theSketch.execute() return allFeatures + + +def createSketch2(theSketch): + global aStartPoint1 + # Initialize sketch by line and arc with coincident boundary + allFeatures = [] + # Line + aSketchLine = theSketch.addFeature("SketchLine") + aStartPoint1 = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint")) + aEndPoint1 = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint")) + aStartPoint1.setValue(10., 10.) + aEndPoint1.setValue(30., 5.) + allFeatures.append(aSketchLine) + # Arc + aSketchArc = theSketch.addFeature("SketchArc") + aStartPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint")) + aEndPoint2 = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint")) + aCenterPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter")) + aCenterPoint.setValue(20., 10.) + aStartPoint2.setValue(10., 10.) + aEndPoint2.setValue(20., 0.) + allFeatures.append(aSketchArc) + # Coincidence + aCoincidence = theSketch.addFeature("SketchConstraintCoincidence") + aCoincidence.refattr("ConstraintEntityA").setAttr(aStartPoint1) + aCoincidence.refattr("ConstraintEntityB").setAttr(aStartPoint2) + + theSketch.execute() + return allFeatures def checkFillet(theObjects, theRadius): # Verify the arc and lines are connected smoothly + print "Check Fillet" aLine = [] anArc = [] aSize = theObjects.size() @@ -57,20 +87,22 @@ def checkFillet(theObjects, theRadius): aLine.append(feat) elif (feat.getKind() == "SketchArc"): anArc.append(feat) - assert(anArc) - assert(anArc[0] is not None) + aFilletArc = anArc[-1] + assert(aFilletArc is not None) + anArc.pop() anArcPoints = [] - aPoint = geomDataAPI_Point2D(anArc[0].attribute("ArcStartPoint")) + aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcStartPoint")) print "ArcStartPoint " + repr(aPoint.x()) + " " + repr(aPoint.y()) anArcPoints.append((aPoint.x(), aPoint.y())) - aPoint = geomDataAPI_Point2D(anArc[0].attribute("ArcEndPoint")) + aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcEndPoint")) print "ArcEndPoint " + repr(aPoint.x()) + " " + repr(aPoint.y()) anArcPoints.append((aPoint.x(), aPoint.y())) - aPoint = geomDataAPI_Point2D(anArc[0].attribute("ArcCenter")) + aPoint = geomDataAPI_Point2D(aFilletArc.attribute("ArcCenter")) print "ArcCenter " + repr(aPoint.x()) + " " + repr(aPoint.y()) aCenterX = aPoint.x() aCenterY = aPoint.y() + aFilletRadius = math.hypot(anArcPoints[0][0]-aCenterX, anArcPoints[0][1]-aCenterY) for line in aLine: aStartPoint = geomDataAPI_Point2D(line.attribute("StartPoint")) @@ -95,6 +127,22 @@ def checkFillet(theObjects, theRadius): break; + for arc in anArc: + aStartPoint = geomDataAPI_Point2D(arc.attribute("ArcStartPoint")) + aEndPoint = geomDataAPI_Point2D(arc.attribute("ArcEndPoint")) + aCenterPoint = geomDataAPI_Point2D(arc.attribute("ArcCenter")) + + aBaseArcPoints = [] + aBaseArcPoints.append((aStartPoint.x(), aStartPoint.y())) + print "anArcStartPoint " + repr(aStartPoint.x()) + " " + repr(aStartPoint.y()) + aBaseArcPoints.append((aEndPoint.x(), aEndPoint.y())) + print "anArcEndPoint " + repr(aEndPoint.x()) + " " + repr(aEndPoint.y()) + print "anArcCenter " + repr(aCenterPoint.x()) + " " + repr(aCenterPoint.y()) + + aRadius = math.hypot(aStartPoint.x()-aCenterPoint.x(), aStartPoint.y()-aCenterPoint.y()) + aDist = math.hypot(aCenterPoint.x() - aCenterX, aCenterPoint.y() - aCenterY) + assert math.fabs(aFilletRadius + aRadius - aDist) < 1.e-7 or math.fabs(math.fabs(aFilletRadius - aRadius) - aDist) < 1.e-7, \ + "Fillet radius = {0}, Base arc radius = {1}, distance between centers = {2}".format(aFilletRadius, aRadius, aDist) #========================================================================= @@ -119,10 +167,10 @@ norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm")) norm.setValue(0, 0, 1) aSession.finishOperation() #========================================================================= -# Initialize sketch +# Initialize sketch by two lines #========================================================================= aSession.startOperation() -aFeaturesList = createSketch(aSketchFeature) +aFeaturesList = createSketch1(aSketchFeature) aSession.finishOperation() #========================================================================= # Global variables @@ -146,8 +194,55 @@ aResObjects = aFillet.reflist("ConstraintEntityB") # Verify the objects of fillet are created #========================================================================= assert(aResObjects) +checkFillet(aResObjects, FILLET_RADIUS1) +#========================================================================= +# Change Fillet radius +#========================================================================= +aRadius.setValue(FILLET_RADIUS2) +aSession.finishOperation() +checkFillet(aResObjects, FILLET_RADIUS2) + +#========================================================================= +# Create another sketch +#========================================================================= +aSession.startOperation() +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, 1, 0) +aSession.finishOperation() +#========================================================================= +# Initialize sketch by line and arc +#========================================================================= +aSession.startOperation() +aFeaturesList = createSketch2(aSketchFeature) aSession.finishOperation() +#========================================================================= +# Create the Fillet +#========================================================================= +aSession.startOperation() +aFillet = aSketchFeature.addFeature("SketchConstraintFillet") +aRefAttrA = aFillet.refattr("ConstraintEntityA"); +aRefAttrA.setAttr(aStartPoint1) +aRadius = aFillet.real("ConstraintValue") +aRadius.setValue(FILLET_RADIUS1) +aFillet.execute() +aResObjects = aFillet.reflist("ConstraintEntityB") +#========================================================================= +# Verify the objects of fillet are created +#========================================================================= +assert(aResObjects) checkFillet(aResObjects, FILLET_RADIUS1) #========================================================================= +# Change Fillet radius +#========================================================================= +aRadius.setValue(FILLET_RADIUS2) +aSession.finishOperation() +checkFillet(aResObjects, FILLET_RADIUS2) +#========================================================================= # End of test #========================================================================= diff --git a/src/SketchPlugin/Test/TestMultiRotation.py b/src/SketchPlugin/Test/TestMultiRotation.py index 34cb0387f..27b0aae24 100644 --- a/src/SketchPlugin/Test/TestMultiRotation.py +++ b/src/SketchPlugin/Test/TestMultiRotation.py @@ -35,6 +35,15 @@ def createSketch(theSketch): theSketch.execute() return allFeatures +def createLine(theSketch): + aSketchLine = theSketch.addFeature("SketchLine") + aStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint")) + aEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint")) + aStartPoint.setValue(7., 5.) + aEndPoint.setValue(1., 3.) + theSketch.execute() + return aSketchLine + def checkRotation(theObjects, theNbObjects, theCenterX, theCenterY, theAngle): # Verify distances of the objects and the number of copies aFeatures = [] @@ -159,11 +168,54 @@ aNbCopies.setValue(3) aSession.finishOperation() aRotated = aMultiRotation.reflist("ConstraintEntityB") checkRotation(aRotated, aNbCopies.value(), CENTER_X, CENTER_Y, ANGLE) + +#========================================================================= +# Create new feature and add it into the Rotation +#========================================================================= +aSession.startOperation() +aLine = createLine(aSketchFeature) +aSession.finishOperation() +aSession.startOperation() +aResult = modelAPI_ResultConstruction(aLine.lastResult()) +assert(aResult is not None) +aRotList.append(aResult) +aSession.finishOperation() +checkRotation(aRotated, aNbCopies.value(), CENTER_X, CENTER_Y, ANGLE) +#========================================================================= +# Move line and check the copies are moved too +#========================================================================= +aSession.startOperation() +aStartPoint = geomDataAPI_Point2D(aLine.attribute("StartPoint")) +aStartPoint.setValue(12., 5.) +aSession.finishOperation() +checkRotation(aRotated, aNbCopies.value(), CENTER_X, CENTER_Y, ANGLE) +#========================================================================= +# Change number of copies and verify Rotation +#========================================================================= +aSession.startOperation() +aNbCopies.setValue(2) +aSession.finishOperation() +checkRotation(aRotated, aNbCopies.value(), CENTER_X, CENTER_Y, ANGLE) + +#========================================================================= +# Remove a feature from the Rotation +#========================================================================= +aSession.startOperation() +aRemoveIt = aRotList.object(0) +aRotList.remove(aRemoveIt) +aSession.finishOperation() +checkRotation(aRotated, aNbCopies.value(), CENTER_X, CENTER_Y, ANGLE) + #========================================================================= -# TODO: improve test -# 1. Add more features into Rotation -# 2. Move one of initial features and check the Rotated is moved too +# Clear the list of rotated features #========================================================================= +aSession.startOperation() +aRotList.clear() +checkRotation(aRotated, 1, CENTER_X, CENTER_Y, ANGLE) +# Add line once again +aRotList.append(aResult) +aSession.finishOperation() +checkRotation(aRotated, aNbCopies.value(), CENTER_X, CENTER_Y, ANGLE) #========================================================================= # End of test #========================================================================= diff --git a/src/SketchPlugin/Test/TestMultiTranslation.py b/src/SketchPlugin/Test/TestMultiTranslation.py index 4dca56c49..2c0a2b937 100644 --- a/src/SketchPlugin/Test/TestMultiTranslation.py +++ b/src/SketchPlugin/Test/TestMultiTranslation.py @@ -34,6 +34,15 @@ def createSketch(theSketch): theSketch.execute() return allFeatures +def createLine(theSketch): + aSketchLine = theSketch.addFeature("SketchLine") + aStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint")) + aEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint")) + aStartPoint.setValue(7., 5.) + aEndPoint.setValue(1., 3.) + theSketch.execute() + return aSketchLine + def checkTranslation(theObjects, theNbObjects, theDeltaX, theDeltaY): # Verify distances of the objects and the number of copies aFeatures = [] @@ -46,7 +55,7 @@ def checkTranslation(theObjects, theNbObjects, theDeltaX, theDeltaY): anInd = 0 for feat, next in zip(aFeatures[:-1], aFeatures[1:]): anInd = anInd + 1 - if (anInd > theNbObjects): + if (anInd > theNbObjects-1): anInd = 0 continue assert(feat.getKind() == next.getKind()) @@ -150,11 +159,54 @@ aNbCopies.setValue(3) aSession.finishOperation() aTranslated = aMultiTranslation.reflist("ConstraintEntityB") checkTranslation(aTranslated, aNbCopies.value(), DELTA_X, DELTA_Y) + +#========================================================================= +# Create new feature and add it into the Rotation +#========================================================================= +aSession.startOperation() +aLine = createLine(aSketchFeature) +aSession.finishOperation() +aSession.startOperation() +aResult = modelAPI_ResultConstruction(aLine.lastResult()) +assert(aResult is not None) +aTransList.append(aResult) +aSession.finishOperation() +checkTranslation(aTranslated, aNbCopies.value(), DELTA_X, DELTA_Y) +#========================================================================= +# Move line and check the copies are moved too +#========================================================================= +aSession.startOperation() +aStartPoint = geomDataAPI_Point2D(aLine.attribute("StartPoint")) +aStartPoint.setValue(12., 5.) +aSession.finishOperation() +checkTranslation(aTranslated, aNbCopies.value(), DELTA_X, DELTA_Y) #========================================================================= -# TODO: improve test -# 1. Add more features into translation -# 2. Move one of initial features and check the translated is moved too +# Change number of copies and verify Rotation #========================================================================= +aSession.startOperation() +aNbCopies.setValue(2) +aSession.finishOperation() +checkTranslation(aTranslated, aNbCopies.value(), DELTA_X, DELTA_Y) + +#========================================================================= +# Remove a feature from the Rotation +#========================================================================= +aSession.startOperation() +aRemoveIt = aTransList.object(0) +aTransList.remove(aRemoveIt) +aSession.finishOperation() +checkTranslation(aTranslated, aNbCopies.value(), DELTA_X, DELTA_Y) + +#========================================================================= +# Clear the list of rotated features +#========================================================================= +aSession.startOperation() +aTransList.clear() +checkTranslation(aTranslated, 1, DELTA_X, DELTA_Y) +# Add line once again +aTransList.append(aResult) +aSession.finishOperation() +checkTranslation(aTranslated, aNbCopies.value(), DELTA_X, DELTA_Y) #========================================================================= # End of test #========================================================================= diff --git a/src/SketchSolver/SketchSolver_ConstraintMulti.cpp b/src/SketchSolver/SketchSolver_ConstraintMulti.cpp index d2135179c..96fa9ea2f 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMulti.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMulti.cpp @@ -42,24 +42,53 @@ void SketchSolver_ConstraintMulti::getEntities(std::list& theE myStorage->update(aFeature); theEntities.push_back(myStorage->entity(aFeature)); - for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) - ; // just skip copied features + myFeatures.insert(aFeature); + for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) { + // just add copied features into the list of objects + aFeature = ModelAPI_Feature::feature(*anObjIt); + if (aFeature) + myFeatures.insert(aFeature); + } } } +bool SketchSolver_ConstraintMulti::remove() +{ + myFeatures.clear(); + return SketchSolver_Constraint::remove(); +} + void SketchSolver_ConstraintMulti::update() { update(false); } - void SketchSolver_ConstraintMulti::update(bool isForce) { cleanErrorMsg(); AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast( myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects()); - if (anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies) { + bool isUpdated= anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies; + if (!isUpdated) { + // additional check that the features and their copies are changed + AttributeRefListPtr aRefList = std::dynamic_pointer_cast( + myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); + if (aRefList && aRefList->size() != 0) { + FeaturePtr aFeature; + std::list anObjectList = aRefList->list(); + std::list::iterator anObjIt = anObjectList.begin(); + for (; anObjIt != anObjectList.end(); ++anObjIt) { + aFeature = ModelAPI_Feature::feature(*anObjIt); + if (aFeature && myFeatures.find(aFeature) == myFeatures.end()) { + isUpdated = true; + break; + } + } + } else + isUpdated = true; + } + if (isUpdated) { remove(); process(); return; diff --git a/src/SketchSolver/SketchSolver_ConstraintMulti.h b/src/SketchSolver/SketchSolver_ConstraintMulti.h index 16db54dbd..03f0a6923 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMulti.h +++ b/src/SketchSolver/SketchSolver_ConstraintMulti.h @@ -32,6 +32,10 @@ public: /// \brief Update constraint void update(bool isForce); + /// \brief Tries to remove constraint + /// \return \c false, if current constraint contains another SketchPlugin constraints (like for multiple coincidence) + virtual bool remove(); + protected: /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints virtual void process() @@ -68,6 +72,8 @@ protected: int myNumberOfCopies; ///< number of previous copies of initial objects bool myAdjusted; ///< the constraint is already adjusted (to not do it several times) + + std::set myFeatures; ///< list of features and their copies to find whether some of them are disappeared }; #endif diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index 7ef43366f..c74580b07 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -172,30 +172,6 @@ bool SketchSolver_Group::changeConstraint( return true; } - -void SketchSolver_Group::updateConstraints() -{ - std::set aPostponed; // postponed constraints Multi-Rotation and Multi-Translation - - ConstraintConstraintMap::iterator anIt = myConstraints.begin(); - for (; anIt != myConstraints.end(); ++anIt) { - if (myChangedConstraints.find(anIt->first) == myChangedConstraints.end()) - continue; - if (anIt->first->getKind() == SketchPlugin_MultiRotation::ID() || - anIt->first->getKind() == SketchPlugin_MultiTranslation::ID()) - aPostponed.insert(anIt->second); - else - anIt->second->update(); - } - - // Update postponed constraints - std::set::iterator aSCIter = aPostponed.begin(); - for (; aSCIter != aPostponed.end(); ++aSCIter) - (*aSCIter)->update(); - - myChangedConstraints.clear(); -} - static void updateMultiConstraints(ConstraintConstraintMap& theConstraints, FeaturePtr theFeature) { ConstraintConstraintMap::iterator aCIt = theConstraints.begin(); @@ -293,9 +269,6 @@ bool SketchSolver_Group::updateWorkplane() // ============================================================================ bool SketchSolver_Group::resolveConstraints() { - if (!myChangedConstraints.empty()) - updateConstraints(); - bool aResolved = false; bool isGroupEmpty = isEmpty(); if (myStorage->isNeedToResolve() && !isGroupEmpty) { diff --git a/src/SketchSolver/SketchSolver_Group.h b/src/SketchSolver/SketchSolver_Group.h index f1520d3bd..7544fbaa2 100644 --- a/src/SketchSolver/SketchSolver_Group.h +++ b/src/SketchSolver/SketchSolver_Group.h @@ -152,9 +152,6 @@ private: /// \brief Verifies is the feature valid bool checkFeatureValidity(FeaturePtr theFeature); - /// \brief Update just changed constraints - void updateConstraints(); - private: GroupID myID; ///< Index of the group EntityID myWorkplaneID; ///< Index of workplane, the group is based on @@ -162,7 +159,6 @@ private: ConstraintConstraintMap myConstraints; ///< List of constraints std::set myTempConstraints; ///< List of temporary constraints std::map myParametricConstraints; ///< List of parametric constraints - std::set myChangedConstraints; ///< List of just updated constraints StoragePtr myStorage; ///< Container for the set of SolveSpace constraints and their entities -- 2.39.2