[Bf-extensions-cvs] [31abe549] master: BlenderKit: fixes for HDRs

Vilem Duha noreply at git.blender.org
Thu Aug 12 16:54:35 CEST 2021


Commit: 31abe549839bdb30ce0926142bcbf8a3d9236067
Author: Vilem Duha
Date:   Thu Aug 12 16:15:06 2021 +0200
Branches: master
https://developer.blender.org/rBA31abe549839bdb30ce0926142bcbf8a3d9236067

BlenderKit: fixes for HDRs

Now HDRs are clearly separated between true HDR files and simple 360 photos.
the 360 photos are hidden in search filter by default.
Also fixed version check for HDRs and several little tweaks to UI

===================================================================

M	blenderkit/__init__.py
M	blenderkit/download.py
M	blenderkit/image_utils.py
M	blenderkit/paths.py
M	blenderkit/search.py
M	blenderkit/ui_panels.py
M	blenderkit/upload.py
M	blenderkit/utils.py

===================================================================

diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index 547060ac..d22f383b 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -976,16 +976,19 @@ class BlenderKitBrushSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
 class BlenderKitHDRUploadProps(PropertyGroup, BlenderKitCommonUploadProps):
     texture_resolution_max: IntProperty(name="Texture Resolution Max", description="texture resolution maximum",
                                         default=0)
+    evs_cap: IntProperty(name="EV cap", description="EVs dynamic range",
+                                        default=0)
+    true_hdr: BoolProperty(name="Real HDR", description="Image has High dynamic range.",default=False)
 
 
 class BlenderKitBrushUploadProps(PropertyGroup, BlenderKitCommonUploadProps):
     mode: EnumProperty(
         name="Mode",
         items=(
-            ('IMAGE', 'Texture paint', "Texture brush"),
-            ('SCULPT', 'Sculpt', 'Sculpt brush'),
-            ('VERTEX', 'Vertex paint', 'Vertex paint brush'),
-            ('WEIGHT', 'Weight paint', 'Weight paint brush'),
+            ("IMAGE", "Texture paint", "Texture brush"),
+            ("SCULPT", "Sculpt", "Sculpt brush"),
+            ("VERTEX", "Vertex paint", "Vertex paint brush"),
+            ("WEIGHT", "Weight paint", "Weight paint brush"),
         ),
         description="Mode where the brush works",
         default="SCULPT",
@@ -1514,6 +1517,13 @@ class BlenderKitHDRSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
         update=search.search_update
     )
 
+    true_hdr: BoolProperty(
+        name='Real HDRs only',
+        description='Search only for real HDRs, this means images that have a range higher than 0-1 in their pixels.',
+        default=True,
+        update=search.search_update
+    )
+
 
 class BlenderKitSceneSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
     search_keywords: StringProperty(
diff --git a/blenderkit/download.py b/blenderkit/download.py
index d0b6cc98..2d5343b3 100644
--- a/blenderkit/download.py
+++ b/blenderkit/download.py
@@ -17,7 +17,7 @@
 # ##### END GPL LICENSE BLOCK #####
 
 
-from blenderkit import paths, append_link, utils, ui, colors, tasks_queue, rerequests, resolutions, ui_panels
+from blenderkit import paths, append_link, utils, ui, colors, tasks_queue, rerequests, resolutions, ui_panels, search
 
 import threading
 import time
@@ -693,7 +693,11 @@ def delete_unfinished_file(file_name):
 
 def download_asset_file(asset_data, resolution='blend', api_key = ''):
     # this is a simple non-threaded way to download files for background resolution genenration tool
-    file_name = paths.get_download_filepaths(asset_data, resolution)[0]  # prefer global dir if possible.
+    file_names = paths.get_download_filepaths(asset_data, resolution)  # prefer global dir if possible.
+    if len(file_names) == 0:
+        return None
+
+    file_name = file_names[0]
 
     if check_existing(asset_data, resolution=resolution):
         # this sends the thread for processing, where another check should occur, since the file might be corrupted.
@@ -704,6 +708,7 @@ def download_asset_file(asset_data, resolution='blend', api_key = ''):
 
     with open(file_name, "wb") as f:
         print("Downloading %s" % file_name)
+        headers = utils.get_headers(api_key)
         res_file_info, resolution = paths.get_res_file(asset_data, resolution)
         response = requests.get(res_file_info['url'], stream=True)
         total_length = response.headers.get('Content-Length')
@@ -1308,12 +1313,23 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
             # or from the scene.
             asset_base_id = self.asset_base_id
 
-        au = s.get('assets used')
-        if au == None:
-            s['assets used'] = {}
-        if asset_base_id in s.get('assets used'):
-            # already used assets have already download link and especially file link.
-            asset_data = s['assets used'][asset_base_id].to_dict()
+            au = s.get('assets used')
+            if au == None:
+                s['assets used'] = {}
+            if asset_base_id in s.get('assets used'):
+                # already used assets have already download link and especially file link.
+                asset_data = s['assets used'][asset_base_id].to_dict()
+            else:
+                #when not in scene nor in search results, we need to get it from the server
+                params = {
+                    'asset_base_id': self.asset_base_id
+                }
+                preferences = bpy.context.preferences.addons['blenderkit'].preferences
+
+                results = search.get_search_simple(params,  page_size=1, max_results=1,
+                             api_key=preferences.api_key)
+                asset_data = search.parse_result(results[0])
+
         return asset_data
 
     def execute(self, context):
diff --git a/blenderkit/image_utils.py b/blenderkit/image_utils.py
index 2566eaa4..4c09b06a 100644
--- a/blenderkit/image_utils.py
+++ b/blenderkit/image_utils.py
@@ -2,6 +2,7 @@ import bpy
 import os
 import time
 
+
 def get_orig_render_settings():
     rs = bpy.context.scene.render
     ims = rs.image_settings
@@ -33,7 +34,8 @@ def set_orig_render_settings(orig_settings):
     vs.view_transform = orig_settings['view_transform']
 
 
-def img_save_as(img, filepath='//', file_format='JPEG', quality=90, color_mode='RGB', compression=15, view_transform = 'Raw', exr_codec = 'DWAA'):
+def img_save_as(img, filepath='//', file_format='JPEG', quality=90, color_mode='RGB', compression=15,
+                view_transform='Raw', exr_codec='DWAA'):
     '''Uses Blender 'save render' to save images - BLender isn't really able so save images with other methods correctly.'''
 
     ors = get_orig_render_settings()
@@ -49,11 +51,11 @@ def img_save_as(img, filepath='//', file_format='JPEG', quality=90, color_mode='
     ims.exr_codec = exr_codec
     vs.view_transform = view_transform
 
-
     img.save_render(filepath=bpy.path.abspath(filepath), scene=bpy.context.scene)
 
     set_orig_render_settings(ors)
 
+
 def set_colorspace(img, colorspace):
     '''sets image colorspace, but does so in a try statement, because some people might actually replace the default
     colorspace settings, and it literally can't be guessed what these people use, even if it will mostly be the filmic addon.
@@ -66,11 +68,22 @@ def set_colorspace(img, colorspace):
     except:
         print(f'Colorspace {colorspace} not found.')
 
+def analyze_image_is_true_hdr(image):
+    import numpy
+    scene = bpy.context.scene
+    ui_props = scene.blenderkitUI
+    size = image.size
+    imageWidth = size[0]
+    imageHeight = size[1]
+    tempBuffer = numpy.empty(imageWidth * imageHeight * 4, dtype=numpy.float32)
+    image.pixels.foreach_get(tempBuffer)
+    image.blenderkit.true_hdr = numpy.amax(tempBuffer) > 1.05
+
 def generate_hdr_thumbnail():
     import numpy
     scene = bpy.context.scene
     ui_props = scene.blenderkitUI
-    hdr_image = ui_props.hdr_upload_image#bpy.data.images.get(ui_props.hdr_upload_image)
+    hdr_image = ui_props.hdr_upload_image  # bpy.data.images.get(ui_props.hdr_upload_image)
 
     base, ext = os.path.splitext(hdr_image.filepath)
     thumb_path = base + '.jpg'
@@ -90,6 +103,8 @@ def generate_hdr_thumbnail():
 
     hdr_image.pixels.foreach_get(tempBuffer)
 
+    hdr_image.blenderkit.true_hdr = numpy.amax(tempBuffer) > 1.05
+
     inew.filepath = thumb_path
     set_colorspace(inew, 'Linear')
     inew.pixels.foreach_set(tempBuffer)
@@ -103,29 +118,31 @@ def generate_hdr_thumbnail():
 
 def find_color_mode(image):
     if not isinstance(image, bpy.types.Image):
-        raise(TypeError)
+        raise (TypeError)
     else:
         depth_mapping = {
             8: 'BW',
             24: 'RGB',
-            32: 'RGBA',#can also be bw.. but image.channels doesn't work.
+            32: 'RGBA',  # can also be bw.. but image.channels doesn't work.
             96: 'RGB',
             128: 'RGBA',
         }
-        return depth_mapping.get(image.depth,'RGB')
+        return depth_mapping.get(image.depth, 'RGB')
+
 
 def find_image_depth(image):
     if not isinstance(image, bpy.types.Image):
-        raise(TypeError)
+        raise (TypeError)
     else:
         depth_mapping = {
             8: '8',
             24: '8',
-            32: '8',#can also be bw.. but image.channels doesn't work.
+            32: '8',  # can also be bw.. but image.channels doesn't work.
             96: '16',
             128: '16',
         }
-        return depth_mapping.get(image.depth,'8')
+        return depth_mapping.get(image.depth, '8')
+
 
 def can_erase_alpha(na):
     alpha = na[3::4]
@@ -148,6 +165,7 @@ def is_image_black(na):
         print('image can have alpha channel dropped')
     return rgbsum == 0
 
+
 def is_image_bw(na):
     r = na[::4]
     g = na[1::4]
@@ -186,7 +204,8 @@ def numpytoimage(a, iname, width=0, height=0, channels=3):
         if image.name[:len(iname)] == iname and image.size[0] == width and image.size[1] == height:
             i = image
     if i is None:
-        i = bpy.data.images.new(iname, width, height, alpha=False, float_buffer=False, stereo3d=False, is_data=False, tiled=False)
+        i = bpy.data.images.new(iname, width, height, alpha=False, float_buffer=False, stereo3d=False, is_data=False,
+                                tiled=False)
 
     # dropping this re-shaping code -  just doing flat array for speed and simplicity
     #    d = a.shape[0] * a.shape[1]
@@ -220,6 +239,7 @@ def imagetonumpy_flat(i):
     # print('\ntime of image to numpy ' + str(time.time() - t))
     return na
 
+
 def imagetonumpy(i):
     t = time.time()
 
@@ -273,18 +293,19 @@ def get_rgb_mean(i):
     #    return(rmedian,gmedian, bmedian)
     return (rmean, gmean, bmean)
 
+
 def check_nmap_mean_ok(i):
     '''checks if normal map values are in standard range.'''
 
-    rmean,gmean,bmean = get_rgb_mean(i)
+    rmean, gmean, bmean = get_rgb_mean(i)
 
-    #we could/should also check blue, but some ogl substance exports have 0-1, while 90% nmaps have 0.5 - 1.
-    nmap_ok = 0.45< rmean < 0.55 and .45 < gmean < .55

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list