Hi Pascal,
Here is a snippet of code that allows to search for a 3D.io furniture, download it and convert it to obj to finally save it on your server! Hope you will find some part of the code helpful for you!
Cheers, Julien
// Packages Used
import io3d from ‘3dio’;
import { ArcRotateCamera, Vector3, StandardMaterial, NullEngine, Scene, Mesh, VertexData } from ‘babylonjs’;
import { OBJExport } from ‘babylonjs-serializers’;
import axios from ‘axios’;
// ExpressJS Route
router.get('/download/:furniture', async (req, res) => {
try {
const { furniture = 'Plywood DCW' } = req.params;
console.log('Search for:', furniture);
const saveFile = async (name, file, type) => {
try {
if (!file) return;
const filePath = `models/${name}.${type}`;
if (type === 'jpg') {
const stream = fs.createWriteStream(filePath);
const response = await axios({ url: file, method: 'GET', responseType: 'stream' });
await response.data.pipe(stream);
} else {
fs.writeFile(filePath, file, (err) => { if (err) throw err; });
}
} catch (error) {
console.log(error);
}
};
const objects = await io3d.furniture.search(furniture, { limit: 1 });
const objectsCount = objects.length;
const engine = new NullEngine();
const objectsData = await Promise.all(objects.map(async (object, index) => {
const { name, description, designer } = objects[index];
const { meshes, materials } = await io3d.utils.data3d.load(object.data3dUrl);
const mesh = await Promise.all(Object.keys(meshes).map(async (meshId) => {
const { positions, normals, uvs } = meshes[meshId];
const indices = [...Array(positions.length / 3).keys()];
const scene = new Scene(engine);
const mesh = new Mesh(name, scene);
const vertexData = new VertexData();
const positionsFormat = Array.prototype.slice.call(positions);
const normalsFormat = Array.prototype.slice.call(normals);
const uvsFormat = Array.prototype.slice.call(uvs);
vertexData.positions = positionsFormat;
vertexData.indices = indices;
vertexData.normals = normalsFormat;
vertexData.uvs = uvsFormat;
vertexData.applyToMesh(mesh);
const material = new StandardMaterial('material', scene);
mesh.material = material;
const OBJFile = OBJExport.OBJ([mesh]);
const hello = positions.toString() + normals.toString() + uvs.toString();
await saveFile('text', hello, 'txt');
Object.keys(materials).forEach(async (materialId) => {
const { mapDiffuseSource = null, mapNormalSource = null, mapSpecularSource = null } =
materials[materialId];
await saveFile(`${name}_diffuse`, mapDiffuseSource, 'jpg');
await saveFile(`${name}_normal`, mapNormalSource, 'jpg');
await saveFile(`${name}_specular`, mapSpecularSource, 'jpg');
});
saveFile(name, OBJFile, 'obj');
return { positions: positionsFormat, normals: normalsFormat, uvs: uvsFormat, indices };
}));
return { ...mesh[0] };
// return { name, designer, description, mesh };
}));
console.log('File saved:', objectsData.name);
const data = objectsData[0];
const json = Buffer.from(JSON.stringify(data), 'ascii').toString('base64');
res.send(json);
// res.send({ count: objectsCount, objects: objectsData });
} catch (error) {
console.log('Error', error);
res.status(502).send({ message: 'Error', error });
}
});