X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSolveSpaceSolver%2FSolveSpaceSolver_Builder.cpp;h=24f6d229973f2dfc0ee8c866149fde9888a54ee2;hb=b857d9ea753bef79dbbadaeb990b54aae56e488d;hp=11b634a89b13d6da105b76f106bb03dbac91ec31;hpb=af68f1a45db8f50e0786190d56b8c71ab732eac4;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp index 11b634a89..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 @@ -107,6 +123,25 @@ std::list SolveSpaceSolver_Builder::createConstraint( 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) @@ -119,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]); } @@ -184,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, @@ -235,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: @@ -256,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; } @@ -312,11 +348,13 @@ EntityWrapperPtr SolveSpaceSolver_Builder::createFeature( else if (aFeatureKind == SketchPlugin_Arc::ID()) 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 = theAttributes.empty() ? createAttribute(aPoint, theGroupID, theSketchID) : + EntityWrapperPtr aSub = theAttributes.empty() ? + createAttribute(aPoint, theGroupID, theSketchID) : theAttributes.front(); if (!aSub) return aDummy; @@ -367,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); @@ -377,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); @@ -445,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 @@ -500,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; @@ -536,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; @@ -576,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; @@ -666,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) @@ -791,9 +759,11 @@ 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]); } }