Salome HOME
Preparation of intermediate revision
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Splitter.cxx
1 //  Copyright (C) 2007-2008  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.
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 //  File:   GEOMAlgo_Splitter.cxx
23 //  Author: Peter KURNEV
24
25 #include <GEOMAlgo_Splitter.ixx>
26
27 #include <TopAbs_ShapeEnum.hxx>
28
29 #include <TopoDS_Shape.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <TopoDS_Iterator.hxx>
32
33 #include <TopExp.hxx>
34
35 #include <BRep_Builder.hxx>
36 #include <BRepLib.hxx>
37
38 #include <TopTools_MapOfShape.hxx>
39 #include <TopTools_ListOfShape.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41 #include <TopTools_IndexedMapOfShape.hxx>
42
43 #include <BOP_CorrectTolerances.hxx>
44
45
46 static
47   void TreatCompound(const TopoDS_Shape& aC,
48                      TopTools_ListOfShape& aLSX);
49
50 //=======================================================================
51 //function :
52 //purpose  :
53 //=======================================================================
54   GEOMAlgo_Splitter::GEOMAlgo_Splitter()
55 :
56   GEOMAlgo_Builder()
57 {
58   myLimit=TopAbs_SHAPE;
59   myLimitMode=0;
60 }
61 //=======================================================================
62 //function : ~
63 //purpose  :
64 //=======================================================================
65   GEOMAlgo_Splitter::~GEOMAlgo_Splitter()
66 {
67 }
68 //=======================================================================
69 //function : AddToolCompound
70 //purpose  :
71 //=======================================================================
72   void GEOMAlgo_Splitter::AddToolCompound(const TopoDS_Shape& theShape)
73 {
74   TopoDS_Iterator aIt;
75   //
76   aIt.Initialize(theShape);
77   for (; aIt.More(); aIt.Next()) {
78     const TopoDS_Shape& aS=aIt.Value();
79     AddTool(aS);
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     AddShape(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   GEOMAlgo_Builder::Clear();
144 }
145 //=======================================================================
146 //function : BuildResult
147 //purpose  :
148 //=======================================================================
149   void GEOMAlgo_Splitter::BuildResult(const TopAbs_ShapeEnum theType)
150 {
151   myErrorStatus=0;
152   //
153   TopAbs_ShapeEnum aType;
154   BRep_Builder aBB;
155   TopTools_MapOfShape aM;
156   TopTools_ListIteratorOfListOfShape aIt, aItIm;
157   //
158   aIt.Initialize(myShapes);
159   for (; aIt.More(); aIt.Next()) {
160     const TopoDS_Shape& aS=aIt.Value();
161     aType=aS.ShapeType();
162     if (aType==theType && !myMapTools.Contains(aS)) {
163       if (myImages.HasImage(aS)) {
164         const TopTools_ListOfShape& aLSIm=myImages.Image(aS);
165         aItIm.Initialize(aLSIm);
166         for (; aItIm.More(); aItIm.Next()) {
167           const TopoDS_Shape& aSIm=aItIm.Value();
168           if (aM.Add(aSIm)) {
169             aBB.Add(myShape, aSIm);
170           }
171         }
172       }
173       else {
174         if (aM.Add(aS)) {
175           aBB.Add(myShape, aS);
176         }
177       }
178     }
179   }
180 }
181 //=======================================================================
182 //function : PostTreat
183 //purpose  :
184 //=======================================================================
185   void GEOMAlgo_Splitter::PostTreat()
186 {
187   if (myLimit!=TopAbs_SHAPE) {
188     Standard_Integer i, aNbS;
189     BRep_Builder aBB;
190     TopoDS_Compound aC;
191     TopTools_IndexedMapOfShape aMx;
192     //
193     aBB.MakeCompound(aC);
194     //
195     TopExp::MapShapes(myShape, myLimit, aMx);
196     aNbS=aMx.Extent();
197     for (i=1; i<=aNbS; ++i) {
198       const TopoDS_Shape& aS=aMx(i);
199       aBB.Add(aC, aS);
200     }
201     //
202     if (myLimitMode) {
203       Standard_Integer iType, iLimit, iTypeX;
204       TopAbs_ShapeEnum aType, aTypeX;
205       TopTools_ListOfShape aLSP, aLSX;
206       TopTools_ListIteratorOfListOfShape aIt, aItX, aItIm;
207       TopTools_MapOfShape  aM;
208       //
209       iLimit=(Standard_Integer)myLimit;
210       //
211       // 1. Collect the shapes to process aLSP
212       aIt.Initialize(myShapes);
213       for (; aIt.More(); aIt.Next()) {
214         const TopoDS_Shape& aS=aIt.Value();
215         if (myMapTools.Contains(aS)) {
216           continue;
217         }
218         //
219         aType=aS.ShapeType();
220         iType=(Standard_Integer)aType;
221         //
222         if (iType>iLimit) {
223           aLSP.Append(aS);
224         }
225         //
226         else if (aType==TopAbs_COMPOUND) {
227           aLSX.Clear();
228           //
229           TreatCompound(aS, aLSX);
230           //
231           aItX.Initialize(aLSX);
232           for (; aItX.More(); aItX.Next()) {
233             const TopoDS_Shape& aSX=aItX.Value();
234             aTypeX=aSX.ShapeType();
235             iTypeX=(Standard_Integer)aTypeX;
236             //
237             if (iTypeX>iLimit) {
238               aLSP.Append(aSX);
239             }
240           }
241         }
242       }// for (; aIt.More(); aIt.Next()) {
243       //
244       //modified by NIZNHY-PKV Fri Oct 30 11:07:08 2009 f
245       aMx.Clear();
246       TopExp::MapShapes(aC, aMx);
247       //modified by NIZNHY-PKV Fri Oct 30 11:12:30 2009t
248       //
249       // 2. Add them to aC
250       aIt.Initialize(aLSP);
251       for (; aIt.More(); aIt.Next()) {
252         const TopoDS_Shape& aS=aIt.Value();
253         if (myImages.HasImage(aS)) {
254           const TopTools_ListOfShape& aLSIm=myImages.Image(aS);
255           aItIm.Initialize(aLSIm);
256           for (; aItIm.More(); aItIm.Next()) {
257             const TopoDS_Shape& aSIm=aItIm.Value();
258             if (aM.Add(aSIm)) {
259               //modified by NIZNHY-PKV Fri Oct 30 11:09:57 2009f
260               if (!aMx.Contains(aSIm)) {
261                 aBB.Add(aC, aSIm);
262               }
263               //aBB.Add(aC, aSIm);
264               //modified by NIZNHY-PKV Fri Oct 30 11:10:02 2009
265             }
266           }
267         }
268         else {
269           if (aM.Add(aS)) {
270             //modified by NIZNHY-PKV Fri Oct 30 11:10:46 2009f
271             if (!aMx.Contains(aS)) {
272               aBB.Add(aC, aS);
273             }
274             //aBB.Add(aC, aS);
275             //modified by NIZNHY-PKV Fri Oct 30 11:11:00 2009t
276           }
277         }
278       }
279     }// if (myLimitMode) {
280     myShape=aC;
281   }//if (myLimit!=TopAbs_SHAPE) {
282   //
283   GEOMAlgo_Builder::PostTreat();
284 }
285 //=======================================================================
286 //function : TreatCompound
287 //purpose  :
288 //=======================================================================
289 void TreatCompound(const TopoDS_Shape& aC1,
290                    TopTools_ListOfShape& aLSX)
291 {
292   Standard_Integer aNbC1;
293   TopAbs_ShapeEnum aType;
294   TopTools_ListOfShape aLC, aLC1;
295   TopTools_ListIteratorOfListOfShape aIt, aIt1;
296   TopoDS_Iterator aItC;
297   //
298   aLC.Append (aC1);
299   while(1) {
300     aLC1.Clear();
301     aIt.Initialize(aLC);
302     for (; aIt.More(); aIt.Next()) {
303       const TopoDS_Shape& aC=aIt.Value(); //C is compound
304       //
305       aItC.Initialize(aC);
306       for (; aItC.More(); aItC.Next()) {
307         const TopoDS_Shape& aS=aItC.Value();
308         aType=aS.ShapeType();
309         if (aType==TopAbs_COMPOUND) {
310           aLC1.Append(aS);
311         }
312         else {
313           aLSX.Append(aS);
314         }
315       }
316     }
317     //
318     aNbC1=aLC1.Extent();
319     if (!aNbC1) {
320       break;
321     }
322     //
323     aLC.Clear();
324     aIt.Initialize(aLC1);
325     for (; aIt.More(); aIt.Next()) {
326       const TopoDS_Shape& aSC=aIt.Value();
327       aLC.Append(aSC);
328     }
329   }// while(1)
330 }
331 //
332 // myErrorStatus
333 //
334 // 0  - Ok
335 // 1  - The object is just initialized
336 // 2  - PaveFiller is failed
337 // 10 - No shapes to process
338 // 30 - SolidBuilder failed