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