X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintRigid.cpp;h=3ab5794b2c6402fe1c0c7803da54da4bc9f7439d;hb=4b42d82d7269a3146fbe09d88f5da936bf49452f;hp=39e6f93eeb2be2bb1fac7759b1c42ecd8693d041;hpb=b565fcd859e5551d317233b9e8103b3987f1e79a;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintRigid.cpp b/src/SketchSolver/SketchSolver_ConstraintRigid.cpp index 39e6f93ee..3ab5794b2 100644 --- a/src/SketchSolver/SketchSolver_ConstraintRigid.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintRigid.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include @@ -31,63 +33,29 @@ void SketchSolver_ConstraintRigid::process() double aValue; std::vector anEntities; getAttributes(aValue, anEntities); - if (!myErrorMsg.empty()) + if (!myErrorMsg.empty() || myFeatureMap.empty()) return; - Slvs_Constraint aConstraint; - std::vector::iterator aConstrIter = mySlvsConstraints.begin(); - bool isEmpty = aConstrIter == mySlvsConstraints.end(); - - // Check the fixed entity is an arc - if (isEmpty) { - if (!myFeatureMap.empty() && myFeatureMap.begin()->first->getKind() == SketchPlugin_Arc::ID()) { - Slvs_Entity anArc = myStorage->getEntity(myFeatureMap.begin()->second); - fixArc(anArc); - return; - } + Slvs_hEntity anEntID = myFeatureMap.begin()->second; + if (myStorage->isEntityFixed(anEntID, true)) { + myErrorMsg = SketchSolver_Error::ALREADY_FIXED(); + return; } - std::vector::const_iterator anEntIter = anEntities.begin(); - for (; anEntIter != anEntities.end(); anEntIter++) { - if (*anEntIter == SLVS_E_UNKNOWN) - continue; - Slvs_hConstraint aConstrID = myStorage->isPointFixed(*anEntIter); - bool isForceUpdate = (aConstrID != SLVS_E_UNKNOWN && !myBaseConstraint && - myStorage->isTemporary(aConstrID)); - if (isEmpty && !isForceUpdate) { // create new constraint - if (aConstrID != SLVS_E_UNKNOWN) - continue; // the coincident point is already fixed - aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(), - aValue, *anEntIter, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); - aConstraint.h = myStorage->addConstraint(aConstraint); - mySlvsConstraints.push_back(aConstraint.h); - if (!myBaseConstraint) - myStorage->addConstraintWhereDragged(aConstraint.h); - } else { // update already existent constraint - if (aConstrID == SLVS_E_UNKNOWN || myBaseConstraint) - aConstrID = *aConstrIter; - aConstraint = myStorage->getConstraint(aConstrID); - aConstraint.ptA = *anEntIter; - myStorage->addConstraint(aConstraint); - if (!myBaseConstraint) - myStorage->addConstraintWhereDragged(aConstraint.h); - if (!isEmpty) { - aConstrIter++; - isEmpty = aConstrIter == mySlvsConstraints.end(); - } - } + if (myFeatureMap.begin()->first->getKind() == SketchPlugin_Line::ID()) { + Slvs_Entity aLine = myStorage->getEntity(anEntID); + fixLine(aLine); } - - if (!myFeatureMap.empty() && myFeatureMap.begin()->first->getKind() == SketchPlugin_Circle::ID()) { - // Fix radius of a circle - AttributeDoublePtr aRadiusAttr = std::dynamic_pointer_cast( - myFeatureMap.begin()->first->attribute(SketchPlugin_Circle::RADIUS_ID())); - aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, myGroup->getWorkplaneId(), - aRadiusAttr->value() * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, myFeatureMap.begin()->second, SLVS_E_UNKNOWN); - aConstraint.h = myStorage->addConstraint(aConstraint); - mySlvsConstraints.push_back(aConstraint.h); - if (!myBaseConstraint) - myStorage->addConstraintWhereDragged(aConstraint.h); + else if (myFeatureMap.begin()->first->getKind() == SketchPlugin_Arc::ID()) { + Slvs_Entity anArc = myStorage->getEntity(anEntID); + fixArc(anArc); + } + else if (myFeatureMap.begin()->first->getKind() == SketchPlugin_Circle::ID()) { + Slvs_Entity aCirc = myStorage->getEntity(anEntID); + fixCircle(aCirc); + } + else if (myFeatureMap.begin()->first->getKind() == SketchPlugin_Point::ID()) { + fixPoint(anEntID); } } @@ -184,14 +152,130 @@ bool SketchSolver_ConstraintRigid::remove(ConstraintPtr theConstraint) return true; } +void SketchSolver_ConstraintRigid::fixPoint(const Slvs_hEntity& thePointID) +{ + if (thePointID == SLVS_E_UNKNOWN) + return; + + Slvs_Constraint aConstraint; + Slvs_hConstraint aConstrID = SLVS_E_UNKNOWN; + bool isFixed = myStorage->isPointFixed(thePointID, aConstrID, true); + bool isForceUpdate = (isFixed && !myBaseConstraint && + myStorage->isTemporary(aConstrID)); + if (!isForceUpdate) { // create new constraint + if (isFixed) return; + aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(), + 0.0, thePointID, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); + aConstraint.h = myStorage->addConstraint(aConstraint); + mySlvsConstraints.push_back(aConstraint.h); + if (!myBaseConstraint) + myStorage->addConstraintWhereDragged(aConstraint.h); + } else { // update already existent constraint + if (!isFixed || aConstrID == SLVS_E_UNKNOWN || myBaseConstraint) + return; + aConstraint = myStorage->getConstraint(aConstrID); + aConstraint.ptA = thePointID; + myStorage->addConstraint(aConstraint); + if (!myBaseConstraint) + myStorage->addConstraintWhereDragged(aConstraint.h); + } +} + +void SketchSolver_ConstraintRigid::fixLine(const Slvs_Entity& theLine) +{ + Slvs_Constraint anEqual; + if (isUsedInEqual(theLine, anEqual)) { + // Check another entity of Equal is already fixed + Slvs_hEntity anOtherEntID = anEqual.entityA == theLine.h ? anEqual.entityB : anEqual.entityA; + if (myStorage->isEntityFixed(anOtherEntID, true)) { + // Fix start point of the line (if end point is not fixed yet) ... + Slvs_hConstraint anEndFixedID = SLVS_E_UNKNOWN; + bool isFixed = myStorage->isPointFixed(theLine.point[1], anEndFixedID, true); + if (isFixed == SLVS_E_UNKNOWN) + fixPoint(theLine.point[0]); + // ... and create fixed point lying on this line + Slvs_hEntity aPointToCopy = anEndFixedID == SLVS_E_UNKNOWN ? theLine.point[1] : theLine.point[0]; + // Firstly, search already fixed point on line + bool isPonLineFixed = false; + Slvs_hEntity aFixedPoint; + std::list aPonLineList = myStorage->getConstraintsByType(SLVS_C_PT_ON_LINE); + std::list::const_iterator aPLIter = aPonLineList.begin(); + for (; aPLIter != aPonLineList.end() && !isPonLineFixed; aPLIter++) + if (aPLIter->entityA == theLine.h) { + isPonLineFixed = myStorage->isPointFixed(aPLIter->ptA, anEndFixedID); + aFixedPoint = aPLIter->ptA; + } + + if (isPonLineFixed) { // update existent constraint + myStorage->copyEntity(aPointToCopy, aFixedPoint); + } else { // create new constraint + Slvs_hEntity aCopied = myStorage->copyEntity(aPointToCopy); + Slvs_Constraint aPonLine = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_PT_ON_LINE, + myGroup->getWorkplaneId(), 0.0, aCopied, SLVS_E_UNKNOWN, theLine.h, SLVS_E_UNKNOWN); + aPonLine.h = myStorage->addConstraint(aPonLine); + mySlvsConstraints.push_back(aPonLine.h); + fixPoint(aCopied); + } + return; + } + } + + for (int i = 0; i < 2; i++) + fixPoint(theLine.point[i]); +} + +void SketchSolver_ConstraintRigid::fixCircle(const Slvs_Entity& theCircle) +{ + bool isFixRadius = true; + // Verify the arc is under Equal constraint + Slvs_Constraint anEqual; + if (isUsedInEqual(theCircle, anEqual)) { + // Check another entity of Equal is already fixed + Slvs_hEntity anOtherEntID = anEqual.entityA == theCircle.h ? anEqual.entityB : anEqual.entityA; + if (myStorage->isEntityFixed(anOtherEntID, true)) + isFixRadius = false; + } + + fixPoint(theCircle.point[0]); + + if (isFixRadius) { + // Fix radius of a circle + AttributeDoublePtr aRadiusAttr = std::dynamic_pointer_cast( + myFeatureMap.begin()->first->attribute(SketchPlugin_Circle::RADIUS_ID())); + Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, + myGroup->getWorkplaneId(), aRadiusAttr->value() * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, + myFeatureMap.begin()->second, SLVS_E_UNKNOWN); + aFixedR.h = myStorage->addConstraint(aFixedR); + mySlvsConstraints.push_back(aFixedR.h); + } +} void SketchSolver_ConstraintRigid::fixArc(const Slvs_Entity& theArc) { - Slvs_Constraint aConstraint; - Slvs_hConstraint aConstrID = myStorage->isPointFixed(theArc.point[0]); - int aPointsToFix = 2; // number of fixed points for the arc - if (aConstrID != SLVS_E_UNKNOWN) - aPointsToFix--; + bool isFixRadius = true; + std::list aPointsToFix; + aPointsToFix.push_back(theArc.point[1]); + aPointsToFix.push_back(theArc.point[2]); + + // Verify the arc is under Equal constraint + Slvs_Constraint anEqual; + if (isUsedInEqual(theArc, anEqual)) { + // Check another entity of Equal is already fixed + Slvs_hEntity anOtherEntID = anEqual.entityA == theArc.h ? anEqual.entityB : anEqual.entityA; + if (myStorage->isEntityFixed(anOtherEntID, true)) { + isFixRadius = false; + Slvs_Entity anOtherEntity = myStorage->getEntity(anOtherEntID); + if (anOtherEntity.type == SLVS_E_LINE_SEGMENT) { + aPointsToFix.pop_back(); + aPointsToFix.push_back(theArc.point[0]); + } + } + } + + Slvs_hConstraint aConstrID; + int aNbPointsToFix = 2; // number of fixed points for the arc + if (myStorage->isPointFixed(theArc.point[0], aConstrID, true)) + aNbPointsToFix--; // Radius of the arc FeaturePtr aFeature = myFeatureMap.begin()->first; @@ -218,32 +302,46 @@ void SketchSolver_ConstraintRigid::fixArc(const Slvs_Entity& theArc) myStorage->updateParameter(aParam); } - for (int i = 1; aPointsToFix > 0; i++, aPointsToFix--) { - aConstrID = myStorage->isPointFixed(theArc.point[i]); - if (aConstrID != SLVS_E_UNKNOWN) - continue; // the coincident point is already fixed - aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(), - 0.0, theArc.point[i], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); - aConstraint.h = myStorage->addConstraint(aConstraint); - mySlvsConstraints.push_back(aConstraint.h); - if (!myBaseConstraint) - myStorage->addConstraintWhereDragged(aConstraint.h); - } + std::list::iterator aPtIt = aPointsToFix.begin(); + for (; aNbPointsToFix > 0; aPtIt++, aNbPointsToFix--) + fixPoint(*aPtIt); - // Fix radius of the arc - bool isExists = false; - std::list aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER); - std::list::iterator anIt = aDiamConstraints.begin(); - for (; anIt != aDiamConstraints.end() && !isExists; anIt) - if (anIt->entityA == myFeatureMap.begin()->second) - isExists = true; - if (!isExists) { - aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, myGroup->getWorkplaneId(), - aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, myFeatureMap.begin()->second, SLVS_E_UNKNOWN); - aConstraint.h = myStorage->addConstraint(aConstraint); - mySlvsConstraints.push_back(aConstraint.h); - if (!myBaseConstraint) - myStorage->addConstraintWhereDragged(aConstraint.h); + if (isFixRadius) { + // Fix radius of the arc + bool isExists = false; + std::list aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER); + std::list::iterator anIt = aDiamConstraints.begin(); + for (; anIt != aDiamConstraints.end() && !isExists; anIt++) + if (anIt->entityA == myFeatureMap.begin()->second) + isExists = true; + if (!isExists) { + Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, + myGroup->getWorkplaneId(), aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, + myFeatureMap.begin()->second, SLVS_E_UNKNOWN); + aFixedR.h = myStorage->addConstraint(aFixedR); + mySlvsConstraints.push_back(aFixedR.h); + if (!myBaseConstraint) + myStorage->addConstraintWhereDragged(aFixedR.h); + } } } +bool SketchSolver_ConstraintRigid::isUsedInEqual( + const Slvs_Entity& theEntity, Slvs_Constraint& theEqual) const +{ + // Check the entity is used in Equal constraint + std::list anEqualConstr = myStorage->getConstraintsByType(SLVS_C_EQUAL_LENGTH_LINES); + std::list anAddList = myStorage->getConstraintsByType(SLVS_C_EQUAL_LINE_ARC_LEN); + anEqualConstr.insert(anEqualConstr.end(), anAddList.begin(), anAddList.end()); + anAddList = myStorage->getConstraintsByType(SLVS_C_EQUAL_RADIUS); + anEqualConstr.insert(anEqualConstr.end(), anAddList.begin(), anAddList.end()); + + std::list::const_iterator anEqIter = anEqualConstr.begin(); + for (; anEqIter != anEqualConstr.end(); anEqIter++) + if (anEqIter->entityA == theEntity.h || anEqIter->entityB == theEntity.h) { + theEqual = *anEqIter; + return true; + } + return false; +} +