0031587: Modeling Data - add BRepTools::RemoveInternals() removing internal sub-shape...
[occt.git] / src / BRepTools / BRepTools_History.hxx
1 // Created on: 2017-04-21
2 // Created by: Alexander Bobkov
3 // Copyright (c) 2017 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _BRepTools_History_HeaderFile
17 #define _BRepTools_History_HeaderFile
18
19 #include <NCollection_Handle.hxx>
20 #include <TopExp.hxx>
21 #include <TopTools_DataMapOfShapeListOfShape.hxx>
22 #include <TopTools_MapOfShape.hxx>
23
24 class BRepTools_History;
25 DEFINE_STANDARD_HANDLE(BRepTools_History, Standard_Transient)
26
27 //! The history keeps the following relations between the input shapes
28 //! (S1, ..., Sm) and output shapes (T1, ..., Tn):
29 //! 1) an output shape Tj is generated from an input shape Si: Tj <= G(Si);
30 //! 2) a output shape Tj is modified from an input shape Si: Tj <= M(Si);
31 //! 3) an input shape (Si) is removed: R(Si) == 1.
32 //!
33 //! The relations are kept only for shapes of types vertex, edge, face, and
34 //! solid.
35 //!
36 //! The last relation means that:
37 //! 1) shape Si is not an output shape and
38 //! 2) no any shape is modified (produced) from shape Si:
39 //! R(Si) == 1 ==> Si != Tj, M(Si) == 0.
40 //!
41 //! It means that the input shape cannot be removed and modified
42 //! simultaneously. However, the shapes may be generated from the
43 //! removed shape. For instance, in Fillet operation the edges
44 //! generate faces and then are removed.
45 //!
46 //! No any shape could be generated and modified from the same shape
47 //! simultaneously: sets G(Si) and M(Si) are not intersected
48 //! (G(Si) ^ M(Si) == 0).
49 //!
50 //! Each output shape should be:
51 //! 1) an input shape or
52 //! 2) generated or modified from an input shape (even generated from the
53 //!   implicit null shape if necessary):
54 //!   Tj == Si V (exists Si that Tj <= G(Si) U M(Si)).
55 //!
56 //! Recommendations to choose between relations 'generated' and 'modified':
57 //! 1) a shape is generated from input shapes if it dimension is greater or
58 //!   smaller than the dimensions of the input shapes;
59 //! 2) a shape is generated from input shapes if these shapes are also output
60 //!   shapes;
61 //! 3) a shape is generated from input shapes of the same dimension if it is
62 //!   produced by joining shapes generated from these shapes;
63 //! 4) a shape is modified from an input shape if it replaces the input shape by
64 //!   changes of the location, the tolerance, the bounds of the parametric
65 //!   space (the faces for a solid), the parametrization and/or by applying of
66 //!   an approximation;
67 //! 5) a shape is modified from input shapes of the same dimension if it is
68 //!   produced by joining shapes modified from these shapes.
69 //!
70 //! Two sequential histories:
71 //! - one history (H12) of shapes S1, ..., Sm to shapes T1, ..., Tn and
72 //! - another history (H23) of shapes T1, ..., Tn to shapes Q1, ..., Ql
73 //! could be merged to the single history (H13) of shapes S1, ..., Sm to shapes
74 //! Q1, ..., Ql.
75 //!
76 //! During the merge:
77 //! 1) if shape Tj is generated from shape Si then each shape generated or
78 //!   modified from shape Tj is considered as a shape generated from shape Si
79 //!   among shapes Q1, ..., Ql:
80 //!   Tj <= G12(Si), Qk <= G23(Tj) U M23(Tj) ==> Qk <= G13(Si).
81 //! 2) if shape Tj is modified from shape Si, shape Qk is generated from shape
82 //!   Tj then shape Qk is considered as a shape generated from shape Si among
83 //!   shapes Q1, ..., Ql:
84 //!   Tj <= M12(Si), Qk <= G23(Tj) ==> Qk <= G13(Si);
85 //! 3) if shape Tj is modified from shape Si, shape Qk is modified from shape
86 //!   Tj then shape Qk is considered as a shape modified from shape Si among
87 //!   shapes Q1, ..., Ql:
88 //!   Tj <= M12(Si), Qk <= M23(Tj) ==> Qk <= M13(Si);
89 class BRepTools_History: public Standard_Transient
90 {
91 public: //! @name Constructors for History creation
92
93   //! Empty constructor
94   BRepTools_History() {}
95
96   //! Template constructor for History creation from the algorithm having
97   //! standard history methods such as IsDeleted(), Modified() and Generated().
98   //! @param theArguments [in] Arguments of the algorithm;
99   //! @param theAlgo [in] The algorithm.
100   template <class TheAlgo>
101   BRepTools_History(const TopTools_ListOfShape& theArguments,
102                     TheAlgo& theAlgo)
103   {
104     // Map all argument shapes to save them in history
105     TopTools_IndexedMapOfShape anArgsMap;
106     TopTools_ListIteratorOfListOfShape aIt(theArguments);
107     for (; aIt.More(); aIt.Next())
108     {
109       if (!aIt.Value().IsNull())
110         TopExp::MapShapes(aIt.Value(), anArgsMap);
111     }
112
113     // Copy the history for all supported shapes from the algorithm
114     Standard_Integer i, aNb = anArgsMap.Extent();
115     for (i = 1; i <= aNb; ++i)
116     {
117       const TopoDS_Shape& aS = anArgsMap(i);
118       if (!IsSupportedType(aS))
119         continue;
120
121       if (theAlgo.IsDeleted(aS))
122         Remove(aS);
123
124       // Check Modified
125       const TopTools_ListOfShape& aModified = theAlgo.Modified(aS);
126       for (aIt.Initialize(aModified); aIt.More(); aIt.Next())
127         AddModified(aS, aIt.Value());
128
129       // Check Generated
130       const TopTools_ListOfShape& aGenerated = theAlgo.Generated(aS);
131       for (aIt.Initialize(aGenerated); aIt.More(); aIt.Next())
132         AddGenerated(aS, aIt.Value());
133     }
134   }
135
136 public:
137
138   //! The types of the historical relations.
139   enum TRelationType
140   {
141     TRelationType_Removed,
142     TRelationType_Generated,
143     TRelationType_Modified
144   };
145
146 public:
147
148   //! Returns 'true' if the type of the shape is supported by the history.
149   static Standard_Boolean IsSupportedType(const TopoDS_Shape& theShape)
150   {
151     const TopAbs_ShapeEnum aType = theShape.ShapeType();
152     return aType == TopAbs_VERTEX || aType == TopAbs_EDGE ||
153       aType == TopAbs_FACE || aType == TopAbs_SOLID;
154   }
155
156 public: //! Methods to set the history.
157
158   //! Set the second shape as generated one from the first shape.
159   Standard_EXPORT void AddGenerated(
160     const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated);
161
162   //! Set the second shape as modified one from the first shape.
163   Standard_EXPORT void AddModified(
164     const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified);
165
166   //! Set the shape as removed one.
167   Standard_EXPORT void Remove(const TopoDS_Shape& theRemoved);
168
169   //! Set the second shape as the only generated one from the first one.
170   Standard_EXPORT void ReplaceGenerated(
171     const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated);
172
173   //! Set the second shape as the only modified one from the first one.
174   Standard_EXPORT void ReplaceModified(
175     const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified);
176
177   //! Clears the history.
178   void Clear()
179   {
180     myShapeToModified.Clear();
181     myShapeToGenerated.Clear();
182     myRemoved.Clear();
183   }
184
185 public: //! Methods to read the history.
186
187   //! Returns all shapes generated from the shape.
188   Standard_EXPORT
189   const TopTools_ListOfShape& Generated(const TopoDS_Shape& theInitial) const;
190
191   //! Returns all shapes modified from the shape.
192   Standard_EXPORT
193   const TopTools_ListOfShape& Modified(const TopoDS_Shape& theInitial) const;
194
195   //! Returns 'true' if the shape is removed.
196   Standard_EXPORT
197   Standard_Boolean IsRemoved(const TopoDS_Shape& theInitial) const;
198
199   //! Returns 'true' if there any shapes with Generated elements present
200   Standard_Boolean HasGenerated() const { return !myShapeToGenerated.IsEmpty(); }
201
202   //! Returns 'true' if there any Modified shapes present
203   Standard_Boolean HasModified() const { return !myShapeToModified.IsEmpty(); }
204
205   //! Returns 'true' if there any removed shapes present
206   Standard_Boolean HasRemoved() const { return !myRemoved.IsEmpty(); }
207
208 public: //! A method to merge a next history to this history.
209
210   //! Merges the next history to this history.
211   Standard_EXPORT void Merge(const Handle(BRepTools_History)& theHistory23);
212
213   //! Merges the next history to this history.
214   Standard_EXPORT void Merge(const BRepTools_History& theHistory23);
215
216   //! Template method for merging history of the algorithm having standard
217   //! history methods such as IsDeleted(), Modified() and Generated()
218   //! into current history object.
219   //! @param theArguments [in] Arguments of the algorithm;
220   //! @param theAlgo [in] The algorithm.
221   template<class TheAlgo>
222   void Merge(const TopTools_ListOfShape& theArguments,
223              TheAlgo& theAlgo)
224   {
225     // Create new history object from the given algorithm and merge it into this.
226     Merge(BRepTools_History(theArguments, theAlgo));
227   }
228
229 public: //! A method to dump a history
230
231   //! Prints the brief description of the history into a stream
232   void Dump(Standard_OStream& theS)
233   {
234     theS << "History contains:\n";
235     theS << " - " << myRemoved.Extent() << " Deleted shapes;\n";
236     theS << " - " << myShapeToModified.Extent() << " Modified shapes;\n";
237     theS << " - " << myShapeToGenerated.Extent() << " Generated shapes.\n";
238   }
239
240 public:
241
242   //! Define the OCCT RTTI for the type.
243   DEFINE_STANDARD_RTTIEXT(BRepTools_History, Standard_Transient)
244
245 private:
246   //! Prepares the shapes generated from the first shape to set the second one
247   //! as generated one from the first one by the addition or the replacement.
248   //! Returns 'true' on success.
249   Standard_Boolean prepareGenerated(
250     const TopoDS_Shape& theInitial, const TopoDS_Shape& theGenerated);
251
252   //! Prepares the shapes modified from the first shape to set the second one
253   //! as modified one from the first one by the addition or the replacement.
254   //! Returns 'true' on success.
255   Standard_Boolean prepareModified(
256     const TopoDS_Shape& theInitial, const TopoDS_Shape& theModified);
257
258 private: //! Data to keep the history.
259
260   //! Maps each input shape to all shapes modified from it.
261   //! If an input shape is not bound to the map then
262   //! there is no shapes modified from the shape.
263   //! No any shape should be mapped to an empty list.
264   TopTools_DataMapOfShapeListOfShape myShapeToModified;
265
266   //! Maps each input shape to all shapes generated from it.
267   //! If an input shape is not bound to the map then
268   //! there is no shapes generated from the shape.
269   //! No any shape should be mapped to an empty list.
270   TopTools_DataMapOfShapeListOfShape myShapeToGenerated;
271
272   TopTools_MapOfShape myRemoved; //!< The removed shapes.
273
274 private: //! Auxiliary members to read the history.
275
276   //! An auxiliary empty list.
277   static const TopTools_ListOfShape myEmptyList;
278
279   //! A method to export the auxiliary list.
280   Standard_EXPORT static const TopTools_ListOfShape& emptyList();
281
282 private:
283
284   //! Auxiliary messages.
285   static const char* myMsgUnsupportedType;
286   static const char* myMsgGeneratedAndRemoved;
287   static const char* myMsgModifiedAndRemoved;
288   static const char* myMsgGeneratedAndModified;
289 };
290
291 #endif // _BRepTools_History_HeaderFile