def convert_png_to_jpg_rgb(self, tex_path): tex_basename = os.path.splitext(tex_path)[0] img = PNMImage() self.load_img_with_retry(img, tex_path) jpg_path = tex_basename + '.jpg' x_size = img.get_x_size() y_size = img.get_y_size() output_img = PNMImage(x_size, y_size, 3) output_img.copy_sub_image(img, 0, 0, 0, 0, x_size, y_size) jpg_path = tex_basename + '.jpg' print(f'Writing JPG {jpg_path}...') output_img.write(Filename.from_os_specific(jpg_path)) if img.num_channels == 4: alpha_image = PNMImage(x_size, y_size, 1) alpha_image.set_type(RGB_TYPE) # Copy alpha channel from source image for i in range(x_size): for j in range(y_size): alpha_image.set_gray(i, j, img.get_alpha(i, j)) rgb_path = tex_basename + '_a.rgb' print(f'Writing RGB {rgb_path}...') alpha_image.write(Filename.from_os_specific(rgb_path))
class AtlasEntry: def __init__(self, verbose_name, source_path): self.name = verbose_name self.path = source_path self.tex = PNMImage(source_path) self.w = self.tex.get_x_size() self.h = self.tex.get_y_size() self.area = self.w * self.h self.assigned_pos = None def __repr__(self): return self.name
def loadTerrain(name, widthScale = 0.5, heightScale = 10.0): """load terrain stuff""" global app, terrain, terrainRootNetPos steerMgr = OSSteerManager.get_global_ptr() terrain = GeoMipTerrain("terrain") heightField = PNMImage(Filename(dataDir + "/heightfield.png")) terrain.set_heightfield(heightField) # sizing environmentWidthX = (heightField.get_x_size() - 1) * widthScale environmentWidthY = (heightField.get_y_size() - 1) * widthScale environmentWidth = (environmentWidthX + environmentWidthY) / 2.0 terrain.get_root().set_sx(widthScale) terrain.get_root().set_sy(widthScale) terrain.get_root().set_sz(heightScale) # set other terrain's properties blockSize, minimumLevel = (64, 0) nearPercent, farPercent = (0.1, 0.7) terrainLODmin = min(minimumLevel, terrain.get_max_level()) flattenMode = GeoMipTerrain.AFM_off terrain.set_block_size(blockSize) terrain.set_near(nearPercent * environmentWidth) terrain.set_far(farPercent * environmentWidth) terrain.set_min_level(terrainLODmin) terrain.set_auto_flatten(flattenMode) # terrain texturing textureStage0 = TextureStage("TextureStage0") textureImage = TexturePool.load_texture(Filename("terrain.png")) terrain.get_root().set_tex_scale(textureStage0, 1.0, 1.0) terrain.get_root().set_texture(textureStage0, textureImage, 1) # reparent this Terrain node path to the object node path terrain.get_root().reparent_to(steerMgr.get_reference_node_path()) terrain.get_root().set_collide_mask(mask) terrain.get_root().set_name(name) # brute force generation bruteForce = True terrain.set_bruteforce(bruteForce) # Generate the terrain terrain.generate() # check if terrain needs update or not if not bruteForce: # save the net pos of terrain root terrainRootNetPos = terrain.get_root().get_net_transform().get_pos() # Add a task to keep updating the terrain app.taskMgr.add(terrainUpdate, "terrainUpdate", appendTask=True) # return terrain.get_root()
def load_3d_texture(cls, fname, tile_size_x, tile_size_y=None, num_tiles=None): """ Loads a texture from the given filename and dimensions. If only one dimensions is specified, the other dimensions are assumed to be equal. This internally loads the texture into ram, splits it into smaller sub-images, and then calls the load_3d_texture from the Panda loader """ # Generate a unique name to prevent caching tempfile_name = "$$SliceLoaderTemp-" + str(time.time()) + "/" # For quaddratic textures tile_size_y = tile_size_x if tile_size_y is None else tile_size_y num_tiles = tile_size_x if num_tiles is None else num_tiles # Load sliced image from disk source = PNMImage(fname) width = source.get_x_size() # Find slice properties num_cols = width // tile_size_x temp = PNMImage( tile_size_x, tile_size_y, source.get_num_channels(), source.get_maxval()) # Construct a ramdisk to write the files to vfs = VirtualFileSystem.get_global_ptr() ramdisk = VirtualFileMountRamdisk() vfs.mount(ramdisk, tempfile_name, 0) # Extract all slices and write them to the virtual disk for z_slice in range(num_tiles): slice_x = (z_slice % num_cols) * tile_size_x slice_y = (z_slice // num_cols) * tile_size_y temp.copy_sub_image(source, 0, 0, slice_x, slice_y, tile_size_x, tile_size_y) temp.write(tempfile_name + str(z_slice) + ".png") # Load the de-sliced texture from the ramdisk texture_handle = Globals.loader.load3DTexture(tempfile_name + "/#.png") # This should never trigger, but can't hurt to have assert texture_handle.get_x_size() == tile_size_x assert texture_handle.get_y_size() == tile_size_y assert texture_handle.get_z_size() == num_tiles # Finally unmount the ramdisk vfs.unmount(ramdisk) return texture_handle
def load_sliced_3d_texture(cls, fname, tile_size_x, tile_size_y=None, num_tiles=None): """ Loads a texture from the given filename and dimensions. If only one dimensions is specified, the other dimensions are assumed to be equal. This internally loads the texture into ram, splits it into smaller sub-images, and then calls the load_3d_texture from the Panda loader """ tempfile_name = "/$$slice_loader_temp-" + str(time.time()) + "/" tile_size_y = tile_size_x if tile_size_y is None else tile_size_y num_tiles = tile_size_x if num_tiles is None else num_tiles # Load sliced image from disk tex_handle = cls.load_texture(fname) source = PNMImage() tex_handle.store(source) width = source.get_x_size() # Find slice properties num_cols = width // tile_size_x temp_img = PNMImage(tile_size_x, tile_size_y, source.get_num_channels(), source.get_maxval()) # Construct a ramdisk to write the files to vfs = VirtualFileSystem.get_global_ptr() ramdisk = VirtualFileMountRamdisk() vfs.mount(ramdisk, tempfile_name, 0) # Extract all slices and write them to the virtual disk for z_slice in range(num_tiles): slice_x = (z_slice % num_cols) * tile_size_x slice_y = (z_slice // num_cols) * tile_size_y temp_img.copy_sub_image(source, 0, 0, slice_x, slice_y, tile_size_x, tile_size_y) temp_img.write(tempfile_name + str(z_slice) + ".png") # Load the de-sliced texture from the ramdisk texture_handle = cls.load_3d_texture(tempfile_name + "/#.png") vfs.unmount(ramdisk) return texture_handle
def load_sliced_3d_texture(cls, fname, tile_size_x, tile_size_y=None, num_tiles=None): """ Loads a texture from the given filename and dimensions. If only one dimensions is specified, the other dimensions are assumed to be equal. This internally loads the texture into ram, splits it into smaller sub-images, and then calls the load_3d_texture from the Panda loader """ tempfile_name = "/$$slice_loader_temp-" + str(time.time()) + "/" tile_size_y = tile_size_x if tile_size_y is None else tile_size_y num_tiles = tile_size_x if num_tiles is None else num_tiles # Load sliced image from disk source = PNMImage(fname) width = source.get_x_size() # Find slice properties num_cols = width // tile_size_x temp_img = PNMImage( tile_size_x, tile_size_y, source.get_num_channels(), source.get_maxval()) # Construct a ramdisk to write the files to vfs = VirtualFileSystem.get_global_ptr() ramdisk = VirtualFileMountRamdisk() vfs.mount(ramdisk, tempfile_name, 0) # Extract all slices and write them to the virtual disk for z_slice in range(num_tiles): slice_x = (z_slice % num_cols) * tile_size_x slice_y = (z_slice // num_cols) * tile_size_y temp_img.copy_sub_image(source, 0, 0, slice_x, slice_y, tile_size_x, tile_size_y) temp_img.write(tempfile_name + str(z_slice) + ".png") # Load the de-sliced texture from the ramdisk texture_handle = cls.load_3d_texture(tempfile_name + "/#.png") vfs.unmount(ramdisk) return texture_handle
def convert_texture(self, texture, model_path=None): if not self.model_path: self.print_exc('ERROR: No model path specified in ImageConverter.') return tex_path = texture[0] tex_basename = os.path.splitext(os.path.basename(tex_path))[0] if not os.path.isabs(tex_path): if '../' in tex_path and model_path: # This texture path is using relative paths. # We assume that the working directory is the model's directory tex_path = os.path.join(os.path.dirname(model_path), tex_path) else: tex_path = os.path.join(self.model_path, tex_path) tex_path = tex_path.replace('\\', os.sep).replace('/', os.sep) if not os.path.exists(tex_path): self.print_exc('ERROR: Could not convert {}: Missing RGB texture!'.format(tex_path)) return png_tex_path = os.path.join(os.path.dirname(tex_path), tex_basename + '.png') png_tex_path = png_tex_path.replace('\\', os.sep).replace('/', os.sep) print('Converting to PNG...', png_tex_path) if len(texture) == 1: # Only one texture, we can save this immediately if tex_path.lower().endswith('.rgb'): output_img = PNMImage() output_img.read(Filename.from_os_specific(tex_path)) if output_img.num_channels in (1, 2) and 'golf_ball' not in tex_path and 'roll-o-dex' not in tex_path: # HACK: Toontown output_img.set_color_type(4) for i in range(output_img.get_x_size()): for j in range(output_img.get_y_size()): output_img.set_alpha(i, j, output_img.get_gray(i, j)) else: output_img = self.read_texture(tex_path, alpha=False) elif len(texture) == 2: img = self.read_texture(tex_path, alpha=True) # Two textures: the second one should be a RGB file alpha_path = texture[1] if not os.path.isabs(alpha_path): if '../' in alpha_path and model_path: # This texture path is using relative paths. # We assume that the working directory is the model's directory alpha_path = os.path.join(os.path.dirname(model_path), alpha_path) else: alpha_path = os.path.join(self.model_path, alpha_path) alpha_path = alpha_path.replace('\\', os.sep).replace('/', os.sep) if not os.path.exists(alpha_path): self.print_exc('ERROR: Could not convert {} with alpha {}: Missing alpha texture!'.format(tex_path, alpha_path)) return alpha_img = PNMImage() alpha_img.read(Filename.from_os_specific(alpha_path)) alpha_img = self.resize_image(alpha_img, img.get_x_size(), img.get_y_size()) output_img = PNMImage(img.get_x_size(), img.get_y_size(), 4) output_img.alpha_fill(1) output_img.copy_sub_image(img, 0, 0, 0, 0, img.get_x_size(), img.get_y_size()) for i in range(img.get_x_size()): for j in range(img.get_y_size()): output_img.set_alpha(i, j, alpha_img.get_gray(i, j)) output_img.write(Filename.from_os_specific(png_tex_path))
# run mitsuba print("Running mitsuba for ior =", ior, "( index =", pass_index,")") with open("res/scene" + config["template_suffix"] + ".templ.xml", "r") as handle: content = handle.read() content = content.replace("%IOR%", str(ior)) content = content.replace("%SAMPLES%", str(config["samples"])) with open("res/scene.xml", "w") as handle: handle.write(content) os.system("run_mitsuba.bat") img = PNMImage("scene.png") source_w = img.get_x_size() print("Converting ..") indices = [] nxv_values = [] # Generate nonlinear NxV sequence for i in xrange(source_w): v = 1 - i / float(source_w) NxV = math.sqrt(1 - v*v) nxv_values.append(NxV) # Generate lerp indices and weights for x in xrange(dest_size): NxV = (x) / float(dest_size)
""" from __future__ import print_function from panda3d.core import PNMImage source_a = "scene.png" source_b = "scene-rp.png" write_diff_img = False img_a = PNMImage(source_a) img_b = PNMImage(source_b) w, h = img_a.get_x_size(), img_a.get_y_size() img_dest = PNMImage(w, h, 3) error_scale = 10.0 total_diff = 0.0 for x in xrange(w): for y in xrange(h): val_a = img_a.get_xel(x, y) val_b = img_b.get_xel(x, y) abs_diff = (val_a - val_b) * error_scale r, g, b = abs(abs_diff.x), abs(abs_diff.y), abs(abs_diff.z) img_dest.set_xel(x, y, r, g, b)
from panda3d.core import Filename, PNMImage jpgFile = raw_input("JPEG file: ") aFile = raw_input("Alpha file: ") fn = Filename.fromOsSpecific(jpgFile) fnrgb = Filename.fromOsSpecific(aFile) fnout = Filename(fn.getFullpathWoExtension() + ".png") image = PNMImage(fn) imagergb = PNMImage(fnrgb) image.set_num_channels(4) for x in xrange(image.get_x_size()): for y in xrange(image.get_y_size()): image.set_channel(x, y, 3, imagergb.getChannel(x, y, 0)) image.write(fnout)
# run mitsuba print("Running mitsuba for ior =", ior, "( index =", pass_index, ")") with open("res/scene" + config["template_suffix"] + ".templ.xml", "r") as handle: content = handle.read() content = content.replace("%IOR%", str(ior)) content = content.replace("%SAMPLES%", str(config["samples"])) with open("res/scene.xml", "w") as handle: handle.write(content) os.system("run_mitsuba.bat") img = PNMImage("scene.png") source_w = img.get_x_size() print("Converting ..") indices = [] nxv_values = [] # Generate nonlinear NxV sequence for i in xrange(source_w): v = 1 - i / float(source_w) NxV = math.sqrt(1 - v * v) nxv_values.append(NxV) # Generate lerp indices and weights for x in xrange(dest_size): NxV = (x) / float(dest_size)