0028187: Add possibility to avoid creation of Internal parts in the result of Volume...
[occt.git] / src / BOPAlgo / BOPAlgo_CheckerSI.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17
18 //
19
20 #include <BOPAlgo_CheckerSI.hxx>
21 #include <BOPCol_MapOfShape.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPDS_Interf.hxx>
24 #include <BOPDS_IteratorSI.hxx>
25 #include <BOPDS_MapOfPassKey.hxx>
26 #include <BOPDS_PassKey.hxx>
27 #include <BOPDS_PIteratorSI.hxx>
28 #include <BOPDS_VectorOfInterfEF.hxx>
29 #include <BOPDS_VectorOfInterfFF.hxx>
30 #include <BOPDS_VectorOfInterfVE.hxx>
31 #include <BOPDS_VectorOfInterfVF.hxx>
32 #include <BOPDS_VectorOfInterfVV.hxx>
33 #include <BOPTools.hxx>
34 #include <BOPTools_AlgoTools.hxx>
35 #include <BRepBuilderAPI_Copy.hxx>
36 #include <IntTools_Context.hxx>
37 #include <Standard_ErrorHandler.hxx>
38 #include <Standard_Failure.hxx>
39 #include <TopTools_ListOfShape.hxx>
40
41 //=======================================================================
42 //function : 
43 //purpose  : 
44 //=======================================================================
45 BOPAlgo_CheckerSI::BOPAlgo_CheckerSI()
46 :
47   BOPAlgo_PaveFiller()
48 {
49   myLevelOfCheck=BOPDS_DS::NbInterfTypes()-1;
50   myNonDestructive=Standard_True;
51 }
52 //=======================================================================
53 //function : ~
54 //purpose  : 
55 //=======================================================================
56 BOPAlgo_CheckerSI::~BOPAlgo_CheckerSI()
57 {
58 }
59 //=======================================================================
60 //function : SetLevelOfCheck
61 //purpose  : 
62 //=======================================================================
63 void BOPAlgo_CheckerSI::SetLevelOfCheck(const Standard_Integer theLevel)
64 {
65   Standard_Integer aNbLists;
66   //
67   aNbLists=BOPDS_DS::NbInterfTypes();
68   if (theLevel >= 0 && theLevel < aNbLists) {
69     myLevelOfCheck = theLevel;
70   }
71 }
72 //=======================================================================
73 //function : Init
74 //purpose  : 
75 //=======================================================================
76 void BOPAlgo_CheckerSI::Init()
77 {
78   myErrorStatus=0;
79   //
80   Clear();
81   //
82   // 1. myDS
83   myDS=new BOPDS_DS(myAllocator);
84   myDS->SetArguments(myArguments);
85   myDS->Init(myFuzzyValue);
86   //
87   // 2.myIterator 
88   BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator);
89   theIterSI->SetDS(myDS);
90   theIterSI->Prepare();
91   theIterSI->UpdateByLevelOfCheck(myLevelOfCheck);
92   //
93   myIterator=theIterSI;
94   //
95   // 3 myContext
96   myContext=new IntTools_Context;
97   //
98   myErrorStatus=0;
99 }
100 //=======================================================================
101 //function : Perform
102 //purpose  : 
103 //=======================================================================
104 void BOPAlgo_CheckerSI::Perform()
105 {
106   try {
107     Standard_Integer iErr;
108     //
109     OCC_CATCH_SIGNALS
110     //
111     myErrorStatus=0;
112     if (myArguments.Extent()!=1) {
113       myErrorStatus=10;
114       return;
115     }
116     //
117     if (myNonDestructive) {
118       PrepareCopy();
119       if (myErrorStatus) {
120         return; 
121       }
122     }
123     //
124     BOPAlgo_PaveFiller::Perform();
125     iErr=myErrorStatus; 
126     //
127     PostTreat();
128     if (myErrorStatus) {
129       iErr=myErrorStatus; 
130     }
131     //
132     if (myNonDestructive) {
133       PostTreatCopy();
134       if (myErrorStatus) {
135         iErr=myErrorStatus; 
136       }
137     }
138     //
139     if (iErr) {
140       myErrorStatus=iErr;
141     }
142   }
143   //
144   catch (Standard_Failure) {
145     if (myNonDestructive) { 
146       PostTreatCopy();
147     }
148     //
149     myErrorStatus=11;
150   }
151 }
152 //=======================================================================
153 //function : PostTreat
154 //purpose  : 
155 //=======================================================================
156 void BOPAlgo_CheckerSI::PostTreat()
157 {
158   Standard_Integer i, aNb, n1, n2; 
159   BOPDS_PassKey aPK;
160   //
161   myErrorStatus=0;
162   //
163   BOPDS_MapOfPassKey& aMPK=
164     *((BOPDS_MapOfPassKey*)&myDS->Interferences());
165   aMPK.Clear();
166   //
167   // 0
168   BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
169   aNb=aVVs.Extent();
170   for (i=0; i!=aNb; ++i) {
171     const BOPDS_InterfVV& aVV=aVVs(i);
172     aVV.Indices(n1, n2);
173     if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
174       continue;
175     }
176     aPK.SetIds(n1, n2);
177     aMPK.Add(aPK);
178   }
179   //
180   // 1
181   BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
182   aNb=aVEs.Extent();
183   for (i=0; i!=aNb; ++i) {
184     const BOPDS_InterfVE& aVE=aVEs(i);
185     aVE.Indices(n1, n2);
186     if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
187       continue;
188     }
189     aPK.SetIds(n1, n2);
190     aMPK.Add(aPK);
191   }
192   //
193   // 2
194   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
195   aNb=aEEs.Extent();
196   for (i=0; i!=aNb; ++i) {
197     const BOPDS_InterfEE& aEE=aEEs(i);
198     aEE.Indices(n1, n2);
199     if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
200       continue;
201     }
202     aPK.SetIds(n1, n2);
203     aMPK.Add(aPK);
204   }
205   //
206   // 3
207   BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
208   aNb=aVFs.Extent();
209   for (i=0; i!=aNb; ++i) {
210     const BOPDS_InterfVF& aVF=aVFs(i);
211     aVF.Indices(n1, n2);
212     if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
213       continue;
214     }
215     aPK.SetIds(n1, n2);
216     aMPK.Add(aPK);
217   }
218   //
219   // 4
220   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
221   aNb=aEFs.Extent();
222   for (i=0; i!=aNb; ++i) {
223     const BOPDS_InterfEF& aEF=aEFs(i);
224     if (aEF.CommonPart().Type()==TopAbs_SHAPE) {
225       continue;
226     }
227     aEF.Indices(n1, n2);
228     if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
229       continue;
230     }
231     aPK.SetIds(n1, n2);
232     aMPK.Add(aPK);
233   }
234   //
235   // 5
236   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
237   aNb=aFFs.Extent();
238   for (i=0; i!=aNb; ++i) {
239     Standard_Boolean bTangentFaces, bFlag;
240     Standard_Integer aNbC, aNbP, j, iFound;
241     //
242     const BOPDS_InterfFF& aFF=aFFs(i);
243     aFF.Indices(n1, n2);
244     //
245     bTangentFaces=aFF.TangentFaces();
246     aNbP=aFF.Points().Extent();
247     const BOPDS_VectorOfCurve& aVC=aFF.Curves();
248     aNbC=aVC.Extent();
249     if (!aNbP && !aNbC && !bTangentFaces) {
250       continue;
251     }
252     //
253     iFound=0;
254     if (bTangentFaces) {
255       const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1));
256       const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2));
257       bFlag=BOPTools_AlgoTools::AreFacesSameDomain
258         (aF1, aF2, myContext, myFuzzyValue);
259       if (bFlag) {
260         ++iFound;
261       }
262     }
263     else {
264       for (j=0; j!=aNbC; ++j) {
265         const BOPDS_Curve& aNC=aVC(j);
266         const BOPDS_ListOfPaveBlock& aLPBC=aNC.PaveBlocks();
267         if (aLPBC.Extent()) {
268           ++iFound;
269           break;
270         }
271       }
272     }
273     //
274     if (!iFound) {
275       continue;
276     }
277     //
278     aPK.SetIds(n1, n2);
279     aMPK.Add(aPK);
280   }
281   //
282   //
283   // 6
284   BOPDS_VectorOfInterfVZ& aVZs=myDS->InterfVZ();
285   aNb=aVZs.Extent();
286   for (i=0; i!=aNb; ++i) {
287     //
288     const BOPDS_InterfVZ& aVZ=aVZs(i);
289     aVZ.Indices(n1, n2);
290     if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
291       continue;
292     }
293     aPK.SetIds(n1, n2);
294     aMPK.Add(aPK);
295   }
296   //
297   // 7
298   BOPDS_VectorOfInterfEZ& aEZs=myDS->InterfEZ();
299   aNb=aEZs.Extent();
300   for (i=0; i!=aNb; ++i) {
301     //
302     const BOPDS_InterfEZ& aEZ=aEZs(i);
303     aEZ.Indices(n1, n2);
304     aPK.SetIds(n1, n2);
305     aMPK.Add(aPK);
306   }
307   //
308   // 8
309   BOPDS_VectorOfInterfFZ& aFZs=myDS->InterfFZ();
310   aNb=aFZs.Extent();
311   for (i=0; i!=aNb; ++i) {
312     //
313     const BOPDS_InterfFZ& aFZ=aFZs(i);
314     aFZ.Indices(n1, n2);
315     aPK.SetIds(n1, n2);
316     aMPK.Add(aPK);
317   }
318   //
319   // 9
320   BOPDS_VectorOfInterfZZ& aZZs=myDS->InterfZZ();
321   aNb=aZZs.Extent();
322   for (i=0; i!=aNb; ++i) {
323     //
324     const BOPDS_InterfZZ& aZZ=aZZs(i);
325     aZZ.Indices(n1, n2);
326     aPK.SetIds(n1, n2);
327     aMPK.Add(aPK);
328   }
329 }
330 //=======================================================================
331 //function : PrepareCopy
332 //purpose  : 
333 //=======================================================================
334 void BOPAlgo_CheckerSI::PrepareCopy()
335 {
336   Standard_Boolean bIsDone;
337   BRepBuilderAPI_Copy aCopier;
338   BOPCol_MapOfShape aMSA;
339   BOPCol_MapIteratorOfMapOfShape aItMS;
340   //
341   myErrorStatus=0;
342   //
343   myNewOldMap.Clear();
344   //
345   const TopoDS_Shape& aSA=myArguments.First();
346   //
347   BOPTools::MapShapes(aSA, aMSA);
348   //
349   aCopier.Perform(aSA, Standard_False);
350   bIsDone=aCopier.IsDone();
351   if (!bIsDone) {
352     myErrorStatus=12; 
353     return;
354   }
355   //
356   const TopoDS_Shape& aSC=aCopier.Shape();
357   //
358   aItMS.Initialize(aMSA);
359   for(; aItMS.More(); aItMS.Next()) {
360     const TopoDS_Shape& aSAx=aItMS.Value();
361     const TopoDS_Shape& aSCx=aCopier.Modified(aSAx).First();
362     myNewOldMap.Bind(aSCx, aSAx);
363   }
364   //
365   myArguments.Clear();
366   myArguments.Append(aSC);
367 }
368 //=======================================================================
369 //function : PostTreatCopy
370 //purpose  : 
371 //=======================================================================
372 void BOPAlgo_CheckerSI::PostTreatCopy() 
373 {
374   Standard_Integer i, aNb;
375   //
376   myErrorStatus=0;
377   //
378   aNb=myDS->NbSourceShapes();
379   for (i=0; i!=aNb; ++i) {
380     BOPDS_ShapeInfo& aSI=myDS->ChangeShapeInfo(i);
381     const TopoDS_Shape& aSCi=aSI.Shape();
382     if (!myNewOldMap.IsBound(aSCi)) {
383       myErrorStatus=13;
384       return;
385     }
386     //
387     const TopoDS_Shape& aSAi=myNewOldMap.Find(aSCi);
388     aSI.SetShape(aSAi);
389   }
390 }
391 //
392 // myErrorStatus:
393 //
394 // 10 - The number of the arguments is not 1
395 // 11 - Exception is caught
396 // 12 - BRepBuilderAPI_Copy is not done
397 // 13 - myNewOldMap doe not contain DS shape 
398