Salome HOME
43c530e37038ef797a60740363a9459a3ae77f1b
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_RemoverWebs.cxx
1 // Copyright (C) 2007-2023  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 // File:        GEOMAlgo_RemoverWebs.cxx
23 // Created:     Thu Mar 28 07:40:32 2013
24 // Author:      Peter KURNEV
25
26 #include <GEOMAlgo_RemoverWebs.hxx>
27 #include <GEOMAlgo_ShapeAlgo.hxx>
28
29 #include <TopoDS_Iterator.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Solid.hxx>
32 #include <BRep_Builder.hxx>
33
34 #include <TopExp.hxx>
35
36 #include <BRepClass3d_SolidClassifier.hxx>
37
38 #include <IntTools_Context.hxx>
39
40 #include <BOPAlgo_BuilderSolid.hxx>
41
42 #include <BOPTools_AlgoTools.hxx>
43 #include <TopTools_MapOfShape.hxx>
44
45 //=======================================================================
46 //function : 
47 //purpose  :
48 //=======================================================================
49 GEOMAlgo_RemoverWebs::GEOMAlgo_RemoverWebs()
50 :
51   GEOMAlgo_ShapeAlgo()
52 {
53 }
54 //=======================================================================
55 //function : ~
56 //purpose  :
57 //=======================================================================
58 GEOMAlgo_RemoverWebs::~GEOMAlgo_RemoverWebs()
59 {
60 }
61 //=======================================================================
62 //function : CheckData
63 //purpose  :
64 //=======================================================================
65 void GEOMAlgo_RemoverWebs::CheckData()
66 {
67   TopoDS_Iterator aIt;
68   //
69   myErrorStatus=0;
70   //
71   if (myShape.IsNull()) {
72     myErrorStatus=10;
73     return;
74   }
75   //
76   aIt.Initialize(myShape);
77   for (; aIt.More(); aIt.Next()) {
78     const TopoDS_Shape& aS=aIt.Value();
79     if (aS.ShapeType()!=TopAbs_SOLID) {
80       myErrorStatus=11;
81       return;
82     }
83   }
84 }
85 //=======================================================================
86 //function : Perform
87 //purpose  :
88 //=======================================================================
89 void GEOMAlgo_RemoverWebs::Perform()
90 {
91   myErrorStatus=0;
92   myWarningStatus=0;
93   //
94   // 1.
95   CheckData();
96   if(myErrorStatus) {
97     return;
98   }
99   //
100   // 2. Init myContext
101   if (!myContext.IsNull()) {
102     myContext.Nullify();
103   }
104   myContext=new IntTools_Context;
105   //
106   BuildSolid();
107   //
108 }
109
110 //=======================================================================
111 //function : BuildSolid
112 //purpose  :
113 //=======================================================================
114 void GEOMAlgo_RemoverWebs::BuildSolid()
115 {
116   Standard_Integer i, aNbF, aNbSx, iErr, aNbSI, aNbF2, aNbS, aNbR;  
117   TopAbs_Orientation aOr;
118   TopoDS_Iterator aIt1, aIt2;
119   TopoDS_Shape aShape;
120   BRep_Builder aBB;
121   TopTools_MapOfShape aMFence;
122   TopTools_IndexedMapOfShape aMSI;
123   TopTools_IndexedDataMapOfShapeListOfShape aMFS;
124   TopTools_ListOfShape aSFS;
125   TopTools_ListIteratorOfListOfShape aItLS;
126   BOPAlgo_BuilderSolid aSB;
127   //
128   //modified by NIZNHY-PKV Thu Jul 11 06:54:51 2013f
129   //
130   // 0. 
131   // The compound myShape may contain equal solids 
132   // (itz.brep for e.g.). The block is to refine 
133   // such data if it is necessary. The shape to treat 
134   // will be aShape (not myShape).
135   //
136   aShape=myShape;
137   //
138   aIt1.Initialize(myShape);
139   for (aNbS=0; aIt1.More(); aIt1.Next(), ++aNbS) {
140     const TopoDS_Shape& aS=aIt1.Value();
141     aMFence.Add(aS);
142   }
143   //
144   aNbR=aMFence.Extent();
145   if (aNbS!=aNbR) {
146     TopTools_MapIteratorOfMapOfShape aItMS;
147     //
148     BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aShape);  
149     //
150     aItMS.Initialize(aMFence);
151     for (; aItMS.More(); aItMS.Next()) {
152       const TopoDS_Shape& aS=aItMS.Key();
153       aBB.Add(aShape, aS);
154     }
155   }
156   //modified by NIZNHY-PKV Thu Jul 11 06:54:54 2013t
157   //
158   aNbF2=0;
159   //
160   // 1. aSFS: Faces 
161   TopExp::MapShapesAndAncestors(aShape, TopAbs_FACE, TopAbs_SOLID, aMFS);
162   //
163   aNbF=aMFS.Extent();
164   for (i=1; i<=aNbF; ++i) {
165     const TopoDS_Shape& aFx=aMFS.FindKey(i);
166     aOr=aFx.Orientation();
167     if (aOr==TopAbs_INTERNAL) {
168       TopoDS_Shape aFi;
169       //
170       aFi=aFx;
171       aFi.Orientation(TopAbs_FORWARD);
172       aSFS.Append(aFi);
173       aFi.Orientation(TopAbs_REVERSED);
174       aSFS.Append(aFi);
175     }
176     else {
177       const TopTools_ListOfShape& aLSx=aMFS(i);
178       aNbSx=aLSx.Extent();
179       if (aNbSx==1) {
180         aSFS.Append(aFx);
181       }
182       else if (aNbSx==2) {
183         ++aNbF2;
184       }
185     }
186   }
187   //
188   if (!aNbF2) { // nothing to do here
189     myResult=aShape;
190     return;
191   }
192   //
193   // 2 Internal shapes: edges, vertices
194   aIt1.Initialize(aShape);
195   for (; aIt1.More(); aIt1.Next()) {
196     const TopoDS_Shape& aSD=aIt1.Value(); 
197     //
198     aIt2.Initialize(aSD);
199     for (; aIt2.More(); aIt2.Next()) {
200       const TopoDS_Shape& aSi=aIt2.Value(); 
201       if (aSi.ShapeType()!=TopAbs_SHELL) {
202         aOr=aSi.Orientation();
203         if (aOr==TopAbs_INTERNAL) {
204           aMSI.Add(aSi);
205         }
206       }
207     }
208   }
209   aNbSI=aMSI.Extent();
210   //
211   // 3 Solids without internals
212   BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, myResult);  
213   //
214   aSB.SetContext(myContext);
215   aSB.SetShapes(aSFS);
216   aSB.Perform();
217   iErr=aSB.HasErrors();
218   if (iErr) {
219     myErrorStatus=20; // SolidBuilder failed
220     return;
221   }
222   //
223   const TopTools_ListOfShape& aLSR=aSB.Areas();
224   // 
225   // 4 Add the internals
226   if (aNbSI) {
227     AddInternalShapes(aLSR, aMSI);
228   }
229   //
230   aItLS.Initialize(aLSR);
231   for (; aItLS.More(); aItLS.Next()) {
232     const TopoDS_Shape& aSR=aItLS.Value();
233     aBB.Add(myResult, aSR);
234   }
235 }
236
237 //=======================================================================
238 //function : AddInternalShapes
239 //purpose  : 
240 //=======================================================================
241 void GEOMAlgo_RemoverWebs::AddInternalShapes(const TopTools_ListOfShape& aLSR,
242                                              const TopTools_IndexedMapOfShape& aMSI)
243 {
244   Standard_Integer i, aNbSI;
245   TopAbs_State aState;  
246   TopoDS_Solid aSd;
247   BRep_Builder aBB;
248   TopTools_ListIteratorOfListOfShape aItLS;
249   Handle(IntTools_Context) aCtx=new IntTools_Context;
250   //
251   aNbSI=aMSI.Extent();
252   for (i=1; i<=aNbSI; ++i) {
253     const TopoDS_Shape& aSI=aMSI(i);
254     //
255     aItLS.Initialize(aLSR);
256     for (; aItLS.More(); aItLS.Next()) {
257       aSd=*((TopoDS_Solid*)&aItLS.Value());
258       //
259       aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, aCtx);
260       if (aState==TopAbs_IN) {
261         aBB.Add(aSd, aSI);
262         //
263         BRepClass3d_SolidClassifier& aSC=aCtx->SolidClassifier(aSd);
264         aSC.Load(aSd);
265       }
266     }
267   }
268 }
269 //
270 // myErrorStatus
271 // 0  - OK
272 // 10 - myShape is Null
273 // 11 - myShape contains non-solids
274 // 20 - BuilderSolid failed