]> OCCT Git - occt-copy.git/commitdiff
BRep history added for hidden faces remove tool support
authorsnn <snn@opencascade.com>
Fri, 16 Mar 2018 09:19:08 +0000 (12:19 +0300)
committersnn <snn@opencascade.com>
Fri, 16 Mar 2018 09:19:08 +0000 (12:19 +0300)
src/BRepTools/BRepTools_History.cxx [new file with mode: 0644]
src/BRepTools/BRepTools_History.hxx [new file with mode: 0644]
src/BRepTools/FILES

diff --git a/src/BRepTools/BRepTools_History.cxx b/src/BRepTools/BRepTools_History.cxx
new file mode 100644 (file)
index 0000000..6f9ea8a
--- /dev/null
@@ -0,0 +1,422 @@
+// Created on: 2017-04-21
+// Created by: Alexander Bobkov
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepTools_History.hxx>
+
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+// Implement the OCCT RTTI for the type.
+IMPLEMENT_STANDARD_RTTIEXT(BRepTools_History, Standard_Transient)
+
+namespace
+{
+
+//==============================================================================
+//function : add
+//purpose  : Adds the elements of the list to the map.
+//==============================================================================
+void add(TopTools_MapOfShape& theMap, const TopTools_ListOfShape& theList)
+{
+  for (TopTools_ListOfShape::Iterator aSIt(theList); aSIt.More(); aSIt.Next())
+  {
+    theMap.Add(aSIt.Value());
+  }
+}
+
+//==============================================================================
+//function : add
+//purpose  : Adds the elements of the collection to the list.
+//==============================================================================
+template<typename TCollection>
+void add(TopTools_ListOfShape& theList, const TCollection& theCollection)
+{
+  for (typename TCollection::Iterator aSIt(theCollection);
+    aSIt.More(); aSIt.Next())
+  {
+    theList.Append(aSIt.Value());
+  }
+}
+
+}
+
+//==============================================================================
+//function : AddGenerated
+//purpose  :
+//==============================================================================
+void BRepTools_History::AddGenerated(
+  const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
+{
+  if (!prepareGenerated(theInitial, theGenerated))
+  {
+    return;
+  }
+
+  TopTools_ListOfShape* aGenerations =
+    myShapeToGenerated.ChangeSeek(theInitial);
+  if (aGenerations == NULL)
+  {
+    aGenerations = myShapeToGenerated.Bound(theInitial, TopTools_ListOfShape());
+  }
+
+  Standard_ASSERT_VOID(!aGenerations->Contains(theGenerated),
+    "Error: a duplicated generation of a shape.");
+
+  aGenerations->Append(theGenerated);
+}
+
+//==============================================================================
+//function : AddModified
+//purpose  :
+//==============================================================================
+void BRepTools_History::AddModified(
+  const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
+{
+  if (!prepareModified(theInitial, theModified))
+  {
+    return;
+  }
+
+  TopTools_ListOfShape* aModifications =
+    myShapeToModified.ChangeSeek(theInitial);
+  if (aModifications == NULL)
+  {
+    aModifications =
+      myShapeToModified.Bound(theInitial, TopTools_ListOfShape());
+  }
+
+  Standard_ASSERT_VOID(!aModifications->Contains(theModified),
+    "Error: a duplicated modification of a shape.");
+
+  aModifications->Append(theModified);
+}
+
+//==============================================================================
+//function : Remove
+//purpose  :
+//==============================================================================
+void BRepTools_History::Remove(const TopoDS_Shape& theRemoved)
+{
+  // Apply the limitations.
+  Standard_ASSERT_RETURN(IsSupportedType(theRemoved), myMsgUnsupportedType,);
+
+  if (myShapeToGenerated.UnBind(theRemoved))
+  {
+    Standard_ASSERT_INVOKE_(, myMsgGeneratedAndRemoved);
+  }
+
+  if (myShapeToModified.UnBind(theRemoved))
+  {
+    Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved);
+  }
+
+  //
+  myRemoved.Add(theRemoved);
+}
+
+//==============================================================================
+//function : ReplaceGenerated
+//purpose  :
+//==============================================================================
+void BRepTools_History::ReplaceGenerated(
+  const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
+{
+  if (!prepareGenerated(theInitial, theGenerated))
+  {
+    return;
+  }
+
+  TopTools_ListOfShape* aGenerations =
+    myShapeToGenerated.Bound(theInitial, TopTools_ListOfShape());
+  aGenerations->Append(theGenerated);
+}
+
+//==============================================================================
+//function : ReplaceModified
+//purpose  :
+//==============================================================================
+void BRepTools_History::ReplaceModified(
+  const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
+{
+  if (!prepareModified(theInitial, theModified))
+  {
+    return;
+  }
+
+  TopTools_ListOfShape* aModifications =
+    myShapeToModified.Bound(theInitial, TopTools_ListOfShape());
+  aModifications->Append(theModified);
+}
+
+//==============================================================================
+//function : Generated
+//purpose  :
+//==============================================================================
+const TopTools_ListOfShape& BRepTools_History::Generated(
+  const TopoDS_Shape& theInitial) const
+{
+  // Apply the limitations.
+  Standard_ASSERT_RETURN(theInitial.IsNull() || IsSupportedType(theInitial),
+    myMsgUnsupportedType, emptyList());
+
+  //
+  const TopTools_ListOfShape* aGenerations =
+    myShapeToGenerated.Seek(theInitial);
+  return (aGenerations != NULL) ? *aGenerations : emptyList();
+}
+
+//==============================================================================
+//function : Modified
+//purpose  :
+//==============================================================================
+const TopTools_ListOfShape& BRepTools_History::Modified(
+  const TopoDS_Shape& theInitial) const
+{
+  // Apply the limitations.
+  Standard_ASSERT_RETURN(IsSupportedType(theInitial),
+    myMsgUnsupportedType, emptyList());
+
+  //
+  const TopTools_ListOfShape* aModifications =
+    myShapeToModified.Seek(theInitial);
+  return (aModifications != NULL) ? *aModifications : emptyList();
+}
+
+//==============================================================================
+//function : IsRemoved
+//purpose  :
+//==============================================================================
+Standard_Boolean BRepTools_History::IsRemoved(
+  const TopoDS_Shape& theInitial) const
+{
+  // Apply the limitations.
+  Standard_ASSERT_RETURN(IsSupportedType(theInitial),
+    myMsgUnsupportedType, Standard_False);
+
+  //
+  return myRemoved.Contains(theInitial);
+}
+
+//==============================================================================
+//function : Merge
+//purpose  :
+//==============================================================================
+void BRepTools_History::Merge(const Handle(BRepTools_History)& theHistory23)
+{
+  // Propagate R23 directly and M23 and G23 fully to M12 and G12.
+  // Remember the propagated shapes.
+  TopTools_DataMapOfShapeListOfShape* aS1ToGAndM[] =
+    {&myShapeToGenerated, &myShapeToModified};
+  TopTools_MapOfShape aRPropagated;
+  {
+    // Propagate R23, M23 and G23 to M12 and G12 directly.
+    // Remember the propagated shapes.
+    TopTools_MapOfShape aMAndGPropagated;
+    for (Standard_Integer aI = 0; aI < 2; ++aI)
+    {
+      for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]);
+        aMIt1.More(); aMIt1.Next())
+      {
+        TopTools_ListOfShape& aL12 = aMIt1.ChangeValue();
+        TopTools_MapOfShape aAdditions[2]; // The G and M additions.
+        for (TopTools_ListOfShape::Iterator aSIt2(aL12); aSIt2.More();)
+        {
+          const TopoDS_Shape& aS2 = aSIt2.Value();
+          if (theHistory23->IsRemoved(aS2))
+          {
+            aL12.Remove(aSIt2);
+            aRPropagated.Add(aS2);
+          }
+          else
+          {
+            if (theHistory23->myShapeToGenerated.IsBound(aS2))
+            {
+              add(aAdditions[0], theHistory23->myShapeToGenerated(aS2));
+              aMAndGPropagated.Add(aS2);
+            }
+
+            if (theHistory23->myShapeToModified.IsBound(aS2))
+            {
+              add(aAdditions[aI], theHistory23->myShapeToModified(aS2));
+              aMAndGPropagated.Add(aS2);
+
+              aL12.Remove(aSIt2);
+            }
+            else
+            {
+              aSIt2.Next();
+            }
+          }
+        }
+
+        add(aL12, aAdditions[aI]);
+        if (aI != 0 && !aAdditions[0].IsEmpty())
+        {
+          const TopoDS_Shape& aS1 = aMIt1.Key();
+          TopTools_ListOfShape* aGAndM = aS1ToGAndM[0]->ChangeSeek(aS1);
+          if (aGAndM == NULL)
+          {
+            aGAndM = aS1ToGAndM[0]->Bound(aS1, TopTools_ListOfShape());
+          }
+
+          add(*aGAndM, aAdditions[0]);
+        }
+      }
+    }
+
+    // Propagate M23 and G23 to M12 and G12 sequentially.
+    const TopTools_DataMapOfShapeListOfShape* aS2ToGAndM[] =
+      {&theHistory23->myShapeToGenerated, &theHistory23->myShapeToModified};
+    for (Standard_Integer aI = 0; aI < 2; ++aI)
+    {
+      for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt2(*aS2ToGAndM[aI]);
+        aMIt2.More(); aMIt2.Next())
+      {
+        const TopoDS_Shape& aS2 = aMIt2.Key();
+        if (!aMAndGPropagated.Contains(aS2))
+        {
+          if (!aS1ToGAndM[aI]->IsBound(aS2))
+          {
+            aS1ToGAndM[aI]->Bind(aS2, TopTools_ListOfShape());
+          }
+
+          TopTools_ListOfShape aM2 = aMIt2.Value();
+          ((*aS1ToGAndM[aI])(aS2)).Append(aM2);
+        }
+      }
+    }
+  }
+
+  // Unbound the empty M12 and G12.
+  for (Standard_Integer aI = 0; aI < 2; ++aI)
+  {
+    for (TopTools_DataMapOfShapeListOfShape::Iterator aMIt1(*aS1ToGAndM[aI]);
+      aMIt1.More();)
+    {
+      const TopoDS_Shape& aS1 = aMIt1.Key();
+      const TopTools_ListOfShape& aL12 = aMIt1.Value();
+      aMIt1.Next();
+      if (aL12.IsEmpty())
+      {
+        aS1ToGAndM[aI]->UnBind(aS1);
+      }
+    }
+  }
+
+  // Propagate R23 to R12 sequentially.
+  for (TopTools_MapOfShape::Iterator aRIt23(theHistory23->myRemoved);
+    aRIt23.More(); aRIt23.Next())
+  {
+    const TopoDS_Shape& aS2 = aRIt23.Value();
+    if (!aRPropagated.Contains(aS2) &&
+      !myShapeToModified.IsBound(aS2) &&
+      !myShapeToGenerated.IsBound(aS2))
+    {
+      myRemoved.Add(aS2);
+    }
+  }
+}
+
+//==============================================================================
+//function : prepareGenerated
+//purpose  :
+//==============================================================================
+Standard_Boolean BRepTools_History::prepareGenerated(
+  const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated)
+{
+  Standard_ASSERT_RETURN(theInitial.IsNull() ||
+    IsSupportedType(theInitial), myMsgUnsupportedType, Standard_False);
+
+  if (myRemoved.Remove(theInitial))
+  {
+    Standard_ASSERT_INVOKE_(, myMsgGeneratedAndRemoved);
+  }
+
+  if (myShapeToModified.IsBound(theInitial) &&
+    myShapeToModified(theInitial).Remove(theGenerated))
+  {
+    Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified);
+  }
+
+  return Standard_True;
+}
+
+//==============================================================================
+//function : prepareModified
+//purpose  :
+//==============================================================================
+Standard_Boolean BRepTools_History::prepareModified(
+  const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified)
+{
+  Standard_ASSERT_RETURN(IsSupportedType(theInitial),
+    myMsgUnsupportedType, Standard_False);
+
+  if (myRemoved.Remove(theInitial))
+  {
+    Standard_ASSERT_INVOKE_(, myMsgModifiedAndRemoved);
+  }
+
+  if (myShapeToGenerated.IsBound(theInitial) &&
+    myShapeToGenerated(theInitial).Remove(theModified))
+  {
+    Standard_ASSERT_INVOKE_(, myMsgGeneratedAndModified);
+  }
+
+  return Standard_True;
+}
+
+//==============================================================================
+//data : myEmptyList
+//purpose  :
+//==============================================================================
+const TopTools_ListOfShape BRepTools_History::myEmptyList;
+
+//==============================================================================
+//function : emptyList
+//purpose  :
+//==============================================================================
+const TopTools_ListOfShape& BRepTools_History::emptyList()
+{
+  return myEmptyList;
+}
+
+//==============================================================================
+//data : myMsgUnsupportedType
+//purpose  :
+//==============================================================================
+const char* BRepTools_History::myMsgUnsupportedType =
+  "Error: unsupported shape type.";
+
+//==============================================================================
+//data : myMsgGeneratedAndRemoved
+//purpose  :
+//==============================================================================
+const char* BRepTools_History::myMsgGeneratedAndRemoved =
+  "Error: a shape is generated and removed simultaneously.";
+
+//==============================================================================
+//data : myMsgModifiedAndRemoved
+//purpose  :
+//==============================================================================
+const char* BRepTools_History::myMsgModifiedAndRemoved =
+  "Error: a shape is modified and removed simultaneously.";
+
+//==============================================================================
+//data : myMsgGeneratedAndModified
+//purpose  :
+//==============================================================================
+const char* BRepTools_History::myMsgGeneratedAndModified =
+  "Error: a shape is generated and modified "
+    "from the same shape simultaneously.";
diff --git a/src/BRepTools/BRepTools_History.hxx b/src/BRepTools/BRepTools_History.hxx
new file mode 100644 (file)
index 0000000..63f416c
--- /dev/null
@@ -0,0 +1,204 @@
+// Created on: 2017-04-21
+// Created by: Alexander Bobkov
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepTools_History_HeaderFile
+#define _BRepTools_History_HeaderFile
+
+#include <NCollection_Handle.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+
+class BRepTools_History;
+DEFINE_STANDARD_HANDLE(BRepTools_History, Standard_Transient)
+
+//! The history keeps the following relations between the input shapes
+//! (S1, ..., Sm) and output shapes (T1, ..., Tn):
+//! 1) an output shape Tj is generated from an input shape Si: Tj <= G(Si);
+//! 2) a output shape Tj is modified from an input shape Si: Tj <= M(Si);
+//! 3) an input shape (Si) is removed: R(Si) == 1.
+//!
+//! The relations are kept only for shapes of types vertex, edge, face, and
+//! solid.
+//!
+//! The last relation means that:
+//! 1) shape Si is not an output shape and
+//! 2) no any shape is generated or modified (produced) from shape Si:
+//! R(Si) == 1 ==> Si != Tj, G(Si) == 0, M(Si) == 0.
+//!
+//! No any shape could be generated and modified from the same shape
+//! simultaneously: sets G(Si) and M(Si) are not intersected
+//! (G(Si) ^ M(Si) == 0).
+//!
+//! Each output shape should be:
+//! 1) an input shape or
+//! 2) generated or modified from an input shape (even generated from the
+//!   implicit null shape if necessary):
+//!   Tj == Si V (exists Si that Tj <= G(Si) U M(Si)).
+//!
+//! Recommendations to choose between relations 'generated' and 'modified':
+//! 1) a shape is generated from input shapes if it dimension is greater or
+//!   smaller than the dimensions of the input shapes;
+//! 2) a shape is generated from input shapes if these shapes are also output
+//!   shapes;
+//! 3) a shape is generated from input shapes of the same dimension if it is
+//!   produced by joining shapes generated from these shapes;
+//! 4) a shape is modified from an input shape if it replaces the input shape by
+//!   changes of the location, the tolerance, the bounds of the parametrical
+//!   space (the faces for a solid), the parametrization and/or by applying of
+//!   an approximation;
+//! 5) a shape is modified from input shapes of the same dimension if it is
+//!   produced by joining shapes modified from these shapes.
+//!
+//! Two sequential histories:
+//! - one history (H12) of shapes S1, ..., Sm to shapes T1, ..., Tn and
+//! - another history (H23) of shapes T1, ..., Tn to shapes Q1, ..., Ql
+//! could be merged to the single history (H13) of shapes S1, ..., Sm to shapes
+//! Q1, ..., Ql.
+//!
+//! During the merge:
+//! 1) if shape Tj is generated from shape Si then each shape generated or
+//!   modified from shape Tj is considered as a shape generated from shape Si
+//!   among shapes Q1, ..., Ql:
+//!   Tj <= G12(Si), Qk <= G23(Tj) U M23(Tj) ==> Qk <= G13(Si).
+//! 2) if shape Tj is modified from shape Si, shape Qk is generated from shape
+//!   Tj then shape Qk is considered as a shape generated from shape Si among
+//!   shapes Q1, ..., Ql:
+//!   Tj <= M12(Si), Qk <= G23(Tj) ==> Qk <= G13(Si);
+//! 3) if shape Tj is modified from shape Si, shape Qk is modified from shape
+//!   Tj then shape Qk is considered as a shape modified from shape Si among
+//!   shapes Q1, ..., Ql:
+//!   Tj <= M12(Si), Qk <= M23(Tj) ==> Qk <= M13(Si);
+class BRepTools_History: public Standard_Transient
+{
+public:
+
+  //! The types of the historical relations.
+  enum TRelationType
+  {
+    TRelationType_Removed,
+    TRelationType_Generated,
+    TRelationType_Modified
+  };
+
+public:
+
+  //! Returns 'true' if the type of the shape is supported by the history.
+  static Standard_Boolean IsSupportedType(const TopoDS_Shape& theShape)
+  {
+    const TopAbs_ShapeEnum aType = theShape.ShapeType();
+    return aType == TopAbs_VERTEX || aType == TopAbs_EDGE ||
+      aType == TopAbs_FACE || aType == TopAbs_SOLID;
+  }
+
+public: //! Methods to set the history.
+
+  //! Set the second shape as generated one from the first shape.
+  Standard_EXPORT void AddGenerated(
+    const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated);
+
+  //! Set the second shape as modified one from the first shape.
+  Standard_EXPORT void AddModified(
+    const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified);
+
+  //! Set the shape as removed one.
+  Standard_EXPORT void Remove(const TopoDS_Shape& theRemoved);
+
+  //! Set the second shape as the only generated one from the first one.
+  Standard_EXPORT void ReplaceGenerated(
+    const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated);
+
+  //! Set the second shape as the only modified one from the first one.
+  Standard_EXPORT void ReplaceModified(
+    const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified);
+
+  //! Clears the history.
+  void Clear()
+  {
+    myShapeToModified.Clear();
+    myShapeToGenerated.Clear();
+    myRemoved.Clear();
+  }
+
+public: //! Methods to read the history.
+
+  //! Returns all shapes generated from the shape.
+  Standard_EXPORT
+  const TopTools_ListOfShape& Generated(const TopoDS_Shape& theInitial) const;
+
+  //! Returns all shapes modified from the shape.
+  Standard_EXPORT
+  const TopTools_ListOfShape& Modified(const TopoDS_Shape& theInitial) const;
+
+  //! Returns 'true' if the shape is removed.
+  Standard_EXPORT
+  Standard_Boolean IsRemoved(const TopoDS_Shape& theInitial) const;
+
+public: //! A method to merge a next history to this history.
+
+  //! Merges the next history to this history.
+  Standard_EXPORT void Merge(const Handle(BRepTools_History)& theHistory23);
+
+public:
+
+  //! Define the OCCT RTTI for the type.
+  DEFINE_STANDARD_RTTIEXT(BRepTools_History, Standard_Transient)
+
+private:
+  //! Prepares the shapes generated from the first shape to set the second one
+  //! as generated one from the first one by the addition or the replacement.
+  //! Returns 'true' on success.
+  Standard_Boolean prepareGenerated(
+    const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated);
+
+  //! Prepares the shapes modified from the first shape to set the second one
+  //! as modified one from the first one by the addition or the replacement.
+  //! Returns 'true' on success.
+  Standard_Boolean prepareModified(
+    const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified);
+
+private: //! Data to keep the history.
+
+  //! Maps each input shape to all shapes modified from it.
+  //! If an input shape is not bound to the map then
+  //! there is no shapes modified from the shape.
+  //! No any shape should be mapped to an empty list.
+  TopTools_DataMapOfShapeListOfShape myShapeToModified;
+
+  //! Maps each input shape to all shapes generated from it.
+  //! If an input shape is not bound to the map then
+  //! there is no shapes generated from the shape.
+  //! No any shape should be mapped to an empty list.
+  TopTools_DataMapOfShapeListOfShape myShapeToGenerated;
+
+  TopTools_MapOfShape myRemoved; //!< The removed shapes.
+
+private: //! Auxiliary members to read the history.
+
+  //! An auxiliary empty list.
+  static const TopTools_ListOfShape myEmptyList;
+
+  //! A method to export the auxiliary list.
+  Standard_EXPORT static const TopTools_ListOfShape& emptyList();
+
+private:
+
+  //! Auxiliary messages.
+  static const char* myMsgUnsupportedType;
+  static const char* myMsgGeneratedAndRemoved;
+  static const char* myMsgModifiedAndRemoved;
+  static const char* myMsgGeneratedAndModified;
+};
+
+#endif // _BRepTools_History_HeaderFile
index 1bd4daa492792b7eb7008d891b99bdc6567d2e25..019937817dcace96b49447cb4a53cf462216efc6 100644 (file)
@@ -4,6 +4,8 @@ BRepTools_DataMapIteratorOfMapOfVertexPnt2d.hxx
 BRepTools_Debug.cxx
 BRepTools_GTrsfModification.cxx
 BRepTools_GTrsfModification.hxx
+BRepTools_History.cxx
+BRepTools_History.hxx
 BRepTools_MapOfVertexPnt2d.hxx
 BRepTools_Modification.cxx
 BRepTools_Modification.hxx