0028709: Extend type 'BRepTools_ReShape' to support 'BRepTools_History' history
authorabk <abk@opencascade.com>
Tue, 25 Apr 2017 12:32:51 +0000 (15:32 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 29 Jun 2017 11:23:56 +0000 (14:23 +0300)
Type 'BRepTools_ReShape' was extended to:
- support the 'BRepTools_History' history;
- merge several shapes to a single shape that
  the history of the merged shapes is presented by equal ways.

Type 'ShapeBuild_ReShape' was changed to support 'BRepTools_History' history.

dox/dev_guides/upgrade/upgrade.md
src/BRepTools/BRepTools_ReShape.cxx
src/BRepTools/BRepTools_ReShape.hxx
src/ShapeBuild/ShapeBuild_ReShape.cxx

index 35d1f6b..ed2f82c 100644 (file)
@@ -1147,6 +1147,7 @@ The following obsolete features have been removed:
 * The method Perform of the *ShapeConstruct_ProjectCurveOnSurface* class is modified:
   - input arguments *continuity*, *maxdeg*, *nbinterval* have been removed as unused;
   - input arguments *TolFirst*, *TolLast* have been added at the end of arguments' list.
+* The functionality to process shapes different only in orientation by different ways was removed from types *BRepTools_ReShape* and *ShapeBuild_ReShape*.
 
 @subsection upgrade_occt720_correction_of_Offset_API Corrections in BRepOffset API
 
index 77216b7..c650117 100644 (file)
@@ -23,6 +23,7 @@
 #include <BRep_Tool.hxx>
 #include <BRepTools_ReShape.hxx>
 #include <Geom_Surface.hxx>
+#include <NCollection_IndexedMap.hxx>
 #include <Standard_Type.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopLoc_Location.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(BRepTools_ReShape,MMgt_TShared)
 
+namespace
+{
+
+//! Adds the shape to the map.
+//! If the shape is a wire, shell or solid then
+//! adds the sub-shapes of the shape instead.
+//! Returns 'true' if the sub-shapes were added.
+template<typename TMap>
+void Add(TMap& theMap, const TopoDS_Shape& theShape)
+{
+  const TopAbs_ShapeEnum aType = theShape.ShapeType();
+  if (aType != TopAbs_WIRE && aType != TopAbs_SHELL &&
+    aType != TopAbs_COMPSOLID)
+  {
+    theMap.Add(theShape);
+    return;
+  }
+
+  for (TopoDS_Iterator aIt(theShape); aIt.More(); aIt.Next())
+  {
+    theMap.Add(aIt.Value());
+  }
+}
+
+}
+
 //include <ShapeExtend.hxx>
 //#include <BRepTools_Edge.hxx>
 static void CopyRanges (const TopoDS_Shape& toedge, const TopoDS_Shape& fromedge,
@@ -101,7 +128,7 @@ BRepTools_ReShape::BRepTools_ReShape()
 
 void BRepTools_ReShape::Clear() 
 {
-  myNMap.Clear();
+  myShapeToReplacement.Clear();
   myNewShapes.Clear();
 }
 
@@ -114,7 +141,7 @@ void BRepTools_ReShape::Clear()
 void BRepTools_ReShape::Remove (const TopoDS_Shape& shape)
 {
   TopoDS_Shape nulshape;
-  Replace (shape,nulshape);
+  replace(shape, nulshape, TReplacementKind_Remove);
 }
 
 //=======================================================================
@@ -123,7 +150,8 @@ void BRepTools_ReShape::Remove (const TopoDS_Shape& shape)
 //=======================================================================
 
 void BRepTools_ReShape::replace (const TopoDS_Shape& ashape,
-                                 const TopoDS_Shape& anewshape)
+                                 const TopoDS_Shape& anewshape,
+                                 const TReplacementKind theKind)
 {
   TopoDS_Shape shape = ashape;
   TopoDS_Shape newshape = anewshape;
@@ -156,11 +184,10 @@ void BRepTools_ReShape::replace (const TopoDS_Shape& ashape,
     cout << "Warning: BRepTools_ReShape::Replace: shape already recorded" << endl;
 #endif
 
-  myNMap.Bind (shape, newshape);
+  myShapeToReplacement.Bind(shape, TReplacement(newshape, theKind));
   myNewShapes.Add (newshape);
 }
 
-
 //=======================================================================
 //function : IsRecorded
 //purpose  : 
@@ -174,7 +201,7 @@ Standard_Boolean BRepTools_ReShape::IsRecorded (const TopoDS_Shape& ashape) cons
     shape.Location ( nullLoc );
   }
   if (shape.IsNull()) return Standard_False;
-  return myNMap.IsBound (shape);
+  return myShapeToReplacement.IsBound (shape);
 }
 
 
@@ -194,19 +221,18 @@ TopoDS_Shape BRepTools_ReShape::Value (const TopoDS_Shape& ashape) const
   }
   
   Standard_Boolean fromMap = Standard_False;
-  if ( shape.Orientation()==TopAbs_REVERSED ) {
-    if (!myNMap.IsBound (shape)) res = shape;
-    else { 
-      res = myNMap.Find (shape).Reversed();
-      fromMap = Standard_True;
-    }
+  if (!myShapeToReplacement.IsBound(shape))
+  {
+    res = shape;
   }
-  else {
-    if (!myNMap.IsBound (shape)) res = shape;
-    else {
-      res = myNMap.Find (shape);
-      fromMap = Standard_True;
+  else
+  {
+    res = myShapeToReplacement(shape).Result();
+    if (shape.Orientation() == TopAbs_REVERSED)
+    {
+      res.Reverse();
     }
+    fromMap = Standard_True;
   }
   // for INTERNAL/EXTERNAL, since they are not fully supported, keep orientation
   if ( shape.Orientation() == TopAbs_INTERNAL ||
@@ -243,8 +269,16 @@ Standard_Integer BRepTools_ReShape::Status(const TopoDS_Shape& ashape,
     shape.Location ( nullLoc );
   }
 
-  if (!myNMap.IsBound (shape))  {  newsh = shape;  res = 0; }
-  else {  newsh = myNMap.Find (shape);  res = 1;  }
+  if (!myShapeToReplacement.IsBound(shape))
+  {
+    newsh = shape;
+    res = 0;
+  }
+  else
+  {
+    newsh = myShapeToReplacement(shape).Result();
+    res = 1;
+  }
   if (res > 0) {
     if (newsh.IsNull()) res = -1;
     else if (newsh.IsEqual (shape)) res = 0;
@@ -413,7 +447,8 @@ TopoDS_Shape BRepTools_ReShape::Apply (const TopoDS_Shape& shape,
     result.Orientation(orien);
   }
 
-  Replace ( shape, result );
+  replace(shape, result,
+    result.IsNull() ? TReplacementKind_Remove : TReplacementKind_Modify);
   myStatus = locStatus;
 
   return result;
@@ -468,3 +503,63 @@ Standard_Boolean BRepTools_ReShape::IsNewShape(const TopoDS_Shape& theShape) con
 {
   return myNewShapes.Contains(theShape);
 }
+
+//=======================================================================
+//function : History
+//purpose  :
+//=======================================================================
+
+Handle(BRepTools_History) BRepTools_ReShape::History() const
+{
+  Handle(BRepTools_History) aHistory = new BRepTools_History;
+
+  // Fill the history.
+  for (TShapeToReplacement::Iterator aRIt(myShapeToReplacement);
+    aRIt.More(); aRIt.Next())
+  {
+    const TopoDS_Shape& aShape = aRIt.Key();
+    if (!BRepTools_History::IsSupportedType(aShape) ||
+      myNewShapes.Contains(aShape))
+    {
+      continue;
+    }
+
+    NCollection_IndexedMap<TopoDS_Shape> aIntermediates;
+    NCollection_Map<TopoDS_Shape> aModified;
+    aIntermediates.Add(aShape);
+    for (Standard_Integer aI = 1; aI <= aIntermediates.Size(); ++aI)
+    {
+      const TopoDS_Shape& aIntermediate = aIntermediates(aI);
+      const TReplacement* aReplacement =
+        myShapeToReplacement.Seek(aIntermediate);
+      if (aReplacement == NULL)
+      {
+        Add(aModified, aIntermediate);
+      }
+      else if (aReplacement->RelationKind() !=
+        BRepTools_History::TRelationType_Removed)
+      {
+        const TopoDS_Shape aResult = aReplacement->RelationResult();
+        if (!aResult.IsNull())
+        {
+          Add(aIntermediates, aResult);
+        }
+      }
+    }
+
+    if (aModified.IsEmpty())
+    {
+      aHistory->Remove(aShape);
+    }
+    else
+    {
+      for (NCollection_Map<TopoDS_Shape>::Iterator aIt(aModified);
+        aIt.More(); aIt.Next())
+      {
+        aHistory->AddModified(aShape, aIt.Value());
+      }
+    }
+  }
+
+  return aHistory;
+}
index 6201831..a14541b 100644 (file)
@@ -17,8 +17,7 @@
 #ifndef _BRepTools_ReShape_HeaderFile
 #define _BRepTools_ReShape_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
+#include <BRepTools_History.hxx>
 
 #include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopTools_MapOfShape.hxx>
@@ -26,6 +25,7 @@
 #include <Standard_Boolean.hxx>
 #include <MMgt_TShared.hxx>
 #include <TopAbs_ShapeEnum.hxx>
+
 class TopoDS_Shape;
 class TopoDS_Vertex;
 
@@ -49,12 +49,11 @@ DEFINE_STANDARD_HANDLE(BRepTools_ReShape, MMgt_TShared)
 //!
 //! Then, these requests may be applied to any shape which may
 //! contain one or more of these individual shapes
+//!
+//! Supports the 'BRepTools_History' history by method 'History'.
 class BRepTools_ReShape : public MMgt_TShared
 {
-
 public:
-
-  
   //! Returns an empty Reshape
   Standard_EXPORT BRepTools_ReShape();
   
@@ -67,9 +66,32 @@ public:
   //! Sets a request to Replace a Shape by a new one.
   virtual void Replace (const TopoDS_Shape& shape, const TopoDS_Shape& newshape)
   {
-    replace (shape, newshape);
+    replace (shape, newshape, TReplacementKind_Modify);
   }
   
+  //! Merges the parts to the single product.
+  //! The first part is replaced by the product.
+  //! The other parts are removed.
+  //! The history of the merged shapes is presented by equal ways.
+  template<typename TCollection> void Merge(
+    const TCollection& theParts, const TopoDS_Shape& theProduct)
+  {
+    typename TCollection::Iterator aPIt(theParts);
+
+    if (aPIt.More())
+    {
+      replace(aPIt.Value(), theProduct, TReplacementKind_Merge_Main);
+
+      aPIt.Next();
+    }
+
+    const TReplacementKind aKind = TReplacementKind_Merge_Ordinary;
+    for (; aPIt.More(); aPIt.Next())
+    {
+      replace(aPIt.Value(), theProduct, aKind);
+    }
+  }
+
   //! Tells if a shape is recorded for Replace/Remove
   Standard_EXPORT virtual Standard_Boolean IsRecorded (const TopoDS_Shape& shape) const;
   
@@ -127,9 +149,21 @@ public:
   //@param theShape is the given shape
   Standard_EXPORT Standard_Boolean IsNewShape(const TopoDS_Shape& theShape) const;
 
+  //! Returns the history of the substituted shapes.
+  Standard_EXPORT Handle(BRepTools_History) History() const;
+
   DEFINE_STANDARD_RTTIEXT(BRepTools_ReShape,MMgt_TShared)
 
-private:
+protected:
+  //! The kinds of the replacements.
+  enum TReplacementKind
+  {
+    TReplacementKind_Remove = 1,
+    TReplacementKind_Modify = 2,
+    TReplacementKind_Merge_Main = 4,
+    TReplacementKind_Merge_Ordinary = 8
+  };
+
   //! Replaces the first shape by the second one
   //! after the following reorientation.
   //!
@@ -139,12 +173,70 @@ private:
   //! - the second shape is oriented forward (reversed) if it's orientation
   //!   is equal (not equal) to the orientation of the first shape; <br>
   //! - the first shape is oriented forward.
-  Standard_EXPORT virtual void replace (const TopoDS_Shape& shape, const TopoDS_Shape& newshape);
+  Standard_EXPORT virtual void replace (
+    const TopoDS_Shape& shape,
+    const TopoDS_Shape& newshape,
+    const TReplacementKind theKind);
 
-protected:
+private:
+  //! Returns 'true' if the kind of a replacement is an ordinary merging.
+  static Standard_Boolean isOrdinaryMerged(const TReplacementKind theKind)
+  {
+    return (theKind == TReplacementKind_Merge_Ordinary);
+  }
+
+  //! A replacement of an initial shape.
+  struct TReplacement
+  {
+  public:
+    //! The default constructor.
+    TReplacement() : myKind(TReplacementKind_Remove)
+    {
+    }
+
+    //! The initializing constructor.
+    TReplacement(
+        const TopoDS_Shape& theResult, const TReplacementKind theKind) :
+      myResult(theResult), myKind(theKind)
+    {
+    }
 
+    //! Returns the result of the replacement.
+    TopoDS_Shape Result() const
+    {
+      return (myKind != TReplacementKind_Merge_Ordinary) ?
+        myResult : TopoDS_Shape();
+    }
 
-  TopTools_DataMapOfShapeShape myNMap;
+    //! Returns the result of the relation.
+    const TopoDS_Shape& RelationResult() const
+    {
+      return myResult;
+    }
+
+    //! Returns the kind of the relation
+    //! between an initial shape and the result of the replacement.
+    BRepTools_History::TRelationType RelationKind() const
+    {
+      return (myKind == TReplacementKind_Remove) ?
+        BRepTools_History::TRelationType_Removed :
+        BRepTools_History::TRelationType_Modified;
+    }
+
+  private:
+    TopoDS_Shape myResult; //!< The result of the replacement.
+    TReplacementKind myKind; //!< The kind of the replacement.
+  };
+
+  typedef NCollection_DataMap<TopoDS_Shape, TReplacement,
+    TopTools_ShapeMapHasher> TShapeToReplacement;
+
+private:
+  //! Maps each shape to its replacement.
+  //! If a shape is not bound to the map then the shape is replaced by itself.
+  TShapeToReplacement myShapeToReplacement;
+
+protected:
   TopTools_MapOfShape myNewShapes;
   Standard_Integer myStatus;
 
index cef79d3..9251333 100644 (file)
@@ -224,7 +224,9 @@ TopoDS_Shape ShapeBuild_ReShape::Apply (const TopoDS_Shape& shape,
     result.Closed (BRep_Tool::IsClosed (result));
   result.Orientation(orient);
   myStatus = locStatus;
-  Replace ( shape, result );
+
+  replace(shape, result,
+    result.IsNull() ? TReplacementKind_Remove : TReplacementKind_Modify);
 
   return result;
 }