def test_spline_fitting(self): # Test a real spline interpolation xs = np.linspace(0.0, 2 * math.pi, 100) ys = np.array([math.sin(x) for x in xs]) points = [geom.Vertex((xs[i], ys[i], 0.0)) for i in range(len(xs))] cpoints_chunks = fit.fit_bezier_spline(points, mmath.interp_bezier_curve_2, 2) curves = [] cpoints = [] for chunk in cpoints_chunks: cpoints += chunk verts = map(lambda x: geom.Vertex(x), chunk) curves += [ geom.BaseCurve(list(verts), mmath.interp_bezier_curve_2) ] curve = geom.SuperCurve(curves) # Compute the current spline spline_ts = np.linspace(0.0, 1.0, 100) spline_points = [curve.t(t) for t in spline_ts] spline_xs = [p.x for p in spline_points] spline_ys = [p.y for p in spline_points] # Compute the control points cpointsx = [cp[0] for cp in cpoints] cpointsy = [cp[1] for cp in cpoints] # Actually plot the graph if DRAW_GRAPHS: plt.plot(spline_xs, spline_ys) # Approximate function plt.plot(xs, ys) # Original function plt.plot(cpointsx, cpointsy, "o") plt.show()
def test_vert(self): vert1 = geom.Vertex((2.0, 3.0, -3.0)) vert2 = geom.Vertex((2.0, 3.0, 3.0)) self.assertFalse(np.allclose(vert1, vert2)) self.assertTrue( np.allclose((vert1 + vert2), geom.Vertex((4.0, 6.0, 0.0)))) self.assertFalse(np.allclose(2 * vert1, vert1 * 3)) self.assertTrue(np.allclose(vert2, abs(vert1))) self.assertTrue(np.allclose(abs(vert1), abs(vert2)))
def are_edges_coplanar(c, e1, e2, e3, threshold=0.1): cross = lambda x, y: geom.Vertex(funchelps.cross(x, y)) gc = blender.convert_vert(c) ge1 = blender.convert_vert(e1) ge2 = blender.convert_vert(e2) ge3 = blender.convert_vert(e3) return abs(funchelps.dot(cross(ge1 - gc, ge2 - gc), ge3 - gc)) < threshold
def plot_beizer_spline_2d(points, function, n, figname, steps=100): points_xs = [p[0] for p in points] points_ys = [p[1] for p in points] cpoints_chunks = fit.fit_bezier_spline(points, function, n) curves = [] cpoints = [] for chunk in cpoints_chunks: cpoints += chunk verts = map(lambda x: geom.Vertex(x), chunk) curves += [geom.BaseCurve(list(verts), function)] curve = geom.SuperCurve(curves) spline_ts = np.linspace(0.0, 1.0, steps) spline_points = [curve.t(t) for t in spline_ts] curve_xs = [p.x for p in spline_points] curve_ys = [p.y for p in spline_points] # Compute the control points cpoints_xs = [cp[0] for cp in cpoints] cpoints_ys = [cp[1] for cp in cpoints] plt.plot(points_xs, points_ys, "o", color="blue", label="Input points") plt.plot(cpoints_xs, cpoints_ys, "o", color="red", label="Control points") plt.plot(curve_xs, curve_ys, color="green", label="Bezier spline") plt.grid() plt.legend() plt.savefig(OUT_GRAPH_DIR + figname) plt.show()
def test_curve2_fitting(self): A = geom.Vertex((0.0, 0.0, 0.0)) B = geom.Vertex((0.5, 2.0, 0.0)) C = geom.Vertex((1.0, 2.0, 1.0)) curve = geom.BaseCurve((A, B, C), mmath.interp_bezier_curve_2) points = list(geom.sample_curve_samples(curve, 100)) vals = fit.fit_bezier_curve(points, mmath.interp_bezier_curve_2) self.assertTrue(np.allclose(np.array(vals), np.array([A, B, C]))) if HUMAN_READABLE_TESTS: print(DELIMETER) print(vals) print([A, B, C]) print(DELIMETER)
def test_very_simple_spline_fitting(self): # Manually construct a sort of sine wave using bezier curves sin = lambda x: math.sin(x) xs = np.linspace(0.0, 2 * math.pi, 5) ys = np.array([math.sin(x) for x in xs]) cpoints = [geom.Vertex((xs[i], ys[i], 0.0)) for i in range(len(xs))] # We need to repeat the control points to have a spline cpoints_chunks = ut.splinify_list(cpoints, 3) curves = [ geom.BaseCurve(ps, mmath.interp_bezier_curve_2) for ps in cpoints_chunks ] curve = geom.SuperCurve(curves) # Plot the current spline spline_ts = np.linspace(0.0, 1.0, 100) spline_points = [curve.t(t) for t in spline_ts] spline_xs = [p.x for p in spline_points] spline_ys = [p.y for p in spline_points] # Print the graph if DRAW_GRAPHS: plt.plot(spline_xs, spline_ys) plt.show()
def parse_vertex(values): vertex_coord = geometry.VertexCoord(float(values[2]), float(values[3]), float(values[4])) normal = geometry.Normal(float(values[6]), float(values[7]), float(values[8])) tex_coord_1 = geometry.TexCoord(float(values[10]), float(values[11])) tex_coord_2 = geometry.TexCoord(float(values[13]), float(values[14])) return geometry.Vertex(vertex_coord, normal, tex_coord_1, tex_coord_2)
def test_vertex(self): v = geometry.Vertex('reflex', 65, 47) self.assertEqual('%s' % v, '#<Vertex kind=reflex y=65 x=47 idx=None>') self.assertFalse(v.is_convex) v.mark_terminal() self.assertEqual( '%s' % v, '#<Vertex kind=reflex y=65 x=47 idx=None terminal=true>') v = geometry.Vertex('convex', 82, 31) self.assertEqual('%s' % v, '#<Vertex kind=convex y=82 x=31 idx=None>') self.assertTrue(v.is_convex) v.mark_terminal() self.assertEqual( '%s' % v, '#<Vertex kind=convex y=82 x=31 idx=None terminal=true>') f = lambda: geometry.Vertex('other', 90, 54) self.assertRaises(errors.GeometryError, f)
def test_simple_net(self): v0 = geom.Vertex((0.0, 0.0, 0.0)) v1 = geom.Vertex((1.0, 0.0, 0.0)) v2 = geom.Vertex((1.0, 1.0, 0.0)) v3 = geom.Vertex((0.0, 1.0, 0.0)) disp = geom.Vertex((0.0, 0.0, 0.5)) m0 = (v0 + v1) / 2.0 + disp m1 = (v1 + v2) / 2.0 + disp m2 = (v2 + v3) / 2.0 + disp m3 = (v3 + v0) / 2.0 + disp c1 = geom.SuperCurve( [geom.BaseCurve((v0, m0, v1), mmath.interp_bezier_curve_2)]) c2 = geom.BaseCurve((v1, m1, v2), mmath.interp_bezier_curve_2) c3 = geom.BaseCurve((v2, m2, v3), mmath.interp_bezier_curve_2) c4 = geom.BaseCurve((v3, m3, v0), mmath.interp_bezier_curve_2) c1_points = list(geom.sample_curve_samples(c1, 10)) c2_points = list(geom.sample_curve_samples(c2, 10)) c3_points = list(geom.sample_curve_samples(c3, 10)) c4_points = list(geom.sample_curve_samples(c4, 10)) polygon = geom.PolygonsNetQuad((c1, c2, c3, c4)) points = list(geom.sample_patch_samples(polygon, 70)) if DRAW_GRAPHS: fig = plt.figure() ax = fig.gca(projection='3d') ax.plot([p.x for p in c1_points], [p.y for p in c1_points], [p.z for p in c1_points]) ax.plot([p.x for p in c2_points], [p.y for p in c2_points], [p.z for p in c2_points]) ax.plot([p.x for p in c3_points], [p.y for p in c3_points], [p.z for p in c3_points]) ax.plot([p.x for p in c4_points], [p.y for p in c4_points], [p.z for p in c4_points]) ax.plot([p.x for p in points], [p.y for p in points], [p.z for p in points], "o", label="Geometry points") plt.show()
def test_complex_net(self): coords1 = [(0.0, 0.0, 0.0), (0.5, 0.0, 1.0), (1.0, -0.2, 0.5), (1.5, 0.0, 0.0), (2.0, -0.1, 0.5)] cpoints1 = [geom.Vertex(coord) for coord in coords1] curve1 = geom.generate_spline(cpoints1, mmath.interp_bezier_curve_2) coords2 = [(2.0, -0.1, 0.5), (2.0, 1.0, 1.0), (2.1, 2.0, 0.0)] cpoints2 = [geom.Vertex(coord) for coord in coords2] curve2 = geom.generate_spline(cpoints2, mmath.interp_bezier_curve_2) coords3 = [(2.1, 2.0, 0.0), (1.5, 2.0, 0.0), (1.0, 2.1, 0.5), (0.5, 2.0, 1.0), (0.0, 2.0, 0.0)] cpoints3 = [geom.Vertex(coord) for coord in coords3] curve3 = geom.generate_spline(cpoints3, mmath.interp_bezier_curve_2) coords4 = [(0.0, 2.0, 0.0), (-0.5, 1.0, 0.0), (0.0, 0.0, 0.0)] cpoints4 = [geom.Vertex(coord) for coord in coords4] curve4 = geom.generate_spline(cpoints4, mmath.interp_bezier_curve_2) polygon = geom.PolygonsNetQuad((curve1, curve2, curve3, curve4)) points = list(geom.sample_patch_samples(polygon, 50)) c1_points = list(geom.sample_curve_samples(curve1, 20)) c2_points = list(geom.sample_curve_samples(curve2, 20)) c3_points = list(geom.sample_curve_samples(curve3, 20)) c4_points = list(geom.sample_curve_samples(curve4, 20)) if DRAW_GRAPHS: fig = plt.figure() ax = fig.gca(projection='3d') ax.plot([p.x for p in c1_points], [p.y for p in c1_points], [p.z for p in c1_points]) ax.plot([p.x for p in c2_points], [p.y for p in c2_points], [p.z for p in c2_points]) ax.plot([p.x for p in c3_points], [p.y for p in c3_points], [p.z for p in c3_points]) ax.plot([p.x for p in c4_points], [p.y for p in c4_points], [p.z for p in c4_points]) ax.plot([p.x for p in points], [p.y for p in points], [p.z for p in points], "o", label="Geometry points") plt.show()
def plot_bezier_spline_3d(points, function, n, figname, steps=100): cpoints_chunks = fit.fit_bezier_spline(points, mmath.bezier_curve_3, 5) curves = [] cpoints = [] for chunk in cpoints_chunks: cpoints += chunk verts = map(lambda x: geom.Vertex(x), chunk) curves += [geom.BaseCurve(list(verts), mmath.bezier_curve_3)] curve = geom.SuperCurve(curves) # Compute the current spline spline_ts = np.linspace(0.0, 1.0, steps) spline_points = [curve.t(t) for t in spline_ts] spline_xs = [p.x for p in spline_points] spline_ys = [p.y for p in spline_points] spline_zs = [p.z for p in spline_points] # Compute the current control points cpointsx = [cp[0] for cp in cpoints] cpointsy = [cp[1] for cp in cpoints] cpointsz = [cp[2] for cp in cpoints] # Draw the graph fig = plt.figure() ax = fig.gca(projection='3d') ax.plot([p[0] for p in points], [p[1] for p in points], [p[2] for p in points], "o", color="blue", label="Input points") ax.plot(spline_xs, spline_ys, spline_zs, color="green", label='Bezier spline') ax.plot(cpointsx, cpointsy, cpointsz, "o", color="red", label="Control points") plt.grid() plt.legend() plt.savefig(OUT_GRAPH_DIR + figname) plt.show()
def test_spline_fitting_3d(self): '''Fit a complex 3d curve with a bezier spline of degree three (5 curves).''' # Generate a cool 3d curve theta = np.linspace(-4 * np.pi, 4 * np.pi, 100) zs = np.linspace(-2, 2, 100) r = zs**2 + 1 xs = r * np.sin(theta) ys = r * np.cos(theta) # Fit the data points = list(zip(xs, ys, zs)) cpoints_chunks = fit.fit_bezier_spline(points, mmath.bezier_curve_3, 5) curves = [] cpoints = [] for chunk in cpoints_chunks: cpoints += chunk verts = map(lambda x: geom.Vertex(x), chunk) curves += [geom.BaseCurve(list(verts), mmath.bezier_curve_3)] curve = geom.SuperCurve(curves) # Compute the current spline spline_ts = np.linspace(0.0, 1.0, 100) spline_points = [curve.t(t) for t in spline_ts] spline_xs = [p.x for p in spline_points] spline_ys = [p.y for p in spline_points] spline_zs = [p.z for p in spline_points] # Compute the current control points cpointsx = [cp[0] for cp in cpoints] cpointsy = [cp[1] for cp in cpoints] cpointsz = [cp[2] for cp in cpoints] # Draw the graph if DRAW_GRAPHS: fig = plt.figure() ax = fig.gca(projection='3d') ax.plot(xs, ys, zs, label='parametric curve') ax.plot(spline_xs, spline_ys, spline_zs, label='Fitted spline') ax.plot(cpointsx, cpointsy, cpointsz, "o", label="Control points") plt.legend() plt.show()
def plot_bezier_curve(points, function, figname): points_xs = [p[0] for p in points] points_ys = [p[1] for p in points] cpoints = fit.fit_bezier_curve( list(zip(points_xs, points_ys, [0] * len(points_xs))), function) cpoints_xs = [p[0] for p in cpoints] cpoints_ys = [p[1] for p in cpoints] curve = geom.BaseCurve([geom.Vertex(p) for p in cpoints], function) curve_points = list(geom.sample_curve_samples(curve, 100)) curve_xs = [p.x for p in curve_points] curve_ys = [p.y for p in curve_points] plt.plot(points_xs, points_ys, "o", color="blue", label="Input points") plt.plot(cpoints_xs, cpoints_ys, "o", color="red", label="Control points") plt.plot(curve_xs, curve_ys, color="green", label="Bezier curve") plt.grid() plt.legend() plt.savefig(OUT_GRAPH_DIR + figname) plt.show()
def add(self, dir, point_y, point_x, next_dir): self.count += 1 if self.count >= 128: raise errors.AlgorithmError('loop detected at y=%s, x=%s' % (point_y, point_x)) # Adjust if dir == DIR_DOWN: point_x += 1 if dir == DIR_LEFT: point_y += 1 if next_dir == DIR_DOWN: point_x += 1 elif next_dir == DIR_LEFT: point_y += 1 # Edge edge = geometry.Edge(rotate_dir_cw(dir), self.curr_y, self.curr_x, point_y, point_x) self.edges.append(edge) # Vertex kind = 'convex' if next_dir == rotate_dir_cw(dir) else 'reflex' self.vertices.append( geometry.Vertex(kind, point_y, point_x, len(self.vertices))) # Border if point_y < self.min_y: self.min_y = point_y if point_y > self.max_y: self.max_y = point_y if point_x < self.min_x: self.min_x = point_x if point_x > self.max_x: self.max_x = point_x # Done? self.curr_y = point_y self.curr_x = point_x if point_y == self.start_y and point_x == self.start_x: first = self.vertices[-1] self.vertices = [first] + self.vertices[:-1] return True
def test_interpolating_curves(self): '''We should check that interpolating curves are really interpolating''' A = geom.Vertex((0.0, 0.0, 0.0)) B = geom.Vertex((0.0, 1.0, 0.0)) C = geom.Vertex((1.0, 1.0, 0.0)) c = mmath.interp_bezier_curve_2 self.assertTrue(np.allclose(c(0.0, A, B, C), A)) self.assertTrue(np.allclose(c(0.5, A, B, C), B)) self.assertTrue(np.allclose(c(1.0, A, B, C), C)) A = geom.Vertex((0.0, 0.0, 0.0)) B = geom.Vertex((0.5, 2.0, 0.0)) C = geom.Vertex((1.0, 2.0, 1.0)) D = geom.Vertex((0.0, 0.0, 1.0)) c = mmath.interp_bezier_curve_3 self.assertTrue(np.allclose(c(0.0, A, B, C, D), A)) self.assertTrue(np.allclose(c(1 / 3, A, B, C, D), B)) self.assertTrue(np.allclose(c(2 / 3, A, B, C, D), C)) self.assertTrue(np.allclose(c(1.0, A, B, C, D), D))
def convert_vert(bmv): '''Convert blender bmesh vertexes to our geometry.Vertex class.''' return geom.Vertex((bmv.co[0], bmv.co[1], bmv.co[2]))
def read(self, filename, model, params): # lists with parsed vertex attributes vertex_coords = [] tex_coords = [] normals = [] materials = {} # read file input_file = open(filename, 'r') flipX = 1.0 flipY = 1.0 flipZ = 1.0 if modelformat.get_param(params, 'flipX') != None: flipX = -1.0 if modelformat.get_param(params, 'flipY') != None: flipY = -1.0 if modelformat.get_param(params, 'flipZ') != None: flipZ = -1.0 flipOrder = (flipX * flipY * flipZ) < 0 # parse lines while True: line = input_file.readline() if len(line) == 0: break if line[len(line) - 1] == '\n': line = line[:len(line) - 1] parts = line.split(' ') if parts[0] == 'mtllib': name = parts[1] materials = read_mtl_file(name) elif parts[0] == 'v': vertex_coords.append( geometry.VertexCoord(flipX * float(parts[1]), flipY * float(parts[2]), flipZ * float(parts[3]))) elif parts[0] == 'vt': tex_coords.append( geometry.TexCoord(float(parts[1]), 1 - float(parts[2]))) elif parts[0] == 'vn': normals.append( geometry.Normal(flipX * float(parts[1]), flipY * float(parts[2]), flipZ * float(parts[3]))) elif parts[0] == 'usemtl': current_material = materials[parts[1]] elif parts[0] == 'f': polygon = [] # parse vertices for i in range(1, len(parts)): elements = parts[i].split('/') vert_coord = vertex_coords[int(elements[0]) - 1] normal = normals[int(elements[2]) - 1] if elements[1] == '': tex_coord = geometry.TexCoord(0.0, 0.0) else: tex_coord = tex_coords[int(elements[1]) - 1] polygon.append( geometry.Vertex(vert_coord, normal, tex_coord)) # triangulate polygon new_triangles = geometry.triangulate(polygon, flipOrder) # save vertices for triangle in new_triangles: triangle.material = current_material model.triangles.append(triangle) input_file.close() return True
def test_3d_quad_plot_almost_cube(self): verts = [ geom.Vertex((0.0, 0.0, 0.0)), geom.Vertex((1.0, 0.0, 0.0)), geom.Vertex((1.0, 1.0, 0.0)), geom.Vertex((0.0, 1.0, 0.0)) ] verts2 = [ geom.Vertex((0.0, 0.0, 1.0)), geom.Vertex((1.0, 0.0, 1.0)), geom.Vertex((1.0, 1.0, 1.0)), geom.Vertex((0.0, 1.0, 1.0)) ] verts3 = [ geom.Vertex((0.0, 0.0, 0.0)), geom.Vertex((0.0, 0.0, 1.0)), geom.Vertex((1.0, 0.0, 1.0)), geom.Vertex((1.0, 0.0, 0.0)) ] verts4 = [ geom.Vertex((0.0, 1.0, 0.0)), geom.Vertex((0.0, 1.0, 1.0)), geom.Vertex((1.0, 1.0, 1.0)), geom.Vertex((1.0, 1.0, 0.0)) ] if DRAW_GRAPHS: fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.add_collection3d( Poly3DCollection([verts, verts2, verts3, verts4])) plt.show()
def run(bm): '''Run the algorithm on the given bmesh (blender mesh), returns the patches (TODO in a data structure we still need to decide)''' verts_list = list(bm.verts) faces_list = list(bm.faces) verts_indexes = [v.index for v in verts_list] # Extract the skeleton mesh. patches, macro_edges, singular_verts = extract_base_mesh(bm) def calculate_patches(macro_edges, bm): boundaries = set(sum(macro_edges, ())) # Now we need to understand which vertex belong to which face. We use the connected components approach. patch_verts_attribution = partition_mesh_vertices( verts_indexes, boundaries, bm) # Now we need to understand which superedges belong to which face. patches = compute_patch_edges(patch_verts_attribution, macro_edges) # We now need to reorder the vertices of each face so that we can build a spline on them. for i, part in enumerate(patches): try: patches[i] = reorder_patch_edges(part) except: patches[i] = None # Filter empty and quadrangualte. patches = [p for p in patches if p] patches = quadrangulate_patches_keep_separate_edges( patches, verts_list) return patch_verts_attribution, patches MIN_VERTS = 20 threshold = PATCH_THRESHOLD * size_estimate(bm) print("Using Threshold:", threshold) def is_patch_big_enough(patch): '''Returns if all the edges of the patch are big enough for it to be splitted.''' return all(len(edge) >= 5 for edge in flat_patch_edges(patch)) def can_simplify(patch_verts): '''Returns wheter the patch contains enough point to be simplified.''' return patch_verts and len(patch_verts) > MIN_VERTS patch_verts_attribution, patches = calculate_patches(macro_edges, bm) skip_patches = [] # Now that we defined the patches we should iterate to improve the error. result = [] patch_improved = True #patch_improved = False while patch_improved: patch_improved = False print("Number of patches", len(patches)) for i, current_patch in enumerate(patches): current_attr = patch_verts_attribution[i] if all([ current_patch not in skip_patches, can_simplify(current_attr), is_patch_big_enough(current_patch), compute_patch_error(flat_patch_edges(current_patch), bm, current_attr) > threshold ]): #pr("ERROR", compute_patch_error(current_patch, bm, current_attr)) try: old_edges = sum(current_patch, []) new_edges = split_patch_4(current_patch, current_attr, bm) new_macro_edges = set(macro_edges) for edge in old_edges: if edge in new_macro_edges: new_macro_edges.remove(edge) if edge[::-1] in macro_edges: new_macro_edges.remove(edge[::-1]) for edge in new_edges: if edge[::-1] not in new_macro_edges: new_macro_edges.add(edge) patch_verts_attribution, patches = calculate_patches( new_macro_edges, bm) macro_edges = new_macro_edges patch_improved = True break except Exception as e: print("Patch discarded") skip_patches += [current_patch] result = patches #We need to fit the patch edges with lower degree curves #edges = set(sum(result, [])) edges = set(sum(sum(result, []), [])) edges = sorted(edges, key=len) edge_correspondence = {} old_verts = [geom.Vertex((v.co.x, v.co.y, v.co.z)) for v in verts_list] # TODO Disable this. Returns the patches without the edge fitting. #return old_verts, result, old_verts, result # Output values new_verts = [] new_edges = [] new_patches = [] SAMPLES = 20 spline_threshold = SPLINE_THRESHOLD * size_estimate(bm) THRESHOLD_DISTANCE = VERTEX_MERGE_THRESHOLD * size_estimate(bm) edge_conversion = {} def merge_all_edges(edges): if not edges: return [] result = edges[0] for e in edges[1:]: result += e[1:] return tuple(result) for i, edge in enumerate(edges): if edge_conversion.get(edge): pass else: cpoints = tuple([old_verts[i] for i in edge]) def squash_chunks(chunks): if len(chunks) == 1: return chunks[0] return chunks[0][:-1] + squash_chunks(chunks[1:]) new_cpoints = [] error = float("inf") n_splines = 1 try: while error > spline_threshold: cpoints_chunks = fit.fit_bezier_spline( cpoints, mmath.interp_bezier_curve_2, n_splines) verts_chunks = [[geom.Vertex(p) for p in chunk] for chunk in cpoints_chunks] verts_chunks[0][0] = cpoints[0] verts_chunks[-1][-1] = cpoints[-1] # Increase the precision at the next step n_splines += 1 # We need to use the original extremes control points to ensure continuity new_cpoints = squash_chunks(verts_chunks) # Check the error and fallback to default spline if issues new_curve = geom.generate_spline( new_cpoints, mmath.interp_bezier_curve_2) new_curve_points = list( geom.sample_curve_samples(new_curve, len(cpoints))) error = errors.simple_max_error(new_curve_points, cpoints) except: new_cpoints = cpoints print("Compressing edge: %s/%s. n.verts: %s -> %s" % (i + 1, len(edges), len(cpoints), len(new_cpoints))) new_verts += new_cpoints new_verts_indexes = tuple( [new_verts.index(v) for v in new_cpoints]) edge_conversion[edge] = new_verts_indexes edge_conversion[edge[::-1]] = new_verts_indexes[::-1] final_patches = [] # Convert the edges with the approximated ones. for patch in result: converted_edges = [[edge_conversion[edge] for edge in edges] for edges in patch] final_patches += [flat_patch_edges(converted_edges)] # TODO Remember to disable this. #return new_verts, final_patches, new_verts, final_patches def generate_convert(threshold_index, prev_index): def convert(index): if index < threshold_index: return index elif index == threshold_index: return prev_index else: return index - 1 return convert def update_edge(e, convert): return tuple([convert(i) for i in e]) def update_patch(p, convert): return [update_edge(e, convert) for e in p] def my_index(l, element): """Returns the element in the list, otherwise -1""" return l.index(element) if element in l else -1 def my_index_closest(l, element): temp = list(l) mod = lambda x: x[0] * x[0] + x[1] * x[1] + x[2] * x[2] closest = sorted(temp, key=lambda x: mod(x - element))[0] return l.index(closest) if mod(element - closest) < THRESHOLD_DISTANCE else -1 def recursive_max(l): if isinstance(l, (int, float)): return l return max((recursive_max(e) for e in l)) # Filter out vertices which are not unique. final_verts = [] for i, vert in enumerate(new_verts): index = my_index_closest(final_verts, vert) if final_verts else -1 if index == -1: final_verts += [vert] else: # The element is not in the list. This means that we need to decrement all the indexes and replace i with index. convert_func = generate_convert(len(final_verts), index) for i, p in enumerate(final_patches): final_patches[i] = update_patch(p, convert_func) input_size = compute_input_mesh_size(bm) output_size = compute_output_mesh_size(final_patches) print("Statistics ------------------------------------------") print("Input Vertices: ", len(verts_list)) print("Input Faces: ", len(faces_list)) print("Output Vertices: ", len(final_verts)) print("Output Faces: ", len(final_patches)) print("Input Size: ", input_size) print("Output Size: ", output_size) print("Compression Ratio:", (input_size / output_size)) print("-----------------------------------------------------") old_pathces = [flat_patch_edges(p) for p in result] return old_verts, old_pathces, final_verts, final_patches
import Smeshalist import geometry import random Smeshalist.getInstance(8383, False) counter = 0 while counter < 1000: counter = counter + 1 point1 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0)) vertex = geometry.Vertex(point1) vertex.groupId = 1 Smeshalist.addVertex(vertex) counter = 0 while counter < 1000: counter = counter + 1 point1 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0)) point2 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0)) edge = geometry.Edge(point1, point2) edge.groupId = 1 Smeshalist.addEdge(edge) counter = 0 while counter < 1000: counter = counter + 1 point1 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0)) point2 = geometry.Point3D(random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0), random.uniform(-10.0, 10.0))
def test_complex_error(self): verts1 = [geom.Vertex((0.0, 0.0, 1.0)), geom.Vertex((0.0, 0.0, 0.0))] refs = [geom.Vertex((0.0, 1.0, 1.0)), geom.Vertex((0.0, 1.0, 0.0))] self.assertEqual(errors.verts_sets_sq_error(verts1, refs), 2)