Use WebWorkers to parralelize mesh generation issue
Closed this issue · 1 comments
Hello,
I'm currently working on a project that requires me to generate intersections. However, I'm using meshes that can be complex and I need to do this on a recurring basis. So I'm looking to use three-bvh-csg with Webworkers.
However, I'm stuck, I have the impression (after my tests) that I need to render my scene for the evaluator to work. But I can't provide my scene in a WebWorker.
So I always get a mesh with empty attributes (array(0)).
Is it possible to activate the evaluator outside a render?
Here's the code for my main thread:
generateCollisions(mesh1, mesh2) {
// let worker = new Worker('/src/scripts/collisionWorker.js');
const worker = new Worker(new URL('/src/scripts/collisionWorker.js', import.meta.url), { type: 'module' });
// Convertir les géométries en JSON pour les envoyer au Web Worker
let mesh1Data = mesh1.geometry.toJSON();
let mesh2Data = mesh2.geometry.toJSON();
const scene = this.context.scene
worker.postMessage({
mesh1: mesh1Data,
mesh2: mesh2Data
});
worker.onmessage = function(event) {
let intersectionData = event.data;
if (intersectionData) {
// Convertir le JSON en une géométrie
let loader = new THREE.BufferGeometryLoader();
let geometry = loader.parse(intersectionData);
let material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
let intersectionMesh = new THREE.Mesh(geometry, material);
intersectionMesh.name = "intersection_" + mesh1.name + "_" + mesh2.name
console.log(intersectionMesh.geometry.attributes)
scene.add(intersectionMesh)
}
};
}
And here the code of my WebWorker script:
import { INTERSECTION, Brush, Evaluator } from 'three-bvh-csg';
import { BufferGeometryLoader, BufferGeometry, MeshStandardMaterial, Mesh, Scene } from 'three';
import * as THREE from 'three';
function convertJSONToBufferGeometry(jsonData) {
const loader = new THREE.BufferGeometryLoader();
return loader.parse(jsonData);
}
// Création d'une "fausse" scène juste pour le calcul
// const fakeScene = new Scene();
// Evaluator qui calculera la différence entre les deux maillages
const csgEvaluator = new Evaluator();
// csgEvaluator.scene = scene;
csgEvaluator.attributes = ['position', 'normal', 'color'];
self.onmessage = function(event) {
const { mesh1, mesh2 } = event.data;
const geometry1 = convertJSONToBufferGeometry(mesh1);
const geometry2 = convertJSONToBufferGeometry(mesh2);
const scene = new THREE.Scene();
const brush1 = new Brush(geometry1);
const brush2 = new Brush(geometry2);
// Ajouter les brosses à la "fausse" scène
scene.add(brush1);
scene.add(brush2);
csgEvaluator.scene = scene;
// Utilisation du même évaluateur pour effectuer l'intersection
const resultObject = new Mesh(new BufferGeometry(), new MeshStandardMaterial({
flatShading: false,
polygonOffset: true,
polygonOffsetUnits: 0.1,
polygonOffsetFactor: 0.1,
color: "#008000",
}));
const result = csgEvaluator.evaluate(brush1, brush2, INTERSECTION, resultObject);
// Récupérez les données de géométrie du résultat et envoyez-les de nouveau au thread principal
postMessage(result.geometry.toJSON());
};
I have the impression (after my tests) that I need to render my scene for the evaluator to work.
There's no need to render in order to perform a CSG evaluation. It can be performed without a scene, renderer, or anything. It is just important that the Brush matrixWorld
matrices be updated before performing an operation.
So I always get a mesh with empty attributes (array(0)).
Without providing a working example it won't be possible to tell what might be happening here. Make sure you transfer the world matrices to the worker, as well, and that the operations are working without the WebWorker.