MaterialXMaterials 1.39.5
Utilities for retrieving materials from remote servers
Loading...
Searching...
No Matches
JsGPUOpenLoader.js
1
13 if (JsGPUOpenMaterialLoader.instance) {
14 return JsGPUOpenMaterialLoader.instance;
15 }
16
17 this.rootUrl = 'https://api.matlib.gpuopen.com/api';
18 this.url = `${this.rootUrl}/materials`;
19 this.packageUrl = `${this.rootUrl}/packages`;
20 this.materials = null;
21 this.materialNames = null;
22
23 this.logger = console;
24
25 // Cache the instance
26 JsGPUOpenMaterialLoader.instance = this;
27 }
28
34 return this.materials;
35 }
36
42 return this.materialNames;
43 }
44
50 async getMaterials(batchSize = 50) {
51
52 /*
53 * Get the materials returned from the GPUOpen material database.
54 * Will loop based on the linked-list of materials stored in the database.
55 * Currently, the batch size requested is 100 materials per batch.
56 * @param batchSize: Number of materials to fetch per batch
57 * @return: List of material lists
58 */
59
60 this.materials = [];
61 this.materialNames = [];
62
63 let url = this.url;
64
65 // Get batches of materials. Start with the first N.
66 let params = new URLSearchParams({
67 limit: batchSize,
68 offset: 0
69 });
70
71 // Append & parameters to url using params
72 if (params) {
73 url += '?' + params.toString();
74 }
75
76 let haveMoreMaterials = true;
77 while (haveMoreMaterials)
78 {
79 try {
80
81 console.log('- Fetch material infoormation from url:', url)
82
83 const response = await fetch(url);
84
85 if (!response.ok) {
86 throw new Error(`HTTP error! status: ${response.status}`);
87 }
88
89 const jsonData = await response.json();
90 this.materials.push(jsonData)
91
92 for (const material of jsonData.results) {
93 this.materialNames.push(material['title']);
94 }
95
96 //console.log("Number of materials fetched:", jsonData.results.length)
97
98 let nextURL = jsonData.next
99 if (nextURL) {
100 //console.log('Next URL: ', jsonData.next)
101 url = nextURL;
102 haveMoreMaterials = true
103 }
104 else
105 {
106 console.log('Finished fetching materials')
107 haveMoreMaterials = false;
108 break;
109 }
110
111 } catch (error) {
112 this.logger.info(`Error: ${error.message}`);
113 haveMoreMaterials = true;
114 }
115 }
116
117 return this.materials;
118 }
119
127 async downloadPackage(listNumber, materialNumber, packageId = 0) {
128 if (this.materials === null || this.materials.length === 0) {
129 console.error('No materials available. Please fetch materials first.');
130 return [null, null];
131 }
132
133 const jsonData = this.materials[listNumber];
134 if (!jsonData) {
135 console.error('Invalid list number:', listNumber);
136 return [null, null];
137 }
138
139 let jsonResults = null;
140 let jsonResult = null;
141 if ('results' in jsonData) {
142 jsonResults = jsonData['results'];
143 if (jsonResults.length <= materialNumber) {
144 console.error('Invalid material number:', materialNumber);
145 return [null, null];
146 } else {
147 jsonResult = jsonResults[materialNumber];
148 }
149 }
150
151 if (!jsonResult) {
152 console.error('Material not found for list number:', listNumber, ' material number:', materialNumber);
153 return [null, null];
154 }
155
156 let jsonPackages = null;
157 if ('packages' in jsonResult) {
158 jsonPackages = jsonResult['packages'];
159 }
160 if (!jsonPackages) {
161 console.error('No packages found for material:', jsonResult['title']);
162 return [null, null];
163 }
164
165 if (jsonPackages.length <= packageId) {
166 console.error('Invalid package ID:', packageId, ' for material:', jsonResult['title']);
167 return [null, null];
168 }
169 const packageIdValue = jsonPackages[packageId];
170
171 if (!packageIdValue) {
172 console.error('Package ID not found for material:', jsonResult['title'], ' package index:', packageId);
173 return [null, null];
174 }
175
176 const url = `${this.packageUrl}/${packageIdValue}/download`;
177 const response = await fetch(url);
178 const data = await response.arrayBuffer();
179 const title = jsonResult['title'];
180
181 console.log(`- Loader: Downloaded package: ${title} from ${url}`);
182 return [data, title];
183 }
184
191 findMaterialsByName(materialName)
192 {
193 if (!this.materials) {
194 return [];
195 }
196
197 const materialsList = [];
198 let listNumber = 0;
199
200 // Create a RegExp object for case-insensitive matching
201 const regex = new RegExp(materialName, 'i');
202
203 this.materials.forEach((materialList, materialIndex) => {
204 let materialNumber = 0;
205
206 materialList['results'].forEach((material) => {
207
208 //console.log('testing material:', material['title'], ' with regex:', regex)
209 if (regex.test(material['title'])) {
210 materialsList.push({
211 listNumber: listNumber,
212 materialNumber: materialNumber,
213 title: material['title'],
214 });
215 }
216 materialNumber += 1;
217 });
218
219 listNumber += 1;
220 });
221
222 return materialsList;
223 }
224
233 async downloadPackageByExpression(searchExpr, packageId = 0) {
234 const downloadList = [];
235
236 const foundList = this.findMaterialsByName(searchExpr);
237 if (foundList.length > 0) {
238 for (const found of foundList) {
239 const listNumber = found['listNumber'];
240 const materialNumber = found['materialNumber'];
241 const matName = found['title'];
242 this.logger.info(`> Download material: ${matName} List: ${listNumber}. Index: ${materialNumber}`);
243 const [data, title] = await this.downloadPackage(listNumber, materialNumber, packageId);
244 downloadList.push([data, title]);
245 }
246 }
247 return downloadList;
248 }
249}
250
251// Export a singleton instance of the class
252module.exports = new JsGPUOpenMaterialLoader();
253
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.