Salome HOME
fbd3fbfcee49797297c898c57f9e8d68274398e0
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Splitter.cxx
1 // Copyright (C) 2007-2022  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 // File:        GEOMAlgo_Splitter.cxx
24 // Created:     Thu Sep 06 10:54:04 2012
25 // Author:      Peter KURNEV
26 //              <pkv@irinox>
27 //
28
29 #include <GEOMAlgo_Splitter.hxx>
30
31 #include <TopAbs_ShapeEnum.hxx>
32
33 #include <TopoDS_Shape.hxx>
34 #include <TopoDS_Compound.hxx>
35 #include <TopoDS_Iterator.hxx>
36
37 #include <BRep_Builder.hxx>
38
39 #include <TopTools_MapOfShape.hxx>
40 #include <TopTools_ListOfShape.hxx>
41
42 #include <TopExp.hxx>
43
44 static 
45   void TreatCompound(const TopoDS_Shape& aC, 
46                      TopTools_ListOfShape& aLSX);
47
48 //=======================================================================
49 //function : 
50 //purpose  : 
51 //=======================================================================
52 GEOMAlgo_Splitter::GEOMAlgo_Splitter()
53 :
54   BOPAlgo_Builder(),
55   myTools(myAllocator),
56   myMapTools(100, myAllocator)
57 {
58   myLimit=TopAbs_SHAPE;
59   myLimitMode=0;
60 }
61 //=======================================================================
62 //function : 
63 //purpose  : 
64 //=======================================================================
65 GEOMAlgo_Splitter::GEOMAlgo_Splitter
66   (const Handle(NCollection_BaseAllocator)& theAllocator)
67 :
68   BOPAlgo_Builder(theAllocator),
69   myTools(myAllocator),
70   myMapTools(100, myAllocator)
71 {
72   myLimit=TopAbs_SHAPE;
73   myLimitMode=0;
74 }
75 //=======================================================================
76 //function : ~
77 //purpose  : 
78 //=======================================================================
79 GEOMAlgo_Splitter::~GEOMAlgo_Splitter()
80 {
81 }
82 //=======================================================================
83 //function : AddTool
84 //purpose  : 
85 //=======================================================================
86 void GEOMAlgo_Splitter::AddTool(const TopoDS_Shape& theShape)
87 {
88   if (myMapTools.Add(theShape)) {
89     myTools.Append(theShape);
90     //
91     AddArgument(theShape);
92   }
93 }
94 //=======================================================================
95 //function : Tools
96 //purpose  : 
97 //=======================================================================
98 const TopTools_ListOfShape& GEOMAlgo_Splitter::Tools()const
99 {
100   return myTools;
101 }
102 //=======================================================================
103 //function : SetLimit
104 //purpose  : 
105 //=======================================================================
106 void GEOMAlgo_Splitter::SetLimit(const TopAbs_ShapeEnum aLimit) 
107 {
108   myLimit=aLimit;
109 }
110 //=======================================================================
111 //function : Limit
112 //purpose  : 
113 //=======================================================================
114 TopAbs_ShapeEnum GEOMAlgo_Splitter::Limit()const
115 {
116   return myLimit;
117 }
118 //=======================================================================
119 //function : SetLimitMode
120 //purpose  : 
121 //=======================================================================
122 void GEOMAlgo_Splitter::SetLimitMode(const Standard_Integer aMode)
123 {
124   myLimitMode=aMode;
125 }
126 //=======================================================================
127 //function : LimitMode
128 //purpose  : 
129 //=======================================================================
130 Standard_Integer GEOMAlgo_Splitter::LimitMode()const
131 {
132   return myLimitMode;
133 }
134 //=======================================================================
135 //function : Clear
136 //purpose  : 
137 //=======================================================================
138 void GEOMAlgo_Splitter::Clear()
139 {
140   myTools.Clear();
141   myMapTools.Clear();
142   myLimit=TopAbs_SHAPE;
143   BOPAlgo_Builder::Clear();
144 }
145 //=======================================================================
146 //function : BuildResult
147 //purpose  : 
148 //=======================================================================
149 void GEOMAlgo_Splitter::BuildResult(const TopAbs_ShapeEnum theType)
150 {
151   TopAbs_ShapeEnum aType;
152   BRep_Builder aBB;
153   TopTools_MapOfShape aM;
154   TopTools_ListIteratorOfListOfShape aIt, aItIm;
155   //
156   aIt.Initialize(myArguments);
157   for (; aIt.More(); aIt.Next()) {
158     const TopoDS_Shape& aS=aIt.Value();
159     aType=aS.ShapeType();
160     if (aType==theType && !myMapTools.Contains(aS)) {
161       if (myImages.IsBound(aS)) {
162         const TopTools_ListOfShape& aLSIm=myImages.Find(aS);
163         aItIm.Initialize(aLSIm);
164         for (; aItIm.More(); aItIm.Next()) {
165           const TopoDS_Shape& aSIm=aItIm.Value();
166           if (aM.Add(aSIm)) {
167             aBB.Add(myShape, aSIm);
168           }
169         }
170       }
171       else {
172         if (aM.Add(aS)) {
173           aBB.Add(myShape, aS);
174         }
175       }
176     }
177   }
178 }
179 //=======================================================================
180 //function : PostTreat
181 //purpose  : 
182 //=======================================================================
183 void GEOMAlgo_Splitter::PostTreat()
184 {
185   if (myLimit!=TopAbs_SHAPE) {
186     Standard_Integer i, aNbS;
187     BRep_Builder aBB;
188     TopoDS_Compound aC;
189     TopTools_IndexedMapOfShape aMx;
190     //
191     aBB.MakeCompound(aC);
192     //
193     TopExp::MapShapes(myShape, myLimit, aMx);
194     aNbS=aMx.Extent();
195     for (i=1; i<=aNbS; ++i) {
196       const TopoDS_Shape& aS=aMx(i);
197       aBB.Add(aC, aS);
198     }
199     if (myLimitMode) {
200       Standard_Integer iType, iLimit, iTypeX;
201       TopAbs_ShapeEnum aType, aTypeX;
202       TopTools_ListOfShape aLSP, aLSX;
203       TopTools_ListIteratorOfListOfShape aIt, aItX, aItIm;
204       TopTools_MapOfShape  aM;
205       //
206       iLimit=(Standard_Integer)myLimit; 
207       //
208       // 1. Collect the shapes to process aLSP
209       aIt.Initialize(myArguments);
210       for (; aIt.More(); aIt.Next()) {
211         const TopoDS_Shape& aS=aIt.Value();
212         if (myMapTools.Contains(aS)) {
213           continue;
214         }
215         //
216         aType=aS.ShapeType();
217         iType=(Standard_Integer)aType;
218         //
219         if (iType>iLimit) {
220           aLSP.Append(aS);
221         }
222         //
223         else if (aType==TopAbs_COMPOUND) {
224           aLSX.Clear();
225           //
226           TreatCompound(aS, aLSX);
227           //
228           aItX.Initialize(aLSX);
229           for (; aItX.More(); aItX.Next()) {
230             const TopoDS_Shape& aSX=aItX.Value();
231             aTypeX=aSX.ShapeType();
232             iTypeX=(Standard_Integer)aTypeX;
233             //
234             if (iTypeX>iLimit) {
235               aLSP.Append(aSX);
236             }
237           }
238         }
239       }// for (; aIt.More(); aIt.Next()) {
240       //
241       aMx.Clear();
242       TopExp::MapShapes(aC, aMx);
243        // 2. Add them to aC
244       aIt.Initialize(aLSP);
245       for (; aIt.More(); aIt.Next()) {
246         const TopoDS_Shape& aS=aIt.Value();
247         if (myImages.IsBound(aS)) {
248           const TopTools_ListOfShape& aLSIm=myImages.Find(aS);
249           aItIm.Initialize(aLSIm);
250           for (; aItIm.More(); aItIm.Next()) {
251             const TopoDS_Shape& aSIm=aItIm.Value();
252             if (aM.Add(aSIm)) {
253               if (!aMx.Contains(aSIm)) {
254                 aBB.Add(aC, aSIm);
255               }
256             }
257           }
258         }
259         else {
260           if (aM.Add(aS)) {
261             if (!aMx.Contains(aS)) {
262               aBB.Add(aC, aS);
263             }
264           }
265         }
266       }
267     }// if (myLimitMode) {
268     myShape=aC;
269   }//if (myLimit!=TopAbs_SHAPE) {
270   //
271   Standard_Integer aNbS;
272   TopoDS_Iterator aIt;
273   TopTools_ListOfShape aLS;
274   //
275   aIt.Initialize(myShape);
276   for (; aIt.More(); aIt.Next()) {
277     const TopoDS_Shape& aS=aIt.Value();
278     aLS.Append(aS);
279   }
280   aNbS=aLS.Extent();
281   if (aNbS==1) {
282     myShape=aLS.First();
283   }
284   //
285   BOPAlgo_Builder::PostTreat();
286 }
287 //=======================================================================
288 //function : TreatCompound
289 //purpose  : 
290 //=======================================================================
291 void TreatCompound(const TopoDS_Shape& aC1, 
292                    TopTools_ListOfShape& aLSX)
293 {
294   Standard_Integer aNbC1;
295   TopAbs_ShapeEnum aType;
296   TopTools_ListOfShape aLC, aLC1;
297   TopTools_ListIteratorOfListOfShape aIt, aIt1;
298   TopoDS_Iterator aItC;
299   //
300   aLC.Append (aC1);
301   for(;;) {
302     aLC1.Clear();
303     aIt.Initialize(aLC);
304     for (; aIt.More(); aIt.Next()) {
305       const TopoDS_Shape& aC=aIt.Value(); //C is compound
306       //
307       aItC.Initialize(aC);
308       for (; aItC.More(); aItC.Next()) {
309         const TopoDS_Shape& aS=aItC.Value();
310         aType=aS.ShapeType();
311         if (aType==TopAbs_COMPOUND) {
312           aLC1.Append(aS);
313         }
314         else {
315           aLSX.Append(aS);
316         }
317       }
318     }
319     //
320     aNbC1=aLC1.Extent();
321     if (!aNbC1) {
322       break;
323     }
324     //
325     aLC.Clear();
326     aIt.Initialize(aLC1);
327     for (; aIt.More(); aIt.Next()) {
328       const TopoDS_Shape& aSC=aIt.Value();
329       aLC.Append(aSC);
330     }
331   }// while(1)
332 }
333 //
334 // myErrorStatus
335 // 
336 // 0  - Ok
337 // 1  - The object is just initialized
338 // 2  - PaveFiller is failed
339 // 10 - No shapes to process
340 // 30 - SolidBuilder failed