Salome HOME
There is implemented fixed constraint for the points which coordinates are given...
authorazv <azv@opencascade.com>
Mon, 14 Sep 2015 15:35:44 +0000 (18:35 +0300)
committerazv <azv@opencascade.com>
Mon, 14 Sep 2015 15:36:17 +0000 (18:36 +0300)
src/SketchSolver/CMakeLists.txt
src/SketchSolver/SketchSolver_Builder.cpp
src/SketchSolver/SketchSolver_Builder.h
src/SketchSolver/SketchSolver_ConstraintParametric.cpp [new file with mode: 0644]
src/SketchSolver/SketchSolver_ConstraintParametric.h [new file with mode: 0644]
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Group.h

index 97441526be0b1feb9d2aa7b23a42abca4265b12b..126fb212e7c6cddf5886afbd8a885f0bf7fe2b93 100644 (file)
@@ -21,6 +21,7 @@ SET(PROJECT_HEADERS
     SketchSolver_ConstraintMultiRotation.h
     SketchSolver_ConstraintMultiTranslation.h
     SketchSolver_ConstraintMovement.h
+    SketchSolver_ConstraintParametric.h
     SketchSolver_Builder.h
     SketchSolver_Group.h
     SketchSolver_ConstraintManager.h
@@ -43,6 +44,7 @@ SET(PROJECT_SOURCES
     SketchSolver_ConstraintMulti.cpp
     SketchSolver_ConstraintMultiRotation.cpp
     SketchSolver_ConstraintMultiTranslation.cpp
+    SketchSolver_ConstraintParametric.cpp
     SketchSolver_ConstraintMovement.cpp
     SketchSolver_Builder.cpp
     SketchSolver_Group.cpp
index f491471df556b6894f98659fee14ee9a8564e1a4..78bfc59bb19eff477c4c13b367ec68f81425fe58 100644 (file)
@@ -18,6 +18,7 @@
 #include <SketchSolver_ConstraintMultiRotation.h>
 #include <SketchSolver_ConstraintMultiTranslation.h>
 #include <SketchSolver_ConstraintMovement.h>
+#include <SketchSolver_ConstraintParametric.h>
 #include <SketchSolver_Error.h>
 
 #include <GeomAPI_Edge.h>
@@ -151,6 +152,11 @@ SolverConstraintPtr SketchSolver_Builder::createMovementConstraint(FeaturePtr th
   return SolverConstraintPtr(new SketchSolver_ConstraintMovement(theFixedFeature));
 }
 
+SolverConstraintPtr SketchSolver_Builder::createParametricConstraint(AttributePtr theAttribute)
+{
+  return SolverConstraintPtr(new SketchSolver_ConstraintParametric(theAttribute));
+}
+
 
 
 bool SketchSolver_Builder::createWorkplane(
index 1fd353f85e541b83478500365ff701cab4cf5cfa..21beac3191fe136cf2f47f8a38d055f213b29ea3 100644 (file)
@@ -38,6 +38,9 @@ public:
   /// \brief Creates temporary constraint to fix the feature after movement
   SolverConstraintPtr createMovementConstraint(FeaturePtr theFixedFeature);
 
+  /// \brief Creates constraint for parametrically given attribute
+  SolverConstraintPtr createParametricConstraint(AttributePtr theAttribute);
+
   /// \brief Converts sketch parameters to the list of SolveSpace entities.
   ///        Identifiers of entities and parameters are local. They should be changed while adding into storage.
   ///        The sketch entity goes last.
diff --git a/src/SketchSolver/SketchSolver_ConstraintParametric.cpp b/src/SketchSolver/SketchSolver_ConstraintParametric.cpp
new file mode 100644 (file)
index 0000000..29147d7
--- /dev/null
@@ -0,0 +1,166 @@
+#include <SketchSolver_ConstraintParametric.h>
+#include <SketchSolver_Error.h>
+#include <SketchSolver_Group.h>
+
+#include <GeomDataAPI_Point2D.h>
+
+SketchSolver_ConstraintParametric::SketchSolver_ConstraintParametric(AttributePtr theAttribute)
+  : SketchSolver_ConstraintRigid(ConstraintPtr()),
+    myBaseAttribute(theAttribute)
+{
+  process();
+}
+
+void SketchSolver_ConstraintParametric::process()
+{
+  cleanErrorMsg();
+  if (!myBaseAttribute || !myStorage || myGroup == 0) {
+    /// TODO: Put error message here
+    return;
+  }
+  if (!mySlvsConstraints.empty()) // some data is changed, update constraint
+    update(myBaseConstraint);
+
+  Slvs_hEntity anAttrID;
+  getAttributes(anAttrID);
+  if (!myErrorMsg.empty() || (myFeatureMap.empty() && myAttributeMap.empty()))
+    return;
+
+  myHorizLineID = SLVS_E_UNKNOWN;
+  myVertLineID = SLVS_E_UNKNOWN;
+
+  std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
+  if (!aPoint)
+    return;
+  if (!aPoint->textX().empty()) {
+    // Create vertical line with fixed boundary point
+    Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), aPoint->x());
+    Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), -10000.0);
+    aParX.h = myStorage->addParameter(aParX);
+    aParY.h = myStorage->addParameter(aParY);
+    Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(),
+        myGroup->getWorkplaneId(), aParX.h, aParY.h);
+    aStartPoint.h = myStorage->addEntity(aStartPoint);
+    Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(),
+        myGroup->getWorkplaneId(), aStartPoint.h, anAttrID);
+    aLine.h = myStorage->addEntity(aLine);
+
+    // Fix start point
+    fixPoint(aStartPoint.h);
+    // Add vertical constraint
+    Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
+        SLVS_C_VERTICAL, myGroup->getWorkplaneId(), 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
+        aLine.h, SLVS_E_UNKNOWN);
+    aConstraint.h = myStorage->addConstraint(aConstraint);
+    mySlvsConstraints.push_back(aConstraint.h);
+    myVertLineID = aLine.h;
+    myX = aPoint->x();
+  }
+  if (!aPoint->textY().empty()) {
+    // Create horizontal line with fixed boundary point
+    Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), -10000.0);
+    Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), aPoint->y());
+    aParX.h = myStorage->addParameter(aParX);
+    aParY.h = myStorage->addParameter(aParY);
+    Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(),
+        myGroup->getWorkplaneId(), aParX.h, aParY.h);
+    aStartPoint.h = myStorage->addEntity(aStartPoint);
+    Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(),
+        myGroup->getWorkplaneId(), aStartPoint.h, anAttrID);
+    aLine.h = myStorage->addEntity(aLine);
+
+    // Fix start point
+    fixPoint(aStartPoint.h);
+    // Add horizontal constraint
+    Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
+        SLVS_C_HORIZONTAL, myGroup->getWorkplaneId(), 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
+        aLine.h, SLVS_E_UNKNOWN);
+    aConstraint.h = myStorage->addConstraint(aConstraint);
+    mySlvsConstraints.push_back(aConstraint.h);
+    myHorizLineID = aLine.h;
+    myY = aPoint->y();
+  }
+}
+
+
+void SketchSolver_ConstraintParametric::getAttributes(Slvs_hEntity& theAttributeID)
+{
+  int aType = SLVS_E_UNKNOWN; // type of created entity
+  theAttributeID = SLVS_E_UNKNOWN;
+  theAttributeID = myGroup->getAttributeId(myBaseAttribute);
+  if (theAttributeID == SLVS_E_UNKNOWN) {
+    theAttributeID = changeEntity(myBaseAttribute, aType);
+    if (theAttributeID == SLVS_E_UNKNOWN) {
+      myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
+      return;
+    }
+  }
+  else
+     myAttributeMap[myBaseAttribute] = theAttributeID;
+}
+
+
+void SketchSolver_ConstraintParametric::update(ConstraintPtr theConstraint)
+{
+  cleanErrorMsg();
+  if (!theConstraint || theConstraint == myBaseConstraint) {
+    std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
+    if (aPoint && ((!aPoint->textX().empty() && myVertLineID != SLVS_E_UNKNOWN) || 
+        (!aPoint->textY().empty() && myHorizLineID != SLVS_E_UNKNOWN))) {
+      remove();
+      process();
+      return;
+    }
+  }
+  adjustConstraint();
+}
+
+void SketchSolver_ConstraintParametric::refresh()
+{
+  Slvs_hEntity aBasePointID = myAttributeMap[myBaseAttribute];
+  const Slvs_Entity& aBasePoint = myStorage->getEntity(aBasePointID);
+  double aXY[2];
+  aXY[0] = myVertLineID  != SLVS_E_UNKNOWN ? myX : myStorage->getParameter(aBasePoint.param[0]).val;
+  aXY[1] = myHorizLineID != SLVS_E_UNKNOWN ? myY : myStorage->getParameter(aBasePoint.param[1]).val;
+
+  std::list<Slvs_Constraint> aCoincidence = myStorage->getConstraintsByType(SLVS_C_POINTS_COINCIDENT);
+  std::list<Slvs_Constraint>::const_iterator aCIt = aCoincidence.begin();
+  for (; aCIt != aCoincidence.end(); ++aCIt) {
+    if (aCIt->ptA != aBasePointID && aCIt->ptB != aBasePointID)
+      continue;
+    Slvs_hEntity anOtherPointID = aCIt->ptA == aBasePointID ? aCIt->ptB : aCIt->ptA;
+    const Slvs_Entity& aPoint = myStorage->getEntity(anOtherPointID);
+    for (int i = 0; i < 2; i++) {
+      Slvs_Param aParam = myStorage->getParameter(aPoint.param[i]);
+      aParam.val = aXY[i];
+      myStorage->updateParameter(aParam);
+    }
+  }
+}
+
+void SketchSolver_ConstraintParametric::adjustConstraint()
+{
+  std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
+  if (!aPoint)
+    return;
+
+  if (!aPoint->textX().empty()) {
+    const Slvs_Entity& aLine = myStorage->getEntity(myVertLineID);
+    const Slvs_Entity& aStartPoint = myStorage->getEntity(aLine.point[0]);
+    Slvs_Param aParX = myStorage->getParameter(aStartPoint.param[0]);
+    aParX.val = aPoint->x();
+    myStorage->updateParameter(aParX);
+    myX = aParX.val;
+  }
+  if (!aPoint->textY().empty()) {
+    const Slvs_Entity& aLine = myStorage->getEntity(myHorizLineID);
+    const Slvs_Entity& aStartPoint = myStorage->getEntity(aLine.point[0]);
+    Slvs_Param aParY = myStorage->getParameter(aStartPoint.param[1]);
+    aParY.val = aPoint->y();
+    myStorage->updateParameter(aParY);
+    myY = aParY.val;
+  }
+}
diff --git a/src/SketchSolver/SketchSolver_ConstraintParametric.h b/src/SketchSolver/SketchSolver_ConstraintParametric.h
new file mode 100644 (file)
index 0000000..61eb3e7
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:    SketchSolver_ConstraintParametric.h
+// Created: 15 Jun 2015
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchSolver_ConstraintParametric_H_
+#define SketchSolver_ConstraintParametric_H_
+
+#include "SketchSolver.h"
+#include <SketchSolver_ConstraintRigid.h>
+
+/** \class   SketchSolver_ConstraintParametric
+ *  \ingroup Plugins
+ *  \brief   Stores data of Rigid (Fixed) constraint for the attribute
+ *           which coordinates are given by parametric expression
+ */
+class SketchSolver_ConstraintParametric : public SketchSolver_ConstraintRigid
+{
+private:
+  /// Creates constraint to manage the given constraint from plugin
+  SketchSolver_ConstraintParametric()
+    : SketchSolver_ConstraintRigid(ConstraintPtr())
+  {}
+
+public:
+  /// Creates temporary constraint based on feature
+  SketchSolver_ConstraintParametric(AttributePtr theAttribute);
+
+  /// \brief Update constraint
+  virtual void update(ConstraintPtr theConstraint = ConstraintPtr());
+
+  /// \brief Update points coincident with parametric one
+  virtual void refresh();
+
+protected:
+  /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints
+  virtual void process();
+
+  /// \brief Convert attribute to the entity
+  /// \param[out] theAttributeID   identifier of the entity related to the attribute
+  virtual void getAttributes(Slvs_hEntity& theAttributeID);
+
+  /// \brief This method is used in derived objects to check consistence of constraint.
+  virtual void adjustConstraint();
+
+private:
+  AttributePtr myBaseAttribute; ///< attribute given by expression
+  Slvs_hEntity myHorizLineID;   ///< identifier of horizontal line, containing the point
+  Slvs_hEntity myVertLineID;    ///< identifier of vertical line, containing the point
+  double myX, myY;
+};
+
+#endif
index 8b4026ef22993dced39bece02f4d4af1522359d6..0e636f7df22c5f1e761327ced6cb5a71b9edf8d2 100644 (file)
@@ -209,7 +209,7 @@ bool SketchSolver_Group::changeConstraint(
   if (myWorkplaneID == SLVS_E_UNKNOWN)
     return false;
 
-  if (!theConstraint)
+  if (!theConstraint || !theConstraint->data())
     return false;
 
   if (!checkFeatureValidity(theConstraint))
@@ -298,6 +298,34 @@ bool SketchSolver_Group::changeConstraint(
     myFeatureStorage = FeatureStoragePtr(new SketchSolver_FeatureStorage);
   myFeatureStorage->changeConstraint(theConstraint);
 
+  // Check the attributes of constraint are given by parametric expression
+  std::list<AttributePtr> anAttributes =
+      theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+  std::list<AttributePtr>::iterator anAttrIt = anAttributes.begin();
+  for (; anAttrIt != anAttributes.end(); ++anAttrIt) {
+    AttributeRefAttrPtr aRefAttr =
+        std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIt);
+    if (!aRefAttr || aRefAttr->isObject())
+      continue;
+    std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
+    if (!aPoint || (aPoint->textX().empty() && aPoint->textY().empty()))
+      continue;
+
+    std::map<AttributePtr, SolverConstraintPtr>::iterator aFound =
+        myParametricConstraints.find(aRefAttr->attr());
+    if (aFound == myParametricConstraints.end()) {
+      SolverConstraintPtr aConstraint =
+          SketchSolver_Builder::getInstance()->createParametricConstraint(aRefAttr->attr());
+      if (!aConstraint)
+        continue;
+      aConstraint->setGroup(this);
+      aConstraint->setStorage(myStorage);
+      myParametricConstraints[aRefAttr->attr()] = aConstraint;
+    } else
+      aFound->second->update();
+  }
+
   return true;
 }
 
@@ -345,6 +373,20 @@ bool SketchSolver_Group::updateFeature(std::shared_ptr<SketchPlugin_Feature> the
     aSolConIter->second->addFeature(theFeature);
     myChangedConstraints.insert(aSolConIter->first);
   }
+
+  // Search attributes of the feature in the set of parametric constraints and update them
+  std::list<AttributePtr> anAttrList =
+      theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+  std::list<AttributePtr>::iterator anAttrIt = anAttrList.begin();
+  for (; anAttrIt != anAttrList.end(); ++anAttrIt) {
+    AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIt);
+    if (!aRefAttr || aRefAttr->isObject())
+      continue;
+    std::map<AttributePtr, SolverConstraintPtr>::iterator aFound =
+        myParametricConstraints.find(aRefAttr->attr());
+    if (aFound != myParametricConstraints.end())
+      aFound->second->update();
+  }
   return true;
 }
 
@@ -525,8 +567,13 @@ bool SketchSolver_Group::resolveConstraints()
     }
     if (aResult == SLVS_RESULT_OKAY) {  // solution succeeded, store results into correspondent attributes
       myFeatureStorage->blockEvents(true);
+      // First refresh parametric constraints to satisfy parameters
+      std::map<AttributePtr, SolverConstraintPtr>::iterator aParIter = myParametricConstraints.begin();
+      for (; aParIter != myParametricConstraints.end(); ++aParIter)
+        aParIter->second->refresh();
+      // Update all other constraints
       ConstraintConstraintMap::iterator aConstrIter = myConstraints.begin();
-      for (; aConstrIter != myConstraints.end(); aConstrIter++)
+      for (; aConstrIter != myConstraints.end(); ++aConstrIter)
         aConstrIter->second->refresh();
       myFeatureStorage->blockEvents(false);
       if (!myPrevSolved) {
index 79181c38288d709e769fe9e4152fa2d37e842d65..6c842caef88abe089d656a351e7f30c0b03c8529 100644 (file)
@@ -175,6 +175,7 @@ private:
   CompositeFeaturePtr mySketch; ///< Sketch is equivalent to workplane
   ConstraintConstraintMap myConstraints; ///< List of constraints
   std::set<SolverConstraintPtr> myTempConstraints; ///< List of temporary constraints
+  std::map<AttributePtr, SolverConstraintPtr> myParametricConstraints; ///< List of parametric constraints
   std::set<ConstraintPtr> myChangedConstraints; ///< List of just updated constraints
 
   StoragePtr myStorage; ///< Container for the set of SolveSpace constraints and their entities