| 127 | } |
| 128 | |
| 129 | void findBoxedTrisInBall( const MeshPart & mp, Ball3f ball, const FoundBoxedTriCallback& foundCallback ) |
| 130 | { |
| 131 | const auto & tree = mp.mesh.getAABBTree(); |
| 132 | if ( tree.nodes().empty() ) |
| 133 | return; |
| 134 | |
| 135 | InplaceStack<NoInitNodeId, 32> subtasks; |
| 136 | |
| 137 | auto boxDistSq = [&]( NodeId n ) // squared distance from ball center to the box with interior |
| 138 | { |
| 139 | return tree.nodes()[n].box.getDistanceSq( ball.center ); |
| 140 | }; |
| 141 | |
| 142 | auto addSubTask = [&]( NodeId n ) |
| 143 | { |
| 144 | subtasks.push( n ); |
| 145 | }; |
| 146 | |
| 147 | addSubTask( tree.rootNodeId() ); |
| 148 | |
| 149 | while ( !subtasks.empty() ) |
| 150 | { |
| 151 | const auto n = subtasks.top(); |
| 152 | subtasks.pop(); |
| 153 | const auto & node = tree[n]; |
| 154 | if ( !( boxDistSq( n ) < ball.radiusSq ) ) |
| 155 | continue; |
| 156 | |
| 157 | if ( node.leaf() ) |
| 158 | { |
| 159 | const auto face = node.leafId(); |
| 160 | if ( mp.region && !mp.region->test( face ) ) |
| 161 | continue; |
| 162 | if ( foundCallback( face, ball ) == Processing::Stop ) |
| 163 | break; |
| 164 | continue; |
| 165 | } |
| 166 | |
| 167 | auto lDistSq = boxDistSq( node.l ); |
| 168 | auto rDistSq = boxDistSq( node.r ); |
| 169 | /// first go in the node located closer to ball's center (in case the ball will shrink and the other node will be away) |
| 170 | if ( lDistSq <= rDistSq ) |
| 171 | { |
| 172 | addSubTask( node.r ); |
| 173 | addSubTask( node.l ); |
| 174 | } |
| 175 | else |
| 176 | { |
| 177 | addSubTask( node.l ); |
| 178 | addSubTask( node.r ); |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | void findTrisInBall( const MeshPart & mp, const Ball3f& ball, const FoundTriCallback& foundCallback, const FacePredicate & validFaces ) |
| 184 | { |
no test coverage detected