X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_Constraint.cpp;h=2a4c36f8f7dada5503b0c0c55875144e3c55344c;hb=1834431e0e067cbb4616f42679562d56af528f5e;hp=946ee0edee685fc23f5f0ea0127873c270387591;hpb=041e61bc73a3917195bb1f32d9375baefdfdad77;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index 946ee0ede..2a4c36f8f 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,12 @@ void SketchSolver_Constraint::setGroup(SketchSolver_Group* theGroup) process(); } +void SketchSolver_Constraint::addFeature(FeaturePtr theFeature) +{ + int aType; + changeEntity(theFeature, aType); +} + void SketchSolver_Constraint::process() { @@ -79,6 +86,8 @@ void SketchSolver_Constraint::process() getAttributes(aValue, anAttributes); if (!myErrorMsg.empty()) return; + if (aConstrType == SLVS_C_UNKNOWN) + aConstrType = getType(); Slvs_hGroup aGroupID = myGroup->getId(); Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId(); @@ -107,15 +116,53 @@ void SketchSolver_Constraint::process() adjustConstraint(); } +bool SketchSolver_Constraint::checkAttributesChanged(ConstraintPtr theConstraint) +{ + // Check the attrbutes of constraint are changed + ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint; + std::list anAttrList = aConstraint->data()->attributes(std::string()); + std::list::iterator anAttrIter = anAttrList.begin(); + for (; anAttrIter != anAttrList.end(); anAttrIter++) { + AttributeRefAttrPtr aRefAttr = + std::dynamic_pointer_cast(*anAttrIter); + if (aRefAttr) { + if (aRefAttr->isObject()) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); + if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) + return true; + } else if (aRefAttr->attr() && + myAttributeMap.find(aRefAttr->attr()) == myAttributeMap.end()) + return true; + } + AttributeRefListPtr aRefList = + std::dynamic_pointer_cast(*anAttrIter); + if (aRefList) { + std::list anItems = aRefList->list(); + std::list::iterator anIt = anItems.begin(); + for (; anIt != anItems.end(); anIt++) { + FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) + return true; + } + } + } + return false; +} + void SketchSolver_Constraint::update(ConstraintPtr theConstraint) { cleanErrorMsg(); - if (theConstraint && theConstraint != myBaseConstraint) { - if (theConstraint->getKind() != myBaseConstraint->getKind()) + bool needToRebuild = (theConstraint && theConstraint != myBaseConstraint); + if (!needToRebuild) + needToRebuild = checkAttributesChanged(theConstraint); + if (needToRebuild) { + if (theConstraint && theConstraint->getKind() != myBaseConstraint->getKind()) return; remove(myBaseConstraint); - myBaseConstraint = theConstraint; + if (theConstraint) + myBaseConstraint = theConstraint; process(); + return; } // Update all attributes @@ -147,7 +194,8 @@ void SketchSolver_Constraint::update(ConstraintPtr theConstraint) std::vector::iterator aCIter = mySlvsConstraints.begin(); for (; aCIter != mySlvsConstraints.end(); aCIter++) { Slvs_Constraint aConstraint = myStorage->getConstraint(*aCIter); - aConstraint.valA = aValue; + if (aValueAttr) + aConstraint.valA = aValue; Slvs_hEntity* aCoeffs[6] = { &aConstraint.ptA, &aConstraint.ptB, &aConstraint.entityA, &aConstraint.entityB, @@ -288,8 +336,10 @@ Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributeRefAttrPtr theAttrib Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributePtr theEntity, int& theType) { Slvs_hEntity aResult = SLVS_E_UNKNOWN; - if (!theEntity || !isInitialized(theEntity)) + if (!theEntity || !isInitialized(theEntity)) { + myErrorMsg = SketchSolver_Error::NOT_INITIALIZED(); return SLVS_E_UNKNOWN; + } // If the entity is already in the group, try to find it std::map, Slvs_hEntity>::const_iterator anEntIter = @@ -527,7 +577,7 @@ void SketchSolver_Constraint::refresh() } if (fabs(aPoint2D->x() - aXY[0]) > tolerance || fabs(aPoint2D->y() - aXY[1]) > tolerance) - aPoint2D->setValue(aXY[0], aXY[1]); + aPoint2D->setValue(aXY[0], aXY[1]); } else { // Scalar value (used for the distance entities) AttributeDoublePtr aScalar = @@ -558,7 +608,15 @@ Slvs_hEntity SketchSolver_Constraint::getId(FeaturePtr theFeature) const std::map::const_iterator aFIter = myFeatureMap.find(theFeature); if (aFIter == myFeatureMap.end()) return SLVS_E_UNKNOWN; - return aFIter->second; + // check the Feature is really in the storage + Slvs_Entity anEntity = myStorage->getEntity(aFIter->second); + if (anEntity.h == SLVS_E_UNKNOWN) { + // rebuild feature + int aType; + anEntity.h = const_cast(this)->changeEntity(aFIter->first, aType); + const_cast(this)->myFeatureMap[theFeature] = anEntity.h; + } + return anEntity.h; } Slvs_hEntity SketchSolver_Constraint::getId(AttributePtr theAttribute) const @@ -622,61 +680,16 @@ void SketchSolver_Constraint::calculateMiddlePoint( return; } - double xStart = anArcPoint[1][0] / aRad, xEnd = anArcPoint[2][0] / aRad; - double yStart = anArcPoint[1][1] / aRad, yEnd = anArcPoint[2][1] / aRad; - double aTanStart = abs(xStart) < tolerance ? yStart : yStart / xStart; - double aTanEnd = abs(xEnd) < tolerance ? yEnd : yEnd / xEnd; - double aCotStart = abs(yStart) < tolerance ? xStart : xStart / yStart; - double aCotEnd = abs(yEnd) < tolerance ? xEnd : xEnd / yEnd; - if (anArcPoint[1][0] * anArcPoint[2][0] < 0.0) { - if (anArcPoint[1][0] > 0.0) - yEnd = 2.0 - yEnd; - else - yStart = -2.0 - yStart; - } else { - if (aTanStart > aTanEnd) { - if (yStart > yEnd) { - yStart = 2.0 - yStart; - yEnd = -2.0 - yEnd; - } else { - yStart = -2.0 - yStart; - yEnd = 2.0 - yEnd; - } - } - } - if (anArcPoint[1][1] * anArcPoint[2][1] < 0.0) { - if (anArcPoint[1][1] > 0.0) - xEnd = 2.0 - xEnd; - else - xStart = -2.0 - xStart; - } else { - if (aCotStart < aCotEnd) { - if (xStart > xEnd) { - xStart = 2.0 - xStart; - xEnd = -2.0 - xEnd; - } else { - xStart = -2.0 - xStart; - xEnd = 2.0 - xEnd; - } - } - } - x = (1.0 - theCoeff) * xStart + theCoeff * xEnd; - y = (1.0 - theCoeff) * yStart + theCoeff * yEnd; - if (x > 1.0) x = 2.0 - x; - if (x < -1.0) x = -2.0 - x; - if (y > 1.0) y = 2.0 - y; - if (y < -1.0) y = -2.0 - y; - - aNorm = sqrt(x*x + y*y); - if (aNorm >= tolerance) { - x *= aRad / aNorm; - y *= aRad / aNorm; - } else { - x = -0.5 * (anArcPoint[2][1] + anArcPoint[1][1]); - y = -0.5 * (anArcPoint[2][0] + anArcPoint[1][0]); - } - theX = anArcPoint[0][0] + x; - theY = anArcPoint[0][1] + y; + std::shared_ptr aStartDir(new GeomAPI_Dir2d(anArcPoint[1][0], anArcPoint[1][1])); + std::shared_ptr aEndDir(new GeomAPI_Dir2d(anArcPoint[2][0], anArcPoint[2][1])); + double anAngle = aStartDir->angle(aEndDir); + if (anAngle < 0) + anAngle += 2.0 * PI; + anAngle *= theCoeff; + double aCos = cos(anAngle); + double aSin = sin(anAngle); + theX = anArcPoint[0][0] + anArcPoint[1][0] * aCos - anArcPoint[1][1] * aSin; + theY = anArcPoint[0][1] + anArcPoint[1][0] * aSin + anArcPoint[1][1] * aCos; } }