I'm looking to draw a continuous line with a given thickness showing only the edges using three.js. I have achieved it. I'm trying to add thickness to the line but it is not getting reflected in the scene due to some angle in three.js. Can anyone help me out with the issue.
Here's the fiddle https://jsfiddle.net/16vhjm0y/1/
var renderer, scene, camera;
var line;
var count = 0;
var mouse = new THREE.Vector3();
var mesh3D;
var maxPoint = 6;
var height = window.innerHeight * .99;
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0); // facing us for mouse intersection
var raycaster = new THREE.Raycaster();
var point3ds = [];
var usePerspectiveCamera = false; // toggles back and forth
var perspOrbit;
var perspCam;
var orthoOrbit;
var orthoCam;
var labelRenderer, labelAjay;
var testBoolean = false;
var mouseDownBoolean = false;
var distanceData, showDistanceData;
var ajay;
var arrAjay = [];
var arrAjayFinal = [];
var mouseUpBoolean = false;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, height);
document.body.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
// camera perspective
perspCam = new THREE.PerspectiveCamera(45, window.innerWidth / height, 1, 10000);
perspCam.position.set(0, 0, 200);
// camera ortho
var width = window.innerWidth;
//var height = window.innerHeight;
orthoCam = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, 0, 1200);
// assign cam
camera = perspCam;
someMaterial = new THREE.MeshBasicMaterial({ color: 0xA9A9A9, side: THREE.DoubleSide, transparent: true, opacity: 0.3 });
// grid
var grid = new THREE.GridHelper(1024, 56);
grid.rotateX(Math.PI / 2);
// scene.add(grid);
// geometry
var geometry = new THREE.BufferGeometry();
var MAX_POINTS = 500;
positions = new Float32Array(MAX_POINTS * 3);
geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
// material
var material = new THREE.LineBasicMaterial({
color: 0xff0000,
linewidth: 10
});
// line
line = new THREE.Line(geometry, material);
// line.position.z = 20;
scene.add(line);
// var geometry = new THREE.BoxBufferGeometry( 10, 2, 20 );
// var edgesPavement = new THREE.EdgesGeometry( geomPavement );
// var lineGeometry = new THREE.LineSegmentsGeometry().setPositions( edgesPavement.attributes.position.array );
// var lineMaterial = new THREE.LineMaterial( { color: 0xff0000, linewidth: 10 } );
// lineMaterial.resolution.set( window.innerWidth, window.innerHeight ); // important, for now...
// var line = new THREE.LineSegments2( lineGeometry, lineMaterial );
// scene.add( line );
document.addEventListener("mousemove", onMouseMove, false);
document.addEventListener('mousedown', onMouseDown, false);
document.addEventListener('mouseup', onMouseUp, false);
createUI();
labelRenderer = new THREE.CSS2DRenderer();
ajay = document.createElement('div');
ajay.className = 'ajay';
ajay.style.color = "black";
ajayInsert = document.createElement('div');
ajayInsert.className = 'ajay';
ajayInsert.style.color = "black";
// ajay.style.color = "black";
// console.log(ajay)
labelAjay = new THREE.CSS2DObject(ajay);
labelAjayFinal = new THREE.CSS2DObject(ajayInsert);
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0';
labelRenderer.domElement.style.pointerEvents = 'none';
ajay.style.display = "none";
ajayInsert.style.display = "none";
}
// update line
function updateLine() {
positions[count * 3 - 3] = mouse.x;
positions[count * 3 - 2] = mouse.y;
positions[count * 3 - 1] = mouse.z;
line.geometry.attributes.position.needsUpdate = true;
}
// mouse move handler
function onMouseMove(event) {
var rect = renderer.domElement.getBoundingClientRect();
mouse.x = (event.clientX - rect.left) / (rect.right - rect.left) * 2 - 1;
mouse.y = - ((event.clientY - rect.top) / (rect.bottom - rect.top)) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
mouse = raycaster.ray.intersectPlane(plane, mouse);
if (count !== 0 && count < maxPoint) {
updateLine();
}
testBoolean = true;
if (testBoolean == true) {
// scene.remove(labelAjay);
var geometry = line.geometry;
geometry.computeBoundingBox();
center = geometry.boundingBox.getCenter();
// line.localToWorld(center);
// console.log(center);
if (mouseDownBoolean == true) {
labelAjay.position.set(mouse.x, mouse.y, mouse.z);
// console.log(line.position)
scene.add(labelAjay);
document.body.appendChild(labelRenderer.domElement);
// console.log(positions);
distanceData = point3ds[0].distanceTo(new THREE.Vector3(mouse.x, mouse.y, mouse.z));
showDistanceData = Math.round(distanceData * 1000);
// console.log(point3ds[0]);
// console.log(point3ds[1]);
// console.log(distanceData);
// console.log(showDistanceData)
ajay.textContent = showDistanceData + ' mm';
// console.log(labelRenderer)
}
// console.log(labelRenderer.domElement)
// document.getElementsByClassName("ajay").remove();
// document.getElementsByClassName("ajay").outerHTML = "";
}
}
// add point
function addPoint(event) {
if (count < maxPoint) {
console.log("point nr " + count + ": " + mouse.x + " " + mouse.y + " " + mouse.z);
positions[count * 3 + 0] = mouse.x;
positions[count * 3 + 1] = mouse.y;
positions[count * 3 + 2] = mouse.z
count++;
line.geometry.setDrawRange(0, count);
updateLine();
point3ds.push(new THREE.Vector3(mouse.x, mouse.y, mouse.z));
} else {
console.log('max points reached: ' + maxPoint);
}
}
function getPointInBetweenByLen(pointA, pointB, length) {
var dir = pointB.clone().sub(pointA).normalize().multiplyScalar(length);
return pointA.clone().add(dir);
}
// mouse down handler
function onMouseDown(evt) {
mouseDownBoolean = true;
// force add an extra point on first click so buffer line can display
// buffer geometry requires two points to display, so first click should add two points
if (count === 0) {
addPoint();
}
if (count < maxPoint) {
addPoint();
}
}
function onMouseUp(event){
mouseUpBoolean = true;
if(mouseUpBoolean == true){
// showDistanceData = Math.round(distanceData * 1000);
arrAjay.push(showDistanceData);
console.log(arrAjay);
arrAjayFinal = arrAjay.splice(-1)[0];
var geometry = line.geometry;
geometry.computeBoundingBox();
center = geometry.boundingBox.getCenter();
if (mouseDownBoolean == true) {
labelAjayFinal.position.set(center.x, center.y, center.z);
scene.add(labelAjayFinal);
document.body.appendChild(labelRenderer.domElement);
// distanceData = point3ds[0].distanceTo(new THREE.Vector3(mouse.x, mouse.y, mouse.z));
// showDistanceData = Math.round(distanceData * 1000);
console.log('arrAjayFinal', arrAjayFinal);
ajayInsert.textContent = arrAjayFinal;
}
}
}
// render
function render() {
renderer.render(scene, camera);
labelRenderer.render(scene, camera);
}
// animate
function animate() {
requestAnimationFrame(animate);
render();
}
// loop through all the segments and create their 3D
function create3D() {
if (!mesh3D && point3ds && point3ds.length) {
console.log('creating 3D');
mesh3D = new THREE.Mesh(); // metpy mesh but is the root mesh for all 3D
scene.add(mesh3D);
// prepare create segments from point3ds - every two points create a segement
var index = 1;
var segmentHeight = 56;
point3ds.forEach(point3d => {
if (index < point3ds.length) {
var seg = new Segment(point3d, point3ds[index], someMaterial, segmentHeight);
mesh3D.add(seg.mesh3D);
index++;
}
});
}
}
function createUI() {
// create3D
var btn = document.createElement('button');
document.body.appendChild(btn);
btn.innerHTML = 'Create3D';
btn.addEventListener('mousedown', () => {
create3D();
// add orbiting controls to both cameras
var controls;
if (!perspOrbit) {
perspOrbit = new THREE.OrbitControls(perspCam, renderer.domElement);
perspOrbit.screenSpacePanning = true;
// raotation is enabled once create3D is pressed
setToFullOrbit(perspOrbit);
perspOrbit.enabled = true; // set to true by default
}
// add orbit to orthocam
if (!orthoOrbit) {
orthoOrbit = new THREE.OrbitControls(orthoCam, renderer.domElement);
orthoOrbit.screenSpacePanning = true;
orthoOrbit.enabled = false; // set to false by default
//orthoOrbit.enableDamping = true;
//orthoOrbit.dampingFactor = .15;
}
});
}
function switchCam() {
usePerspectiveCamera = !usePerspectiveCamera;
if (usePerspectiveCamera) {
if (perspCam) {
camera = perspCam;
perspOrbit.enabled = true;
orthoOrbit.enabled = false;
} else {
throw new Error('Switch to perspective cam failed, perspective cam is null');
}
} else {
if (orthoCam) {
camera = orthoCam;
orthoOrbit.enabled = true;
perspOrbit.enabled = false;
} else {
throw new Error('Switch to ortho cam failed, orthoCam is null');
}
}
}
function rotateCam90() {
if (camera instanceof THREE.OrthographicCamera) {
orthoOrbit.update();
camera.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI / 2));
}
}
function reset() {
scene.remove(mesh3D);
mesh3D = null;
for (var i = 0; i < 3 * 8; i++) {
positions[i] = 0;
}
count = 0;
line.geometry.setDrawRange(0, count);
updateLine();
point3ds = [];
}
function setToFullOrbit(orbitControl) {
// how far you can orbit vertically
orbitControl.minPolarAngle = 0;
orbitControl.maxPolarAngle = Math.PI;
// How far you can dolly in and out ( PerspectiveCamera only )
orbitControl.minDistance = 0;
orbitControl.maxDistance = Infinity;
orbitControl.enableZoom = true; // Set to false to disable zooming
orbitControl.zoomSpeed = 1.0;
orbitControl.enableRotate = true;
// allow keyboard arrows
orbitControl.enableKeys = true;
// Set to false to disable panning (ie vertical and horizontal translations)
orbitControl.enablePan = true;
}
// each segment knows how to create its 3D
class Segment {
constructor(start, end, material, height) {
this.start = start;
this.end = end;
this.height = height; // height of the segment's 3D
this.material = material;
this.mesh3D = null;
this.create3D();
}
create3D() {
if (this.start && this.end) {
//create the shape geometry
var distStartToEnd = this.start.distanceTo(this.end);
var vec2s = [
new THREE.Vector2(),
new THREE.Vector2(0, this.height),
new THREE.Vector2(distStartToEnd, this.height),
new THREE.Vector2(distStartToEnd, 0)
];
console.log('vec2s', vec2s);
var shape = new THREE.Shape(vec2s);
var geo = new THREE.BoxGeometry(5, 5, 5);
// console.log('shape', shape);
var geo = new THREE.ShapeGeometry(shape);
geo.applyMatrix(new THREE.Matrix4().makeRotationX(THREE.Math.degToRad(90)));
this.mesh3D = new THREE.Mesh(geo, this.material);
this.alignRotation();
this.alignPosition();
// the mesh3D should be added to the scene outside of this class
}
}
alignRotation() {
var p1 = this.start.clone();
var p2 = this.end.clone();
var direction = new THREE.Vector3();
direction.subVectors(p2, p1);
direction.normalize();
this.mesh3D.quaternion.setFromUnitVectors(new THREE.Vector3(1, 0, 0), direction);
}
alignPosition() {
if (this.mesh3D) {
this.mesh3D.position.copy(this.start);
} else {
throw new Error('mesh3D null');
}
}
}
The linewidth parameter relies on native WebGL support for drawing line thickness, but its performance is very spotty across browsers & operating systems. I think Windows doesn't support it, but MacOS does, so it shouldn't be relied upon. See this discussion on the Three.js Github for several bug reports.
As a workaround, they've created LineGeometry, which sort of re-builds a line with geometry to allow for thickness. See this example for how to use it. It even allows for dashed lines. After importing the module, you can implement it with:
const geometry = new LineGeometry();
geometry.setPositions( positions );
geometry.setColors( colors );
matLine = new LineMaterial( {
color: 0xffffff,
linewidth: 5, // in pixels
vertexColors: true,
dashed: false
} );
line = new Line2( geometry, matLine );
line.computeLineDistances();
scene.add( line );
I have a mesh (image 1) and a parallelepipede, I add the intersection result of this 2 objects in a scene and I move the parallelepipede along my mesh repeating the same process to "cut" my mesh and get an exploded view of my mesh (image 2).
Problem is that the process time is more than 2 mins... I have tryed to reduce the mesh with meshmixxer but it's not enough... Does someone has another idea ?
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);
}
}
I try to integrate a plugin
Demo here: http://makg10.github.io/jquery-meme-generator/
The js code and read.me here:
https://jsfiddle.net/t6xu4pyf/1/
(function($){
var i18n = {
topTextPlaceholder: "TEXTE HAUT",
bottomTextPlaceholder: "TEXT BAS",
Server side and client, it works for me if I put directly the url of an image in my html.
If I use
It also works except that the image does not resize to upload.
I'm very very bad with the canvas and I do not know at all if I can work on the size of the image directly in the plugin code or if I have to resize the image "before" with other function? ()
Thank you very much for your help
Finally, solution was client side.
It is about the image resize before upload ... no more.
The answer already existed in many topic above. Sorry.
Anyway, here's the code:
function readURL(input) {
if (input.files && input.files[0]) {
var current_file = input.files[0];
var reader = new FileReader();
reader.onload = function (event) {
var image = new Image();
image.src = event.target.result;
image.onload = function () {
var maxWidth = 500,
maxHeight = 500,
imageWidth = image.width,
imageHeight = image.height;
if (imageWidth > imageHeight) {
if (imageWidth > maxWidth) {
imageHeight *= maxWidth / imageWidth;
imageWidth = maxWidth;
}
}
else {
if (imageHeight > maxHeight) {
imageWidth *= maxHeight / imageHeight;
imageHeight = maxHeight;
}
}
var canvas = document.createElement('canvas');
canvas.width = imageWidth;
canvas.height = imageHeight;
image.width = imageWidth;
image.height = imageHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
$('#example').attr('src', canvas.toDataURL(current_file.type));
}
}
reader.readAsDataURL(input.files[0]);
}
}
$("#inputfiles").change(function(){
readURL(this);
});
<script type="text/javascript">
canvas.onmouseover = function onMouseover(e) {
waveFlag( flag, 20, 10, 150, 200, -0.1 );
}
canvas.onmouseout = function onMouseover(e) {
}
</script>
Above code is when the mouse move to the flag the flag will waving, how can i stop waving the flag when mouse out???
Just stop the setInterval from firing and the function will stop
<script type="text/javascript">
var timer = null;
function waveFlag( canvas, wavelength, amplitude, period, shading, squeeze ) {
if (!squeeze) squeeze = 0;
if (!shading) shading = 100;
if (!period) period = 200;
if (!amplitude) amplitude = 10;
if (!wavelength) wavelength = canvas.width/10;
var fps = 30;
var ctx = canvas.getContext('2d');
var w = canvas.width, h = canvas.height;
var od = ctx.getImageData(0,0,w,h).data;
// var ct = 0, st=new Date;
return setInterval(function(){
var id = ctx.getImageData(0,0,w,h);
var d = id.data;
var now = (new Date)/period;
for (var y=0;y<h;++y){
var lastO=0,shade=0;
var sq = (y-h/2)*squeeze;
for (var x=0;x<w;++x){
var px = (y*w + x)*4;
var pct = x/w;
var o = Math.sin(x/wavelength-now)*amplitude*pct;
var y2 = y + (o+sq*pct)<<0;
var opx = (y2*w + x)*4;
shade = (o-lastO)*shading;
d[px ] = od[opx ]+shade;
d[px+1] = od[opx+1]+shade;
d[px+2] = od[opx+2]+shade;
d[px+3] = od[opx+3];
lastO = o;
}
}
ctx.putImageData(id,0,0);
// if ((++ct)%100 == 0) console.log( 1000 * ct / (new Date - st));
},1000/fps);
}
var canvas = document.getElementById("flag");
canvas.onmouseover = function onMouseover(e) {
timer = waveFlag( flag, 20, 10, 150, 200, -0.1 );
}
canvas.onmouseout = function onMouseover(e) {
window.clearInterval(timer);
timer = null;
}
</script>