0026619: Tolerances of operands are modified using bop
[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);
92ae0f2f 104 pPF->Perform();
105 //
106 myEntryPoint = 1;
107 PerformInternal(*pPF);
108}
109
110//=======================================================================
111//function : PerformInternal1
112//purpose :
113//=======================================================================
114void BOPAlgo_MakerVolume::PerformInternal1
115 (const BOPAlgo_PaveFiller& theFiller)
116{
117 myErrorStatus=0;
118 //
119 myPaveFiller = (BOPAlgo_PaveFiller*)&theFiller;
120 myDS = myPaveFiller->PDS();
121 myContext = myPaveFiller->Context();
122 //
123 // 1. CheckData
124 CheckData();
125 if (myErrorStatus) {
126 return;
127 }
128 //
129 // 2. Prepare
130 Prepare();
131 if (myErrorStatus) {
132 return;
133 }
134 //
135 // 3. Fill Images
136 // 3.1. Vertice
137 if (myIntersect) {
138 FillImagesVertices();
139 if (myErrorStatus) {
140 return;
141 }
142 // 3.2. Edges
143 FillImagesEdges();
144 if (myErrorStatus) {
145 return;
146 }
147 // 3.3. Wires
148 FillImagesContainers(TopAbs_WIRE);
149 if (myErrorStatus) {
150 return;
151 }
152 // 3.4. Faces
153 FillImagesFaces();
154 if (myErrorStatus) {
155 return;
156 }
157 }
158 //
159 // 4. Collect faces
160 CollectFaces();
161 if (myErrorStatus) {
162 return;
163 }
164 //
165 BOPCol_MapOfShape aBoxFaces;
166 BOPCol_ListOfShape aLSR;
167 //
168 // 5. Create bounding box
169 MakeBox(aBoxFaces);
170 //
171 // 6. Make volumes
172 BuildSolids(aLSR);
173 if (myErrorStatus) {
174 return;
175 }
176 //
177 // 7. Treat the result
178 RemoveBox(aLSR, aBoxFaces);
179 //
180 // 8. Fill internal shapes
181 FillInternalShapes(aLSR);
182 //
183 // 9. Build Result
184 BuildShape(aLSR);
185 //
186 // 10. History
187 PrepareHistory();
188 //
189 // 11. Post-treatment
190 PostTreat();
191}
192
193//=======================================================================
194//function : CollectFaces
195//purpose :
196//=======================================================================
197void BOPAlgo_MakerVolume::CollectFaces()
198{
199 UserBreak();
200 //
201 Standard_Integer i, aNbShapes;
202 BOPCol_ListIteratorOfListOfShape aIt;
203 //
204 aNbShapes = myDS->NbSourceShapes();
205 for (i = 0; i < aNbShapes; ++i) {
206 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
207 if (aSI.ShapeType() != TopAbs_FACE) {
208 continue;
209 }
210 //
211 const Bnd_Box& aB = aSI.Box();
212 myBBox.Add(aB);
213 //
214 const TopoDS_Shape& aF = aSI.Shape();
215 if (myImages.IsBound(aF)) {
216 const BOPCol_ListOfShape& aLFIm = myImages.Find(aF);
217 aIt.Initialize(aLFIm);
218 for (; aIt.More(); aIt.Next()) {
219 const TopoDS_Shape& aFIm = aIt.Value();
220 AddFace(aFIm, myFaces);
221 }
222 }
223 else {
224 AddFace(aF, myFaces);
225 }
226 }
227}
228
229//=======================================================================
230//function : MakeBox
231//purpose :
232//=======================================================================
233void BOPAlgo_MakerVolume::MakeBox(BOPCol_MapOfShape& theBoxFaces)
234{
235 UserBreak();
236 //
237 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, anExt;
238 //
0f04f1e1 239 anExt = sqrt(myBBox.SquareExtent()) * 0.5;
92ae0f2f 240 myBBox.Enlarge(anExt);
241 myBBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
242 //
243 gp_Pnt aPMin(aXmin, aYmin, aZmin),
244 aPMax(aXmax, aYmax, aZmax);
245 //
246 mySBox = BRepPrimAPI_MakeBox(aPMin, aPMax).Solid();
247 //
248 TopExp_Explorer aExp(mySBox, TopAbs_FACE);
249 for (; aExp.More(); aExp.Next()) {
250 const TopoDS_Shape& aF = aExp.Current();
251 myFaces.Append(aF);
252 theBoxFaces.Add(aF);
253 }
254}
255
256//=======================================================================
257//function : BuildSolids
258//purpose :
259//=======================================================================
260void BOPAlgo_MakerVolume::BuildSolids(BOPCol_ListOfShape& theLSR)
261{
262 UserBreak();
263 //
264 BOPAlgo_BuilderSolid aBS;
265 //
266 aBS.SetSolid(mySBox);
267 aBS.SetShapes(myFaces);
268 aBS.SetRunParallel(myRunParallel);
269 aBS.Perform();
270 if (aBS.ErrorStatus()) {
271 myErrorStatus = 103;
272 return;
273 }
274 //
275 theLSR = aBS.Areas();
276}
277
278//=======================================================================
279//function : TreatResult
280//purpose :
281//=======================================================================
282void BOPAlgo_MakerVolume::RemoveBox(BOPCol_ListOfShape& theLSR,
283 const BOPCol_MapOfShape& theBoxFaces)
284{
285 UserBreak();
286 //
287 BOPCol_ListIteratorOfListOfShape aIt;
288 TopExp_Explorer aExp;
289 Standard_Boolean bFound;
290 //
291 bFound = Standard_False;
292 aIt.Initialize(theLSR);
293 for (; aIt.More(); aIt.Next()) {
294 const TopoDS_Shape& aSR = aIt.Value();
295 //
296 aExp.Init(aSR, TopAbs_FACE);
297 for (; aExp.More(); aExp.Next()) {
298 const TopoDS_Shape& aF = aExp.Current();
299 if (theBoxFaces.Contains(aF)) {
300 bFound = Standard_True;
301 theLSR.Remove(aIt);
302 break;
303 }
304 }
305 if (bFound) {
306 break;
307 }
308 }
309}
310
311//=======================================================================
312//function : BuildShape
313//purpose :
314//=======================================================================
315void BOPAlgo_MakerVolume::BuildShape(const BOPCol_ListOfShape& theLSR)
316{
317 if (theLSR.Extent() == 1) {
318 myShape = theLSR.First();
319 }
320 else {
321 BRep_Builder aBB;
322 BOPCol_ListIteratorOfListOfShape aIt;
323 //
324 aIt.Initialize(theLSR);
325 for (; aIt.More(); aIt.Next()) {
326 const TopoDS_Shape& aSol = aIt.Value();
327 aBB.Add(myShape, aSol);
328 }
329 }
330}
331
332//=======================================================================
333//function : FillInternalShapes
334//purpose :
335//=======================================================================
336void BOPAlgo_MakerVolume::FillInternalShapes(const BOPCol_ListOfShape& theLSR)
337{
338 UserBreak();
339 //
340 Standard_Integer aNbSI;
341 TopAbs_ShapeEnum aType;
342 TopAbs_State aState;
343 TopoDS_Iterator aItS;
344 BRep_Builder aBB;
345 BOPCol_MapOfShape aMFence;
346 BOPCol_IndexedMapOfShape aMSS;
347 BOPCol_ListOfShape aLVE, aLSC, aLSIn;
348 BOPCol_ListIteratorOfListOfShape aIt, aIt1;
349 //
350 // 1. Collect shapes to process: vertices, edges, wires
351 const BOPCol_ListOfShape& anArguments = myDS->Arguments();
352 aIt.Initialize(anArguments);
353 for (; aIt.More(); aIt.Next()) {
354 const TopoDS_Shape& aS = aIt.Value();
355 TreatCompound(aS, aMFence, aLSC);
356 }
357 //
358 aIt.Initialize(aLSC);
359 for (; aIt.More(); aIt.Next()) {
360 const TopoDS_Shape& aS = aIt.Value();
361 aType = aS.ShapeType();
362 if (aType == TopAbs_WIRE) {
363 aItS.Initialize(aS);
364 for(; aItS.More(); aItS.Next()) {
365 const TopoDS_Shape& aE = aItS.Value();
366 if (aMFence.Add(aE)) {
367 aLVE.Append(aE);
368 }
369 }
370 }
371 else if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
372 aLVE.Append(aS);
373 }
374 }
375 //
376 aIt.Initialize(theLSR);
377 for (; aIt.More(); aIt.Next()) {
378 const TopoDS_Shape& aS = aIt.Value();
379 BOPTools::MapShapes(aS, TopAbs_EDGE, aMSS);
380 BOPTools::MapShapes(aS, TopAbs_VERTEX, aMSS);
381 }
382 //
383 aIt.Initialize(aLVE);
384 for (; aIt.More(); aIt.Next()) {
385 const TopoDS_Shape& aS = aIt.Value();
386 if (myImages.IsBound(aS)) {
387 const BOPCol_ListOfShape &aLSp = myImages.Find(aS);
388 aIt1.Initialize(aLSp);
389 for (; aIt1.More(); aIt1.Next()) {
390 const TopoDS_Shape& aSp = aIt1.Value();
391 if (aMSS.Add(aSp)) {
392 aLSIn.Append(aSp);
393 }
394 }
395 }
396 else {
397 if (aMSS.Add(aS)) {
398 aLSIn.Append(aS);
399 }
400 }
401 }
402 //
403 aNbSI = aLSIn.Extent();
404 if (!aNbSI) {
405 return;
406 }
407 //
408 // 2. Settle internal vertices and edges into solids
409 aIt.Initialize(theLSR);
410 for (; aIt.More(); aIt.Next()) {
411 TopoDS_Solid aSd = *(TopoDS_Solid*)&aIt.Value();
412 //
413 aIt1.Initialize(aLSIn);
414 for (; aIt1.More(); ) {
415 TopoDS_Shape aSI = aIt1.Value();
416 aSI.Orientation(TopAbs_INTERNAL);
417 //
418 aState = BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
419 if (aState == TopAbs_IN) {
420 aBB.Add(aSd, aSI);
421 aLSIn.Remove(aIt1);
422 }
423 else {
424 aIt1.Next();
425 }
426 }
427 }
428}
429
430//=======================================================================
431//function : AddFace
432//purpose :
433//=======================================================================
434void AddFace(const TopoDS_Shape& theF,
435 BOPCol_ListOfShape& theLF)
436{
437 TopoDS_Shape aFF = theF;
438 aFF.Orientation(TopAbs_FORWARD);
439 theLF.Append(aFF);
440 aFF.Orientation(TopAbs_REVERSED);
441 theLF.Append(aFF);
442}
443
444//=======================================================================
445//function : TreatCompound
446//purpose :
447//=======================================================================
448void TreatCompound(const TopoDS_Shape& theS,
449 BOPCol_MapOfShape& aMFence,
450 BOPCol_ListOfShape& theLS)
451{
452 TopAbs_ShapeEnum aType = theS.ShapeType();
453 if (aType != TopAbs_COMPOUND) {
454 if (aMFence.Add(theS)) {
455 theLS.Append(theS);
456 }
457 return;
458 }
459 //
460 TopoDS_Iterator aIt(theS);
461 for (; aIt.More(); aIt.Next()) {
462 const TopoDS_Shape& aS = aIt.Value();
463 TreatCompound(aS, aMFence, theLS);
464 }
465}
466