]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Implemented processing of Mirror constraint by sketch solver
authorazv <azv@opencascade.com>
Wed, 18 Mar 2015 07:36:20 +0000 (10:36 +0300)
committerazv <azv@opencascade.com>
Wed, 18 Mar 2015 12:01:34 +0000 (15:01 +0300)
Test case added

src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
src/SketchPlugin/Test/TestConstraintMirror.py
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.h

index b8e644cc62c1fe9d702c8e6a3f87c57f44ac3b52..1a70246b266ce1014a02ee877d7fead52264952d 100644 (file)
@@ -103,5 +103,6 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestConstraintVertical.py
                TestConstraintEqual.py
                TestConstraintTangent.py
+               TestConstraintMirror.py
                TestHighload.py
                TestSnowflake.py)
index 633eed69e0f53b986a6e4f36c74faac864033c1d..8479e107da7c3563772defdd61145c6b9c977d3b 100644 (file)
@@ -64,7 +64,8 @@ void SketchPlugin_ConstraintMirror::execute()
       if (aMirrorIter != aMirroredList.end())
         break; // the lists are inconsistent
       // There is no mirrored object yet, create it
-      FeaturePtr aNewFeature = aFeatureIn->document()->addFeature(aFeatureIn->getKind());
+      FeaturePtr aNewFeature = sketch()->addFeature(aFeatureIn->getKind());
+      aFeatureIn->data()->copyTo(aNewFeature->data());
       aRefListOfMirrored->append(aNewFeature);
       continue;
     }
index de1c0870e0a1596151c28c6ef768dce3c5b00538..3c3c2d05288fa382ca68257de98e8e577695d0bf 100644 (file)
@@ -122,5 +122,37 @@ aRefListB.append(aSketchLine2)
 aMirror.execute()
 aSession.finishOperation()
 #=========================================================================
+# Verify the simmetricity of all mirrored objects
+#=========================================================================
+aRefListC = aMirror.reflist("ConstraintEntityC")
+aListSize = aRefListB.size()
+aLineDirX = aLineEndPoint.x() - aLineStartPoint.x()
+aLineDirY = aLineEndPoint.y() - aLineStartPoint.y()
+
+for ind in range(0, aListSize):
+  aFeatureB = modelAPI_Feature(aRefListB.object(ind))
+  aFeatureC = modelAPI_Feature(aRefListC.object(ind))
+  assert(aFeatureB is not None)
+  assert(aFeatureC is not None)
+  assert(aFeatureB.getKind() == aFeatureC.getKind())
+  anAttributes = {}
+  print aFeatureB.getKind()
+  if (aFeatureB.getKind() == "SketchLine"):
+    anAttributes = {'StartPoint':'StartPoint', 'EndPoint':'EndPoint'}
+  elif (aFeatureB.getKind() == "SketchArc"):
+    anAttributes = {'ArcCenter':'ArcCenter', 'ArcStartPoint':'ArcEndPoint', 'ArcEndPoint':'ArcStartPoint'}
+
+  for key in anAttributes:
+    aPointB = geomDataAPI_Point2D(aFeatureB.attribute(key))
+    aPointC = geomDataAPI_Point2D(aFeatureC.attribute(anAttributes[key]))
+    aDirX = aPointC.x() - aPointB.x()
+    aDirY = aPointC.y() - aPointB.y()
+    aDot = aLineDirX * aDirX + aLineDirY * aDirY
+    assert(math.fabs(aDot) < 1.e-10)
+    aDirX = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x())
+    aDirY = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y())
+    aCross = aLineDirX * aDirY - aLineDirY * aDirX
+    assert(math.fabs(aCross) < 1.e-10)
+#=========================================================================
 # End of test
 #=========================================================================
index e4af2a0643970b1518b35cd344566ccaffdce20a..aed82cec5b1f2c16143eae40c737440f37c9322c 100644 (file)
@@ -16,6 +16,7 @@
 #include <SketchPlugin_ConstraintEqual.h>
 #include <SketchPlugin_ConstraintHorizontal.h>
 #include <SketchPlugin_ConstraintLength.h>
+#include <SketchPlugin_ConstraintMirror.h>
 #include <SketchPlugin_ConstraintParallel.h>
 #include <SketchPlugin_ConstraintPerpendicular.h>
 #include <SketchPlugin_ConstraintRadius.h>
@@ -24,6 +25,7 @@
 #include <SketchPlugin_ConstraintVertical.h>
 
 #include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Object.h>
@@ -217,8 +219,7 @@ const int& SketchSolver_Constraint::getType(
     return getType();
   }
 
-  if (aConstraintKind.compare(SketchPlugin_ConstraintEqual::ID()) == 0)
-  {
+  if (aConstraintKind.compare(SketchPlugin_ConstraintEqual::ID()) == 0) {
     static const int aConstrType[3] = {
         SLVS_C_EQUAL_RADIUS,
         SLVS_C_EQUAL_LINE_ARC_LEN,
@@ -242,8 +243,7 @@ const int& SketchSolver_Constraint::getType(
     return getType();
   }
 
-  if (aConstraintKind.compare(SketchPlugin_ConstraintTangent::ID()) == 0)
-  {
+  if (aConstraintKind.compare(SketchPlugin_ConstraintTangent::ID()) == 0) {
     static const int anArcPosDefault = 2;
     static const int aLinePosDefault = 3;
     int anArcPos = anArcPosDefault; // arc in tangency constraint should be placed before line
@@ -262,6 +262,30 @@ const int& SketchSolver_Constraint::getType(
     return getType();
   }
 
+  if (aConstraintKind.compare(SketchPlugin_ConstraintMirror::ID()) == 0) {
+    int aNbAttrs = 0;
+    bool hasMirrorLine = false;
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
+      AttributeRefListPtr anAttrRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)));
+      if (anAttrRefList) {
+        aNbAttrs++;
+        myAttributesList[aNbAttrs] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+      }
+      else {
+        std::shared_ptr<ModelAPI_Attribute> anAttr = 
+            aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+        if (typeOfAttribute(anAttr) == LINE) {
+          hasMirrorLine = !hasMirrorLine;
+          myAttributesList[0] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+        }
+      }
+    }
+    if (aNbAttrs == 2 && hasMirrorLine)
+      myType = SLVS_C_SYMMETRIC_LINE;
+    return getType();
+  }
+
   /// \todo Implement other kind of constraints
 
   return getType();
index 61299f8a7c0bf55ec19a89dace873b947f581a5a..9a0f29050970ef9b62a59bdefc8370336cf5bac6 100644 (file)
@@ -24,6 +24,7 @@
 #include <SketchPlugin_Constraint.h>
 #include <SketchPlugin_ConstraintLength.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_ConstraintMirror.h>
 #include <SketchPlugin_ConstraintRigid.h>
 
 #include <SketchPlugin_Arc.h>
@@ -155,7 +156,19 @@ bool SketchSolver_ConstraintGroup::isInteract(
   std::list<std::shared_ptr<ModelAPI_Attribute>>::const_iterator
       anAttrIter = anAttrList.begin();
   for ( ; anAttrIter != anAttrList.end(); anAttrIter++) {
-    std::shared_ptr<ModelAPI_AttributeRefAttr> aCAttrRef =
+    AttributeRefListPtr aCAttrRefList = 
+        std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anAttrIter);
+    if (aCAttrRefList) {
+      std::list<ObjectPtr> anObjList = aCAttrRefList->list();
+      std::list<ObjectPtr>::iterator anIt = anObjList.begin();
+      for ( ; anIt != anObjList.end(); anIt++) {
+        FeaturePtr aFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
+        if (aFeature && myEntityFeatMap.find(aFeature) != myEntityFeatMap.end())
+          return true;
+      }
+      continue;
+    }
+    AttributeRefAttrPtr aCAttrRef =
         std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIter);
     if (!aCAttrRef || !aCAttrRef->isObject()) {
       std::shared_ptr<ModelAPI_Attribute> anAttr = 
@@ -232,8 +245,12 @@ bool SketchSolver_ConstraintGroup::changeConstraint(
   if (myWorkplane.h == SLVS_E_UNKNOWN)
     return false;
 
-  if (theConstraint && theConstraint->getKind() == SketchPlugin_ConstraintRigid::ID())
-    return changeRigidConstraint(theConstraint);
+  if (theConstraint) {
+    if (theConstraint->getKind() == SketchPlugin_ConstraintRigid::ID())
+      return changeRigidConstraint(theConstraint);
+    if (theConstraint->getKind() == SketchPlugin_ConstraintMirror::ID())
+      return changeMirrorConstraint(theConstraint);
+  }
 
   // Search this constraint in the current group to update it
   ConstraintMap::const_iterator aConstrMapIter = myConstraintMap.find(theConstraint);
@@ -582,6 +599,140 @@ bool SketchSolver_ConstraintGroup::changeRigidConstraint(
   return true;
 }
 
+// ============================================================================
+//  Function: changeMirrorConstraint
+//  Class:    SketchSolver_ConstraintGroup
+//  Purpose:  create/update the "Mirror" constraint in the group
+// ============================================================================
+bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
+    std::shared_ptr<SketchPlugin_Constraint> theConstraint)
+{
+  DataPtr aConstrData = theConstraint->data();
+
+  // Search this constraint in the current group to update it
+  ConstraintMap::const_iterator aConstrMapIter = myConstraintMap.find(theConstraint);
+  std::vector<Slvs_Constraint>::iterator aConstrIter;
+  if (aConstrMapIter != myConstraintMap.end()) {
+    int aConstrPos = Search(aConstrMapIter->second.front(), myConstraints);
+    aConstrIter = myConstraints.begin() + aConstrPos;
+  }
+
+  // Get constraint type and verify the constraint parameters are correct
+  SketchSolver_Constraint aConstraint(theConstraint);
+  int aConstrType = aConstraint.getType();
+  if (aConstrType == SLVS_C_UNKNOWN
+      || (aConstrMapIter != myConstraintMap.end() && aConstrIter->type != aConstrType))
+    return false;
+  const std::vector<std::string>& aConstraintAttributes = aConstraint.getAttributes();
+
+  Slvs_hEntity aMirrorLineEnt = SLVS_E_UNKNOWN;
+  AttributeRefAttrPtr aConstrAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+      aConstrData->attribute(aConstraintAttributes[0]));
+  if (!aConstrAttr)
+    return false;
+
+  // Convert the object of the attribute to the feature
+  FeaturePtr aMirrorLineFeat;
+  if (aConstrAttr->isObject() && aConstrAttr->object()) {
+    ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
+        aConstrAttr->object());
+    if (!aRC)
+      return false;
+    std::shared_ptr<ModelAPI_Document> aDoc = aRC->document();
+    aMirrorLineFeat = aDoc->feature(aRC);
+  }
+  aMirrorLineEnt = aConstrAttr->isObject() ?
+      changeEntityFeature(aMirrorLineFeat) : changeEntity(aConstrAttr->attr());
+
+  if (aConstrMapIter == myConstraintMap.end()) { // Add new constraint
+    // Append symmetric constraint for each point of mirroring features
+    AttributeRefListPtr aBaseRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+        aConstrData->attribute(aConstraintAttributes[1]));
+    AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+        aConstrData->attribute(aConstraintAttributes[2]));
+    if (!aBaseRefList || !aMirroredRefList)
+      return false;
+
+    std::list<ObjectPtr> aBaseList = aBaseRefList->list();
+    std::list<ObjectPtr> aMirroredList = aMirroredRefList->list();
+    if (aBaseList.size() != aMirroredList.size())
+      return false;
+
+    myConstraintMap[theConstraint] = std::vector<Slvs_hEntity>();
+
+    FeaturePtr aBaseFeature, aMirrorFeature;
+    ResultConstructionPtr aRC;
+    std::list<ObjectPtr>::iterator aBaseIter = aBaseList.begin();
+    std::list<ObjectPtr>::iterator aMirIter = aMirroredList.begin();
+    for ( ; aBaseIter != aBaseList.end(); aBaseIter++, aMirIter++) {
+      aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aBaseIter);
+      aBaseFeature = aRC ? aRC->document()->feature(aRC) :
+          std::dynamic_pointer_cast<SketchPlugin_Feature>(*aBaseIter);
+      aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aMirIter);
+      aMirrorFeature = aRC ? aRC->document()->feature(aRC) :
+          std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirIter);
+
+      if (!aBaseFeature || !aMirrorFeature || 
+          aBaseFeature->getKind() != aMirrorFeature->getKind())
+        return false;
+      Slvs_hEntity aBaseEnt = changeEntityFeature(aBaseFeature);
+      Slvs_hEntity aMirrorEnt = changeEntityFeature(aMirrorFeature);
+
+      if (aBaseFeature->getKind() == SketchPlugin_Point::ID()) {
+        Slvs_Constraint aConstraint = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType,
+            myWorkplane.h, 0.0, aBaseEnt, aMirrorEnt, aMirrorLineEnt, SLVS_E_UNKNOWN);
+        myConstraints.push_back(aConstraint);
+        myConstraintMap[theConstraint].push_back(aConstraint.h);
+      } else {
+        int aBasePos = Search(aBaseEnt, myEntities);
+        int aMirrorPos = Search(aMirrorEnt, myEntities);
+        if (aBaseFeature->getKind() == SketchPlugin_Line::ID()) {
+          for (int ind = 0; ind < 2; ind++) {
+            Slvs_Constraint aConstraint = Slvs_MakeConstraint(
+                ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
+                myEntities[aBasePos].point[ind], myEntities[aMirrorPos].point[ind],
+                aMirrorLineEnt, SLVS_E_UNKNOWN);
+            myConstraints.push_back(aConstraint);
+            myConstraintMap[theConstraint].push_back(aConstraint.h);
+          }
+        } else if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) {
+          Slvs_Constraint aConstraint = Slvs_MakeConstraint(
+              ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
+              myEntities[aBasePos].point[0], myEntities[aMirrorPos].point[0],
+              aMirrorLineEnt, SLVS_E_UNKNOWN);
+          myConstraints.push_back(aConstraint);
+          myConstraintMap[theConstraint].push_back(aConstraint.h);
+          // Additional constraint for equal radii
+          Slvs_Constraint anEqRadConstr = Slvs_MakeConstraint(
+              ++myConstrMaxID, myID, SLVS_C_EQUAL_RADIUS, myWorkplane.h, 0.0,
+              SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aBaseEnt, aMirrorEnt);
+          myConstraints.push_back(anEqRadConstr);
+          myConstraintMap[theConstraint].push_back(anEqRadConstr.h);
+        } else if (aBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
+          int aBaseArcInd[3] = {0, 1, 2}; // indices of points of arc, center corresponds center, first point corresponds last point
+          int aMirrorArcInd[3] = {0, 2, 1};
+          for (int ind = 0; ind < 2; ind++) {
+            Slvs_Constraint aConstraint = Slvs_MakeConstraint(
+                ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
+                myEntities[aBasePos].point[aBaseArcInd[ind]], myEntities[aMirrorPos].point[aMirrorArcInd[ind]],
+                aMirrorLineEnt, SLVS_E_UNKNOWN);
+            myConstraints.push_back(aConstraint);
+            myConstraintMap[theConstraint].push_back(aConstraint.h);
+          }
+        }
+      }
+    }
+  }
+
+  // Set the mirror line unchanged during constraint recalculation
+  if (aConstrAttr->isObject()) {
+    addTemporaryConstraintWhereDragged(aMirrorLineFeat->attribute(SketchPlugin_Line::START_ID()));
+    addTemporaryConstraintWhereDragged(aMirrorLineFeat->attribute(SketchPlugin_Line::END_ID()));
+  }
+  else addTemporaryConstraintWhereDragged(aConstrAttr->attr());
+  return true;
+}
+
 // ============================================================================
 //  Function: changeEntity
 //  Class:    SketchSolver_ConstraintGroup
index 36583e3381362b75fa054cc3983a0e39c33d3678..5816eee75f4b93dfea4abc9ce43dacc0647b178c 100644 (file)
@@ -67,6 +67,11 @@ class SketchSolver_ConstraintGroup
    *  \return \c true if the constraint added or updated successfully
    */
   bool changeRigidConstraint(std::shared_ptr<SketchPlugin_Constraint> theConstraint);
+  /** \brief Adds or updates a mirror constraint in the group
+   *  \param[in] theConstraint constraint to be changed
+   *  \return \c true if the constraint added or updated successfully
+   */
+  bool changeMirrorConstraint(std::shared_ptr<SketchPlugin_Constraint> theConstraint);
 
   /** \brief Verifies the feature attributes are used in this group
    *  \param[in] theFeature constraint or any other object for verification of interaction