{"action":"created","issue":{"url":"https://api.github.com/repos/mikedh/trimesh/issues/235","repository_url":"https://api.github.com/repos/mikedh/trimesh","labels_url":"https://api.github.com/repos/mikedh/trimesh/issues/235/labels{/name}","comments_url":"https://api.github.com/repos/mikedh/trimesh/issues/235/comments","events_url":"https://api.github.com/repos/mikedh/trimesh/issues/235/events","html_url":"https://github.com/mikedh/trimesh/issues/235","id":372222290,"node_id":"MDU6SXNzdWUzNzIyMjIyOTA=","number":235,"title":"Split mesh using a splitting plane","user":{"login":"themmes","id":12343995,"node_id":"MDQ6VXNlcjEyMzQzOTk1","avatar_url":"https://avatars1.githubusercontent.com/u/12343995?v=4","gravatar_id":"","url":"https://api.github.com/users/themmes","html_url":"https://github.com/themmes","followers_url":"https://api.github.com/users/themmes/followers","following_url":"https://api.github.com/users/themmes/following{/other_user}","gists_url":"https://api.github.com/users/themmes/gists{/gist_id}","starred_url":"https://api.github.com/users/themmes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/themmes/subscriptions","organizations_url":"https://api.github.com/users/themmes/orgs","repos_url":"https://api.github.com/users/themmes/repos","events_url":"https://api.github.com/users/themmes/events{/privacy}","received_events_url":"https://api.github.com/users/themmes/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2018-10-20T15:27:01Z","updated_at":"2018-11-28T21:16:47Z","closed_at":"2018-11-24T17:50:29Z","author_association":"NONE","body":"I want to split a mesh using a plane, similar to `cross_section` but returning both halves of the mesh as closed meshes instead of the polyline boundary of the intersection surface. I wrote the following code to achieve this:\r\n\r\n```\r\ndef split_mesh(mesh, plane_origin, plane_normal):\r\n    \"\"\"\r\n    Splits mesh by intersection with a plane, \r\n    returns closed mesh for positive and negative side of plane \r\n    \"\"\"\r\n    plane_normal = unit_vector(plane_normal)\r\n    \r\n    polyline, triangles_edge = trimesh.intersections.mesh_plane(bbox_mesh, \r\n                                                           plane_origin= plane_origin, \r\n                                                           plane_normal= plane_normal, \r\n                                                           return_faces=True)\r\n    \r\n    vertices_negative = []\r\n    vertices_positive = []\r\n    for vertex_id, vertex in enumerate(bbox_mesh.vertices):\r\n        # TODO: add threshold\r\n        signed_distance = np.dot(plane_normal, np.subtract(vertex, plane_origin))\r\n        if signed_distance < 0:\r\n            vertices_negative.append(vertex_id)\r\n        else:\r\n            vertices_positive.append(vertex_id)\r\n    \r\n    triangles_negative = []\r\n    triangles_positive = []\r\n    # For each triangle check how many points on either side of the plane\r\n    for triangle in bbox_mesh.faces:\r\n        triangle_negative_check = [vertex_id in vertices_negative for vertex_id in triangle]\r\n        # If all points on the negative side this triangle is not affected\r\n        if all(triangle_negative_check):\r\n            triangles_negative.append(np.array(bbox_mesh.vertices[triangle]))\r\n        elif any(triangle_negative_check):\r\n            # Get section line for this triangle on edge\r\n            section = polyline[np.all(np.isin(bbox_mesh.faces[triangles_edge], np.array(triangle)), axis=1)][0]\r\n            assert section.shape == (2,3)\r\n            # If two points on negative side\r\n            if sum(triangle_negative_check) == 2:\r\n                vertex_1, vertex_2 = bbox_mesh.vertices[triangle[triangle_negative_check]]\r\n                triangles_negative.extend(unordered_to_triangles([section[0], section[1], vertex_1, vertex_2]))\r\n                vertex_3 = bbox_mesh.vertices[triangle[np.logical_not(triangle_negative_check)]]\r\n                triangles_positive.append(np.vstack([section[0], section[1], vertex_3]))\r\n            elif sum(triangle_negative_check) == 1:\r\n                vertex_3 = bbox_mesh.vertices[triangle[triangle_negative_check]]\r\n                triangles_negative.append(np.vstack([section[0], section[1], vertex_3]))\r\n                vertex_1, vertex_2 = bbox_mesh.vertices[triangle[np.logical_not(triangle_negative_check)]]\r\n                triangles_positive.extend(unordered_to_triangles([section[0], section[1], vertex_1, vertex_2]))\r\n        # If all points on the positive side this triangle is not affected\r\n        else:\r\n            triangles_positive.append(np.array(bbox_mesh.vertices[triangle]))\r\n            \r\n    # Get triangulation of the split surface\r\n    vertices_splitsurface = []\r\n    for a, b in polyline:\r\n        for vertex in [a,b]:\r\n            if tuple(vertex) not in vertices_splitsurface:\r\n                vertices_splitsurface.append(tuple(vertex))\r\n\r\n    triangles_splitsurface = unordered_to_triangles(vertices_splitsurface)\r\n    \r\n    # Add triangles of split surface to both the positive and negative side\r\n    triangles_negative.extend(triangles_splitsurface)\r\n    triangles_positive.extend(triangles_splitsurface)\r\n    \r\n    # Create Trimesh from triangles for positive and negative\r\n    mesh_negative = trimesh.Trimesh(*to_face_indices(triangles_negative))\r\n    mesh_positive = trimesh.Trimesh(*to_face_indices(triangles_positive))\r\n    \r\n    return mesh_positive, mesh_negative\r\n```\r\n\r\nWould it be useful to improve and create a pull request, or is there a much more simple way to achieve this with trimesh?\r\n\r\nLooking forward to your reply!"},"comment":{"url":"https://api.github.com/repos/mikedh/trimesh/issues/comments/442607702","html_url":"https://github.com/mikedh/trimesh/issues/235#issuecomment-442607702","issue_url":"https://api.github.com/repos/mikedh/trimesh/issues/235","id":442607702,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0MjYwNzcwMg==","user":{"login":"HakuG","id":5514073,"node_id":"MDQ6VXNlcjU1MTQwNzM=","avatar_url":"https://avatars0.githubusercontent.com/u/5514073?v=4","gravatar_id":"","url":"https://api.github.com/users/HakuG","html_url":"https://github.com/HakuG","followers_url":"https://api.github.com/users/HakuG/followers","following_url":"https://api.github.com/users/HakuG/following{/other_user}","gists_url":"https://api.github.com/users/HakuG/gists{/gist_id}","starred_url":"https://api.github.com/users/HakuG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HakuG/subscriptions","organizations_url":"https://api.github.com/users/HakuG/orgs","repos_url":"https://api.github.com/users/HakuG/repos","events_url":"https://api.github.com/users/HakuG/events{/privacy}","received_events_url":"https://api.github.com/users/HakuG/received_events","type":"User","site_admin":false},"created_at":"2018-11-28T21:16:47Z","updated_at":"2018-11-28T21:16:47Z","author_association":"NONE","body":"I'm confused as to why it's not watertight? is there a way to make it watertight? I'm looking to create something like the \"split\" functionality in slic3r and cura. "}}
{"actor":{"display_login":"HakuG"}}