1330 lines
44 KiB
Python
1330 lines
44 KiB
Python
# #### BEGIN GPL LICENSE BLOCK #####
|
||
#
|
||
# This program is free software; you can redistribute it and/or
|
||
# modify it under the terms of the GNU General Public License
|
||
# as published by the Free Software Foundation; either version 2
|
||
# of the License, or (at your option) any later version.
|
||
#
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
# GNU General Public License for more details.
|
||
#
|
||
# You should have received a copy of the GNU General Public License
|
||
# along with this program; if not, write to the Free Software Foundation,
|
||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
#
|
||
# ##### END GPL LICENSE BLOCK #####
|
||
|
||
from math import ceil
|
||
from typing import Dict, List, Optional, Tuple
|
||
|
||
import bpy
|
||
|
||
from ..modules.poliigon_core.assets import (
|
||
AssetData,
|
||
AssetType,
|
||
find_closest_size,
|
||
ModelType)
|
||
from ..modules.poliigon_core.api import ERR_LIMIT_DOWNLOAD_RATE, ERR_NOT_ENOUGH_CREDITS
|
||
from ..modules.poliigon_core.api_remote_control_params import (
|
||
CATEGORY_ALL,
|
||
KEY_TAB_IMPORTED,
|
||
KEY_TAB_MY_ASSETS,
|
||
KEY_TAB_ONLINE,
|
||
IDX_PAGE_ACCUMULATED,
|
||
PAGE_SIZE_ACCUMULATED)
|
||
from ..modules.poliigon_core.multilingual import _t
|
||
from .utils_dlg import (
|
||
check_convention,
|
||
check_dpi,
|
||
get_model_op_details,
|
||
get_ui_scale,
|
||
safe_size_apply,
|
||
wrapped_label)
|
||
from ..operators.operator_material import set_op_mat_disp_strength
|
||
|
||
|
||
THUMB_SIZE_FACTOR = {"Tiny": 0.5,
|
||
"Small": 0.75,
|
||
"Medium": 1.0,
|
||
"Large": 1.5,
|
||
"Huge": 2.0}
|
||
W_THUMB_BASE = 170
|
||
|
||
|
||
def _get_imported_material(asset_id: int) -> Optional[bpy.types.Material]:
|
||
"""Returns the imported material belonging to given assetID (if any)."""
|
||
|
||
mat_asset = None
|
||
for _mat in bpy.data.materials:
|
||
try:
|
||
asset_id_mat = _mat.poliigon_props.asset_id
|
||
if asset_id_mat != asset_id:
|
||
continue
|
||
mat_asset = _mat
|
||
break
|
||
except Exception: # TODO(Andreas): correct exception for missing prop
|
||
continue
|
||
return mat_asset
|
||
|
||
|
||
def _build_assets_no_assets(cTB, area: str, category: str) -> None:
|
||
box_not_found = cTB.vBase.box()
|
||
|
||
label = _t("No Poliigon {0} found in Library").format(category)
|
||
if cTB.vSearch[area] != "":
|
||
label = _t(
|
||
"No results found."
|
||
" Please try changing your filter or search term."
|
||
)
|
||
elif area == KEY_TAB_IMPORTED:
|
||
label = _t("No Poliigon {0} found in the Scene").format(category)
|
||
elif area == KEY_TAB_ONLINE:
|
||
label = _t("No Poliigon {0} found Online").format(category)
|
||
|
||
width = cTB.width_draw_ui - 20 * get_ui_scale(cTB)
|
||
wrapped_label(cTB, width, label, box_not_found, add_padding=True)
|
||
|
||
return box_not_found
|
||
|
||
|
||
def _determine_thumb_width(cTB, thumb_size_factor: float) -> float:
|
||
thumb_width = ceil(W_THUMB_BASE * thumb_size_factor)
|
||
thumb_width *= get_ui_scale(cTB)
|
||
return thumb_width
|
||
|
||
|
||
def _determine_num_thumb_columns(
|
||
cTB,
|
||
thumb_width: float,
|
||
sorted_assets: List[Dict]
|
||
) -> int:
|
||
num_columns = int(cTB.width_draw_ui / thumb_width)
|
||
num_columns = max(num_columns, 1)
|
||
num_columns = min(num_columns, len(sorted_assets))
|
||
return num_columns
|
||
|
||
|
||
def _determine_grid_padding(
|
||
cTB,
|
||
num_columns: int,
|
||
thumb_width: float) -> float:
|
||
padding = (cTB.width_draw_ui - (num_columns * thumb_width)) / 2
|
||
if padding < 1.0 and num_columns > 1:
|
||
num_columns -= 1
|
||
padding = (cTB.width_draw_ui - (num_columns * thumb_width)) / 2
|
||
return padding
|
||
|
||
|
||
def _build_assets_prepare_grid(cTB,
|
||
thumb_size_factor: float,
|
||
sorted_assets: List[Dict]
|
||
) -> Tuple[bpy.types.UILayout, float, int]:
|
||
thumb_width = _determine_thumb_width(cTB, thumb_size_factor)
|
||
num_columns = _determine_num_thumb_columns(cTB, thumb_width, sorted_assets)
|
||
padding = _determine_grid_padding(cTB, num_columns, thumb_width)
|
||
|
||
split_right = None
|
||
if padding >= 1.0 or thumb_width + 1 <= cTB.width_draw_ui:
|
||
# Typical case, fit rows and columns.
|
||
factor = padding / cTB.width_draw_ui
|
||
split_left = cTB.vBase.split(factor=factor)
|
||
|
||
split_left.separator()
|
||
|
||
factor = 1.0 - factor
|
||
split_right = split_left.split(factor=factor)
|
||
|
||
container_grid = split_right
|
||
else:
|
||
# Panel is narrower than a single preview width, single col.
|
||
container_grid = cTB.vBase
|
||
|
||
grid = container_grid.grid_flow(
|
||
row_major=True, columns=num_columns,
|
||
even_columns=True, even_rows=True, align=False
|
||
)
|
||
|
||
if split_right is not None:
|
||
split_right.separator()
|
||
|
||
return grid, thumb_width, num_columns
|
||
|
||
|
||
def _determine_in_scene_sizes(cTB,
|
||
asset_data: AssetData,
|
||
size_default: str
|
||
) -> Tuple[List[str], str]:
|
||
asset_id = asset_data.asset_id
|
||
|
||
query_key = cTB.get_accumulated_query_cache_key(tab=KEY_TAB_IMPORTED)
|
||
if query_key not in cTB._asset_index.cached_queries:
|
||
return [], size_default
|
||
asset_ids_imported = cTB._asset_index.cached_queries[query_key]
|
||
|
||
sizes_in_scene = []
|
||
if asset_id not in asset_ids_imported:
|
||
return sizes_in_scene, size_default
|
||
|
||
asset_ids_no_longer_in_scene = asset_ids_imported.copy()
|
||
|
||
# TODO(Andreas): Why is this cleanup happening in here???
|
||
for _entities in [bpy.data.objects, bpy.data.materials, bpy.data.images]:
|
||
for _entity in _entities:
|
||
try:
|
||
asset_id_entity = _entity.poliigon_props.asset_id
|
||
|
||
if asset_id_entity in asset_ids_no_longer_in_scene:
|
||
asset_ids_no_longer_in_scene.remove(asset_id_entity)
|
||
|
||
if asset_id_entity != asset_id:
|
||
continue
|
||
sizes_in_scene.append(_entity.poliigon_props.size)
|
||
except Exception:
|
||
cTB.logger_ui.exception("Unexpected exception")
|
||
|
||
for _asset_id in asset_ids_no_longer_in_scene:
|
||
asset_ids_imported.remove(_asset_id)
|
||
|
||
if sizes_in_scene and size_default not in sizes_in_scene and sizes_in_scene[0]:
|
||
size_default = sizes_in_scene[0]
|
||
|
||
return sizes_in_scene, size_default
|
||
|
||
|
||
def _draw_thumbnail(cTB,
|
||
asset_data: AssetData,
|
||
thumb_size_factor: float,
|
||
layout_box: bpy.types.UILayout) -> None:
|
||
asset_name = asset_data.asset_name
|
||
thumb_scale = cTB.settings["preview_size"] * thumb_size_factor
|
||
|
||
# TODO(Andreas): If we used ThumbCache, instead of lines below
|
||
# id_bmp, is_real = cTB.thumb_cache.get_thumb_bitmap(
|
||
# asset_id, cTB.callback_asset_update_ui)
|
||
# layout_box.template_icon(
|
||
# icon_value=id_bmp,
|
||
# scale=thumb_scale
|
||
# )
|
||
|
||
with cTB.lock_thumbs:
|
||
if asset_name == "dummy":
|
||
layout_box.template_icon(
|
||
icon_value=cTB.ui_icons["GET_preview"].icon_id,
|
||
scale=thumb_scale
|
||
)
|
||
elif asset_name in cTB.thumbs.keys():
|
||
layout_box.template_icon(
|
||
icon_value=cTB.thumbs[asset_name].icon_id,
|
||
scale=thumb_scale
|
||
)
|
||
asset_data.runtime.set_thumb_downloading(is_downloading=False)
|
||
else:
|
||
if asset_data.runtime.get_thumb_downloading():
|
||
layout_box.template_icon(
|
||
icon_value=cTB.ui_icons["GET_preview"].icon_id,
|
||
scale=thumb_scale
|
||
)
|
||
|
||
else:
|
||
layout_box.template_icon(
|
||
icon_value=cTB.ui_icons["NO_preview"].icon_id,
|
||
scale=thumb_scale
|
||
)
|
||
|
||
|
||
def _draw_thumb_state_asset_dummy(layout_row: bpy.types.UILayout) -> None:
|
||
op = layout_row.operator("poliigon.poliigon_setting", text=" ")
|
||
op.mode = "none"
|
||
|
||
|
||
def _draw_thumb_state_asset_purchasing(
|
||
layout_row: bpy.types.UILayout, asset_data: AssetData) -> None:
|
||
credits = 0 if asset_data.credits is None else asset_data.credits
|
||
is_free = credits == 0
|
||
if is_free:
|
||
label = _t("Starting...")
|
||
else:
|
||
label = _t("Purchasing...")
|
||
|
||
row = layout_row.row()
|
||
row.enabled = False
|
||
op = row.operator(
|
||
"poliigon.poliigon_setting",
|
||
text=label,
|
||
emboss=1,
|
||
depress=1,
|
||
)
|
||
op.mode = "none"
|
||
op.tooltip = label
|
||
|
||
|
||
def _draw_thumb_state_asset_downloading(layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
thumb_width: float
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
|
||
progress = asset_data.state.dl.get_progress()
|
||
progress = max(0.001, progress)
|
||
|
||
layout_row.label(text="", icon="IMPORT")
|
||
|
||
col = layout_row.column()
|
||
col_cancel = layout_row.column()
|
||
# Display cancel button instead of time remaining.
|
||
ops = col_cancel.operator("poliigon.cancel_download",
|
||
emboss=False, text="", icon="X")
|
||
ops.asset_id = asset_id
|
||
|
||
spacer = col.row()
|
||
spacer.scale_y = 0.2
|
||
spacer.label(text="")
|
||
|
||
row_progress = col.row()
|
||
row_progress.scale_y = 0.4
|
||
|
||
split_progress = row_progress.split(factor=progress, align=True)
|
||
pcent = round(progress * 100, 1)
|
||
# tooltip = f"Downloading ({pcent}%)\n{asset_name} @ {download_data['size']}..."
|
||
# TODO(Andreas): AssetData does not have the size info during download, only after, atm...
|
||
tooltip = _t("Downloading ({0}%)\n{1}...").format(pcent, asset_name)
|
||
|
||
op = split_progress.operator(
|
||
"poliigon.poliigon_setting", text="", emboss=1, depress=1
|
||
)
|
||
op.mode = "none"
|
||
op.tooltip = tooltip
|
||
|
||
op = split_progress.operator(
|
||
"poliigon.poliigon_setting", text="", emboss=1, depress=0
|
||
)
|
||
op.mode = "none"
|
||
op.tooltip = tooltip
|
||
|
||
layout_row.separator()
|
||
|
||
|
||
def _draw_thumb_state_cancelling_download(
|
||
layout_row: bpy.types.UILayout, asset_data: AssetData) -> None:
|
||
label = _t("Cancelling...")
|
||
|
||
row = layout_row.row()
|
||
row.enabled = False
|
||
op = row.operator(
|
||
"poliigon.poliigon_setting",
|
||
text=label,
|
||
emboss=1,
|
||
depress=0,
|
||
)
|
||
op.mode = "none"
|
||
op.tooltip = label
|
||
|
||
|
||
def _draw_button_quick_preview(
|
||
cTB,
|
||
layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
is_selection: bool,
|
||
have_text_label: bool = False
|
||
) -> None:
|
||
if cTB.is_unlimited_user():
|
||
return
|
||
if not check_convention(asset_data):
|
||
return
|
||
|
||
asset_type_data = asset_data.get_type_data()
|
||
asset_name = asset_data.asset_name
|
||
asset_type = asset_data.asset_type
|
||
if asset_type != AssetType.TEXTURE:
|
||
return
|
||
|
||
credits = 0 if asset_data.credits is None else asset_data.credits
|
||
is_free = credits == 0
|
||
is_backplate = asset_data.is_backplate()
|
||
|
||
do_show = False
|
||
# TODO(Andreas): confused about backplate handling...
|
||
has_thumb_urls = len(asset_data.thumb_urls) > 0
|
||
has_cf_thumb_urls = len(asset_data.cloudflare_thumb_urls) > 0
|
||
if is_backplate and (has_thumb_urls or has_cf_thumb_urls):
|
||
do_show = True
|
||
elif len(asset_type_data.get_watermark_preview_url_list()):
|
||
do_show = True
|
||
|
||
if not do_show:
|
||
return
|
||
|
||
col_preview = layout_row.column(align=True)
|
||
# Quick preview button gets disabled on free assets as they
|
||
# don't need to be purchased (and their Purchase button was
|
||
# changed into 'Download' woth an implicit auto-download)
|
||
col_preview.enabled = not is_free
|
||
|
||
popup_preview = cTB.settings["popup_preview"]
|
||
if not popup_preview:
|
||
name_op = "poliigon.popup_first_preview"
|
||
else:
|
||
name_op = "poliigon.poliigon_preview"
|
||
|
||
if have_text_label:
|
||
label = _t("Texture Preview")
|
||
else:
|
||
label = ""
|
||
|
||
op = col_preview.operator(
|
||
name_op,
|
||
text=label,
|
||
icon="HIDE_OFF",
|
||
emboss=1,
|
||
)
|
||
op.asset_id = asset_data.asset_id
|
||
if is_free:
|
||
op.tooltip = _t(
|
||
"{0} is free, just download and use it right away").format(
|
||
asset_name)
|
||
elif is_selection:
|
||
op.tooltip = _t("Preview {0} on selected object(s)").format(asset_name)
|
||
else:
|
||
op.tooltip = _t(
|
||
"Preview {0} on a plane created during import").format(asset_name)
|
||
|
||
|
||
def _draw_checkmark_purchased(cTB, layout_row: bpy.types.UILayout) -> None:
|
||
col_checkmark = layout_row.column(align=True)
|
||
col_checkmark.enabled = False
|
||
icon_val = cTB.ui_icons["ICON_acquired_check"].icon_id
|
||
op = col_checkmark.operator(
|
||
"poliigon.poliigon_setting",
|
||
text="",
|
||
icon_value=icon_val,
|
||
depress=False,
|
||
emboss=True
|
||
)
|
||
op.tooltip = _t("Asset already acquired")
|
||
|
||
|
||
def _draw_checkmark_unlimited(cTB, layout_row: bpy.types.UILayout) -> None:
|
||
col_checkmark = layout_row.column(align=True)
|
||
col_checkmark.enabled = False
|
||
icon_val = cTB.ui_icons["ICON_unlimited_local"].icon_id
|
||
op = col_checkmark.operator(
|
||
"poliigon.poliigon_setting",
|
||
text="",
|
||
icon_value=icon_val,
|
||
depress=False,
|
||
emboss=True
|
||
)
|
||
op.tooltip = _t("Asset found locally")
|
||
|
||
|
||
def _draw_button_model_local(cTB,
|
||
layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
error: Optional[str]
|
||
) -> None:
|
||
asset_type_data = asset_data.get_type_data()
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
asset_type = asset_data.asset_type
|
||
|
||
size_desired = asset_data.runtime.get_current_size()
|
||
if size_desired is None:
|
||
size_desired = cTB.get_pref_size(asset_type)
|
||
size = asset_type_data.get_size(
|
||
size_desired,
|
||
local_only=True,
|
||
addon_convention=cTB._asset_index.addon_convention,
|
||
local_convention=asset_data.get_convention(local=True))
|
||
|
||
if error is not None:
|
||
icon = "ERROR"
|
||
label = "Error"
|
||
lod = "NONE"
|
||
tip = error
|
||
else:
|
||
lod, label, tip = get_model_op_details(cTB, asset_data, size)
|
||
if lod != "" and lod != "NONE":
|
||
label = _t("Import {0}, {1}").format(size, lod)
|
||
else:
|
||
label = _t("Import {0}").format(size)
|
||
icon = "TRACKING_REFINE_BACKWARDS"
|
||
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_model",
|
||
text=label,
|
||
icon=icon,
|
||
)
|
||
op.asset_id = asset_id
|
||
op.tooltip = tip
|
||
try:
|
||
op.lod = lod if len(lod) > 0 else "NONE"
|
||
except TypeError:
|
||
# TODO(Andreas): Exception handling can likely be removed again.
|
||
# Was needed to find another issue...
|
||
msg = (f"{asset_name}: {lod} not found\n"
|
||
f"{asset_data.get_type_data().get_lod_list()}\n")
|
||
cTB.logger_ui.exception(msg)
|
||
op.lod = "NONE"
|
||
safe_size_apply(cTB, op, size, asset_name)
|
||
|
||
|
||
def _draw_button_texture_local(cTB,
|
||
layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
error: Optional[str],
|
||
sizes_in_scene,
|
||
size_default: str,
|
||
is_selection: bool
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
|
||
row_button = layout_row.row(align=True)
|
||
|
||
label = _t("Import {0}").format(size_default)
|
||
icon = "TRACKING_REFINE_BACKWARDS"
|
||
tooltip = _t("{0}\n(Import Material)").format(asset_name)
|
||
if len(sizes_in_scene):
|
||
row_button.enabled = is_selection
|
||
label = _t("Apply {0}").format(size_default)
|
||
icon = "TRACKING_REFINE_BACKWARDS"
|
||
tooltip = _t("{0}\n(Apply Material)").format(asset_name)
|
||
elif is_selection:
|
||
label = _t("Apply {0}").format(size_default)
|
||
icon = "TRACKING_REFINE_BACKWARDS"
|
||
tooltip = _t("{0}\n(Import + Apply Material)").format(asset_name)
|
||
|
||
if error is not None:
|
||
op = row_button.operator(
|
||
"poliigon.poliigon_material",
|
||
text="Retry",
|
||
icon="ERROR",
|
||
)
|
||
op.tooltip = error
|
||
else:
|
||
op = row_button.operator(
|
||
"poliigon.poliigon_material",
|
||
text=label,
|
||
icon=icon,
|
||
)
|
||
op.tooltip = tooltip
|
||
|
||
op.asset_id = asset_id
|
||
safe_size_apply(cTB, op, size_default, asset_name)
|
||
op.mapping = "UV"
|
||
op.scale = 1.0
|
||
op.use_16bit = cTB.settings["use_16"]
|
||
op.reuse_material = True
|
||
set_op_mat_disp_strength(op, asset_name, op.mode_disp)
|
||
|
||
|
||
def _draw_button_model_imported(layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData
|
||
) -> None:
|
||
asset_name = asset_data.asset_name
|
||
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_select",
|
||
text=_t("Select"),
|
||
icon="RESTRICT_SELECT_OFF",
|
||
)
|
||
op.mode = "model"
|
||
op.data = asset_name
|
||
op.tooltip = _t("{0}\n(Select all instances)").format(asset_name)
|
||
|
||
|
||
def _draw_button_texture_imported(layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_apply",
|
||
text=_t("Apply"),
|
||
icon="TRACKING_REFINE_BACKWARDS",
|
||
)
|
||
op.asset_id = asset_id
|
||
mat = _get_imported_material(asset_id)
|
||
if mat is not None:
|
||
op.name_material = mat.name
|
||
else:
|
||
op.name_material = "Deleted Material" # Should not appear in UI!
|
||
op.tooltip = _t("{0}\n(Apply to selected models)").format(asset_name)
|
||
|
||
|
||
def determine_hdri_sizes(asset_data: AssetData,
|
||
size_light_default: str,
|
||
size_bg_default: str,
|
||
use_jpg_bg: bool,
|
||
addon_convention: int
|
||
) -> Tuple[str, str]:
|
||
# TODO(Andreas): Will probably want this in operators fill_size_drop_down
|
||
# as well.
|
||
# Refactor following code into function.
|
||
# Maybe have this in AssetData
|
||
|
||
asset_type_data = asset_data.get_type_data()
|
||
|
||
sizes_local = asset_type_data.get_size_list(
|
||
local_only=True,
|
||
addon_convention=addon_convention,
|
||
local_convention=asset_data.local_convention)
|
||
|
||
sizes_jpg = []
|
||
sizes_exr = []
|
||
for _size in sizes_local:
|
||
tex_maps_jpg = asset_type_data.get_maps(
|
||
size=_size, suffix_list=[".jpg"])
|
||
if len(tex_maps_jpg) > 0:
|
||
sizes_jpg.append(_size)
|
||
tex_maps_exr = asset_type_data.get_maps(
|
||
size=_size, suffix_list=[".exr"])
|
||
if len(tex_maps_exr) > 0:
|
||
sizes_exr.append(_size)
|
||
|
||
if len(sizes_exr) > 0:
|
||
size_light = find_closest_size(size_light_default, sizes_exr)
|
||
elif len(sizes_jpg) > 0:
|
||
size_light = find_closest_size(size_light_default, sizes_jpg)
|
||
else:
|
||
# Just get any best fit
|
||
size_light = asset_type_data.get_size(
|
||
size=size_light_default,
|
||
local_only=True,
|
||
addon_convention=addon_convention,
|
||
local_convention=asset_data.get_convention(local=True))
|
||
|
||
size_bg = size_bg_default
|
||
if not use_jpg_bg:
|
||
size_bg = f"{size_light}_EXR"
|
||
elif len(sizes_jpg) > 0:
|
||
size_bg = find_closest_size(size_bg_default, sizes_jpg)
|
||
size_bg = f"{size_bg}_JPG"
|
||
elif len(sizes_exr) > 0:
|
||
size_bg = find_closest_size(size_bg_default, sizes_exr)
|
||
size_bg = f"{size_bg}_EXR"
|
||
# TODO(Andreas): fallback
|
||
# else:
|
||
# tex_maps = asset_type_data.get_maps(size=size_light)
|
||
# # determine suffix to be used...
|
||
return size_light, size_bg
|
||
|
||
|
||
def _draw_button_hdri_local(cTB,
|
||
layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
error: Optional[str],
|
||
size_default: str
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
|
||
if error is not None:
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_hdri",
|
||
text="Retry",
|
||
icon="ERROR",
|
||
)
|
||
op.tooltip = error.description
|
||
else:
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_hdri",
|
||
text=_t("Import {0}").format(size_default),
|
||
icon="TRACKING_REFINE_BACKWARDS",
|
||
)
|
||
op.tooltip = _t("{0}\n(Import HDRI)").format(asset_name)
|
||
op.asset_id = asset_id
|
||
|
||
size_light, size_bg = determine_hdri_sizes(
|
||
asset_data,
|
||
size_light_default=size_default,
|
||
size_bg_default=cTB.settings["hdrib"],
|
||
use_jpg_bg=cTB.settings["hdri_use_jpg_bg"],
|
||
addon_convention=cTB.addon_convention)
|
||
safe_size_apply(cTB, op, size_light, asset_name)
|
||
op.size_bg = size_bg
|
||
|
||
|
||
def _draw_button_hdri_imported(cTB,
|
||
layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_hdri",
|
||
text=_t("Apply"),
|
||
icon="TRACKING_REFINE_BACKWARDS",
|
||
)
|
||
op.asset_id = asset_id
|
||
# NOTE: Size values will not be used, due to do_apply being set.
|
||
# Nevertheless the values need to exist in the size enums.
|
||
hdri_size = cTB.settings["hdri"]
|
||
safe_size_apply(cTB, op, hdri_size, asset_name)
|
||
try:
|
||
op.size_bg = f"{hdri_size}_EXR"
|
||
except TypeError:
|
||
msg = f"Failed to assign bg {hdri_size} for asset {asset_name})"
|
||
cTB.logger_ui.exception(msg)
|
||
op.do_apply = True
|
||
op.tooltip = _t("{0}\n(Apply to Scene)").format(asset_name)
|
||
|
||
|
||
def _draw_button_download(cTB,
|
||
layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
error: Optional[str],
|
||
size_default: str
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
|
||
if error is not None:
|
||
if error == ERR_LIMIT_DOWNLOAD_RATE and cTB.msg_download_limit is not None:
|
||
error = cTB.msg_download_limit
|
||
label = "Fair use"
|
||
else:
|
||
label = "Retry"
|
||
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_download",
|
||
text=label,
|
||
icon="ERROR",
|
||
)
|
||
op.tooltip = error
|
||
else:
|
||
op = layout_row.operator(
|
||
"poliigon.poliigon_download",
|
||
text=_t("Download {0}").format(size_default),
|
||
)
|
||
op.tooltip = _t("{0}\nDownload Default").format(asset_name)
|
||
layout_row.enabled = not asset_data.state.dl.is_cancelled()
|
||
|
||
op.mode = "download"
|
||
op.asset_id = asset_id
|
||
safe_size_apply(cTB, op, size_default, asset_name)
|
||
|
||
|
||
def _draw_button_purchase(cTB,
|
||
layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
error: Optional[str],
|
||
size_default: str
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
num_credits = asset_data.credits
|
||
is_free = num_credits == 0
|
||
|
||
thumb_size = THUMB_SIZE_FACTOR[cTB.settings["thumbsize"]]
|
||
|
||
if error == ERR_NOT_ENOUGH_CREDITS:
|
||
label = "Balance"
|
||
elif error is not None:
|
||
label = "Retry"
|
||
elif is_free or cTB.is_unlimited_user():
|
||
# While it will still be a purchase button,
|
||
# for free assets it will lead to an implicit auto-download
|
||
label = _t("Download {0}").format(size_default)
|
||
elif thumb_size >= 0.75:
|
||
label = _t("Purchase")
|
||
else:
|
||
label = _t("Buy")
|
||
name_op = "poliigon.poliigon_download"
|
||
mode_purchase = "purchase"
|
||
tooltip = _t("Purchase {0}").format(asset_name)
|
||
if not is_free:
|
||
if cTB.is_free_user():
|
||
name_op = "poliigon.poliigon_setting"
|
||
mode_purchase = "my_account"
|
||
label = _t("Learn More")
|
||
tooltip = _t("Switch to your account overview.")
|
||
elif cTB.is_unlimited_user():
|
||
mode_purchase = "download"
|
||
tooltip = _t("Download {0}").format(asset_name)
|
||
elif not cTB.settings["one_click_purchase"]:
|
||
name_op = "poliigon.popup_purchase"
|
||
else:
|
||
tooltip = _t("Download {0}").format(asset_name)
|
||
|
||
icon = "ERROR" if error is not None else "NONE"
|
||
|
||
op = layout_row.operator(
|
||
name_op, text=label,
|
||
icon=icon
|
||
)
|
||
op.mode = mode_purchase
|
||
if mode_purchase == "purchase" or mode_purchase == "download":
|
||
op.asset_id = asset_id
|
||
safe_size_apply(cTB, op, size_default, asset_name)
|
||
if error:
|
||
op.tooltip = error
|
||
else:
|
||
op.tooltip = tooltip
|
||
|
||
|
||
def _draw_button_quick_menu(layout_row: bpy.types.UILayout,
|
||
asset_data: AssetData,
|
||
hide_detail_view: bool = False
|
||
) -> None:
|
||
asset_id = asset_data.asset_id
|
||
asset_name = asset_data.asset_name
|
||
is_downloaded = asset_data.is_local
|
||
|
||
quick_subtitle = _t("(options)") if is_downloaded else _t("See More")
|
||
|
||
op = layout_row.operator(
|
||
"poliigon.show_quick_menu",
|
||
text="",
|
||
icon="TRIA_DOWN",
|
||
)
|
||
op.asset_id = asset_id
|
||
op.hide_detail_view = hide_detail_view
|
||
op.tooltip = f"{asset_name}\n{quick_subtitle}"
|
||
|
||
|
||
def _draw_missing_grid_dummies(cTB,
|
||
layout_grid: bpy.types.UILayout,
|
||
sorted_assets: List[Dict],
|
||
num_columns: int,
|
||
thumb_width: float
|
||
) -> None:
|
||
# Fill rest of grid with empty cells, if needed
|
||
if len(sorted_assets) >= cTB.settings["page"]:
|
||
return
|
||
if num_columns == len(sorted_assets):
|
||
num_cols_normal = ceil(cTB.width_draw_ui / thumb_width)
|
||
num_cols_normal = max(1, num_cols_normal)
|
||
num_empty_rows = (cTB.settings["page"] // num_cols_normal) - 1
|
||
for _ in range(num_empty_rows):
|
||
layout_grid.column(align=1)
|
||
else:
|
||
for _ in range(len(sorted_assets), cTB.settings["page"]):
|
||
layout_grid.column(align=1)
|
||
|
||
|
||
def _draw_view_more_my_assets(
|
||
cTB, layout_box_not_found: bpy.types.UILayout) -> None:
|
||
if layout_box_not_found is None:
|
||
return
|
||
|
||
row = layout_box_not_found.row(align=True)
|
||
row.scale_y = 1.5
|
||
|
||
label = _t("View more online")
|
||
use_padding = 500
|
||
|
||
if cTB.width_draw_ui >= use_padding * get_ui_scale(cTB):
|
||
row.label(text="")
|
||
|
||
op = row.operator(
|
||
"poliigon.poliigon_setting",
|
||
text=label,
|
||
icon_value=cTB.ui_icons["ICON_poliigon"].icon_id
|
||
)
|
||
op.mode = "view_more"
|
||
|
||
if cTB.width_draw_ui >= use_padding * get_ui_scale(cTB):
|
||
row.label(text="")
|
||
|
||
|
||
def _draw_view_more_imported(cTB, sorted_assets: List[Dict]) -> None:
|
||
if len(sorted_assets) != 0:
|
||
return
|
||
|
||
cTB.vBase.separator()
|
||
cTB.vBase.separator()
|
||
|
||
asset_ids_my_assets = cTB._asset_index.query(
|
||
"my_assets/All Assets",
|
||
chunk=IDX_PAGE_ACCUMULATED,
|
||
chunk_size=PAGE_SIZE_ACCUMULATED)
|
||
if asset_ids_my_assets is not None and len(asset_ids_my_assets) > 0:
|
||
row = cTB.vBase.row(align=True)
|
||
op = row.operator(
|
||
"poliigon.poliigon_setting",
|
||
text=_t("Explore Your Assets"),
|
||
icon_value=cTB.ui_icons["ICON_myassets"].icon_id,
|
||
)
|
||
op.mode = "area_my_assets"
|
||
op.tooltip = _t("Show My Assets")
|
||
else:
|
||
row = cTB.vBase.row(align=True)
|
||
op = row.operator(
|
||
"poliigon.poliigon_setting",
|
||
text=_t("Explore Poliigon Assets"),
|
||
icon_value=cTB.ui_icons["ICON_poliigon"].icon_id,
|
||
)
|
||
op.mode = "area_poliigon"
|
||
op.tooltip = _t("Show Poliigon Assets")
|
||
|
||
|
||
def _draw_button_unsupported_convention(row: bpy.types.UILayout) -> None:
|
||
_ = row.operator(
|
||
"poliigon.unsupported_convention",
|
||
text=_t("Update Needed"),
|
||
icon="ERROR",
|
||
)
|
||
|
||
|
||
def _draw_page_buttons(
|
||
cTB, area: str, idx_page_current: int, at_top: bool = False) -> None:
|
||
num_pages = cTB.vPages[area]
|
||
|
||
if num_pages <= 1:
|
||
return
|
||
|
||
if not at_top:
|
||
cTB.vBase.separator()
|
||
|
||
row = cTB.vBase.row(align=False)
|
||
|
||
idx_page_start = 0
|
||
idx_page_end = num_pages
|
||
|
||
num_pages_max = int((cTB.width_draw_ui / (30 * get_ui_scale(cTB))) - 5)
|
||
if num_pages > num_pages_max:
|
||
idx_page_start = idx_page_current - int(num_pages_max / 2)
|
||
idx_page_end = idx_page_current + int(num_pages_max / 2)
|
||
if idx_page_start < 0:
|
||
idx_page_start = 0
|
||
idx_page_end = num_pages_max
|
||
elif idx_page_end >= num_pages:
|
||
idx_page_start = num_pages - num_pages_max
|
||
idx_page_end = num_pages
|
||
|
||
row_left = row.row(align=True)
|
||
row_left.enabled = idx_page_current != 0
|
||
|
||
op = row_left.operator(
|
||
"poliigon.poliigon_setting", text="", icon="TRIA_LEFT"
|
||
)
|
||
op.mode = "page_-"
|
||
op.tooltip = _t("Go to Previous Page")
|
||
|
||
row_middle = row.row(align=True)
|
||
|
||
op = row_middle.operator(
|
||
"poliigon.poliigon_setting", text="1", depress=(idx_page_current == 0)
|
||
)
|
||
op.mode = "page_0"
|
||
op.tooltip = _t("Go to Page 1")
|
||
|
||
if idx_page_start > 1:
|
||
row_middle.label(
|
||
text="",
|
||
icon_value=cTB.ui_icons["ICON_dots"].icon_id,
|
||
)
|
||
|
||
for idx_page in range(idx_page_start, idx_page_end):
|
||
if idx_page in [0, num_pages - 1]:
|
||
continue
|
||
|
||
op = row_middle.operator(
|
||
"poliigon.poliigon_setting",
|
||
text=str(idx_page + 1),
|
||
depress=(idx_page == idx_page_current),
|
||
)
|
||
op.mode = "page_" + str(idx_page)
|
||
op.tooltip = _t("Go to Page {0}").format(str(idx_page + 1))
|
||
|
||
# Buttons get drawn twice, we want to prefetch thumbs only once
|
||
if not at_top:
|
||
continue
|
||
|
||
# Make sure we have data for this page
|
||
# TODO(Andreas): If we have no data here, we have messed up elsewhere.
|
||
# Yet, thumb prefetching not working as expected.
|
||
# So, we'll see, if doing another server request might
|
||
# help us here.
|
||
# cTB.f_GetAssets(area=area, page=idx_page)
|
||
|
||
# NOT A GOOD IDEA: Chokes Blender almost completely
|
||
# # Schedule thumb prefretching
|
||
# asset_ids_prefetch, _ = cTB.f_GetPageAssets(idx_page)
|
||
# asset_data_prefetch = cTB._asset_index.get_asset_data_list(
|
||
# asset_ids_prefetch)
|
||
# for _asset_data in asset_data_prefetch:
|
||
# path_thumb, url_thumb = cTB._asset_index.get_cf_thumbnail_info(
|
||
# _asset_data.asset_id)
|
||
# cTB.f_QueuePreview(
|
||
# _asset_data, path_thumb, url_thumb, thumbnail_index=0)
|
||
|
||
if idx_page_end < num_pages - 1:
|
||
row_middle.label(text="", icon_value=cTB.ui_icons["ICON_dots"].icon_id)
|
||
|
||
col = row_middle.column(align=True)
|
||
|
||
categories = cTB.settings["category"][area]
|
||
search = cTB.vSearch[area]
|
||
key_fetch = (tuple(categories), search)
|
||
enabled = key_fetch not in cTB.fetching_asset_data[area]
|
||
|
||
col.enabled = enabled
|
||
if enabled:
|
||
text = str(num_pages)
|
||
else:
|
||
text = "..."
|
||
op = col.operator(
|
||
"poliigon.poliigon_setting",
|
||
text=text,
|
||
depress=(idx_page_current == (num_pages - 1)),
|
||
)
|
||
op.mode = "page_" + str(num_pages - 1)
|
||
op.tooltip = _t("Go to Page {0}").format(str(num_pages))
|
||
|
||
row_right = row.row(align=True)
|
||
row_right.enabled = idx_page_current != (num_pages - 1)
|
||
|
||
op = row_right.operator(
|
||
"poliigon.poliigon_setting", text="", icon="TRIA_RIGHT"
|
||
)
|
||
op.mode = "page_+"
|
||
op.tooltip = _t("Go to Next Page")
|
||
|
||
if at_top:
|
||
cTB.vBase.separator()
|
||
|
||
|
||
def _build_unlimited_banner(cTB, layout: bpy.types.UILayout) -> None:
|
||
if not cTB.is_unlimited_user():
|
||
return
|
||
area = cTB.settings["area"]
|
||
if area != KEY_TAB_MY_ASSETS:
|
||
return
|
||
|
||
col_grid = layout.column()
|
||
|
||
box_unlimited = col_grid.box()
|
||
box_unlimited.alignment = "CENTER"
|
||
|
||
col_unlimited = box_unlimited.column()
|
||
col_unlimited.alignment = "CENTER"
|
||
|
||
text_info = _t("Unlimited Downloads - "
|
||
"Assets downloaded on an unlimited plan won’t show up in "
|
||
"My Assets.")
|
||
# 20 seems a good value, determined by trial and error
|
||
w_info = cTB.width_draw_ui - 20 * get_ui_scale(cTB)
|
||
wrapped_label(cTB, w_info, text_info, col_unlimited, add_padding=False)
|
||
|
||
col_link = col_unlimited.column()
|
||
col_link.alignment = "LEFT"
|
||
icon_value = cTB.ui_icons["LOGO_unlimited"].icon_id
|
||
op_link = col_link.operator(
|
||
"poliigon.poliigon_link", text=_t("Learn More"), emboss=True, icon_value=icon_value)
|
||
op_link.tooltip = _t("Learn more online about unlimited plans")
|
||
op_link.mode = "unlimited"
|
||
|
||
|
||
def _build_tab_title(cTB) -> None:
|
||
row = cTB.vBase.row()
|
||
|
||
area = cTB.settings["area"]
|
||
|
||
categories = cTB.vActiveCat
|
||
search = cTB.vSearch[area]
|
||
has_search = len(search) > 0
|
||
is_category_all = categories == [CATEGORY_ALL]
|
||
|
||
is_all = is_category_all and not has_search
|
||
if is_all and area != KEY_TAB_IMPORTED:
|
||
num_assets = cTB.num_assets[area]
|
||
else:
|
||
num_assets = cTB.num_assets_current_query
|
||
|
||
# We do not want the "All" removed, if search comes from our
|
||
# virtual "free category" (which only exists on Online tab), alone.
|
||
# TODO(Andreas): This will change again, once we do the "virtual free"
|
||
# category via API RC.
|
||
if area == KEY_TAB_ONLINE:
|
||
if has_search and cTB.vSearch[area] != "free ":
|
||
prefix_top_level = ""
|
||
else:
|
||
# Leads to deliberately replacing "All " with "All " (-> no change)
|
||
prefix_top_level = "All "
|
||
elif has_search:
|
||
prefix_top_level = ""
|
||
elif area == KEY_TAB_MY_ASSETS:
|
||
prefix_top_level = "My "
|
||
elif area == KEY_TAB_IMPORTED:
|
||
prefix_top_level = "Imported "
|
||
|
||
if cTB.settings["show_settings"]:
|
||
area_title = _t("Settings")
|
||
elif cTB.settings["show_user"]:
|
||
area_title = _t("My Account")
|
||
elif len(categories) == 1:
|
||
category = categories[0]
|
||
if category in ["HDRIs", "Models", "Textures"]:
|
||
category = f"{prefix_top_level}{category}"
|
||
elif category == "All Assets" and area == KEY_TAB_ONLINE:
|
||
if "free" in cTB.vSearch[area]:
|
||
category = "All Free Assets"
|
||
category = category.replace("All ", prefix_top_level)
|
||
|
||
area_title = category
|
||
else:
|
||
area_title = categories[-1].title()
|
||
|
||
if area_title == KEY_TAB_ONLINE:
|
||
area_title = _t("Online")
|
||
|
||
area_title = f"{area_title} ({num_assets})"
|
||
|
||
row.label(text=area_title)
|
||
|
||
row_right = row.row()
|
||
row_right.alignment = "RIGHT"
|
||
|
||
row_right.separator()
|
||
|
||
col = row_right.column()
|
||
is_fetching_my_assets = len(cTB.fetching_asset_data[KEY_TAB_MY_ASSETS]) > 0
|
||
is_fetching_online = len(cTB.fetching_asset_data[KEY_TAB_ONLINE]) > 0
|
||
is_fetching = is_fetching_my_assets or is_fetching_online
|
||
op = col.operator(
|
||
"poliigon.refresh_data",
|
||
text="",
|
||
icon="FILE_REFRESH"
|
||
)
|
||
if is_fetching:
|
||
op.tooltip = _t("Fetching of asset data in progress")
|
||
col.enabled = not is_fetching
|
||
|
||
|
||
def _asset_is_local(cTB, asset_data: AssetData) -> bool:
|
||
"""Checks if asset is local, taking renderer into account for Models."""
|
||
|
||
asset_id = asset_data.asset_id
|
||
if asset_data.asset_type != AssetType.MODEL:
|
||
return cTB._asset_index.check_asset_is_local(asset_id)
|
||
|
||
desired_model_type = ModelType.BLEND
|
||
prefer_blend = cTB.settings["download_prefer_blend"]
|
||
if prefer_blend:
|
||
desired_model_type = ModelType.BLEND
|
||
native_only = True
|
||
else:
|
||
desired_model_type = ModelType.FBX
|
||
native_only = False
|
||
|
||
is_local = cTB._asset_index.check_asset_is_local(
|
||
asset_id,
|
||
model_type=desired_model_type,
|
||
native_only=native_only,
|
||
renderer=None # None is for legacy cycles models w/o engine name
|
||
)
|
||
return is_local
|
||
|
||
|
||
# @timer
|
||
def build_assets(cTB):
|
||
cTB.logger_ui.debug("build_assets")
|
||
|
||
check_dpi(cTB, force=False)
|
||
|
||
area = cTB.settings["area"]
|
||
idx_page_current = cTB.vPage[area]
|
||
|
||
sorted_assets = cTB.f_GetAssetsSorted(idx_page_current)
|
||
cTB.logger_ui.debug(f"build_assets: sorted_assets {len(sorted_assets)}")
|
||
|
||
_draw_page_buttons(cTB, area, idx_page_current, at_top=True)
|
||
|
||
if cTB.is_unlimited_user():
|
||
row = cTB.vBase.row(align=False)
|
||
_build_unlimited_banner(cTB, row)
|
||
|
||
_build_tab_title(cTB)
|
||
|
||
thumb_size_factor = THUMB_SIZE_FACTOR[cTB.settings["thumbsize"]]
|
||
|
||
category = cTB.vActiveCat[0].replace("All ", "")
|
||
if len(cTB.vActiveCat) > 1:
|
||
category = f"{cTB.vActiveCat[-1]} {category}"
|
||
|
||
box_not_found = None
|
||
if len(sorted_assets) == 0:
|
||
box_not_found = _build_assets_no_assets(cTB, area, category)
|
||
else:
|
||
grid, thumb_width, num_columns = _build_assets_prepare_grid(
|
||
cTB, thumb_size_factor, sorted_assets)
|
||
|
||
is_selection = len(bpy.context.selected_objects) > 0
|
||
|
||
# Build Asset Grid ...
|
||
for _asset_id in sorted_assets:
|
||
if _asset_id != 0:
|
||
asset_data = cTB._asset_index.get_asset(_asset_id)
|
||
else:
|
||
asset_data = AssetData(
|
||
0, AssetType.TEXTURE, "dummy", api_convention=0)
|
||
asset_type_data = asset_data.get_type_data()
|
||
asset_name = asset_data.asset_name
|
||
asset_name_display = asset_data.display_name
|
||
asset_type = asset_data.asset_type
|
||
api_convention = asset_data.get_convention()
|
||
|
||
cTB.f_GetPreview(asset_data)
|
||
|
||
is_downloaded = _asset_is_local(cTB, asset_data)
|
||
|
||
size_pref = cTB.get_pref_size(asset_type)
|
||
if asset_type_data is not None: # may happen for dummies
|
||
try:
|
||
size_default = asset_type_data.get_size(
|
||
size_pref,
|
||
local_only=is_downloaded,
|
||
addon_convention=cTB._asset_index.addon_convention,
|
||
local_convention=asset_data.local_convention)
|
||
except KeyError:
|
||
# AssetData's size list seems to be empty
|
||
# This should actually never be the case.
|
||
# Use an arbitrary default, instead.
|
||
|
||
# TODO(Andreas): reporting
|
||
size_default = "2K"
|
||
else:
|
||
size_default = "DUMMY SIZE"
|
||
|
||
sizes_in_scene, size_default = _determine_in_scene_sizes(
|
||
cTB, asset_data, size_default)
|
||
if cTB.settings["download_prefer_blend"]:
|
||
model_type = ModelType.BLEND
|
||
else:
|
||
model_type = ModelType.FBX
|
||
native_only = model_type == ModelType.BLEND
|
||
is_purchased = asset_data.is_purchased
|
||
is_local = cTB._asset_index.check_asset_is_local(
|
||
_asset_id,
|
||
model_type=model_type,
|
||
native_only=native_only,
|
||
renderer=None
|
||
)
|
||
size_default = asset_data.get_current_size(
|
||
size_default,
|
||
local_only=is_local,
|
||
addon_convention=cTB.addon_convention)
|
||
|
||
if asset_type == AssetType.TEXTURE and api_convention >= 1:
|
||
map_prefs = cTB.user.map_preferences
|
||
is_downloaded = asset_type_data.all_expected_maps_local(
|
||
map_prefs, size=size_default)
|
||
|
||
cell = grid.column(align=True)
|
||
box_thumb = cell.box().column()
|
||
|
||
name_row = box_thumb.row(align=True)
|
||
ui_label = "" if "dummy" in asset_name.lower() else asset_name_display
|
||
name_row.label(text=ui_label)
|
||
name_row.scale_y = 0.8
|
||
name_row.alignment = "CENTER"
|
||
name_row.enabled = False # To fade label for less contrast.
|
||
|
||
_draw_thumbnail(cTB, asset_data, thumb_size_factor, box_thumb)
|
||
|
||
# See if there's any errors associated with this asset,
|
||
# such as after or during purchase/download failure.
|
||
error = None
|
||
if asset_data.state.dl.has_error():
|
||
error = asset_data.state.dl.error
|
||
if asset_data.state.purchase.has_error():
|
||
error = asset_data.state.purchase.error
|
||
|
||
row = cell.row(align=True)
|
||
|
||
if asset_name == "dummy":
|
||
_draw_thumb_state_asset_dummy(row)
|
||
elif asset_data.state.purchase.is_in_progress():
|
||
_draw_thumb_state_asset_purchasing(row, asset_data)
|
||
elif asset_data.state.dl.is_cancelled():
|
||
_draw_thumb_state_cancelling_download(row, asset_data)
|
||
elif asset_data.state.dl.is_in_progress():
|
||
_draw_thumb_state_asset_downloading(
|
||
row, asset_data, thumb_width)
|
||
elif area in [KEY_TAB_ONLINE, KEY_TAB_MY_ASSETS]:
|
||
is_tex = asset_type == AssetType.TEXTURE
|
||
is_local = asset_data.is_local
|
||
if cTB.is_unlimited_user() and is_local:
|
||
_draw_checkmark_unlimited(cTB, row)
|
||
elif cTB.is_unlimited_user():
|
||
# No need for green checkmark or wm preview if unlimited
|
||
pass
|
||
elif is_tex and not is_purchased:
|
||
_draw_button_quick_preview(
|
||
cTB, row, asset_data, is_selection)
|
||
elif is_purchased and area == KEY_TAB_ONLINE:
|
||
_draw_checkmark_purchased(cTB, row)
|
||
|
||
if is_purchased or cTB.is_unlimited_user():
|
||
if is_downloaded:
|
||
if asset_type == AssetType.MODEL:
|
||
_draw_button_model_local(
|
||
cTB, row, asset_data, error)
|
||
elif asset_type == AssetType.TEXTURE:
|
||
_draw_button_texture_local(
|
||
cTB,
|
||
row,
|
||
asset_data,
|
||
error,
|
||
sizes_in_scene,
|
||
size_default,
|
||
is_selection)
|
||
elif asset_type == AssetType.HDRI:
|
||
_draw_button_hdri_local(
|
||
cTB, row, asset_data, error, size_default)
|
||
else:
|
||
if not check_convention(asset_data):
|
||
_draw_button_unsupported_convention(row)
|
||
else:
|
||
_draw_button_download(
|
||
cTB, row, asset_data, error, size_default)
|
||
else:
|
||
if not check_convention(asset_data):
|
||
_draw_button_unsupported_convention(row)
|
||
else:
|
||
_draw_button_purchase(
|
||
cTB, row, asset_data, error, size_default)
|
||
|
||
if is_downloaded or check_convention(asset_data):
|
||
_draw_button_quick_menu(row, asset_data)
|
||
|
||
elif area == KEY_TAB_IMPORTED:
|
||
if asset_name == "dummy":
|
||
_draw_thumb_state_asset_dummy(row)
|
||
elif asset_type == AssetType.MODEL:
|
||
_draw_button_model_local(
|
||
cTB, row, asset_data, error)
|
||
elif asset_type == AssetType.TEXTURE:
|
||
_draw_button_texture_local(
|
||
cTB,
|
||
row,
|
||
asset_data,
|
||
error,
|
||
sizes_in_scene,
|
||
size_default,
|
||
is_selection)
|
||
elif asset_type == AssetType.HDRI:
|
||
_draw_button_hdri_local(
|
||
cTB, row, asset_data, error, size_default)
|
||
|
||
_draw_button_quick_menu(row, asset_data)
|
||
|
||
cell.separator()
|
||
|
||
_draw_missing_grid_dummies(
|
||
cTB, grid, sorted_assets, num_columns, thumb_width)
|
||
|
||
_draw_page_buttons(cTB, area, idx_page_current)
|
||
|
||
if area == KEY_TAB_MY_ASSETS:
|
||
_draw_view_more_my_assets(cTB, box_not_found)
|
||
elif area == KEY_TAB_IMPORTED:
|
||
_draw_view_more_imported(cTB, sorted_assets)
|