def generate_mesh(surface, shader): # shape = (128, 128) shape = (256, 256) mesh = MicropolygonMesh(shape) shape = 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 = read_texture(texture_path) texture_start = generate_numpy_begin(texture) texture_width, texture_height = texture.shape mesh_width, mesh_height = mesh.buffer.shape c_generate_mesh = load_sampler_lib()['generate_mesh'] c_generate_mesh( generate_numpy_begin(mesh.buffer), mesh_width, mesh_height, texture_start, texture_width, texture_height ) return mesh
def downsample(self, sample_rate): downrate = int(math.ceil(self.sample_rate / sample_rate)) in_height, in_width = self.buffer.shape buffer = array_view(self.buffer) new_shape = [ int(math.ceil(o / downrate)) for o in buffer.shape ] new_shape[-1] = buffer.shape[-1] out_height, out_width = new_shape[:2] out = np.zeros(shape=new_shape, dtype=np.float32) downsample_tile( generate_numpy_begin(buffer), in_width, in_height, downrate, downrate, generate_numpy_begin(out), out_width, out_height ) return pixel_view(out)
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 main(): colors = { 'red' : '#f00', 'white' : '#fff', } float_colors = { } for key, value in colors.items(): color = parse_color(value) colors[key] = np.array([ color ], dtype=Pixel) float_colors[key] = np.array(tuple(c / 255. for c in color), dtype=FloatPixel) image = Tile((0, 0), (512, 512), sample_rate=4, dtype=FloatPixel) image.buffer[:,:] = float_colors['white'] tile_width, tile_height = image.buffer.shape mesh = MicropolygonMesh((1,1)) mesh_width, mesh_height = mesh.buffer.shape margin = 16 width = 128 right = image.shape[0] top = image.shape[1] buffer = np.array([ [ (right - margin - width, top - margin, 1, 1, 1.5, 0, 0, 1), (right - margin , top - margin, 1, 1, 0 , 0, 0, 1) ], [ (margin , margin, 1, 1, .5, 0, 0, 1), (margin + width, margin, 1, 1, 0 , 0, 0, 1) ], ], dtype=np.float32 ) mesh.buffer.view(dtype=(np.float32, 8))[:] = buffer fill_micropolygon_mesh( mesh_width, mesh_height, generate_numpy_begin(mesh.buffer), tile_width, tile_height, generate_numpy_begin(image.coordinate_image), generate_numpy_begin(image.buffer) ) buffer = array_view(image.downsample(1)) buffer = np.clip(buffer, 0., 1.) buffer = (255. * buffer).astype(dtype=np.uint8) save_array_as_image(pixel_view(buffer), 'render/002_micropolygon.tiff', 'RGBA')
def test_coordinate_image(tmpdir): try: lib = build_test_so(tmpdir) except Exception as e: import pdb pdb.set_trace() print_coordinates = lib['print_coordinates'] print_coordinates.restype = ctypes.c_char_p expected = [ [ 0, 3 ], [ 1, 3 ], [ 0, 2 ], [ 1, 2 ], [ 0, 1, ], [ 1, 1 ], [ 0, 0, ], [ 1, 0 ], ] tile = Tile((0, 0), (2, 4), 1) image = tile.coordinate_image width, height = image.shape size = width * height ptr = generate_numpy_begin(image) text = print_coordinates(ptr, size) coords = json.loads(text.decode('utf-8')) assert coords == expected
def bounds(self): if self.__bounds is not None: return self.__bounds buffer = self.__buffer mesh_rows, mesh_columns = buffer.shape bounds_rows, bounds_columns = mesh_rows - 1, mesh_columns - 1 self.__bounds = np.zeros((bounds_rows, bounds_columns), dtype=Position) outer_bounds = fill_bounds_buffer( mesh_rows, mesh_columns, generate_numpy_begin(buffer), generate_numpy_begin(self.__bounds), ) self.__outer_bounds = outer_bounds return self.__bounds
def render_mesh(mesh): cache = TileCache((16, 16), 4, FloatPixel) mesh_bounds = mesh.outer_bounds mesh_rows, mesh_columns = mesh.buffer.shape for tile in cache.get_tiles_for_bounds(mesh_bounds): 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) ) return cache
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 make_tile_cacher(shape, dtype, cache_size=int(4 * 2 ** 20)): from functools import reduce from operator import mul item_size = dtype.itemsize if not isinstance(item_size, int): item_size = dtype().itemsize items_per_tile = reduce(mul, shape) tile_size = item_size * items_per_tile tiles_per_cache = max(int(cache_size // tile_size), 1) while True: cache = np.zeros(tiles_per_cache * items_per_tile, dtype=dtype) begin = generate_numpy_begin(cache) for offset in range(tiles_per_cache): start, end = offset * items_per_tile, (offset + 1) * items_per_tile ptr = c_void_p(begin.value + start * item_size) out = cache[start:end].reshape(shape) yield (ptr, out)
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)