| 1 | // Created by: Peter KURNEV |
| 2 | // Copyright (c) 2010-2014 OPEN CASCADE SAS |
| 3 | // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE |
| 4 | // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, |
| 5 | // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS |
| 6 | // |
| 7 | // This file is part of Open CASCADE Technology software library. |
| 8 | // |
| 9 | // This library is free software; you can redistribute it and / or modify it |
| 10 | // under the terms of the GNU Lesser General Public version 2.1 as published |
| 11 | // by the Free Software Foundation, with special exception defined in the file |
| 12 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 13 | // distribution for complete text of the license and disclaimer of any warranty. |
| 14 | // |
| 15 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 16 | // commercial license or contractual agreement. |
| 17 | |
| 18 | #include <BOPAlgo_Builder.hxx> |
| 19 | |
| 20 | #include <NCollection_IncAllocator.hxx> |
| 21 | |
| 22 | #include <TopAbs_State.hxx> |
| 23 | |
| 24 | #include <TopoDS.hxx> |
| 25 | #include <TopoDS_Iterator.hxx> |
| 26 | #include <TopoDS_Solid.hxx> |
| 27 | #include <TopoDS_Shape.hxx> |
| 28 | #include <TopoDS_Face.hxx> |
| 29 | #include <TopoDS_Edge.hxx> |
| 30 | #include <TopoDS_Solid.hxx> |
| 31 | #include <TopoDS_Iterator.hxx> |
| 32 | #include <TopoDS_Shell.hxx> |
| 33 | #include <TopoDS_Compound.hxx> |
| 34 | |
| 35 | #include <TopExp.hxx> |
| 36 | #include <TopExp_Explorer.hxx> |
| 37 | |
| 38 | #include <BRep_Builder.hxx> |
| 39 | #include <BRepTools.hxx> |
| 40 | #include <BRepClass3d_SolidClassifier.hxx> |
| 41 | // |
| 42 | #include <BOPCol_IndexedMapOfShape.hxx> |
| 43 | #include <BOPCol_MapOfShape.hxx> |
| 44 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
| 45 | #include <BOPCol_ListOfShape.hxx> |
| 46 | // |
| 47 | #include <BOPDS_DS.hxx> |
| 48 | #include <BOPDS_ShapeInfo.hxx> |
| 49 | // |
| 50 | #include <BOPTools.hxx> |
| 51 | #include <BOPTools_AlgoTools.hxx> |
| 52 | // |
| 53 | #include <BOPTools_MapOfSet.hxx> |
| 54 | #include <BOPTools_Set.hxx> |
| 55 | // |
| 56 | #include <BOPAlgo_BuilderSolid.hxx> |
| 57 | |
| 58 | #include <BOPCol_DataMapOfIntegerShape.hxx> |
| 59 | #include <Bnd_Box.hxx> |
| 60 | #include <BRepBndLib.hxx> |
| 61 | |
| 62 | #include <NCollection_UBTreeFiller.hxx> |
| 63 | #include <BOPDS_BoxBndTree.hxx> |
| 64 | #include <BOPCol_ListOfInteger.hxx> |
| 65 | #include <BOPInt_Context.hxx> |
| 66 | |
| 67 | |
| 68 | static |
| 69 | Standard_Boolean IsClosedShell(const TopoDS_Shell& aSh); |
| 70 | |
| 71 | static |
| 72 | void OwnInternalShapes(const TopoDS_Shape& , |
| 73 | BOPCol_IndexedMapOfShape& ); |
| 74 | |
| 75 | static |
| 76 | void TreatCompound(const TopoDS_Shape& theS, |
| 77 | BOPCol_MapOfShape& aMFence, |
| 78 | BOPCol_ListOfShape& theLS); |
| 79 | |
| 80 | //======================================================================= |
| 81 | //class : BOPAlgo_ShapeBox |
| 82 | //purpose : Auxiliary class |
| 83 | //======================================================================= |
| 84 | class BOPAlgo_ShapeBox { |
| 85 | public: |
| 86 | BOPAlgo_ShapeBox() { |
| 87 | }; |
| 88 | // |
| 89 | ~BOPAlgo_ShapeBox() { |
| 90 | }; |
| 91 | // |
| 92 | void SetShape(const TopoDS_Shape& aS) { |
| 93 | myShape=aS; |
| 94 | }; |
| 95 | // |
| 96 | const TopoDS_Shape& Shape()const { |
| 97 | return myShape; |
| 98 | }; |
| 99 | // |
| 100 | void SetBox(const Bnd_Box& aBox) { |
| 101 | myBox=aBox; |
| 102 | }; |
| 103 | // |
| 104 | const Bnd_Box& Box()const { |
| 105 | return myBox; |
| 106 | }; |
| 107 | // |
| 108 | protected: |
| 109 | TopoDS_Shape myShape; |
| 110 | Bnd_Box myBox; |
| 111 | }; |
| 112 | // |
| 113 | typedef NCollection_DataMap\ |
| 114 | <Standard_Integer, BOPAlgo_ShapeBox, TColStd_MapIntegerHasher> \ |
| 115 | BOPAlgo_DataMapOfIntegerShapeBox; |
| 116 | // |
| 117 | typedef BOPAlgo_DataMapOfIntegerShapeBox::Iterator \ |
| 118 | BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox; |
| 119 | // |
| 120 | |
| 121 | //======================================================================= |
| 122 | //function : FillImagesSolids |
| 123 | //purpose : |
| 124 | //======================================================================= |
| 125 | void BOPAlgo_Builder::FillImagesSolids() |
| 126 | { |
| 127 | Standard_Boolean bHasSolids; |
| 128 | Standard_Integer i, aNbS; |
| 129 | // |
| 130 | myErrorStatus=0; |
| 131 | // |
| 132 | bHasSolids=Standard_False; |
| 133 | aNbS=myDS->NbSourceShapes(); |
| 134 | for (i=0; i<aNbS; ++i) { |
| 135 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
| 136 | if (aSI.ShapeType()==TopAbs_SOLID) { |
| 137 | bHasSolids=!bHasSolids; |
| 138 | break; |
| 139 | } |
| 140 | } |
| 141 | // |
| 142 | if (!bHasSolids) { |
| 143 | return; |
| 144 | } |
| 145 | // |
| 146 | Handle(NCollection_IncAllocator) aAlr; |
| 147 | // |
| 148 | aAlr=new NCollection_IncAllocator(); |
| 149 | // |
| 150 | BOPCol_DataMapOfShapeListOfShape theInParts(100, aAlr); |
| 151 | BOPCol_DataMapOfShapeShape theDraftSolids(100, aAlr); |
| 152 | // |
| 153 | FillIn3DParts(theInParts, theDraftSolids, aAlr); |
| 154 | BuildSplitSolids(theInParts, theDraftSolids, aAlr); |
| 155 | FillInternalShapes(); |
| 156 | // |
| 157 | theInParts.Clear(); |
| 158 | theDraftSolids.Clear(); |
| 159 | } |
| 160 | //======================================================================= |
| 161 | //function : FillIn3DParts |
| 162 | //purpose : |
| 163 | //======================================================================= |
| 164 | void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts, |
| 165 | BOPCol_DataMapOfShapeShape& theDraftSolids, |
| 166 | const BOPCol_BaseAllocator& ) |
| 167 | { |
| 168 | Standard_Boolean bHasImage; |
| 169 | Standard_Integer i, k, aNbS, aNbLIF, nFP, aNbFP, aNbFIN, iIsIN; |
| 170 | TopoDS_Solid aSD; |
| 171 | TopoDS_Iterator aIt; |
| 172 | BRep_Builder aBB; |
| 173 | BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1; |
| 174 | BOPCol_ListIteratorOfListOfShape aItLS; |
| 175 | BOPAlgo_ShapeBox aSB; |
| 176 | Handle(NCollection_IncAllocator) aAlr0; |
| 177 | // |
| 178 | aAlr0=new NCollection_IncAllocator(); |
| 179 | BOPAlgo_DataMapOfIntegerShapeBox aDMISB(100, aAlr0); |
| 180 | BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox aItDMISB; |
| 181 | // |
| 182 | myErrorStatus=0; |
| 183 | theDraftSolids.Clear(); |
| 184 | // |
| 185 | // 1. aDMISB map Index/FaceBox |
| 186 | k=0; |
| 187 | aNbS=myDS->NbSourceShapes(); |
| 188 | for (i=0; i<aNbS; ++i) { |
| 189 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
| 190 | if (aSI.ShapeType()!=TopAbs_FACE) { |
| 191 | continue; |
| 192 | } |
| 193 | // |
| 194 | const TopoDS_Shape& aS=aSI.Shape(); |
| 195 | // |
| 196 | if (myImages.IsBound(aS)) { |
| 197 | const BOPCol_ListOfShape& aLS=myImages.Find(aS); |
| 198 | aItLS.Initialize(aLS); |
| 199 | for (; aItLS.More(); aItLS.Next()) { |
| 200 | const TopoDS_Shape& aSx=aItLS.Value(); |
| 201 | // |
| 202 | Bnd_Box aBox; |
| 203 | BRepBndLib::Add(aSx, aBox); |
| 204 | // |
| 205 | aSB.SetShape(aSx); |
| 206 | aSB.SetBox(aBox); |
| 207 | // |
| 208 | aDMISB.Bind(k, aSB); |
| 209 | ++k; |
| 210 | } |
| 211 | } |
| 212 | else { |
| 213 | const Bnd_Box& aBox=aSI.Box(); |
| 214 | // |
| 215 | aSB.SetShape(aS); |
| 216 | aSB.SetBox(aBox); |
| 217 | // |
| 218 | aDMISB.Bind(k, aSB); |
| 219 | ++k; |
| 220 | } |
| 221 | }//for (i=0; i<aNbS; ++i) { |
| 222 | // |
| 223 | // 2. Solids |
| 224 | for (i=0; i<aNbS; ++i) { |
| 225 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
| 226 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
| 227 | continue; |
| 228 | } |
| 229 | // |
| 230 | //--------------------------------------------- |
| 231 | Handle(NCollection_IncAllocator) aAlr1; |
| 232 | // |
| 233 | aAlr1=new NCollection_IncAllocator(); |
| 234 | // |
| 235 | BOPCol_ListOfShape aLFIN(aAlr1); |
| 236 | BOPCol_ListOfShape aLIF(aAlr1); |
| 237 | BOPCol_IndexedMapOfShape aMF(100, aAlr1); |
| 238 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1); |
| 239 | // |
| 240 | BOPDS_BoxBndTreeSelector aSelector; |
| 241 | BOPDS_BoxBndTree aBBTree; |
| 242 | NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree); |
| 243 | Bnd_Box aBoxS; |
| 244 | // |
| 245 | const TopoDS_Shape& aS=aSI.Shape(); |
| 246 | const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS)); |
| 247 | // |
| 248 | // 2.0 Flag bHasImage |
| 249 | bHasImage=Standard_False; |
| 250 | aIt.Initialize(aS); |
| 251 | for (; aIt.More(); aIt.Next()) { |
| 252 | const TopoDS_Shape& aShell=aIt.Value(); |
| 253 | bHasImage=myImages.IsBound(aShell); |
| 254 | if (bHasImage){ |
| 255 | break; |
| 256 | } |
| 257 | } |
| 258 | // |
| 259 | // 2.1 Compute Bnd_Box for the solid aS [ aBoxS ] |
| 260 | BuildBndBox(i, aBoxS); |
| 261 | //----- |
| 262 | // |
| 263 | // 2.2 Build Draft Solid [aSD] |
| 264 | aBB.MakeSolid(aSD); |
| 265 | // |
| 266 | BuildDraftSolid(aSolid, aSD, aLIF); |
| 267 | aNbLIF=aLIF.Extent(); |
| 268 | // |
| 269 | BOPTools::MapShapesAndAncestors(aSD, TopAbs_EDGE, TopAbs_FACE, aMEF); |
| 270 | // |
| 271 | // 2.3 Faces from aSD and own internal faces => aMF |
| 272 | BOPTools::MapShapes(aSD, TopAbs_FACE, aMF); |
| 273 | // |
| 274 | aItLS.Initialize(aLIF); |
| 275 | for (; aItLS.More(); aItLS.Next()) { |
| 276 | const TopoDS_Shape& aFI=aItLS.Value(); |
| 277 | aMF.Add(aFI); |
| 278 | } |
| 279 | // |
| 280 | // 2.4. Prepare TreeFiller |
| 281 | aItDMISB.Initialize(aDMISB); |
| 282 | for (; aItDMISB.More(); aItDMISB.Next()) { |
| 283 | k=aItDMISB.Key(); |
| 284 | const BOPAlgo_ShapeBox& aSBk=aItDMISB.Value(); |
| 285 | const TopoDS_Shape& aFk=aSBk.Shape(); |
| 286 | if (aMF.Contains(aFk)) { |
| 287 | continue; |
| 288 | } |
| 289 | // |
| 290 | const Bnd_Box& aBk=aSBk.Box(); |
| 291 | // |
| 292 | aTreeFiller.Add(k, aBk); |
| 293 | } |
| 294 | // |
| 295 | // 2.5. Shake TreeFiller |
| 296 | aTreeFiller.Fill(); |
| 297 | // |
| 298 | // 2.6. Select boxes of faces that are not out of aBoxS |
| 299 | aSelector.Clear(); |
| 300 | aSelector.SetBox(aBoxS); |
| 301 | // |
| 302 | aNbFP=aBBTree.Select(aSelector); |
| 303 | // |
| 304 | const BOPCol_ListOfInteger& aLIFP=aSelector.Indices(); |
| 305 | // |
| 306 | // 2.7. Collect faces that are IN aSolid [ aLFIN ] |
| 307 | BOPCol_ListOfShape aLFP(aAlr1); |
| 308 | BOPCol_ListOfShape aLCBF(aAlr1); |
| 309 | BOPCol_MapOfShape aMFDone(100, aAlr1); |
| 310 | BOPCol_IndexedMapOfShape aME(100, aAlr1); |
| 311 | // |
| 312 | BOPTools::MapShapes(aSD, TopAbs_EDGE, aME); |
| 313 | // |
| 314 | aItLI.Initialize(aLIFP); |
| 315 | for (; aItLI.More(); aItLI.Next()) { |
| 316 | nFP=aItLI.Value(); |
| 317 | const BOPAlgo_ShapeBox& aSBF=aDMISB.Find(nFP); |
| 318 | const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape()); |
| 319 | if (aMFDone.Contains(aFP)) { |
| 320 | continue; |
| 321 | } |
| 322 | // |
| 323 | aMFDone.Add(aFP); |
| 324 | // |
| 325 | iIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSD, aMEF, 1.e-14, myContext); |
| 326 | // |
| 327 | aLFP.Clear(); |
| 328 | aLFP.Append(aFP); |
| 329 | // |
| 330 | aItLI1.Initialize(aLIFP); |
| 331 | for (; aItLI1.More(); aItLI1.Next()) { |
| 332 | const TopoDS_Shape& aFx=aDMISB.Find(aItLI1.Value()).Shape(); |
| 333 | if (!aMFDone.Contains(aFx)) { |
| 334 | aLFP.Append(aFx); |
| 335 | } |
| 336 | } |
| 337 | // |
| 338 | aLCBF.Clear(); |
| 339 | //---------------------------------------- |
| 340 | { |
| 341 | Handle(NCollection_IncAllocator) aAlr2; |
| 342 | aAlr2=new NCollection_IncAllocator(); |
| 343 | // |
| 344 | BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aME, aLCBF, aAlr2); |
| 345 | } |
| 346 | //---------------------------------------- |
| 347 | aItLS.Initialize(aLCBF); |
| 348 | for (; aItLS.More(); aItLS.Next()) { |
| 349 | const TopoDS_Shape& aFx=aItLS.Value(); |
| 350 | aMFDone.Add(aFx); |
| 351 | if (iIsIN) { |
| 352 | aLFIN.Append(aFx); |
| 353 | } |
| 354 | } |
| 355 | }// for (; aItLI.More(); aItLI.Next()) { |
| 356 | // |
| 357 | // 2.8. Store the results in theInParts, theDraftSolids |
| 358 | aNbFIN=aLFIN.Extent(); |
| 359 | if (aNbFIN || aNbLIF) { |
| 360 | aItLS.Initialize(aLIF); |
| 361 | for (; aItLS.More(); aItLS.Next()) { |
| 362 | const TopoDS_Shape& aFI=aItLS.Value(); |
| 363 | aLFIN.Append(aFI); |
| 364 | } |
| 365 | theInParts.Bind(aSolid, aLFIN); |
| 366 | } |
| 367 | // |
| 368 | if (aNbFIN || bHasImage) { |
| 369 | theDraftSolids.Bind(aSolid, aSD); |
| 370 | } |
| 371 | //--------------------------------------------- |
| 372 | }// for (i=0; i<aNbS; ++i) { |
| 373 | } |
| 374 | |
| 375 | //======================================================================= |
| 376 | //function : BuildDraftSolid |
| 377 | //purpose : |
| 378 | //======================================================================= |
| 379 | void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid, |
| 380 | TopoDS_Shape& theDraftSolid, |
| 381 | BOPCol_ListOfShape& theLIF) |
| 382 | { |
| 383 | myErrorStatus=0; |
| 384 | // |
| 385 | Standard_Boolean bToReverse; |
| 386 | Standard_Integer iFlag; |
| 387 | TopAbs_Orientation aOrF, aOrSh, aOrSd; |
| 388 | TopoDS_Iterator aIt1, aIt2; |
| 389 | TopoDS_Shell aShD; |
| 390 | TopoDS_Shape aFSDx, aFx; |
| 391 | BRep_Builder aBB; |
| 392 | BOPCol_ListIteratorOfListOfShape aItS; |
| 393 | // |
| 394 | aOrSd=theSolid.Orientation(); |
| 395 | theDraftSolid.Orientation(aOrSd); |
| 396 | // |
| 397 | aIt1.Initialize(theSolid); |
| 398 | for (; aIt1.More(); aIt1.Next()) { |
| 399 | const TopoDS_Shape& aSh=aIt1.Value(); |
| 400 | if(aSh.ShapeType()!=TopAbs_SHELL) { |
| 401 | continue; // mb internal edges,vertices |
| 402 | } |
| 403 | // |
| 404 | aOrSh=aSh.Orientation(); |
| 405 | aBB.MakeShell(aShD); |
| 406 | aShD.Orientation(aOrSh); |
| 407 | iFlag=0; |
| 408 | // |
| 409 | aIt2.Initialize(aSh); |
| 410 | for (; aIt2.More(); aIt2.Next()) { |
| 411 | const TopoDS_Shape& aF=aIt2.Value(); |
| 412 | aOrF=aF.Orientation(); |
| 413 | // |
| 414 | if (myImages.IsBound(aF)) { |
| 415 | const BOPCol_ListOfShape& aLSp=myImages.Find(aF); |
| 416 | aItS.Initialize(aLSp); |
| 417 | for (; aItS.More(); aItS.Next()) { |
| 418 | aFx=aItS.Value(); |
| 419 | // |
| 420 | if (myShapesSD.IsBound(aFx)) { |
| 421 | aFSDx=myShapesSD.Find(aFx); |
| 422 | // |
| 423 | if (aOrF==TopAbs_INTERNAL) { |
| 424 | aFSDx.Orientation(aOrF); |
| 425 | theLIF.Append(aFSDx); |
| 426 | } |
| 427 | else { |
| 428 | bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aFSDx, aF, myContext); |
| 429 | if (bToReverse) { |
| 430 | aFSDx.Reverse(); |
| 431 | } |
| 432 | // |
| 433 | iFlag=1; |
| 434 | aBB.Add(aShD, aFSDx); |
| 435 | } |
| 436 | }//if (myShapesSD.IsBound(aFx)) { |
| 437 | else { |
| 438 | aFx.Orientation(aOrF); |
| 439 | if (aOrF==TopAbs_INTERNAL) { |
| 440 | theLIF.Append(aFx); |
| 441 | } |
| 442 | else{ |
| 443 | iFlag=1; |
| 444 | aBB.Add(aShD, aFx); |
| 445 | } |
| 446 | } |
| 447 | } |
| 448 | } // if (myImages.IsBound(aF)) { |
| 449 | // |
| 450 | else { |
| 451 | if (aOrF==TopAbs_INTERNAL) { |
| 452 | theLIF.Append(aF); |
| 453 | } |
| 454 | else{ |
| 455 | iFlag=1; |
| 456 | aBB.Add(aShD, aF); |
| 457 | } |
| 458 | } |
| 459 | } //for (; aIt2.More(); aIt2.Next()) { |
| 460 | // |
| 461 | if (iFlag) { |
| 462 | aBB.Add(theDraftSolid, aShD); |
| 463 | } |
| 464 | } //for (; aIt1.More(); aIt1.Next()) { |
| 465 | } |
| 466 | //======================================================================= |
| 467 | //function : BuildSplitSolids |
| 468 | //purpose : |
| 469 | //======================================================================= |
| 470 | void BOPAlgo_Builder::BuildSplitSolids(BOPCol_DataMapOfShapeListOfShape& theInParts, |
| 471 | BOPCol_DataMapOfShapeShape& theDraftSolids, |
| 472 | const BOPCol_BaseAllocator& ) |
| 473 | { |
| 474 | myErrorStatus=0; |
| 475 | // |
| 476 | Standard_Boolean bFlagSD; |
| 477 | Standard_Integer i, aNbS, iErr, aNbSFS; |
| 478 | TopExp_Explorer aExp; |
| 479 | BOPCol_ListIteratorOfListOfShape aIt; |
| 480 | BOPCol_DataMapIteratorOfDataMapOfShapeShape aIt1; |
| 481 | // |
| 482 | Handle(NCollection_IncAllocator) aAlr0; |
| 483 | aAlr0=new NCollection_IncAllocator(); |
| 484 | // |
| 485 | BOPCol_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0); |
| 486 | BOPCol_MapOfShape aMFence(100, aAlr0); |
| 487 | BOPTools_MapOfSet aMST(100, aAlr0); |
| 488 | // |
| 489 | // 0. Find same domain solids for non-interferred solids |
| 490 | aNbS=myDS->NbSourceShapes(); |
| 491 | for (i=0; i<aNbS; ++i) { |
| 492 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
| 493 | // |
| 494 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
| 495 | continue; |
| 496 | } |
| 497 | // |
| 498 | const TopoDS_Shape& aS=aSI.Shape(); |
| 499 | if (!aMFence.Add(aS)) { |
| 500 | continue; |
| 501 | } |
| 502 | if(theDraftSolids.IsBound(aS)) { |
| 503 | continue; |
| 504 | } |
| 505 | // |
| 506 | BOPTools_Set aST; |
| 507 | // |
| 508 | aST.Add(aS, TopAbs_FACE); |
| 509 | aMST.Add(aST); |
| 510 | // |
| 511 | } //for (i=1; i<=aNbS; ++i) |
| 512 | // |
| 513 | // 1. Build solids for interferred source solids |
| 514 | for (i=0; i<aNbS; ++i) { |
| 515 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
| 516 | // |
| 517 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
| 518 | continue; |
| 519 | } |
| 520 | // |
| 521 | const TopoDS_Shape& aS=aSI.Shape(); |
| 522 | if(!theDraftSolids.IsBound(aS)) { |
| 523 | continue; |
| 524 | } |
| 525 | const TopoDS_Shape& aSD=theDraftSolids.Find(aS); |
| 526 | const BOPCol_ListOfShape& aLFIN= |
| 527 | (theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty; |
| 528 | // |
| 529 | // 1.1 Fill Shell Faces Set |
| 530 | aSFS.Clear(); |
| 531 | aExp.Init(aSD, TopAbs_FACE); |
| 532 | for (; aExp.More(); aExp.Next()) { |
| 533 | const TopoDS_Shape& aF=aExp.Current(); |
| 534 | aSFS.Append(aF); |
| 535 | } |
| 536 | // |
| 537 | aIt.Initialize(aLFIN); |
| 538 | for (; aIt.More(); aIt.Next()) { |
| 539 | TopoDS_Shape aF=aIt.Value(); |
| 540 | // |
| 541 | aF.Orientation(TopAbs_FORWARD); |
| 542 | aSFS.Append(aF); |
| 543 | aF.Orientation(TopAbs_REVERSED); |
| 544 | aSFS.Append(aF); |
| 545 | } |
| 546 | // |
| 547 | aNbSFS=aSFS.Extent(); |
| 548 | // |
| 549 | // 1.3 Build new solids |
| 550 | Handle(NCollection_IncAllocator) aAlr1; |
| 551 | aAlr1=new NCollection_IncAllocator(); |
| 552 | // |
| 553 | BOPAlgo_BuilderSolid aSB(aAlr1); |
| 554 | // |
| 555 | //aSB.SetContext(myContext); |
| 556 | aSB.SetShapes(aSFS); |
| 557 | aSB.Perform(); |
| 558 | iErr=aSB.ErrorStatus(); |
| 559 | if (iErr) { |
| 560 | myErrorStatus=30; // SolidBuilder failed |
| 561 | return; |
| 562 | } |
| 563 | // |
| 564 | const BOPCol_ListOfShape& aLSR=aSB.Areas(); |
| 565 | // |
| 566 | // 1.4 Collect resulting solids and theirs set of faces. |
| 567 | // Update Images. |
| 568 | if (!myImages.IsBound(aS)) { |
| 569 | BOPCol_ListOfShape aLSx; |
| 570 | // |
| 571 | myImages.Bind(aS, aLSx); |
| 572 | BOPCol_ListOfShape& aLSIm=myImages.ChangeFind(aS); |
| 573 | // |
| 574 | aIt.Initialize(aLSR); |
| 575 | for (; aIt.More(); aIt.Next()) { |
| 576 | BOPTools_Set aST; |
| 577 | // |
| 578 | const TopoDS_Shape& aSR=aIt.Value(); |
| 579 | aST.Add(aSR, TopAbs_FACE); |
| 580 | // |
| 581 | bFlagSD=aMST.Contains(aST); |
| 582 | // |
| 583 | const BOPTools_Set& aSTx=aMST.Added(aST); |
| 584 | const TopoDS_Shape& aSx=aSTx.Shape(); |
| 585 | aLSIm.Append(aSx); |
| 586 | // |
| 587 | if (bFlagSD) { |
| 588 | myShapesSD.Bind(aSR, aSx); |
| 589 | } |
| 590 | } |
| 591 | } |
| 592 | }// for (i=0; i<aNbS; ++i) { |
| 593 | } |
| 594 | |
| 595 | //======================================================================= |
| 596 | //function :FillInternalShapes |
| 597 | //purpose : |
| 598 | //======================================================================= |
| 599 | void BOPAlgo_Builder::FillInternalShapes() |
| 600 | { |
| 601 | myErrorStatus=0; |
| 602 | // |
| 603 | Standard_Integer i, j, aNbS, aNbSI, aNbSx, aNbSd; |
| 604 | TopAbs_ShapeEnum aType; |
| 605 | TopAbs_State aState; |
| 606 | TopoDS_Iterator aItS; |
| 607 | BRep_Builder aBB; |
| 608 | BOPCol_MapIteratorOfMapOfShape aItM; |
| 609 | BOPCol_ListIteratorOfListOfShape aIt, aIt1; |
| 610 | // |
| 611 | Handle(NCollection_IncAllocator) aAllocator; |
| 612 | //-----------------------------------------------------scope f |
| 613 | aAllocator=new NCollection_IncAllocator(); |
| 614 | // |
| 615 | BOPCol_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator); |
| 616 | BOPCol_IndexedMapOfShape aMx(100, aAllocator); |
| 617 | BOPCol_MapOfShape aMSI(100, aAllocator); |
| 618 | BOPCol_MapOfShape aMFence(100, aAllocator); |
| 619 | BOPCol_MapOfShape aMSOr(100, aAllocator); |
| 620 | BOPCol_ListOfShape aLSd(aAllocator); |
| 621 | BOPCol_ListOfShape aLArgs(aAllocator); |
| 622 | BOPCol_ListOfShape aLSC(aAllocator); |
| 623 | // |
| 624 | // 1. Shapes to process |
| 625 | // |
| 626 | // 1.1 Shapes from pure arguments aMSI |
| 627 | // 1.1.1 vertex, edge, wire |
| 628 | // |
| 629 | aIt.Initialize(myArguments); |
| 630 | for (; aIt.More(); aIt.Next()) { |
| 631 | const TopoDS_Shape& aS=aIt.Value(); |
| 632 | TreatCompound(aS, aMFence, aLSC); |
| 633 | } |
| 634 | aIt.Initialize(aLSC); |
| 635 | for (; aIt.More(); aIt.Next()) { |
| 636 | const TopoDS_Shape& aS=aIt.Value(); |
| 637 | aType=aS.ShapeType(); |
| 638 | if (aType==TopAbs_WIRE) { |
| 639 | aItS.Initialize(aS); |
| 640 | for(; aItS.More(); aItS.Next()) { |
| 641 | const TopoDS_Shape& aE=aItS.Value(); |
| 642 | if (aMFence.Add(aE)) { |
| 643 | aLArgs.Append(aE); |
| 644 | } |
| 645 | } |
| 646 | } |
| 647 | else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){ |
| 648 | aLArgs.Append(aS); |
| 649 | } |
| 650 | } |
| 651 | aMFence.Clear(); |
| 652 | // |
| 653 | aIt.Initialize(aLArgs); |
| 654 | for (; aIt.More(); aIt.Next()) { |
| 655 | const TopoDS_Shape& aS=aIt.Value(); |
| 656 | aType=aS.ShapeType(); |
| 657 | if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE ||aType==TopAbs_WIRE) { |
| 658 | if (aMFence.Add(aS)) { |
| 659 | if (myImages.IsBound(aS)) { |
| 660 | const BOPCol_ListOfShape &aLSp=myImages.Find(aS); |
| 661 | aIt1.Initialize(aLSp); |
| 662 | for (; aIt1.More(); aIt1.Next()) { |
| 663 | const TopoDS_Shape& aSp=aIt1.Value(); |
| 664 | aMSI.Add(aSp); |
| 665 | } |
| 666 | } |
| 667 | else { |
| 668 | aMSI.Add(aS); |
| 669 | } |
| 670 | } |
| 671 | } |
| 672 | } |
| 673 | |
| 674 | aNbSI=aMSI.Extent(); |
| 675 | // |
| 676 | // 2. Internal vertices, edges from source solids |
| 677 | aMFence.Clear(); |
| 678 | aLSd.Clear(); |
| 679 | // |
| 680 | aNbS=myDS->NbSourceShapes(); |
| 681 | for (i=0; i<aNbS; ++i) { |
| 682 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
| 683 | // |
| 684 | if (aSI.ShapeType()!=TopAbs_SOLID) { |
| 685 | continue; |
| 686 | } |
| 687 | // |
| 688 | const TopoDS_Shape& aS=aSI.Shape(); |
| 689 | // |
| 690 | aMx.Clear(); |
| 691 | OwnInternalShapes(aS, aMx); |
| 692 | // |
| 693 | aNbSx=aMx.Extent(); |
| 694 | for (j=1; j<=aNbSx; ++j) { |
| 695 | const TopoDS_Shape& aSi=aMx(j); |
| 696 | if (myImages.IsBound(aSi)) { |
| 697 | const BOPCol_ListOfShape &aLSp=myImages.Find(aSi); |
| 698 | aIt1.Initialize(aLSp); |
| 699 | for (; aIt1.More(); aIt1.Next()) { |
| 700 | const TopoDS_Shape& aSp=aIt1.Value(); |
| 701 | aMSI.Add(aSp); |
| 702 | } |
| 703 | } |
| 704 | else { |
| 705 | aMSI.Add(aSi); |
| 706 | } |
| 707 | } |
| 708 | // |
| 709 | // build aux map from splits of solids |
| 710 | if (myImages.IsBound(aS)) { |
| 711 | const BOPCol_ListOfShape &aLSp=myImages.Find(aS); |
| 712 | aIt.Initialize(aLSp); |
| 713 | for (; aIt.More(); aIt.Next()) { |
| 714 | const TopoDS_Shape& aSp=aIt.Value(); |
| 715 | if (aMFence.Add(aSp)) { |
| 716 | BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
| 717 | BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
| 718 | BOPTools::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx); |
| 719 | aLSd.Append(aSp); |
| 720 | } |
| 721 | } |
| 722 | } |
| 723 | else { |
| 724 | if (aMFence.Add(aS)) { |
| 725 | BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx); |
| 726 | BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx); |
| 727 | BOPTools::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx); |
| 728 | aLSd.Append(aS); |
| 729 | aMSOr.Add(aS); |
| 730 | } |
| 731 | } |
| 732 | }// for (i=0; i<aNbS; ++i) { |
| 733 | // |
| 734 | aNbSd=aLSd.Extent(); |
| 735 | // |
| 736 | // 3. Some shapes of aMSI can be already tied with faces of |
| 737 | // split solids |
| 738 | aItM.Initialize(aMSI); |
| 739 | for (; aItM.More(); aItM.Next()) { |
| 740 | const TopoDS_Shape& aSI=aItM.Key(); |
| 741 | if (aMSx.Contains(aSI)) { |
| 742 | const BOPCol_ListOfShape &aLSx=aMSx.FindFromKey(aSI); |
| 743 | aNbSx=aLSx.Extent(); |
| 744 | if (aNbSx) { |
| 745 | aMSI.Remove(aSI); |
| 746 | } |
| 747 | } |
| 748 | } |
| 749 | // |
| 750 | // 4. Just check it |
| 751 | aNbSI=aMSI.Extent(); |
| 752 | if (!aNbSI) { |
| 753 | return; |
| 754 | } |
| 755 | // |
| 756 | // 5 Settle internal vertices and edges into solids |
| 757 | aMx.Clear(); |
| 758 | aIt.Initialize(aLSd); |
| 759 | for (; aIt.More(); aIt.Next()) { |
| 760 | TopoDS_Solid aSd=TopoDS::Solid(aIt.Value()); |
| 761 | // |
| 762 | aItM.Initialize(aMSI); |
| 763 | for (; aItM.More(); aItM.Next()) { |
| 764 | TopoDS_Shape aSI=aItM.Key(); |
| 765 | aSI.Orientation(TopAbs_INTERNAL); |
| 766 | // |
| 767 | aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext); |
| 768 | if (aState==TopAbs_IN) { |
| 769 | // |
| 770 | if(aMSOr.Contains(aSd)) { |
| 771 | // |
| 772 | TopoDS_Solid aSdx; |
| 773 | // |
| 774 | aBB.MakeSolid(aSdx); |
| 775 | aItS.Initialize(aSd); |
| 776 | for (; aItS.More(); aItS.Next()) { |
| 777 | const TopoDS_Shape& aSh=aItS.Value(); |
| 778 | aBB.Add(aSdx, aSh); |
| 779 | } |
| 780 | // |
| 781 | aBB.Add(aSdx, aSI); |
| 782 | // |
| 783 | if (myImages.IsBound(aSdx)) { |
| 784 | BOPCol_ListOfShape& aLS=myImages.ChangeFind(aSdx); |
| 785 | aLS.Append(aSdx); |
| 786 | } |
| 787 | else { |
| 788 | BOPCol_ListOfShape aLS; |
| 789 | aLS.Append(aSdx); |
| 790 | myImages.Bind(aSd, aLS); |
| 791 | } |
| 792 | // |
| 793 | aMSOr.Remove(aSd); |
| 794 | aSd=aSdx; |
| 795 | } |
| 796 | else { |
| 797 | aBB.Add(aSd, aSI); |
| 798 | } |
| 799 | // |
| 800 | aMSI.Remove(aSI); |
| 801 | } //if (aState==TopAbs_IN) { |
| 802 | }// for (; aItM.More(); aItM.Next()) { |
| 803 | }//for (; aIt1.More(); aIt1.Next()) { |
| 804 | // |
| 805 | //-----------------------------------------------------scope t |
| 806 | aLArgs.Clear(); |
| 807 | aLSd.Clear(); |
| 808 | aMSOr.Clear(); |
| 809 | aMFence.Clear(); |
| 810 | aMSI.Clear(); |
| 811 | aMx.Clear(); |
| 812 | aMSx.Clear(); |
| 813 | } |
| 814 | //======================================================================= |
| 815 | //function : BuildBndBox |
| 816 | //purpose : |
| 817 | //======================================================================= |
| 818 | void BOPAlgo_Builder::BuildBndBox(const Standard_Integer theIndex, |
| 819 | Bnd_Box& aBoxS) |
| 820 | { |
| 821 | Standard_Boolean bIsOpenBox; |
| 822 | Standard_Integer nSh, nFc; |
| 823 | Standard_Real aTolS, aTolFc; |
| 824 | TopAbs_State aState; |
| 825 | BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1; |
| 826 | // |
| 827 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(theIndex); |
| 828 | const TopoDS_Shape& aS=aSI.Shape(); |
| 829 | const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS)); |
| 830 | // |
| 831 | bIsOpenBox=Standard_False; |
| 832 | // |
| 833 | aTolS=0.; |
| 834 | const BOPCol_ListOfInteger& aLISh=aSI.SubShapes(); |
| 835 | aItLI.Initialize(aLISh); |
| 836 | for (; aItLI.More(); aItLI.Next()) { |
| 837 | nSh=aItLI.Value(); |
| 838 | const BOPDS_ShapeInfo& aSISh=myDS->ShapeInfo(nSh); |
| 839 | if (aSISh.ShapeType()!=TopAbs_SHELL) { |
| 840 | continue; |
| 841 | } |
| 842 | // |
| 843 | const BOPCol_ListOfInteger& aLIFc=aSISh.SubShapes(); |
| 844 | aItLI1.Initialize(aLIFc); |
| 845 | for (; aItLI1.More(); aItLI1.Next()) { |
| 846 | nFc=aItLI1.Value(); |
| 847 | const BOPDS_ShapeInfo& aSIFc=myDS->ShapeInfo(nFc); |
| 848 | if (aSIFc.ShapeType()!=TopAbs_FACE) { |
| 849 | continue; |
| 850 | } |
| 851 | // |
| 852 | const Bnd_Box& aBFc=aSIFc.Box(); |
| 853 | aBoxS.Add(aBFc); |
| 854 | // |
| 855 | if (!bIsOpenBox) { |
| 856 | bIsOpenBox=(aBFc.IsOpenXmin() || aBFc.IsOpenXmax() || |
| 857 | aBFc.IsOpenYmin() || aBFc.IsOpenYmax() || |
| 858 | aBFc.IsOpenZmin() || aBFc.IsOpenZmax()); |
| 859 | if (bIsOpenBox) { |
| 860 | break; |
| 861 | } |
| 862 | } |
| 863 | // |
| 864 | const TopoDS_Face& aFc=*((TopoDS_Face*)&aSIFc.Shape()); |
| 865 | aTolFc=BRep_Tool::Tolerance(aFc); |
| 866 | if (aTolFc>aTolS) { |
| 867 | aTolS=aTolFc; |
| 868 | } |
| 869 | }//for (; aItLI1.More(); aItLI1.Next()) { |
| 870 | if (bIsOpenBox) { |
| 871 | break; |
| 872 | } |
| 873 | // |
| 874 | const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSISh.Shape()); |
| 875 | bIsOpenBox=IsClosedShell(aSh); |
| 876 | if (bIsOpenBox) { |
| 877 | break; |
| 878 | } |
| 879 | }//for (; aItLI.More(); aItLI.Next()) { |
| 880 | // |
| 881 | if (bIsOpenBox) { |
| 882 | aBoxS.SetWhole(); |
| 883 | } |
| 884 | else { |
| 885 | BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid); |
| 886 | aSC.PerformInfinitePoint(aTolS); |
| 887 | aState=aSC.State(); |
| 888 | if (aState==TopAbs_IN) { |
| 889 | aBoxS.SetWhole(); |
| 890 | } |
| 891 | } |
| 892 | } |
| 893 | //======================================================================= |
| 894 | //function : OwnInternalShapes |
| 895 | //purpose : |
| 896 | //======================================================================= |
| 897 | void OwnInternalShapes(const TopoDS_Shape& theS, |
| 898 | BOPCol_IndexedMapOfShape& theMx) |
| 899 | { |
| 900 | TopoDS_Iterator aIt; |
| 901 | // |
| 902 | aIt.Initialize(theS); |
| 903 | for (; aIt.More(); aIt.Next()) { |
| 904 | const TopoDS_Shape& aSx=aIt.Value(); |
| 905 | if (aSx.ShapeType()!=TopAbs_SHELL) { |
| 906 | theMx.Add(aSx); |
| 907 | } |
| 908 | } |
| 909 | } |
| 910 | //======================================================================= |
| 911 | //function : IsClosedShell |
| 912 | //purpose : |
| 913 | //======================================================================= |
| 914 | Standard_Boolean IsClosedShell(const TopoDS_Shell& aSh) |
| 915 | { |
| 916 | Standard_Boolean bRet; |
| 917 | Standard_Integer i, aNbE, aNbF; |
| 918 | TopAbs_Orientation aOrF; |
| 919 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF; |
| 920 | BOPCol_ListIteratorOfListOfShape aItLS; |
| 921 | // |
| 922 | bRet=Standard_False; |
| 923 | // |
| 924 | BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF); |
| 925 | // |
| 926 | aNbE=aMEF.Extent(); |
| 927 | for (i=1; i<=aNbE; ++i) { |
| 928 | const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i)); |
| 929 | if (BRep_Tool::Degenerated(aE)) { |
| 930 | continue; |
| 931 | } |
| 932 | // |
| 933 | aNbF=0; |
| 934 | const BOPCol_ListOfShape& aLF=aMEF(i); |
| 935 | aItLS.Initialize(aLF); |
| 936 | for (; aItLS.More(); aItLS.Next()) { |
| 937 | const TopoDS_Shape& aF=aItLS.Value(); |
| 938 | aOrF=aF.Orientation(); |
| 939 | if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) { |
| 940 | continue; |
| 941 | } |
| 942 | ++aNbF; |
| 943 | } |
| 944 | // |
| 945 | if (aNbF==1) { |
| 946 | bRet=!bRet; // True |
| 947 | break; |
| 948 | } |
| 949 | } |
| 950 | // |
| 951 | return bRet; |
| 952 | } |
| 953 | //======================================================================= |
| 954 | //function : TreatCompound |
| 955 | //purpose : |
| 956 | //======================================================================= |
| 957 | void TreatCompound(const TopoDS_Shape& theS, |
| 958 | BOPCol_MapOfShape& aMFence, |
| 959 | BOPCol_ListOfShape& theLS) |
| 960 | { |
| 961 | TopAbs_ShapeEnum aType; |
| 962 | // |
| 963 | aType = theS.ShapeType(); |
| 964 | if (aType != TopAbs_COMPOUND) { |
| 965 | if (aMFence.Add(theS)) { |
| 966 | theLS.Append(theS); |
| 967 | } |
| 968 | return; |
| 969 | } |
| 970 | // |
| 971 | TopoDS_Iterator aIt; |
| 972 | // |
| 973 | aIt.Initialize(theS); |
| 974 | for (; aIt.More(); aIt.Next()) { |
| 975 | const TopoDS_Shape& aS = aIt.Value(); |
| 976 | TreatCompound(aS, aMFence, theLS); |
| 977 | } |
| 978 | } |
| 979 | |
| 980 | // |
| 981 | // ErrorStatus |
| 982 | // 30 - SolidBuilder failed |
| 983 | // A |