MaterialXMaterials 0.0.1
Utilities for retrieving materials from remote servers
Loading...
Searching...
No Matches
JsGPUOpenLoader.js
1
13 this.rootUrl = 'https://api.matlib.gpuopen.com/api';
14 this.url = `${this.rootUrl}/materials`;
15 this.packageUrl = `${this.rootUrl}/packages`;
16 this.materials = null;
17 this.materialNames = null;
18
19 this.logger = console;
20 }
21
27 return this.materials;
28 }
29
35 return this.materialNames;
36 }
37
43 async getMaterials(batchSize = 50) {
44
45 const fetch = (await import('node-fetch')).default;
46
47 /*
48 * Get the materials returned from the GPUOpen material database.
49 * Will loop based on the linked-list of materials stored in the database.
50 * Currently, the batch size requested is 100 materials per batch.
51 * @param batchSize: Number of materials to fetch per batch
52 * @return: List of material lists
53 */
54
55 this.materials = [];
56 this.materialNames = [];
57
58 let url = this.url;
59
60 // Get batches of materials. Start with the first N.
61 let params = new URLSearchParams({
62 limit: batchSize,
63 offset: 0
64 });
65
66 // Append & parameters to url using params
67 if (params) {
68 url += '?' + params.toString();
69 }
70
71 let haveMoreMaterials = true;
72 while (haveMoreMaterials)
73 {
74 try {
75
76 console.log('Fetch materials from url:', url)
77
78 const response = await fetch(url);
79
80 if (!response.ok) {
81 throw new Error(`HTTP error! status: ${response.status}`);
82 }
83
84 const jsonData = await response.json();
85 this.materials.push(jsonData)
86
87 for (const material of jsonData.results) {
88 this.materialNames.push(material['title']);
89 }
90
91 //console.log("Number of materials fetched:", jsonData.results.length)
92
93 let nextURL = jsonData.next
94 if (nextURL) {
95 //console.log('Next URL: ', jsonData.next)
96 url = nextURL;
97 haveMoreMaterials = true
98 }
99 else
100 {
101 console.log('Finished fetching materials')
102 haveMoreMaterials = false;
103 break;
104 }
105
106 } catch (error) {
107 this.logger.info(`Error: ${error.message}`);
108 haveMoreMaterials = true;
109 }
110 }
111
112 return this.materials;
113 }
114
122 async downloadPackage(listNumber, materialNumber, packageId = 0) {
123 if (this.materials === null || this.materials.length === 0) {
124 return [null, null];
125 }
126
127 const jsonData = this.materials[listNumber];
128 if (!jsonData) {
129 return [null, null];
130 }
131
132 let jsonResults = null;
133 let jsonResult = null;
134 if ('results' in jsonData) {
135 jsonResults = jsonData['results'];
136 if (jsonResults.length <= materialNumber) {
137 return [null, null];
138 } else {
139 jsonResult = jsonResults[materialNumber];
140 }
141 }
142
143 if (!jsonResult) {
144 return [null, null];
145 }
146
147 let jsonPackages = null;
148 if ('packages' in jsonResult) {
149 jsonPackages = jsonResult['packages'];
150 }
151 if (!jsonPackages) {
152 return [null, null];
153 }
154
155 if (jsonPackages.length <= packageId) {
156 return [null, null];
157 }
158 const packageIdValue = jsonPackages[packageId];
159
160 if (!packageIdValue) {
161 return [null, null];
162 }
163
164 const fetch = (await import('node-fetch')).default;
165
166 const url = `${this.packageUrl}/${packageIdValue}/download`;
167 const response = await fetch(url);
168 const data = await response.arrayBuffer();
169 const title = jsonResult['title'];
170
171 console.log(`Downloaded package: ${title} from ${url}`);
172 //console.log(`Package size: ${data.byteLength} bytes`);
173 return [data, title];
174 }
175
182 findMaterialsByName(materialName)
183 {
184 if (!this.materials) {
185 return [];
186 }
187
188 const materialsList = [];
189 let listNumber = 0;
190
191 // Create a RegExp object for case-insensitive matching
192 const regex = new RegExp(materialName, 'i');
193
194 this.materials.forEach((materialList, materialIndex) => {
195 let materialNumber = 0;
196
197 materialList['results'].forEach((material) => {
198
199 //console.log('testing material:', material['title'], ' with regex:', regex)
200 if (regex.test(material['title'])) {
201 materialsList.push({
202 listNumber: listNumber,
203 materialNumber: materialNumber,
204 title: material['title'],
205 });
206 }
207 materialNumber += 1;
208 });
209
210 listNumber += 1;
211 });
212
213 return materialsList;
214 }
215
224 async downloadPackageByExpression(searchExpr, packageId = 0) {
225 const downloadList = [];
226
227 const foundList = this.findMaterialsByName(searchExpr);
228 if (foundList.length > 0) {
229 for (const found of foundList) {
230 const listNumber = found['listNumber'];
231 const materialNumber = found['materialNumber'];
232 const matName = found['title'];
233 this.logger.info(`> Download material: ${matName} List: ${listNumber}. Index: ${materialNumber}`);
234 const [data, title] = await this.downloadPackage(listNumber, materialNumber, packageId);
235 downloadList.push([data, title]);
236 }
237 }
238 return downloadList;
239 }
240}
241
242module.exports = { JsGPUOpenMaterialLoader };
Class to download MaterialX materials from the GPUOpen material database.
async getMaterials(batchSize=50)
Get lists of materials from the GPUOpen material database.
async downloadPackage(listNumber, materialNumber, packageId=0)
Download a material package from the GPUOpen material database.
findMaterialsByName(materialName)
Find materials by name.
getMaterialList()
Return downloaded material list.
getMaterialNames()
Return downloaded material names.
constructor()
Constructor for the JsGPUOpenMaterialLoader class.
async downloadPackageByExpression(searchExpr, packageId=0)
Download a material package by string expression.