]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Check the multi coincidence between different types of entities (issue #751)
authorazv <azv@opencascade.com>
Thu, 20 Aug 2015 08:07:52 +0000 (11:07 +0300)
committerazv <azv@opencascade.com>
Thu, 20 Aug 2015 12:25:56 +0000 (15:25 +0300)
src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp
src/SketchSolver/SketchSolver_ConstraintCoincidence.h
src/SketchSolver/SketchSolver_ConstraintFillet.cpp
src/SketchSolver/SketchSolver_ConstraintTangent.cpp
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Storage.cpp
src/SketchSolver/SketchSolver_Storage.h

index 0840c3714423d08c45d6a38435cb7d14d52bc8cd..0e6ee74906d94719567f80112fde232e40c9f8f8 100644 (file)
@@ -48,10 +48,6 @@ std::list<ConstraintPtr> SketchSolver_ConstraintCoincidence::constraints() const
 bool SketchSolver_ConstraintCoincidence::isCoincide(
     std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint) const
 {
-  // Multi-coincidence allowed for two points only
-  if (getType() != theConstraint->getType() || getType() != SLVS_C_POINTS_COINCIDENT)
-    return false;
-
   std::set<AttributePtr>::const_iterator anAttrIter = theConstraint->myCoincidentPoints.begin();
   for (; anAttrIter != theConstraint->myCoincidentPoints.end(); anAttrIter++)
     if (myCoincidentPoints.find(*anAttrIter) != myCoincidentPoints.end())
@@ -112,6 +108,9 @@ void SketchSolver_ConstraintCoincidence::attach(
 Slvs_hConstraint SketchSolver_ConstraintCoincidence::addConstraint(
     Slvs_hEntity thePoint1, Slvs_hEntity thePoint2)
 {
+  if (thePoint1 == thePoint2)
+    return SLVS_E_UNKNOWN;
+
   bool hasDuplicated = myStorage->hasDuplicatedConstraint();
   Slvs_Constraint aNewConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
       SLVS_C_POINTS_COINCIDENT, myGroup->getWorkplaneId(), 0.0, thePoint1, thePoint2, 
@@ -126,34 +125,96 @@ Slvs_hConstraint SketchSolver_ConstraintCoincidence::addConstraint(
   return aNewID;
 }
 
+Slvs_hConstraint SketchSolver_ConstraintCoincidence::addPointOnEntity(
+    Slvs_hEntity thePoint, Slvs_hEntity theEntity)
+{
+  // Check the point is not coincident with boundaries of the entity
+  Slvs_Entity anEnt = myStorage->getEntity(theEntity);
+  int aPos = anEnt.type == SLVS_E_LINE_SEGMENT ? 0 : 1;
+  for (; anEnt.point[aPos] != SLVS_E_UNKNOWN; aPos++)
+    if (anEnt.point[aPos] == thePoint ||
+        myStorage->isCoincident(anEnt.point[aPos], thePoint))
+      return SLVS_E_UNKNOWN;
+
+  bool hasDuplicated = myStorage->hasDuplicatedConstraint();
+  Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
+  Slvs_hConstraint aType = anEnt.type == SLVS_E_LINE_SEGMENT ?
+      SLVS_C_PT_ON_LINE : SLVS_C_PT_ON_CIRCLE;
+  Slvs_Constraint aNewConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
+      aType, myGroup->getWorkplaneId(), 0.0, aBaseCoincidence.ptA, SLVS_E_UNKNOWN,
+      theEntity, SLVS_E_UNKNOWN);
+  Slvs_hConstraint aNewID = myStorage->addConstraint(aNewConstraint);
+  if (!hasDuplicated && myStorage->hasDuplicatedConstraint()) {
+    // the duplicated constraint appears
+    myStorage->removeConstraint(aNewID);
+    return SLVS_E_UNKNOWN;
+  }
+  mySlvsConstraints.push_back(aNewID);
+  return aNewID;
+}
+
 void SketchSolver_ConstraintCoincidence::addConstraint(ConstraintPtr theConstraint)
 {
+  if (mySlvsConstraints.empty()) {
+    // This constraint is empty, rebuild it from scratch
+    myBaseConstraint = theConstraint;
+    process();
+    return;
+  }
+
   std::list<AttributePtr> anAttrList =
       theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
   std::list<AttributePtr>::iterator anIter = anAttrList.begin();
-  std::vector<Slvs_hEntity> anEntities;
+  std::vector<Slvs_hEntity> aPoints;
+  Slvs_hEntity anEntity = SLVS_E_UNKNOWN;
+  int anEntType;
   for (; anIter != anAttrList.end(); anIter++) {
     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
-    if (!aRefAttr || aRefAttr->isObject() ||
-        myAttributeMap.find(aRefAttr->attr()) != myAttributeMap.end())
+    if (!aRefAttr)
       continue;
-    int aType;
-    Slvs_hEntity anEntityID = myGroup->getAttributeId(aRefAttr->attr());
-    if (anEntityID == SLVS_E_UNKNOWN)
-      anEntityID = changeEntity(aRefAttr->attr(), aType);
-    anEntities.push_back(anEntityID);
-    myCoincidentPoints.insert(aRefAttr->attr());
+    if (aRefAttr->isObject()) {
+      FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+      std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFeatFound = 
+          myFeatureMap.find(aFeature);
+      if (aFeatFound != myFeatureMap.end())
+        anEntity = aFeatFound->second;
+      else {
+        anEntity = myGroup->getFeatureId(aFeature);
+        if (anEntity == SLVS_E_UNKNOWN)
+          anEntity = changeEntity(aFeature, anEntType);
+        else
+          myFeatureMap[aFeature] = anEntity;
+      }
+    } else {
+      Slvs_hEntity anEntID = SLVS_E_UNKNOWN;
+      std::map<AttributePtr, Slvs_hEntity>::const_iterator anAttrFound =
+          myAttributeMap.find(aRefAttr->attr());
+      if (anAttrFound != myAttributeMap.end())
+        anEntID = anAttrFound->second;
+      else {
+        anEntID = myGroup->getAttributeId(aRefAttr->attr());
+        if (anEntID == SLVS_E_UNKNOWN)
+          anEntID = changeEntity(aRefAttr->attr(), anEntType);
+        else
+          myAttributeMap[aRefAttr->attr()] = anEntID;
+      }
+      aPoints.push_back(anEntID);
+      myCoincidentPoints.insert(aRefAttr->attr());
+    }
   }
 
   Slvs_hConstraint aNewConstr = SLVS_E_UNKNOWN;
-  std::vector<Slvs_hEntity>::iterator anEntIter = anEntities.begin();
-  if (mySlvsConstraints.empty()) {
-    aNewConstr = addConstraint(*anEntIter, *(anEntIter + 1));
-    anEntIter += 2;
+  if (anEntity != SLVS_E_UNKNOWN)
+    aNewConstr = addPointOnEntity(aPoints.front(), anEntity);
+  else { // coincidence between two points
+    Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
+    std::vector<Slvs_hEntity>::const_iterator aPtIter = aPoints.begin();
+    for (; aPtIter != aPoints.end(); aPtIter++) {
+      Slvs_hConstraint aC = addConstraint(aBaseCoincidence.ptA, *aPtIter);
+      if (aC != SLVS_E_UNKNOWN)
+        aNewConstr = aC;
+    }
   }
-  Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
-  for (; anEntIter != anEntities.end(); anEntIter++)
-    aNewConstr = addConstraint(aBaseCoincidence.ptA, *anEntIter);
   myExtraCoincidence[theConstraint] = aNewConstr;
 }
 
index 43354e80d4e7c907d7bafeaf74695cf8ebed297c..47d58e0e23299282a208d848f156ce28faf4b603 100644 (file)
@@ -58,6 +58,9 @@ private:
   /// \brief Create full SolveSpace structure according to given constraint
   void addConstraint(ConstraintPtr theConstraint);
 
+  /// \brief Create constraint of point concident to the line or circle
+  Slvs_hConstraint addPointOnEntity(Slvs_hEntity thePoint, Slvs_hEntity theEntity);
+
 private:
   int myType; ///< type of constraint (applicable SLVS_C_POINTS_COINCIDENT or SLVS_C_PT_ON_LINE or SLVS_C_PT_ON_CIRCLE)
   std::map<ConstraintPtr, Slvs_hConstraint> myExtraCoincidence; ///< multiple coincidence of points
index a8b9bcf372dfb2525fdf73ac545f76af4790b920..3d53b9010b39706ccf6791967d9f2c4521d0bb71 100644 (file)
@@ -104,7 +104,7 @@ void SketchSolver_ConstraintFillet::process()
   bool isPointFound = false;
   for (int i = 0; i < 2 && !isPointFound; i++)
     for (int j = 2; j < 4 && !isPointFound; j++)
-      if (myStorage->isCoincident(aPointsToFind[i], aPointsToFind[j])) {
+      if (myStorage->isEqual(aPointsToFind[i], aPointsToFind[j])) {
         aCoincInd[0] = i;
         aCoincInd[1] = j - 2;
         isPointFound = true;
index 37b59fab2b61808d8e48756d107d95e6ed857f90..865065411596d9e96ec503398675a63f43cf78a3 100644 (file)
@@ -61,7 +61,7 @@ void SketchSolver_ConstraintTangent::process()
   bool isPointFound = false;
   for (int i = 0; i < 2 && !isPointFound; i++)
     for (int j = 2; j < 4 && !isPointFound; j++)
-      if (myStorage->isCoincident(aPointsToFind[i], aPointsToFind[j])) {
+      if (myStorage->isEqual(aPointsToFind[i], aPointsToFind[j])) {
         aSlvsOtherFlag = i;
         aSlvsOther2Flag = j - 2;
         isPointFound = true;
index f77a22f331f34667ffe068a75fddc14116da07ca..dbe952f614cbe34bc0af9df929fdf3fbf96eeb02 100644 (file)
@@ -209,6 +209,11 @@ bool SketchSolver_Group::changeConstraint(
           std::dynamic_pointer_cast<SketchSolver_ConstraintCoincidence>(aConstraint);
         if (aCoincidence != aCoinc2 && aCoincidence->isCoincide(aCoinc2)) {
           aCoinc2->attach(aCoincidence);
+          // update other coincidences
+          ConstraintConstraintMap::iterator anIt = aCIter;
+          for (++anIt; anIt != myConstraints.end(); ++anIt)
+            if (anIt->second == aCIter->second)
+              anIt->second = aCoinc2;
           aCIter->second = aCoinc2;
         }
       }
index 793d6d42d43f14ad736e1fc2f92b061fe203858e..30d3f57905551faa703ae689f382d382172cec61 100644 (file)
@@ -738,7 +738,16 @@ bool SketchSolver_Storage::isCoincident(
   for (; aCIter != myCoincidentPoints.end(); aCIter++)
     if (aCIter->find(thePoint1) != aCIter->end() && aCIter->find(thePoint2) != aCIter->end())
       return true;
-  // precise checking of coincidence
+  return false;
+}
+
+bool SketchSolver_Storage::isEqual(
+    const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) const
+{
+  if (isCoincident(thePoint1, thePoint2))
+    return true;
+
+  // Precise checking of coincidence: verify that points have equal coordinates
   int aEnt1Pos = Search(thePoint1, myEntities);
   int aEnt2Pos = Search(thePoint2, myEntities);
   if (aEnt1Pos >= 0 && aEnt1Pos < (int)myEntities.size() &&
index 346440996d75dec830f6e4d6c0a3dc59e932de8a..2d1e1cd12f3ee0c74bf0e8d0e4eb7d870c55392c 100644 (file)
@@ -150,6 +150,9 @@ public:
   /// \brief Check two points are coincident
   bool isCoincident(const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) const;
 
+  /// \brief Check two points are coincident or have same coordinates
+  bool isEqual(const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) const;
+
   /// \brief Check the entity is horizontal of vertical
   bool isAxisParallel(const Slvs_hEntity& theEntity) const;