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);
103 pPF->SetNonDestructive(myNonDestructive);
107 PerformInternal(*pPF);
110 //=======================================================================
111 //function : PerformInternal1
113 //=======================================================================
114 void BOPAlgo_MakerVolume::PerformInternal1
115 (const BOPAlgo_PaveFiller& theFiller)
119 myPaveFiller = (BOPAlgo_PaveFiller*)&theFiller;
120 myDS = myPaveFiller->PDS();
121 myContext = myPaveFiller->Context();
138 FillImagesVertices();
148 FillImagesContainers(TopAbs_WIRE);
165 BOPCol_MapOfShape aBoxFaces;
166 BOPCol_ListOfShape aLSR;
168 // 5. Create bounding box
177 // 7. Treat the result
178 RemoveBox(aLSR, aBoxFaces);
180 // 8. Fill internal shapes
181 FillInternalShapes(aLSR);
189 // 11. Post-treatment
193 //=======================================================================
194 //function : CollectFaces
196 //=======================================================================
197 void BOPAlgo_MakerVolume::CollectFaces()
201 Standard_Integer i, aNbShapes;
202 BOPCol_ListIteratorOfListOfShape aIt;
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) {
211 const Bnd_Box& aB = aSI.Box();
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);
224 AddFace(aF, myFaces);
229 //=======================================================================
232 //=======================================================================
233 void BOPAlgo_MakerVolume::MakeBox(BOPCol_MapOfShape& theBoxFaces)
237 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, anExt;
239 anExt = sqrt(myBBox.SquareExtent()) * 0.5;
240 myBBox.Enlarge(anExt);
241 myBBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
243 gp_Pnt aPMin(aXmin, aYmin, aZmin),
244 aPMax(aXmax, aYmax, aZmax);
246 mySBox = BRepPrimAPI_MakeBox(aPMin, aPMax).Solid();
248 TopExp_Explorer aExp(mySBox, TopAbs_FACE);
249 for (; aExp.More(); aExp.Next()) {
250 const TopoDS_Shape& aF = aExp.Current();
256 //=======================================================================
257 //function : BuildSolids
259 //=======================================================================
260 void BOPAlgo_MakerVolume::BuildSolids(BOPCol_ListOfShape& theLSR)
264 BOPAlgo_BuilderSolid aBS;
266 aBS.SetSolid(mySBox);
267 aBS.SetShapes(myFaces);
268 aBS.SetRunParallel(myRunParallel);
270 if (aBS.ErrorStatus()) {
275 theLSR = aBS.Areas();
278 //=======================================================================
279 //function : TreatResult
281 //=======================================================================
282 void BOPAlgo_MakerVolume::RemoveBox(BOPCol_ListOfShape& theLSR,
283 const BOPCol_MapOfShape& theBoxFaces)
287 BOPCol_ListIteratorOfListOfShape aIt;
288 TopExp_Explorer aExp;
289 Standard_Boolean bFound;
291 bFound = Standard_False;
292 aIt.Initialize(theLSR);
293 for (; aIt.More(); aIt.Next()) {
294 const TopoDS_Shape& aSR = aIt.Value();
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;
311 //=======================================================================
312 //function : BuildShape
314 //=======================================================================
315 void BOPAlgo_MakerVolume::BuildShape(const BOPCol_ListOfShape& theLSR)
317 if (theLSR.Extent() == 1) {
318 myShape = theLSR.First();
322 BOPCol_ListIteratorOfListOfShape aIt;
324 aIt.Initialize(theLSR);
325 for (; aIt.More(); aIt.Next()) {
326 const TopoDS_Shape& aSol = aIt.Value();
327 aBB.Add(myShape, aSol);
332 //=======================================================================
333 //function : FillInternalShapes
335 //=======================================================================
336 void BOPAlgo_MakerVolume::FillInternalShapes(const BOPCol_ListOfShape& theLSR)
340 Standard_Integer aNbSI;
341 TopAbs_ShapeEnum aType;
343 TopoDS_Iterator aItS;
345 BOPCol_MapOfShape aMFence;
346 BOPCol_IndexedMapOfShape aMSS;
347 BOPCol_ListOfShape aLVE, aLSC, aLSIn;
348 BOPCol_ListIteratorOfListOfShape aIt, aIt1;
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);
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) {
364 for(; aItS.More(); aItS.Next()) {
365 const TopoDS_Shape& aE = aItS.Value();
366 if (aMFence.Add(aE)) {
371 else if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
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);
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();
403 aNbSI = aLSIn.Extent();
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();
413 aIt1.Initialize(aLSIn);
414 for (; aIt1.More(); ) {
415 TopoDS_Shape aSI = aIt1.Value();
416 aSI.Orientation(TopAbs_INTERNAL);
418 aState = BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
419 if (aState == TopAbs_IN) {
430 //=======================================================================
433 //=======================================================================
434 void AddFace(const TopoDS_Shape& theF,
435 BOPCol_ListOfShape& theLF)
437 TopoDS_Shape aFF = theF;
438 aFF.Orientation(TopAbs_FORWARD);
440 aFF.Orientation(TopAbs_REVERSED);
444 //=======================================================================
445 //function : TreatCompound
447 //=======================================================================
448 void TreatCompound(const TopoDS_Shape& theS,
449 BOPCol_MapOfShape& aMFence,
450 BOPCol_ListOfShape& theLS)
452 TopAbs_ShapeEnum aType = theS.ShapeType();
453 if (aType != TopAbs_COMPOUND) {
454 if (aMFence.Add(theS)) {
460 TopoDS_Iterator aIt(theS);
461 for (; aIt.More(); aIt.Next()) {
462 const TopoDS_Shape& aS = aIt.Value();
463 TreatCompound(aS, aMFence, theLS);