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);
#include "SketchPlugin_Line.h"
#include "SketchPlugin_Arc.h"
#include "SketchPlugin_Circle.h"
+#include "SketchPlugin_Point.h"
#include "SketcherPrs_Tools.h"
return true;
}
+
+bool SketchPlugin_CoincidenceAttrValidator::isValid(
+ const AttributePtr& theAttribute, const std::list<std::string>& 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<ModelAPI_Feature>(theAttribute->owner());
+ AttributeRefAttrPtr aRefAttrA = aConstraint->data()->refattr(aParamA);
+ if (!aRefAttrA)
+ return false;
+
+ AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(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;
+}
+
};
+/**\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<std::string>& theArguments) const;
+};
+
#endif
</feature>
<!-- SketchConstraintCoincedence -->
- <feature id="SketchConstraintCoincidence" title="Coincident" tooltip="Create constraint for the coincidence of two points" icon=":icons/coincedence.png">
- <sketch_shape_selector id="ConstraintEntityA" label="First point" tooltip="Select a first point" shape_types="vertex">
+ <feature id="SketchConstraintCoincidence" title="Coincident" tooltip="Create constraint for the coincidence of two points or point on line or circle" icon=":icons/coincedence.png">
+ <sketch_shape_selector id="ConstraintEntityA" label="First object" tooltip="Select a first object" shape_types="vertex edge">
<validator id="PartSet_DifferentObjects"/>
<validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
</sketch_shape_selector>
- <sketch_shape_selector id="ConstraintEntityB" label="Second point" tooltip="Select a second point" shape_types="vertex">
+ <sketch_shape_selector id="ConstraintEntityB" label="Second object" tooltip="Select a second object" shape_types="vertex edge">
<validator id="PartSet_DifferentObjects"/>
<validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
+ <validator id="SketchPlugin_CoincidenceAttr" parameters="ConstraintEntityA"/>
</sketch_shape_selector>
<validator id="PartSet_CoincidentSelection"/>
</feature>
getAttributes(aValue, anAttributes);
if (!myErrorMsg.empty())
return;
+ if (aConstrType == SLVS_C_UNKNOWN)
+ aConstrType = getType();
Slvs_hGroup aGroupID = myGroup->getId();
Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId();
#include <map>
+void SketchSolver_ConstraintCoincidence::getAttributes(
+ double& theValue,
+ std::vector<Slvs_hEntity>& 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)
bool SketchSolver_ConstraintCoincidence::isCoincide(
std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint) const
{
+ // Multi-coincidence allowed for two points only
+ if (getType() != theConstraint->getType() || getType() != SLVS_C_POINTS_COINCIDENT)
+ return false;
+
std::set<AttributePtr>::const_iterator anAttrIter = theConstraint->myCoincidentPoints.begin();
for (; anAttrIter != theConstraint->myCoincidentPoints.end(); anAttrIter++)
if (myCoincidentPoints.find(*anAttrIter) != myCoincidentPoints.end())
{
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)
/// \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<Slvs_hEntity>& theAttributes);
+
private:
/// \brief Creates new coincidence constraint
Slvs_hConstraint addConstraint(Slvs_hEntity thePoint1, Slvs_hEntity thePoint2);
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<Slvs_hConstraint, ConstraintPtr> myExtraCoincidence; ///< multiple coincidence of points
std::set<AttributePtr> myCoincidentPoints; ///< list of points under the Coincidence constraint
};