]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Implement Arcs mode for offset in case of multiple output wires
authorjfa <jfa@opencascade.com>
Tue, 24 May 2022 19:28:45 +0000 (22:28 +0300)
committerjfa <jfa@opencascade.com>
Tue, 24 May 2022 19:28:45 +0000 (22:28 +0300)
src/GeomAlgoAPI/GeomAlgoAPI_Fillet1D.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Fillet1D.h
src/Model/Model_AttributeIntArray.cpp
src/SketchPlugin/SketchPlugin_Offset.cpp

index d1313e663b45e80fa61f19c0f2f08256d591f9a9..2dd7dbed0330e4a493141c6f07c848830e13e566 100644 (file)
 #include <GeomAlgoAPI_Copy.h>
 #include <GeomAlgoAPI_MapShapesAndAncestors.h>
 #include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Pln.h>
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Wire.h>
 #include <GeomAPI_WireExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
 
 #include <GEOMImpl_Fillet1d.hxx>
 
@@ -66,14 +68,64 @@ GeomAlgoAPI_Fillet1D::GeomAlgoAPI_Fillet1D(const GeomShapePtr& theBaseWire,
   build(theBaseWire, theFilletVertices, theFilletRadius);
 }
 
-void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseWire,
+void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseShape,
                                  const ListOfShape&  theFilletVertices,
                                  const double        theRadius)
 {
-  if (!theBaseWire || theFilletVertices.empty() || theRadius < 0.)
+  if (!theBaseShape.get() || theFilletVertices.empty() || theRadius < 0.)
     return;
 
   myFailedVertices.clear();
+  GeomShapePtr aShape;
+
+  if (theBaseShape->isWire())
+    aShape = buildWire(theBaseShape, theFilletVertices, theRadius);
+  else if (theBaseShape->isCompound()) {
+    std::list<GeomShapePtr> aShapes;
+    for (GeomAPI_ShapeIterator it (theBaseShape); it.more(); it.next()) {
+      GeomShapePtr aSubShape = it.current();
+      if (aSubShape->isWire()) {
+        // get only fillet vertices of current wire
+        ListOfShape aFilletVertices;
+        std::set<GeomShapePtr, GeomAPI_Shape::Comparator> aFilletVerticesSet
+          (theFilletVertices.begin(), theFilletVertices.end());
+        for (GeomAPI_WireExplorer anExp(aSubShape->wire()); anExp.more(); anExp.next()) {
+          if (aFilletVerticesSet.find(anExp.currentVertex()) != aFilletVerticesSet.end())
+            aFilletVertices.push_back(anExp.currentVertex());
+        }
+
+        GeomShapePtr aShape_i = buildWire(aSubShape, aFilletVertices, theRadius);
+        if (aShape_i.get() != NULL)
+          aShapes.push_back(aShape_i);
+        else
+          aShapes.push_back(aSubShape);
+      }
+      else {
+        setDone(false);
+        myError = "Input shape for fillet is neither a wire nor a compound of wires";
+        return;
+      }
+    }
+    aShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
+    myModified[theBaseShape].push_back(aShape);
+  } else {
+    setDone(false);
+    myError = "Input shape for fillet is neither a wire nor a compound";
+    return;
+  }
+
+  setShape(aShape);
+  setDone(myFailedVertices.empty());
+}
+
+GeomShapePtr GeomAlgoAPI_Fillet1D::buildWire(const GeomShapePtr& theBaseWire,
+                                             const ListOfShape&  theFilletVertices,
+                                             const double        theRadius)
+{
+  std::shared_ptr<GeomAPI_Shape> aShape;
+  if (!theBaseWire.get() || theFilletVertices.empty() || theRadius < 0.)
+    return aShape;
+
   // store all edges of a base wire as modified, because they will be rebuild by ShapeFix
   for (GeomAPI_WireExplorer aWExp(theBaseWire->wire()); aWExp.more(); aWExp.next()) {
     GeomShapePtr aCurrent = aWExp.current();
@@ -103,7 +155,7 @@ void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseWire,
 
     GeomPlanePtr aPlane = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
     if (!aPlane)
-      return; // non-planar edges
+      return aShape; // non-planar edges
 
     TopoDS_Edge anEdge1 = TopoDS::Edge(anEdges.front()->impl<TopoDS_Shape>());
     TopoDS_Edge anEdge2 = TopoDS::Edge(anEdges.back()->impl<TopoDS_Shape>());
@@ -148,9 +200,10 @@ void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseWire,
       aNewEdges.push_back(aWExp.current());
     for (ListOfShape::iterator anIt = aNewEdges.begin(); anIt != aNewEdges.end(); ++anIt)
       aBuilder.Add(aNewWire, TopoDS::Edge((*anIt)->impl<TopoDS_Shape>()));
-  }
-  for (MapModified::iterator aGenIt = myGenerated.begin(); aGenIt != myGenerated.end(); ++aGenIt) {
-    for (ListOfShape::iterator anIt = aGenIt->second.begin(); anIt != aGenIt->second.end(); ++anIt)
+
+    ListOfShape aNewEdges1;
+    generated(aWExp.currentVertex(), aNewEdges1);
+    for (ListOfShape::iterator anIt = aNewEdges1.begin(); anIt != aNewEdges1.end(); ++anIt)
       aBuilder.Add(aNewWire, TopoDS::Edge((*anIt)->impl<TopoDS_Shape>()));
   }
   // fix the wire connectivity
@@ -161,7 +214,7 @@ void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseWire,
   aNewWire = aFixWire.WireAPIMake();
   if (aNewWire.IsNull()) {
     myFailedVertices = theFilletVertices;
-    return;
+    return aShape;
   }
 
   // update the map of modified shapes, because the edges are changed by ShapeFix
@@ -197,12 +250,10 @@ void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseWire,
     aNewWire = aReorderedWire;
   }
 
-  std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
-  aShape->setImpl(new TopoDS_Shape(aNewWire));
-  myModified[theBaseWire].push_back(aShape);
-
-  setShape(aShape);
-  setDone(myFailedVertices.empty());
+  std::shared_ptr<GeomAPI_Shape> aResShape(new GeomAPI_Shape);
+  aResShape->setImpl(new TopoDS_Shape(aNewWire));
+  myModified[theBaseWire].push_back(aResShape);
+  return aResShape;
 }
 
 void GeomAlgoAPI_Fillet1D::generated(const GeomShapePtr theOldShape,
index a1065bd4854f73957ad073f9ba767435f0766d66..187df078bf6a7075e9c4d8521cb8175a10401633 100644 (file)
@@ -34,8 +34,8 @@ class GeomAlgoAPI_Fillet1D : public GeomAlgoAPI_MakeShape
 
 public:
   /// Run fillet operation on a set of vertices with fixed radius.
-  /// \param theBaseWire        a changing Wire
-  /// \param theFilletVertices  list of edges the fillet is performed on
+  /// \param theBaseWire        a wire or a compound of wires
+  /// \param theFilletVertices  list of vertices the fillet is performed on
   /// \param theFilletRadius    radius of the fillet
   GEOMALGOAPI_EXPORT GeomAlgoAPI_Fillet1D(const GeomShapePtr& theBaseWire,
                                           const ListOfShape&  theFilletVertices,
@@ -57,14 +57,22 @@ public:
   const ListOfShape& failedVertices() const { return myFailedVertices; }
 
 private:
-  /// Perform 1d-fillet on wire
-  /// \param theBaseWire        a changing wire
-  /// \param theFilletVertices  list of vertices of filler
+  /// Perform 1d-fillet on a wire or a compound of wires
+  /// \param theBaseShape       the base wire or a compound of wires for fillet
+  /// \param theFilletVertices  list of vertices of fillet
   /// \param theRadius          fillet radius
-  void build(const GeomShapePtr& theBaseWire,
+  void build(const GeomShapePtr& theBaseShape,
              const ListOfShape&  theFilletVertices,
              const double        theRadius);
 
+  /// Perform 1d-fillet on wire
+  /// \param theBaseWire        the base wire for fillet
+  /// \param theFilletVertices  list of vertices of fillet
+  /// \param theRadius          fillet radius
+  GeomShapePtr buildWire(const GeomShapePtr& theBaseWire,
+                         const ListOfShape&  theFilletVertices,
+                         const double        theRadius);
+
 private:
   MapModified myGenerated;
   MapModified myModified;
index 69c000f9c6b74444bfa3524fa633284a29d53a73..5e1239a588aa65c174b23ea6360d4350b229a4c6 100644 (file)
@@ -54,7 +54,8 @@ void Model_AttributeIntArray::setSize(const int theSize, bool sendUpdated)
   } else { // reset the old array
     if (theSize) {
       if (theSize != myArray->Length()) { // old data is not kept, a new array is created
-        Handle(TColStd_HArray1OfInteger) aNewArray = new TColStd_HArray1OfInteger(0, theSize - 1);
+        Handle(TColStd_HArray1OfInteger) aNewArray =
+          new TColStd_HArray1OfInteger(0, theSize - 1, 0);
         myArray->ChangeArray(aNewArray);
         if (sendUpdated)
           owner()->data()->sendAttributeUpdated(this);
index 84a77e9649f5f7db0501958aa424bea19c0d33aa..c175d42f0d85dbc9af2fa100f325f479c40a0923 100644 (file)
@@ -821,39 +821,31 @@ void SketchPlugin_Offset::makeFillet
 
   // find vertices for fillet
   std::set<GeomShapePtr, GeomAPI_Shape::Comparator> aFilletVertices;
-  // ??? TODO: if aResWire is a compound of wires - process each wire ???
-  if (aResWire->isWire()) {
-    for (MapShapeToShapes::const_iterator anIt = aSubshapes.begin();
-         anIt != aSubshapes.end(); ++anIt) {
-      // vertex should have 2 adjacent edges
-      if (anIt->second.size() != 2)
-        continue;
+  for (MapShapeToShapes::const_iterator anIt = aSubshapes.begin();
+       anIt != aSubshapes.end(); ++anIt) {
+    // vertex should have 2 adjacent edges
+    if (anIt->second.size() != 2)
+      continue;
 
-      // both edges should be linear
-      ListOfShape anEdges;
-      anEdges.insert(anEdges.end(), anIt->second.begin(), anIt->second.end());
-      GeomEdgePtr anEdge1 (new GeomAPI_Edge(anEdges.front()));
-      GeomEdgePtr anEdge2 (new GeomAPI_Edge(anEdges.back()));
-      if (!anEdge1->isLine() || !anEdge2->isLine())
-        continue;
+    // both edges should be linear
+    ListOfShape anEdges;
+    anEdges.insert(anEdges.end(), anIt->second.begin(), anIt->second.end());
+    GeomEdgePtr anEdge1 (new GeomAPI_Edge(anEdges.front()));
+    GeomEdgePtr anEdge2 (new GeomAPI_Edge(anEdges.back()));
+    if (!anEdge1->isLine() || !anEdge2->isLine())
+      continue;
 
-      // skip vertices, which smoothly connect adjacent edges
-      GeomVertexPtr aSharedVertex(new GeomAPI_Vertex(anIt->first));
-      if (GeomAlgoAPI_ShapeTools::isTangent(anEdge1, anEdge2, aSharedVertex))
-        continue;
+    // skip vertices, which smoothly connect adjacent edges
+    GeomVertexPtr aSharedVertex(new GeomAPI_Vertex(anIt->first));
+    if (GeomAlgoAPI_ShapeTools::isTangent(anEdge1, anEdge2, aSharedVertex))
+      continue;
 
-      aFilletVertices.insert(anIt->first);
-    }
+    aFilletVertices.insert(anIt->first);
   }
 
   if (!aFilletVertices.empty()) {
     isOK = false; // the wire needs correction
-    ListOfShape aVerticesList;
-    for (GeomAPI_WireExplorer anExp (aResWire->wire()); anExp.more(); anExp.next()) {
-      GeomShapePtr aVertex = anExp.currentVertex();
-      if (aFilletVertices.find(aVertex) != aFilletVertices.end())
-        aVerticesList.push_back(aVertex);
-    }
+    ListOfShape aVerticesList (aFilletVertices.begin(), aFilletVertices.end());
 
     // Fillet1D on all linear edges intersections
     std::shared_ptr<GeomAlgoAPI_Fillet1D> aFilletBuilder
@@ -867,8 +859,7 @@ void SketchPlugin_Offset::makeFillet
     }
     else {
       ListOfShape aFailedVertices = aFilletBuilder->failedVertices();
-      if (aFailedVertices.size() != 0 &&
-          aFailedVertices.size() != aVerticesList.size()) {
+      if (aFailedVertices.size() != 0) {
         // Exclude failed vertices and also vertices, joined
         // with failed by one edge, and run algorithm once again
         ListOfShape::iterator itVertices = aFailedVertices.begin();
@@ -897,12 +888,7 @@ void SketchPlugin_Offset::makeFillet
         }
         else {
           // Fillet1D one more try
-          ListOfShape aVerticesList1;
-          for (GeomAPI_WireExplorer anExp (aResWire->wire()); anExp.more(); anExp.next()) {
-            GeomShapePtr aVertex = anExp.currentVertex();
-            if (aFilletVertices.find(aVertex) != aFilletVertices.end())
-              aVerticesList1.push_back(aVertex);
-          }
+          ListOfShape aVerticesList1 (aFilletVertices.begin(), aFilletVertices.end());
 
           std::shared_ptr<GeomAlgoAPI_Fillet1D> aFilletBuilder1
             (new GeomAlgoAPI_Fillet1D(aResWire, aVerticesList1, theValue));