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