]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #424: Avoid conflicting constraint message.
authorazv <azv@opencascade.com>
Fri, 3 Apr 2015 13:21:21 +0000 (16:21 +0300)
committerazv <azv@opencascade.com>
Fri, 3 Apr 2015 13:21:21 +0000 (16:21 +0300)
Implemented correction for moving the mirror

src/SketchSolver/SketchSolver_ConstraintMirror.cpp
src/SketchSolver/SketchSolver_ConstraintMirror.h
src/SketchSolver/SketchSolver_ConstraintRigid.cpp
src/SketchSolver/SketchSolver_Storage.cpp
src/SketchSolver/SketchSolver_Storage.h

index 6ea42d13ef6ef4d5c475443f36152f2851f2c9ad..f3ded1d30f1046113d0ef92ac879f94f63c959df 100644 (file)
@@ -137,8 +137,8 @@ void SketchSolver_ConstraintMirror::process()
           aBaseIter->point[2],
           SLVS_E_UNKNOWN};
       Slvs_hEntity aMirrorArcPoints[3] = { // indices of points of arc, center corresponds center, first point corresponds last point
-          aBaseIter->point[2],
-          aBaseIter->point[1],
+          aMirrorIter->point[2],
+          aMirrorIter->point[1],
           SLVS_E_UNKNOWN};
 
       Slvs_Entity aBothArcs[2] = {*aBaseIter, *aMirrorIter};
@@ -234,6 +234,10 @@ void SketchSolver_ConstraintMirror::makeMirrorEntity(
     aMirrorPoint[2] = aMirrorPoint[1];
     aMirrorPoint[1] = aTmp;
   }
+  if (theBase.type == SLVS_E_POINT_IN_2D || theBase.type == SLVS_E_POINT_IN_3D) {
+    aBasePoint[0] = theBase.h;
+    aMirrorPoint[0] = theMirror.h;
+  }
 
   // Mirror line parameters
   std::shared_ptr<GeomAPI_XY> aLinePoints[2];
@@ -267,3 +271,63 @@ void SketchSolver_ConstraintMirror::makeMirrorEntity(
   }
 }
 
+void SketchSolver_ConstraintMirror::adjustConstraint()
+{
+  // Search mirror between middle points on the arcs and recompute their coordinates
+  std::list<Slvs_Constraint> aPonCirc = myStorage->getConstraintsByType(SLVS_C_PT_ON_CIRCLE);
+  if (aPonCirc.empty())
+    return;
+
+  AttributeRefAttrPtr aMirLineAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+      myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+  if (!aMirLineAttr || !aMirLineAttr->isInitialized() || !aMirLineAttr->isObject()) {
+    myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
+    return;
+  }
+  ResultConstructionPtr aRC =
+      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aMirLineAttr->object());
+  FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
+    std::dynamic_pointer_cast<ModelAPI_Feature>(aMirLineAttr->object());
+  std::map<FeaturePtr, Slvs_hEntity>::iterator aMirLineIter = myFeatureMap.find(aFeature);
+  if (aMirLineIter == myFeatureMap.end())
+    return;
+  Slvs_Entity aMirrorLine = myStorage->getEntity(aMirLineIter->second);
+
+  double aStartEnd[4];
+  for (int i = 0; i < 2; i++) {
+    Slvs_Entity aPoint = myStorage->getEntity(aMirrorLine.point[i]);
+    for (int j = 0; j < 2; j++)
+      aStartEnd[2*i+j] = myStorage->getParameter(aPoint.param[j]).val;
+  }
+
+  Slvs_Constraint aMirror;
+  std::vector<Slvs_hConstraint>::iterator aConstrIter = mySlvsConstraints.begin();
+  for (; aConstrIter != mySlvsConstraints.end(); aConstrIter++) {
+    aMirror = myStorage->getConstraint(*aConstrIter);
+    if (aMirror.type != SLVS_C_SYMMETRIC_LINE)
+      continue;
+    Slvs_Constraint aPonCircA, aPonCircB;
+    aPonCircA.h = SLVS_E_UNKNOWN;
+    aPonCircB.h = SLVS_E_UNKNOWN;
+    std::list<Slvs_Constraint>::iterator aPtIter = aPonCirc.begin();
+    for (; aPtIter != aPonCirc.end(); aPtIter++) {
+      if (aMirror.ptA == aPtIter->ptA)
+        aPonCircA = *aPtIter;
+      if (aMirror.ptB == aPtIter->ptA)
+        aPonCircB = *aPtIter;
+    }
+    if (aPonCircA.h == SLVS_E_UNKNOWN || aPonCircB.h == SLVS_E_UNKNOWN)
+      continue;
+
+    // Calculate middle point for base arc and mirrored point on mirror arc
+    Slvs_Entity aBaseArc = myStorage->getEntity(aPonCircA.entityA);
+    Slvs_Entity aBasePoint = myStorage->getEntity(aPonCircA.ptA);
+    Slvs_Param aParamX = myStorage->getParameter(aBasePoint.param[0]);
+    Slvs_Param aParamY = myStorage->getParameter(aBasePoint.param[1]);
+    calculateMiddlePoint(aBaseArc, 0.5, aParamX.val, aParamY.val);
+    myStorage->updateParameter(aParamX);
+    myStorage->updateParameter(aParamY);
+    Slvs_Entity aMirrorPoint = myStorage->getEntity(aPonCircB.ptA);
+    makeMirrorEntity(aBasePoint, aMirrorPoint, aStartEnd);
+  }
+}
index 092e4dff658f1020b63f1c003ce75f8bae83176e..eb3af1fb34aeeba34cce6a084953c519f47896c0 100644 (file)
@@ -50,6 +50,10 @@ protected:
                      std::vector<Slvs_Entity>& theBaseEntities,
                      std::vector<Slvs_Entity>& theMirrorEntities);
 
+  /// \brief This method is used in derived objects to check consistence of constraint.
+  ///        E.g. the distance between line and point may be signed.
+  virtual void adjustConstraint();
+
 private:
   /// \brief Change parameters of entities to be symmetric relative a line,
   ///        given by array of parameters (coordinates of first and last points)
index 75cf0d0d0ec87f4f63e52dee18dcb9d9a086f2cf..a1deb96ccd44516b25004ebf166363b615ae6554 100644 (file)
@@ -113,6 +113,8 @@ void SketchSolver_ConstraintRigid::getAttributes(
     anEntityID = myGroup->getFeatureId(myBaseFeature);
     if (anEntityID == SLVS_E_UNKNOWN)
       anEntityID = changeEntity(myBaseFeature, aType);
+    else
+      myFeatureMap[myBaseFeature] = anEntityID;
   }
 
   // Check the entity is complex
@@ -223,11 +225,19 @@ void SketchSolver_ConstraintRigid::fixArc(const Slvs_Entity& theArc)
   }
 
   // Fix radius of the arc
-  aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, myGroup->getWorkplaneId(),
-    aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
-  aConstraint.h = myStorage->addConstraint(aConstraint);
-  mySlvsConstraints.push_back(aConstraint.h);
-  if (!myBaseConstraint)
-    myStorage->addTemporaryConstraint(aConstraint.h);
+  bool isExists = false;
+  std::list<Slvs_Constraint> aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
+  std::list<Slvs_Constraint>::iterator anIt = aDiamConstraints.begin();
+  for (; anIt != aDiamConstraints.end() && !isExists; anIt)
+    if (anIt->entityA == myFeatureMap.begin()->second)
+      isExists = true;
+  if (!isExists) {
+    aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, myGroup->getWorkplaneId(),
+      aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
+    aConstraint.h = myStorage->addConstraint(aConstraint);
+    mySlvsConstraints.push_back(aConstraint.h);
+    if (!myBaseConstraint)
+      myStorage->addTemporaryConstraint(aConstraint.h);
+  }
 }
 
index 9dbf54f0c6aa5bbdd166a615460cc2f63c9e201c..d4a5171322ad5701bd990264cbe94c8185c8c901 100644 (file)
@@ -226,6 +226,20 @@ Slvs_hConstraint SketchSolver_Storage::addConstraint(const Slvs_Constraint& theC
   }
 
   Slvs_Constraint aConstraint = theConstraint;
+
+  // Find a constraint with same type uses same arguments
+  std::vector<Slvs_Constraint>::iterator aCIt = myConstraints.begin();
+  for (; aCIt != myConstraints.end(); aCIt++) {
+    if (aConstraint.type != aCIt->type)
+      continue;
+    if (aConstraint.ptA == aCIt->ptA && aConstraint.ptB == aCIt->ptB &&
+        aConstraint.entityA == aCIt->entityA && aConstraint.entityB == aCIt->entityB &&
+        aConstraint.entityC == aCIt->entityC && aConstraint.entityD == aCIt->entityD) {
+      aConstraint.h = aCIt->h;
+      return updateConstraint(aConstraint);
+    }
+  }
+
   if (aConstraint.h > myConstrMaxID)
     myConstrMaxID = aConstraint.h;
   else
@@ -293,6 +307,17 @@ const Slvs_Constraint& SketchSolver_Storage::getConstraint(const Slvs_hConstrain
   return aDummy;
 }
 
+std::list<Slvs_Constraint> SketchSolver_Storage::getConstraintsByType(int theConstraintType) const
+{
+  std::list<Slvs_Constraint> aResult;
+  std::vector<Slvs_Constraint>::const_iterator aCIter = myConstraints.begin();
+  for (; aCIter != myConstraints.end(); aCIter++)
+    if (aCIter->type == theConstraintType)
+      aResult.push_back(*aCIter);
+  return aResult;
+}
+
+
 void SketchSolver_Storage::addTemporaryConstraint(const Slvs_hConstraint& theConstraintID)
 {
   if (myFixed != SLVS_E_UNKNOWN)
index 70f2622b15190c591fad9b9c7d45d1e23c2a7bd8..cf04f47ab4c89112e1f9117b2a9b3d23ed73b5e7 100644 (file)
@@ -10,6 +10,7 @@
 #include "SketchSolver.h"
 #include <SketchSolver_Solver.h>
 
+#include <list>
 #include <memory>
 #include <set>
 #include <vector>
@@ -83,6 +84,8 @@ public:
   bool removeConstraint(const Slvs_hConstraint& theConstraintID);
   /// \brief Returns the constraint by its ID
   const Slvs_Constraint& getConstraint(const Slvs_hConstraint& theConstraintID) const;
+  /// \brief Returns list of constraints of specified type
+  std::list<Slvs_Constraint> getConstraintsByType(int theConstraintType) const;
 
   /// \brief Attach temporary constraint to this storage. It need to make precise calculations
   void addTemporaryConstraint(const Slvs_hConstraint& theConstraintID);