0025232: Functionality to create solids from set of shapes
[occt.git] / src / BOPAlgo / BOPAlgo_MakerVolume.cxx
CommitLineData
92ae0f2f 1// Created by: Eugeny MALTCHIKOV
2// Copyright (c) 2014 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#include <BOPAlgo_MakerVolume.ixx>
16
17#include <NCollection_IncAllocator.hxx>
18
19#include <Bnd_Box.hxx>
20
21#include <TopoDS_Solid.hxx>
22
23#include <TopExp_Explorer.hxx>
24
25#include <BRepPrimAPI_MakeBox.hxx>
26
27#include <BOPCol_ListOfShape.hxx>
28#include <BOPCol_DataMapOfShapeListOfShape.hxx>
29
30#include <BOPDS_DS.hxx>
31
32#include <BOPAlgo_PaveFiller.hxx>
33#include <BOPAlgo_BuilderSolid.hxx>
34
35#include <BOPTools.hxx>
36#include <BOPTools_AlgoTools.hxx>
37
38static
39 void AddFace(const TopoDS_Shape& theF,
40 BOPCol_ListOfShape& theLF);
41static
42 void TreatCompound(const TopoDS_Shape& theS,
43 BOPCol_MapOfShape& aMFence,
44 BOPCol_ListOfShape& theLS);
45
46//=======================================================================
47//function : Perform
48//purpose :
49//=======================================================================
50void BOPAlgo_MakerVolume::Perform()
51{
52 myErrorStatus = 0;
53 //
54 if (myEntryPoint == 1) {
55 if (myPaveFiller) {
56 delete myPaveFiller;
57 myPaveFiller = NULL;
58 }
59 }
60 //
61 Handle(NCollection_BaseAllocator) aAllocator = new NCollection_IncAllocator;
62 BOPAlgo_PaveFiller* pPF = new BOPAlgo_PaveFiller(aAllocator);
63 //
64 if (!myIntersect) {
65 //if there is no need to intersect the arguments, then it is necessary
66 //to create the compound of them and use it as one argument
67 TopoDS_Compound anArgs;
68 BRep_Builder aBB;
69 BOPCol_ListIteratorOfListOfShape aIt;
70 BOPCol_ListOfShape aLS;
71 //
72 aBB.MakeCompound(anArgs);
73 aIt.Initialize(myArguments);
74 for (; aIt.More(); aIt.Next()) {
75 const TopoDS_Shape& aS = aIt.Value();
76 aBB.Add(anArgs, aS);
77 }
78 aLS.Append(anArgs);
79 //
80 pPF->SetArguments(aLS);
81 }
82 else {
83 pPF->SetArguments(myArguments);
84 }
85 //
86 pPF->SetRunParallel(myRunParallel);
87 pPF->Perform();
88 //
89 myEntryPoint = 1;
90 PerformInternal(*pPF);
91}
92
93//=======================================================================
94//function : PerformInternal1
95//purpose :
96//=======================================================================
97void BOPAlgo_MakerVolume::PerformInternal1
98 (const BOPAlgo_PaveFiller& theFiller)
99{
100 myErrorStatus=0;
101 //
102 myPaveFiller = (BOPAlgo_PaveFiller*)&theFiller;
103 myDS = myPaveFiller->PDS();
104 myContext = myPaveFiller->Context();
105 //
106 // 1. CheckData
107 CheckData();
108 if (myErrorStatus) {
109 return;
110 }
111 //
112 // 2. Prepare
113 Prepare();
114 if (myErrorStatus) {
115 return;
116 }
117 //
118 // 3. Fill Images
119 // 3.1. Vertice
120 if (myIntersect) {
121 FillImagesVertices();
122 if (myErrorStatus) {
123 return;
124 }
125 // 3.2. Edges
126 FillImagesEdges();
127 if (myErrorStatus) {
128 return;
129 }
130 // 3.3. Wires
131 FillImagesContainers(TopAbs_WIRE);
132 if (myErrorStatus) {
133 return;
134 }
135 // 3.4. Faces
136 FillImagesFaces();
137 if (myErrorStatus) {
138 return;
139 }
140 }
141 //
142 // 4. Collect faces
143 CollectFaces();
144 if (myErrorStatus) {
145 return;
146 }
147 //
148 BOPCol_MapOfShape aBoxFaces;
149 BOPCol_ListOfShape aLSR;
150 //
151 // 5. Create bounding box
152 MakeBox(aBoxFaces);
153 //
154 // 6. Make volumes
155 BuildSolids(aLSR);
156 if (myErrorStatus) {
157 return;
158 }
159 //
160 // 7. Treat the result
161 RemoveBox(aLSR, aBoxFaces);
162 //
163 // 8. Fill internal shapes
164 FillInternalShapes(aLSR);
165 //
166 // 9. Build Result
167 BuildShape(aLSR);
168 //
169 // 10. History
170 PrepareHistory();
171 //
172 // 11. Post-treatment
173 PostTreat();
174}
175
176//=======================================================================
177//function : CollectFaces
178//purpose :
179//=======================================================================
180void BOPAlgo_MakerVolume::CollectFaces()
181{
182 UserBreak();
183 //
184 Standard_Integer i, aNbShapes;
185 BOPCol_ListIteratorOfListOfShape aIt;
186 //
187 aNbShapes = myDS->NbSourceShapes();
188 for (i = 0; i < aNbShapes; ++i) {
189 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
190 if (aSI.ShapeType() != TopAbs_FACE) {
191 continue;
192 }
193 //
194 const Bnd_Box& aB = aSI.Box();
195 myBBox.Add(aB);
196 //
197 const TopoDS_Shape& aF = aSI.Shape();
198 if (myImages.IsBound(aF)) {
199 const BOPCol_ListOfShape& aLFIm = myImages.Find(aF);
200 aIt.Initialize(aLFIm);
201 for (; aIt.More(); aIt.Next()) {
202 const TopoDS_Shape& aFIm = aIt.Value();
203 AddFace(aFIm, myFaces);
204 }
205 }
206 else {
207 AddFace(aF, myFaces);
208 }
209 }
210}
211
212//=======================================================================
213//function : MakeBox
214//purpose :
215//=======================================================================
216void BOPAlgo_MakerVolume::MakeBox(BOPCol_MapOfShape& theBoxFaces)
217{
218 UserBreak();
219 //
220 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, anExt;
221 //
222 anExt = myBBox.SquareExtent() * 0.5;
223 myBBox.Enlarge(anExt);
224 myBBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
225 //
226 gp_Pnt aPMin(aXmin, aYmin, aZmin),
227 aPMax(aXmax, aYmax, aZmax);
228 //
229 mySBox = BRepPrimAPI_MakeBox(aPMin, aPMax).Solid();
230 //
231 TopExp_Explorer aExp(mySBox, TopAbs_FACE);
232 for (; aExp.More(); aExp.Next()) {
233 const TopoDS_Shape& aF = aExp.Current();
234 myFaces.Append(aF);
235 theBoxFaces.Add(aF);
236 }
237}
238
239//=======================================================================
240//function : BuildSolids
241//purpose :
242//=======================================================================
243void BOPAlgo_MakerVolume::BuildSolids(BOPCol_ListOfShape& theLSR)
244{
245 UserBreak();
246 //
247 BOPAlgo_BuilderSolid aBS;
248 //
249 aBS.SetSolid(mySBox);
250 aBS.SetShapes(myFaces);
251 aBS.SetRunParallel(myRunParallel);
252 aBS.Perform();
253 if (aBS.ErrorStatus()) {
254 myErrorStatus = 103;
255 return;
256 }
257 //
258 theLSR = aBS.Areas();
259}
260
261//=======================================================================
262//function : TreatResult
263//purpose :
264//=======================================================================
265void BOPAlgo_MakerVolume::RemoveBox(BOPCol_ListOfShape& theLSR,
266 const BOPCol_MapOfShape& theBoxFaces)
267{
268 UserBreak();
269 //
270 BOPCol_ListIteratorOfListOfShape aIt;
271 TopExp_Explorer aExp;
272 Standard_Boolean bFound;
273 //
274 bFound = Standard_False;
275 aIt.Initialize(theLSR);
276 for (; aIt.More(); aIt.Next()) {
277 const TopoDS_Shape& aSR = aIt.Value();
278 //
279 aExp.Init(aSR, TopAbs_FACE);
280 for (; aExp.More(); aExp.Next()) {
281 const TopoDS_Shape& aF = aExp.Current();
282 if (theBoxFaces.Contains(aF)) {
283 bFound = Standard_True;
284 theLSR.Remove(aIt);
285 break;
286 }
287 }
288 if (bFound) {
289 break;
290 }
291 }
292}
293
294//=======================================================================
295//function : BuildShape
296//purpose :
297//=======================================================================
298void BOPAlgo_MakerVolume::BuildShape(const BOPCol_ListOfShape& theLSR)
299{
300 if (theLSR.Extent() == 1) {
301 myShape = theLSR.First();
302 }
303 else {
304 BRep_Builder aBB;
305 BOPCol_ListIteratorOfListOfShape aIt;
306 //
307 aIt.Initialize(theLSR);
308 for (; aIt.More(); aIt.Next()) {
309 const TopoDS_Shape& aSol = aIt.Value();
310 aBB.Add(myShape, aSol);
311 }
312 }
313}
314
315//=======================================================================
316//function : FillInternalShapes
317//purpose :
318//=======================================================================
319void BOPAlgo_MakerVolume::FillInternalShapes(const BOPCol_ListOfShape& theLSR)
320{
321 UserBreak();
322 //
323 Standard_Integer aNbSI;
324 TopAbs_ShapeEnum aType;
325 TopAbs_State aState;
326 TopoDS_Iterator aItS;
327 BRep_Builder aBB;
328 BOPCol_MapOfShape aMFence;
329 BOPCol_IndexedMapOfShape aMSS;
330 BOPCol_ListOfShape aLVE, aLSC, aLSIn;
331 BOPCol_ListIteratorOfListOfShape aIt, aIt1;
332 //
333 // 1. Collect shapes to process: vertices, edges, wires
334 const BOPCol_ListOfShape& anArguments = myDS->Arguments();
335 aIt.Initialize(anArguments);
336 for (; aIt.More(); aIt.Next()) {
337 const TopoDS_Shape& aS = aIt.Value();
338 TreatCompound(aS, aMFence, aLSC);
339 }
340 //
341 aIt.Initialize(aLSC);
342 for (; aIt.More(); aIt.Next()) {
343 const TopoDS_Shape& aS = aIt.Value();
344 aType = aS.ShapeType();
345 if (aType == TopAbs_WIRE) {
346 aItS.Initialize(aS);
347 for(; aItS.More(); aItS.Next()) {
348 const TopoDS_Shape& aE = aItS.Value();
349 if (aMFence.Add(aE)) {
350 aLVE.Append(aE);
351 }
352 }
353 }
354 else if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
355 aLVE.Append(aS);
356 }
357 }
358 //
359 aIt.Initialize(theLSR);
360 for (; aIt.More(); aIt.Next()) {
361 const TopoDS_Shape& aS = aIt.Value();
362 BOPTools::MapShapes(aS, TopAbs_EDGE, aMSS);
363 BOPTools::MapShapes(aS, TopAbs_VERTEX, aMSS);
364 }
365 //
366 aIt.Initialize(aLVE);
367 for (; aIt.More(); aIt.Next()) {
368 const TopoDS_Shape& aS = aIt.Value();
369 if (myImages.IsBound(aS)) {
370 const BOPCol_ListOfShape &aLSp = myImages.Find(aS);
371 aIt1.Initialize(aLSp);
372 for (; aIt1.More(); aIt1.Next()) {
373 const TopoDS_Shape& aSp = aIt1.Value();
374 if (aMSS.Add(aSp)) {
375 aLSIn.Append(aSp);
376 }
377 }
378 }
379 else {
380 if (aMSS.Add(aS)) {
381 aLSIn.Append(aS);
382 }
383 }
384 }
385 //
386 aNbSI = aLSIn.Extent();
387 if (!aNbSI) {
388 return;
389 }
390 //
391 // 2. Settle internal vertices and edges into solids
392 aIt.Initialize(theLSR);
393 for (; aIt.More(); aIt.Next()) {
394 TopoDS_Solid aSd = *(TopoDS_Solid*)&aIt.Value();
395 //
396 aIt1.Initialize(aLSIn);
397 for (; aIt1.More(); ) {
398 TopoDS_Shape aSI = aIt1.Value();
399 aSI.Orientation(TopAbs_INTERNAL);
400 //
401 aState = BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
402 if (aState == TopAbs_IN) {
403 aBB.Add(aSd, aSI);
404 aLSIn.Remove(aIt1);
405 }
406 else {
407 aIt1.Next();
408 }
409 }
410 }
411}
412
413//=======================================================================
414//function : AddFace
415//purpose :
416//=======================================================================
417void AddFace(const TopoDS_Shape& theF,
418 BOPCol_ListOfShape& theLF)
419{
420 TopoDS_Shape aFF = theF;
421 aFF.Orientation(TopAbs_FORWARD);
422 theLF.Append(aFF);
423 aFF.Orientation(TopAbs_REVERSED);
424 theLF.Append(aFF);
425}
426
427//=======================================================================
428//function : TreatCompound
429//purpose :
430//=======================================================================
431void TreatCompound(const TopoDS_Shape& theS,
432 BOPCol_MapOfShape& aMFence,
433 BOPCol_ListOfShape& theLS)
434{
435 TopAbs_ShapeEnum aType = theS.ShapeType();
436 if (aType != TopAbs_COMPOUND) {
437 if (aMFence.Add(theS)) {
438 theLS.Append(theS);
439 }
440 return;
441 }
442 //
443 TopoDS_Iterator aIt(theS);
444 for (; aIt.More(); aIt.Next()) {
445 const TopoDS_Shape& aS = aIt.Value();
446 TreatCompound(aS, aMFence, theLS);
447 }
448}
449