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