(wires, logger, remove_holes, dist)
| 205 | return mesh; |
| 206 | |
| 207 | def bevel(wires, logger, remove_holes, dist): |
| 208 | bbox_min, bbox_max = wires.bbox; |
| 209 | |
| 210 | #wires = uniform_sampling(wires); |
| 211 | mesh = constrained_triangulate(wires, logger, remove_holes); |
| 212 | |
| 213 | cell_ids = mesh.get_attribute("cell").ravel().astype(int); |
| 214 | num_cells = np.amax(cell_ids) + 1; |
| 215 | |
| 216 | comps = []; |
| 217 | for i in range(num_cells): |
| 218 | to_keep = np.arange(mesh.num_faces, dtype=int)[cell_ids == i]; |
| 219 | if not np.any(to_keep): |
| 220 | continue; |
| 221 | |
| 222 | cut_mesh = pymesh.submesh(mesh, to_keep, 0); |
| 223 | bd_edges = cut_mesh.boundary_edges; |
| 224 | vertices, edges, __ = pymesh.remove_isolated_vertices_raw( |
| 225 | cut_mesh.vertices, bd_edges); |
| 226 | bd_wires = pymesh.wires.WireNetwork.create_from_data(vertices, edges); |
| 227 | |
| 228 | offset_dir = np.zeros((bd_wires.num_vertices, 2)); |
| 229 | for ei in edges: |
| 230 | v0 = ei[0]; |
| 231 | v1 = ei[1]; |
| 232 | adj_vts = bd_wires.get_vertex_neighbors(v0); |
| 233 | if len(adj_vts) == 2: |
| 234 | if adj_vts[0] == v1: |
| 235 | vp = adj_vts[1]; |
| 236 | else: |
| 237 | vp = adj_vts[0]; |
| 238 | e0 = vertices[v1] - vertices[v0]; |
| 239 | e1 = vertices[vp] - vertices[v0]; |
| 240 | e0 /= norm(e0); |
| 241 | e1 /= norm(e1); |
| 242 | theta = math.atan2(e0[0]*e1[1] - e0[1]*e1[0], e0.dot(e1)); |
| 243 | |
| 244 | if abs(theta) > 0.99 * math.pi: |
| 245 | offset = np.array([-e0[1], e0[0]]); |
| 246 | scale = 1.0; |
| 247 | else: |
| 248 | if theta > 0: |
| 249 | offset = e0 + e1; |
| 250 | scale = math.sin(theta/2); |
| 251 | else: |
| 252 | offset = -e0 - e1 |
| 253 | scale = math.cos(math.pi/2 + theta/2); |
| 254 | offset /= norm(offset); |
| 255 | offset_dir[v0] = offset * dist / scale; |
| 256 | |
| 257 | offset_vertices = vertices + offset_dir; |
| 258 | vertices = np.vstack((vertices, offset_vertices)); |
| 259 | edges = np.vstack((edges, edges + bd_wires.num_vertices)); |
| 260 | |
| 261 | vertices, edges, __ = pymesh.remove_duplicated_vertices_raw( |
| 262 | vertices, edges, dist/2); |
| 263 | |
| 264 | comp_wires = pymesh.wires.WireNetwork.create_from_data(vertices, edges); |
no test coverage detected