From 0a9f18240ee26f317844e296806573c7935932e9 Mon Sep 17 00:00:00 2001 From: rmn20 Date: Sun, 7 Jun 2026 16:27:01 +0300 Subject: [PATCH] Added notexblend, noassetsfolders, noresfolders, notexfolders arguments notexblend disables downloading of .blend files for textures noassetsfolders disables separate folders for each asset noresfolders disables separate folders for each texture resolution notexfolders disables creation of "textures" folder --- polydown/__main__.py | 24 +++++++++++++ polydown/cli.py | 8 +++++ polydown/controller.py | 78 ++++++++++++++++++++++++++++++++---------- 3 files changed, 92 insertions(+), 18 deletions(-) diff --git a/polydown/__main__.py b/polydown/__main__.py index 52ce1db..0c79e25 100644 --- a/polydown/__main__.py +++ b/polydown/__main__.py @@ -106,6 +106,30 @@ default=None, help="maps to download (e.g. diffuse, rough, arm, etc). If used without values, lists available common map types.", ) +ap.add_argument( + "--notexblend", + action="store_true", + default=False, + help="Do not download blend files for granular textures.", +) +ap.add_argument( + "--noassetsfolders", + action="store_true", + default=False, + help="Do not create assets subfolders.", +) +ap.add_argument( + "--noresfolders", + action="store_true", + default=False, + help="Do not create folders for different texture resolutions.", +) +ap.add_argument( + "--notexfolders", + action="store_true", + default=False, + help="Do not create \"textures\" folder.", +) args = ap.parse_args() diff --git a/polydown/cli.py b/polydown/cli.py index 82caa54..e17f201 100644 --- a/polydown/cli.py +++ b/polydown/cli.py @@ -27,6 +27,10 @@ async def _async_polycli(args): texture_format = args.texture_format maps = args.maps model_format = args.model_format + notexblend = args.notexblend + noassetsfolders = args.noassetsfolders + noresfolders = args.noresfolders + notexfolders = args.notexfolders # Validation Phase async with aiohttp.ClientSession() as session: @@ -120,6 +124,10 @@ async def _async_polycli(args): iters=iter_limit, tone=tone, fileformat=fileformat, + notexblend=notexblend, + noassetsfolders=noassetsfolders, + noresfolders=noresfolders, + notexfolders=notexfolders, texture_format=args.texture_format, maps=args.maps, model_format=model_format, diff --git a/polydown/controller.py b/polydown/controller.py index ea637cc..58950ee 100644 --- a/polydown/controller.py +++ b/polydown/controller.py @@ -35,6 +35,10 @@ async def start( noimgs: bool, iters: Optional[int], tone: bool, + notexblend: bool, + noassetsfolders: bool, + noresfolders: bool, + notexfolders: bool, fileformat: Optional[str], texture_format: Optional[str] = None, maps: Optional[List[str]] = None, @@ -66,8 +70,10 @@ async def process_asset(asset_id): files_data = await client.get_files(asset_id) new_tasks = self._generate_tasks( asset_type, asset_id, files_data, folder, sizes, - overwrite, noimgs, tone, fileformat, - texture_format, maps, model_format + overwrite, noimgs, tone, notexblend, + noassetsfolders, noresfolders, notexfolders, + fileformat, + texture_format, maps, model_format, ) tasks.extend(new_tasks) except Exception as e: @@ -197,6 +203,10 @@ def _generate_tasks( overwrite: bool, noimgs: bool, tone: bool, + notexblend: bool, + noassetsfolders: bool, + noresfolders: bool, + notexfolders: bool, fileformat: Optional[str], texture_format: Optional[str] = None, maps: Optional[List[str]] = None, @@ -206,33 +216,57 @@ def _generate_tasks( if asset_type == "hdris": tasks.extend(self._generate_hdri_tasks( - asset_id, data, root_folder, target_sizes, overwrite, noimgs, tone, fileformat + asset_id, data, root_folder, target_sizes, overwrite, noimgs, tone, + noassetsfolders, noresfolders, notexfolders, + fileformat )) elif asset_type in ["textures", "models"]: tasks.extend(self._generate_texture_tasks( asset_id, data, root_folder, target_sizes, overwrite, noimgs, tone, - texture_format, maps, asset_type, model_format + notexblend, noassetsfolders, noresfolders, notexfolders, texture_format, + maps, asset_type, model_format, )) return tasks - def _generate_texture_tasks(self, asset_id, data, root_folder, target_sizes, overwrite, noimgs, tone, texture_format, maps, asset_type="textures", model_format=None): + def _generate_texture_tasks( + self, + asset_id, + data, + root_folder, + target_sizes, + overwrite, + noimgs, + tone, + notexblend, + noassetsfolders, + noresfolders, + notexfolders, + texture_format, + maps, + asset_type="textures", + model_format=None, + ): tasks = [] # If no specific texture args are provided, fallback to default behavior (downloading model bundle) if not texture_format and not maps: return self._generate_model_tasks( asset_id, data, root_folder, target_sizes, overwrite, noimgs, tone, + noassetsfolders, noresfolders, notexfolders, asset_type=asset_type, model_format=model_format, ) - # Logic for Granular Textures - # Always attempt to download the model file (but without its default texture dependencies) - tasks.extend(self._generate_model_tasks( - asset_id, data, root_folder, target_sizes, overwrite, - noimgs=True, tone=tone, asset_type=asset_type, - include_model_textures=False, model_format=model_format, - )) + if not notexblend: + # Logic for Granular Textures + # Always attempt to download the model file (but without its default texture dependencies) + tasks.extend(self._generate_model_tasks( + asset_id, data, root_folder, target_sizes, overwrite, + noimgs=True, tone=tone, noassetsfolders=noassetsfolders, + noresfolders=noresfolders, notexfolders=notexfolders, + asset_type=asset_type, include_model_textures=False, + model_format=model_format, + )) # Filter out non-map keys ignored_keys = {'blend', 'gltf', 'mtlx', 'zip'} @@ -243,6 +277,9 @@ def _generate_texture_tasks(self, asset_id, data, root_folder, target_sizes, ove wanted_maps_lower = [m.lower() for m in maps] available_maps = [m for m in available_maps if m.lower() in wanted_maps_lower] + asset_folder = root_folder + if not noassetsfolders: asset_folder = os.path.join(asset_folder, asset_id) + for map_name in available_maps: if map_name not in data: continue @@ -273,7 +310,9 @@ def _generate_texture_tasks(self, asset_id, data, root_folder, target_sizes, ove filename = url.split('/')[-1] # Store in a subfolder structure: asset_id/size/textures to match standard behavior - dest_folder = os.path.join(root_folder, asset_id, f"{asset_id}_{size}", "textures") + dest_folder = asset_folder + if not noresfolders: dest_folder = os.path.join(dest_folder, f"{asset_id}_{size}") + if not notexfolders: dest_folder = os.path.join(dest_folder, "textures") tasks.append(DownloadTask( url=url, @@ -284,19 +323,20 @@ def _generate_texture_tasks(self, asset_id, data, root_folder, target_sizes, ove )) if not noimgs: - image_folder = os.path.join(root_folder, asset_id) - tasks.extend(self._get_image_tasks(asset_type, asset_id, image_folder, overwrite, tone)) + tasks.extend(self._get_image_tasks(asset_type, asset_id, asset_folder, overwrite, tone)) return tasks def _generate_model_tasks( self, asset_id, data, root_folder, target_sizes, overwrite, noimgs, tone, + noassetsfolders, noresfolders, notexfolders, asset_type="models", include_model_textures=True, model_format=None, ): tasks = [] formats = model_format or ["blend"] - asset_folder = os.path.join(root_folder, asset_id) + asset_folder = root_folder + if not noassetsfolders: asset_folder = os.path.join(asset_folder, asset_id) for fmt in formats: fmt_data = data.get(fmt, {}) @@ -307,8 +347,10 @@ def _generate_model_tasks( if target_sizes and size not in target_sizes: continue - size_folder = os.path.join(asset_folder, f"{asset_id}_{size}") - textures_folder = os.path.join(size_folder, "textures") + size_folder = asset_folder + if not noresfolders: size_folder = os.path.join(size_folder, f"{asset_id}_{size}") + textures_folder = size_folder + if not notexfolders: textures_folder = os.path.join(textures_folder, "textures") file_info = content.get(fmt) if not file_info or 'url' not in file_info: