Salome HOME
Add tests to improve coverage of Filters plugin.
[modules/shaper.git] / src / GeomAlgoImpl / GEOMAlgo_Splitter.cxx
1 // Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include <GEOMAlgo_Splitter.hxx>
24
25 #include <TopAbs_ShapeEnum.hxx>
26 #include <TopExp.hxx>
27 #include <TopoDS_Shape.hxx>
28 #include <TopoDS_Compound.hxx>
29 #include <TopoDS_Iterator.hxx>
30
31 #include <BRep_Builder.hxx>
32
33 static 
34   void TreatCompound(const TopoDS_Shape& aC, 
35                      NCollection_List<TopoDS_Shape>& aLSX);
36
37 //=======================================================================
38 //function : 
39 //purpose  : 
40 //=======================================================================
41 GEOMAlgo_Splitter::GEOMAlgo_Splitter()
42 :
43   BOPAlgo_Builder(),
44   myTools(myAllocator),
45   myMapTools(100, myAllocator)
46 {
47   myLimit=TopAbs_SHAPE;
48   myLimitMode=0;
49 }
50 //=======================================================================
51 //function : 
52 //purpose  : 
53 //=======================================================================
54 GEOMAlgo_Splitter::GEOMAlgo_Splitter
55   (const Handle(NCollection_BaseAllocator)& theAllocator)
56 :
57   BOPAlgo_Builder(theAllocator),
58   myTools(myAllocator),
59   myMapTools(100, myAllocator)
60 {
61   myLimit=TopAbs_SHAPE;
62   myLimitMode=0;
63 }
64 //=======================================================================
65 //function : ~
66 //purpose  : 
67 //=======================================================================
68 GEOMAlgo_Splitter::~GEOMAlgo_Splitter()
69 {
70 }
71 //=======================================================================
72 //function : AddTool
73 //purpose  : 
74 //=======================================================================
75 void GEOMAlgo_Splitter::AddTool(const TopoDS_Shape& theShape)
76 {
77   if (myMapTools.Add(theShape)) {
78     myTools.Append(theShape);
79     //
80     AddArgument(theShape);
81   }
82 }
83 //=======================================================================
84 //function : Tools
85 //purpose  : 
86 //=======================================================================
87 const NCollection_List<TopoDS_Shape>& GEOMAlgo_Splitter::Tools()const
88 {
89   return myTools;
90 }
91 //=======================================================================
92 //function : SetLimit
93 //purpose  : 
94 //=======================================================================
95 void GEOMAlgo_Splitter::SetLimit(const TopAbs_ShapeEnum aLimit) 
96 {
97   myLimit=aLimit;
98 }
99 //=======================================================================
100 //function : Limit
101 //purpose  : 
102 //=======================================================================
103 TopAbs_ShapeEnum GEOMAlgo_Splitter::Limit()const
104 {
105   return myLimit;
106 }
107 //=======================================================================
108 //function : SetLimitMode
109 //purpose  : 
110 //=======================================================================
111 void GEOMAlgo_Splitter::SetLimitMode(const Standard_Integer aMode)
112 {
113   myLimitMode=aMode;
114 }
115 //=======================================================================
116 //function : LimitMode
117 //purpose  : 
118 //=======================================================================
119 Standard_Integer GEOMAlgo_Splitter::LimitMode()const
120 {
121   return myLimitMode;
122 }
123 //=======================================================================
124 //function : Clear
125 //purpose  : 
126 //=======================================================================
127 void GEOMAlgo_Splitter::Clear()
128 {
129   myTools.Clear();
130   myMapTools.Clear();
131   myLimit=TopAbs_SHAPE;
132   BOPAlgo_Builder::Clear();
133 }
134 //=======================================================================
135 //function : BuildResult
136 //purpose  : 
137 //=======================================================================
138 void GEOMAlgo_Splitter::BuildResult(const TopAbs_ShapeEnum theType)
139 {
140   TopAbs_ShapeEnum aType;
141   BRep_Builder aBB;
142   NCollection_Map<TopoDS_Shape> aM;
143   NCollection_List<TopoDS_Shape>::Iterator aIt, aItIm;
144   //
145   aIt.Initialize(myArguments);
146   for (; aIt.More(); aIt.Next()) {
147     const TopoDS_Shape& aS=aIt.Value();
148     aType=aS.ShapeType();
149     if (aType==theType && !myMapTools.Contains(aS)) {
150       if (myImages.IsBound(aS)) {
151         const NCollection_List<TopoDS_Shape>& aLSIm=myImages.Find(aS);
152         aItIm.Initialize(aLSIm);
153         for (; aItIm.More(); aItIm.Next()) {
154           const TopoDS_Shape& aSIm=aItIm.Value();
155           if (aM.Add(aSIm)) {
156             aBB.Add(myShape, aSIm);
157           }
158         }
159       }
160       else {
161         if (aM.Add(aS)) {
162           aBB.Add(myShape, aS);
163         }
164       }
165     }
166   }
167 }
168 //=======================================================================
169 //function : PostTreat
170 //purpose  : 
171 //=======================================================================
172 void GEOMAlgo_Splitter::PostTreat()
173 {
174   if (myLimit!=TopAbs_SHAPE) {
175     Standard_Integer i, aNbS;
176     BRep_Builder aBB;
177     TopoDS_Compound aC;
178     TopTools_IndexedMapOfShape aMx;
179     //
180     aBB.MakeCompound(aC);
181     //
182     TopExp::MapShapes(myShape, myLimit, aMx);
183     aNbS=aMx.Extent();
184     for (i=1; i<=aNbS; ++i) {
185       const TopoDS_Shape& aS=aMx(i);
186       aBB.Add(aC, aS);
187     }
188     if (myLimitMode) {
189       Standard_Integer iType, iLimit, iTypeX;
190       TopAbs_ShapeEnum aType, aTypeX;
191       NCollection_List<TopoDS_Shape> aLSP, aLSX;
192       NCollection_List<TopoDS_Shape>::Iterator aIt, aItX, aItIm;
193       NCollection_Map<TopoDS_Shape>  aM;
194       //
195       iLimit=(Standard_Integer)myLimit; 
196       //
197       // 1. Collect the shapes to process aLSP
198       aIt.Initialize(myArguments);
199       for (; aIt.More(); aIt.Next()) {
200         const TopoDS_Shape& aS=aIt.Value();
201         if (myMapTools.Contains(aS)) {
202           continue;
203         }
204         //
205         aType=aS.ShapeType();
206         iType=(Standard_Integer)aType;
207         //
208         if (iType>iLimit) {
209           aLSP.Append(aS);
210         }
211         //
212         else if (aType==TopAbs_COMPOUND) {
213           aLSX.Clear();
214           //
215           TreatCompound(aS, aLSX);
216           //
217           aItX.Initialize(aLSX);
218           for (; aItX.More(); aItX.Next()) {
219             const TopoDS_Shape& aSX=aItX.Value();
220             aTypeX=aSX.ShapeType();
221             iTypeX=(Standard_Integer)aTypeX;
222             //
223             if (iTypeX>iLimit) {
224               aLSP.Append(aSX);
225             }
226           }
227         }
228       }// for (; aIt.More(); aIt.Next()) {
229       //
230       aMx.Clear();
231       TopExp::MapShapes(aC, aMx);
232        // 2. Add them to aC
233       aIt.Initialize(aLSP);
234       for (; aIt.More(); aIt.Next()) {
235         const TopoDS_Shape& aS=aIt.Value();
236         if (myImages.IsBound(aS)) {
237           const NCollection_List<TopoDS_Shape>& aLSIm=myImages.Find(aS);
238           aItIm.Initialize(aLSIm);
239           for (; aItIm.More(); aItIm.Next()) {
240             const TopoDS_Shape& aSIm=aItIm.Value();
241             if (aM.Add(aSIm)) {
242               if (!aMx.Contains(aSIm)) {
243                 aBB.Add(aC, aSIm);
244               }
245             }
246           }
247         }
248         else {
249           if (aM.Add(aS)) {
250             if (!aMx.Contains(aS)) {
251               aBB.Add(aC, aS);
252             }
253           }
254         }
255       }
256     }// if (myLimitMode) {
257     myShape=aC;
258   }//if (myLimit!=TopAbs_SHAPE) {
259   //
260   Standard_Integer aNbS;
261   TopoDS_Iterator aIt;
262   NCollection_List<TopoDS_Shape> aLS;
263   //
264   aIt.Initialize(myShape);
265   for (; aIt.More(); aIt.Next()) {
266     const TopoDS_Shape& aS=aIt.Value();
267     aLS.Append(aS);
268   }
269   aNbS=aLS.Extent();
270   if (aNbS==1) {
271     myShape=aLS.First();
272   }
273   //
274   BOPAlgo_Builder::PostTreat();
275 }
276 //=======================================================================
277 //function : TreatCompound
278 //purpose  : 
279 //=======================================================================
280 void TreatCompound(const TopoDS_Shape& aC1, 
281                    NCollection_List<TopoDS_Shape>& aLSX)
282 {
283   Standard_Integer aNbC1;
284   TopAbs_ShapeEnum aType;
285   NCollection_List<TopoDS_Shape> aLC, aLC1;
286   NCollection_List<TopoDS_Shape>::Iterator aIt, aIt1;
287   TopoDS_Iterator aItC;
288   //
289   aLC.Append (aC1);
290   while(1) {
291     aLC1.Clear();
292     aIt.Initialize(aLC);
293     for (; aIt.More(); aIt.Next()) {
294       const TopoDS_Shape& aC=aIt.Value(); //C is compound
295       //
296       aItC.Initialize(aC);
297       for (; aItC.More(); aItC.Next()) {
298         const TopoDS_Shape& aS=aItC.Value();
299         aType=aS.ShapeType();
300         if (aType==TopAbs_COMPOUND) {
301           aLC1.Append(aS);
302         }
303         else {
304           aLSX.Append(aS);
305         }
306       }
307     }
308     //
309     aNbC1=aLC1.Extent();
310     if (!aNbC1) {
311       break;
312     }
313     //
314     aLC.Clear();
315     aIt.Initialize(aLC1);
316     for (; aIt.More(); aIt.Next()) {
317       const TopoDS_Shape& aSC=aIt.Value();
318       aLC.Append(aSC);
319     }
320   }// while(1)
321 }
322 //
323 // myErrorStatus
324 // 
325 // 0  - Ok
326 // 1  - The object is just initialized
327 // 2  - PaveFiller is failed
328 // 10 - No shapes to process
329 // 30 - SolidBuilder failed