in packages/miew/src/gfx/geometries/IsoSurface.js [222:364]
_doGridPosNorms(isoValue, step, appendSimple) {
const vol = this._volumetricData;
const volData = this._volumetricData.getData();
const dim = vol.getDimensions();
const xSize = dim[0];
const ySize = dim[1];
const zSize = dim[2];
const stepX = step * vol.getStrideX();
const stepY = step * vol.getStrideY();
const stepZ = step * vol.getStrideZ();
const gc = new GridCell();
const gcVal = gc.val;
const gcValSize = gc.val.length;
const additions = [
new THREE.Vector3(0, 0, 0), // 0
new THREE.Vector3(step, 0, 0), // 1
new THREE.Vector3(step, step, 0), // 2
new THREE.Vector3(0, step, 0), // 3
new THREE.Vector3(0, 0, step), // 4
new THREE.Vector3(step, 0, step), // 5
new THREE.Vector3(step, step, step), // 6
new THREE.Vector3(0, step, step), // 7
];
const tmpTriCount = 5;
const triangles = new Array(tmpTriCount);
for (let j = 0; j < tmpTriCount; ++j) {
triangles[j] = new Triangle();
}
let appendVertex;
const self = this;
const positions = this._position;
const normals = this._normals;
if (appendSimple) {
// Special case for axis-aligned grid with positive unit vector normals
appendVertex = (function () {
const axis = new THREE.Vector3(self._xAxis.x, self._yAxis.y, self._zAxis.z);
return function (triVertex) {
const vertex = triVertex.p.clone();
vertex.multiply(axis);
positions.push(vertex.add(self._origin));
normals.push(triVertex.n.clone());
};
}());
} else {
appendVertex = (function () {
const posMtx = new THREE.Matrix3();
posMtx.set(
self._xAxis.x,
self._yAxis.x,
self._zAxis.x,
self._xAxis.y,
self._yAxis.y,
self._zAxis.y,
self._xAxis.z,
self._yAxis.z,
self._zAxis.z,
);
const normMtx = new THREE.Matrix3();
normMtx.set(
self._xDir.x,
self._yDir.x,
self._zDir.x,
self._xDir.y,
self._yDir.y,
self._zDir.y,
self._xDir.z,
self._yDir.z,
self._zDir.z,
);
return function (triVertex) {
positions.push(triVertex.p.clone().applyMatrix3(posMtx).add(self._origin));
normals.push(triVertex.n.clone().applyMatrix3(normMtx));
};
}());
}
const indices = this._indices;
let globTriCount = 0;
for (let z = 0; z < (zSize - step); z += step) {
for (let y = 0; y < (ySize - step); y += step) {
let idx = vol.getDirectIdx(0, y, z);
for (let x = 0; x < (xSize - step); x += step, idx += stepX) {
/* eslint-disable no-multi-spaces */
/* eslint-disable computed-property-spacing */
gcVal[0] = volData[idx];
gcVal[1] = volData[idx + stepX];
gcVal[3] = volData[idx + stepY];
gcVal[2] = volData[idx + stepX + stepY];
gcVal[4] = volData[idx + stepZ];
gcVal[5] = volData[idx + stepX + stepZ];
gcVal[7] = volData[idx + stepY + stepZ];
gcVal[6] = volData[idx + stepX + stepY + stepZ];
/* eslint-enable no-multi-spaces */
/* eslint-enable computed-property-spacing */
// Determine the index into the edge table which
// tells us which vertices are inside of the surface
let cubeIndex = 0;
let i = 0;
for (; i < gcValSize; ++i) {
if (gcVal[i] < isoValue) {
cubeIndex |= (1 << i);
}
}
if (edgeTable[cubeIndex] === 0) {
continue;
}
gc.cubeIndex = cubeIndex;
for (i = 0; i < gcValSize; ++i) {
gc.p[i].set(x + additions[i].x, y + additions[i].y, z + additions[i].z);
_voxelGradientFast(this._gradient, gc.p[i], gc.g[i]);
}
// calculate vertices and facets for this cube,
// calculate normals by interpolating between the negated
// normalized volume gradients for the 8 reference voxels
const triCount = this._polygonize(gc, isoValue, triangles);
globTriCount += triCount;
// append triangles using different techniques
for (i = 0; i < triCount; ++i) {
indices.push(this._numTriangles * 3);
indices.push(this._numTriangles * 3 + 1);
indices.push(this._numTriangles * 3 + 2);
++this._numTriangles;
appendVertex(triangles[i].a);
appendVertex(triangles[i].b);
appendVertex(triangles[i].c);
}
}
}
}
return globTriCount;
}