From 042fbefac686666190915d206600a5dab8e03066 Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Thu, 7 Jul 2022 08:03:39 +0200 Subject: glTF importer/exporter: Manage some official Khronos Extensions about Materials KHR_materials_ior KHR_materials_sheen KHR_materials_specular KHR_materials_transmission KHR_materials_variants KHR_materials_emissive_strength KHR_materials_volume Documentation update is still in progress --- io_scene_gltf2/blender/exp/gltf2_blender_image.py | 46 ++++++++++++++++++----- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_image.py') diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_image.py b/io_scene_gltf2/blender/exp/gltf2_blender_image.py index 8b9db89a..6730f479 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_image.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_image.py @@ -27,6 +27,18 @@ class FillWhite: """Fills a channel with all ones (1.0).""" pass +class StoreData: + def __init__(self, data): + """Store numeric data (not an image channel""" + self.data = data + +class StoreImage: + """ + Store a channel with the channel src_chan from a Blender image. + This channel will be used for numpy calculation (no direct channel mapping) + """ + def __init__(self, image: bpy.types.Image): + self.image = image class ExportImage: """Custom image class. @@ -55,9 +67,13 @@ class ExportImage: def __init__(self, original=None): self.fills = {} + self.stored = {} - # In case of keeping original texture images - self.original = original + self.original = original # In case of keeping original texture images + self.numpy_calc = None + + def set_calc(self, numpy_calc): + self.numpy_calc = numpy_calc # In case of numpy calculation (no direct channel mapping) @staticmethod def from_blender_image(image: bpy.types.Image): @@ -73,6 +89,12 @@ class ExportImage: def fill_image(self, image: bpy.types.Image, dst_chan: Channel, src_chan: Channel): self.fills[dst_chan] = FillImage(image, src_chan) + def store_data(self, identifier, data, type='Image'): + if type == "Image": # This is an image + self.stored[identifier] = StoreImage(data) + else: # This is a numeric value + self.stored[identifier] = StoreData(data) + def fill_white(self, dst_chan: Channel): self.fills[dst_chan] = FillWhite() @@ -81,7 +103,7 @@ class ExportImage: def empty(self) -> bool: if self.original is None: - return not self.fills + return not (self.fills or self.stored) else: return False @@ -103,7 +125,7 @@ class ExportImage: len(set(fill.image.name for fill in self.fills.values())) == 1 ) - def encode(self, mime_type: Optional[str]) -> bytes: + def encode(self, mime_type: Optional[str]) -> Tuple[bytes, bool]: self.file_format = { "image/jpeg": "JPEG", "image/png": "PNG" @@ -111,10 +133,14 @@ class ExportImage: # Happy path = we can just use an existing Blender image if self.__on_happy_path(): - return self.__encode_happy() + return self.__encode_happy(), None - # Unhappy path = we need to create the image self.fills describes. - return self.__encode_unhappy() + # Unhappy path = we need to create the image self.fills describes or self.stores describes + if self.numpy_calc is None: + return self.__encode_unhappy(), None + else: + pixels, width, height, factor = self.numpy_calc(self.stored) + return self.__encode_from_numpy_array(pixels, (width, height)), factor def __encode_happy(self) -> bytes: return self.__encode_from_image(self.blender_image()) @@ -147,7 +173,7 @@ class ExportImage: else: # Image is the wrong size; make a temp copy and scale it. with TmpImageGuard() as guard: - _make_temp_image_copy(guard, src_image=image) + make_temp_image_copy(guard, src_image=image) tmp_image = guard.image tmp_image.scale(width, height) tmp_image.pixels.foreach_get(tmp_buf) @@ -197,7 +223,7 @@ class ExportImage: # Copy to a temp image and save. with TmpImageGuard() as guard: - _make_temp_image_copy(guard, src_image=image) + make_temp_image_copy(guard, src_image=image) tmp_image = guard.image return _encode_temp_image(tmp_image, self.file_format) @@ -228,7 +254,7 @@ class TmpImageGuard: bpy.data.images.remove(self.image, do_unlink=True) -def _make_temp_image_copy(guard: TmpImageGuard, src_image: bpy.types.Image): +def make_temp_image_copy(guard: TmpImageGuard, src_image: bpy.types.Image): """Makes a temporary copy of src_image. Will be cleaned up with guard.""" guard.image = src_image.copy() tmp_image = guard.image -- cgit v1.2.3