def main(): args = parse_args() mesh_1 = pymesh.load_mesh(args.input_mesh_1) mesh_2 = pymesh.load_mesh(args.input_mesh_2) assert (mesh_1.dim == 3) assert (mesh_2.dim == 3) bbox_min_1, bbox_max_1 = mesh_1.bbox bbox_min_2, bbox_max_2 = mesh_2.bbox bbox_min = np.minimum(bbox_min_1, bbox_min_2) bbox_max = np.maximum(bbox_max_1, bbox_max_2) #queries = grid_sample(bbox_min, bbox_max, args.num_samples); queries = random_sample(bbox_min, bbox_max, args.num_samples) winding_number_1 = pymesh.compute_winding_number( mesh_1, queries, engine=args.winding_number_engine) > 0.5 winding_number_2 = pymesh.compute_winding_number( mesh_2, queries, engine=args.winding_number_engine) > 0.5 diff = np.logical_xor(winding_number_1, winding_number_2) num_diff = np.count_nonzero(diff) print("Winding numbers of {} out of {} samples differ".format( num_diff, len(queries))) if args.output is not None: r = np.amax(bbox_max - bbox_min) * 0.01 box = pymesh.generate_box_mesh(np.ones(3) * -r, np.ones(3) * r) vertices = [] faces = [] for i in range(len(queries)): vertices.append(box.vertices + queries[i]) faces.append(box.faces + box.num_vertices * i) vertices = np.vstack(vertices) faces = np.vstack(faces) mesh = pymesh.form_mesh(vertices, faces) mesh.add_attribute("diff") mesh.set_attribute("diff", np.repeat(diff, box.num_faces)) pymesh.save_mesh(args.output, mesh, "diff") if args.export: info = load_info(args.input_mesh_2) info["diff"] = num_diff dump_info(args.input_mesh_2, info) if args.timing: pymesh.timethis.summarize()
def main(): args = parse_args(); mesh_1 = pymesh.load_mesh(args.input_mesh_1); mesh_2 = pymesh.load_mesh(args.input_mesh_2); assert(mesh_1.dim == 3); assert(mesh_2.dim == 3); bbox_min_1, bbox_max_1 = mesh_1.bbox; bbox_min_2, bbox_max_2 = mesh_2.bbox; bbox_min = np.minimum(bbox_min_1, bbox_min_2); bbox_max = np.maximum(bbox_max_1, bbox_max_2); #queries = grid_sample(bbox_min, bbox_max, args.num_samples); queries = random_sample(bbox_min, bbox_max, args.num_samples); winding_number_1 = pymesh.compute_winding_number(mesh_1, queries, engine=args.winding_number_engine) > 0.5; winding_number_2 = pymesh.compute_winding_number(mesh_2, queries, engine=args.winding_number_engine) > 0.5; diff = np.logical_xor(winding_number_1, winding_number_2); num_diff = np.count_nonzero(diff); print("Winding numbers of {} out of {} samples differ".format( num_diff, len(queries))); if args.output is not None: r = np.amax(bbox_max - bbox_min) * 0.01; box = pymesh.generate_box_mesh(np.ones(3) * -r, np.ones(3) * r); vertices = []; faces = []; for i in range(len(queries)): vertices.append(box.vertices + queries[i]); faces.append(box.faces + box.num_vertices * i); vertices = np.vstack(vertices); faces = np.vstack(faces); mesh = pymesh.form_mesh(vertices, faces); mesh.add_attribute("diff"); mesh.set_attribute("diff", np.repeat(diff, box.num_faces)); pymesh.save_mesh(args.output, mesh, "diff"); if args.export: info = load_info(args.input_mesh_2); info["diff"] = num_diff dump_info(args.input_mesh_2, info); if args.timing: pymesh.timethis.summarize();
def _conductord_winding_squared(self, pts, distance): """Compute and returned the signed distances between particles and mesh. The distances are computed via the functions of winding number and squared distance provided by PyMesh. PyMesh's distance_to_mesh function needs to compute BVH engine every time it is called. The PyMesh library has been modified so distance_to_mesh can take BVH engine as an argument to avoid this time consuming step called every time. Args: pts: numpy.ndarray of Nx3 storing the positions of particles for query. distance: A list to store the computed distance Return: distance: A list. Points outside conductor have positive values, and those inside have negative values. """ winding_number = pymesh.compute_winding_number(self.surface, pts) winding_number[np.abs(winding_number) < self._winding_fuzz] = 0.0 pts_inside = winding_number > 0. try: distance[:], _, _ = pymesh.distance_to_mesh(self.surface, pts, bvh=self._bvh) except TypeError: distance[:], _, _ = pymesh.distance_to_mesh(self.surface, pts) distance[:] = np.sqrt(distance) distance[pts_inside] *= -1
def test_cube(self): mesh = generate_box_mesh(np.array([0, 0, 0]), np.array([1, 1, 1])) queries = np.array([ [-1, 0, 0], [0.0, 0.0, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.5, 0.5], ]) winding_numbers = compute_winding_number(mesh, queries) self.assertEqual(len(queries), len(winding_numbers)) self.assert_array_almost_equal([0, 0.125, 0.25, 0.5, 1], winding_numbers)
def test_cube(self): mesh = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); queries = np.array([ [-1, 0, 0], [0.0, 0.0, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.5, 0.5], ]); winding_numbers = compute_winding_number(mesh, queries); self.assertEqual(len(queries), len(winding_numbers)); self.assertAlmostEqual(0.0, norm(winding_numbers - np.array([0, 0.125, 0.25, 0.5, 1])));
def test_fast_winding_number(self): mesh = generate_box_mesh( np.array([0, 0, 0]), np.array([1, 1, 1])); queries = np.array([ [-1, 0, 0], [0.0, 0.0, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.5, 0.5], ]); winding_numbers = compute_winding_number(mesh, queries, "fast_winding_number"); self.assertEqual(len(queries), len(winding_numbers)); self.assert_array_almost_equal( [0, 0.125, 0.25, 0.5, 1], winding_numbers, decimal=4);