0026738: Make Boolean operations safely treating arguments when running with fuzzy...
[occt.git] / src / BOPAlgo / BOPAlgo_Builder.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_Builder.hxx>
20 #include <BOPAlgo_PaveFiller.hxx>
21 #include <BOPTools_AlgoTools.hxx>
22 #include <BRep_Builder.hxx>
23 #include <IntTools_Context.hxx>
24 #include <Standard_ErrorHandler.hxx>
25 #include <Standard_Failure.hxx>
26 #include <TopoDS_Compound.hxx>
27 #include <BRep_Builder.hxx>
28
29 #include <BOPCol_IndexedMapOfShape.hxx>
30
31 #include <BOPDS_ShapeInfo.hxx>
32 #include <BOPDS_DS.hxx>
33
34 #include <BOPTools_AlgoTools.hxx>
35 #include <TopTools_ListIteratorOfListOfShape.hxx>
36
37
38 //=======================================================================
39 //function : 
40 //purpose  : 
41 //=======================================================================
42 BOPAlgo_Builder::BOPAlgo_Builder()
43 :
44   BOPAlgo_BuilderShape(),
45   myArguments(myAllocator),
46   myMapFence(100, myAllocator),
47   myPaveFiller(NULL),
48   myDS(NULL),
49   myEntryPoint(0),
50   myImages(100, myAllocator),
51   myShapesSD(100, myAllocator),
52   mySplits(100, myAllocator),
53   myOrigins(100, myAllocator),
54   myNonDestructive(Standard_False)
55 {
56 }
57 //=======================================================================
58 //function : 
59 //purpose  : 
60 //=======================================================================
61 BOPAlgo_Builder::BOPAlgo_Builder
62   (const Handle(NCollection_BaseAllocator)& theAllocator)
63 :
64   BOPAlgo_BuilderShape(theAllocator),
65   myArguments(myAllocator),
66   myMapFence(100, myAllocator),
67   myPaveFiller(NULL),
68   myDS(NULL),
69   myEntryPoint(0),
70   myImages(100, myAllocator), 
71   myShapesSD(100, myAllocator),
72   mySplits(100, myAllocator),
73   myOrigins(100, myAllocator),
74   myNonDestructive(Standard_False)
75 {
76 }
77 //=======================================================================
78 //function : ~
79 //purpose  : 
80 //=======================================================================
81 BOPAlgo_Builder::~BOPAlgo_Builder()
82 {
83   if (myEntryPoint==1) {
84     if (myPaveFiller) {
85       delete myPaveFiller;
86       myPaveFiller=NULL;
87     }
88   }
89 }
90 //=======================================================================
91 //function : Clear
92 //purpose  : 
93 //=======================================================================
94 void BOPAlgo_Builder::Clear()
95 {
96   myArguments.Clear();
97   myMapFence.Clear();
98   myImages.Clear();
99   myShapesSD.Clear();
100   mySplits.Clear();
101   myOrigins.Clear();
102 }
103 //=======================================================================
104 //function : AddArgument
105 //purpose  : 
106 //=======================================================================
107 void BOPAlgo_Builder::AddArgument(const TopoDS_Shape& theShape)
108 {
109   if (myMapFence.Add(theShape)) {
110     myArguments.Append(theShape);
111   }
112 }
113 //=======================================================================
114 //function : SetArguments
115 //purpose  : 
116 //=======================================================================
117 void BOPAlgo_Builder::SetArguments(const BOPCol_ListOfShape& theShapes)
118 {
119   BOPCol_ListIteratorOfListOfShape aIt;
120   //
121   myArguments.Clear();
122   //
123   aIt.Initialize(theShapes);
124   for (; aIt.More(); aIt.Next()) {
125     const TopoDS_Shape& aS = aIt.Value();
126     AddArgument(aS);
127   }
128 }
129 //=======================================================================
130 //function : Arguments
131 //purpose  : 
132 //=======================================================================
133 const BOPCol_ListOfShape& BOPAlgo_Builder::Arguments()const
134 {
135   return myArguments;
136 }
137 //=======================================================================
138 //function : Images
139 //purpose  : 
140 //=======================================================================
141 const BOPCol_DataMapOfShapeListOfShape& BOPAlgo_Builder::Images()const
142 {
143   return myImages;
144 }
145 //=======================================================================
146 //function : Origins
147 //purpose  : 
148 //=======================================================================
149 const BOPCol_DataMapOfShapeShape& BOPAlgo_Builder::Origins()const
150 {
151   return myOrigins;
152 }
153
154 //=======================================================================
155 //function : ShapesSd
156 //purpose  : 
157 //=======================================================================
158 const BOPCol_DataMapOfShapeShape& BOPAlgo_Builder::ShapesSD()const
159 {
160   return myShapesSD;
161 }
162 //=======================================================================
163 //function : Splits
164 //purpose  : 
165 //=======================================================================
166 const BOPCol_DataMapOfShapeListOfShape& BOPAlgo_Builder::Splits()const
167 {
168   return mySplits;
169 }
170 //=======================================================================
171 //function : PPaveFiller
172 //purpose  : 
173 //=======================================================================
174 BOPAlgo_PPaveFiller BOPAlgo_Builder::PPaveFiller()
175 {
176   return myPaveFiller;
177 }
178 //=======================================================================
179 //function : PDS
180 //purpose  : 
181 //=======================================================================
182 BOPDS_PDS BOPAlgo_Builder::PDS()
183 {
184   return myDS;
185 }
186 //=======================================================================
187 //function : SetNonDestructive
188 //purpose  : 
189 //=======================================================================
190 void BOPAlgo_Builder::SetNonDestructive(const Standard_Boolean theFlag)
191 {
192   myNonDestructive = theFlag;
193 }
194 //=======================================================================
195 //function : NonDestructive
196 //purpose  : 
197 //=======================================================================
198 Standard_Boolean BOPAlgo_Builder::NonDestructive() const
199 {
200   return myNonDestructive;
201 }
202 //=======================================================================
203 // function: CheckData
204 // purpose: 
205 //=======================================================================
206 void BOPAlgo_Builder::CheckData()
207 {
208   Standard_Integer aNb;
209   //
210   myErrorStatus=0;
211   //
212   aNb=myArguments.Extent();
213   if (aNb<2) {
214     myErrorStatus=100; // too few arguments to process
215     return;
216   }
217   //
218   //  myPaveFiller
219   if (!myPaveFiller) {
220     myErrorStatus=101; 
221     return;
222   }
223   //
224   myErrorStatus=myPaveFiller->ErrorStatus();
225   if (myErrorStatus) {
226     myErrorStatus=102; // PaveFiller is failed
227     return;
228   }
229 }
230 //=======================================================================
231 //function : Prepare
232 //purpose  : 
233 //=======================================================================
234 void BOPAlgo_Builder::Prepare()
235 {
236   myErrorStatus=0;
237   //
238   BRep_Builder aBB;
239   TopoDS_Compound aC;
240   //
241   // 1. myShape is empty compound
242   aBB.MakeCompound(aC);
243   myShape=aC;
244   myFlagHistory=Standard_True;
245 }
246 //=======================================================================
247 //function : Perform
248 //purpose  : 
249 //=======================================================================
250 void BOPAlgo_Builder::Perform()
251 {
252   myErrorStatus=0;
253   //
254   if (myEntryPoint==1) {
255     if (myPaveFiller) {
256       delete myPaveFiller;
257       myPaveFiller=NULL;
258     }
259   }
260   //
261   Handle(NCollection_BaseAllocator) aAllocator=
262     NCollection_BaseAllocator::CommonBaseAllocator();
263   //
264   BOPAlgo_PaveFiller* pPF=new BOPAlgo_PaveFiller(aAllocator);
265   //
266   pPF->SetArguments(myArguments);
267   pPF->SetRunParallel(myRunParallel);
268   pPF->SetProgressIndicator(myProgressIndicator);
269   pPF->SetFuzzyValue(myFuzzyValue);
270   pPF->SetNonDestructive(myNonDestructive);
271   //
272   pPF->Perform();
273   //
274   myEntryPoint=1;
275   PerformInternal(*pPF);
276 }
277 //=======================================================================
278 //function : PerformWithFiller
279 //purpose  : 
280 //=======================================================================
281 void BOPAlgo_Builder::PerformWithFiller(const BOPAlgo_PaveFiller& theFiller)
282 {
283   myEntryPoint=0;
284   myNonDestructive = theFiller.NonDestructive();
285   myFuzzyValue = theFiller.FuzzyValue();
286   PerformInternal(theFiller);
287 }
288 //=======================================================================
289 //function : PerformInternal
290 //purpose  : 
291 //=======================================================================
292 void BOPAlgo_Builder::PerformInternal(const BOPAlgo_PaveFiller& theFiller)
293 {
294   try { 
295     OCC_CATCH_SIGNALS
296     PerformInternal1(theFiller);
297   }
298   //
299   catch (Standard_Failure) {
300     myErrorStatus=191;
301   }  
302 }
303 //=======================================================================
304 //function : PerformInternal1
305 //purpose  : 
306 //=======================================================================
307 void BOPAlgo_Builder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
308 {
309   myErrorStatus=0;
310   //
311   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
312   myDS=myPaveFiller->PDS();
313   myContext=myPaveFiller->Context();
314   myFuzzyValue = myPaveFiller->FuzzyValue();
315   myNonDestructive = myPaveFiller->NonDestructive();
316   //
317   // 1. CheckData
318   CheckData();
319   if (myErrorStatus) {
320     return;
321   }
322   //
323   // 2. Prepare
324   Prepare();
325   if (myErrorStatus) {
326     return;
327   }
328   //
329   // 3. Fill Images
330   // 3.1 Vertice
331   FillImagesVertices();
332   if (myErrorStatus) {
333     return;
334   }
335   //
336   BuildResult(TopAbs_VERTEX);
337   if (myErrorStatus) {
338     return;
339   }
340   // 3.2 Edges
341   FillImagesEdges();
342   if (myErrorStatus) {
343     return;
344   }
345   //
346   BuildResult(TopAbs_EDGE);
347   if (myErrorStatus) {
348     return;
349   }
350   //
351   // 3.3 Wires
352   FillImagesContainers(TopAbs_WIRE);
353   if (myErrorStatus) {
354     return;
355   }
356   //
357   BuildResult(TopAbs_WIRE);
358   if (myErrorStatus) {
359     return;
360   }
361   
362   // 3.4 Faces
363   FillImagesFaces();
364   if (myErrorStatus) {
365     return;
366   }
367   //
368   BuildResult(TopAbs_FACE);
369   if (myErrorStatus) {
370     return;
371   }
372   // 3.5 Shells
373   FillImagesContainers(TopAbs_SHELL);
374   if (myErrorStatus) {
375     return;
376   }
377   
378   BuildResult(TopAbs_SHELL);
379   if (myErrorStatus) {
380     return;
381   }
382   // 3.6 Solids
383   FillImagesSolids();
384   if (myErrorStatus) {
385     return;
386   }
387   
388   BuildResult(TopAbs_SOLID);
389   if (myErrorStatus) {
390     return;
391   }
392   // 3.7 CompSolids
393   FillImagesContainers(TopAbs_COMPSOLID);
394   if (myErrorStatus) {
395     return;
396   }
397   
398   BuildResult(TopAbs_COMPSOLID);
399   if (myErrorStatus) {
400     return;
401   }
402   
403   // 3.8 Compounds
404   FillImagesCompounds();
405   if (myErrorStatus) {
406     return;
407   }
408   
409   BuildResult(TopAbs_COMPOUND);
410   if (myErrorStatus) {
411     return;
412   }
413   //
414   // 4.History
415   PrepareHistory();
416   //
417   //
418   // 5 Post-treatment 
419   PostTreat();
420   
421 }
422 //=======================================================================
423 //function : PostTreat
424 //purpose  : 
425 //=======================================================================
426 void BOPAlgo_Builder::PostTreat()
427 {
428   Standard_Integer i, aNbS;
429   TopAbs_ShapeEnum aType;
430   BOPCol_IndexedMapOfShape aMA;
431   if (myPaveFiller->NonDestructive()) {
432     // MapToAvoid
433     aNbS=myDS->NbSourceShapes();
434     for (i=0; i<aNbS; ++i) {
435       const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
436       aType=aSI.ShapeType();
437       if (aType==TopAbs_VERTEX ||
438           aType==TopAbs_EDGE||
439           aType==TopAbs_FACE) {
440         const TopoDS_Shape& aS=aSI.Shape();
441         aMA.Add(aS);
442       }
443     }
444   }
445   //
446   BOPTools_AlgoTools::CorrectTolerances(myShape, aMA, 0.05, myRunParallel);
447   BOPTools_AlgoTools::CorrectShapeTolerances(myShape, aMA, myRunParallel);
448 }