| 114 | } |
| 115 | |
| 116 | bool reducePathViaVertex( const Mesh & mesh, const MeshTriPoint & s, VertId v, const MeshTriPoint & e, |
| 117 | SurfacePath & outPath, std::vector<Vector2f> & tmp, SurfacePath& cachePath ) |
| 118 | { |
| 119 | MeshTriPoint stp( s ); |
| 120 | MeshTriPoint etp( e ); |
| 121 | if ( fromSameTriangle( mesh.topology, stp, etp ) ) |
| 122 | { |
| 123 | // line segment from s to e is the shortest path |
| 124 | return true; |
| 125 | } |
| 126 | |
| 127 | const auto vp = mesh.points[ v ]; |
| 128 | const auto sp = mesh.triPoint( s ) - vp; |
| 129 | const auto ep = mesh.triPoint( e ) - vp; |
| 130 | const auto dist0 = sp.length() + ep.length(); |
| 131 | const auto sz0 = outPath.size(); |
| 132 | float distOneSide = FLT_MAX; |
| 133 | |
| 134 | EdgeId e0 = lastCommonEdge( mesh.topology, v, s ); |
| 135 | assert( e0 ); |
| 136 | EdgeId e1 = firstCommonEdge( mesh.topology, v, e ); |
| 137 | assert( e1 ); |
| 138 | if ( e0 && e1 ) |
| 139 | { |
| 140 | tmp.clear(); |
| 141 | cachePath.clear(); |
| 142 | auto dp = mesh.destPnt( e0 ) - vp; |
| 143 | tmp.push_back( Vector2f( 0, dp.length() ) ); |
| 144 | const Vector2f s2 = unfoldOnPlane( dp, sp, tmp.back(), false ); |
| 145 | if ( e0 != e1 ) |
| 146 | { |
| 147 | for ( EdgeId ei = mesh.topology.next( e0 ); ; ei = mesh.topology.next( ei ) ) |
| 148 | { |
| 149 | auto np = mesh.destPnt( ei ) - vp; |
| 150 | tmp.push_back( unfoldOnPlane( dp, np, tmp.back(), true ) ); |
| 151 | dp = np; |
| 152 | if ( ei == e1 ) |
| 153 | break; |
| 154 | } |
| 155 | } |
| 156 | const Vector2f e2 = unfoldOnPlane( dp, ep, tmp.back(), true ); |
| 157 | if ( tmp.back() != Vector2f() ) |
| 158 | { |
| 159 | // no zero-length edges were encountered |
| 160 | int i = 0; |
| 161 | distOneSide = 0; |
| 162 | for ( EdgeId ei = e0; i < tmp.size(); ei = mesh.topology.next( ei ), ++i ) |
| 163 | { |
| 164 | if ( !mesh.topology.left( ei ) ) |
| 165 | { |
| 166 | // do not allow pass via hole space |
| 167 | distOneSide = FLT_MAX; |
| 168 | break; |
| 169 | } |
| 170 | auto & d = tmp[i]; |
| 171 | const auto x = std::clamp( lineIsect( d, s2, e2 ), 0.0f, 1.0f ); |
| 172 | if ( x <= TriPointf::eps ) |
| 173 | { |
no test coverage detected