def generate_mesh_from_surface(surface, shape, u_range, v_range): u_start, u_end = u_range v_start, v_end = v_range u_steps = np.linspace(u_start, u_end, shape[0] + 1, endpoint=True, dtype=np.float32) v_steps = np.linspace(v_start, v_end, shape[1] + 1, endpoint=True, dtype=np.float32) points = [ [ surface(u, v) for u in u_steps ] for v in v_steps ] points = np.squeeze(np.array(points).view(Position)).T start_color = palette['blue'] end_color = palette['black'] colors = [ [ shader(u, v) for u in u_steps ] for v in v_steps ] colors = np.squeeze(np.array(colors).view(FloatPixel)).T mesh = MicropolygonMesh(shape) mesh.buffer[:,:]['position'] = points mesh.buffer[:,:]['color'] = colors # mesh.buffer[:,:]['color'] = palette['red'].view(FloatPixel) return mesh
def subdivide_mesh(mesh): buffer = mesh.buffer rows, columns = mesh.shape row_stride = rows // 4 column_stride = columns // 4 row_start = 0 while row_start < rows: row_end = row_start + row_stride column_start = 0 while column_start < columns: column_end = column_start + column_stride mesh_slice = buffer[row_start:row_end + 1, column_start:column_end + 1] r, c = mesh_slice.shape mesh = MicropolygonMesh((r - 1, c - 1)) mesh.buffer[:,:] = mesh_slice yield mesh column_start = column_end row_start = row_end
def generate_mesh_from_surface(surface, shader, shape, u_range, v_range): from handsome.MicropolygonMesh import MicropolygonMesh, Position from handsome.Pixel import FloatPixel u_start, u_end = u_range v_start, v_end = v_range u_steps = np.linspace(u_start, u_end, shape[0] + 1, endpoint=True, dtype=np.float32) v_steps = np.linspace(v_start, v_end, shape[1] + 1, endpoint=True, dtype=np.float32) points = [ [ surface(u, v) for u in u_steps ] for v in v_steps ] points = np.squeeze(np.array(points).view(Position)).T mesh = MicropolygonMesh(shape) mesh.buffer[:,:]['position'] = points if shader is not None: colors = [ [ shader(u, v) for u in u_steps ] for v in v_steps ] colors = np.squeeze(np.array(colors).view(FloatPixel)).T mesh.buffer[:,:]['color'] = colors return mesh
def slice_mesh(mesh, factor): from handsome.MicropolygonMesh import MicropolygonMesh buffer = mesh.buffer rows, columns = mesh.shape row_stride = rows // factor column_stride = columns // factor row_start = 0 while row_start < rows: row_end = row_start + row_stride column_start = 0 while column_start < columns: column_end = column_start + column_stride mesh_slice = buffer[row_start:row_end + 1, column_start:column_end + 1] r, c = mesh_slice.shape mesh = MicropolygonMesh((r - 1, c - 1)) mesh.buffer[:,:] = mesh_slice yield mesh column_start = column_end row_start = row_end
def generate_mesh(): mesh = MicropolygonMesh((1, 1)) half = 512 / 2 center = point(half, half, 1, 1) right = point((1/2) * half, (1/6) * half, 0., 0) up = point(0, 3/4 * half, 0, 0) points = [ [ point(5, 10, 1, 1), point(20, 20, 1, 1) ], [ point(0, 0, 1, 1), point(10, 0, 1, 1) ], ] points = [ [ point(80, 160, 1, 1), point(320, 320, 1, 1) ], [ point(0, 0, 1, 1), point(160, 0, 1, 1) ], ] points = [ [ center + up - right, center + (up + right) ], [ center - (up + right), center - up + 1.5 * right ], ] colors = [ [ point(1, 0, 0, 1), point(1, 0, 1, 1) ], [ point(0, 0, 0, 1), point(0, 0, 1, 1) ] ] mesh.buffer[:,:]['position'] = points mesh.buffer[:,:]['color'] = colors return mesh
def extract_meshes_from_micropolygon_mesh(mesh_data): shape = tuple(d - 1 for d in mesh_data.vertices.shape[:-1]) mesh = MicropolygonMesh(shape) mesh.buffer[:] = np.squeeze(mesh_data.vertices.view(Vertex)) apply_transform_to_mesh(current_xform, mesh) yield mesh
def star(center, radius): from math import cos, sin, pi start = pi / 2 delta = 2. * pi / 5 center = np.array(center + (1, 1), dtype=np.float32) outer = np.array([ ( center[0] + radius * cos(start + i * delta), center[1] + radius * sin(start + i * delta), 1, 1 ) for i in range(5) ], dtype=np.float32) p = outer[2,:2] - outer[0,:2] q = outer[1,:2] - outer[4,:2] b = outer[1,:2] - outer[0,:2] A = np.array([p, q]).T (u, v) = np.linalg.solve(A, b) inner = [ ] for i in range(5): start = outer[i,:] end = outer[(i + 2) % len(outer),:] inner.append((1 - u) * start + u * end) points = [ [ outer[1], inner[0], outer[0], inner[4], outer[4], ], [ inner[1], .5 * (inner[1] + center), center , .5 * (center + inner[3]), inner[3], ], [ outer[2], .5 * (outer[2] + inner[2]), inner[2], .5 * (inner[2] + outer[3]), outer[3], ], ] red, black, blue = [ palette[color].view(dtype=FloatPixel) for color in ('red', 'black', 'blue') ] colors = [ [ red , black, blue , red, black, ], [ blue, red, black, blue, red, ], [ black, blue, red, black, blue, ], ] rows = len(points) - 1 columns = len(points[0]) - 1 mesh = MicropolygonMesh((rows, columns)) mesh.buffer[:,:]['position'] = points mesh.buffer[:,:]['color'] = colors return mesh
def extract_meshes_from_micropolygon_mesh(self, mesh_data): from handsome.MicropolygonMesh import MicropolygonMesh, Vertex shape = tuple(d - 1 for d in mesh_data.vertices.shape[:-1]) mesh = MicropolygonMesh(shape) mesh.buffer[:] = np.squeeze(mesh_data.vertices.view(Vertex)) apply_transform_to_mesh(self.current_xform, mesh) texture = mesh_data.data.get('texture') if texture is not None: from handsome.capi import generate_numpy_begin import ctypes texture_module = load_texture_module() subdivide_mesh = texture_module.c_subdivide_mesh factor = 1000 old_cols, old_rows = mesh.shape new_cols, new_rows = factor * old_cols, factor * old_rows # new_cols, new_rows = 20 * old_cols, 20 * old_rows new_mesh = MicropolygonMesh((new_cols, new_rows)) # TODO: Make this type conversion automatic argtypes = subdivide_mesh.argtypes new_mesh_pointer = ctypes.cast(generate_numpy_begin(new_mesh.buffer), argtypes[0]) old_mesh_pointer = ctypes.cast(generate_numpy_begin(mesh.buffer), argtypes[3]) b = subdivide_mesh( new_mesh_pointer, new_rows, new_cols, old_mesh_pointer, old_rows, old_cols, ) mesh = new_mesh sample_texture_to_mesh = texture_module.c_sample_texture_to_mesh # TODO: Make this type conversion automatic argtypes = sample_texture_to_mesh.argtypes mesh_pointer = ctypes.cast(generate_numpy_begin(mesh.buffer), argtypes[0]) texture_pointer = ctypes.cast(generate_numpy_begin(texture.buffer), argtypes[3]) mesh_height, mesh_width = mesh.buffer.shape texture_height, texture_width = texture.shape texture_module.c_sample_texture_to_mesh( mesh_pointer, mesh_width, mesh_height, texture_pointer, texture_width, texture_height, ) # yield from slice_mesh(mesh, int(factor / 100)) yield mesh
def extract_meshes_from_convex_polygon(self, polygon): from handsome.MicropolygonMesh import MicropolygonMesh vertices = polygon.vertices center = vertices.sum(axis=0) / vertices.shape[0] vertices = list(vertices) assert len(vertices) >= 3 vertices.extend(vertices[:2]) for a, b, c in n_wise(vertices, 3): mesh = MicropolygonMesh((1, 1)) mesh.buffer[0,0] = b mesh.buffer[1,0] = (a + b) / 2 mesh.buffer[0,1] = (b + c) / 2 mesh.buffer[1,1] = center yield mesh
def test_bounds(): mesh = MicropolygonMesh((1, 2)) mesh.buffer[:,:]['position'] = np.array( [ [ (2, 2, 1, 1), (3, 2, 1, 1), (4, 2, 1, 1) ], [ (1, 1, 1, 1), (2, 1, 1, 1), (3, 1, 1, 1), ] ], dtype=Position ) assert mesh.bounds is not None print(mesh.bounds)
def generate_mesh(surface, shader): # shape = (128, 128) shape = (256, 256) mesh = MicropolygonMesh(shape) shape = mesh.buffer.shape u_steps = np.linspace(0, 1, shape[1], endpoint=True) v_steps = np.linspace(0, 1, shape[0], endpoint=True) points = [ [ surface(u, v) for u in u_steps ] for v in v_steps ] mesh.buffer[:,:]['position'] = points colors = [ [ shader(u, v) for u in u_steps ] for v in v_steps ] mesh.buffer[:,:]['color'] = colors return mesh sample_texture_to_mesh = load_sampler_lib()['sample_texture_to_mesh'] mesh_start = generate_numpy_begin(mesh.buffer) mesh_width, mesh_height = mesh.buffer.shape dir_path, base_path = os.path.split(__file__) texture_path = os.path.abspath(os.path.join(dir_path, 'render', 'texture.tiff')) # texture_path = os.path.abspath(os.path.join(dir_path, 'render', 'texture_black.tif')) texture = read_texture(texture_path) texture_start = generate_numpy_begin(texture) texture_width, texture_height = texture.shape sample_texture_to_mesh( mesh_start, mesh_width, mesh_height, texture_start, texture_width, texture_height, ) return mesh
def generate_test_mesh(): margin = 16 width = 128 right = 512 top = 512 buffer = np.array( [ [ (right - margin - width, top - margin, 1, 2 ), (right - margin , top - margin, 2, 1 ) ], [ (margin , margin, 2, 3, ), (margin + width, margin, 2, 2, ) ], ], dtype=Position ) mesh = MicropolygonMesh((1,1)) mesh.buffer[:,:]['position'] = buffer return mesh
def test_tile_render(): from handsome.MicropolygonMesh import MicropolygonMesh from handsome.Tile import Tile mesh = MicropolygonMesh((1, 1)) mesh.buffer[:,:]['position'] = [ [ (16, 16, 1, 1), (32, 16, 1, 1) ], [ (0, 0, 1, 1), (16, 0, 1, 1) ], ] red = color(1, 0, 0) green = color(0, 1, 0) orange = color(1, 1, 0) black = color(0, 0, 0, 1) zero = color(0, 0, 0, 0) mesh.buffer[:,:]['color'] = [ [ green, orange, ], [ black, red, ], ] mesh_rows, mesh_columns = mesh.buffer.shape tile = Tile((0,0), (32, 16), 1, FloatPixel) tile_rows, tile_columns = tile.buffer.shape fill_micropolygon_mesh( mesh_rows, mesh_columns, generate_numpy_begin(mesh.buffer), generate_numpy_begin(mesh.bounds), tile_rows, tile_columns, tile.bounds, generate_numpy_begin(tile.coordinate_image), generate_numpy_begin(tile.buffer), ) buffer = array_view(tile.buffer) rows, columns, channels = buffer.shape def image(x, y): return buffer[rows - 1 - y, x] low, high = 1/16, 15/16 expected = [ ((0, 0), color(0, 0, 0, 1)), ((15, 0), color(15/16, 0, 0, 1)), ((16, 0), color(0, 0, 0, 0)), ((31, 0), color(0, 0, 0, 0)), ((0, 8), color(0, 0, 0, 0)), ((8,8), color(0, 1/2, 0, 1)), ((16,8), color(1/2, 1/2, 0, 1)), ((31, 8), color(0, 0, 0, 0)), ((0, 15), color(0, 0, 0, 0)), ((15, 15), low * black + high * green), ((30, 15), low * (low * black + high * green) + high * (low * red + high * orange)), ] for index, c in expected: assert points_are_close(image(*index), c)