我有一个网格(图像1)和一个平行管,我在场景中添加了这两个对象的交集结果,我沿着我的网格移动平行管,重复相同的过程到" cut"我的网格,得到我的网格的爆炸视图(图2)。
问题是处理时间超过2分钟......我试图用meshmixxer减少网格但是它还不够......有人有另一个想法吗?
function FirstCut() {
var scene, camera, renderer, controls;
//stl loader from https://threejs.org/examples/webgl_loader_stl.html
// cf example https://stemkoski.github.io/Three.js/CSG.html
//with obj
init();
animate();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xeeeeee);
camera = new THREE.PerspectiveCamera(75, 800 / 500, 1, 2000);
//camera.position.set(50, 500, 0);
camera.position.x = 50;
camera.position.y = 500;
camera.position.z = 0;
//var axeX = new THREE.Vector3(1, 0, 0);
//camera.rotateOnAxis(axeX, -1);
camera.lookAt(new THREE.Vector3(0, 500, 0));
controls = new THREE.OrbitControls(camera);
//les valeurs de min and max distance sont choisies pour que le filet ne disparaisse pas quand on le fait tourner
controls.minDistance = 0;
controls.maxDistance = 1000;
//scene
//var ambient = new THREE.AmbientLight(0x101030);
//scene.add(ambient);
//scene.add(new THREE.GridHelper(1000, 20));
//var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
//directionalLight.position.set(0, 1, 0);
//scene.add(directionalLight);
var widthH = parseInt(document.getElementById("wdthH").value) || 0; // H for Head
var widthT = parseInt(document.getElementById("wdthT").value) || 0; // T for tail
var height = parseInt(document.getElementById("hght").value) || 0; // flank
//création du pavé
var EmportePieceH = new THREE.BoxGeometry(300, 60, widthH);
var EmportePieceT = new THREE.BoxGeometry(300, 60, widthT);
var EmportePieceB = new THREE.BoxGeometry(height, 60, 520);
var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });
// création du meshage et material
var EmportePieceMeshH = new THREE.Mesh(EmportePieceH, paveMaterial);
var EmportePieceMeshT = new THREE.Mesh(EmportePieceT, paveMaterial);
var paveMeshB = new THREE.Mesh(EmportePieceB, paveMaterial);
var zH = 247 - widthH / 2;
var zT = -247 + widthT / 2;
EmportePieceMeshH.position.set(0, 30, zH);
EmportePieceMeshT.position.set(0, 30, zT);
paveMeshB.position.set(-95 + height / 2, 30, 0);
var EmportePieceBSPH = new ThreeBSP(EmportePieceMeshH);
var EmportePieceBSPT = new ThreeBSP(EmportePieceMeshT);
var paveBSPB = new ThreeBSP(paveMeshB);
//scene.add(EmportePieceMeshH);
//scene.add(EmportePieceMeshT);
//scene.add(paveMeshB);
// texture
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var texture = new THREE.Texture();
var onProgress = function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}
};
var onError = function (xhr) {
};
var loader = new THREE.ImageLoader(manager);
loader.load('/Scan/filet_1kg500-reposition-reduit_material_0.jpg', function (image) {
texture.image = image;
texture.needsUpdate = true;
});
var width = parseInt(document.getElementById("wdth").value) || 0;
//création du pavé
var paveGeom = new THREE.BoxGeometry(250, 250, width);
var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });
// création du meshage parallélépipède avec material
var paveMesh = new THREE.Mesh(paveGeom, paveMaterial);
var z0 = -247 + widthH;
paveMesh.position.set(0, 0, z0);
var paveBSP = new ThreeBSP(paveMesh);
//scene.add(paveMesh);
//tableau des volumes
var tabVolumes = new Array();
// model
var loader = new THREE.OBJLoader(manager);
loader.load('/Scan/filet_1kg500-reposition-reduit.obj', function (object) {
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
var geo = new THREE.Geometry().fromBufferGeometry(child.geometry);
var filetMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
var filetMesh = new THREE.Mesh(geo, filetMaterial);
//scene.add(filetMesh);
var newBSPH, newBSPT, newBSPB, newBSP2, newBSP1, filletBSP
var filetBSP = new ThreeBSP(filetMesh);
newBSPH = filetBSP.intersect(EmportePieceBSPH);
newBSPT = filetBSP.intersect(EmportePieceBSPT);
newBSPB = filetBSP.intersect(paveBSPB);
newBSP2 = filetBSP.subtract(EmportePieceBSPH);
newBSP1 = newBSP2.subtract(paveBSPB);
filletBSP = newBSP1.subtract(EmportePieceBSPT);
////////////////////subtract//////////////////////////////
var newFilet = new THREE.Geometry();
newFilet = filletBSP.toGeometry();
var newFilletMesh = new THREE.Mesh(newFilet, new THREE.MeshBasicMaterial({ map: texture }));
newFilletMesh.position.set(0, 0, 0);
///////////////////////////////////création morceaux découpés///////////////////////////////////////////
var HeadFillet = new THREE.Geometry();
var TailFillet = new THREE.Geometry();
var degraissageFillet = new THREE.Geometry();
HeadFillet = newBSPH.toGeometry();
TailFillet = newBSPT.toGeometry();
degraissageFillet = newBSPB.toGeometry();
/////////////////////////////////calcul des volumes des 1ers morceaux/////////////////////////////////////////
if (widthH != 0) {
tabVolumes[0] = calculateVolume2(HeadFillet);
} else { tabVolumes[0] = 0;}
if (widthT != 0) {
//alert(tabVolumes[0]);
tabVolumes[1] = calculateVolume2(TailFillet);
} else { tabVolumes[1] = 0; }
if (height != 0) {
tabVolumes[2] = calculateVolume2(degraissageFillet);
} else { tabVolumes[2] = 0; }
var ind = 3;
var HeadFilletMesh = new THREE.Mesh(HeadFillet, new THREE.MeshBasicMaterial({ map: texture }));
var TailFilletMesh = new THREE.Mesh(TailFillet, new THREE.MeshBasicMaterial({ map: texture }));
var degraissageFilletMesh = new THREE.Mesh(degraissageFillet, new THREE.MeshBasicMaterial({ map: texture }));
HeadFilletMesh.position.set(0, 0, 20);
degraissageFilletMesh.position.set(-20, 0, 0);
TailFilletMesh.position.set(0, 0, -20);
scene.add(HeadFilletMesh);
scene.add(TailFilletMesh);
scene.add(degraissageFilletMesh);
//scene.add(newFilletMesh);
var cloneHeadFilletMesh = HeadFilletMesh.clone();
var cloneTailFilletMesh = TailFilletMesh.clone();
var clonedegraissageFilletMesh = degraissageFilletMesh.clone();
var mesh_decoupe = new THREE.Object3D;
mesh_decoupe.add(cloneHeadFilletMesh);
mesh_decoupe.add(cloneTailFilletMesh);
mesh_decoupe.add(clonedegraissageFilletMesh);
if (width != 0) {
var paveGeom = new THREE.BoxGeometry(300, 300, width);
var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });
var fillet2BSP = new ThreeBSP(newFilletMesh);
var intersectionPave = new THREE.Geometry();
intersectionPave = fillet2BSP.intersect(paveBSP);
var geometryPave = new THREE.Geometry();
geometryPave = intersectionPave.toGeometry();
var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));
//alert(geometryPave.faces.length);
while (geometryPave.faces.length != 0) {
var z = paveMesh.position.z + width + 5;
paveMesh.position.set(0, 0, z);
paveBSP = new ThreeBSP(paveMesh);
//scene.add(paveMesh);
fillet2BSP = new ThreeBSP(newFilletMesh);
intersectionPave = filletBSP.intersect(paveBSP);
geometryPave = intersectionPave.toGeometry();
tabVolumes[ind] = calculateVolume2(geometryPave);
ind = ind + 1;
var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));
newMesh.position.set(0, 0, newMesh.position.z);
scene.add(newMesh);
var meshSave = newMesh.clone();
mesh_decoupe.add(meshSave);
}
document.body.style.cursor = '';
} else {
scene.add(newFilletMesh);
document.body.style.cursor = '';
tabVolumes[3] = 0;
tabVolumes[4] = calculateVolume2(newFilet);
}
// }
//}
//else {
// scene.add(newFilletMesh);
// tabVolumes[ind] = calculateVolume2(newFilet);
//}
//alert(calculateVolume2(newBSP.toGeometry()));
//afficher les volumes dans la textarea
var txtVolume = document.getElementById("txtVolume");
txtVolume.value = tabVolumes.join("\n");
//var exporter = new THREE.OBJExporter();
//var result = exporter.parse(mesh_decoupe);
//var blob = new Blob([result], { type: 'text/plain' });
//saveAs(blob, 'dechets.obj');
}
});
//scene.add(object);
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setSize(800, 500, false);
document.getElementById('canvas3D').innerHTML = "";
document.getElementById('canvas3D').appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
camin();
renderer.render(scene, camera);
}
function camin() {
camera.position.y -= .1;
}
function volumeOfT(p1, p2, p3) {
var v321 = p3.x * p2.y * p1.z;
var v231 = p2.x * p3.y * p1.z;
var v312 = p3.x * p1.y * p2.z;
var v132 = p1.x * p3.y * p2.z;
var v213 = p2.x * p1.y * p3.z;
var v123 = p1.x * p2.y * p3.z;
return (-v321 + v231 + v312 - v132 - v213 + v123) / 6.0;
}
function calculateVolume2(object) {
var volumes = 0.0;
for (var i = 0; i < object.faces.length; i++) {
var Pi = object.faces[i].a;
var Qi = object.faces[i].b;
var Ri = object.faces[i].c;
//alert (Pi);
var P = new THREE.Vector3(object.vertices[Pi].x, object.vertices[Pi].y, object.vertices[Pi].z);
//alert(object.vertices[Pi].x);
var Q = new THREE.Vector3(object.vertices[Qi].x, object.vertices[Qi].y, object.vertices[Qi].z);
var R = new THREE.Vector3(object.vertices[Ri].x, object.vertices[Ri].y, object.vertices[Ri].z);
volumes += volumeOfT(P, Q, R);
}
return Math.abs(volumes);
}
}
function FirstCut() {
var scene, camera, renderer, controls;
//stl loader from https://threejs.org/examples/webgl_loader_stl.html
// cf example https://stemkoski.github.io/Three.js/CSG.html
//with obj
init();
animate();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xeeeeee);
camera = new THREE.PerspectiveCamera(75, 800 / 500, 1, 2000);
//camera.position.set(50, 500, 0);
camera.position.x = 50;
camera.position.y = 500;
camera.position.z = 0;
//var axeX = new THREE.Vector3(1, 0, 0);
//camera.rotateOnAxis(axeX, -1);
camera.lookAt(new THREE.Vector3(0, 500, 0));
controls = new THREE.OrbitControls(camera);
//les valeurs de min and max distance sont choisies pour que le filet ne disparaisse pas quand on le fait tourner
controls.minDistance = 0;
controls.maxDistance = 1000;
//scene
//var ambient = new THREE.AmbientLight(0x101030);
//scene.add(ambient);
//scene.add(new THREE.GridHelper(1000, 20));
//var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
//directionalLight.position.set(0, 1, 0);
//scene.add(directionalLight);
var widthH = parseInt(document.getElementById("wdthH").value) || 0; // H for Head
var widthT = parseInt(document.getElementById("wdthT").value) || 0; // T for tail
var height = parseInt(document.getElementById("hght").value) || 0; // flank
//création du pavé
var EmportePieceH = new THREE.BoxGeometry(300, 60, widthH);
var EmportePieceT = new THREE.BoxGeometry(300, 60, widthT);
var EmportePieceB = new THREE.BoxGeometry(height, 60, 520);
var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });
// création du meshage et material
var EmportePieceMeshH = new THREE.Mesh(EmportePieceH, paveMaterial);
var EmportePieceMeshT = new THREE.Mesh(EmportePieceT, paveMaterial);
var paveMeshB = new THREE.Mesh(EmportePieceB, paveMaterial);
var zH = 247 - widthH / 2;
var zT = -247 + widthT / 2;
EmportePieceMeshH.position.set(0, 30, zH);
EmportePieceMeshT.position.set(0, 30, zT);
paveMeshB.position.set(-95 + height / 2, 30, 0);
var EmportePieceBSPH = new ThreeBSP(EmportePieceMeshH);
var EmportePieceBSPT = new ThreeBSP(EmportePieceMeshT);
var paveBSPB = new ThreeBSP(paveMeshB);
//scene.add(EmportePieceMeshH);
//scene.add(EmportePieceMeshT);
//scene.add(paveMeshB);
// texture
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var texture = new THREE.Texture();
var onProgress = function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}
};
var onError = function (xhr) {
};
var loader = new THREE.ImageLoader(manager);
loader.load('/Scan/filet_1kg500-reposition-reduit_material_0.jpg', function (image) {
texture.image = image;
texture.needsUpdate = true;
});
var width = parseInt(document.getElementById("wdth").value) || 0;
//création du pavé
var paveGeom = new THREE.BoxGeometry(250, 250, width);
var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });
// création du meshage parallélépipède avec material
var paveMesh = new THREE.Mesh(paveGeom, paveMaterial);
var z0 = -247 + widthH;
paveMesh.position.set(0, 0, z0);
var paveBSP = new ThreeBSP(paveMesh);
//scene.add(paveMesh);
//tableau des volumes
var tabVolumes = new Array();
// model
var loader = new THREE.OBJLoader(manager);
loader.load('/Scan/filet_1kg500-reposition-reduit.obj', function (object) {
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
var geo = new THREE.Geometry().fromBufferGeometry(child.geometry);
var filetMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
var filetMesh = new THREE.Mesh(geo, filetMaterial);
//scene.add(filetMesh);
var newBSPH, newBSPT, newBSPB, newBSP2, newBSP1, filletBSP
var filetBSP = new ThreeBSP(filetMesh);
newBSPH = filetBSP.intersect(EmportePieceBSPH);
newBSPT = filetBSP.intersect(EmportePieceBSPT);
newBSPB = filetBSP.intersect(paveBSPB);
newBSP2 = filetBSP.subtract(EmportePieceBSPH);
newBSP1 = newBSP2.subtract(paveBSPB);
filletBSP = newBSP1.subtract(EmportePieceBSPT);
////////////////////subtract//////////////////////////////
var newFilet = new THREE.Geometry();
newFilet = filletBSP.toGeometry();
var newFilletMesh = new THREE.Mesh(newFilet, new THREE.MeshBasicMaterial({ map: texture }));
newFilletMesh.position.set(0, 0, 0);
///////////////////////////////////création morceaux découpés///////////////////////////////////////////
var HeadFillet = new THREE.Geometry();
var TailFillet = new THREE.Geometry();
var degraissageFillet = new THREE.Geometry();
HeadFillet = newBSPH.toGeometry();
TailFillet = newBSPT.toGeometry();
degraissageFillet = newBSPB.toGeometry();
/////////////////////////////////calcul des volumes des 1ers morceaux/////////////////////////////////////////
if (widthH != 0) {
tabVolumes[0] = calculateVolume2(HeadFillet);
} else { tabVolumes[0] = 0;}
if (widthT != 0) {
//alert(tabVolumes[0]);
tabVolumes[1] = calculateVolume2(TailFillet);
} else { tabVolumes[1] = 0; }
if (height != 0) {
tabVolumes[2] = calculateVolume2(degraissageFillet);
} else { tabVolumes[2] = 0; }
var ind = 3;
var HeadFilletMesh = new THREE.Mesh(HeadFillet, new THREE.MeshBasicMaterial({ map: texture }));
var TailFilletMesh = new THREE.Mesh(TailFillet, new THREE.MeshBasicMaterial({ map: texture }));
var degraissageFilletMesh = new THREE.Mesh(degraissageFillet, new THREE.MeshBasicMaterial({ map: texture }));
HeadFilletMesh.position.set(0, 0, 20);
degraissageFilletMesh.position.set(-20, 0, 0);
TailFilletMesh.position.set(0, 0, -20);
scene.add(HeadFilletMesh);
scene.add(TailFilletMesh);
scene.add(degraissageFilletMesh);
//scene.add(newFilletMesh);
var cloneHeadFilletMesh = HeadFilletMesh.clone();
var cloneTailFilletMesh = TailFilletMesh.clone();
var clonedegraissageFilletMesh = degraissageFilletMesh.clone();
var mesh_decoupe = new THREE.Object3D;
mesh_decoupe.add(cloneHeadFilletMesh);
mesh_decoupe.add(cloneTailFilletMesh);
mesh_decoupe.add(clonedegraissageFilletMesh);
if (width != 0) {
var paveGeom = new THREE.BoxGeometry(300, 300, width);
var paveMaterial = new THREE.MeshBasicMaterial({ wireframe: true });
var fillet2BSP = new ThreeBSP(newFilletMesh);
var intersectionPave = new THREE.Geometry();
intersectionPave = fillet2BSP.intersect(paveBSP);
var geometryPave = new THREE.Geometry();
geometryPave = intersectionPave.toGeometry();
var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));
//alert(geometryPave.faces.length);
while (geometryPave.faces.length != 0) {
var z = paveMesh.position.z + width + 5;
paveMesh.position.set(0, 0, z);
paveBSP = new ThreeBSP(paveMesh);
//scene.add(paveMesh);
fillet2BSP = new ThreeBSP(newFilletMesh);
intersectionPave = filletBSP.intersect(paveBSP);
geometryPave = intersectionPave.toGeometry();
tabVolumes[ind] = calculateVolume2(geometryPave);
ind = ind + 1;
var newMesh = new THREE.Mesh(geometryPave, new THREE.MeshBasicMaterial({ map: texture }));
newMesh.position.set(0, 0, newMesh.position.z);
scene.add(newMesh);
var meshSave = newMesh.clone();
mesh_decoupe.add(meshSave);
}
document.body.style.cursor = '';
} else {
scene.add(newFilletMesh);
document.body.style.cursor = '';
tabVolumes[3] = 0;
tabVolumes[4] = calculateVolume2(newFilet);
}
// }
//}
//else {
// scene.add(newFilletMesh);
// tabVolumes[ind] = calculateVolume2(newFilet);
//}
//alert(calculateVolume2(newBSP.toGeometry()));
//afficher les volumes dans la textarea
var txtVolume = document.getElementById("txtVolume");
txtVolume.value = tabVolumes.join("\n");
//var exporter = new THREE.OBJExporter();
//var result = exporter.parse(mesh_decoupe);
//var blob = new Blob([result], { type: 'text/plain' });
//saveAs(blob, 'dechets.obj');
}
});
//scene.add(object);
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setSize(800, 500, false);
document.getElementById('canvas3D').innerHTML = "";
document.getElementById('canvas3D').appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
camin();
renderer.render(scene, camera);
}
function camin() {
camera.position.y -= .1;
}
function volumeOfT(p1, p2, p3) {
var v321 = p3.x * p2.y * p1.z;
var v231 = p2.x * p3.y * p1.z;
var v312 = p3.x * p1.y * p2.z;
var v132 = p1.x * p3.y * p2.z;
var v213 = p2.x * p1.y * p3.z;
var v123 = p1.x * p2.y * p3.z;
return (-v321 + v231 + v312 - v132 - v213 + v123) / 6.0;
}
function calculateVolume2(object) {
var volumes = 0.0;
for (var i = 0; i < object.faces.length; i++) {
var Pi = object.faces[i].a;
var Qi = object.faces[i].b;
var Ri = object.faces[i].c;
//alert (Pi);
var P = new THREE.Vector3(object.vertices[Pi].x, object.vertices[Pi].y, object.vertices[Pi].z);
//alert(object.vertices[Pi].x);
var Q = new THREE.Vector3(object.vertices[Qi].x, object.vertices[Qi].y, object.vertices[Qi].z);
var R = new THREE.Vector3(object.vertices[Ri].x, object.vertices[Ri].y, object.vertices[Ri].z);
volumes += volumeOfT(P, Q, R);
}
return Math.abs(volumes);
}
}