1const axios = require(
'axios');
2const fs = require(
'fs');
3const { Writable } = require(
'stream');
4const { createGunzip } = require(
'zlib');
5const { parse } = require(
'csv-parse/sync');
15 this.logger = console;
18 this.materials =
null;
19 this.materialNames = [];
20 this.csvMaterials =
null;
21 this.downloadMaterial =
null;
22 this.downloadMaterialFileName =
'';
24 this.stdlib = mxStdlib;
25 this.supportOpenPBR =
false;
28 this.logger.error(
'MaterialX module not specified.');
33 const version = this.mx.getVersionIntegers();
34 this.logger.info(`Using MaterialX version: ${version.join(
'.')}`);
35 if (version[0] >= 1 && version[1] >= 39) || version[0] > 1) {
36 this.logger.debug(
'OpenPBR shading model supported');
37 this.supportOpenPBR =
true;
42 this.stdlib = this.mx.createDocument();
43 const libFiles = this.mx.loadLibraries(this.mx.getDefaultDataLibraryFolders(),
this.mx.getDefaultDataSearchPath(),
this.stdlib);
44 this.logger.debug(`Loaded standard library: ${libFiles}`);
53 this.logger.level = debug ?
'debug' :
'info';
62 this.materialNames = [];
63 const uniqueNames =
new Set();
65 this.materials.forEach(item => uniqueNames.add(item[key]));
67 this.materialNames = Array.from(uniqueNames).sort();
68 return this.materialNames;
77 this.logger.info(`Writing material list to file: ${filename}`);
78 fs.writeFileSync(filename, JSON.stringify(materialList,
null, 4));
88 return `${imageResolution}K-${imageFormat}`;
97 filename: this.downloadMaterialFileName,
98 content: this.downloadMaterial
106 if (this.downloadMaterial) {
107 this.downloadMaterial =
null;
109 this.downloadMaterialFileName =
'';
117 const haveDownload = this.downloadMaterialFileName && this.downloadMaterial;
119 this.logger.warning(
'No current material downloaded');
123 const filename = `${path}/${this.downloadMaterialFileName}`;
124 fs.writeFileSync(filename, this.downloadMaterial);
125 this.logger.info(`Saved downloaded material to: ${filename}`);
128 async
downloadMaterialAsset(assetId, imageFormat =
'PNG', imageResolution =
'1', downloadAttributeKey =
'downloadAttribute', downloadLinkKey =
'downloadLink') {
143 let downloadAttribute =
'';
145 items.forEach(item => {
146 downloadAttribute = item[downloadAttributeKey];
147 if (downloadAttribute === target) {
148 url = item[downloadLinkKey];
149 this.logger.info(`Found Asset: ${assetId}. Download Attribute: ${downloadAttribute} -> ${url}`);
154 this.logger.error(`No download link found
for asset: ${assetId}, attribute: ${target}`);
158 this.downloadMaterialFileName = url.split(
'file=')[1];
161 const response = await axios.get(url, { responseType:
'arraybuffer' });
162 this.downloadMaterial = Buffer.from(response.data,
'binary');
163 this.logger.info(`Material file downloaded: ${this.downloadMaterialFileName}`);
165 this.downloadMaterialFileName =
'';
166 this.logger.error(`Error occurred
while downloading the file: ${error}`);
169 return this.downloadMaterialFileName;
179 if (this.materials) {
180 return this.materials.filter(item => item[key] === assetId);
191 this.materials = JSON.parse(fs.readFileSync(fileName,
'utf8'));
192 this.logger.info(`Loaded materials list from: ${fileName}`);
193 return this.materials;
201 const url =
'https://ambientCG.com/api/v2/downloads_csv';
202 const headers = { Accept:
'application/csv' };
204 method:
'PBRPhotogrammetry',
209 this.logger.info(
'Downloading materials CSV list...');
211 const response = await axios.get(url, { headers, params });
212 if (response.status === 200) {
213 const csvContent = response.data;
214 this.csvMaterials = csvContent;
216 this.logger.info(
'Downloaded CSV material list as JSON.');
218 this.materials =
null;
219 this.logger.warning(`Failed to fetch the CSV material content. HTTP status code: ${response.status}`);
222 this.materials =
null;
223 this.logger.error(`Error downloading materials list: ${error}`);
226 return this.materials;
234 return this.database;
253 const url =
'https://ambientcg.com/api/v2/full_json';
254 const headers = { Accept:
'application/json' };
256 method:
'PBRPhotogrammetry',
262 const response = await axios.get(url, { headers, params });
263 if (response.status === 200) {
264 this.database = response.data;
265 this.assets = this.database.foundAssets;
267 this.logger.error(`Status: ${response.status}, ${response.data}`);
270 this.logger.error(`Error downloading asset database: ${error}`);
273 return this.database;
282 if (!this.database) {
283 this.logger.warning(
'No database to write');
287 fs.writeFileSync(filename, JSON.stringify(
this.database,
null, 4));
298 this.logger.error(
'MaterialX module is required');
303 this.logger.warning(
'MaterialX document is required');
307 const valid = doc.validate();
308 return [valid, valid ?
'' :
'Validation failed'];
317 const comment = doc.addChildOfCategory(
'comment');
318 comment.setDocString(commentString);
328 this.logger.error(
'MaterialX module is required');
332 const writeOptions = this.mx.XmlWriteOptions();
333 writeOptions.writeXIncludeEnable =
false;
334 writeOptions.elementPredicate = this.skipLibraryElement;
335 return this.mx.writeToXmlString(doc, writeOptions);
validateMaterialXDocument(doc)
buildDownloadAttribute(imageFormat='PNG', imageResolution='1')
async downloadMaterialAsset(assetId, imageFormat='PNG', imageResolution='1', downloadAttributeKey='downloadAttribute', downloadLinkKey='downloadLink')
async downloadAssetDatabase()
getDataBaseMaterialList()
writeDownloadedMaterialToFile(path='')
addComment(doc, commentString)
getDownloadedMaterialInformation()
constructor(mxModule, mxStdlib=null)
Class to load materials from the AmbientCG site.
findMaterial(assetId, key='assetId')
getMaterialNames(key='assetId')
writeDatabaseToFile(filename)
loadMaterialsList(fileName)
writeMaterialList(materialList, filename)
async downloadMaterialsList()