Hi Everyone,
I’m doing this web app in react and I use Rhino3dmLoader to load the rhino file. I’m creating this feature where I can add objects from the app and then save a new rhino file back without losing any information. In this new file all the objects are meshes and I was able to save almost everything. My problem is when I have some surfaces with images mapped into it. So I was not able to save the textures back and when I reload the app and load the new updated 3d, everything is there except the textures mapped. Here is a bit of my code so it helps you guys understand my issue.
const preserveObjects = (doc, rhino) => {
const existingObjects = threeProps.rhinoObject.children;
for (let i = 0; i < existingObjects.length; i++) {
const rhinoObject = existingObjects[i];
// Extract geometry and convert it to Rhino mesh
if (rhinoObject.type === 'Mesh') {
const bufferGeometry = rhinoObject.geometry;
// Create a Rhino mesh
const rhinoMesh = new rhino.Mesh();
// Add vertices to Rhino mesh
const vertices = bufferGeometry.attributes.position.array;
for (let j = 0; j < vertices.length; j += 3) {
rhinoMesh
.vertices()
.add(vertices[j], vertices[j + 1], vertices[j + 2]);
}
// Add faces to Rhino mesh (assuming it's a triangle-based mesh)
const indices = bufferGeometry.index.array;
for (let j = 0; j < indices.length; j += 3) {
rhinoMesh
.faces()
.addTriFace(indices[j], indices[j + 1], indices[j + 2]);
}
const attributes = new rhino.ObjectAttributes();
let materialIndex = -1;
const materialName = rhinoObject.material.name;
for (let k = 0; k < doc.materials().count; k++) {
const existingMaterial = doc.materials().get(k);
if (existingMaterial.name === materialName) {
materialIndex = k; // Use the existing material index
break;
}
}
if (materialIndex === -1) {
// If material does not exist, create and add it
const material = new rhino.Material();
material.name = materialName;
if (rhinoObject.material.map) {
const loader = new THREE.TextureLoader();
async function loadTextureAndApplyToRhino(rhinoObject: {
material: { map: THREE.Texture };
}) {
try {
if (rhinoObject.material.map) {
// Await the loading of the texture
const texture = await loadTextureAsync(
rhinoObject.material.map
);
// Create a Rhino texture and set the fileName from the loaded texture
const rhinoTexture = new rhino.Texture();
rhinoTexture.
rhinoTexture.fileName = texture.source.data.src;
// Apply the Rhino texture to the material
material.setBitmapTexture(rhinoTexture);
material.setBitmapTextureFilename(rhinoTexture.fileName);
// const bitmaps = doc.bitmaps();
// bitmaps.add()
}
} catch (error) {
console.error('Error loading texture:', error);
}
}
function loadTextureAsync(
texture: THREE.Texture
): Promise<THREE.Texture> {
return new Promise((resolve, reject) => {
loader.load(
texture.source.data.src,
// On texture load, resolve the promise
(loadedTexture) => resolve(loadedTexture),
undefined,
// On texture load error, reject the promise
(err) => reject(err)
);
});
}
loadTextureAndApplyToRhino(rhinoObject);
}
materialIndex = doc.materials().add(material);
}
attributes.name = rhinoObject.name; // Preserve name
attributes.materialSource =
rhino.ObjectMaterialSource.MaterialFromObject;
attributes.layerIndex = getLayerIndex(rhinoObject);
attributes.materialIndex = materialIndex;
if (rhinoObject.userData && rhinoObject.userData.attributes) {
attributes.userString = rhinoObject.userData.attributes;
}
// Add the Rhino meshes/Breps to the document
doc.objects().addMesh(rhinoMesh, attributes);
}
}
};
So basically I’m saving the doc at the end and reloading the browser with the new 3d file but it does not show any texture in the meshes. any idea what is missing? thanks in advance!