0028245: Result of Cells Builder algorithm becomes invalid after removal of internal...
[occt.git] / src / BOPAlgo / BOPAlgo_CellsBuilder.hxx
1 // Created by: Eugeny MALTCHIKOV
2 // Copyright (c) 2015 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #ifndef _BOPAlgo_CellsBuilder_HeaderFile
17 #define _BOPAlgo_CellsBuilder_HeaderFile
18
19 #include <Standard_DefineAlloc.hxx>
20 #include <Standard_Handle.hxx>
21 #include <Standard_OStream.hxx>
22
23 #include <TopoDS_Shape.hxx>
24
25 #include <TopAbs_ShapeEnum.hxx>
26 #include <TopTools_MapOfShape.hxx>
27 #include <BOPAlgo_Builder.hxx>
28
29 #include <BOPCol_ListOfShape.hxx>
30 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
31 #include <BOPCol_DataMapOfIntegerListOfShape.hxx>
32 #include <BOPCol_DataMapOfShapeInteger.hxx>
33 #include <BOPCol_DataMapOfShapeShape.hxx>
34
35 //!
36 //! The algorithm is based on the General Fuse algorithm (GFA). The result of
37 //! GFA is all split parts of the Arguments.<br>
38 //!
39 //! The purpose of this algorithm is to provide the result with the content of:<br>
40 //! 1. Cells (parts) defined by the user;<br>
41 //! 2. Internal boundaries defined by the user.<br>
42 //!
43 //! In other words the algorithm should provide the possibility for the user
44 //! to add or remove any part to (from) result and remove any internal boundaries
45 //! between parts.<br>
46 //!
47 //! Requirements for the Data:<br>
48 //! All the requirements of GFA for the DATA are inherited in this algorithm -
49 //! The arguments could be of any type (dimension) and should be valid in terms of
50 //! BRepCheck_Analyzer and BOPAlgo_ArgumentAnalyzer.<br>
51 //!
52 //! Results:<br>
53 //! The result of the algorithm is compound containing selected parts of
54 //! the basic types (VERTEX, EDGE, FACE or SOLID). The default result
55 //! is empty compound. It is possible to add any split part to the result
56 //! by using the methods AddToRessult() and AddAllToResult().
57 //! It is also possible to remove any part from the result by using methods
58 //! RemoveFromResult() and RemoveAllFromResult().
59 //! The method RemoveAllFromResult() is also suitable for clearing the result.<br>
60 //!
61 //! To remove Internal boundaries it is necessary to set the same material to the
62 //! parts between which the boundaries should be removed and call the method
63 //! RemoveInternalBoundaries(). The material should not be equal to 0, as this is
64 //! default material value. The boundaries between parts with this value
65 //! will not be removed.
66 //! One part cannot be added with the different materials.
67 //! It is also possible to remove the boundaries during combining the result.
68 //! To do this it is necessary to set the material for parts (not equal to 0)
69 //! and set the flag bUpdate to TRUE.
70 //! For the arguments of the types FACE or EDGE it is recommended
71 //! to remove the boundaries in the end when the result is completely built.
72 //! It will help to avoid self-intersections in the result.<br>
73 //! Note, that if the result contains the parts with same material but of different
74 //! dimension the boundaries between such parts will not be removed. Currently,
75 //! the removal of the internal boundaries between multi-dimensional shapes is not supported.<br>
76 //!
77 //! It is possible to create typed Containers from the parts added to result by using
78 //! method MakeContainers(). The type of the containers will depend on the type of
79 //! the arguments: WIRES for EEDGE, SHELLS for FACES and COMPSOLIDS for SOLIDS.
80 //! The result will be compound containing containers.
81 //! Adding of the parts to such result will not update containers. The result
82 //! compound will contain the containers and new added parts (of basic type).
83 //! Removing of the parts from such result may affect some containers if
84 //! the parts that should be removed is in container. In this case this container
85 //! will be rebuilt without that part.<br>
86 //!
87 //! History:<br>
88 //! The algorithm supports history information for basic types of the shapes -
89 //! VERTEX, EDGE, FACE. This information available through the methods
90 //! IsDeleted() and Modified().<br>
91 //! In DRAW Test Harness it is available through the same
92 //! commands as for Boolean Operations (bmodified, bgenerated and bisdeleted).<br>
93 //! There could be Generated shapes only after removing of the internal boundaries
94 //! between faces and edges, i.e. after using ShapeUpgrade_UnifySameDomain tool.<br>
95 //!
96 //! The algorithm can return the following Error Statuses:
97 //! - Error status acquired in the General Fuse algorithm.
98 //! The Error status can be checked with HasErrors() method.
99 //! If the Error status is not equal to zero, the result cannot be trustworthy.
100 //!
101 //! The algorithm can set the following Warning Statuses:
102 //! - Warning status acquired in the General Fuse algorithm;
103 //! - BOPAlgo_AlertRemovalOfIBForMDimShapes
104 //! - BOPAlgo_AlertRemovalOfIBForFacesFailed
105 //! - BOPAlgo_AlertRemovalOfIBForEdgesFailed
106 //! - BOPAlgo_AlertRemovalOfIBForSolidsFailed
107 //!
108 //! The Warning status can be checked with HasWarnings() method or
109 //! printed with the DumpWarnings() method. If warnings are recorded,
110 //! the result may be not as expected.<br>
111 //!
112 //! Examples:<br>
113 //! 1. API<br>
114 //! BOPAlgo_CellsBuilder aCBuilder;<br>
115 //! BOPCol_ListOfShape aLS = ...; // arguments<br>
116 //! /* parallel or single mode (the default value is FALSE)*/<br>
117 //! Standard_Boolean bRunParallel = Standard_False;<br>
118 //! /* fuzzy option (default value is 0)*/<br>
119 //! Standard_Real aTol = 0.0;<br>
120 //! //<br>
121 //! aCBuilder.SetArguments(aLS);<br>
122 //! aCBuilder.SetRunParallel(bRunParallel);<br>
123 //! aCBuilder.SetFuzzyValue(aTol);<br>
124 //! //<br>
125 //! aCBuilder.Perform();<br>
126 //! if (aCBuilder.HasErrors()) { // check error status<br>
127 //!   return;<br>
128 //! }<br>
129 //! /* empty compound, as nothing has been added yet */<br>
130 //! const TopoDS_Shape& aRes = aCBuilder.Shape();<br>
131 //! /* all split parts */<br>
132 //! const TopoDS_Shape& aRes = aCBuilder.GetAllParts();<br>
133 //! //<br>
134 //! BOPCol_ListOfShape aLSToTake = ...; // parts of these arguments will be taken into result<br>
135 //! BOPCol_ListOfShape aLSToAvoid = ...; // parts of these arguments will not be taken into result<br>
136 //! //<br>
137 //! /* defines the material common for the cells, i.e. 
138 //!    the boundaries between cells with the same material
139 //!    will be removed.<br>
140 //!    By default it is set to 0. Thus, to remove some boundary
141 //!    the value of this variable should not be equal to 0 */<br>
142 //! Standard_Integer iMaterial = ...;<br>
143 //! /* defines whether to update the result right now or not */<br>
144 //! Standard_Boolean bUpdate = ...;<br>
145 //! // adding to result<br>
146 //! aCBuilder.AddToResult(aLSToTake, aLSToAvoid, iMaterial, bUpdate);<br>
147 //! aR = aCBuilder.Shape(); // the result<br>
148 //! // removing of the boundaries (should be called only if bUpdate is false)<br>
149 //! aCBuilder.RemoveInternalBoundaries();<br>
150 //! //<br>
151 //! // removing from result<br>
152 //! aCBuilder.AddAllToResult();<br>
153 //! aCBuilder.RemoveFromResult(aLSToTake, aLSToAvoid);<br>
154 //! aR = aCBuilder.Shape(); // the result<br>
155 //! <br>
156 //!
157 //! 2. DRAW Test Harness<br>
158 //! psphere s1 15<br>
159 //! psphere s2 15<br>
160 //! psphere s3 15<br>
161 //! ttranslate s1 0 0 10<br>
162 //! ttranslate s2 20 0 10<br>
163 //! ttranslate s3 10 0 0<br>
164 //! \# adding arguments<br>
165 //! bclearobjects; bcleartools<br>
166 //! baddobjects s1 s2 s3<br>
167 //! \# intersection<br>
168 //! bfillds<br>
169 //! \# rx will contain all split parts<br>
170 //! bcbuild rx<br>
171 //! \# add to result the part that is common for all three spheres<br>
172 //! bcadd res s1 1 s2 1 s3 1 -m 1<br>
173 //! \# add to result the part that is common only for first and third spheres<br>
174 //! bcadd res s1 1 s2 0 s3 1 -m 1<br>
175 //! \# remove internal boundaries<br>
176 //! bcremoveint res<br>
177 //!
178 class BOPAlgo_CellsBuilder : public BOPAlgo_Builder
179 {
180  public:
181
182   DEFINE_STANDARD_ALLOC
183
184   Standard_EXPORT BOPAlgo_CellsBuilder();
185
186   Standard_EXPORT BOPAlgo_CellsBuilder(const Handle(NCollection_BaseAllocator)& theAllocator);
187
188   Standard_EXPORT virtual ~BOPAlgo_CellsBuilder();
189
190   //! Redefined method Clear - clears the contents.
191   Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
192
193   //! Adding the parts to result.<br>
194   //! The parts are defined by two lists of shapes:<br>
195   //! <theLSToTake> defines the arguments which parts should be taken into result;<br>
196   //! <theLSToAvoid> defines the arguments which parts should not be taken into result;<br>
197   //! To be taken into result the part must be IN for all shapes from the list
198   //! <theLSToTake> and must be OUT of all shapes from the list <theLSToAvoid>.<br>
199   //! 
200   //! To remove internal boundaries between any cells in the result
201   //! <theMaterial> variable should be used. The boundaries between
202   //! cells with the same material will be removed. Default value is 0.<br>
203   //! Thus, to remove any boundary the value of this variable should not be equal to 0.<br>
204   //! <theUpdate> parameter defines whether to remove boundaries now or not.
205   Standard_EXPORT void AddToResult(const BOPCol_ListOfShape& theLSToTake,
206                                    const BOPCol_ListOfShape& theLSToAvoid,
207                                    const Standard_Integer theMaterial = 0,
208                                    const Standard_Boolean theUpdate = Standard_False);
209
210   //! Add all split parts to result.<br>
211   //! <theMaterial> defines the removal of internal boundaries;<br>
212   //! <theUpdate> parameter defines whether to remove boundaries now or not.
213   Standard_EXPORT void AddAllToResult(const Standard_Integer theMaterial = 0,
214                                       const Standard_Boolean theUpdate = Standard_False);
215
216   //! Removing the parts from result.<br>
217   //! The parts are defined by two lists of shapes:<br>
218   //! <theLSToTake> defines the arguments which parts should be removed from result;<br>
219   //! <theLSToAvoid> defines the arguments which parts should not be removed from result.<br>
220   //! To be removed from the result the part must be IN for all shapes from the list
221   //! <theLSToTake> and must be OUT of all shapes from the list <theLSToAvoid>.
222   Standard_EXPORT void RemoveFromResult(const BOPCol_ListOfShape& theLSToTake,
223                                         const BOPCol_ListOfShape& theLSToAvoid);
224
225   //! Remove all parts from result.
226   Standard_EXPORT void RemoveAllFromResult();
227
228   //! Removes internal boundaries between cells with the same material.<br>
229   //! If the result contains the cells with same material but of different dimension
230   //! the removal of internal boundaries between these cells will not be performed.<br>
231   //! In case of some errors during the removal the method will set the appropriate warning 
232   //! status - use GetReport() to access them.
233   Standard_EXPORT void RemoveInternalBoundaries();
234
235   //! Get all split parts.
236   Standard_EXPORT const TopoDS_Shape& GetAllParts() const;
237
238   //! Makes the Containers of proper type from the parts added to result.
239   Standard_EXPORT void MakeContainers();
240
241   //! Returns the list of shapes generated from the shape theS.
242   Standard_EXPORT virtual const TopTools_ListOfShape& Modified(const TopoDS_Shape& theS) Standard_OVERRIDE;
243   
244   //! Returns true if the shape theS has been deleted.
245   Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& theS) Standard_OVERRIDE;
246
247  protected:
248
249    //! Redefined method Prepare - no need to prepare history
250   //! information on the default result as it is empty compound.
251   Standard_EXPORT virtual void Prepare() Standard_OVERRIDE;
252
253   //! Redefined method PerformInternal1 - makes all split parts,
254   //! nullifies the result <myShape>, and index all parts.
255   Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF) Standard_OVERRIDE;
256
257   //! Indexes the parts for quick access to the arguments.
258   Standard_EXPORT void IndexParts();
259
260   //! Looking for the parts defined by two lists.
261   Standard_EXPORT void FindParts(const BOPCol_ListOfShape& theLSToTake,
262                                  const BOPCol_ListOfShape& theLSToAvoid,
263                                  BOPCol_ListOfShape& theParts);
264
265   //! Removes internal boundaries between cells with the same material.<br>
266   //! Returns TRUE if any internal boundaries have been removed.
267   Standard_EXPORT Standard_Boolean RemoveInternals(const BOPCol_ListOfShape& theLS,
268                                                    BOPCol_ListOfShape& theLSNew,
269                                                    const TopTools_MapOfShape& theMapKeepBnd = TopTools_MapOfShape());
270
271   // fields
272   TopoDS_Shape myAllParts;
273   BOPCol_IndexedDataMapOfShapeListOfShape myIndex;
274   BOPCol_DataMapOfIntegerListOfShape myMaterials;
275   BOPCol_DataMapOfShapeInteger myShapeMaterial;
276   BOPCol_DataMapOfShapeShape myMapModified;
277 };
278
279 #endif //_BOPAlgo_CellsBuilder_HeaderFile