1 // Created by: Eugeny MALTCHIKOV
2 // Copyright (c) 2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <Bnd_Box.hxx>
16 #include <BOPAlgo_BuilderSolid.hxx>
17 #include <BOPAlgo_MakerVolume.hxx>
18 #include <BOPAlgo_PaveFiller.hxx>
19 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
20 #include <BOPCol_ListOfShape.hxx>
21 #include <BOPDS_DS.hxx>
22 #include <BOPTools.hxx>
23 #include <BOPTools_AlgoTools.hxx>
24 #include <BRepPrimAPI_MakeBox.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopoDS_Solid.hxx>
29 void AddFace(const TopoDS_Shape& theF,
30 BOPCol_ListOfShape& theLF);
32 void TreatCompound(const TopoDS_Shape& theS,
33 BOPCol_MapOfShape& aMFence,
34 BOPCol_ListOfShape& theLS);
36 //=======================================================================
37 //function : CheckData
39 //=======================================================================
40 void BOPAlgo_MakerVolume::CheckData()
42 if (myArguments.IsEmpty()) {
43 myErrorStatus = 100; // no arguments to process
52 myErrorStatus = myPaveFiller->ErrorStatus();
54 myErrorStatus = 102; // PaveFiller is failed
59 //=======================================================================
62 //=======================================================================
63 void BOPAlgo_MakerVolume::Perform()
67 if (myEntryPoint == 1) {
74 Handle(NCollection_BaseAllocator) aAllocator =
75 NCollection_BaseAllocator::CommonBaseAllocator();
76 BOPAlgo_PaveFiller* pPF = new BOPAlgo_PaveFiller(aAllocator);
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;
83 BOPCol_ListIteratorOfListOfShape aIt;
84 BOPCol_ListOfShape aLS;
86 aBB.MakeCompound(anArgs);
87 aIt.Initialize(myArguments);
88 for (; aIt.More(); aIt.Next()) {
89 const TopoDS_Shape& aS = aIt.Value();
94 pPF->SetArguments(aLS);
97 pPF->SetArguments(myArguments);
100 pPF->SetRunParallel(myRunParallel);
101 pPF->SetProgressIndicator(myProgressIndicator);
102 pPF->SetFuzzyValue(myFuzzyValue);
106 PerformInternal(*pPF);
109 //=======================================================================
110 //function : PerformInternal1
112 //=======================================================================
113 void BOPAlgo_MakerVolume::PerformInternal1
114 (const BOPAlgo_PaveFiller& theFiller)
118 myPaveFiller = (BOPAlgo_PaveFiller*)&theFiller;
119 myDS = myPaveFiller->PDS();
120 myContext = myPaveFiller->Context();
137 FillImagesVertices();
147 FillImagesContainers(TopAbs_WIRE);
164 BOPCol_MapOfShape aBoxFaces;
165 BOPCol_ListOfShape aLSR;
167 // 5. Create bounding box
176 // 7. Treat the result
177 RemoveBox(aLSR, aBoxFaces);
179 // 8. Fill internal shapes
180 FillInternalShapes(aLSR);
188 // 11. Post-treatment
192 //=======================================================================
193 //function : CollectFaces
195 //=======================================================================
196 void BOPAlgo_MakerVolume::CollectFaces()
200 Standard_Integer i, aNbShapes;
201 BOPCol_ListIteratorOfListOfShape aIt;
203 aNbShapes = myDS->NbSourceShapes();
204 for (i = 0; i < aNbShapes; ++i) {
205 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
206 if (aSI.ShapeType() != TopAbs_FACE) {
210 const Bnd_Box& aB = aSI.Box();
213 const TopoDS_Shape& aF = aSI.Shape();
214 if (myImages.IsBound(aF)) {
215 const BOPCol_ListOfShape& aLFIm = myImages.Find(aF);
216 aIt.Initialize(aLFIm);
217 for (; aIt.More(); aIt.Next()) {
218 const TopoDS_Shape& aFIm = aIt.Value();
219 AddFace(aFIm, myFaces);
223 AddFace(aF, myFaces);
228 //=======================================================================
231 //=======================================================================
232 void BOPAlgo_MakerVolume::MakeBox(BOPCol_MapOfShape& theBoxFaces)
236 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, anExt;
238 anExt = sqrt(myBBox.SquareExtent()) * 0.5;
239 myBBox.Enlarge(anExt);
240 myBBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
242 gp_Pnt aPMin(aXmin, aYmin, aZmin),
243 aPMax(aXmax, aYmax, aZmax);
245 mySBox = BRepPrimAPI_MakeBox(aPMin, aPMax).Solid();
247 TopExp_Explorer aExp(mySBox, TopAbs_FACE);
248 for (; aExp.More(); aExp.Next()) {
249 const TopoDS_Shape& aF = aExp.Current();
255 //=======================================================================
256 //function : BuildSolids
258 //=======================================================================
259 void BOPAlgo_MakerVolume::BuildSolids(BOPCol_ListOfShape& theLSR)
263 BOPAlgo_BuilderSolid aBS;
265 aBS.SetSolid(mySBox);
266 aBS.SetShapes(myFaces);
267 aBS.SetRunParallel(myRunParallel);
269 if (aBS.ErrorStatus()) {
274 theLSR = aBS.Areas();
277 //=======================================================================
278 //function : TreatResult
280 //=======================================================================
281 void BOPAlgo_MakerVolume::RemoveBox(BOPCol_ListOfShape& theLSR,
282 const BOPCol_MapOfShape& theBoxFaces)
286 BOPCol_ListIteratorOfListOfShape aIt;
287 TopExp_Explorer aExp;
288 Standard_Boolean bFound;
290 bFound = Standard_False;
291 aIt.Initialize(theLSR);
292 for (; aIt.More(); aIt.Next()) {
293 const TopoDS_Shape& aSR = aIt.Value();
295 aExp.Init(aSR, TopAbs_FACE);
296 for (; aExp.More(); aExp.Next()) {
297 const TopoDS_Shape& aF = aExp.Current();
298 if (theBoxFaces.Contains(aF)) {
299 bFound = Standard_True;
310 //=======================================================================
311 //function : BuildShape
313 //=======================================================================
314 void BOPAlgo_MakerVolume::BuildShape(const BOPCol_ListOfShape& theLSR)
316 if (theLSR.Extent() == 1) {
317 myShape = theLSR.First();
321 BOPCol_ListIteratorOfListOfShape aIt;
323 aIt.Initialize(theLSR);
324 for (; aIt.More(); aIt.Next()) {
325 const TopoDS_Shape& aSol = aIt.Value();
326 aBB.Add(myShape, aSol);
331 //=======================================================================
332 //function : FillInternalShapes
334 //=======================================================================
335 void BOPAlgo_MakerVolume::FillInternalShapes(const BOPCol_ListOfShape& theLSR)
339 Standard_Integer aNbSI;
340 TopAbs_ShapeEnum aType;
342 TopoDS_Iterator aItS;
344 BOPCol_MapOfShape aMFence;
345 BOPCol_IndexedMapOfShape aMSS;
346 BOPCol_ListOfShape aLVE, aLSC, aLSIn;
347 BOPCol_ListIteratorOfListOfShape aIt, aIt1;
349 // 1. Collect shapes to process: vertices, edges, wires
350 const BOPCol_ListOfShape& anArguments = myDS->Arguments();
351 aIt.Initialize(anArguments);
352 for (; aIt.More(); aIt.Next()) {
353 const TopoDS_Shape& aS = aIt.Value();
354 TreatCompound(aS, aMFence, aLSC);
357 aIt.Initialize(aLSC);
358 for (; aIt.More(); aIt.Next()) {
359 const TopoDS_Shape& aS = aIt.Value();
360 aType = aS.ShapeType();
361 if (aType == TopAbs_WIRE) {
363 for(; aItS.More(); aItS.Next()) {
364 const TopoDS_Shape& aE = aItS.Value();
365 if (aMFence.Add(aE)) {
370 else if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
375 aIt.Initialize(theLSR);
376 for (; aIt.More(); aIt.Next()) {
377 const TopoDS_Shape& aS = aIt.Value();
378 BOPTools::MapShapes(aS, TopAbs_EDGE, aMSS);
379 BOPTools::MapShapes(aS, TopAbs_VERTEX, aMSS);
382 aIt.Initialize(aLVE);
383 for (; aIt.More(); aIt.Next()) {
384 const TopoDS_Shape& aS = aIt.Value();
385 if (myImages.IsBound(aS)) {
386 const BOPCol_ListOfShape &aLSp = myImages.Find(aS);
387 aIt1.Initialize(aLSp);
388 for (; aIt1.More(); aIt1.Next()) {
389 const TopoDS_Shape& aSp = aIt1.Value();
402 aNbSI = aLSIn.Extent();
407 // 2. Settle internal vertices and edges into solids
408 aIt.Initialize(theLSR);
409 for (; aIt.More(); aIt.Next()) {
410 TopoDS_Solid aSd = *(TopoDS_Solid*)&aIt.Value();
412 aIt1.Initialize(aLSIn);
413 for (; aIt1.More(); ) {
414 TopoDS_Shape aSI = aIt1.Value();
415 aSI.Orientation(TopAbs_INTERNAL);
417 aState = BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
418 if (aState == TopAbs_IN) {
429 //=======================================================================
432 //=======================================================================
433 void AddFace(const TopoDS_Shape& theF,
434 BOPCol_ListOfShape& theLF)
436 TopoDS_Shape aFF = theF;
437 aFF.Orientation(TopAbs_FORWARD);
439 aFF.Orientation(TopAbs_REVERSED);
443 //=======================================================================
444 //function : TreatCompound
446 //=======================================================================
447 void TreatCompound(const TopoDS_Shape& theS,
448 BOPCol_MapOfShape& aMFence,
449 BOPCol_ListOfShape& theLS)
451 TopAbs_ShapeEnum aType = theS.ShapeType();
452 if (aType != TopAbs_COMPOUND) {
453 if (aMFence.Add(theS)) {
459 TopoDS_Iterator aIt(theS);
460 for (; aIt.More(); aIt.Next()) {
461 const TopoDS_Shape& aS = aIt.Value();
462 TreatCompound(aS, aMFence, theLS);