#include <SketchPlugin_Arc.h>
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Point.h>
+#include <SketchPlugin_ConstraintAngle.h>
#include <SketchPlugin_ConstraintLength.h>
#include <SketchPlugin_ConstraintDistance.h>
#include <SketchPlugin_ConstraintParallel.h>
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);
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);
}
}
#include <SketchPlugin_ConstraintCoincidence.h>
#include <SketchPlugin_ConstraintFillet.h>
#include <SketchPlugin_ConstraintMirror.h>
+#include <SketchPlugin_ConstraintAngle.h>
#include <SketchPlugin_MultiRotation.h>
#include <SketchPlugin_MultiTranslation.h>
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();
}
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)
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<std::string>& theArguments,
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 ////////////////
SketchPlugin_ConstraintTangent.h
SketchPlugin_ConstraintMirror.h
SketchPlugin_ConstraintFillet.h
+ SketchPlugin_ConstraintAngle.h
SketchPlugin_MultiRotation.h
SketchPlugin_MultiTranslation.h
SketchPlugin_ExternalValidator.h
SketchPlugin_ConstraintTangent.cpp
SketchPlugin_ConstraintMirror.cpp
SketchPlugin_ConstraintFillet.cpp
+ SketchPlugin_ConstraintAngle.cpp
SketchPlugin_MultiRotation.cpp
SketchPlugin_MultiTranslation.cpp
SketchPlugin_ExternalValidator.cpp
--- /dev/null
+// 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 <SketchPlugin_Line.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <GeomDataAPI_Point2D.h>
+
+#include <GeomAPI_Dir2d.h>
+#include <GeomAPI_Lin2d.h>
+#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_XY.h>
+
+#include <SketcherPrs_Factory.h>
+#include <SketcherPrs_Tools.h>
+
+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<ModelAPI_Data> aData = data();
+ AttributeDoublePtr anAttrValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+ 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<ModelAPI_Data> 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<ModelAPI_AttributeDouble> 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<ModelAPI_Data> aData = data();
+ std::shared_ptr<GeomAPI_Ax3> 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<GeomDataAPI_Point2D> aPointA1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineA->attribute(SketchPlugin_Line::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aPointA2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineA->attribute(SketchPlugin_Line::END_ID()));
+
+ std::shared_ptr<GeomDataAPI_Point2D> aPointB1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineB->attribute(SketchPlugin_Line::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aPointB2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineB->attribute(SketchPlugin_Line::END_ID()));
+
+ std::shared_ptr<GeomAPI_Pnt2d> aStartA = aPointA1->pnt();
+ std::shared_ptr<GeomAPI_Pnt2d> aEndA = aPointA2->pnt();
+ std::shared_ptr<GeomAPI_Pnt2d> aStartB = aPointB1->pnt();
+ std::shared_ptr<GeomAPI_Pnt2d> aEndB = aPointB2->pnt();
+ if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance)
+ return anAngle;
+
+ // Lines and their intersection point
+ std::shared_ptr<GeomAPI_Lin2d> aLA(new GeomAPI_Lin2d(aStartA, aEndA));
+ std::shared_ptr<GeomAPI_Lin2d> aLB(new GeomAPI_Lin2d(aStartB, aEndB));
+ std::shared_ptr<GeomAPI_Pnt2d> 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<GeomAPI_Dir2d> aDirA(new GeomAPI_Dir2d(aEndA->xy()->decreased(anInter->xy())));
+ std::shared_ptr<GeomAPI_Dir2d> aDirB(new GeomAPI_Dir2d(aEndB->xy()->decreased(anInter->xy())));
+
+ anAngle = aDirA->angle(aDirB) * 180.0 / PI;
+ return anAngle;
+}
--- /dev/null
+// 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 <SketchPlugin_Sketch.h>
+#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
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");
#include <SketchPlugin_Point.h>
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_ConstraintAngle.h>
#include <SketchPlugin_ConstraintCoincidence.h>
#include <SketchPlugin_ConstraintDistance.h>
#include <SketchPlugin_ConstraintEqual.h>
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();
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);
}
<group id="Basic">
<feature
id="Sketch"
- nested="SketchPoint SketchLine SketchCircle SketchArc SketchConstraintLength SketchConstraintRadius SketchConstraintDistance SketchConstraintParallel SketchConstraintPerpendicular SketchConstraintRigid SketchConstraintHorizontal SketchConstraintVertical SketchConstraintEqual SketchConstraintTangent SketchConstraintFillet SketchConstraintCoincidence SketchConstraintMirror SketchMultiRotation SketchMultiTranslation"
+ nested="SketchPoint SketchLine SketchCircle SketchArc SketchConstraintLength SketchConstraintRadius SketchConstraintDistance SketchConstraintParallel SketchConstraintPerpendicular SketchConstraintRigid SketchConstraintHorizontal SketchConstraintVertical SketchConstraintEqual SketchConstraintTangent SketchConstraintFillet SketchConstraintCoincidence SketchConstraintMirror SketchConstraintAngle SketchMultiRotation SketchMultiTranslation"
when_nested="accept abort"
title="Sketch"
tooltip="Create sketch"
<validator id="PartSet_TangentSelection"/>
</feature>
+
+ <!-- SketchConstraintAngle -->
+ <feature id="SketchConstraintAngle" title="Angle" tooltip="Set fixed angle between two line segments">
+ <shape_selector id="ConstraintEntityA" label="Line" tooltip="Select an line" shape_types="edge" >
+ <validator id="GeomValidators_ShapeType" parameters="line"/>
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
+ </shape_selector>
+ <shape_selector id="ConstraintEntityB" label="Line" tooltip="Select an line" shape_types="edge" >
+ <validator id="GeomValidators_ShapeType" parameters="line"/>
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
+ </shape_selector>
+ <doublevalue_editor label="Value" tooltip="Angle" id="ConstraintValue" default="computed" />
+ <validator id="PartSet_AngleSelection"/>
+ </feature>
+
</group>
// Author: Artem ZHIDKOV
#include "SketchSolver_Builder.h"
+#include <SketchPlugin_ConstraintAngle.h>
#include <SketchSolver_ConstraintCoincidence.h>
#include <SketchSolver_ConstraintDistance.h>
#include <SketchSolver_ConstraintEqual.h>
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;
}
}
};
+
+/** \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
aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aPrs));
return aAISObj;
}
+
+AISObjectPtr SketcherPrs_Factory::angleConstraint(ModelAPI_Feature* theConstraint,
+ const std::shared_ptr<GeomAPI_Ax3>& thePlane)
+{
+ return AISObjectPtr(new GeomAPI_AISObject());
+}
/// \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