From 46d8e5be6651d01489c3820541d1a7bbbe4be06f Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 29 Jan 2016 11:40:07 +0300 Subject: [PATCH] Implement constraint middle-point-on-line --- src/PartSet/PartSet_Module.cpp | 1 + src/PartSet/PartSet_Validators.cpp | 8 + src/PartSet/PartSet_Validators.h | 8 + src/PartSet/PartSet_icons.qrc | 1 + src/PartSet/icons/middlepoint.png | Bin 0 -> 378 bytes src/SketchPlugin/CMakeLists.txt | 3 + .../SketchPlugin_ConstraintMiddle.cpp | 36 +++++ .../SketchPlugin_ConstraintMiddle.h | 50 +++++++ src/SketchPlugin/SketchPlugin_Plugin.cpp | 5 + src/SketchPlugin/SketchPlugin_Validators.cpp | 46 ++++++ src/SketchPlugin/SketchPlugin_Validators.h | 19 +++ .../Test/TestConstraintMiddlePoint.py | 141 ++++++++++++++++++ src/SketchPlugin/plugin-Sketch.xml | 17 ++- .../PlaneGCSSolver/PlaneGCSSolver_Builder.cpp | 68 +++++++++ src/SketchSolver/SketchSolver_Constraint.cpp | 3 + .../SketchSolver_IConstraintWrapper.h | 1 + .../SolveSpaceSolver_ConstraintType.h | 2 + 17 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 src/PartSet/icons/middlepoint.png create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintMiddle.cpp create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintMiddle.h create mode 100644 src/SketchPlugin/Test/TestConstraintMiddlePoint.py diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 124766058..35a077041 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -203,6 +203,7 @@ void PartSet_Module::registerValidators() aFactory->registerValidator("PartSet_AngleSelection", new PartSet_AngleSelection); aFactory->registerValidator("PartSet_EqualSelection", new PartSet_EqualSelection); aFactory->registerValidator("PartSet_CollinearSelection", new PartSet_CollinearSelection); + aFactory->registerValidator("PartSet_MiddlePointSelection", new PartSet_MiddlePointSelection); aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator); aFactory->registerValidator("PartSet_CoincidentAttr", new PartSet_CoincidentAttr); aFactory->registerValidator("PartSet_SketchEntityValidator", new PartSet_SketchEntityValidator); diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp index a81557ac4..163063bd0 100755 --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -324,6 +324,14 @@ bool PartSet_CollinearSelection::isValid(const ModuleBase_ISelection* theSelecti } } +bool PartSet_MiddlePointSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const +{ + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) + return isEmptySelectionValid(theOperation); + else + return shapesNbLines(theSelection) == 1 && shapesNbPoints(theSelection) == 1; +} + std::string PartSet_DifferentObjectsValidator::errorMessage( const PartSet_DifferentObjectsValidator::ErrorType& theType, diff --git a/src/PartSet/PartSet_Validators.h b/src/PartSet/PartSet_Validators.h index 05e90f05f..aaf3c88c9 100644 --- a/src/PartSet/PartSet_Validators.h +++ b/src/PartSet/PartSet_Validators.h @@ -123,6 +123,14 @@ public: PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; +//! \ingroup Validators +//! A class to validate a selection for Middle point constraints operation +class PartSet_MiddlePointSelection : public ModuleBase_SelectionValidator +{ +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; +}; + ////////////// Attribute validators //////////////// diff --git a/src/PartSet/PartSet_icons.qrc b/src/PartSet/PartSet_icons.qrc index 9b674aea9..826d7fd11 100644 --- a/src/PartSet/PartSet_icons.qrc +++ b/src/PartSet/PartSet_icons.qrc @@ -83,5 +83,6 @@ icons/bool_common.png icons/plane_view.png icons/collinear.png + icons/middlepoint.png diff --git a/src/PartSet/icons/middlepoint.png b/src/PartSet/icons/middlepoint.png new file mode 100644 index 0000000000000000000000000000000000000000..98d1b6383661987b0f1460aefcbc7c6756483a7f GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHh#u47Z+s;GWfr3=E9yo-U3d7N?W{{QqyytlGeOE-A%j zs^X;twK+yTJu})KnJ}~;db?;63vU8QMHutBkDNvovu-AL?7y>jo&~dngv6_fH`tHF zGVvuD_XM6%T_6{mbZu!c9}f`xTR+dz00=~~rF0U2AVO*F2ZqDkNqUSD2V;xgvpK)q zE3J{lc+8CFIIF8i2dmJfM&?}$9=wnLRh%+aB1rE3>=OqL958SX)4c!us&U)nCMEHW z$C`FzGcYqVD>ExUu5T0HZFb;Nqixh7s}6Nlr=*AW!orTc5_$sV+$lf)zqbdeJAC@? zYY#r=W&i8{PoDH;<54E%E5c7^9{4i + +// File: SketchPlugin_ConstraintMiddle.cpp +// Created: 26 May 2014 +// Author: Artem ZHIDKOV + +#include "SketchPlugin_ConstraintMiddle.h" + +SketchPlugin_ConstraintMiddle::SketchPlugin_ConstraintMiddle() +{ +} + +void SketchPlugin_ConstraintMiddle::initAttributes() +{ + data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); + data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); +} + +void SketchPlugin_ConstraintMiddle::execute() +{ +} + +AISObjectPtr SketchPlugin_ConstraintMiddle::getAISObject(AISObjectPtr thePrevious) +{ + if (!sketch()) + return thePrevious; + + AISObjectPtr anAIS = thePrevious; + if (!anAIS) { + // TODO + //anAIS = SketcherPrs_Factory::collinearConstraint(this, sketch()->coordinatePlane()); + } + return anAIS; +} + + diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMiddle.h b/src/SketchPlugin/SketchPlugin_ConstraintMiddle.h new file mode 100644 index 000000000..9cf7b866f --- /dev/null +++ b/src/SketchPlugin/SketchPlugin_ConstraintMiddle.h @@ -0,0 +1,50 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +// File: SketchPlugin_ConstraintMiddle.h +// Created: 27 Jan 2016 +// Author: Artem ZHIDKOV + +#ifndef SketchPlugin_ConstraintMiddle_H_ +#define SketchPlugin_ConstraintMiddle_H_ + +#include "SketchPlugin.h" +#include +#include "SketchPlugin_ConstraintBase.h" + +/** \class SketchPlugin_ConstraintMiddle + * \ingroup Plugins + * \brief Feature for creation of a new constraintwhich places a point in the middle of a line + * + * This constraint has two attributes: + * SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B() + */ +class SketchPlugin_ConstraintMiddle : public SketchPlugin_ConstraintBase +{ + public: + /// Parallel constraint kind + inline static const std::string& ID() + { + static const std::string MY_CONSTRAINT_MIDDLE_ID("SketchConstraintMiddle"); + return MY_CONSTRAINT_MIDDLE_ID; + } + /// \brief Returns the kind of a feature + SKETCHPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = SketchPlugin_ConstraintMiddle::ID(); + return MY_KIND; + } + + /// \brief Creates a new part document if needed + SKETCHPLUGIN_EXPORT virtual void execute(); + + /// \brief Request for initialization of data model of the feature: adding all attributes + SKETCHPLUGIN_EXPORT virtual void initAttributes(); + + /// Returns the AIS preview + SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious); + + /// \brief Use plugin manager for features creation + SketchPlugin_ConstraintMiddle(); +}; + +#endif diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 0119d3b63..a07675a53 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,8 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() new SketchPlugin_SolverErrorValidator); aFactory->registerValidator("SketchPlugin_FilletVertexValidator", new SketchPlugin_FilletVertexValidator); + aFactory->registerValidator("SketchPlugin_MiddlePointAttr", + new SketchPlugin_MiddlePointAttrValidator); // register this plugin ModelAPI_Session::get()->registerPlugin(this); @@ -136,6 +139,8 @@ FeaturePtr SketchPlugin_Plugin::createFeature(string theFeatureID) return FeaturePtr(new SketchPlugin_ConstraintEqual); } else if (theFeatureID == SketchPlugin_ConstraintTangent::ID()) { return FeaturePtr(new SketchPlugin_ConstraintTangent); + } else if (theFeatureID == SketchPlugin_ConstraintMiddle::ID()) { + return FeaturePtr(new SketchPlugin_ConstraintMiddle); } else if (theFeatureID == SketchPlugin_ConstraintMirror::ID()) { return FeaturePtr(new SketchPlugin_ConstraintMirror); } else if (theFeatureID == SketchPlugin_ConstraintFillet::ID()) { diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 66fc18d8b..612b083e7 100755 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -615,3 +615,49 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut return true; } + +bool SketchPlugin_MiddlePointAttrValidator::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const +{ + if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) { + theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed"; + return false; + } + + // there is a check whether the feature contains a point and a linear edge or two point values + std::string aParamA = theArguments.front(); + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + + FeaturePtr anAttributeFeature = std::dynamic_pointer_cast(theAttribute->owner()); + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); + AttributeRefAttrPtr anOtherAttr = anAttributeFeature->data()->refattr(aParamA); + + AttributeRefAttrPtr aRefAttrs[2] = {aRefAttr, anOtherAttr}; + int aNbPoints = 0; + int aNbLines = 0; + for (int i = 0; i < 2; ++i) { + if (!aRefAttrs[i]->isObject()) + ++aNbPoints; + else { + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttrs[i]->object()); + if (!aFeature) { + if (aNbPoints + aNbLines != 0) + return true; + else continue; + } + + if (aFeature->getKind() == SketchPlugin_Point::ID()) + ++aNbPoints; + else if (aFeature->getKind() == SketchPlugin_Line::ID()) + ++aNbLines; + } + } + + if (aNbPoints != 1 || aNbLines != 1) { + theError = "Middle point constraint allows points and lines only"; + return false; + } + return true; +} diff --git a/src/SketchPlugin/SketchPlugin_Validators.h b/src/SketchPlugin/SketchPlugin_Validators.h index 966f33be1..1b38eb0e7 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.h +++ b/src/SketchPlugin/SketchPlugin_Validators.h @@ -180,4 +180,23 @@ class SketchPlugin_FilletVertexValidator : public ModelAPI_AttributeValidator std::string& theError) const; }; + +/**\class SketchPlugin_MiddlePointAttrValidator + * \ingroup Validators + * \brief Validator for the middle point constraint input. + * + * It checks that attributes of the Middle point constraint are correct. + */ +class SketchPlugin_MiddlePointAttrValidator : public ModelAPI_AttributeValidator +{ + public: + //! returns true if attribute is valid + //! \param theAttribute the checked attribute + //! \param theArguments arguments of the attribute (not used) + //! \param theError error message + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const; +}; + #endif diff --git a/src/SketchPlugin/Test/TestConstraintMiddlePoint.py b/src/SketchPlugin/Test/TestConstraintMiddlePoint.py new file mode 100644 index 000000000..09506082b --- /dev/null +++ b/src/SketchPlugin/Test/TestConstraintMiddlePoint.py @@ -0,0 +1,141 @@ +""" + TestConstraintCoincidence.py + Unit test of SketchPlugin_ConstraintCoincidence class + + SketchPlugin_Constraint + static const std::string MY_CONSTRAINT_VALUE("ConstraintValue"); + static const std::string MY_FLYOUT_VALUE_PNT("ConstraintFlyoutValuePnt"); + static const std::string MY_ENTITY_A("ConstraintEntityA"); + static const std::string MY_ENTITY_B("ConstraintEntityB"); + static const std::string MY_ENTITY_C("ConstraintEntityC"); + static const std::string MY_ENTITY_D("ConstraintEntityD"); + + SketchPlugin_ConstraintCoincidence + static const std::string MY_CONSTRAINT_COINCIDENCE_ID("SketchConstraintCoincidence"); + data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); + data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); + +""" +from GeomDataAPI import * +from ModelAPI import * +import math +#========================================================================= +# Initialization of the test +#========================================================================= + +__updated__ = "2016-01-29" +TOLERANCE = 1.e-7 + + +#========================================================================= +# Auxiliary functions +#========================================================================= +def checkMiddlePoint(point, line): + aStart = geomDataAPI_Point2D(line.attribute("StartPoint")) + aEnd = geomDataAPI_Point2D(line.attribute("EndPoint")) + assert math.fabs(aStart.x() + aEnd.x() - 2.0 * point.x()) <= TOLERANCE, "x1={0}, x2={1}, mid={2}".format(aStart.x(), aEnd.x(), point.x()) + assert math.fabs(aStart.y() + aEnd.y() - 2.0 * point.y()) <= TOLERANCE, "y1={0}, y2={1}, mid={2}".format(aStart.y(), aEnd.y(), point.y()) + + +#========================================================================= +# Start of test +#========================================================================= +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() +# add an origin +aSession.startOperation() +aFeature = aDocument.addFeature("Point") +aFeature.real("x").setValue(0.) +aFeature.real("y").setValue(0.) +aFeature.real("z").setValue(0.) +anOriginName = aFeature.name() +aSession.finishOperation() +#========================================================================= +# Creation of a sketch +#========================================================================= +aSession.startOperation() +aSketchFeature = featureToCompositeFeature(aDocument.addFeature("Sketch")) +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin")) +origin.setValue(0, 0, 0) +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX")) +dirx.setValue(1, 0, 0) +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm")) +norm.setValue(0, 0, 1) +aSession.finishOperation() +#========================================================================= +# Create a two lines +#========================================================================= +aSession.startOperation() +aLine1 = aSketchFeature.addFeature("SketchLine") +aStartPoint1 = geomDataAPI_Point2D(aLine1.attribute("StartPoint")) +aEndPoint1 = geomDataAPI_Point2D(aLine1.attribute("EndPoint")) +aStartPoint1.setValue(50., 0.) +aEndPoint1.setValue(100., 25.) +aLine2 = aSketchFeature.addFeature("SketchLine") +aStartPoint2 = geomDataAPI_Point2D(aLine2.attribute("StartPoint")) +aEndPoint2 = geomDataAPI_Point2D(aLine2.attribute("EndPoint")) +aStartPoint2.setValue(10., 100.) +aEndPoint2.setValue(100., 25.) +aSession.finishOperation() +#========================================================================= +# Make end point of second line middle point on first line +#========================================================================= +aSession.startOperation() +aConstraint = aSketchFeature.addFeature("SketchConstraintMiddle") +reflistA = aConstraint.refattr("ConstraintEntityA") +reflistB = aConstraint.refattr("ConstraintEntityB") +reflistA.setAttr(aEndPoint2) +reflistB.setObject(aLine1.lastResult()) +aConstraint.execute() +aSession.finishOperation() +#========================================================================= +# Check values and move one constrainted object +#========================================================================= +checkMiddlePoint(aEndPoint2, aLine1) +deltaX, deltaY = -80.0, -40.0 +aSession.startOperation() +aStartPoint1.setValue(aStartPoint1.x() + deltaX, aStartPoint1.y() + deltaY) +aSession.finishOperation() +checkMiddlePoint(aEndPoint2, aLine1) +#========================================================================= +# Remove constraint and move the line +#========================================================================= +aCurX, aCurY = aEndPoint2.x(), aEndPoint2.y() +aSession.startOperation() +aDocument.removeFeature(aConstraint) +aSession.finishOperation() +aSession.startOperation() +aEndPoint1.setValue(90., 0.) +aSession.finishOperation() +assert (aEndPoint2.x() == aCurX and aEndPoint2.y() == aCurY) + +#========================================================================= +# Set external point as a middle point +#========================================================================= +# create origin +aSession.startOperation() +anOrigRes = modelAPI_Result(aDocument.objectByName("Construction", anOriginName)) +assert (anOrigRes) +anOrigShape = anOrigRes.shape() +assert (anOrigShape) +anOrigin = aSketchFeature.addFeature("SketchPoint") +anOriginCoord = geomDataAPI_Point2D(anOrigin.attribute("PointCoordindates")) +anOriginCoord.setValue(0., 0.) +anOrigin.selection("External").setValue(anOrigRes, anOrigShape) +aSession.finishOperation() +# middle point constraint +aSession.startOperation() +aConstraint = aSketchFeature.addFeature("SketchConstraintMiddle") +reflistA = aConstraint.refattr("ConstraintEntityA") +reflistB = aConstraint.refattr("ConstraintEntityB") +reflistA.setObject(aLine2.lastResult()) +reflistB.setObject(anOrigin.lastResult()) +aSession.finishOperation() +checkMiddlePoint(anOriginCoord, aLine2) +#========================================================================= +# Check origin coordinates does not changed +#========================================================================= +assert (anOriginCoord.x() == 0. and anOriginCoord.y() == 0.) +#========================================================================= +# End of test +#========================================================================= diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 6b7233f6c..79de2c5d7 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -5,7 +5,7 @@ + + + + + + + + + + + + + + + diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp index 9cc222f58..23933b232 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp @@ -133,6 +133,11 @@ static ConstraintWrapperPtr const GroupID& theGroupID, std::shared_ptr theEntity1, std::shared_ptr theEntity2); +static ConstraintWrapperPtr + createConstraintMiddlePoint(ConstraintPtr theConstraint, + const GroupID& theGroupID, + std::shared_ptr thePoint, + std::shared_ptr theEntity); @@ -203,6 +208,10 @@ std::list PlaneGCSSolver_Builder::createConstraint( aResult = createConstraintPointOnEntity(theConstraint, theGroupID, theType, aPoint1, GCS_ENTITY_WRAPPER(theEntity1)); break; + case CONSTRAINT_MIDDLE_POINT: + aResult = createConstraintMiddlePoint(theConstraint, theGroupID, + aPoint1, GCS_ENTITY_WRAPPER(theEntity1)); + break; case CONSTRAINT_PT_PT_DISTANCE: aResult = createConstraintDistancePointPoint(theConstraint, theGroupID, GCS_PARAMETER_WRAPPER(createParameter(GID_OUTOFGROUP, theValue)), @@ -816,6 +825,65 @@ ConstraintWrapperPtr createConstraintPointOnEntity( return aResult; } +// calculate length of the line +static inline double lineLength(const GCS::Line& theLine) +{ + double aDir[2] = {*(theLine.p2.x) - *(theLine.p1.x), *(theLine.p2.y) - *(theLine.p1.y)}; + return sqrt(aDir[0] * aDir[0] + aDir[1] * aDir[1]); +} + +// check the point is on the line +static inline bool isPointOnLine(const GCS::Point& thePoint, const GCS::Line& theLine) +{ + double aDir[2] = {*(theLine.p2.x) - *(theLine.p1.x), *(theLine.p2.y) - *(theLine.p1.y)}; + double aVec[2] = {*(thePoint.x) - *(theLine.p1.x), *(thePoint.y) - *(theLine.p1.y)}; + double aCross = aVec[0] * aDir[1] - aVec[1] * aDir[0]; + return fabs(aCross) < tolerance; +} + +ConstraintWrapperPtr createConstraintMiddlePoint( + ConstraintPtr theConstraint, + const GroupID& theGroupID, + std::shared_ptr thePoint, + std::shared_ptr theEntity) +{ + GCSPointPtr aPoint = thePoint->point(); + std::shared_ptr aLine = std::dynamic_pointer_cast(theEntity->entity()); + if (!aLine) + return ConstraintWrapperPtr(); + + std::list aConstrList; + aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPointOnLine(*aPoint, *aLine))); + double aDist = lineLength(*aLine); + std::shared_ptr aDistance = + std::dynamic_pointer_cast(createParameter(theGroupID, aDist)); + aConstrList.push_back(GCSConstraintPtr( + new GCS::ConstraintP2PDistance(*aPoint, aLine->p1, aDistance->parameter()))); + aConstrList.push_back(GCSConstraintPtr( + new GCS::ConstraintP2PDistance(*aPoint, aLine->p2, aDistance->parameter()))); + + // Workaround to avoid conflicting constraints when the point is already placed on line + if (thePoint->group() != GID_UNKNOWN && isPointOnLine(*aPoint, *aLine)) { + std::shared_ptr aCoord = + std::dynamic_pointer_cast(thePoint->baseAttribute()); + if (aCoord) { + *(aPoint->x) = (*(aLine->p1.x) + *(aLine->p2.x)) * 0.5; + *(aPoint->y) = (*(aLine->p1.y) + *(aLine->p2.y)) * 0.5; + aCoord->setValue(*(aPoint->x), *(aPoint->y)); + } + } + + std::shared_ptr aResult(new PlaneGCSSolver_ConstraintWrapper( + theConstraint, aConstrList, CONSTRAINT_MIDDLE_POINT)); + aResult->setGroup(theGroupID); + std::list aSubs(1, thePoint); + aSubs.push_back(theEntity); + aResult->setEntities(aSubs); + aResult->setValueParameter(aDistance); + return aResult; +} + + ConstraintWrapperPtr createConstraintDistancePointPoint( ConstraintPtr theConstraint, const GroupID& theGroupID, diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index 47ec0fdb3..1d765142e 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,8 @@ SketchSolver_ConstraintType SketchSolver_Constraint::TYPE(ConstraintPtr theConst return CONSTRAINT_TANGENT; else if (aType == SketchPlugin_ConstraintCollinear::ID()) return CONSTRAINT_COLLINEAR; + else if (aType == SketchPlugin_ConstraintMiddle::ID()) + return CONSTRAINT_MIDDLE_POINT; return CONSTRAINT_UNKNOWN; } diff --git a/src/SketchSolver/SketchSolver_IConstraintWrapper.h b/src/SketchSolver/SketchSolver_IConstraintWrapper.h index fcd0c597a..12bf83423 100644 --- a/src/SketchSolver/SketchSolver_IConstraintWrapper.h +++ b/src/SketchSolver/SketchSolver_IConstraintWrapper.h @@ -21,6 +21,7 @@ enum SketchSolver_ConstraintType { CONSTRAINT_PT_PT_COINCIDENT, CONSTRAINT_PT_ON_LINE, CONSTRAINT_PT_ON_CIRCLE, + CONSTRAINT_MIDDLE_POINT, CONSTRAINT_DISTANCE, // base distance if we don't know the measured objects yet CONSTRAINT_PT_PT_DISTANCE, CONSTRAINT_PT_LINE_DISTANCE, diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_ConstraintType.h b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_ConstraintType.h index a38939bd4..14ecf3adc 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_ConstraintType.h +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_ConstraintType.h @@ -19,6 +19,7 @@ namespace ConstraintType case CONSTRAINT_PT_PT_COINCIDENT: return SLVS_C_POINTS_COINCIDENT; case CONSTRAINT_PT_ON_LINE: return SLVS_C_PT_ON_LINE; case CONSTRAINT_PT_ON_CIRCLE: return SLVS_C_PT_ON_CIRCLE; + case CONSTRAINT_MIDDLE_POINT: return SLVS_C_AT_MIDPOINT; case CONSTRAINT_PT_PT_DISTANCE: return SLVS_C_PT_PT_DISTANCE; case CONSTRAINT_PT_LINE_DISTANCE: return SLVS_C_PT_LINE_DISTANCE; case CONSTRAINT_ANGLE: return SLVS_C_ANGLE; @@ -48,6 +49,7 @@ namespace ConstraintType case SLVS_C_POINTS_COINCIDENT: return CONSTRAINT_PT_PT_COINCIDENT; case SLVS_C_PT_ON_LINE: return CONSTRAINT_PT_ON_LINE; case SLVS_C_PT_ON_CIRCLE: return CONSTRAINT_PT_ON_CIRCLE; + case SLVS_C_AT_MIDPOINT: return CONSTRAINT_MIDDLE_POINT; case SLVS_C_PT_PT_DISTANCE: return CONSTRAINT_PT_PT_DISTANCE; case SLVS_C_PT_LINE_DISTANCE: return CONSTRAINT_PT_LINE_DISTANCE; case SLVS_C_EQUAL_LENGTH_LINES: return CONSTRAINT_EQUAL_LINES; -- 2.39.2