]> OCCT Git - occt.git/commitdiff
0033791: Shape Healing - ShapeCustom not take location of source shape for the cached... IR-2024-08-09
authoroan <oan@opencascade.com>
Thu, 8 Aug 2024 18:33:52 +0000 (19:33 +0100)
committerdpasukhi <dpasukhi@opencascade.com>
Fri, 9 Aug 2024 15:27:03 +0000 (15:27 +0000)
Pass ShapeBuild_ReShape to recursive call to retrieve complete change history.
Update history of changes by the source shape (if changed), not only by its subshapes.
Check the context for a cached shape using a reference shape without location.

src/ShapeCustom/ShapeCustom.cxx

index 5e4ab7f82eeceefc3fe3e232c0522b75ae292543..a5e8dd29d87a4861d52de860f6c276b4c06a7c52 100644 (file)
 
 #include <Message_ProgressScope.hxx>
 
+namespace
+{
+  //=======================================================================
+  //function : UpdateHistoryShape
+  //purpose  : Updates ShapeBuild_ReShape by the info of the given shape
+  //=======================================================================
+  bool UpdateHistoryShape (const TopoDS_Shape&               theShape,
+                           const BRepTools_Modifier&         theModifier,
+                           const Handle(ShapeBuild_ReShape)& theReShape)
+  {
+    TopoDS_Shape aResult;
+    try
+    {
+      OCC_CATCH_SIGNALS
+      aResult = theModifier.ModifiedShape (theShape);
+    }
+    catch (Standard_NoSuchObject const&)
+    {
+      // the sub shape isn't in the map
+      aResult.Nullify();
+    }
+
+    if (!aResult.IsNull() && !theShape.IsSame (aResult))
+    {
+      theReShape->Replace (theShape, aResult);
+      return true;
+    }
+
+    return false;
+  }
+
+  //=======================================================================
+  //function : UpdateHistory
+  //purpose  : Recursively updates ShapeBuild_ReShape to add information of all sub-shapes
+  //=======================================================================
+  void UpdateHistory (const TopoDS_Shape&               theShape,
+                      const BRepTools_Modifier&         theModifier,
+                      const Handle(ShapeBuild_ReShape)& theReShape)
+  {
+    for (TopoDS_Iterator theIterator (theShape, Standard_False); theIterator.More(); theIterator.Next())
+    {
+      const TopoDS_Shape& aCurrent = theIterator.Value();
+      if (UpdateHistoryShape (aCurrent, theModifier, theReShape))
+      {
+        UpdateHistory (aCurrent, theModifier, theReShape);
+      }
+    }
+  }
+
+  //=======================================================================
+  //function : UpdateShapeBuild
+  //purpose  : Recursively updates ShapeBuild_ReShape to add information of all sub-shapes
+  //=======================================================================
+  void UpdateShapeBuild (const TopoDS_Shape&               theShape,
+                         const BRepTools_Modifier&         theModifier,
+                         const Handle(ShapeBuild_ReShape)& theReShape)
+  {
+    UpdateHistoryShape (theShape, theModifier, theReShape);
+    UpdateHistory      (theShape, theModifier, theReShape);
+  }
+}
+
 //=======================================================================
 //function : ApplyModifier
 //purpose  : static
@@ -58,25 +120,35 @@ TopoDS_Shape ShapeCustom::ApplyModifier (const TopoDS_Shape &S,
     BRep_Builder B;
     B.MakeCompound ( C );
 
+    SF.Location (TopLoc_Location());
     Standard_Integer aShapeCount = SF.NbChildren();
     Message_ProgressScope aPS(theProgress, "Applying Modifier For Solids", aShapeCount);
-    for ( TopoDS_Iterator it(SF); it.More() && aPS.More(); it.Next()) {
-      TopoDS_Shape shape = it.Value();
-      TopLoc_Location L = shape.Location(), nullLoc;
-      shape.Location ( nullLoc );
-      TopoDS_Shape res;
+    for (TopoDS_Iterator it(SF); it.More() && aPS.More(); it.Next())
+    {
       Message_ProgressRange aRange = aPS.Next();
-      if ( context.IsBound ( shape ) )
-        res = context.Find ( shape ).Oriented ( shape.Orientation() );
+    
+      TopoDS_Shape shape       = it.Value();
+      TopoDS_Shape aShapeNoLoc = it.Value();
+      aShapeNoLoc.Location (TopLoc_Location());
+
+      TopoDS_Shape res;
+      if (context.Find (aShapeNoLoc, res))
+      {
+        res.Orientation (shape.Orientation());
+        res.Location    (shape.Location(), Standard_False);
+      }
       else
-        res = ApplyModifier ( shape, M, context ,MD, aRange);
+      {
+        res = ApplyModifier (shape, M, context, MD, aRange, aReShape);
+      }
 
-      if ( ! res.IsSame ( shape ) ) {
-        context.Bind ( shape, res );
+      if ( !res.IsSame (shape) )
+      {
+        context.Bind (aShapeNoLoc, res.Located (TopLoc_Location()));
         locModified = Standard_True;
       }
-      res.Location ( L, Standard_False );
-      B.Add ( C, res );
+
+      B.Add (C, res);
     }
 
     if ( !aPS.More() )
@@ -85,9 +157,16 @@ TopoDS_Shape ShapeCustom::ApplyModifier (const TopoDS_Shape &S,
       return S;
     }
 
-    if ( ! locModified ) return S;
+    if ( !locModified )
+    {
+      return S;
+    }
+
     context.Bind ( SF, C );
-    return C.Oriented ( S.Orientation() );
+
+    C.Orientation (S.Orientation());
+    C.Location    (S.Location(), Standard_False);
+    return C;
   }
 
   Message_ProgressScope aPS(theProgress, "Modify the Shape", 1);
@@ -98,26 +177,7 @@ TopoDS_Shape ShapeCustom::ApplyModifier (const TopoDS_Shape &S,
   if ( !aPS.More() || !MD.IsDone() ) return S;
   if ( !aReShape.IsNull() )
   {
-    for(TopoDS_Iterator theIterator(SF,Standard_False);theIterator.More();theIterator.Next())
-    {
-      const TopoDS_Shape & current = theIterator.Value();
-      TopoDS_Shape result;
-      try
-      {
-        OCC_CATCH_SIGNALS
-        result = MD.ModifiedShape( current );
-      }
-      catch (Standard_NoSuchObject const&)
-      {
-        // the sub shape isn't in the map
-        result.Nullify();
-      }
-
-      if (!result.IsNull() && !current.IsSame(result))
-      {
-        aReShape->Replace(current, result);
-      }
-    }
+    UpdateShapeBuild ( SF, MD, aReShape );
   }
 
   return MD.ModifiedShape(SF).Oriented(S.Orientation());