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