From 4df3d12284892e126685f42a4e3c3c7f63f3b502 Mon Sep 17 00:00:00 2001 From: azv Date: Wed, 19 Aug 2015 14:29:43 +0300 Subject: [PATCH] Implementation of the Angle constraint (issue #788) --- src/PartSet/PartSet_Module.cpp | 5 +- src/PartSet/PartSet_SketcherMgr.cpp | 5 +- src/PartSet/PartSet_Validators.cpp | 6 + src/PartSet/PartSet_Validators.h | 8 ++ src/SketchPlugin/CMakeLists.txt | 2 + .../SketchPlugin_ConstraintAngle.cpp | 126 ++++++++++++++++++ .../SketchPlugin_ConstraintAngle.h | 57 ++++++++ .../SketchPlugin_ConstraintCoincidence.h | 2 +- src/SketchPlugin/SketchPlugin_Plugin.cpp | 4 + src/SketchPlugin/plugin-Sketch.xml | 19 ++- src/SketchSolver/SketchSolver_Builder.cpp | 3 + src/SketchSolver/SketchSolver_Constraint.h | 23 ++++ src/SketcherPrs/SketcherPrs_Factory.cpp | 6 + src/SketcherPrs/SketcherPrs_Factory.h | 5 + 14 files changed, 267 insertions(+), 4 deletions(-) create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintAngle.h diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 09fdef8f2..164253ada 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -199,6 +200,7 @@ void PartSet_Module::registerValidators() aFactory->registerValidator("PartSet_HVDirSelection", new PartSet_HVDirSelection); aFactory->registerValidator("PartSet_TangentSelection", new PartSet_TangentSelection); aFactory->registerValidator("PartSet_FilletSelection", new PartSet_FilletSelection); + aFactory->registerValidator("PartSet_AngleSelection", new PartSet_AngleSelection); aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator); aFactory->registerValidator("PartSet_DifferentShapes", new ModelAPI_ShapeValidator); @@ -463,7 +465,8 @@ void PartSet_Module::onSelectionChanged() std::string aId = aFeature->getKind(); if ((aId == SketchPlugin_ConstraintRadius::ID()) || (aId == SketchPlugin_ConstraintLength::ID()) || - (aId == SketchPlugin_ConstraintDistance::ID())) { + (aId == SketchPlugin_ConstraintDistance::ID()) || + (aId == SketchPlugin_ConstraintAngle::ID())) { editFeature(aFeature); } } diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 5dd9eaf20..c1d3708bd 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -672,6 +673,7 @@ const QStringList& PartSet_SketcherMgr::constraintsIdList() aIds << SketchPlugin_ConstraintTangent::ID().c_str(); aIds << SketchPlugin_ConstraintCoincidence::ID().c_str(); aIds << SketchPlugin_ConstraintMirror::ID().c_str(); + aIds << SketchPlugin_ConstraintAngle::ID().c_str(); aIds << SketchPlugin_MultiRotation::ID().c_str(); aIds << SketchPlugin_MultiTranslation::ID().c_str(); } @@ -719,7 +721,8 @@ bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation return (aId == SketchPlugin_ConstraintLength::ID()) || (aId == SketchPlugin_ConstraintDistance::ID()) || - (aId == SketchPlugin_ConstraintRadius::ID()); + (aId == SketchPlugin_ConstraintRadius::ID()) || + (aId == SketchPlugin_ConstraintAngle::ID()); } void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp index b6be3e0e3..f62a88b48 100644 --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -182,6 +182,12 @@ bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection return false; } +bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection) const +{ + int aCount = shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); +} + bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, const std::list& theArguments, diff --git a/src/PartSet/PartSet_Validators.h b/src/PartSet/PartSet_Validators.h index 048680613..de46a7660 100644 --- a/src/PartSet/PartSet_Validators.h +++ b/src/PartSet/PartSet_Validators.h @@ -98,6 +98,14 @@ class PartSet_FilletSelection : public ModuleBase_SelectionValidator PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; }; +//! \ingroup Validators +//! A class to validate a selection for Angle constraints operation +class PartSet_AngleSelection : public ModuleBase_SelectionValidator +{ + protected: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +}; + ////////////// Attribute validators //////////////// diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index 914dcfc59..1780d356e 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -28,6 +28,7 @@ SET(PROJECT_HEADERS SketchPlugin_ConstraintTangent.h SketchPlugin_ConstraintMirror.h SketchPlugin_ConstraintFillet.h + SketchPlugin_ConstraintAngle.h SketchPlugin_MultiRotation.h SketchPlugin_MultiTranslation.h SketchPlugin_ExternalValidator.h @@ -59,6 +60,7 @@ SET(PROJECT_SOURCES SketchPlugin_ConstraintTangent.cpp SketchPlugin_ConstraintMirror.cpp SketchPlugin_ConstraintFillet.cpp + SketchPlugin_ConstraintAngle.cpp SketchPlugin_MultiRotation.cpp SketchPlugin_MultiTranslation.cpp SketchPlugin_ExternalValidator.cpp diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp new file mode 100644 index 000000000..c298122ba --- /dev/null +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp @@ -0,0 +1,126 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +// File: SketchPlugin_ConstraintAngle.cpp +// Created: 19 August 2015 +// Author: Artem ZHIDKOV + +#include "SketchPlugin_ConstraintAngle.h" +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +const double tolerance = 1.e-7; +#define PI 3.1415926535897932 + + +SketchPlugin_ConstraintAngle::SketchPlugin_ConstraintAngle() +{ +} + +void SketchPlugin_ConstraintAngle::initAttributes() +{ + data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); + data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId()); +} + +void SketchPlugin_ConstraintAngle::execute() +{ + std::shared_ptr aData = data(); + AttributeDoublePtr anAttrValue = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Constraint::VALUE())); + + if(anAttrValue->isInitialized()) + return; + + double anAngle = calculateAngle(); + anAttrValue->setValue(anAngle); +} + +AISObjectPtr SketchPlugin_ConstraintAngle::getAISObject(AISObjectPtr thePrevious) +{ + if (!sketch()) + return thePrevious; + + AISObjectPtr anAIS = thePrevious; + if (!anAIS) { + anAIS = SketcherPrs_Factory::angleConstraint(this, sketch()->coordinatePlane()); + } + return anAIS; +} + +void SketchPlugin_ConstraintAngle::attributeChanged(const std::string& theID) +{ + if (theID == SketchPlugin_Constraint::ENTITY_A() || + theID == SketchPlugin_Constraint::ENTITY_B()) { + std::shared_ptr aData = data(); + if (!aData) + return; + FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A()); + FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B()); + if (!aLineA || !aLineB) + return; + + std::shared_ptr aValueAttr = std::dynamic_pointer_cast< + ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE())); + if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value + double anAngle = calculateAngle(); + aValueAttr->setValue(anAngle); + } + } +} + +double SketchPlugin_ConstraintAngle::calculateAngle() +{ + double anAngle = 0.0; + + std::shared_ptr aData = data(); + std::shared_ptr aPlane = SketchPlugin_Sketch::plane(sketch()); + FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A()); + FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B()); + + // Start and end points of lines + std::shared_ptr aPointA1 = std::dynamic_pointer_cast( + aLineA->attribute(SketchPlugin_Line::START_ID())); + std::shared_ptr aPointA2 = std::dynamic_pointer_cast( + aLineA->attribute(SketchPlugin_Line::END_ID())); + + std::shared_ptr aPointB1 = std::dynamic_pointer_cast( + aLineB->attribute(SketchPlugin_Line::START_ID())); + std::shared_ptr aPointB2 = std::dynamic_pointer_cast( + aLineB->attribute(SketchPlugin_Line::END_ID())); + + std::shared_ptr aStartA = aPointA1->pnt(); + std::shared_ptr aEndA = aPointA2->pnt(); + std::shared_ptr aStartB = aPointB1->pnt(); + std::shared_ptr aEndB = aPointB2->pnt(); + if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance) + return anAngle; + + // Lines and their intersection point + std::shared_ptr aLA(new GeomAPI_Lin2d(aStartA, aEndA)); + std::shared_ptr aLB(new GeomAPI_Lin2d(aStartB, aEndB)); + std::shared_ptr anInter = aLA->intersect(aLB); + if (!anInter) + return anAngle; + + // Directions of lines + if (anInter->distance(aEndA) < tolerance) + aEndA = aStartA; + if (anInter->distance(aEndB) < tolerance) + aEndB = aStartB; + std::shared_ptr aDirA(new GeomAPI_Dir2d(aEndA->xy()->decreased(anInter->xy()))); + std::shared_ptr aDirB(new GeomAPI_Dir2d(aEndB->xy()->decreased(anInter->xy()))); + + anAngle = aDirA->angle(aDirB) * 180.0 / PI; + return anAngle; +} diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.h b/src/SketchPlugin/SketchPlugin_ConstraintAngle.h new file mode 100644 index 000000000..92f5057fb --- /dev/null +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.h @@ -0,0 +1,57 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +// File: SketchPlugin_ConstraintAngle.h +// Created: 19 August 2015 +// Author: Artem ZHIDKOV + +#ifndef SketchPlugin_ConstraintAngle_H_ +#define SketchPlugin_ConstraintAngle_H_ + +#include "SketchPlugin.h" +#include +#include "SketchPlugin_ConstraintBase.h" + +/** \class SketchPlugin_ConstraintAngle + * \ingroup Plugins + * \brief Feature for creation of a new constraint fix angle between two lines + * + * This constraint has two attributes: + * SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B() + */ +class SketchPlugin_ConstraintAngle : public SketchPlugin_ConstraintBase +{ + public: + /// Angle constraint kind + inline static const std::string& ID() + { + static const std::string MY_CONSTRAINT_ANGLE_ID("SketchConstraintAngle"); + return MY_CONSTRAINT_ANGLE_ID; + } + /// \brief Returns the kind of a feature + SKETCHPLUGIN_EXPORT virtual const std::string& getKind() + { + static std::string MY_KIND = SketchPlugin_ConstraintAngle::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(); + + /// Called on change of any argument-attribute of this object + /// \param theID identifier of changed attribute + SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + + /// Returns the AIS preview + SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious); + + /// Calculate current value of the angle + double calculateAngle(); + + /// \brief Use plugin manager for features creation + SketchPlugin_ConstraintAngle(); +}; + +#endif diff --git a/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.h b/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.h index c3f359d73..ffc4ce1b9 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.h +++ b/src/SketchPlugin/SketchPlugin_ConstraintCoincidence.h @@ -22,7 +22,7 @@ class SketchPlugin_ConstraintCoincidence : public SketchPlugin_ConstraintBase { public: - /// Parallel constraint kind + /// Coincidence constraint kind inline static const std::string& ID() { static const std::string MY_CONSTRAINT_COINCIDENCE_ID("SketchConstraintCoincidence"); diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 1852d4a74..970af790f 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -136,6 +137,8 @@ FeaturePtr SketchPlugin_Plugin::createFeature(string theFeatureID) return FeaturePtr(new SketchPlugin_MultiTranslation); } else if (theFeatureID == SketchPlugin_MultiRotation::ID()) { return FeaturePtr(new SketchPlugin_MultiRotation); + } else if (theFeatureID == SketchPlugin_ConstraintAngle::ID()) { + return FeaturePtr(new SketchPlugin_ConstraintAngle); } // feature of such kind is not found return FeaturePtr(); @@ -186,6 +189,7 @@ std::shared_ptr SketchPlugin_Plugin aMsg->setState(SketchPlugin_ConstraintTangent::ID(), aHasSketchPlane); aMsg->setState(SketchPlugin_ConstraintMirror::ID(), aHasSketchPlane); aMsg->setState(SketchPlugin_ConstraintFillet::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintAngle::ID(), aHasSketchPlane); aMsg->setState(SketchPlugin_MultiRotation::ID(), aHasSketchPlane); aMsg->setState(SketchPlugin_MultiTranslation::ID(), aHasSketchPlane); } diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index a208a9cd8..3c529f688 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -5,7 +5,7 @@ + + + + + + + + + + + + + + + + + diff --git a/src/SketchSolver/SketchSolver_Builder.cpp b/src/SketchSolver/SketchSolver_Builder.cpp index e311b4b55..8e27a4b41 100644 --- a/src/SketchSolver/SketchSolver_Builder.cpp +++ b/src/SketchSolver/SketchSolver_Builder.cpp @@ -5,6 +5,7 @@ // Author: Artem ZHIDKOV #include "SketchSolver_Builder.h" +#include #include #include #include @@ -127,6 +128,8 @@ SolverConstraintPtr SketchSolver_Builder::createConstraint(ConstraintPtr theCons return SolverConstraintPtr(new SketchSolver_ConstraintMultiTranslation(theConstraint)); } else if (theConstraint->getKind() == SketchPlugin_MultiRotation::ID()) { return SolverConstraintPtr(new SketchSolver_ConstraintMultiRotation(theConstraint)); + } else if (theConstraint->getKind() == SketchPlugin_ConstraintAngle::ID()) { + return SolverConstraintPtr(new SketchSolver_ConstraintAngle(theConstraint)); } return aResult; } diff --git a/src/SketchSolver/SketchSolver_Constraint.h b/src/SketchSolver/SketchSolver_Constraint.h index 2a12fc5e9..6e048ccaf 100644 --- a/src/SketchSolver/SketchSolver_Constraint.h +++ b/src/SketchSolver/SketchSolver_Constraint.h @@ -223,4 +223,27 @@ public: } }; + +/** \class SketchSolver_ConstraintAngle + * \ingroup Plugins + * \brief Convert Agnle constraint to SolveSpace structure + */ +class SketchSolver_ConstraintAngle : public SketchSolver_Constraint +{ +public: + SketchSolver_ConstraintAngle(ConstraintPtr theConstraint) : + SketchSolver_Constraint(theConstraint) + {} + + virtual int getType() const + { return SLVS_C_ANGLE; } + + virtual void adjustConstraint() + { + Slvs_Constraint aConstraint = myStorage->getConstraint(mySlvsConstraints.front()); + aConstraint.other = aConstraint.valA >= 0.0; + myStorage->updateConstraint(aConstraint); + } +}; + #endif diff --git a/src/SketcherPrs/SketcherPrs_Factory.cpp b/src/SketcherPrs/SketcherPrs_Factory.cpp index b855929ab..6a8672dac 100644 --- a/src/SketcherPrs/SketcherPrs_Factory.cpp +++ b/src/SketcherPrs/SketcherPrs_Factory.cpp @@ -74,3 +74,9 @@ AISObjectPtr SketcherPrs_Factory::rotateConstraint(ModelAPI_Feature* theConstrai aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aPrs)); return aAISObj; } + +AISObjectPtr SketcherPrs_Factory::angleConstraint(ModelAPI_Feature* theConstraint, + const std::shared_ptr& thePlane) +{ + return AISObjectPtr(new GeomAPI_AISObject()); +} diff --git a/src/SketcherPrs/SketcherPrs_Factory.h b/src/SketcherPrs/SketcherPrs_Factory.h index 291484d3b..c0101fa0a 100644 --- a/src/SketcherPrs/SketcherPrs_Factory.h +++ b/src/SketcherPrs/SketcherPrs_Factory.h @@ -89,6 +89,11 @@ public: /// \param theConstraint the constraint /// \param thePlane the current sketch plane GET_CONSTRAINT_PRS(rotateConstraint) + + /// Creates angle constraint presentation + /// \param theConstraint the constraint + /// \param thePlane the current sketch plane + GET_CONSTRAINT_PRS(angleConstraint) }; #endif -- 2.30.2