Salome HOME
Implementation of the Angle constraint (issue #788)
authorazv <azv@opencascade.com>
Wed, 19 Aug 2015 11:29:43 +0000 (14:29 +0300)
committerazv <azv@opencascade.com>
Wed, 19 Aug 2015 11:30:49 +0000 (14:30 +0300)
14 files changed:
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_Validators.cpp
src/PartSet/PartSet_Validators.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintAngle.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintCoincidence.h
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/SketchSolver_Builder.cpp
src/SketchSolver/SketchSolver_Constraint.h
src/SketcherPrs/SketcherPrs_Factory.cpp
src/SketcherPrs/SketcherPrs_Factory.h

index 09fdef8f2b934e8ad79989ca97772c77b328222d..164253ada2f9b80fcc2847e34355aa8127bd7002 100644 (file)
@@ -71,6 +71,7 @@
 #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>
@@ -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);
         }
       }
index 5dd9eaf20a7ff8260d453f40dc5e8437ea1d03b4..c1d3708bd34e200a52a1ab8bfa6024e9bb3fbccf 100644 (file)
@@ -55,6 +55,7 @@
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintFillet.h>
 #include <SketchPlugin_ConstraintMirror.h>
+#include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_MultiRotation.h>
 #include <SketchPlugin_MultiTranslation.h>
 
@@ -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)
index b6be3e0e387eb648391936c3148011b0c1cccbd5..f62a88b48ba1f732d56afe91ad93b904dbdb7eb5 100644 (file)
@@ -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<std::string>& theArguments,
index 04868061328dd0c76631f18a1c82f33eb1ca53da..de46a76605cd87e330b00fe2d3205fd41b4fa415 100644 (file)
@@ -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 ////////////////
 
 
index 914dcfc596debcc3af332701192c09dc45dc8951..1780d356e10a46311bf4b0f64199d32bf7580051 100644 (file)
@@ -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 (file)
index 0000000..c298122
--- /dev/null
@@ -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 <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;
+}
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.h b/src/SketchPlugin/SketchPlugin_ConstraintAngle.h
new file mode 100644 (file)
index 0000000..92f5057
--- /dev/null
@@ -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 <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
index c3f359d73bcc52b51177bcdaf8637b77f7490fe3..ffc4ce1b9e1f0fb1ef8986ba91c0a38d453913fc 100644 (file)
@@ -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");
index 1852d4a745f4786b9a749151e16210ddf6804257..970af790f8c82d7cfa568b0350f023500251fbfc 100644 (file)
@@ -6,6 +6,7 @@
 #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>
@@ -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<ModelAPI_FeatureStateMessage> 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);
     }
index a208a9cd8f73edd364a3e6621de7050ca5192b6f..3c529f6883ab09f4d64dc8d765e12b236d2f8e8e 100644 (file)
@@ -5,7 +5,7 @@
     <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>
     
index e311b4b55697ead5d95f352bbfcfba039514daad..8e27a4b4156d83a5191b8e2fd0cc7c1c751c1b7a 100644 (file)
@@ -5,6 +5,7 @@
 // Author:  Artem ZHIDKOV
 
 #include "SketchSolver_Builder.h"
+#include <SketchPlugin_ConstraintAngle.h>
 #include <SketchSolver_ConstraintCoincidence.h>
 #include <SketchSolver_ConstraintDistance.h>
 #include <SketchSolver_ConstraintEqual.h>
@@ -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;
 }
index 2a12fc5e95e47b0fb8ee7e21a37cf086bd645f0a..6e048ccaf839b2cf053a293000ab834583a33e9a 100644 (file)
@@ -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
index b855929ab16f7513ffb86b1fe71fd7761c31a492..6a8672dac148299007ebcd6aaecfa279154ef1bb 100644 (file)
@@ -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<GeomAPI_Ax3>& thePlane)
+{
+  return AISObjectPtr(new GeomAPI_AISObject());
+}
index 291484d3b491e53960406d4d28462de3e29db618..c0101fa0a47a3b39231c246ae94c9be64dcc59bb 100644 (file)
@@ -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