]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Improved stability of Test2248 sketch faces order.
authormpv <mpv@opencascade.com>
Thu, 14 Sep 2017 11:22:30 +0000 (14:22 +0300)
committermpv <mpv@opencascade.com>
Thu, 14 Sep 2017 11:22:30 +0000 (14:22 +0300)
src/FeaturesPlugin/Test/Test2248.py
src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp

index 85ef22df96dfedcfa67f68c73fbc243f66ff26f0..89f15dd57e38564aa82aab891e05d74fbf80111b 100644 (file)
@@ -48,7 +48,7 @@ SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_3.result(), SketchArc
 SketchCircle_1 = Sketch_1.addCircle(-13.45056286489504, 169.4770920976776, 150.6703210346195)
 model.do()
 Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/Generated_Face_6"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_6"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_9"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/Generated_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/Generated_Face_8"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/Generated_Face_9"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_9"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_6"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/Generated_Face_9"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_7")])
 model.end()
 
 # check that resulting group selection is valid
index eca84e8a22695d6f98df02f0bc6cccee9b7a0c4c..c4bf9d6f38d37039a245433249aeb4b5a9997624 100644 (file)
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
 
 #include <list>
 #include <cmath>
-
+#include <algorithm>
 
 static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape)
 {
@@ -100,6 +102,92 @@ static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape,
   return findStartVertex(theShape);
 }
 
+// returns true if the first shape must be located earlier than the second
+bool isFirst(const TopoDS_Shape& theFirst, const TopoDS_Shape& theSecond,
+  NCollection_DataMap<TopoDS_Shape, NCollection_Array1<int> >& theAreaToIndex,
+  const NCollection_DataMap<Handle(Geom_Curve), int>& theCurveToIndex)
+{
+  // fill theAreaToIndex for both shapes if needed
+  for(int aShapeNum = 1; aShapeNum <= 2; aShapeNum++) {
+    TopoDS_Shape aShape = aShapeNum == 1 ? theFirst : theSecond;
+    if (!theAreaToIndex.IsBound(aShape)) { // fill the list of curve indices
+      NCollection_List<int> aNewList;
+      TopExp_Explorer anEdgesExp(aShape, TopAbs_EDGE);
+      for(; anEdgesExp.More(); anEdgesExp.Next()) {
+        double aFirst, aLast;
+        Handle(Geom_Curve) aCurve = BRep_Tool::Curve(
+          TopoDS::Edge(anEdgesExp.Current()), aFirst, aLast);
+        if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
+          aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+        if (theCurveToIndex.IsBound(aCurve)) {
+          aNewList.Append(theCurveToIndex.Find(aCurve));
+        }
+      }
+      NCollection_Array1<int> aNewArray(1, aNewList.Extent());
+      NCollection_List<int>::Iterator aListIter(aNewList);
+      for(int anIndex = 1; aListIter.More(); aListIter.Next(), anIndex++) {
+        aNewArray.SetValue(anIndex, aListIter.Value());
+      }
+      std::sort(aNewArray.begin(), aNewArray.end());
+      theAreaToIndex.Bind(aShape, aNewArray);
+    }
+  }
+  // compare lists of indices one by one to find chich list indices are lower
+  NCollection_Array1<int>::Iterator aFirstList(theAreaToIndex.ChangeFind(theFirst));
+  NCollection_Array1<int>::Iterator aSecondList(theAreaToIndex.ChangeFind(theSecond));
+  for(; aFirstList.More() && aSecondList.More(); aFirstList.Next(), aSecondList.Next()) {
+    if (aFirstList.Value() < aSecondList.Value()) return true;
+    if (aFirstList.Value() > aSecondList.Value()) return false;
+  }
+  // if faces are identical by curves names (circle splitted by line in seam-point), use parameters
+  if (!aFirstList.More() && !aSecondList.More()) {
+    GProp_GProps aGProps;
+    BRepGProp::SurfaceProperties(theFirst, aGProps);
+    gp_Pnt aCentre1 = aGProps.CentreOfMass();
+    BRepGProp::SurfaceProperties(theSecond, aGProps);
+    gp_Pnt aCentre2 = aGProps.CentreOfMass();
+    return aCentre1.X() + aCentre1.Y() + aCentre1.Z() < aCentre2.X() + aCentre2.Y() + aCentre2.Z();
+  }
+  // if in first list there is no elements left, it is the first
+  return !aFirstList.More();
+}
+
+// sorts faces (in theAreas list) to make persistent order: by initial shapes edges
+static void sortFaces(TopTools_ListOfShape& theAreas,
+  const std::list<std::shared_ptr<GeomAPI_Shape> >& theInitialShapes)
+{
+  // collect indices of all edges to operate them quickly
+  NCollection_DataMap<Handle(Geom_Curve), int> aCurveToIndex; // curve -> index in initial shapes
+  std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theInitialShapes.begin();
+  for (int anIndex = 0; aFeatIt != theInitialShapes.end(); aFeatIt++) {
+    std::shared_ptr<GeomAPI_Shape> aShape(*aFeatIt);
+    const TopoDS_Edge& anEdge = aShape->impl<TopoDS_Edge>();
+    if (anEdge.ShapeType() != TopAbs_EDGE)
+      continue;
+
+    double aFirst, aLast;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+    if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
+      aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+    if (!aCurveToIndex.IsBound(aCurve))
+      aCurveToIndex.Bind(aCurve, anIndex++);
+  }
+  // map from area to the most first indices of curves (to compare) in it
+  NCollection_DataMap<TopoDS_Shape, NCollection_Array1<int> > anAreaToIndex;
+  // sort areas
+  TopTools_ListOfShape::Iterator anArea1(theAreas);
+  for(; anArea1.More(); anArea1.Next()) {
+    TopTools_ListOfShape::Iterator anArea2 = anArea1;
+    for(anArea2.Next(); anArea2.More(); anArea2.Next()) {
+      if (!isFirst(anArea1.Value(), anArea2.Value(), anAreaToIndex, aCurveToIndex)) { // exchange
+        TopoDS_Shape aTmp = anArea1.Value();
+        anArea1.ChangeValue() = anArea2.Value();
+        anArea2.ChangeValue() = aTmp;
+      }
+    }
+  }
+}
+
 void GeomAlgoAPI_SketchBuilder::createFaces(
     const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
     const std::shared_ptr<GeomAPI_Dir>& theDirX,
@@ -134,7 +222,8 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
     return;
 
   // Collect faces
-  const TopTools_ListOfShape& anAreas = aBB.Modified(aPlnFace);
+  TopTools_ListOfShape anAreas = aBB.Modified(aPlnFace);
+  sortFaces(anAreas, theFeatures); // sort faces by the edges in them
   TopTools_ListIteratorOfListOfShape anIt(anAreas);
   for (; anIt.More(); anIt.Next()) {
     TopoDS_Face aFace = TopoDS::Face(anIt.Value());