X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSolveSpaceSolver%2FSolveSpaceSolver_Builder.cpp;h=24f6d229973f2dfc0ee8c866149fde9888a54ee2;hb=b857d9ea753bef79dbbadaeb990b54aae56e488d;hp=68ce5aaf3b7cc2b4628166aff6bf1915937e5d12;hpb=b83d39afdcf3053712cf0ff8281d5fd54e0b1649;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp index 68ce5aaf3..24f6d2299 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: SolveSpaceSolver_Builder.cpp -// Created: 25 Mar 2015 -// Author: Artem ZHIDKOV +// Copyright (C) 2014-2020 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include #include @@ -14,6 +27,7 @@ #include +#include #include #include #include @@ -27,6 +41,8 @@ #include #include #include +#include +#include #include @@ -51,10 +67,8 @@ static void adjustTangency(ConstraintWrapperPtr theConstraint); static void adjustAngle(ConstraintWrapperPtr theConstraint); /// \brief Update mirror points static void adjustMirror(ConstraintWrapperPtr theConstraint); -/// \brief Update positions of rotated features -static void adjustMultiRotation(ConstraintWrapperPtr theConstraint); -/// \brief Update positions of translated features -static void adjustMultiTranslation(ConstraintWrapperPtr theConstraint); +/// \brief Update a sign of the point-line distance constraint +static void adjustPtLineDistance(ConstraintWrapperPtr theConstraint); /// \brief Transform points to be symmetric regarding to the mirror line static void makeMirrorPoints(EntityWrapperPtr theOriginal, @@ -100,6 +114,34 @@ std::list SolveSpaceSolver_Builder::createConstraint( if (theType == CONSTRAINT_SYMMETRIC) return createMirror(theConstraint, theGroupID, theSketchID, thePoint1, thePoint2, theEntity1); + else if (theType == CONSTRAINT_TANGENT_CIRCLE_LINE) { + // replace by distance from center of circle to the line + const std::list& aSubs = theEntity1->subEntities(); + EntityWrapperPtr aCenter = aSubs.front(); + AttributeDoublePtr aRadius = std::dynamic_pointer_cast( + aSubs.back()->baseAttribute()); + return createConstraint(theConstraint, theGroupID, theSketchID, + CONSTRAINT_PT_LINE_DISTANCE, aRadius->value(), aCenter, EntityWrapperPtr(), theEntity2); + } + else if (theType == CONSTRAINT_COLLINEAR) { + // replace by two constraints point-on-line + std::list aConstraints; + const std::list& aSubs1 = theEntity1->subEntities(); + const std::list& aSubs2 = theEntity2->subEntities(); + std::list::const_iterator anIt1, anIt2; + for (anIt2 = aSubs2.begin(); anIt2 != aSubs2.end(); ++anIt2) { + for (anIt1 = aSubs1.begin(); anIt1 != aSubs1.end(); ++anIt1) + if ((*anIt1)->id() == (*anIt2)->id()) + break; + if (anIt1 != aSubs1.end()) + continue; // the lines have coincident point + + std::list aC = createConstraint(theConstraint, theGroupID, + theSketchID, CONSTRAINT_PT_ON_LINE, theValue, *anIt2, EntityWrapperPtr(), theEntity1); + aConstraints.insert(aConstraints.end(), aC.begin(), aC.end()); + } + return aConstraints; + } int aType = ConstraintType::toSolveSpace(theType); if (aType == SLVS_C_UNKNOWN) @@ -112,8 +154,9 @@ std::list SolveSpaceSolver_Builder::createConstraint( if (!anOriginal[i]) continue; aSlvsEntities[i] = (Slvs_hEntity)anOriginal[i]->id(); + // entity is not added into a storage, constraint can not be created if (aSlvsEntities[i] == SLVS_E_UNKNOWN) - return std::list(); // entity is not added into a storage, constraint can not be created + return std::list(); aConstrAttrList.push_back(anOriginal[i]); } @@ -121,6 +164,7 @@ std::list SolveSpaceSolver_Builder::createConstraint( SLVS_C_UNKNOWN, (Slvs_hGroup)theGroupID, aType, (Slvs_hEntity)theSketchID, theValue, aSlvsEntities[0], aSlvsEntities[1], aSlvsEntities[2], aSlvsEntities[3]); ConstraintWrapperPtr aResult(new SolveSpaceSolver_ConstraintWrapper(theConstraint, aConstraint)); + aResult->setGroup(theGroupID); aResult->setValue(theValue); aResult->setEntities(aConstrAttrList); adjustConstraint(aResult); @@ -156,6 +200,7 @@ std::list SolveSpaceSolver_Builder::createConstraint( aConstrAttrList.push_front(thePoint1); ConstraintWrapperPtr aResult(new SolveSpaceSolver_ConstraintWrapper(theConstraint, aConstraint)); + aResult->setGroup(theGroupID); aResult->setValue(theValue); aResult->setIsFullValue(theFullValue); aResult->setEntities(aConstrAttrList); @@ -175,8 +220,7 @@ std::list SolveSpaceSolver_Builder::createMirror( std::list aResult; std::list aConstrAttrList; if (theEntity1->type() == ENTITY_POINT) { - if (theEntity2->group() == theGroupID) // theEntity2 is not fixed - makeMirrorPoints(theEntity1, theEntity2, theMirrorLine); + makeMirrorPoints(theEntity1, theEntity2, theMirrorLine); aConstraint = Slvs_MakeConstraint( SLVS_E_UNKNOWN, (Slvs_hGroup)theGroupID, SLVS_C_SYMMETRIC_LINE, (Slvs_hEntity)theSketchID, @@ -189,6 +233,7 @@ std::list SolveSpaceSolver_Builder::createMirror( ConstraintWrapperPtr aWrapper(new SolveSpaceSolver_ConstraintWrapper( theConstraint, aConstraint)); + aWrapper->setGroup(theGroupID); aWrapper->setEntities(aConstrAttrList); aResult.push_back(aWrapper); } @@ -225,15 +270,15 @@ std::list SolveSpaceSolver_Builder::createMirror( aResult.insert(aResult.end(), aMrrList.begin(), aMrrList.end()); } else if (theEntity1->type() == ENTITY_ARC) { - // Do not allow mirrored arc recalculate its position until coordinated of all points recalculated + // Do not allow mirrored arc recalculate its position until + // coordinated of all points recalculated FeaturePtr aMirrArc = theEntity2->baseFeature(); - aMirrArc->data()->blockSendAttributeUpdated(true); + bool aWasBlocked = aMirrArc->data()->blockSendAttributeUpdated(true); std::list aMrrList; std::list::const_iterator anIt1 = theEntity1->subEntities().begin(); std::list::const_iterator anIt2 = theEntity2->subEntities().begin(); - if ((*anIt2)->group() == theGroupID) // mirrored point is not fixed - makeMirrorPoints(*anIt1, *anIt2, theMirrorLine); + makeMirrorPoints(*anIt1, *anIt2, theMirrorLine); // Workaround to avoid problems in SolveSpace. // The symmetry of two arcs will be done using symmetry of three points on these arcs: @@ -246,11 +291,12 @@ std::list SolveSpaceSolver_Builder::createMirror( anIt1 = aBaseArcPoints.begin(); anIt2 = aMirrorArcPoints.begin(); for (; anIt1 != aBaseArcPoints.end(); ++anIt1, ++anIt2) { - aMrrList = createMirror(theConstraint, theGroupID, theSketchID, *anIt1, *anIt2, theMirrorLine); + aMrrList = + createMirror(theConstraint, theGroupID, theSketchID, *anIt1, *anIt2, theMirrorLine); aResult.insert(aResult.end(), aMrrList.begin(), aMrrList.end()); } // Restore event sending - aMirrArc->data()->blockSendAttributeUpdated(false); + aMirrArc->data()->blockSendAttributeUpdated(aWasBlocked); } return aResult; } @@ -265,10 +311,8 @@ void SolveSpaceSolver_Builder::adjustConstraint(ConstraintWrapperPtr theConstrai adjustAngle(theConstraint); else if (aType == CONSTRAINT_SYMMETRIC) adjustMirror(theConstraint); - else if (aType == CONSTRAINT_MULTI_ROTATION) - adjustMultiRotation(theConstraint); - else if (aType == CONSTRAINT_MULTI_TRANSLATION) - adjustMultiTranslation(theConstraint); + else if (aType == CONSTRAINT_PT_LINE_DISTANCE) + adjustPtLineDistance(theConstraint); } EntityWrapperPtr SolveSpaceSolver_Builder::createFeature( @@ -299,22 +343,27 @@ EntityWrapperPtr SolveSpaceSolver_Builder::createFeature( return createLine(theFeature, theAttributes, theGroupID, theSketchID); // Circle else if (aFeatureKind == SketchPlugin_Circle::ID()) - return createCircle(theFeature, theAttributes,theGroupID, theSketchID); + return createCircle(theFeature, theAttributes, theGroupID, theSketchID); // Arc else if (aFeatureKind == SketchPlugin_Arc::ID()) - return createArc(theFeature, theAttributes,theGroupID, theSketchID); + return createArc(theFeature, theAttributes, theGroupID, theSketchID); // Point (it has low probability to be an attribute of constraint, so it is checked at the end) - else if (aFeatureKind == SketchPlugin_Point::ID()) { + else if (aFeatureKind == SketchPlugin_Point::ID() || + aFeatureKind == SketchPlugin_IntersectionPoint::ID()) { AttributePtr aPoint = theFeature->attribute(SketchPlugin_Point::COORD_ID()); if (!aPoint->isInitialized()) return aDummy; - EntityWrapperPtr aSub = createAttribute(aPoint, theGroupID, theSketchID); + EntityWrapperPtr aSub = theAttributes.empty() ? + createAttribute(aPoint, theGroupID, theSketchID) : + theAttributes.front(); if (!aSub) return aDummy; const Slvs_Entity& aSubEnt = std::dynamic_pointer_cast(aSub)->entity(); - return EntityWrapperPtr(new SolveSpaceSolver_EntityWrapper(theFeature, aPoint, aSubEnt)); + EntityWrapperPtr aResult(new SolveSpaceSolver_EntityWrapper(theFeature, aPoint, aSubEnt)); + aResult->setSubEntities(theAttributes); + return aResult; } // wrong entity @@ -356,8 +405,10 @@ EntityWrapperPtr SolveSpaceSolver_Builder::createAttribute( std::shared_ptr aPoint2D = std::dynamic_pointer_cast(theAttribute); if (aPoint2D) { - aParameters.push_back(createParameter(theGroupID, aPoint2D->x(), !aPoint2D->textX().empty())); - aParameters.push_back(createParameter(theGroupID, aPoint2D->y(), !aPoint2D->textY().empty())); + aParameters.push_back(createParameter(theGroupID, aPoint2D->x(), + !aPoint2D->textX().empty())); + aParameters.push_back(createParameter(theGroupID, aPoint2D->y(), + !aPoint2D->textY().empty())); // Create entity (parameters are not filled) anEntity = Slvs_MakePoint2d(SLVS_E_UNKNOWN, (Slvs_hGroup)theGroupID, (Slvs_hEntity)theSketchID, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); @@ -366,7 +417,8 @@ EntityWrapperPtr SolveSpaceSolver_Builder::createAttribute( AttributeDoublePtr aScalar = std::dynamic_pointer_cast(theAttribute); if (aScalar) { - aParameters.push_back(createParameter(theGroupID, aScalar->value(), !aScalar->text().empty())); + aParameters.push_back(createParameter(theGroupID, aScalar->value(), + !aScalar->text().empty())); // Create entity (parameter is not filled) anEntity = Slvs_MakeDistance(SLVS_E_UNKNOWN, (Slvs_hGroup)theGroupID, (Slvs_hEntity)theSketchID, SLVS_E_UNKNOWN); @@ -434,7 +486,7 @@ EntityWrapperPtr SolveSpaceSolver_Builder::createNormal( std::shared_ptr aNorm = std::dynamic_pointer_cast(theNormal); std::shared_ptr aDirX = std::dynamic_pointer_cast(theDirX); if (!aDirX || !aNorm || - (fabs(aDirX->x()) + fabs(aDirX->y()) + fabs(aDirX->z()) < tolerance) || + (fabs(aDirX->x()) + fabs(aDirX->y()) + fabs(aDirX->z()) < tolerance) || !aNorm->isInitialized()) return EntityWrapperPtr(); // calculate Y direction @@ -489,7 +541,7 @@ EntityWrapperPtr createLine(FeaturePtr theFeature, EntityWrapperPtr aStartEnt, aEndEnt; std::list::const_iterator anIt = theAttributes.begin(); for (; anIt != theAttributes.end(); ++anIt) { - std::shared_ptr aSlvsEntity = + std::shared_ptr aSlvsEntity = std::dynamic_pointer_cast(*anIt); if (aSlvsEntity->isBase(aStart)) aStartEnt = aSlvsEntity; @@ -525,7 +577,7 @@ EntityWrapperPtr createCircle(FeaturePtr theFeature, EntityWrapperPtr aCenterEnt, aRadiusEnt, aNormalEnt; std::list::const_iterator anIt = theAttributes.begin(); for (; anIt != theAttributes.end(); ++anIt) { - std::shared_ptr aSlvsEntity = + std::shared_ptr aSlvsEntity = std::dynamic_pointer_cast(*anIt); if (aSlvsEntity->isBase(aCenter)) aCenterEnt = aSlvsEntity; @@ -565,7 +617,7 @@ EntityWrapperPtr createArc(FeaturePtr theFeature, EntityWrapperPtr aCenterEnt, aStartEnt, aEndEnt, aNormalEnt; std::list::const_iterator anIt = theAttributes.begin(); for (; anIt != theAttributes.end(); ++anIt) { - std::shared_ptr aSlvsEntity = + std::shared_ptr aSlvsEntity = std::dynamic_pointer_cast(*anIt); if (aSlvsEntity->isBase(aCenter)) aCenterEnt = aSlvsEntity; @@ -655,91 +707,18 @@ void adjustAngle(ConstraintWrapperPtr theConstraint) std::shared_ptr(new GeomAPI_Lin2d(aPoints[0][0], aPoints[0][1])), std::shared_ptr(new GeomAPI_Lin2d(aPoints[1][0], aPoints[1][1])) }; - std::shared_ptr anIntersection = aLine[0]->intersect(aLine[1]); - if (!anIntersection) - return; - double aDist[2][2]; - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - aDist[i][j] = anIntersection->distance(aPoints[i][j]); - if (fabs(aDist[i][j]) <= tolerance) - aDist[i][j] = 0.0; - } - if (aDist[i][0] > tolerance && aDist[i][1] > tolerance && - aDist[i][0] + aDist[i][1] < aPoints[i][0]->distance(aPoints[i][1]) + 2.0 * tolerance) { - // the intersection point is an inner point of the line, - // we change the sign of distance till start point to calculate correct coordinates - // after rotation - aDist[i][0] *= -1.0; - } - } - std::shared_ptr aDir[2]; - for (int i = 0; i < 2; i++) { - if (aDist[i][1] > fabs(aDist[i][0])) - aDir[i] = std::shared_ptr(new GeomAPI_Dir2d( - aPoints[i][1]->xy()->decreased(anIntersection->xy()))); - else { - aDir[i] = std::shared_ptr(new GeomAPI_Dir2d( - aPoints[i][0]->xy()->decreased(anIntersection->xy()))); - // main direction is opposite => change signs - if (aDist[i][0] < 0.0) { - aDist[i][0] *= -1.0; - aDist[i][1] *= -1.0; - } - } - } + bool isReversed[2] = { + aConstraint->baseConstraint()->boolean( + SketchPlugin_ConstraintAngle::ANGLE_REVERSED_FIRST_LINE_ID())->value(), + aConstraint->baseConstraint()->boolean( + SketchPlugin_ConstraintAngle::ANGLE_REVERSED_SECOND_LINE_ID())->value() + }; + std::shared_ptr + anAngle(new GeomAPI_Angle2d(aLine[0], isReversed[0], aLine[1], isReversed[1])); + std::shared_ptr aCenter = anAngle->center(); Slvs_Constraint& aSlvsConstraint = aConstraint->changeConstraint(); - aSlvsConstraint.other = false; - for (int i = 0; i < 2; i++) - if (aLine[i]->direction()->dot(aDir[i]) < 0.0) - aSlvsConstraint.other = !aSlvsConstraint.other; - - // Recalculate positions of lines to avoid conflicting constraints - // while changing angle value several times - double cosA = cos(aConstraint->value() * PI / 180.0); - double sinA = sin(aConstraint->value() * PI / 180.0); - if (aDir[0]->cross(aDir[1]) < 0.0) - sinA *= -1.0; - int aLineToUpd = 1; - if (isFixed[1][0] && isFixed[1][1]) { - sinA *= -1.0; - aLineToUpd = 0; - } - double x = aDir[1-aLineToUpd]->x() * cosA - aDir[1-aLineToUpd]->y() * sinA; - double y = aDir[1-aLineToUpd]->x() * sinA + aDir[1-aLineToUpd]->y() * cosA; - - std::shared_ptr aNewPoints[2]; - for (int i = 0; i < 2; i++) { - aNewPoints[i] = std::shared_ptr( - new GeomAPI_Pnt2d(anIntersection->x() + x * aDist[aLineToUpd][i], - anIntersection->y() + y * aDist[aLineToUpd][i])); - } - - std::shared_ptr aDelta; - if (isFixed[aLineToUpd][0] && !isFixed[aLineToUpd][1]) - aDelta = aPoints[aLineToUpd][0]->xy()->decreased(aNewPoints[0]->xy()); - else if (!isFixed[aLineToUpd][0] && isFixed[aLineToUpd][1]) - aDelta = aPoints[aLineToUpd][1]->xy()->decreased(aNewPoints[1]->xy()); - if (aDelta) { - for (int i = 0; i < 2; i++) { - aNewPoints[i]->setX(aNewPoints[i]->x() + aDelta->x()); - aNewPoints[i]->setY(aNewPoints[i]->y() + aDelta->y()); - } - } - - // Update positions of points - std::list::const_iterator anUpdLine = aConstrLines.begin(); - if (aLineToUpd > 0) ++anUpdLine; - const std::list& anUpdPoints = (*anUpdLine)->subEntities(); - std::list::const_iterator aPIt = anUpdPoints.begin(); - for (int i = 0; aPIt != anUpdPoints.end(); ++aPIt, ++i) { - double aCoord[2] = {aNewPoints[i]->x(), aNewPoints[i]->y()}; - const std::list& aParams = (*aPIt)->parameters(); - std::list::const_iterator aParIt = aParams.begin(); - for (int j = 0; aParIt != aParams.end(); ++j, ++aParIt) - (*aParIt)->setValue(aCoord[j]); - } + aSlvsConstraint.other = isReversed[0] != isReversed[1]; } void adjustMirror(ConstraintWrapperPtr theConstraint) @@ -780,132 +759,32 @@ void makeMirrorPoints(EntityWrapperPtr theOriginal, (*aMIt)->setValue(aCoord[i]); // update corresponding attribute - AttributePtr anAttr = std::dynamic_pointer_cast(theMirrored)->baseAttribute(); + AttributePtr anAttr = + std::dynamic_pointer_cast(theMirrored)->baseAttribute(); if (anAttr) { - std::shared_ptr aMirroredPnt = std::dynamic_pointer_cast(anAttr); + std::shared_ptr aMirroredPnt = + std::dynamic_pointer_cast(anAttr); aMirroredPnt->setValue(aCoord[0], aCoord[1]); } } -static void rotate(EntityWrapperPtr theSource, EntityWrapperPtr theDest, - std::shared_ptr theCenter, - double theSin, double theCos) -{ - std::shared_ptr aSource = - std::dynamic_pointer_cast(theSource); - std::shared_ptr aDest = - std::dynamic_pointer_cast(theDest); - - if (theSource->type() == ENTITY_POINT) { - // Rotate single point - std::shared_ptr aSrcAttr = - std::dynamic_pointer_cast(aSource->baseAttribute()); - std::shared_ptr aDstAttr = - std::dynamic_pointer_cast(aDest->baseAttribute()); - if (aSrcAttr && aDstAttr) { - std::shared_ptr aVec = aSrcAttr->pnt()->xy()->decreased(theCenter->xy()); - double aNewX = aVec->x() * theCos - aVec->y() * theSin; - double aNewY = aVec->x() * theSin + aVec->y() * theCos; - aDstAttr->setValue(theCenter->x() + aNewX, theCenter->y() + aNewY); - } - return; - } - - FeaturePtr aDestFeature = aDest->baseFeature(); - if (aDestFeature) - aDestFeature->data()->blockSendAttributeUpdated(true); - - // Rotate points of the feature - const std::list& aSrcSubs = theSource->subEntities(); - const std::list& aDstSubs = theDest->subEntities(); - std::list::const_iterator aSrcIt, aDstIt; - for (aSrcIt = aSrcSubs.begin(), aDstIt = aDstSubs.begin(); - aSrcIt != aSrcSubs.end() && aDstIt != aDstSubs.end(); ++aSrcIt, ++aDstIt) - rotate(*aSrcIt, *aDstIt, theCenter, theSin, theCos); - - if (aDestFeature) - aDestFeature->data()->blockSendAttributeUpdated(false); -} - -static void translate(EntityWrapperPtr theSource, EntityWrapperPtr theDest, - std::shared_ptr theDelta) -{ - std::shared_ptr aSource = - std::dynamic_pointer_cast(theSource); - std::shared_ptr aDest = - std::dynamic_pointer_cast(theDest); - - if (theSource->type() == ENTITY_POINT) { - // Translate single point - std::shared_ptr aSrcAttr = - std::dynamic_pointer_cast(aSource->baseAttribute()); - std::shared_ptr aDstAttr = - std::dynamic_pointer_cast(aDest->baseAttribute()); - if (aSrcAttr && aDstAttr) - aDstAttr->setValue(aSrcAttr->x() + theDelta->x(), aSrcAttr->y() + theDelta->y()); - return; - } - - FeaturePtr aDestFeature = aDest->baseFeature(); - if (aDestFeature) - aDestFeature->data()->blockSendAttributeUpdated(true); - - // Translate points of the feature - const std::list& aSrcSubs = theSource->subEntities(); - const std::list& aDstSubs = theDest->subEntities(); - std::list::const_iterator aSrcIt, aDstIt; - for (aSrcIt = aSrcSubs.begin(), aDstIt = aDstSubs.begin(); - aSrcIt != aSrcSubs.end() && aDstIt != aDstSubs.end(); ++aSrcIt, ++aDstIt) - translate(*aSrcIt, *aDstIt, theDelta); - - if (aDestFeature) - aDestFeature->data()->blockSendAttributeUpdated(false); -} - -void adjustMultiRotation(ConstraintWrapperPtr theConstraint) -{ - BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance(); - - double anAngleValue = theConstraint->value(); - const std::list& aSubs = theConstraint->entities(); - - bool isFullValue = theConstraint->isFullValue(); - int aNbObjects = aSubs.size()-2; - if (isFullValue && aNbObjects > 0) { - anAngleValue /= aNbObjects; - } - - double anAngleRad = anAngleValue * PI / 180.0; - double aSin = sin(anAngleRad); - double aCos = cos(anAngleRad); - - std::list::const_iterator aSIt = aSubs.begin(); - - std::shared_ptr aCenter = aBuilder->point(*aSIt++); - std::list::const_iterator aPrevIt = aSIt++; - for (; aSIt != aSubs.end(); ++aPrevIt, ++aSIt) - rotate(*aPrevIt, *aSIt, aCenter, aSin, aCos); -} - -void adjustMultiTranslation(ConstraintWrapperPtr theConstraint) +void adjustPtLineDistance(ConstraintWrapperPtr theConstraint) { BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance(); - const std::list& aSubs = theConstraint->entities(); + std::shared_ptr aPoint; + std::shared_ptr aLine; + std::list aSubs = theConstraint->entities(); std::list::const_iterator aSIt = aSubs.begin(); - - std::shared_ptr aStartPnt = aBuilder->point(*aSIt++); - std::shared_ptr aEndPnt = aBuilder->point(*aSIt++); - std::shared_ptr aDelta = aEndPnt->xy()->decreased(aStartPnt->xy()); - - bool isFullValue = theConstraint->isFullValue(); - int aNbObjects = aSubs.size()-3; - if (isFullValue && aNbObjects > 0) { - aDelta->setX(aDelta->x()/aNbObjects); - aDelta->setY(aDelta->y()/aNbObjects); + for (; aSIt != aSubs.end(); ++aSIt) { + if ((*aSIt)->type() == ENTITY_POINT) + aPoint = aBuilder->point(*aSIt); + else if ((*aSIt)->type() == ENTITY_LINE) + aLine = aBuilder->line(*aSIt); } - std::list::const_iterator aPrevIt = aSIt++; - for (; aSIt != aSubs.end(); ++aPrevIt, ++aSIt) - translate(*aPrevIt, *aSIt, aDelta); + std::shared_ptr aLineVec = aLine->direction()->xy(); + std::shared_ptr aPtLineVec = aPoint->xy()->decreased(aLine->location()->xy()); + if (aPtLineVec->cross(aLineVec) * theConstraint->value() < 0.0) + theConstraint->setValue(theConstraint->value() * (-1.0)); }