Пример #1
0
    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))
Пример #2
0
def filter_cubemap(orig_pth):

    if not os.path.isdir("Filtered/"):
        os.makedirs("Filtered/")

    # Copy original cubemap
    for i in range(6):
       shutil.copyfile(orig_pth.replace("#", str(i)), "Filtered/0-" + str(i) + ".png")

    mip = 0
    while True:
        print("Filtering mipmap", mip)
        mip += 1
        pth = "Filtered/" + str(mip - 1) + "-#.png"
        dst_pth = "Filtered/" + str(mip) + "-#.png"
        first_img = load_nth_face(pth, 0)
        size = first_img.get_x_size() // 2
        if size < 1:
            break
        blur_size = size * 0.002
        blur_size += mip * 0.85
        blur_size = int(blur_size)
        effective_size = size + 2 * blur_size
        faces = [load_nth_face(pth, i) for i in range(6)]

        cubemap = loader.loadCubeMap(pth)
        node = NodePath("")
        node.set_shader(compute_shader)
        node.set_shader_input("SourceCubemap", cubemap)
        node.set_shader_input("size", size)
        node.set_shader_input("blurSize", blur_size)
        node.set_shader_input("effectiveSize", effective_size)

        final_img = PNMImage(size, size, 3)

        for i in range(6):
            face_dest = dst_pth.replace("#", str(i))
            dst = Texture("Face-" + str(i))
            dst.setup_2d_texture(effective_size, effective_size,
                                 Texture.T_float, Texture.F_rgba16)

            # Execute compute shader
            node.set_shader_input("faceIndex", i)
            node.set_shader_input("DestTex", dst)
            attr = node.get_attrib(ShaderAttrib)
            base.graphicsEngine.dispatch_compute(( (effective_size+15) // 16,
                                                   (effective_size+15) // 16, 1),
                                                 attr, base.win.get_gsg())

            base.graphicsEngine.extract_texture_data(dst, base.win.get_gsg())
            img = PNMImage(effective_size, effective_size, 3)
            dst.store(img)
            img.gaussian_filter(blur_size)
            final_img.copy_sub_image(img, 0, 0, blur_size, blur_size, size, size)
            final_img.write(face_dest)
Пример #3
0
def generate_atlas(files, dest_dat, dest_png):
    entries = []

    virtual_atlas_size = 32
    all_entries_matched = False

    print("Loading", len(files), "entries ..")
    for verbose_name, source in files:
        entries.append(AtlasEntry(verbose_name, source))

    entries = sorted(entries, key=lambda a: -a.area)

    while not all_entries_matched:
        print("Trying to pack into a", virtual_atlas_size, "x", virtual_atlas_size, "atlas ..")

        packer = LUIAtlasPacker(virtual_atlas_size)
        all_entries_matched = True

        for entry in entries:
            print("Finding position for", entry.w, entry.h)
            uv = packer.find_position(entry.w, entry.h)

            if uv.get_x() < 0:
                # print "  Not all images matched, trying next power of 2"
                all_entries_matched = False
                virtual_atlas_size *= 2
                break
            entry.assigned_pos = uv

    print("Matched entries, writing atlas ..")

    atlas_description_content = ""
    dest = PNMImage(virtual_atlas_size, virtual_atlas_size, 4)

    for entry in entries:

        if not entry.tex.has_alpha():
            entry.tex.add_alpha()
            entry.tex.alpha_fill(1.0)

        dest.copy_sub_image(
            entry.tex, int(entry.assigned_pos.get_x()), int(entry.assigned_pos.get_y()))

        atlas_description_content += "{0} {1} {2} {3} {4}\n".format(
            entry.name.replace(" ", "_"),
            int(entry.assigned_pos.get_x()),
            int(entry.assigned_pos.get_y()),
            entry.w, entry.h)
        print("Writing", entry.name,"with dimensions", entry.w, entry.h)

    dest.write(dest_png)

    with open(dest_dat, "w") as handle:
        handle.write(atlas_description_content)
Пример #4
0
    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
Пример #6
0
    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
Пример #7
0
    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))
Пример #8
0
            content = content.replace("%ENDIF_" + def_name + "%", "")
        else:
            content = content.replace("%IF_" + def_name + "%", "<!--")
            content = content.replace("%ENDIF_" + def_name + "%", "-->")

    content = content.replace("%ALPHA%", str(material["roughness"] * material["roughness"]))
    content = content.replace("%IOR%", str(material.get("ior", 1.51)))
    content = content.replace("%BASECOLOR%", str(material["basecolor"]).strip("()"))
    content = content.replace("%MATERIAL_SRC%", material.get("material_src", "").strip("()"))


    with open("res/scene.xml", "w") as handle:
        handle.write(content)

    os.system("run_mitsuba.bat > nul")

    print("  Writing result ..")
    img = PNMImage("scene-rp.png")
    img_ref = PNMImage("scene.png")

    img.copy_sub_image(img_ref, 256, 0, 256, 0, 256, 512)
    img.mult_sub_image(overlay, 0, 0)
    img.write("batch_compare/" + material["name"] + ".png")

try:
    os.remove("_tmp_material.py")
except:
    pass

print("Done!")