| 63 | } |
| 64 | |
| 65 | FaceBitSet findInnerShellFacesWithSplits( const MeshPart & mp, Mesh & shell, const FindInnerShellSettings & settings ) |
| 66 | { |
| 67 | MR_TIMER; |
| 68 | const auto innerVerts = findInnerShellVerts( mp, shell, settings ); |
| 69 | |
| 70 | // find all edges connecting inner and not-inner vertices |
| 71 | UndirectedEdgeBitSet ues( shell.topology.undirectedEdgeSize() ); |
| 72 | BitSetParallelForAll( ues, [&]( UndirectedEdgeId ue ) |
| 73 | { |
| 74 | if ( contains( innerVerts, shell.topology.org( ue ) ) != contains( innerVerts, shell.topology.dest( ue ) ) ) |
| 75 | ues.set( ue ); |
| 76 | } ); |
| 77 | |
| 78 | std::vector<EdgePoint> splitEdges; |
| 79 | splitEdges.reserve( ues.count() ); |
| 80 | for ( EdgeId e : ues ) |
| 81 | splitEdges.emplace_back( e, 0.f ); |
| 82 | |
| 83 | // find split-point on each edge |
| 84 | ParallelFor( splitEdges, [&]( size_t i ) |
| 85 | { |
| 86 | EdgeId e = splitEdges[i].e; |
| 87 | if ( !contains( innerVerts, shell.topology.org( e ) ) ) |
| 88 | e = e.sym(); |
| 89 | assert( contains( innerVerts, shell.topology.org( e ) ) ); |
| 90 | assert( !contains( innerVerts, shell.topology.dest( e ) ) ); |
| 91 | auto a = shell.orgPnt( e ); |
| 92 | auto b = shell.destPnt( e ); |
| 93 | float av = 0, bv = 1; |
| 94 | // binary search |
| 95 | for ( int j = 0; j < 8; ++j ) |
| 96 | { |
| 97 | const auto v = 0.5f * ( av + bv ); |
| 98 | const auto p = ( 1 - v ) * a + v * b; |
| 99 | if ( classifyShellVert( mp, p, settings ).valid() ) |
| 100 | av = v; |
| 101 | else |
| 102 | bv = v; |
| 103 | } |
| 104 | splitEdges[i] = EdgePoint( e, 0.5f * ( av + bv ) ); |
| 105 | } ); |
| 106 | |
| 107 | // perform actual splitting |
| 108 | for ( const auto & ep : splitEdges ) |
| 109 | shell.splitEdge( ep.e, shell.edgePoint( ep ) ); |
| 110 | |
| 111 | return getIncidentFaces( shell.topology, innerVerts ); |
| 112 | } |
| 113 | |
| 114 | } //namespace MR |
no test coverage detected