From: abk Date: Tue, 25 Apr 2017 12:32:51 +0000 (+0300) Subject: 0028709: Extend type 'BRepTools_ReShape' to support 'BRepTools_History' history X-Git-Tag: V7_2_0_beta~66 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=98ffe9dfdf065311250633826026e02cb61b1ae1 0028709: Extend type 'BRepTools_ReShape' to support 'BRepTools_History' history 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. --- diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index 35d1f6b7d2..ed2f82c401 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -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 diff --git a/src/BRepTools/BRepTools_ReShape.cxx b/src/BRepTools/BRepTools_ReShape.cxx index 77216b7591..c650117b2f 100644 --- a/src/BRepTools/BRepTools_ReShape.cxx +++ b/src/BRepTools/BRepTools_ReShape.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,32 @@ 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 +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 //#include 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 aIntermediates; + NCollection_Map 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::Iterator aIt(aModified); + aIt.More(); aIt.Next()) + { + aHistory->AddModified(aShape, aIt.Value()); + } + } + } + + return aHistory; +} diff --git a/src/BRepTools/BRepTools_ReShape.hxx b/src/BRepTools/BRepTools_ReShape.hxx index 6201831843..a14541b794 100644 --- a/src/BRepTools/BRepTools_ReShape.hxx +++ b/src/BRepTools/BRepTools_ReShape.hxx @@ -17,8 +17,7 @@ #ifndef _BRepTools_ReShape_HeaderFile #define _BRepTools_ReShape_HeaderFile -#include -#include +#include #include #include @@ -26,6 +25,7 @@ #include #include #include + 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 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;
//! - 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 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; diff --git a/src/ShapeBuild/ShapeBuild_ReShape.cxx b/src/ShapeBuild/ShapeBuild_ReShape.cxx index cef79d3580..9251333f95 100644 --- a/src/ShapeBuild/ShapeBuild_ReShape.cxx +++ b/src/ShapeBuild/ShapeBuild_ReShape.cxx @@ -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; }