| 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 under |
| 10 | // the terms of the GNU Lesser General Public License 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_PaveFiller.hxx> |
| 19 | #include <BOPAlgo_SectionAttribute.hxx> |
| 20 | #include <BOPCol_IndexedMapOfShape.hxx> |
| 21 | #include <BOPCol_NCVector.hxx> |
| 22 | #include <BOPCol_Parallel.hxx> |
| 23 | #include <BOPDS_CommonBlock.hxx> |
| 24 | #include <BOPDS_Curve.hxx> |
| 25 | #include <BOPDS_DS.hxx> |
| 26 | #include <BOPDS_FaceInfo.hxx> |
| 27 | #include <BOPDS_Interf.hxx> |
| 28 | #include <BOPDS_Iterator.hxx> |
| 29 | #include <BOPDS_ListOfPaveBlock.hxx> |
| 30 | #include <BOPDS_MapOfPaveBlock.hxx> |
| 31 | #include <BOPDS_Pave.hxx> |
| 32 | #include <BOPDS_PaveBlock.hxx> |
| 33 | #include <BOPDS_ShapeInfo.hxx> |
| 34 | #include <BOPDS_VectorOfCurve.hxx> |
| 35 | #include <BOPDS_VectorOfFaceInfo.hxx> |
| 36 | #include <BOPDS_VectorOfInterfFF.hxx> |
| 37 | #include <BOPDS_VectorOfListOfPaveBlock.hxx> |
| 38 | #include <BOPTools_AlgoTools.hxx> |
| 39 | #include <BOPTools_AlgoTools2D.hxx> |
| 40 | #include <BRep_Builder.hxx> |
| 41 | #include <BRep_Tool.hxx> |
| 42 | #include <BRepBndLib.hxx> |
| 43 | #include <Geom2d_Curve.hxx> |
| 44 | #include <Geom_Curve.hxx> |
| 45 | #include <Geom_Plane.hxx> |
| 46 | #include <Geom_RectangularTrimmedSurface.hxx> |
| 47 | #include <Geom_Surface.hxx> |
| 48 | #include <gp_Pnt.hxx> |
| 49 | #include <IntTools_Context.hxx> |
| 50 | #include <TopExp.hxx> |
| 51 | #include <TopExp_Explorer.hxx> |
| 52 | #include <TopoDS_Edge.hxx> |
| 53 | #include <TopoDS_Face.hxx> |
| 54 | #include <TopoDS_Vertex.hxx> |
| 55 | |
| 56 | |
| 57 | static |
| 58 | Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF); |
| 59 | |
| 60 | |
| 61 | static void UpdateVertices(const TopoDS_Edge& aE, |
| 62 | const TopoDS_Face& aF); |
| 63 | |
| 64 | //======================================================================= |
| 65 | //class : BOPAlgo_SplitEdge |
| 66 | //purpose : |
| 67 | //======================================================================= |
| 68 | class BOPAlgo_SplitEdge : public BOPAlgo_Algo { |
| 69 | |
| 70 | public: |
| 71 | DEFINE_STANDARD_ALLOC |
| 72 | |
| 73 | BOPAlgo_SplitEdge() : |
| 74 | BOPAlgo_Algo() { |
| 75 | myT1=0.; |
| 76 | myT2=0.; |
| 77 | } |
| 78 | // |
| 79 | virtual ~BOPAlgo_SplitEdge() { |
| 80 | } |
| 81 | // |
| 82 | void SetData(const TopoDS_Edge& aE, |
| 83 | const TopoDS_Vertex& aV1, |
| 84 | const Standard_Real aT1, |
| 85 | const TopoDS_Vertex& aV2, |
| 86 | const Standard_Real aT2) { |
| 87 | myE=aE; |
| 88 | myV1=aV1; |
| 89 | myT1=aT1; |
| 90 | myV2=aV2; |
| 91 | myT2=aT2; |
| 92 | myESp=aE; |
| 93 | } |
| 94 | // |
| 95 | void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) { |
| 96 | myPB=aPB; |
| 97 | } |
| 98 | // |
| 99 | Handle(BOPDS_PaveBlock)& PaveBlock() { |
| 100 | return myPB; |
| 101 | } |
| 102 | // |
| 103 | void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) { |
| 104 | myCB=aCB; |
| 105 | } |
| 106 | // |
| 107 | Handle(BOPDS_CommonBlock)& CommonBlock() { |
| 108 | return myCB; |
| 109 | } |
| 110 | // |
| 111 | const TopoDS_Edge& SplitEdge() const { |
| 112 | return myESp; |
| 113 | } |
| 114 | // |
| 115 | const Bnd_Box Box() { |
| 116 | return myBox; |
| 117 | } |
| 118 | // |
| 119 | virtual void Perform () { |
| 120 | BOPAlgo_Algo::UserBreak(); |
| 121 | BOPTools_AlgoTools::MakeSplitEdge(myE, |
| 122 | myV1, myT1, |
| 123 | myV2, myT2, |
| 124 | myESp); |
| 125 | BRepBndLib::Add(myESp, myBox); |
| 126 | } |
| 127 | // |
| 128 | protected: |
| 129 | // -> |
| 130 | TopoDS_Edge myE; |
| 131 | TopoDS_Vertex myV1; |
| 132 | Standard_Real myT1; |
| 133 | TopoDS_Vertex myV2; |
| 134 | Standard_Real myT2; |
| 135 | // <-> |
| 136 | Handle(BOPDS_PaveBlock) myPB; |
| 137 | Handle(BOPDS_CommonBlock) myCB; |
| 138 | // <- |
| 139 | TopoDS_Edge myESp; |
| 140 | Bnd_Box myBox; |
| 141 | }; |
| 142 | // |
| 143 | //======================================================================= |
| 144 | typedef BOPCol_NCVector |
| 145 | <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge; |
| 146 | // |
| 147 | typedef BOPCol_Functor |
| 148 | <BOPAlgo_SplitEdge, |
| 149 | BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor; |
| 150 | // |
| 151 | typedef BOPCol_Cnt |
| 152 | <BOPAlgo_SplitEdgeFunctor, |
| 153 | BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeCnt; |
| 154 | // |
| 155 | //======================================================================= |
| 156 | //class : BOPAlgo_MPC |
| 157 | //purpose : |
| 158 | //======================================================================= |
| 159 | class BOPAlgo_MPC : public BOPAlgo_Algo { |
| 160 | |
| 161 | public: |
| 162 | DEFINE_STANDARD_ALLOC |
| 163 | |
| 164 | BOPAlgo_MPC() : |
| 165 | BOPAlgo_Algo(), |
| 166 | myFlag(Standard_False) { |
| 167 | }; |
| 168 | // |
| 169 | virtual ~BOPAlgo_MPC(){ |
| 170 | }; |
| 171 | // |
| 172 | void SetEdge(const TopoDS_Edge& aE) { |
| 173 | myE=aE; |
| 174 | } |
| 175 | // |
| 176 | const TopoDS_Edge& Edge() const { |
| 177 | return myE; |
| 178 | } |
| 179 | // |
| 180 | void SetFace(const TopoDS_Face& aF) { |
| 181 | myF=aF; |
| 182 | } |
| 183 | // |
| 184 | const TopoDS_Face& Face() const { |
| 185 | return myF; |
| 186 | } |
| 187 | // |
| 188 | void SetFlag(const Standard_Boolean bFlag) { |
| 189 | myFlag=bFlag; |
| 190 | } |
| 191 | // |
| 192 | Standard_Boolean Flag() const { |
| 193 | return myFlag; |
| 194 | } |
| 195 | // |
| 196 | void SetData(const TopoDS_Edge& aEz, |
| 197 | const TopoDS_Vertex& aV1, |
| 198 | const Standard_Real aT1, |
| 199 | const TopoDS_Vertex& aV2, |
| 200 | const Standard_Real aT2) { |
| 201 | myEz=aEz; |
| 202 | myV1=aV1; |
| 203 | myT1=aT1; |
| 204 | myV2=aV2; |
| 205 | myT2=aT2; |
| 206 | } |
| 207 | // |
| 208 | void SetContext(const Handle(IntTools_Context)& aContext) { |
| 209 | myContext=aContext; |
| 210 | } |
| 211 | // |
| 212 | const Handle(IntTools_Context)& Context()const { |
| 213 | return myContext; |
| 214 | } |
| 215 | // |
| 216 | virtual void Perform() { |
| 217 | Standard_Integer iErr; |
| 218 | // |
| 219 | iErr=1; |
| 220 | if (!myEz.IsNull()) { |
| 221 | TopoDS_Edge aSpz; |
| 222 | // |
| 223 | BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1, |
| 224 | myV2, myT2, aSpz); |
| 225 | // |
| 226 | iErr= |
| 227 | BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, |
| 228 | myE, |
| 229 | myF, |
| 230 | myContext); |
| 231 | } |
| 232 | // |
| 233 | if (iErr) { |
| 234 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF); |
| 235 | } |
| 236 | // |
| 237 | if (myFlag) { |
| 238 | UpdateVertices(myE, myF); |
| 239 | } |
| 240 | } |
| 241 | // |
| 242 | protected: |
| 243 | Standard_Boolean myFlag; |
| 244 | TopoDS_Edge myE; |
| 245 | TopoDS_Face myF; |
| 246 | TopoDS_Edge myEz; |
| 247 | TopoDS_Vertex myV1; |
| 248 | Standard_Real myT1; |
| 249 | TopoDS_Vertex myV2; |
| 250 | Standard_Real myT2; |
| 251 | // |
| 252 | Handle(IntTools_Context) myContext; |
| 253 | }; |
| 254 | // |
| 255 | //======================================================================= |
| 256 | typedef BOPCol_NCVector |
| 257 | <BOPAlgo_MPC> BOPAlgo_VectorOfMPC; |
| 258 | // |
| 259 | typedef BOPCol_ContextFunctor |
| 260 | <BOPAlgo_MPC, |
| 261 | BOPAlgo_VectorOfMPC, |
| 262 | Handle(IntTools_Context), |
| 263 | IntTools_Context> BOPAlgo_MPCFunctor; |
| 264 | // |
| 265 | typedef BOPCol_ContextCnt |
| 266 | <BOPAlgo_MPCFunctor, |
| 267 | BOPAlgo_VectorOfMPC, |
| 268 | Handle(IntTools_Context)> BOPAlgo_MPCCnt; |
| 269 | // |
| 270 | //======================================================================= |
| 271 | //class : BOPAlgo_BPC |
| 272 | //purpose : |
| 273 | //======================================================================= |
| 274 | class BOPAlgo_BPC { |
| 275 | public: |
| 276 | BOPAlgo_BPC(){ |
| 277 | }; |
| 278 | // |
| 279 | ~BOPAlgo_BPC(){ |
| 280 | }; |
| 281 | // |
| 282 | void SetFace(const TopoDS_Face& aF) { |
| 283 | myF=aF; |
| 284 | } |
| 285 | // |
| 286 | void SetEdge(const TopoDS_Edge& aE) { |
| 287 | myE=aE; |
| 288 | } |
| 289 | // |
| 290 | const TopoDS_Edge& GetEdge() const { |
| 291 | return myE; |
| 292 | } |
| 293 | const TopoDS_Face& GetFace() const { |
| 294 | return myF; |
| 295 | } |
| 296 | const Handle(Geom2d_Curve)& GetCurve2d() const { |
| 297 | return myCurve; |
| 298 | } |
| 299 | Standard_Boolean IsToUpdate() const { |
| 300 | return myToUpdate; |
| 301 | } |
| 302 | // |
| 303 | void Perform() { |
| 304 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF, myCurve, myToUpdate); |
| 305 | }; |
| 306 | // |
| 307 | protected: |
| 308 | TopoDS_Edge myE; |
| 309 | TopoDS_Face myF; |
| 310 | Handle(Geom2d_Curve) myCurve; |
| 311 | Standard_Boolean myToUpdate; |
| 312 | }; |
| 313 | //======================================================================= |
| 314 | typedef BOPCol_NCVector |
| 315 | <BOPAlgo_BPC> BOPAlgo_VectorOfBPC; |
| 316 | // |
| 317 | typedef BOPCol_Functor |
| 318 | <BOPAlgo_BPC, |
| 319 | BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor; |
| 320 | // |
| 321 | typedef BOPCol_Cnt |
| 322 | <BOPAlgo_BPCFunctor, |
| 323 | BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt; |
| 324 | // |
| 325 | // |
| 326 | //======================================================================= |
| 327 | // function: MakeSplitEdges |
| 328 | // purpose: |
| 329 | //======================================================================= |
| 330 | void BOPAlgo_PaveFiller::MakeSplitEdges() |
| 331 | { |
| 332 | Standard_Integer aNbPBP; |
| 333 | // |
| 334 | myErrorStatus=0; |
| 335 | // |
| 336 | BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool(); |
| 337 | aNbPBP=aPBP.Extent(); |
| 338 | if(!aNbPBP) { |
| 339 | return; |
| 340 | } |
| 341 | // |
| 342 | Standard_Boolean bCB, bV1, bV2; |
| 343 | Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k; |
| 344 | Standard_Real aT1, aT2; |
| 345 | BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB; |
| 346 | Handle(BOPDS_PaveBlock) aPB; |
| 347 | BOPDS_MapOfPaveBlock aMPB(100); |
| 348 | TopoDS_Vertex aV1, aV2; |
| 349 | TopoDS_Edge aE; |
| 350 | BOPAlgo_VectorOfSplitEdge aVBSE; |
| 351 | |
| 352 | // |
| 353 | for (i=0; i<aNbPBP; ++i) { |
| 354 | BOPDS_ListOfPaveBlock& aLPB=aPBP(i); |
| 355 | // |
| 356 | aNbPB=aLPB.Extent(); |
| 357 | if (aNbPB==1) { |
| 358 | aPB=aLPB.First(); |
| 359 | aPB->Indices(nV1, nV2); |
| 360 | bV1=myDS->IsNewShape(nV1); |
| 361 | bV2=myDS->IsNewShape(nV2); |
| 362 | // |
| 363 | if (!(bV1 || bV2)) { |
| 364 | nE=aPB->OriginalEdge(); |
| 365 | aPB->SetEdge(nE); |
| 366 | continue; |
| 367 | } |
| 368 | } |
| 369 | // |
| 370 | aItPB.Initialize(aLPB); |
| 371 | for (; aItPB.More(); aItPB.Next()) { |
| 372 | aPB=aItPB.Value(); |
| 373 | const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB); |
| 374 | bCB=!aCB.IsNull(); |
| 375 | if (bCB) { |
| 376 | myDS->SortPaveBlocks(aCB); |
| 377 | aPB=aCB->PaveBlock1(); |
| 378 | } |
| 379 | // |
| 380 | if (aMPB.Add(aPB)) { |
| 381 | nE=aPB->OriginalEdge(); |
| 382 | aPB->Indices(nV1, nV2); |
| 383 | aPB->Range(aT1, aT2); |
| 384 | // |
| 385 | aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 386 | aE.Orientation(TopAbs_FORWARD); |
| 387 | // |
| 388 | aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
| 389 | aV1.Orientation(TopAbs_FORWARD); |
| 390 | // |
| 391 | aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
| 392 | aV2.Orientation(TopAbs_REVERSED); |
| 393 | // |
| 394 | BOPAlgo_SplitEdge& aBSE=aVBSE.Append1(); |
| 395 | // |
| 396 | aBSE.SetData(aE, aV1, aT1, aV2, aT2); |
| 397 | aBSE.SetPaveBlock(aPB); |
| 398 | if (bCB) { |
| 399 | aBSE.SetCommonBlock(aCB); |
| 400 | } |
| 401 | aBSE.SetProgressIndicator(myProgressIndicator); |
| 402 | } |
| 403 | } // for (; aItPB.More(); aItPB.Next()) { |
| 404 | } // for (i=0; i<aNbPBP; ++i) { |
| 405 | // |
| 406 | aNbVBSE=aVBSE.Extent(); |
| 407 | //====================================================== |
| 408 | BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE); |
| 409 | //====================================================== |
| 410 | // |
| 411 | BOPDS_ShapeInfo aSI; |
| 412 | // |
| 413 | aSI.SetShapeType(TopAbs_EDGE); |
| 414 | // |
| 415 | for (k=0; k < aNbVBSE; ++k) { |
| 416 | BOPAlgo_SplitEdge& aBSE=aVBSE(k); |
| 417 | // |
| 418 | const TopoDS_Edge& aSp=aBSE.SplitEdge(); |
| 419 | const Bnd_Box& aBox=aBSE.Box(); |
| 420 | // |
| 421 | Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock(); |
| 422 | Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock(); |
| 423 | // |
| 424 | aSI.SetShape(aSp); |
| 425 | aSI.ChangeBox()=aBox; |
| 426 | // |
| 427 | nSp=myDS->Append(aSI); |
| 428 | // |
| 429 | if (!aCBk.IsNull()) { |
| 430 | aCBk->SetEdge(nSp); |
| 431 | } |
| 432 | else { |
| 433 | aPBk->SetEdge(nSp); |
| 434 | } |
| 435 | } |
| 436 | } |
| 437 | //======================================================================= |
| 438 | // function: SplitEdge |
| 439 | // purpose: |
| 440 | //======================================================================= |
| 441 | Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, |
| 442 | const Standard_Integer nV1, |
| 443 | const Standard_Real aT1, |
| 444 | const Standard_Integer nV2, |
| 445 | const Standard_Real aT2) |
| 446 | { |
| 447 | Standard_Integer nSp; |
| 448 | TopoDS_Vertex aV1, aV2; |
| 449 | TopoDS_Edge aE, aSp; |
| 450 | BOPDS_ShapeInfo aSI; |
| 451 | // |
| 452 | aSI.SetShapeType(TopAbs_EDGE); |
| 453 | // |
| 454 | aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 455 | aE.Orientation(TopAbs_FORWARD); |
| 456 | // |
| 457 | aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
| 458 | aV1.Orientation(TopAbs_FORWARD); |
| 459 | // |
| 460 | aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
| 461 | aV2.Orientation(TopAbs_REVERSED); |
| 462 | // |
| 463 | BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp); |
| 464 | // |
| 465 | aSI.SetShape(aSp); |
| 466 | // |
| 467 | Bnd_Box& aBox=aSI.ChangeBox(); |
| 468 | BRepBndLib::Add(aSp, aBox); |
| 469 | // |
| 470 | nSp=myDS->Append(aSI); |
| 471 | return nSp; |
| 472 | } |
| 473 | //======================================================================= |
| 474 | // function: MakePCurves |
| 475 | // purpose: |
| 476 | //======================================================================= |
| 477 | void BOPAlgo_PaveFiller::MakePCurves() |
| 478 | { |
| 479 | Standard_Boolean bHasPC; |
| 480 | Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI, nEx; |
| 481 | Standard_Integer j, aNbPBIn, aNbPBOn; |
| 482 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
| 483 | TopoDS_Face aF1F, aF2F; |
| 484 | BOPAlgo_VectorOfMPC aVMPC; |
| 485 | // |
| 486 | myErrorStatus=0; |
| 487 | // |
| 488 | // 1. Process Common Blocks |
| 489 | const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool(); |
| 490 | // |
| 491 | aNbFI=aFIP.Extent(); |
| 492 | for (i=0; i<aNbFI; ++i) { |
| 493 | const BOPDS_FaceInfo& aFI=aFIP(i); |
| 494 | nF1=aFI.Index(); |
| 495 | // |
| 496 | aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1))); |
| 497 | aF1F.Orientation(TopAbs_FORWARD); |
| 498 | // In |
| 499 | const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn(); |
| 500 | aNbPBIn = aMPBIn.Extent(); |
| 501 | for (j = 1; j <= aNbPBIn; ++j) { |
| 502 | const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(j); |
| 503 | nE=aPB->Edge(); |
| 504 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 505 | // |
| 506 | BOPAlgo_MPC& aMPC=aVMPC.Append1(); |
| 507 | aMPC.SetEdge(aE); |
| 508 | aMPC.SetFace(aF1F); |
| 509 | aMPC.SetProgressIndicator(myProgressIndicator); |
| 510 | } |
| 511 | // |
| 512 | // On |
| 513 | const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn(); |
| 514 | aNbPBOn = aMPBOn.Extent(); |
| 515 | for (j = 1; j <= aNbPBOn; ++j) { |
| 516 | const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(j); |
| 517 | nE=aPB->Edge(); |
| 518 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 519 | bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F); |
| 520 | if (bHasPC) { |
| 521 | continue; |
| 522 | } |
| 523 | // |
| 524 | Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB); |
| 525 | if (aCB.IsNull()) { |
| 526 | continue; |
| 527 | } |
| 528 | // |
| 529 | const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks(); |
| 530 | if (aLPB.Extent()<2) { |
| 531 | continue; |
| 532 | } |
| 533 | // |
| 534 | BOPAlgo_MPC& aMPC=aVMPC.Append1(); |
| 535 | // |
| 536 | aItLPB.Initialize(aLPB); |
| 537 | for(; aItLPB.More(); aItLPB.Next()) { |
| 538 | const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value(); |
| 539 | if (aPBx==aPB) { |
| 540 | continue; |
| 541 | } |
| 542 | // |
| 543 | nEx=aPBx->OriginalEdge(); |
| 544 | const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx))); |
| 545 | bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F); |
| 546 | if (!bHasPC) { |
| 547 | continue; |
| 548 | } |
| 549 | // |
| 550 | Standard_Integer nV1x, nV2x; |
| 551 | Standard_Real aT1x, aT2x; |
| 552 | TopoDS_Vertex aV1x, aV2x; |
| 553 | TopoDS_Edge aEz; |
| 554 | // |
| 555 | aEz=aEx; |
| 556 | aEz.Orientation(TopAbs_FORWARD); |
| 557 | // |
| 558 | aPBx->Indices(nV1x, nV2x); |
| 559 | aPBx->Range(aT1x, aT2x); |
| 560 | // |
| 561 | aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x))); |
| 562 | aV1x.Orientation(TopAbs_FORWARD); |
| 563 | // |
| 564 | aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x))); |
| 565 | aV2x.Orientation(TopAbs_REVERSED); |
| 566 | // |
| 567 | aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x); |
| 568 | // |
| 569 | break; |
| 570 | } |
| 571 | // |
| 572 | aMPC.SetEdge(aE); |
| 573 | aMPC.SetFace(aF1F); |
| 574 | aMPC.SetProgressIndicator(myProgressIndicator); |
| 575 | } |
| 576 | }// for (i=0; i<aNbFI; ++i) { |
| 577 | // |
| 578 | // 2. Process section edges |
| 579 | Standard_Boolean bPCurveOnS[2]; |
| 580 | Standard_Integer m; |
| 581 | TopoDS_Face aFf[2]; |
| 582 | // |
| 583 | bPCurveOnS[0]=mySectionAttribute.PCurveOnS1(); |
| 584 | bPCurveOnS[1]=mySectionAttribute.PCurveOnS2(); |
| 585 | // |
| 586 | if (bPCurveOnS[0] || bPCurveOnS[1]) { |
| 587 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
| 588 | aNbFF=aFFs.Extent(); |
| 589 | for (i=0; i<aNbFF; ++i) { |
| 590 | const BOPDS_InterfFF& aFF=aFFs(i); |
| 591 | aFF.Indices(nF1, nF2); |
| 592 | // |
| 593 | aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1))); |
| 594 | aFf[0].Orientation(TopAbs_FORWARD); |
| 595 | // |
| 596 | aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2))); |
| 597 | aFf[1].Orientation(TopAbs_FORWARD); |
| 598 | // |
| 599 | const BOPDS_VectorOfCurve& aVNC=aFF.Curves(); |
| 600 | aNbC=aVNC.Extent(); |
| 601 | for (k=0; k<aNbC; ++k) { |
| 602 | const BOPDS_Curve& aNC=aVNC(k); |
| 603 | const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks(); |
| 604 | aItLPB.Initialize(aLPB); |
| 605 | for(; aItLPB.More(); aItLPB.Next()) { |
| 606 | const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value(); |
| 607 | nE=aPB->Edge(); |
| 608 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 609 | // |
| 610 | for (m=0; m<2; ++m) { |
| 611 | if (bPCurveOnS[m]) { |
| 612 | BOPAlgo_MPC& aMPC=aVMPC.Append1(); |
| 613 | aMPC.SetEdge(aE); |
| 614 | aMPC.SetFace(aFf[m]); |
| 615 | aMPC.SetFlag(bPCurveOnS[m]); |
| 616 | aMPC.SetProgressIndicator(myProgressIndicator); |
| 617 | } |
| 618 | } |
| 619 | } |
| 620 | } |
| 621 | }// for (i=0; i<aNbFF; ++i) { |
| 622 | }//if (bPCurveOnS1 || bPCurveOnS2 ) { |
| 623 | // |
| 624 | //====================================================== |
| 625 | BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext); |
| 626 | //====================================================== |
| 627 | } |
| 628 | //======================================================================= |
| 629 | // function: RefineFaceInfoOn |
| 630 | // purpose: |
| 631 | //======================================================================= |
| 632 | void BOPAlgo_PaveFiller::RefineFaceInfoOn() |
| 633 | { |
| 634 | Standard_Integer aNbPBP; |
| 635 | // |
| 636 | myErrorStatus=0; |
| 637 | // |
| 638 | BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool(); |
| 639 | aNbPBP=aPBP.Extent(); |
| 640 | if(!aNbPBP) { |
| 641 | return; |
| 642 | } |
| 643 | // |
| 644 | Standard_Boolean bV1, bV2; |
| 645 | Standard_Integer i, nV1, nV2, aNbPB; |
| 646 | Handle(BOPDS_PaveBlock) aPB; |
| 647 | // |
| 648 | for (i=0; i<aNbPBP; ++i) { |
| 649 | BOPDS_ListOfPaveBlock& aLPB=aPBP(i); |
| 650 | // |
| 651 | aNbPB=aLPB.Extent(); |
| 652 | if (aNbPB==1) { |
| 653 | aPB=aLPB.First(); |
| 654 | aPB->Indices(nV1, nV2); |
| 655 | bV1=myDS->IsNewShape(nV1); |
| 656 | bV2=myDS->IsNewShape(nV2); |
| 657 | // |
| 658 | if (!(bV1 || bV2)) { |
| 659 | if (!myDS->IsCommonBlock(aPB)) { |
| 660 | // the PB seems to be untouced |
| 661 | aLPB.Clear(); |
| 662 | continue; |
| 663 | } |
| 664 | }//if (!(bV1 || bV2)) { |
| 665 | }//if (aNbPB==1) { |
| 666 | }//for (i=0; i<aNbPBP; ++i) { |
| 667 | myDS->RefineFaceInfoOn(); |
| 668 | } |
| 669 | //======================================================================= |
| 670 | //function : UpdateVertices |
| 671 | //purpose : update tolerances of vertices comparing extremities of |
| 672 | // 3d and 2d curves |
| 673 | //======================================================================= |
| 674 | void UpdateVertices(const TopoDS_Edge& aE, |
| 675 | const TopoDS_Face& aF) |
| 676 | { |
| 677 | Standard_Integer j; |
| 678 | Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD; |
| 679 | gp_Pnt aP3D, aP3Dx; |
| 680 | gp_Pnt2d aP2Dx; |
| 681 | Handle(Geom_Surface) aS; |
| 682 | Handle(Geom_Curve) aC3D; |
| 683 | Handle(Geom2d_Curve) aC2D; |
| 684 | TopoDS_Edge aEf; |
| 685 | TopoDS_Vertex aV[2]; |
| 686 | BRep_Builder aBB; |
| 687 | // |
| 688 | aEf=aE; |
| 689 | aEf.Orientation(TopAbs_FORWARD); |
| 690 | // |
| 691 | TopExp::Vertices(aEf, aV[0], aV[1]); |
| 692 | // |
| 693 | aS=BRep_Tool::Surface(aF); |
| 694 | aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]); |
| 695 | aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]); |
| 696 | // |
| 697 | for (j=0; j<2; ++j) { |
| 698 | aTolV2=BRep_Tool::Tolerance(aV[j]); |
| 699 | aTolV2=aTolV2*aTolV2; |
| 700 | // |
| 701 | aC3D->D0(aT[j], aP3D); |
| 702 | aC2D->D0(aT[j], aP2Dx); |
| 703 | aP2Dx.Coord(aUx, aVx); |
| 704 | aS->D0(aUx, aVx, aP3Dx); |
| 705 | aD2=aP3D.SquareDistance(aP3Dx); |
| 706 | if (aD2>aTolV2) { |
| 707 | aD=sqrt(aD2); |
| 708 | aBB.UpdateVertex(aV[j], aD); |
| 709 | } |
| 710 | } |
| 711 | } |
| 712 | //======================================================================= |
| 713 | // function: Prepare |
| 714 | // purpose: |
| 715 | //======================================================================= |
| 716 | void BOPAlgo_PaveFiller::Prepare() |
| 717 | { |
| 718 | TopAbs_ShapeEnum aType[] = { |
| 719 | TopAbs_VERTEX, |
| 720 | TopAbs_EDGE, |
| 721 | TopAbs_FACE |
| 722 | }; |
| 723 | Standard_Boolean bJustAdd, bIsBasedOnPlane; |
| 724 | Standard_Integer i, aNb, n1, nF, aNbF; |
| 725 | TopExp_Explorer aExp; |
| 726 | BOPCol_IndexedMapOfShape aMF; |
| 727 | // |
| 728 | myErrorStatus=0; |
| 729 | // |
| 730 | aNb=3; |
| 731 | for(i=0; i<aNb; ++i) { |
| 732 | myIterator->Initialize(aType[i], aType[2]); |
| 733 | for (; myIterator->More(); myIterator->Next()) { |
| 734 | myIterator->Value(n1, nF, bJustAdd); |
| 735 | const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); |
| 736 | // |
| 737 | bIsBasedOnPlane=IsBasedOnPlane(aF); |
| 738 | if (bIsBasedOnPlane) { |
| 739 | aMF.Add(aF); |
| 740 | } |
| 741 | } |
| 742 | } |
| 743 | // |
| 744 | aNbF = aMF.Extent(); |
| 745 | if (!aNbF) { |
| 746 | return; |
| 747 | } |
| 748 | // |
| 749 | // Build pcurves of edges on planes; first collect pairs edge-face. |
| 750 | BOPAlgo_VectorOfBPC aVBPC; |
| 751 | // |
| 752 | for (i = 1; i <= aNbF; ++i) { |
| 753 | const TopoDS_Face& aF = *(TopoDS_Face*)&aMF(i); |
| 754 | aExp.Init(aF, aType[1]); |
| 755 | for (; aExp.More(); aExp.Next()) { |
| 756 | const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current()); |
| 757 | BOPAlgo_BPC& aBPC=aVBPC.Append1(); |
| 758 | aBPC.SetEdge(aE); |
| 759 | aBPC.SetFace(aF); |
| 760 | } |
| 761 | } |
| 762 | // |
| 763 | //====================================================== |
| 764 | BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC); |
| 765 | //====================================================== |
| 766 | |
| 767 | // pcurves are built, and now update edges |
| 768 | BRep_Builder aBB; |
| 769 | TopoDS_Edge E; |
| 770 | for (i = 0; i < aVBPC.Extent(); i++) { |
| 771 | const BOPAlgo_BPC& aBPC=aVBPC(i); |
| 772 | if (aBPC.IsToUpdate()) { |
| 773 | Standard_Real aTolE = BRep_Tool::Tolerance(aBPC.GetEdge()); |
| 774 | aBB.UpdateEdge(aBPC.GetEdge(), aBPC.GetCurve2d(), aBPC.GetFace(), aTolE); |
| 775 | } |
| 776 | } |
| 777 | } |
| 778 | //======================================================================= |
| 779 | //function : IsBasedOnPlane |
| 780 | //purpose : |
| 781 | //======================================================================= |
| 782 | Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF) |
| 783 | { |
| 784 | TopLoc_Location aLoc; |
| 785 | Handle(Geom_RectangularTrimmedSurface) aGRTS; |
| 786 | Handle(Geom_Plane) aGP; |
| 787 | |
| 788 | const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc); |
| 789 | aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS); |
| 790 | if(!aGRTS.IsNull()) { |
| 791 | aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface()); |
| 792 | } |
| 793 | else { |
| 794 | aGP = Handle(Geom_Plane)::DownCast(aS); |
| 795 | } |
| 796 | // |
| 797 | return (!aGP.IsNull()); |
| 798 | } |