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