in src/engine/Eraser.js [101:207]
erasePixels(x_, y_, z_, vDir, startflag, length) {
const targetX = Math.floor(x_ * this.xDim);
const targetY = Math.floor(y_ * this.yDim);
const targetZ = Math.floor(z_ * this.zDim);
const normal = new THREE.Vector3();
const normalGauss = new THREE.Vector3();
const GAUSS_R = 2;
const SIGMA = 1.4;
const SIGMA2 = SIGMA * SIGMA;
let nX = 0;
let nY = 0;
let nZ = 0;
let normFactor = 0;
let offDst = 0;
const VAL_2 = 2; // getting normal of surface
for (let k = -Math.min(GAUSS_R, targetZ); k <= Math.min(GAUSS_R, this.zDim - 1 - targetZ); k++) {
for (let j = -Math.min(GAUSS_R, targetY); j <= Math.min(GAUSS_R, this.yDim - 1 - targetY); j++) {
for (let i = -Math.min(GAUSS_R, targetX); i <= Math.min(GAUSS_R, this.xDim - 1 - targetX); i++) {
// handling voxel: (targetX + i; ,targetY+ j; targetZ + k);
const gX = targetX + i;
const gY = targetY + j;
const gZ = targetZ + k;
offDst = gX + gY * this.xDim + gZ * this.xDim * this.yDim;
const gauss = 1 - Math.exp(-(i * i + j * j + k * k) / (VAL_2 * SIGMA2));
normFactor += gauss;
const curVal = this.bufferTextureCPU[offDst];
nX += curVal * gauss * (-i / SIGMA2);
nY += curVal * gauss * (-j / SIGMA2);
nZ += curVal * gauss * (-k / SIGMA2);
}
}
} // end gauss summation
normalGauss.set(nX / normFactor, nY / normFactor, nZ / normFactor);
normal.copy(normalGauss);
normal.normalize();
const pi = 180; // pi (just for console output)
const radiusRatio = this.xDim / this.zDim;
const geometry = new THREE.CylinderGeometry(this.radius, this.radius, this.depth, pi, this.depth);
const mesh = new THREE.Mesh(geometry, null);
const axis = new THREE.Vector3(0, 0, 1);
mesh.quaternion.setFromUnitVectors(axis, normal.clone().normalize().multiplyScalar(-1));
mesh.position.copy(new THREE.Vector3(targetX, targetY, targetZ));
if (startflag === true) {
this.prevDistance = length;
this.resetflag = false;
}
const radius = 0.05;
if (this.resetflag === false) {
if (Math.abs(this.prevDistance - length) < radius) {
this.prevDistance = length;
this.point = new THREE.Vector3(0, 0, 0);
this.queue = [];
this.queue.push(this.point);
const normalBack = -5;
let backZ = 0;
backZ = normalBack;
let deleteflag = false;
while (this.queue.length > 0) {
this.point = this.queue.pop();
const RotPoint = this.point.clone();
RotPoint.z *= radiusRatio;
RotPoint.applyAxisAngle(new THREE.Vector3(1, 0, 0), -mesh.rotation.x);
RotPoint.applyAxisAngle(new THREE.Vector3(0, 1, 0), -mesh.rotation.y);
RotPoint.applyAxisAngle(new THREE.Vector3(0, 0, 1), mesh.rotation.z);
if (
Math.sqrt(RotPoint.x * RotPoint.x + RotPoint.y * RotPoint.y) > this.radius ||
Math.abs(RotPoint.z) > this.depth ||
RotPoint.z < backZ
) {
continue;
}
for (let x = this.point.x - 1; x <= this.point.x + 1; x++) {
for (let y = this.point.y - 1; y <= this.point.y + 1; y++) {
for (let z = this.point.z - 1; z <= this.point.z + 1; z++) {
const mainX = targetX + Math.round(x);
const mainY = targetY + Math.round(y);
const mainZ = targetZ + Math.round(z);
offDst = mainX + mainY * this.xDim + mainZ * this.xDim * this.yDim;
if (this.bufferMask[offDst] === 0) {
continue;
}
const bitconst = 255.0;
const borderinclude = 0.01;
const isoSurfaceBorder = this.isoThreshold * bitconst - borderinclude * bitconst;
if (this.bufferTextureCPU[offDst] >= isoSurfaceBorder) {
deleteflag = true;
this.bufferMask[offDst] = 0;
this.queue.push(new THREE.Vector3(x, y, z));
}
}
}
}
}
if (deleteflag === true) {
this.lastSize.push(this.radius);
this.lastDepth.push(this.depth);
this.lastRotationVector.push(new THREE.Vector3(-mesh.rotation.x, -mesh.rotation.y, mesh.rotation.z));
this.lastTarget.push(new THREE.Vector3(targetX, targetY, targetZ));
this.lastBackDistance.push(-Math.round(Math.abs(Math.tan(vDir.normalize().angleTo(normalGauss.normalize()))) * this.radius));
}
this.updatableTextureMask.needsUpdate = true;
} else {
this.resetflag = false;
}
}
}