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