| 1 | // Created by: Peter KURNEV |
| 2 | // Copyright (c) 1999-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_BOP.ixx> |
| 16 | |
| 17 | #include <TopAbs_ShapeEnum.hxx> |
| 18 | |
| 19 | #include <TopoDS_Compound.hxx> |
| 20 | #include <TopoDS_Iterator.hxx> |
| 21 | #include <TopoDS_Edge.hxx> |
| 22 | #include <BRep_Builder.hxx> |
| 23 | #include <TopExp_Explorer.hxx> |
| 24 | |
| 25 | #include <BOPCol_ListOfShape.hxx> |
| 26 | #include <BOPCol_MapOfShape.hxx> |
| 27 | #include <BOPCol_IndexedMapOfShape.hxx> |
| 28 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
| 29 | #include <BOPCol_DataMapOfShapeShape.hxx> |
| 30 | |
| 31 | #include <BOPDS_DS.hxx> |
| 32 | |
| 33 | #include <BOPTools.hxx> |
| 34 | #include <BOPTools_AlgoTools.hxx> |
| 35 | #include <BOPTools_AlgoTools3D.hxx> |
| 36 | #include <BOPTools_AlgoTools.hxx> |
| 37 | |
| 38 | #include <BOPAlgo_BuilderSolid.hxx> |
| 39 | |
| 40 | #include <BRep_Tool.hxx> |
| 41 | #include <NCollection_IncAllocator.hxx> |
| 42 | // |
| 43 | #include <BOPTools_Set.hxx> |
| 44 | #include <BOPTools_SetMapHasher.hxx> |
| 45 | #include <NCollection_DataMap.hxx> |
| 46 | |
| 47 | typedef NCollection_DataMap |
| 48 | <BOPTools_Set, |
| 49 | TopoDS_Shape, |
| 50 | BOPTools_SetMapHasher> BOPTools_DataMapOfSetShape; |
| 51 | // |
| 52 | typedef BOPTools_DataMapOfSetShape::Iterator |
| 53 | BOPTools_DataMapIteratorOfDataMapOfSetShape; |
| 54 | |
| 55 | static |
| 56 | TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim); |
| 57 | |
| 58 | |
| 59 | //======================================================================= |
| 60 | //function : |
| 61 | //purpose : |
| 62 | //======================================================================= |
| 63 | BOPAlgo_BOP::BOPAlgo_BOP() |
| 64 | : |
| 65 | BOPAlgo_Builder(), |
| 66 | myTools(myAllocator), |
| 67 | myMapTools(100, myAllocator) |
| 68 | { |
| 69 | Clear(); |
| 70 | } |
| 71 | //======================================================================= |
| 72 | //function : |
| 73 | //purpose : |
| 74 | //======================================================================= |
| 75 | BOPAlgo_BOP::BOPAlgo_BOP |
| 76 | (const Handle(NCollection_BaseAllocator)& theAllocator) |
| 77 | : |
| 78 | BOPAlgo_Builder(theAllocator), |
| 79 | myTools(myAllocator), |
| 80 | myMapTools(100, myAllocator) |
| 81 | { |
| 82 | Clear(); |
| 83 | } |
| 84 | //======================================================================= |
| 85 | //function : ~ |
| 86 | //purpose : |
| 87 | //======================================================================= |
| 88 | BOPAlgo_BOP::~BOPAlgo_BOP() |
| 89 | { |
| 90 | } |
| 91 | //======================================================================= |
| 92 | //function : Clear |
| 93 | //purpose : |
| 94 | //======================================================================= |
| 95 | void BOPAlgo_BOP::Clear() |
| 96 | { |
| 97 | myOperation=BOPAlgo_UNKNOWN; |
| 98 | myTools.Clear(); |
| 99 | myMapTools.Clear(); |
| 100 | myDims[0]=-1; |
| 101 | myDims[1]=-1; |
| 102 | // |
| 103 | BOPAlgo_Builder::Clear(); |
| 104 | } |
| 105 | //======================================================================= |
| 106 | //function : SetOperation |
| 107 | //purpose : |
| 108 | //======================================================================= |
| 109 | void BOPAlgo_BOP::SetOperation(const BOPAlgo_Operation theOperation) |
| 110 | { |
| 111 | myOperation=theOperation; |
| 112 | } |
| 113 | //======================================================================= |
| 114 | //function : Operation |
| 115 | //purpose : |
| 116 | //======================================================================= |
| 117 | BOPAlgo_Operation BOPAlgo_BOP::Operation()const |
| 118 | { |
| 119 | return myOperation; |
| 120 | } |
| 121 | //======================================================================= |
| 122 | //function : AddTool |
| 123 | //purpose : |
| 124 | //======================================================================= |
| 125 | void BOPAlgo_BOP::AddTool(const TopoDS_Shape& theShape) |
| 126 | { |
| 127 | if (myMapTools.Add(theShape)) { |
| 128 | myTools.Append(theShape); |
| 129 | } |
| 130 | } |
| 131 | //======================================================================= |
| 132 | //function : CheckData |
| 133 | //purpose : |
| 134 | //======================================================================= |
| 135 | void BOPAlgo_BOP::CheckData() |
| 136 | { |
| 137 | Standard_Integer i, j, iDim, aNbArgs, aNbTools; |
| 138 | Standard_Boolean bFlag; |
| 139 | BOPCol_ListIteratorOfListOfShape aItLS; |
| 140 | // |
| 141 | myErrorStatus=0; |
| 142 | // |
| 143 | aNbArgs=myArguments.Extent(); |
| 144 | if (!aNbArgs) { |
| 145 | myErrorStatus=100; // invalid number of Arguments |
| 146 | return; |
| 147 | } |
| 148 | // |
| 149 | aNbTools=myTools.Extent(); |
| 150 | if (!aNbTools) { |
| 151 | myErrorStatus=100; // invalid number of Tools |
| 152 | return; |
| 153 | } |
| 154 | // |
| 155 | if (!myPaveFiller) { |
| 156 | myErrorStatus=101; |
| 157 | return; |
| 158 | } |
| 159 | // |
| 160 | myErrorStatus=myPaveFiller->ErrorStatus(); |
| 161 | if (myErrorStatus) { |
| 162 | return; |
| 163 | } |
| 164 | // |
| 165 | for (i=0; i<2; ++i) { |
| 166 | const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools; |
| 167 | aItLS.Initialize(aLS); |
| 168 | for (j=0; aItLS.More(); aItLS.Next(), ++j) { |
| 169 | const TopoDS_Shape& aS=aItLS.Value(); |
| 170 | bFlag=BOPTools_AlgoTools3D::IsEmptyShape(aS); |
| 171 | if(bFlag) { |
| 172 | myWarningStatus=2; |
| 173 | } |
| 174 | // |
| 175 | iDim=BOPTools_AlgoTools::Dimension(aS); |
| 176 | if (iDim<0) { |
| 177 | myErrorStatus=13; // non-homogenious argument |
| 178 | return; |
| 179 | } |
| 180 | // |
| 181 | if (!j) { |
| 182 | myDims[i]=iDim; |
| 183 | continue; |
| 184 | } |
| 185 | // |
| 186 | if (iDim!=myDims[i]) { |
| 187 | myErrorStatus=13; // non-homogenious argument |
| 188 | return; |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | // |
| 193 | if (myOperation==BOPAlgo_UNKNOWN) { |
| 194 | myErrorStatus=14; // non-licit operation |
| 195 | return; |
| 196 | } |
| 197 | else if (myDims[0]<myDims[1]) { |
| 198 | if (myOperation==BOPAlgo_FUSE || |
| 199 | myOperation==BOPAlgo_CUT21) { |
| 200 | myErrorStatus=14; // non-licit operation for the arguments |
| 201 | return; |
| 202 | } |
| 203 | } |
| 204 | else if (myDims[0]>myDims[1]) { |
| 205 | if (myOperation==BOPAlgo_FUSE || |
| 206 | myOperation==BOPAlgo_CUT) { |
| 207 | myErrorStatus=14; // non-licit operation for the arguments |
| 208 | return; |
| 209 | } |
| 210 | } |
| 211 | } |
| 212 | //======================================================================= |
| 213 | //function : Prepare |
| 214 | //purpose : |
| 215 | //======================================================================= |
| 216 | void BOPAlgo_BOP::Prepare() |
| 217 | { |
| 218 | // |
| 219 | BOPAlgo_Builder::Prepare(); |
| 220 | // |
| 221 | if(myWarningStatus == 2) { |
| 222 | Standard_Integer i; |
| 223 | BRep_Builder aBB; |
| 224 | BOPCol_ListIteratorOfListOfShape aItLS; |
| 225 | // |
| 226 | switch(myOperation) { |
| 227 | case BOPAlgo_FUSE: { |
| 228 | for (i=0; i<2; ++i) { |
| 229 | const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools; |
| 230 | aItLS.Initialize(aLS); |
| 231 | for (; aItLS.More(); aItLS.Next()) { |
| 232 | const TopoDS_Shape& aS=aItLS.Value(); |
| 233 | aBB.Add(myShape, aS); |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 | break; |
| 238 | // |
| 239 | case BOPAlgo_CUT: { |
| 240 | aItLS.Initialize(myArguments); |
| 241 | for (; aItLS.More(); aItLS.Next()) { |
| 242 | const TopoDS_Shape& aS=aItLS.Value(); |
| 243 | if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) { |
| 244 | aBB.Add(myShape, aS); |
| 245 | } |
| 246 | } |
| 247 | } |
| 248 | break; |
| 249 | |
| 250 | case BOPAlgo_CUT21: { |
| 251 | aItLS.Initialize(myTools); |
| 252 | for (; aItLS.More(); aItLS.Next()) { |
| 253 | const TopoDS_Shape& aS=aItLS.Value(); |
| 254 | if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) { |
| 255 | aBB.Add(myShape, aS); |
| 256 | } |
| 257 | } |
| 258 | } |
| 259 | break; |
| 260 | // |
| 261 | case BOPAlgo_COMMON: |
| 262 | case BOPAlgo_SECTION: |
| 263 | default: |
| 264 | break; |
| 265 | } |
| 266 | } |
| 267 | } |
| 268 | //======================================================================= |
| 269 | //function : BuildResult |
| 270 | //purpose : |
| 271 | //======================================================================= |
| 272 | void BOPAlgo_BOP::BuildResult(const TopAbs_ShapeEnum theType) |
| 273 | { |
| 274 | TopAbs_ShapeEnum aType; |
| 275 | BRep_Builder aBB; |
| 276 | BOPCol_MapOfShape aM; |
| 277 | BOPCol_ListIteratorOfListOfShape aIt, aItIm; |
| 278 | // |
| 279 | myErrorStatus=0; |
| 280 | // |
| 281 | const BOPCol_ListOfShape& aLA=myDS->Arguments(); |
| 282 | aIt.Initialize(aLA); |
| 283 | for (; aIt.More(); aIt.Next()) { |
| 284 | const TopoDS_Shape& aS=aIt.Value(); |
| 285 | aType=aS.ShapeType(); |
| 286 | if (aType==theType) { |
| 287 | if (myImages.IsBound(aS)){ |
| 288 | const BOPCol_ListOfShape& aLSIm=myImages.Find(aS); |
| 289 | aItIm.Initialize(aLSIm); |
| 290 | for (; aItIm.More(); aItIm.Next()) { |
| 291 | const TopoDS_Shape& aSIm=aItIm.Value(); |
| 292 | if (aM.Add(aSIm)) { |
| 293 | aBB.Add(myShape, aSIm); |
| 294 | } |
| 295 | } |
| 296 | } |
| 297 | else { |
| 298 | if (aM.Add(aS)) { |
| 299 | aBB.Add(myShape, aS); |
| 300 | } |
| 301 | } |
| 302 | } |
| 303 | } |
| 304 | } |
| 305 | //======================================================================= |
| 306 | //function : Perform |
| 307 | //purpose : |
| 308 | //======================================================================= |
| 309 | void BOPAlgo_BOP::Perform() |
| 310 | { |
| 311 | Handle(NCollection_BaseAllocator) aAllocator; |
| 312 | BOPAlgo_PaveFiller* pPF; |
| 313 | BOPCol_ListIteratorOfListOfShape aItLS; |
| 314 | // |
| 315 | myErrorStatus=0; |
| 316 | // |
| 317 | if (myEntryPoint==1) { |
| 318 | if (myPaveFiller) { |
| 319 | delete myPaveFiller; |
| 320 | myPaveFiller=NULL; |
| 321 | } |
| 322 | } |
| 323 | // |
| 324 | aAllocator=new NCollection_IncAllocator; |
| 325 | BOPCol_ListOfShape aLS(aAllocator); |
| 326 | // |
| 327 | aItLS.Initialize(myArguments); |
| 328 | for (; aItLS.More(); aItLS.Next()) { |
| 329 | const TopoDS_Shape& aS=aItLS.Value(); |
| 330 | aLS.Append(aS); |
| 331 | } |
| 332 | // |
| 333 | aItLS.Initialize(myTools); |
| 334 | for (; aItLS.More(); aItLS.Next()) { |
| 335 | const TopoDS_Shape& aS=aItLS.Value(); |
| 336 | aLS.Append(aS); |
| 337 | } |
| 338 | // |
| 339 | pPF=new BOPAlgo_PaveFiller(aAllocator); |
| 340 | pPF->SetArguments(aLS); |
| 341 | // |
| 342 | pPF->Perform(); |
| 343 | // |
| 344 | myEntryPoint=1; |
| 345 | PerformInternal(*pPF); |
| 346 | } |
| 347 | //======================================================================= |
| 348 | //function : PerformInternal1 |
| 349 | //purpose : |
| 350 | //======================================================================= |
| 351 | void BOPAlgo_BOP::PerformInternal1(const BOPAlgo_PaveFiller& theFiller) |
| 352 | { |
| 353 | myErrorStatus=0; |
| 354 | myWarningStatus=0; |
| 355 | // |
| 356 | myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller; |
| 357 | myDS=myPaveFiller->PDS(); |
| 358 | myContext=myPaveFiller->Context(); |
| 359 | // |
| 360 | // 1. CheckData |
| 361 | CheckData(); |
| 362 | if (myErrorStatus && !myWarningStatus) { |
| 363 | return; |
| 364 | } |
| 365 | // |
| 366 | // 2. Prepare |
| 367 | Prepare(); |
| 368 | if (myErrorStatus) { |
| 369 | return; |
| 370 | } |
| 371 | // |
| 372 | if(myWarningStatus == 2) { |
| 373 | return; |
| 374 | } |
| 375 | // 3. Fill Images |
| 376 | // 3.1 Vertices |
| 377 | FillImagesVertices(); |
| 378 | if (myErrorStatus) { |
| 379 | return; |
| 380 | } |
| 381 | // |
| 382 | BuildResult(TopAbs_VERTEX); |
| 383 | if (myErrorStatus) { |
| 384 | return; |
| 385 | } |
| 386 | // 3.2 Edges |
| 387 | FillImagesEdges(); |
| 388 | if (myErrorStatus) { |
| 389 | return; |
| 390 | } |
| 391 | |
| 392 | BuildResult(TopAbs_EDGE); |
| 393 | if (myErrorStatus) { |
| 394 | return; |
| 395 | } |
| 396 | //-------------------------------- SECTION |
| 397 | if (myOperation==BOPAlgo_SECTION) { |
| 398 | BuildSection(); |
| 399 | PrepareHistory(); |
| 400 | PostTreat(); |
| 401 | return; |
| 402 | } |
| 403 | //-------------------------------- |
| 404 | // |
| 405 | // 3.3 Wires |
| 406 | FillImagesContainers(TopAbs_WIRE); |
| 407 | if (myErrorStatus) { |
| 408 | return; |
| 409 | } |
| 410 | |
| 411 | BuildResult(TopAbs_WIRE); |
| 412 | if (myErrorStatus) { |
| 413 | return; |
| 414 | } |
| 415 | |
| 416 | // 3.4 Faces |
| 417 | FillImagesFaces(); |
| 418 | if (myErrorStatus) { |
| 419 | return; |
| 420 | } |
| 421 | |
| 422 | BuildResult(TopAbs_FACE); |
| 423 | if (myErrorStatus) { |
| 424 | return; |
| 425 | } |
| 426 | // 3.5 Shells |
| 427 | |
| 428 | FillImagesContainers(TopAbs_SHELL); |
| 429 | if (myErrorStatus) { |
| 430 | return; |
| 431 | } |
| 432 | |
| 433 | BuildResult(TopAbs_SHELL); |
| 434 | if (myErrorStatus) { |
| 435 | return; |
| 436 | } |
| 437 | // 3.6 Solids |
| 438 | FillImagesSolids(); |
| 439 | if (myErrorStatus) { |
| 440 | return; |
| 441 | } |
| 442 | |
| 443 | BuildResult(TopAbs_SOLID); |
| 444 | if (myErrorStatus) { |
| 445 | return; |
| 446 | } |
| 447 | // 3.7 CompSolids |
| 448 | FillImagesContainers(TopAbs_COMPSOLID); |
| 449 | if (myErrorStatus) { |
| 450 | return; |
| 451 | } |
| 452 | |
| 453 | BuildResult(TopAbs_COMPSOLID); |
| 454 | if (myErrorStatus) { |
| 455 | return; |
| 456 | } |
| 457 | // 3.8 Compounds |
| 458 | FillImagesCompounds(); |
| 459 | if (myErrorStatus) { |
| 460 | return; |
| 461 | } |
| 462 | |
| 463 | BuildResult(TopAbs_COMPOUND); |
| 464 | if (myErrorStatus) { |
| 465 | return; |
| 466 | } |
| 467 | // |
| 468 | // 4.BuildShape; |
| 469 | BuildShape(); |
| 470 | if (myErrorStatus) { |
| 471 | return; |
| 472 | } |
| 473 | // |
| 474 | // 5.History |
| 475 | PrepareHistory(); |
| 476 | // |
| 477 | // 6 Post-treatment |
| 478 | PostTreat(); |
| 479 | } |
| 480 | //======================================================================= |
| 481 | //function : BuildRC |
| 482 | //purpose : |
| 483 | //======================================================================= |
| 484 | void BOPAlgo_BOP::BuildRC() |
| 485 | { |
| 486 | Standard_Boolean bFlag1, bFlag2, bIsBound; |
| 487 | Standard_Integer aDmin; |
| 488 | TopAbs_ShapeEnum aTmin; |
| 489 | TopoDS_Compound aC; |
| 490 | TopoDS_Shape aSAIm, aSTIm; |
| 491 | BRep_Builder aBB; |
| 492 | TopExp_Explorer aExp; |
| 493 | BOPCol_DataMapOfShapeShape aDMSSA; |
| 494 | BOPCol_ListIteratorOfListOfShape aItLS, aItIm; |
| 495 | Standard_Boolean bHasInterf; |
| 496 | Standard_Integer iX; |
| 497 | BOPTools_DataMapOfSetShape aDMSTS; |
| 498 | // |
| 499 | myErrorStatus=0; |
| 500 | // |
| 501 | aBB.MakeCompound(aC); |
| 502 | // |
| 503 | // A. Fuse |
| 504 | if (myOperation==BOPAlgo_FUSE) { |
| 505 | aTmin=TypeToExplore(myDims[0]); |
| 506 | aExp.Init(myShape, aTmin); |
| 507 | for (; aExp.More(); aExp.Next()) { |
| 508 | const TopoDS_Shape& aS=aExp.Current(); |
| 509 | aBB.Add(aC, aS); |
| 510 | } |
| 511 | myRC=aC; |
| 512 | return; |
| 513 | } |
| 514 | // |
| 515 | aDmin=myDims[1]; |
| 516 | if (myDims[0] < myDims[1]) { |
| 517 | aDmin=myDims[0]; |
| 518 | } |
| 519 | aTmin=TypeToExplore(aDmin); |
| 520 | // |
| 521 | // B. Common, Cut, Cut21 |
| 522 | // |
| 523 | bFlag1=(myOperation==BOPAlgo_COMMON || myOperation==BOPAlgo_CUT21); |
| 524 | bFlag2=(myOperation==BOPAlgo_CUT || myOperation==BOPAlgo_CUT21); |
| 525 | // |
| 526 | const BOPCol_ListOfShape& aLA=( bFlag1) ? myArguments : myTools; |
| 527 | aItLS.Initialize(aLA); |
| 528 | for (; aItLS.More(); aItLS.Next()) { |
| 529 | const TopoDS_Shape& aSA=aItLS.Value(); |
| 530 | // |
| 531 | if (myImages.IsBound(aSA)){ |
| 532 | const BOPCol_ListOfShape& aLSAIm=myImages.Find(aSA); |
| 533 | aItIm.Initialize(aLSAIm); |
| 534 | for (; aItIm.More(); aItIm.Next()) { |
| 535 | const TopoDS_Shape& aSAIm=aItIm.Value(); |
| 536 | aExp.Init(aSAIm, aTmin); |
| 537 | for (; aExp.More(); aExp.Next()) { |
| 538 | const TopoDS_Shape aSIm=aExp.Current(); |
| 539 | aDMSSA.Bind(aSIm, aSIm); |
| 540 | } |
| 541 | } |
| 542 | } |
| 543 | // |
| 544 | else { |
| 545 | aExp.Init(aSA, aTmin); |
| 546 | for (; aExp.More(); aExp.Next()) { |
| 547 | const TopoDS_Shape aSIm=aExp.Current(); |
| 548 | aDMSSA.Bind(aSIm, aSIm); |
| 549 | if (aTmin==TopAbs_SOLID) { |
| 550 | iX=myDS->Index(aSIm); |
| 551 | bHasInterf=myDS->HasInterf(iX); |
| 552 | if (!bHasInterf) { |
| 553 | BOPTools_Set aST; |
| 554 | // |
| 555 | aST.Add(aSIm, TopAbs_FACE); |
| 556 | // |
| 557 | aDMSTS.Bind(aST, aSIm); |
| 558 | } |
| 559 | } |
| 560 | } |
| 561 | } |
| 562 | } //for (; aItLS.More(); aItLS.Next()) |
| 563 | // |
| 564 | const BOPCol_ListOfShape& aLT=(!bFlag1) ? myArguments : myTools; |
| 565 | aItLS.Initialize(aLT); |
| 566 | for (; aItLS.More(); aItLS.Next()) { |
| 567 | const TopoDS_Shape& aST=aItLS.Value(); |
| 568 | if (myImages.IsBound(aST)){ |
| 569 | const BOPCol_ListOfShape& aLSTIm=myImages.Find(aST); |
| 570 | aItIm.Initialize(aLSTIm); |
| 571 | for (; aItIm.More(); aItIm.Next()) { |
| 572 | const TopoDS_Shape& aSTIm=aItIm.Value(); |
| 573 | aExp.Init(aSTIm, aTmin); |
| 574 | for (; aExp.More(); aExp.Next()) { |
| 575 | const TopoDS_Shape aSIm=aExp.Current(); |
| 576 | // skip degenerated edges |
| 577 | if (aTmin==TopAbs_EDGE) { |
| 578 | const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm); |
| 579 | if (BRep_Tool::Degenerated(aEIm)) { |
| 580 | continue; |
| 581 | } |
| 582 | } |
| 583 | // |
| 584 | bIsBound=aDMSSA.IsBound(aSIm); |
| 585 | if (!bFlag2) { // ie common |
| 586 | if (bIsBound) { |
| 587 | const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm); |
| 588 | aBB.Add(aC, aSImA); |
| 589 | } |
| 590 | } |
| 591 | else {// ie cut or cut21 |
| 592 | if (!bIsBound) { |
| 593 | aBB.Add(aC, aSIm); |
| 594 | } |
| 595 | } |
| 596 | } |
| 597 | } |
| 598 | }// if (myImages.IsBound(aST)){ |
| 599 | else { |
| 600 | aExp.Init(aST, aTmin); |
| 601 | for (; aExp.More(); aExp.Next()) { |
| 602 | const TopoDS_Shape aSIm=aExp.Current(); |
| 603 | // skip degenerated edges |
| 604 | if (aTmin==TopAbs_EDGE) { |
| 605 | const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm); |
| 606 | if (BRep_Tool::Degenerated(aEIm)) { |
| 607 | continue; |
| 608 | } |
| 609 | } |
| 610 | bIsBound=aDMSSA.IsBound(aSIm); |
| 611 | if (!bFlag2) { // ie common |
| 612 | if (bIsBound) { |
| 613 | const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm); |
| 614 | aBB.Add(aC, aSImA); |
| 615 | } |
| 616 | else { |
| 617 | if (aTmin==TopAbs_SOLID) { |
| 618 | BOPTools_Set aST; |
| 619 | // |
| 620 | aST.Add(aSIm, TopAbs_FACE); |
| 621 | // |
| 622 | if (aDMSTS.IsBound(aST)) { |
| 623 | const TopoDS_Shape& aSImA=aDMSTS.Find(aST); |
| 624 | aBB.Add(aC, aSImA); |
| 625 | } |
| 626 | } |
| 627 | } |
| 628 | } |
| 629 | else {// ie cut or cut21 |
| 630 | if (!bIsBound) { |
| 631 | if (aTmin==TopAbs_SOLID) { |
| 632 | BOPTools_Set aST; |
| 633 | // |
| 634 | aST.Add(aSIm, TopAbs_FACE); |
| 635 | // |
| 636 | bIsBound=aDMSTS.IsBound(aST); |
| 637 | } |
| 638 | // |
| 639 | if (!bIsBound) { |
| 640 | aBB.Add(aC, aSIm); |
| 641 | } |
| 642 | } |
| 643 | } |
| 644 | } |
| 645 | } |
| 646 | } //for (; aItLS.More(); aItLS.Next()) |
| 647 | // |
| 648 | // the squats around degeneracy |
| 649 | if (aTmin!=TopAbs_EDGE) { |
| 650 | myRC=aC; |
| 651 | return; |
| 652 | } |
| 653 | //--------------------------------------------------------- |
| 654 | // |
| 655 | // The squats around degenerated edges |
| 656 | Standard_Integer i, aNbS, nVD; |
| 657 | TopAbs_ShapeEnum aType; |
| 658 | BOPCol_IndexedMapOfShape aMVC; |
| 659 | // |
| 660 | // 1. Vertices of aC |
| 661 | BOPTools::MapShapes(aC, TopAbs_VERTEX, aMVC); |
| 662 | // |
| 663 | // 2. DE candidates |
| 664 | aNbS=myDS->NbSourceShapes(); |
| 665 | for (i=0; i<aNbS; ++i) { |
| 666 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
| 667 | aType=aSI.ShapeType(); |
| 668 | if (aType!=aTmin) { |
| 669 | continue; |
| 670 | } |
| 671 | // |
| 672 | const TopoDS_Edge& aE=*((TopoDS_Edge*)&aSI.Shape()); |
| 673 | if (!BRep_Tool::Degenerated(aE)) { |
| 674 | continue; |
| 675 | } |
| 676 | // |
| 677 | nVD=aSI.SubShapes().First(); |
| 678 | const TopoDS_Shape& aVD=myDS->Shape(nVD); |
| 679 | // |
| 680 | if (!aMVC.Contains(aVD)) { |
| 681 | continue; |
| 682 | } |
| 683 | // |
| 684 | if (myDS->IsNewShape(nVD)) { |
| 685 | continue; |
| 686 | } |
| 687 | // |
| 688 | if (myDS->HasInterf(nVD)) { |
| 689 | continue; |
| 690 | } |
| 691 | // |
| 692 | aBB.Add(aC, aE); |
| 693 | } |
| 694 | // |
| 695 | myRC=aC; |
| 696 | } |
| 697 | //======================================================================= |
| 698 | //function : BuildShape |
| 699 | //purpose : |
| 700 | //======================================================================= |
| 701 | void BOPAlgo_BOP::BuildShape() |
| 702 | { |
| 703 | Standard_Integer aDmin, aNbLCB; |
| 704 | TopAbs_ShapeEnum aT1, aT2, aTR; |
| 705 | TopoDS_Shape aR, aRC; |
| 706 | TopoDS_Iterator aIt; |
| 707 | BRep_Builder aBB; |
| 708 | BOPCol_ListOfShape aLCB; |
| 709 | BOPCol_ListIteratorOfListOfShape aItLCB; |
| 710 | // |
| 711 | myErrorStatus=0; |
| 712 | // |
| 713 | BuildRC(); |
| 714 | // |
| 715 | aDmin=myDims[1]; |
| 716 | if (myDims[0]<myDims[1]) { |
| 717 | aDmin=myDims[0]; |
| 718 | } |
| 719 | // |
| 720 | if (!aDmin) { |
| 721 | myShape=myRC; |
| 722 | return; |
| 723 | } |
| 724 | // |
| 725 | else if (aDmin==1 || aDmin==2) { //edges, faces |
| 726 | aT1=TopAbs_VERTEX; |
| 727 | aT2=TopAbs_EDGE; |
| 728 | aTR=TopAbs_WIRE; |
| 729 | if (aDmin==2) { |
| 730 | aT1=TopAbs_EDGE; |
| 731 | aT2=TopAbs_FACE; |
| 732 | aTR=TopAbs_SHELL; |
| 733 | } |
| 734 | // |
| 735 | BOPTools_AlgoTools::MakeConnexityBlocks |
| 736 | (myRC, aT1, aT2, aLCB); |
| 737 | aNbLCB=aLCB.Extent(); |
| 738 | if (!aNbLCB) { |
| 739 | myShape=myRC; |
| 740 | return; |
| 741 | } |
| 742 | // |
| 743 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
| 744 | // |
| 745 | aItLCB.Initialize(aLCB); |
| 746 | for (; aItLCB.More(); aItLCB.Next()) { |
| 747 | BOPTools_AlgoTools::MakeContainer(aTR, aR); |
| 748 | // |
| 749 | const TopoDS_Shape& aCB=aItLCB.Value(); |
| 750 | aIt.Initialize(aCB); |
| 751 | for (; aIt.More(); aIt.Next()) { |
| 752 | const TopoDS_Shape& aS=aIt.Value(); |
| 753 | aBB.Add(aR, aS); |
| 754 | } |
| 755 | // |
| 756 | if (aTR==TopAbs_SHELL) { |
| 757 | BOPTools_AlgoTools::OrientFacesOnShell(aR); |
| 758 | } |
| 759 | // |
| 760 | aBB.Add(aRC, aR); |
| 761 | } |
| 762 | myShape=aRC; |
| 763 | }// elase if (aDmin==1 || aDmin==2) { |
| 764 | |
| 765 | else {//aDmin=3 |
| 766 | Standard_Integer aNbObjs, aNbTools; |
| 767 | // |
| 768 | aNbObjs=myArguments.Extent(); |
| 769 | aNbTools=myTools.Extent(); |
| 770 | // |
| 771 | if (aNbObjs==1 && aNbTools==1) { |
| 772 | if (myOperation==BOPAlgo_FUSE) { |
| 773 | BuildSolid(); |
| 774 | } |
| 775 | else { |
| 776 | myShape=myRC; |
| 777 | } |
| 778 | } |
| 779 | else { |
| 780 | BuildSolid(); |
| 781 | } |
| 782 | } |
| 783 | } |
| 784 | //======================================================================= |
| 785 | //function : BuildSolid |
| 786 | //purpose : |
| 787 | //======================================================================= |
| 788 | void BOPAlgo_BOP::BuildSolid() |
| 789 | { |
| 790 | Standard_Boolean bHasInterf, bHasSharedFaces; |
| 791 | Standard_Integer i, aNbF, aNbSx, iX, iErr, aNbZ; |
| 792 | TopAbs_Orientation aOr, aOr1; |
| 793 | TopoDS_Iterator aIt; |
| 794 | TopoDS_Shape aRC; |
| 795 | BRep_Builder aBB; |
| 796 | TopExp_Explorer aExp; |
| 797 | BOPCol_IndexedMapOfShape aMFI; |
| 798 | BOPCol_IndexedDataMapOfShapeListOfShape aMFS, aMEF; |
| 799 | BOPCol_ListIteratorOfListOfShape aItLS; |
| 800 | BOPCol_ListOfShape aSFS; |
| 801 | BOPAlgo_BuilderSolid aSB; |
| 802 | BOPCol_MapOfShape aMSA, aMZ; |
| 803 | BOPTools_DataMapOfSetShape aDMSTS; |
| 804 | BOPTools_DataMapIteratorOfDataMapOfSetShape aItDMSTS; |
| 805 | // |
| 806 | myErrorStatus=0; |
| 807 | // |
| 808 | // Map of of Solids of Arguments |
| 809 | for (i=0; i<2; ++i) { |
| 810 | const BOPCol_ListOfShape& aLSA=(i) ? myArguments : myTools; |
| 811 | aItLS.Initialize(aLSA); |
| 812 | for (; aItLS.More(); aItLS.Next()) { |
| 813 | const TopoDS_Shape& aSA=aItLS.Value(); |
| 814 | aExp.Init(aSA, TopAbs_SOLID); |
| 815 | for (; aExp.More(); aExp.Next()) { |
| 816 | const TopoDS_Shape& aZA=aExp.Current(); |
| 817 | aMSA.Add(aZA); |
| 818 | // |
| 819 | BOPTools::MapShapesAndAncestors(aZA, |
| 820 | TopAbs_FACE, |
| 821 | TopAbs_SOLID, |
| 822 | aMFS); |
| 823 | } |
| 824 | } |
| 825 | } |
| 826 | // |
| 827 | aNbF=aMFS.Extent(); |
| 828 | for (i=1; i<aNbF; ++i) { |
| 829 | //const TopoDS_Shape& aFA=aMFZA.FindKey(i); |
| 830 | const BOPCol_ListOfShape& aLZA=aMFS(i); |
| 831 | aNbZ=aLZA.Extent(); |
| 832 | if (aNbZ > 1) { |
| 833 | aItLS.Initialize(aLZA); |
| 834 | for(; aItLS.More(); aItLS.Next()) { |
| 835 | const TopoDS_Shape& aZA=aItLS.Value(); |
| 836 | aMZ.Add(aZA); |
| 837 | } |
| 838 | } |
| 839 | } |
| 840 | // |
| 841 | aMFS.Clear(); |
| 842 | // |
| 843 | aIt.Initialize(myRC); |
| 844 | for (; aIt.More(); aIt.Next()) { |
| 845 | const TopoDS_Shape& aSx=aIt.Value(); |
| 846 | if (aMSA.Contains(aSx)) { |
| 847 | iX=myDS->Index(aSx); |
| 848 | bHasInterf=myDS->HasInterf(iX); |
| 849 | bHasSharedFaces=aMZ.Contains(aSx); |
| 850 | // |
| 851 | if (!bHasInterf && !bHasSharedFaces) { |
| 852 | // It means that the solid aSx will be added |
| 853 | // to the result as is. |
| 854 | // The solid aSx will not participate |
| 855 | // in creation of a new solid(s). |
| 856 | BOPTools_Set aST; |
| 857 | // |
| 858 | aST.Add(aSx, TopAbs_FACE); |
| 859 | // |
| 860 | if (!aDMSTS.IsBound(aST)) { |
| 861 | aDMSTS.Bind(aST, aSx); |
| 862 | } |
| 863 | |
| 864 | continue; |
| 865 | } |
| 866 | } |
| 867 | // |
| 868 | aExp.Init(aSx, TopAbs_FACE); |
| 869 | for (; aExp.More(); aExp.Next()) { |
| 870 | const TopoDS_Shape& aFx=aExp.Current(); |
| 871 | // |
| 872 | aOr=aFx.Orientation(); |
| 873 | if (aOr==TopAbs_INTERNAL) { |
| 874 | aMFI.Add(aFx); |
| 875 | continue; |
| 876 | } |
| 877 | // |
| 878 | if (!aMFS.Contains(aFx)) { |
| 879 | BOPCol_ListOfShape aLSx; |
| 880 | // |
| 881 | aLSx.Append(aSx); |
| 882 | aMFS.Add(aFx, aLSx); |
| 883 | } |
| 884 | else { |
| 885 | iX=aMFS.FindIndex(aFx); |
| 886 | const TopoDS_Shape& aFx1=aMFS.FindKey(iX); |
| 887 | aOr1=aFx1.Orientation(); |
| 888 | if (aOr1!=aOr) { |
| 889 | BOPCol_ListOfShape& aLSx=aMFS.ChangeFromKey(aFx); |
| 890 | aLSx.Append(aSx); |
| 891 | aMFS.Add(aFx, aLSx); |
| 892 | } |
| 893 | } |
| 894 | } |
| 895 | } // for (; aIt.More(); aIt.Next()) { |
| 896 | //faces that will be added in the end; |
| 897 | BOPCol_ListOfShape aLF, aLFx; |
| 898 | // SFS |
| 899 | aNbF=aMFS.Extent(); |
| 900 | for (i=1; i<=aNbF; ++i) { |
| 901 | const TopoDS_Shape& aFx=aMFS.FindKey(i); |
| 902 | const BOPCol_ListOfShape& aLSx=aMFS(i); |
| 903 | aNbSx=aLSx.Extent(); |
| 904 | if (aNbSx==1) { |
| 905 | BOPTools::MapShapesAndAncestors |
| 906 | (aFx,TopAbs_EDGE, TopAbs_FACE, aMEF); |
| 907 | if (IsBoundSplits(aFx, aMEF)){ |
| 908 | aLFx.Append(aFx); |
| 909 | continue; |
| 910 | } |
| 911 | aLF.Append(aFx); |
| 912 | } |
| 913 | } |
| 914 | |
| 915 | aItLS.Initialize(aLF); |
| 916 | for(; aItLS.More(); aItLS.Next()) { |
| 917 | const TopoDS_Shape& aFx=aItLS.Value(); |
| 918 | aSFS.Append(aFx); |
| 919 | } |
| 920 | // add faces from aLFx to aSFS; |
| 921 | aItLS.Initialize(aLFx); |
| 922 | for (; aItLS.More(); aItLS.Next()) { |
| 923 | const TopoDS_Shape& aFx=aItLS.Value(); |
| 924 | aSFS.Append(aFx); |
| 925 | } |
| 926 | // |
| 927 | aNbF=aMFI.Extent(); |
| 928 | for (i=1; i<=aNbF; ++i) { |
| 929 | TopoDS_Shape aFx; |
| 930 | // |
| 931 | aFx=aMFI.FindKey(i); |
| 932 | aFx.Orientation(TopAbs_FORWARD); |
| 933 | aSFS.Append(aFx); |
| 934 | aFx.Orientation(TopAbs_REVERSED); |
| 935 | aSFS.Append(aFx); |
| 936 | } |
| 937 | // |
| 938 | // BuilderSolid |
| 939 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
| 940 | // |
| 941 | aSB.SetContext(myContext); |
| 942 | aSB.SetShapes(aSFS); |
| 943 | aSB.Perform(); |
| 944 | iErr=aSB.ErrorStatus(); |
| 945 | if (iErr) { |
| 946 | myErrorStatus=30; // SolidBuilder failed |
| 947 | return; |
| 948 | } |
| 949 | // |
| 950 | const BOPCol_ListOfShape& aLSR=aSB.Areas(); |
| 951 | // |
| 952 | aItLS.Initialize(aLSR); |
| 953 | for (; aItLS.More(); aItLS.Next()) { |
| 954 | const TopoDS_Shape& aSR=aItLS.Value(); |
| 955 | aBB.Add(aRC, aSR); |
| 956 | } |
| 957 | // |
| 958 | aItDMSTS.Initialize(aDMSTS); |
| 959 | for (; aItDMSTS.More(); aItDMSTS.Next()) { |
| 960 | const TopoDS_Shape& aSx=aItDMSTS.Value(); |
| 961 | aBB.Add(aRC, aSx); |
| 962 | } |
| 963 | // |
| 964 | myShape=aRC; |
| 965 | } |
| 966 | //======================================================================= |
| 967 | //function : IsBoundImages |
| 968 | //purpose : |
| 969 | //======================================================================= |
| 970 | Standard_Boolean BOPAlgo_BOP::IsBoundSplits |
| 971 | (const TopoDS_Shape& aS, |
| 972 | BOPCol_IndexedDataMapOfShapeListOfShape& aMEF) |
| 973 | { |
| 974 | Standard_Boolean bRet = Standard_False; |
| 975 | if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) { |
| 976 | return !bRet; |
| 977 | } |
| 978 | |
| 979 | BOPCol_ListIteratorOfListOfShape aIt; |
| 980 | Standard_Integer aNbLS; |
| 981 | TopAbs_Orientation anOr; |
| 982 | // |
| 983 | //check face aF may be connected to face from mySplits |
| 984 | TopExp_Explorer aExp(aS, TopAbs_EDGE); |
| 985 | for (; aExp.More(); aExp.Next()) { |
| 986 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
| 987 | // |
| 988 | anOr = aE.Orientation(); |
| 989 | if (anOr==TopAbs_INTERNAL) { |
| 990 | continue; |
| 991 | } |
| 992 | // |
| 993 | if (BRep_Tool::Degenerated(aE)) { |
| 994 | continue; |
| 995 | } |
| 996 | // |
| 997 | const BOPCol_ListOfShape& aLS=aMEF.FindFromKey(aE); |
| 998 | aNbLS = aLS.Extent(); |
| 999 | if (!aNbLS) { |
| 1000 | continue; |
| 1001 | } |
| 1002 | // |
| 1003 | aIt.Initialize(aLS); |
| 1004 | for (; aIt.More(); aIt.Next()) { |
| 1005 | const TopoDS_Shape& aSx = aIt.Value(); |
| 1006 | if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) { |
| 1007 | return !bRet; |
| 1008 | } |
| 1009 | } |
| 1010 | } |
| 1011 | // |
| 1012 | return bRet; |
| 1013 | } |
| 1014 | //======================================================================= |
| 1015 | //function : TypeToExplore |
| 1016 | //purpose : |
| 1017 | //======================================================================= |
| 1018 | TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim) |
| 1019 | { |
| 1020 | TopAbs_ShapeEnum aRet; |
| 1021 | // |
| 1022 | switch(theDim) { |
| 1023 | case 0: |
| 1024 | aRet=TopAbs_VERTEX; |
| 1025 | break; |
| 1026 | case 1: |
| 1027 | aRet=TopAbs_EDGE; |
| 1028 | break; |
| 1029 | case 2: |
| 1030 | aRet=TopAbs_FACE; |
| 1031 | break; |
| 1032 | case 3: |
| 1033 | aRet=TopAbs_SOLID; |
| 1034 | break; |
| 1035 | default: |
| 1036 | aRet=TopAbs_SHAPE; |
| 1037 | break; |
| 1038 | } |
| 1039 | return aRet; |
| 1040 | } |