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