From 9fdd5bb2d329d3fc435f86a0247b6b5378c252b1 Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 21 Apr 2015 10:28:45 +0300 Subject: [PATCH] Implementation of point-on-line and point-on-circle constraints in terms of Coincidence constraint --- src/SketchPlugin/SketchPlugin_Plugin.cpp | 2 + src/SketchPlugin/SketchPlugin_Validators.cpp | 44 +++++++++++++++++++ src/SketchPlugin/SketchPlugin_Validators.h | 16 +++++++ src/SketchPlugin/plugin-Sketch.xml | 7 +-- src/SketchSolver/SketchSolver_Constraint.cpp | 2 + .../SketchSolver_ConstraintCoincidence.cpp | 28 ++++++++++++ .../SketchSolver_ConstraintCoincidence.h | 11 ++++- 7 files changed, 105 insertions(+), 5 deletions(-) diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 91a92ce7b..ff8824f81 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -61,6 +61,8 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() new SketchPlugin_EqualAttrValidator); aFactory->registerValidator("SketchPlugin_MirrorAttr", new SketchPlugin_MirrorAttrValidator); + aFactory->registerValidator("SketchPlugin_CoincidenceAttr", + new SketchPlugin_CoincidenceAttrValidator); // register this plugin ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 72f0b61d1..674f9de12 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -11,6 +11,7 @@ #include "SketchPlugin_Line.h" #include "SketchPlugin_Arc.h" #include "SketchPlugin_Circle.h" +#include "SketchPlugin_Point.h" #include "SketcherPrs_Tools.h" @@ -236,3 +237,46 @@ bool SketchPlugin_MirrorAttrValidator::isValid( return true; } + +bool SketchPlugin_CoincidenceAttrValidator::isValid( + const AttributePtr& theAttribute, const std::list& theArguments ) const +{ + // 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 aConstraint = std::dynamic_pointer_cast(theAttribute->owner()); + AttributeRefAttrPtr aRefAttrA = aConstraint->data()->refattr(aParamA); + if (!aRefAttrA) + return false; + + AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast(theAttribute); + if (!aRefAttrB) + return false; + + // first attribute is a point, it may coincide with any object + if (!aRefAttrA->isObject()) + return true; + else { + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttrA->object()); + if (!aFeature) + return false; + if (aFeature->getKind() == SketchPlugin_Point::ID()) + return true; + } + + // second attribute is a point, it may coincide with any object + if (!aRefAttrB->isObject()) + return true; + else { + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttrB->object()); + if (!aFeature) + return false; + if (aFeature->getKind() == SketchPlugin_Point::ID()) + return true; + } + + return false; +} + diff --git a/src/SketchPlugin/SketchPlugin_Validators.h b/src/SketchPlugin/SketchPlugin_Validators.h index e4f6d36d6..82e0e1fce 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.h +++ b/src/SketchPlugin/SketchPlugin_Validators.h @@ -93,4 +93,20 @@ class SketchPlugin_MirrorAttrValidator : public ModelAPI_AttributeValidator }; +/**\class SketchPlugin_CoincidenceAttrValidator + * \ingroup Validators + * \brief Validator for the coincidence constraint input. + * + * It checks that attributes of the Coincidence constraint are correct. + */ +class SketchPlugin_CoincidenceAttrValidator : public ModelAPI_AttributeValidator +{ + public: + //! returns true if attribute is valid + //! \param theAttribute the checked attribute + //! \param theArguments arguments of the attribute (not used) + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments) const; +}; + #endif diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 87f4cf324..6474268be 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -142,14 +142,15 @@ - - + + - + + diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index 4e815d649..918a8026b 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -85,6 +85,8 @@ void SketchSolver_Constraint::process() getAttributes(aValue, anAttributes); if (!myErrorMsg.empty()) return; + if (aConstrType == SLVS_C_UNKNOWN) + aConstrType = getType(); Slvs_hGroup aGroupID = myGroup->getId(); Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId(); diff --git a/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp b/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp index 721913b19..69eb1181a 100644 --- a/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp @@ -4,6 +4,30 @@ #include +void SketchSolver_ConstraintCoincidence::getAttributes( + double& theValue, + std::vector& theAttributes) +{ + SketchSolver_Constraint::getAttributes(theValue, theAttributes); + if (!myErrorMsg.empty() || theAttributes[0] == SLVS_E_UNKNOWN) + return; + + if (theAttributes[1] != SLVS_E_UNKNOWN) + myType = SLVS_C_POINTS_COINCIDENT; + else if (theAttributes[2] != SLVS_E_UNKNOWN) { + // check the type of entity (line or circle) + Slvs_Entity anEnt = myStorage->getEntity(theAttributes[2]); + if (anEnt.type == SLVS_E_LINE_SEGMENT) + myType = SLVS_C_PT_ON_LINE; + else if (anEnt.type == SLVS_E_CIRCLE || anEnt.type == SLVS_E_ARC_OF_CIRCLE) + myType = SLVS_C_PT_ON_CIRCLE; + else + myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); + } else + myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); +} + + bool SketchSolver_ConstraintCoincidence::hasConstraint(ConstraintPtr theConstraint) const { if (myBaseConstraint == theConstraint) @@ -28,6 +52,10 @@ std::list SketchSolver_ConstraintCoincidence::constraints() const bool SketchSolver_ConstraintCoincidence::isCoincide( std::shared_ptr theConstraint) const { + // Multi-coincidence allowed for two points only + if (getType() != theConstraint->getType() || getType() != SLVS_C_POINTS_COINCIDENT) + return false; + std::set::const_iterator anAttrIter = theConstraint->myCoincidentPoints.begin(); for (; anAttrIter != theConstraint->myCoincidentPoints.end(); anAttrIter++) if (myCoincidentPoints.find(*anAttrIter) != myCoincidentPoints.end()) diff --git a/src/SketchSolver/SketchSolver_ConstraintCoincidence.h b/src/SketchSolver/SketchSolver_ConstraintCoincidence.h index a5c885ade..c1d1124af 100644 --- a/src/SketchSolver/SketchSolver_ConstraintCoincidence.h +++ b/src/SketchSolver/SketchSolver_ConstraintCoincidence.h @@ -19,11 +19,12 @@ class SketchSolver_ConstraintCoincidence : public SketchSolver_Constraint { public: SketchSolver_ConstraintCoincidence(ConstraintPtr theConstraint) : - SketchSolver_Constraint(theConstraint) + SketchSolver_Constraint(theConstraint), + myType(SLVS_C_UNKNOWN) {} virtual int getType() const - { return SLVS_C_POINTS_COINCIDENT; } + { return myType; } /// \brief Tries to remove constraint /// \return \c false, if current constraint contains another SketchPlugin constraints (like for multiple coincidence) @@ -45,6 +46,11 @@ protected: /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints virtual void process(); + /// \brief Generate list of attributes of constraint in order useful for SolveSpace constraints + /// \param[out] theValue numerical characteristic of constraint (e.g. distance) + /// \param[out] theAttributes list of attributes to be filled + virtual void getAttributes(double& theValue, std::vector& theAttributes); + private: /// \brief Creates new coincidence constraint Slvs_hConstraint addConstraint(Slvs_hEntity thePoint1, Slvs_hEntity thePoint2); @@ -53,6 +59,7 @@ private: void addConstraint(ConstraintPtr theConstraint); private: + int myType; ///< type of constraint (applicable SLVS_C_POINTS_COINCIDENT or SLVS_C_PT_ON_LINE or SLVS_C_PT_ON_CIRCLE) std::map myExtraCoincidence; ///< multiple coincidence of points std::set myCoincidentPoints; ///< list of points under the Coincidence constraint }; -- 2.39.2