| 483 | } |
| 484 | |
| 485 | void xyPlaneMeshIntersect( const MeshPart& meshPart, float zLevel, |
| 486 | FaceBitSet * fs, UndirectedEdgeBitSet * ues, VertBitSet * vs, std::vector<FaceId> * fsVec ) |
| 487 | { |
| 488 | MR_TIMER; |
| 489 | assert( fs || ues || vs || fsVec ); |
| 490 | |
| 491 | const auto& m = meshPart.mesh; |
| 492 | const auto& tree = m.getAABBTree(); |
| 493 | if( tree.nodes().empty() ) |
| 494 | return; |
| 495 | |
| 496 | assert( !fs || fs->size() >= m.topology.faceSize() ); |
| 497 | assert( !ues || ues->size() >= m.topology.undirectedEdgeSize() ); |
| 498 | assert( !vs || vs->size() >= m.topology.vertSize() ); |
| 499 | |
| 500 | constexpr int maxTreeDepth = 32; |
| 501 | NodeId nodesStack[maxTreeDepth]; |
| 502 | int currentNode = -1; |
| 503 | |
| 504 | auto addNode = [&]( NodeId nid ) |
| 505 | { |
| 506 | const auto & box = tree[nid].box; |
| 507 | if ( box.min.z <= zLevel && box.max.z >= zLevel ) |
| 508 | nodesStack[++currentNode] = nid; |
| 509 | }; |
| 510 | addNode( tree.rootNodeId() ); |
| 511 | |
| 512 | while( currentNode >= 0 ) |
| 513 | { |
| 514 | if( currentNode >= maxTreeDepth ) // max depth exceeded |
| 515 | { |
| 516 | spdlog::critical( "Maximal AABBTree depth reached!" ); |
| 517 | assert( false ); |
| 518 | break; |
| 519 | } |
| 520 | |
| 521 | const auto& node = tree[nodesStack[currentNode--]]; |
| 522 | if( node.leaf() ) |
| 523 | { |
| 524 | auto face = node.leafId(); |
| 525 | if( !meshPart.region || meshPart.region->test( face ) ) |
| 526 | { |
| 527 | if ( fs ) |
| 528 | fs->set( face ); |
| 529 | if ( fsVec ) |
| 530 | fsVec->push_back( face ); |
| 531 | if ( ues || vs ) |
| 532 | { |
| 533 | EdgeId e0, e1, e2; |
| 534 | m.topology.getTriEdges( face, e0, e1, e2 ); |
| 535 | if ( ues ) |
| 536 | { |
| 537 | ues->set( e0 ); |
| 538 | ues->set( e1 ); |
| 539 | ues->set( e2 ); |
| 540 | } |
| 541 | if ( vs ) |
| 542 | { |
no test coverage detected