- }
- else if (isUsedInEqual(theLine.h, anEqual)) {
- // Check another entity of Equal is already fixed
- Slvs_hEntity anOtherEntID = anEqual.entityA == theLine.h ? anEqual.entityB : anEqual.entityA;
- if (isEntityFixed(anOtherEntID, true)) {
- // Fix start point of the line (if end point is not fixed yet) ...
- Slvs_hConstraint anEndFixedID = SLVS_E_UNKNOWN;
- bool isFixed = isPointFixed(theLine.point[1], anEndFixedID, true);
- if (isFixed == SLVS_E_UNKNOWN)
- fixPoint(aPoint[0], theCreated);
- // ... 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::vector<Slvs_Constraint>::const_iterator aPLIter = myConstraints.begin();
- for (; aPLIter != myConstraints.end() && !isPonLineFixed; ++aPLIter)
- if (aPLIter->type == SLVS_C_PT_ON_LINE && aPLIter->entityA == theLine.h) {
- isPonLineFixed = isPointFixed(aPLIter->ptA, anEndFixedID);
- aFixedPoint = aPLIter->ptA;
- }
-
- if (isPonLineFixed) { // update existent constraint
- copyEntity(aPointToCopy, aFixedPoint);
- } else { // create new constraint
- Slvs_hEntity aCopied = copyEntity(aPointToCopy);
- Slvs_Constraint aPonLine = Slvs_MakeConstraint(SLVS_E_UNKNOWN, theLine.group, SLVS_C_PT_ON_LINE,
- theLine.wrkpl, 0.0, aCopied, SLVS_E_UNKNOWN, theLine.h, SLVS_E_UNKNOWN);
- aPonLine.h = addConstraint(aPonLine);
- theCreated.push_back(aPonLine.h);
- fixPoint(getEntity(aCopied), theCreated);
- }
- return;
- }
- }
-
- // Fix both points
- for (int i = 0; i < 2; i++)
- fixPoint(aPoint[i], theCreated);
-}
-
-void SketchSolver_Storage::fixCircle(const Slvs_Entity& theCircle,
- std::vector<Slvs_hConstraint>& theCreated)
-{
- bool isFixRadius = true;
- // Verify the arc is under Equal constraint
- Slvs_Constraint anEqual;
- if (isUsedInEqual(theCircle.h, anEqual)) {
- // Check another entity of Equal is already fixed
- Slvs_hEntity anOtherEntID = anEqual.entityA == theCircle.h ? anEqual.entityB : anEqual.entityA;
- if (isEntityFixed(anOtherEntID, true))
- isFixRadius = false;
- }
-
- fixPoint(getEntity(theCircle.point[0]), theCreated);
-
- if (isFixRadius) {
- // Search the radius is already fixed
- std::vector<Slvs_Constraint>::const_iterator aDiamIter = myConstraints.begin();
- for (; aDiamIter != myConstraints.end(); ++aDiamIter)
- if (aDiamIter->type == SLVS_C_DIAMETER && aDiamIter->entityA == theCircle.h)
- return;
-
- // Fix radius of a circle
- const Slvs_Entity& aRadEnt = getEntity(theCircle.distance);
- double aRadius = getParameter(aRadEnt.param[0]).val;
- Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, theCircle.group, SLVS_C_DIAMETER,
- theCircle.wrkpl, aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, theCircle.h, SLVS_E_UNKNOWN);
- aFixedR.h = addConstraint(aFixedR);
- theCreated.push_back(aFixedR.h);
- }
-}
-
-void SketchSolver_Storage::fixArc(const Slvs_Entity& theArc,
- std::vector<Slvs_hConstraint>& theCreated)
-{
- Slvs_Entity aPoint[3] = {
- getEntity(theArc.point[0]),
- getEntity(theArc.point[1]),
- getEntity(theArc.point[2])
- };
-
- bool isFixRadius = true;
- std::list<Slvs_Entity> aPointsToFix;
- aPointsToFix.push_back(aPoint[1]);
- aPointsToFix.push_back(aPoint[2]);
-
- // Verify the arc is under Equal constraint
- Slvs_Constraint anEqual;
- if (isUsedInEqual(theArc.h, anEqual)) {
- // Check another entity of Equal is already fixed
- Slvs_hEntity anOtherEntID = anEqual.entityA == theArc.h ? anEqual.entityB : anEqual.entityA;
- if (isEntityFixed(anOtherEntID, true)) {
- isFixRadius = false;
- Slvs_Entity anOtherEntity = getEntity(anOtherEntID);
- if (anOtherEntity.type == SLVS_E_LINE_SEGMENT) {
- aPointsToFix.pop_back();
- aPointsToFix.push_back(aPoint[0]);
- }
- }
- }
-
- Slvs_hConstraint aConstrID;
- int aNbPointsToFix = 2; // number of fixed points for the arc
- if (isPointFixed(theArc.point[0], aConstrID, true))
- aNbPointsToFix--;
-
- double anArcPoints[3][2];
- for (int i = 0; i < 3; i++) {
- const Slvs_Entity& aPointOnArc = getEntity(theArc.point[i]);
- for (int j = 0; j < 2; j++)
- anArcPoints[i][j] = getParameter(aPointOnArc.param[j]).val;
- }
-
- // Radius of the arc
- std::shared_ptr<GeomAPI_Pnt2d> aCenter(new GeomAPI_Pnt2d(anArcPoints[0][0], anArcPoints[0][1]));
- std::shared_ptr<GeomAPI_Pnt2d> aStart(new GeomAPI_Pnt2d(anArcPoints[1][0], anArcPoints[1][1]));
- double aRadius = aCenter->distance(aStart);
-
- // Update end point of the arc to be on a curve
- std::shared_ptr<GeomAPI_Pnt2d> anEnd(new GeomAPI_Pnt2d(anArcPoints[2][0], anArcPoints[2][1]));
- double aDistance = anEnd->distance(aCenter);
- std::shared_ptr<GeomAPI_XY> aDir = anEnd->xy()->decreased(aCenter->xy());
- if (aDistance < tolerance)
- aDir = aStart->xy()->decreased(aCenter->xy())->multiplied(-1.0);
- else
- aDir = aDir->multiplied(aRadius / aDistance);
- double xy[2] = {aCenter->x() + aDir->x(), aCenter->y() + aDir->y()};
- const Slvs_Entity& aEndPoint = getEntity(theArc.point[2]);
- for (int i = 0; i < 2; i++) {
- Slvs_Param aParam = getParameter(aEndPoint.param[i]);
- aParam.val = xy[i];
- updateParameter(aParam);
- }
-
- std::list<Slvs_Entity>::iterator aPtIt = aPointsToFix.begin();
- for (; aNbPointsToFix > 0; aPtIt++, aNbPointsToFix--)
- fixPoint(*aPtIt, theCreated);
-
- if (isFixRadius) {
- // Fix radius of the arc
- bool isExists = false;
- std::vector<Slvs_Constraint>::iterator anIt = myConstraints.begin();
- for (; anIt != myConstraints.end() && !isExists; ++anIt)
- if (anIt->type == SLVS_C_DIAMETER && anIt->entityA == theArc.h)
- isExists = true;
- if (!isExists) {
- Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, theArc.group, SLVS_C_DIAMETER,
- theArc.wrkpl, aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, theArc.h, SLVS_E_UNKNOWN);
- aFixedR.h = addConstraint(aFixedR);
- theCreated.push_back(aFixedR.h);
- }
- }
-}
-
-
-bool SketchSolver_Storage::isAxisParallel(const Slvs_hEntity& theEntity) const
-{
- std::vector<Slvs_Constraint>::const_iterator anIter = myConstraints.begin();
- for (; anIter != myConstraints.end(); anIter++)
- if ((anIter->type == SLVS_C_HORIZONTAL || anIter->type == SLVS_C_VERTICAL) &&
- anIter->entityA == theEntity)
- return true;
- return false;
-}
-
-bool SketchSolver_Storage::isUsedInEqual(
- const Slvs_hEntity& theEntity, Slvs_Constraint& theEqual) const
-{
- // Check the entity is used in Equal constraint
- std::vector<Slvs_Constraint>::const_iterator anEqIter = myConstraints.begin();
- for (; anEqIter != myConstraints.end(); anEqIter++)
- if ((anEqIter->type == SLVS_C_EQUAL_LENGTH_LINES ||
- anEqIter->type == SLVS_C_EQUAL_LINE_ARC_LEN ||
- anEqIter->type == SLVS_C_EQUAL_RADIUS) &&
- (anEqIter->entityA == theEntity || anEqIter->entityB == theEntity)) {
- theEqual = *anEqIter;
- return true;
- }
- return false;
-}
-
-bool SketchSolver_Storage::isNeedToResolve()
-{
- if (myConstraints.empty())
- return false;
-
- if (!myNeedToResolve) {
- // Verify the updated parameters are used in constraints
- std::set<Slvs_hEntity> aPoints;
- std::vector<Slvs_Entity>::const_iterator anEntIt = myEntities.begin();
- for (; anEntIt != myEntities.end(); ++anEntIt) {
- for (int i = 0; i < 4 && anEntIt->param[i] != SLVS_E_UNKNOWN; ++i)
- if (myUpdatedParameters.find(anEntIt->param[i]) != myUpdatedParameters.end()) {
- aPoints.insert(anEntIt->h);
- break;
- }
- }
- std::set<Slvs_hEntity> anEntities = aPoints;
- for (anEntIt = myEntities.begin(); anEntIt != myEntities.end(); ++anEntIt) {
- for (int i = 0; i < 4 && anEntIt->point[i] != SLVS_E_UNKNOWN; ++i)
- if (aPoints.find(anEntIt->point[i]) != aPoints.end()) {
- anEntities.insert(anEntIt->h);
- break;
- }
- }
-
- std::vector<Slvs_Constraint>::const_iterator aCIt = myConstraints.begin();
- for (; aCIt != myConstraints.end() && !myNeedToResolve; ++aCIt) {
- Slvs_hEntity anAttrs[6] =
- {aCIt->ptA, aCIt->ptB, aCIt->entityA, aCIt->entityB, aCIt->entityC, aCIt->entityD};
- for (int i = 0; i < 6; i++)
- if (anAttrs[i] != SLVS_E_UNKNOWN && anEntities.find(anAttrs[i]) != anEntities.end()) {
- myNeedToResolve = true;
- break;
- }
- }
- }
-
- myUpdatedParameters.clear();
- return myNeedToResolve;
-}
-
-