33 Fetch MaterialX assets from PolyHaven API and filter them by resolution.
34 @param resolution: The resolution of the MaterialX assets to fetch (e.g. "1k", "2k", "4k", "8k").
35 @return: A dictionary of MaterialX assets with their URLs and texture files.
42 resp.raise_for_status()
43 all_assets = resp.json()
46 filtered_polyhaven_assets = {}
49 for id, data
in all_assets.items():
51 if download_id
and id != download_id:
56 thumbnail_url = data.get(
"thumbnail_url")
58 resp = requests.get(f
"{self.FILES_API}/{id}", headers=self.
HEADERS)
59 resp.raise_for_status()
60 files_data = resp.json()
64 files_data = {k: v
for k, v
in files_data.items()
if k ==
"mtlx"}
66 mtlx_files = files_data.get(
"mtlx", [])
69 self.
logger.info(f
"Found MaterialX data for '{id}'")
78 for resolution_key
in resolutions.keys():
79 res = mtlx_files.get(resolution_key,
None)
83 n_k_mtlx = res.get(
"mtlx")
87 include_files = n_k_mtlx.get(
"include", {})
89 for path, data
in include_files.items():
90 texture_url = data.get(
"url")
92 texture_struct[path] = texture_url
93 mtlx_url = n_k_mtlx.get(
"url")
94 res_id = id +
'___' + resolution_key
96 materialx_assets[res_id] = {
98 "texture_files": texture_struct,
99 "thumbnail_url": thumbnail_url
101 json_string = json.dumps(materialx_assets[res_id], indent=4)
111 filtered_polyhaven_assets[id] = files_data
114 if download_id == id:
118 if not download_id
and max_items:
120 if item_count >= max_items:
126 return materialx_assets, all_assets, filtered_polyhaven_assets
130 Download MaterialX asset and its textures from PolyHaven.
131 e.g. asset_list = {'polystyrene': {'url': 'https://.../polystyrene.mtlx', 'texture_files': {...}}}
133 @param asset_list: A dictionary of MaterialX assets with their URLs and texture files.
134 @return: The ID of the downloaded asset, the MaterialX string, and a list of texture binaries.
136 for id, asset
in asset_list.items():
137 url = asset.get(
"url")
139 self.
logger.info(f
"No MaterialX URL found for '{id}'")
142 resp = requests.get(url, headers=self.
HEADERS)
143 resp.raise_for_status()
144 mtlx_string = resp.text
145 self.
logger.info(f
"Download MaterialX document {url}, length: {len(mtlx_string)} characters")
147 texture_binaries = []
148 for path, texture_url
in asset.get(
"texture_files", {}).items():
150 self.
logger.info(f
"Download texture from {texture_url} ...")
151 texture_resp = requests.get(texture_url, headers=self.
HEADERS)
152 texture_resp.raise_for_status()
154 ext = Path(path).suffix.lower()
155 name = Path(path).stem
158 self.
logger.info(f
" WARNING: EXR file present which may not be supported by MaterialX texture loader: {path}")
159 texture_binaries.append((path, texture_resp.content))
161 thumbnail_url = asset.get(
"thumbnail_url")
163 self.
logger.info(f
"Download thumbnail from {thumbnail_url} ...")
164 thumbnail_resp = requests.get(thumbnail_url, headers=self.
HEADERS)
165 thumbnail_resp.raise_for_status()
167 clean_url = thumbnail_url
169 clean_url = clean_url.split(
'?')[0].split(
'#')[0]
170 clean_url = clean_url.split(
'/')[-1]
171 extension = Path(clean_url).suffix.lower()
172 texture_binaries.append((f
"{id}_thumbnail.{extension}", thumbnail_resp.content))
174 return id, mtlx_string, texture_binaries
178 Save MaterialX string and texture binaries to a zip file.'
179 @param id: The ID of the MaterialX asset.
180 @param mtlx_string: The MaterialX string content.
181 @param texture_binaries: A list of tuples containing texture file paths and their binary content.
182 @param data_folder: The folder to save the zip file.
185 filename = f
"{id}_materialx.zip"
186 filename = Path(data_folder) / filename
187 with zipfile.ZipFile(filename,
"w")
as zipf:
189 zipf.writestr(f
"{id}.mtlx", mtlx_string)
191 for path, content
in texture_binaries:
192 zipf.writestr(path, content)
193 self.
logger.info(f
"Saved zip: {filename}")