Salome HOME
Adjust processing of multi coincidences azv/SketchSolver_Refactoring
authorazv <azv@opencascade.com>
Tue, 7 Mar 2017 15:12:37 +0000 (18:12 +0300)
committerazv <azv@opencascade.com>
Tue, 7 Mar 2017 15:12:37 +0000 (18:12 +0300)
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.h
test.models/gear.py

index 1ac316855a6df221b2c2ed07e6bd43ce4cb27e94..ccd7d067504df7dda9f38e10fa8193c9f5198d9b 100644 (file)
@@ -55,14 +55,14 @@ bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence(
 {
   bool isAccepted = true;
 
-  std::list<std::set<EntityWrapperPtr> >::iterator anIt = myCoincident.begin();
-  std::list<std::set<EntityWrapperPtr> >::iterator
+  std::list<CoincidentEntities>::iterator anIt = myCoincident.begin();
+  std::list<CoincidentEntities>::iterator
       aFound[2] = {myCoincident.end(), myCoincident.end()};
 
   for (; anIt != myCoincident.end(); ++anIt) {
-    if (aFound[0] == myCoincident.end() && anIt->find(theEntity1) != anIt->end())
+    if (anIt->isExist(theEntity1))
       aFound[0] = anIt;
-    if (aFound[1] == myCoincident.end() && anIt->find(theEntity2) != anIt->end())
+    if (anIt->isExist(theEntity2))
       aFound[1] = anIt;
     if (aFound[0] != myCoincident.end() && aFound[1] != myCoincident.end())
       break;
@@ -70,37 +70,136 @@ bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence(
 
   if (aFound[0] == myCoincident.end() && aFound[1] == myCoincident.end()) {
     // new group of coincidence
-    std::set<EntityWrapperPtr> aNewCoinc;
-    aNewCoinc.insert(theEntity1);
-    aNewCoinc.insert(theEntity2);
-    myCoincident.push_back(aNewCoinc);
+    myCoincident.push_back(CoincidentEntities(theEntity1, theEntity2));
   } else if (aFound[0] == aFound[1]) // same group => already coincident
     isAccepted = false;
   else {
-    if (theEntity1->type() == ENTITY_POINT && theEntity2->type() == ENTITY_POINT &&
-       (theEntity1->isExternal() || theEntity2->isExternal())) {
-      bool hasExternal = false;
-      for (int i = 0; i < 2 && !hasExternal; ++i) {
-        if (aFound[i] != myCoincident.end()) {
-          if (theEntity1->isExternal())
-            hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity1);
-          if (!hasExternal && theEntity2->isExternal())
-            hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity2);
-        }
-      }
-      if (hasExternal)
-        isAccepted = false;
-    }
-
     if (aFound[0] == myCoincident.end())
-      aFound[1]->insert(theEntity1);
+      isAccepted = aFound[1]->isNewCoincidence(theEntity2, theEntity1);
     else if (aFound[1] == myCoincident.end())
-      aFound[0]->insert(theEntity2);
+      isAccepted = aFound[0]->isNewCoincidence(theEntity1, theEntity2);
     else { // merge two groups
-      aFound[0]->insert(aFound[1]->begin(), aFound[1]->end());
+      isAccepted = aFound[0]->isNewCoincidence(theEntity1, *(aFound[1]), theEntity2);
       myCoincident.erase(aFound[1]);
     }
   }
 
   return isAccepted;
 }
+
+
+
+
+PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::CoincidentEntities(
+    const EntityWrapperPtr& theEntity1,
+    const EntityWrapperPtr& theEntity2)
+{
+  if (theEntity1->isExternal() && theEntity2->isExternal()) {
+    myExternalAndConnected[theEntity1] = std::set<EntityWrapperPtr>();
+    myExternalAndConnected[theEntity2] = std::set<EntityWrapperPtr>();
+  } else if (theEntity1->isExternal())
+    myExternalAndConnected[theEntity1].insert(theEntity2);
+  else if (theEntity2->isExternal())
+    myExternalAndConnected[theEntity2].insert(theEntity1);
+  else {
+    std::set<EntityWrapperPtr> aGroup;
+    aGroup.insert(theEntity1);
+    aGroup.insert(theEntity2);
+    myExternalAndConnected[EntityWrapperPtr()] = aGroup;
+  }
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::hasExternal() const
+{
+  return myExternalAndConnected.size() != 1 ||
+         myExternalAndConnected.find(EntityWrapperPtr()) == myExternalAndConnected.end();
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isExist(
+    const EntityWrapperPtr& theEntity) const
+{
+  std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::const_iterator
+      anIt = myExternalAndConnected.begin();
+  for (; anIt != myExternalAndConnected.end(); ++anIt)
+    if (anIt->first == theEntity ||
+        anIt->second.find(theEntity) != anIt->second.end())
+      return true;
+  return false;
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isNewCoincidence(
+    const EntityWrapperPtr& theEntityExist,
+    const EntityWrapperPtr& theOtherEntity)
+{
+  if (theOtherEntity->isExternal()) {
+    if (hasExternal()) {
+      if (myExternalAndConnected.find(theOtherEntity) == myExternalAndConnected.end())
+        myExternalAndConnected[theOtherEntity] = std::set<EntityWrapperPtr>();
+      return false;
+    } else {
+      myExternalAndConnected[theOtherEntity] = myExternalAndConnected[EntityWrapperPtr()];
+      myExternalAndConnected.erase(EntityWrapperPtr());
+      return true;
+    }
+  }
+
+  if (theEntityExist->isExternal()) {
+    myExternalAndConnected[theEntityExist].insert(theOtherEntity);
+    return true;
+  }
+
+  std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::iterator
+      anIt = myExternalAndConnected.begin();
+  for (; anIt != myExternalAndConnected.end(); ++anIt)
+    if (anIt->second.find(theEntityExist) != anIt->second.end()) {
+      anIt->second.insert(theOtherEntity);
+      break;
+    }
+  return true;
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isNewCoincidence(
+    const EntityWrapperPtr&   theEntityExist,
+    const CoincidentEntities& theOtherGroup,
+    const EntityWrapperPtr&   theEntityInOtherGroup)
+{
+  bool hasExt[2] = {hasExternal(), theOtherGroup.hasExternal()};
+  if (hasExt[0] && hasExt[1]) {
+    myExternalAndConnected.insert(theOtherGroup.myExternalAndConnected.begin(),
+                                  theOtherGroup.myExternalAndConnected.end());
+    return false;
+  } else if (!hasExt[0] && !hasExt[1]) {
+    std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::const_iterator
+        aFound = theOtherGroup.myExternalAndConnected.find(EntityWrapperPtr());
+
+    myExternalAndConnected[EntityWrapperPtr()].insert(
+        aFound->second.begin(), aFound->second.end());
+    return true;
+  } else {
+    std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> > aSource, aDest;
+    EntityWrapperPtr aTarget;
+    if (hasExt[0]) {
+      aDest = myExternalAndConnected;
+      aSource = theOtherGroup.myExternalAndConnected;
+      aTarget = theEntityExist;
+    } else {
+      aSource = myExternalAndConnected;
+      aDest = theOtherGroup.myExternalAndConnected;
+      aTarget = theEntityInOtherGroup;
+    }
+
+    std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::const_iterator
+        aFound = aSource.find(EntityWrapperPtr());
+
+    std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::iterator anIt = aDest.begin();
+    for (; anIt != aDest.end(); ++anIt)
+      if (anIt->first == aTarget ||
+          anIt->second.find(aTarget) != anIt->second.end()) {
+        anIt->second.insert(aFound->second.begin(), aFound->second.end());
+        break;
+      }
+    return true;
+  }
+  // impossible case
+  return false;
+}
index 44f36c4653289d989b2bc9d5fe20cf1b096d6804..afd49a2a1201ca561d2713cd5b5fad9d93eb41a0 100644 (file)
@@ -10,6 +10,8 @@
 #include <PlaneGCSSolver_Update.h>
 #include <SketchSolver_IEntityWrapper.h>
 
+#include <map>
+
 /** \class   PlaneGCSSolver_UpdateCoincidence
  *  \ingroup Plugins
  *  \brief   Send events to listeners about changing a constraint
@@ -44,7 +46,31 @@ public:
   bool checkCoincidence(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2);
 
 private:
-  std::list<std::set<EntityWrapperPtr> > myCoincident; ///< list of coincidences
+  /// \brief Container for collecting and operating coincident entities
+  class CoincidentEntities
+  {
+  public:
+    CoincidentEntities(const EntityWrapperPtr& theEntity1,
+                       const EntityWrapperPtr& theEntity2);
+
+    /// Verify the entity is already in the list
+    bool isExist(const EntityWrapperPtr& theEntity) const;
+    /// Check the coincidence is not in list yet
+    bool isNewCoincidence(const EntityWrapperPtr& theEntityExist,
+                          const EntityWrapperPtr& theOtherEntity);
+    bool isNewCoincidence(const EntityWrapperPtr& theEntityExist,
+                          const CoincidentEntities& theOtherGroup,
+                          const EntityWrapperPtr& theEntityInOtherGroup);
+
+  private:
+    bool hasExternal() const;
+
+  private:
+    /// external entity and set of entities connected to it
+    std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> > myExternalAndConnected;
+  };
+
+  std::list<CoincidentEntities> myCoincident; ///< list of coincidences
 };
 
 #endif
index c08ffd7030bff0a6d1da9464f276c761a9380604..d5190da9a16bc929970ec068f292bec7b7cb1756 100644 (file)
@@ -43,22 +43,21 @@ SketchLine_9.setAuxiliary(True)
 SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchPoint_2.coordinates(), SketchLine_9.startPoint())
 SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_9.result())
 SketchLine_10 = Sketch_2.addLine(-2.5, 37.41657386773942, -0.9611800001338426, 34.11656372860793)
-SketchArc_1 = Sketch_2.addArc(0, 34.39248583236681, -0.9611800001338426, 34.11656372860793, 0.9611800001338454, 34.11656372860793, False)
+SketchArc_1 = Sketch_2.addArc(0, 34.39248583236681, -0.9611800001338426, 34.11656372860793, 0, 33.39248583236681, False)
 SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchArc_1.startPoint())
 SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchArc_1.center(), SketchLine_9.result())
-SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_9.result(), [SketchLine_10.result()])
-[SketchLine_11] = SketchConstraintMirror_1.mirrored()
-SketchConstraintAngle_1 = Sketch_2.setAngleBackward(SketchLine_10.result(), SketchLine_9.result(), 204.9999999999999)
+SketchConstraintAngle_1 = Sketch_2.setAngleBackward(SketchLine_10.result(), SketchLine_9.result(), 205)
 SketchConstraintRadius_1 = Sketch_2.setRadius(SketchArc_1.results()[1], 1)
 SketchConstraintDistance_2 = Sketch_2.setDistance(SketchLine_10.startPoint(), SketchLine_9.result(), 2.5)
-SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchAPI_Line(SketchLine_11).endPoint())
-SketchArc_2 = Sketch_2.addArc(0, 0, -2.5, 37.41657386773942, 2.5, 37.41657386773942, True)
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchArc_1.endPoint(), SketchLine_9.result())
+SketchArc_2 = Sketch_2.addArc(0, 0, -2.5, 37.41657386773942, 0, 37.5, True)
 SketchConstraintCoincidence_15 = Sketch_2.setCoincident(SketchArc_2.center(), SketchPoint_2.result())
 SketchConstraintCoincidence_16 = Sketch_2.setCoincident(SketchLine_10.startPoint(), SketchArc_2.startPoint())
-SketchConstraintCoincidence_17 = Sketch_2.setCoincident(SketchAPI_Line(SketchLine_11).startPoint(), SketchArc_2.endPoint())
-SketchMultiRotation_1_objects = [SketchArc_1.results()[1], SketchLine_10.result(), SketchArc_2.results()[1], SketchLine_11.result()]
+SketchConstraintCoincidence_17 = Sketch_2.setCoincident(SketchLine_9.result(), SketchArc_2.endPoint())
+SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_9.result(), [SketchLine_10.result(), SketchArc_1.results()[1], SketchArc_2.results()[1]])
+[SketchLine_11, SketchArc_3, SketchArc_4] = SketchConstraintMirror_1.mirrored()
+SketchMultiRotation_1_objects = [SketchArc_1.results()[1], SketchLine_10.result(), SketchArc_2.results()[1], SketchArc_3.results()[1], SketchLine_11.result(), SketchArc_4.results()[1]]
 SketchMultiRotation_1 = Sketch_2.addRotation(SketchMultiRotation_1_objects, SketchArc_2.center(), 12, 30)
-[SketchArc_3, SketchArc_4, SketchArc_5, SketchArc_6, SketchArc_7, SketchArc_8, SketchArc_9, SketchArc_10, SketchArc_11, SketchArc_12, SketchArc_13, SketchArc_14, SketchArc_15, SketchArc_16, SketchArc_17, SketchArc_18, SketchArc_19, SketchArc_20, SketchArc_21, SketchArc_22, SketchArc_23, SketchArc_24, SketchArc_25, SketchArc_26, SketchArc_27, SketchArc_28, SketchArc_29, SketchArc_30, SketchArc_31, SketchLine_12, SketchLine_13, SketchLine_14, SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18, SketchLine_19, SketchLine_20, SketchLine_21, SketchLine_22, SketchLine_23, SketchLine_24, SketchLine_25, SketchLine_26, SketchLine_27, SketchLine_28, SketchLine_29, SketchLine_30, SketchLine_31, SketchLine_32, SketchLine_33, SketchLine_34, SketchLine_35, SketchLine_36, SketchLine_37, SketchLine_38, SketchLine_39, SketchLine_40, SketchArc_32, SketchArc_33, SketchArc_34, SketchArc_35, SketchArc_36, SketchArc_37, SketchArc_38, SketchArc_39, SketchArc_40, SketchArc_41, SketchArc_42, SketchArc_43, SketchArc_44, SketchArc_45, SketchArc_46, SketchArc_47, SketchArc_48, SketchArc_49, SketchArc_50, SketchArc_51, SketchArc_52, SketchArc_53, SketchArc_54, SketchArc_55, SketchArc_56, SketchArc_57, SketchArc_58, SketchArc_59, SketchArc_60, SketchLine_11, SketchLine_41, SketchLine_42, SketchLine_43, SketchLine_44, SketchLine_45, SketchLine_46, SketchLine_47, SketchLine_48, SketchLine_49, SketchLine_50, SketchLine_51, SketchLine_52, SketchLine_53, SketchLine_54, SketchLine_55, SketchLine_56, SketchLine_57, SketchLine_58, SketchLine_59, SketchLine_60, SketchLine_61, SketchLine_62, SketchLine_63, SketchLine_64, SketchLine_65, SketchLine_66, SketchLine_67, SketchLine_68, SketchLine_69] = SketchMultiRotation_1.rotated()
 SketchConstraintRadius_2 = Sketch_2.setRadius(SketchArc_2.results()[1], 37.5)
 model.do()
 Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
@@ -179,9 +178,9 @@ from GeomAPI import GeomAPI_Shape
 model.testNbResults(RevolutionCut_1, 1)
 model.testNbSubResults(RevolutionCut_1, [0])
 model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.SOLID, [1])
-model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.FACE, [188])
-model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.EDGE, [1104])
-model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.VERTEX, [2208])
-model.testResultsVolumes(RevolutionCut_1, [65202.414301669727137777954339981])
+model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.FACE, [218])
+model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.EDGE, [1284])
+model.testNbSubShapes(RevolutionCut_1, GeomAPI_Shape.VERTEX, [2568])
+model.testResultsVolumes(RevolutionCut_1, [65202.414255050614883657544851303])
 
 assert(model.checkPythonDump())