Last active
March 22, 2021 10:53
-
-
Save sto3psl/8bca4562096050559ec51544483edc33 to your computer and use it in GitHub Desktop.
esbuild renaming problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
function AVSurface(coordList, radiusList, indexList) { | |
var nAtoms = radiusList.length; | |
var x = new Float32Array(nAtoms); | |
var y = new Float32Array(nAtoms); | |
var z = new Float32Array(nAtoms); | |
for (var i = 0; i < nAtoms; i++) { | |
var ci = 3 * i; | |
x[i] = coordList[ci]; | |
y[i] = coordList[ci + 1]; | |
z[i] = coordList[ci + 2]; | |
} | |
var bbox = computeBoundingBox(coordList); | |
if (coordList.length === 0) { | |
bbox[0].set([0, 0, 0]); | |
bbox[1].set([0, 0, 0]); | |
} | |
var min = bbox[0]; | |
var max = bbox[1]; | |
var r, r2; | |
var maxRadius2; | |
var probeRadius, scaleFactor, setAtomID, probePositions; | |
var lastClip = -1; | |
var dim, matrix2, grid, atomIndex; | |
var gridx, gridy, gridz; | |
var sinTable, cosTable; | |
var hash; | |
var neighbours; | |
var atob2 = new Float32Array([0, 0, 0]); | |
var mid = new Float32Array([0, 0, 0]); | |
var n1 = new Float32Array([0, 0, 0]); | |
var n2 = new Float32Array([0, 0, 0]); | |
var ngTorus; | |
function init3(_probeRadius, _scaleFactor, _setAtomID, _probePositions) { | |
probeRadius = defaults(_probeRadius, 1.4); | |
scaleFactor = defaults(_scaleFactor, 2); | |
setAtomID = defaults(_setAtomID, true); | |
probePositions = defaults(_probePositions, 30); | |
r = new Float32Array(nAtoms); | |
r2 = new Float32Array(nAtoms); | |
for (var i2 = 0; i2 < r.length; ++i2) { | |
var rExt = radiusList[i2] + probeRadius; | |
r[i2] = rExt; | |
r2[i2] = rExt * rExt; | |
} | |
maxRadius2 = 0; | |
for (var j = 0; j < r.length; ++j) { | |
if (r[j] > maxRadius2) { | |
maxRadius2 = r[j]; | |
} | |
} | |
initializeGrid(); | |
initializeAngleTables(); | |
initializeHash(); | |
lastClip = -1; | |
} | |
__name(init3, "init"); | |
function fillGridDim(a, start, step) { | |
for (var i2 = 0; i2 < a.length; i2++) { | |
a[i2] = start + step * i2; | |
} | |
} | |
__name(fillGridDim, "fillGridDim"); | |
function initializeGrid() { | |
var surfGrid = getSurfaceGrid(min, max, maxRadius2, scaleFactor, 0); | |
scaleFactor = surfGrid.scaleFactor; | |
dim = surfGrid.dim; | |
matrix2 = surfGrid.matrix; | |
ngTorus = Math.max(5, 2 + Math.floor(probeRadius * scaleFactor)); | |
grid = uniformArray(dim[0] * dim[1] * dim[2], -1001); | |
atomIndex = new Int32Array(grid.length); | |
gridx = new Float32Array(dim[0]); | |
gridy = new Float32Array(dim[1]); | |
gridz = new Float32Array(dim[2]); | |
fillGridDim(gridx, min[0], 1 / scaleFactor); | |
fillGridDim(gridy, min[1], 1 / scaleFactor); | |
fillGridDim(gridz, min[2], 1 / scaleFactor); | |
} | |
__name(initializeGrid, "initializeGrid"); | |
function initializeAngleTables() { | |
var theta = 0; | |
var step = 2 * Math.PI / probePositions; | |
cosTable = new Float32Array(probePositions); | |
sinTable = new Float32Array(probePositions); | |
for (var i2 = 0; i2 < probePositions; i2++) { | |
cosTable[i2] = Math.cos(theta); | |
sinTable[i2] = Math.sin(theta); | |
theta += step; | |
} | |
} | |
__name(initializeAngleTables, "initializeAngleTables"); | |
function initializeHash() { | |
hash = makeAVHash(x, y, z, r, min, max, 2.01 * maxRadius2); | |
neighbours = new Int32Array(hash.neighbourListLength); | |
} | |
__name(initializeHash, "initializeHash"); | |
function obscured(x2, y2, z2, a, b) { | |
var ai; | |
if (lastClip !== -1) { | |
ai = lastClip; | |
if (ai !== a && ai !== b && singleAtomObscures(ai, x2, y2, z2)) { | |
return ai; | |
} else { | |
lastClip = -1; | |
} | |
} | |
var ni = 0; | |
ai = neighbours[ni]; | |
while (ai >= 0) { | |
if (ai !== a && ai !== b && singleAtomObscures(ai, x2, y2, z2)) { | |
lastClip = ai; | |
return ai; | |
} | |
ai = neighbours[++ni]; | |
} | |
lastClip = -1; | |
return -1; | |
} | |
__name(obscured, "obscured"); | |
function singleAtomObscures(ai, x2, y2, z2) { | |
var ci2 = 3 * ai; | |
var ra2 = r2[ai]; | |
var dx = coordList[ci2] - x2; | |
var dy = coordList[ci2 + 1] - y2; | |
var dz = coordList[ci2 + 2] - z2; | |
var d2 = dx * dx + dy * dy + dz * dz; | |
return d2 < ra2; | |
} | |
__name(singleAtomObscures, "singleAtomObscures"); | |
function projectPoints() { | |
for (var i2 = 0; i2 < nAtoms; i2++) { | |
var ax = x[i2]; | |
var ay = y[i2]; | |
var az = z[i2]; | |
var ar = r[i2]; | |
var ar2 = r2[i2]; | |
hash.withinRadii(ax, ay, az, ar, neighbours); | |
var ng = Math.ceil(ar * scaleFactor); | |
var iax = Math.floor(scaleFactor * (ax - min[0])); | |
var iay = Math.floor(scaleFactor * (ay - min[1])); | |
var iaz = Math.floor(scaleFactor * (az - min[2])); | |
var minx = Math.max(0, iax - ng); | |
var miny = Math.max(0, iay - ng); | |
var minz = Math.max(0, iaz - ng); | |
var maxx = Math.min(dim[0], iax + ng + 2); | |
var maxy = Math.min(dim[1], iay + ng + 2); | |
var maxz = Math.min(dim[2], iaz + ng + 2); | |
for (var ix = minx; ix < maxx; ix++) { | |
var dx = gridx[ix] - ax; | |
var xoffset = dim[1] * dim[2] * ix; | |
for (var iy = miny; iy < maxy; iy++) { | |
var dy = gridy[iy] - ay; | |
var dxy2 = dx * dx + dy * dy; | |
var xyoffset = xoffset + dim[2] * iy; | |
for (var iz = minz; iz < maxz; iz++) { | |
var dz = gridz[iz] - az; | |
var d2 = dxy2 + dz * dz; | |
if (d2 < ar2) { | |
var idx = iz + xyoffset; | |
if (grid[idx] < 0) { | |
grid[idx] = -grid[idx]; | |
} | |
var d = Math.sqrt(d2); | |
var ap = ar / d; | |
var spx = dx * ap; | |
var spy = dy * ap; | |
var spz = dz * ap; | |
spx += ax; | |
spy += ay; | |
spz += az; | |
if (obscured(spx, spy, spz, i2, -1) === -1) { | |
var dd = ar - d; | |
if (dd < grid[idx]) { | |
grid[idx] = dd; | |
if (setAtomID) { | |
atomIndex[idx] = i2; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
__name(projectPoints, "projectPoints"); | |
function projectTorii() { | |
for (var i2 = 0; i2 < nAtoms; i2++) { | |
hash.withinRadii(x[i2], y[i2], z[i2], r[i2], neighbours); | |
var ia = 0; | |
var ni = neighbours[ia]; | |
while (ni >= 0) { | |
if (i2 < ni) { | |
projectTorus(i2, ni); | |
} | |
ni = neighbours[++ia]; | |
} | |
} | |
} | |
__name(projectTorii, "projectTorii"); | |
function projectTorus(a, b) { | |
var r1 = r[a]; | |
var r22 = r[b]; | |
var dx = atob2[0] = x[b] - x[a]; | |
var dy = atob2[1] = y[b] - y[a]; | |
var dz = atob2[2] = z[b] - z[a]; | |
var d2 = dx * dx + dy * dy + dz * dz; | |
var d = Math.sqrt(d2); | |
var cosA = (r1 * r1 + d * d - r22 * r22) / (2 * r1 * d); | |
var dmp = r1 * cosA; | |
v3normalize(atob2, atob2); | |
normalToLine(n1, atob2); | |
v3normalize(n1, n1); | |
v3cross(n2, atob2, n1); | |
v3normalize(n2, n2); | |
var rInt = Math.sqrt(r1 * r1 - dmp * dmp); | |
v3multiplyScalar(n1, n1, rInt); | |
v3multiplyScalar(n2, n2, rInt); | |
v3multiplyScalar(atob2, atob2, dmp); | |
mid[0] = atob2[0] + x[a]; | |
mid[1] = atob2[1] + y[a]; | |
mid[2] = atob2[2] + z[a]; | |
lastClip = -1; | |
var ng = ngTorus; | |
for (var i2 = 0; i2 < probePositions; i2++) { | |
var cost = cosTable[i2]; | |
var sint = sinTable[i2]; | |
var px2 = mid[0] + cost * n1[0] + sint * n2[0]; | |
var py2 = mid[1] + cost * n1[1] + sint * n2[1]; | |
var pz2 = mid[2] + cost * n1[2] + sint * n2[2]; | |
if (obscured(px2, py2, pz2, a, b) === -1) { | |
var iax = Math.floor(scaleFactor * (px2 - min[0])); | |
var iay = Math.floor(scaleFactor * (py2 - min[1])); | |
var iaz = Math.floor(scaleFactor * (pz2 - min[2])); | |
var minx = Math.max(0, iax - ng); | |
var miny = Math.max(0, iay - ng); | |
var minz = Math.max(0, iaz - ng); | |
var maxx = Math.min(dim[0], iax + ng + 2); | |
var maxy = Math.min(dim[1], iay + ng + 2); | |
var maxz = Math.min(dim[2], iaz + ng + 2); | |
for (var ix = minx; ix < maxx; ix++) { | |
dx = px2 - gridx[ix]; | |
var xoffset = dim[1] * dim[2] * ix; | |
for (var iy = miny; iy < maxy; iy++) { | |
dy = py2 - gridy[iy]; | |
var dxy2 = dx * dx + dy * dy; | |
var xyoffset = xoffset + dim[2] * iy; | |
for (var iz = minz; iz < maxz; iz++) { | |
dz = pz2 - gridz[iz]; | |
d2 = dxy2 + dz * dz; | |
var idx = iz + xyoffset; | |
var current = grid[idx]; | |
if (current > 0 && d2 < current * current) { | |
grid[idx] = Math.sqrt(d2); | |
if (setAtomID) { | |
var dp = dx * atob2[0] + dy * atob2[1] + dz * atob2[2]; | |
atomIndex[idx] = dp < 0 ? b : a; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
__name(projectTorus, "projectTorus"); | |
function normalToLine(out, p) { | |
out[0] = out[1] = out[2] = 1; | |
if (p[0] !== 0) { | |
out[0] = (p[1] + p[2]) / -p[0]; | |
} else if (p[1] !== 0) { | |
out[1] = (p[0] + p[2]) / -p[1]; | |
} else if (p[2] !== 0) { | |
out[2] = (p[0] + p[1]) / -p[2]; | |
} | |
return out; | |
} | |
__name(normalToLine, "normalToLine"); | |
function fixNegatives() { | |
for (var i2 = 0; i2 < grid.length; i2++) { | |
if (grid[i2] < 0) { | |
grid[i2] = 0; | |
} | |
} | |
} | |
__name(fixNegatives, "fixNegatives"); | |
function fixAtomIDs() { | |
for (var i2 = 0; i2 < atomIndex.length; i2++) { | |
atomIndex[i2] = indexList[atomIndex[i2]]; | |
} | |
} | |
__name(fixAtomIDs, "fixAtomIDs"); | |
function getVolume(probeRadius2, scaleFactor2, setAtomID2) { | |
console.time("AVSurface.getVolume"); | |
console.time("AVSurface.init"); | |
init3(probeRadius2, scaleFactor2, setAtomID2); | |
console.timeEnd("AVSurface.init"); | |
console.time("AVSurface.projectPoints"); | |
projectPoints(); | |
console.timeEnd("AVSurface.projectPoints"); | |
console.time("AVSurface.projectTorii"); | |
projectTorii(); | |
console.timeEnd("AVSurface.projectTorii"); | |
fixNegatives(); | |
fixAtomIDs(); | |
console.timeEnd("AVSurface.getVolume"); | |
} | |
__name(getVolume, "getVolume"); | |
this.getSurface = function(type, probeRadius2, scaleFactor2, cutoff, setAtomID2, smooth, contour) { | |
getVolume(probeRadius2, scaleFactor2, setAtomID2); | |
var volsurf = new VolumeSurface(grid, dim[2], dim[1], dim[0], atomIndex); | |
return volsurf.getSurface(probeRadius2, false, void 0, matrix2, contour); | |
}; | |
} | |
function EDTSurface(coordList, radiusList, indexList) { | |
var radiusDict = getRadiusDict(radiusList); | |
var bbox = computeBoundingBox(coordList); | |
if (coordList.length === 0) { | |
bbox[0].set([0, 0, 0]); | |
bbox[1].set([0, 0, 0]); | |
} | |
var min = bbox[0]; | |
var max = bbox[1]; | |
var probeRadius, scaleFactor, cutoff; | |
var pLength, pWidth, pHeight; | |
var matrix2, ptran; | |
var depty, widxz; | |
var cutRadius; | |
var setAtomID; | |
var vpBits, vpDistance, vpAtomID; | |
function init3(btype, _probeRadius, _scaleFactor, _cutoff, _setAtomID) { | |
probeRadius = _probeRadius || 1.4; | |
scaleFactor = _scaleFactor || 2; | |
setAtomID = _setAtomID || true; | |
var maxRadius2 = 0; | |
for (var radius in radiusDict) { | |
maxRadius2 = Math.max(maxRadius2, radius); | |
} | |
var grid = getSurfaceGrid(min, max, maxRadius2, scaleFactor, btype ? probeRadius : 0); | |
pLength = grid.dim[0]; | |
pWidth = grid.dim[1]; | |
pHeight = grid.dim[2]; | |
matrix2 = grid.matrix; | |
ptran = grid.tran; | |
scaleFactor = grid.scaleFactor; | |
depty = {}; | |
widxz = {}; | |
boundingatom(btype); | |
cutRadius = probeRadius * scaleFactor; | |
if (_cutoff) { | |
cutoff = _cutoff; | |
} else { | |
cutoff = probeRadius / scaleFactor; | |
} | |
vpBits = new Uint8Array(pLength * pWidth * pHeight); | |
if (btype) { | |
vpDistance = new Float64Array(pLength * pWidth * pHeight); | |
} | |
if (setAtomID) { | |
vpAtomID = new Int32Array(pLength * pWidth * pHeight); | |
} | |
} | |
__name(init3, "init"); | |
var INOUT = 1; | |
var ISDONE = 2; | |
var ISBOUND = 4; | |
var nb = [ | |
new Int32Array([1, 0, 0]), | |
new Int32Array([-1, 0, 0]), | |
new Int32Array([0, 1, 0]), | |
new Int32Array([0, -1, 0]), | |
new Int32Array([0, 0, 1]), | |
new Int32Array([0, 0, -1]), | |
new Int32Array([1, 1, 0]), | |
new Int32Array([1, -1, 0]), | |
new Int32Array([-1, 1, 0]), | |
new Int32Array([-1, -1, 0]), | |
new Int32Array([1, 0, 1]), | |
new Int32Array([1, 0, -1]), | |
new Int32Array([-1, 0, 1]), | |
new Int32Array([-1, 0, -1]), | |
new Int32Array([0, 1, 1]), | |
new Int32Array([0, 1, -1]), | |
new Int32Array([0, -1, 1]), | |
new Int32Array([0, -1, -1]), | |
new Int32Array([1, 1, 1]), | |
new Int32Array([1, 1, -1]), | |
new Int32Array([1, -1, 1]), | |
new Int32Array([-1, 1, 1]), | |
new Int32Array([1, -1, -1]), | |
new Int32Array([-1, -1, 1]), | |
new Int32Array([-1, 1, -1]), | |
new Int32Array([-1, -1, -1]) | |
]; | |
this.getVolume = function(type, probeRadius2, scaleFactor2, cutoff2, setAtomID2) { | |
console.time("EDTSurface.getVolume"); | |
var btype = type !== "vws"; | |
init3(btype, probeRadius2, scaleFactor2, cutoff2, setAtomID2); | |
fillvoxels(btype); | |
buildboundary(); | |
if (type === "ms" || type === "ses") { | |
fastdistancemap(); | |
} | |
if (type === "ses") { | |
boundingatom(false); | |
fillvoxelswaals(); | |
} | |
marchingcubeinit(type); | |
for (var i = 0, il = vpAtomID.length; i < il; ++i) { | |
vpAtomID[i] = indexList[vpAtomID[i]]; | |
} | |
console.timeEnd("EDTSurface.getVolume"); | |
return { | |
data: vpBits, | |
nx: pHeight, | |
ny: pWidth, | |
nz: pLength, | |
atomindex: vpAtomID | |
}; | |
}; | |
this.getSurface = function(type, probeRadius2, scaleFactor2, cutoff2, setAtomID2, smooth, contour) { | |
var vd = this.getVolume(type, probeRadius2, scaleFactor2, cutoff2, setAtomID2); | |
var volsurf = new VolumeSurface(vd.data, vd.nx, vd.ny, vd.nz, vd.atomindex); | |
return volsurf.getSurface(1, smooth, void 0, matrix2, contour); | |
}; | |
function boundingatom(btype) { | |
var r; | |
var j; | |
var k; | |
var txz; | |
var tdept; | |
var sradius; | |
var tradius; | |
var widxzR; | |
var deptyName; | |
var indx; | |
for (var name in radiusDict) { | |
r = parseFloat(name); | |
if (depty[name]) { | |
continue; | |
} | |
if (!btype) { | |
tradius = r * scaleFactor + 0.5; | |
} else { | |
tradius = (r + probeRadius) * scaleFactor + 0.5; | |
} | |
sradius = tradius * tradius; | |
widxzR = Math.floor(tradius) + 1; | |
deptyName = new Int32Array(widxzR * widxzR); | |
indx = 0; | |
for (j = 0; j < widxzR; ++j) { | |
for (k = 0; k < widxzR; ++k) { | |
txz = j * j + k * k; | |
if (txz > sradius) { | |
deptyName[indx] = -1; | |
} else { | |
tdept = Math.sqrt(sradius - txz); | |
deptyName[indx] = Math.floor(tdept); | |
} | |
++indx; | |
} | |
} | |
widxz[name] = widxzR; | |
depty[name] = deptyName; | |
} | |
} | |
__name(boundingatom, "boundingatom"); | |
function fillatom(idx) { | |
var ci = idx * 3; | |
var ri = idx; | |
var cx, cy, cz, ox, oy, oz, mi, mj, mk, i, j, k, si, sj, sk; | |
var ii, jj, kk; | |
cx = Math.floor(0.5 + scaleFactor * (coordList[ci] + ptran[0])); | |
cy = Math.floor(0.5 + scaleFactor * (coordList[ci + 1] + ptran[1])); | |
cz = Math.floor(0.5 + scaleFactor * (coordList[ci + 2] + ptran[2])); | |
var at = radiusList[ri]; | |
var deptyAt = depty[at]; | |
var nind = 0; | |
var pWH = pWidth * pHeight; | |
var n = widxz[at]; | |
var deptyAtNind; | |
for (i = 0; i < n; ++i) { | |
for (j = 0; j < n; ++j) { | |
deptyAtNind = deptyAt[nind]; | |
if (deptyAtNind !== -1) { | |
for (ii = -1; ii < 2; ++ii) { | |
for (jj = -1; jj < 2; ++jj) { | |
for (kk = -1; kk < 2; ++kk) { | |
if (ii !== 0 && jj !== 0 && kk !== 0) { | |
mi = ii * i; | |
mk = kk * j; | |
for (k = 0; k <= deptyAtNind; ++k) { | |
mj = k * jj; | |
si = cx + mi; | |
sj = cy + mj; | |
sk = cz + mk; | |
if (si < 0 || sj < 0 || sk < 0 || si >= pLength || sj >= pWidth || sk >= pHeight) { | |
continue; | |
} | |
var index = si * pWH + sj * pHeight + sk; | |
if (!setAtomID) { | |
vpBits[index] |= INOUT; | |
} else { | |
if (!(vpBits[index] & INOUT)) { | |
vpBits[index] |= INOUT; | |
vpAtomID[index] = idx; | |
} else if (vpBits[index] & INOUT) { | |
var ci2 = vpAtomID[index]; | |
if (ci2 !== ci) { | |
ox = cx + mi - Math.floor(0.5 + scaleFactor * (coordList[ci2] + ptran[0])); | |
oy = cy + mj - Math.floor(0.5 + scaleFactor * (coordList[ci2 + 1] + ptran[1])); | |
oz = cz + mk - Math.floor(0.5 + scaleFactor * (coordList[ci2 + 2] + ptran[2])); | |
if (mi * mi + mj * mj + mk * mk < ox * ox + oy * oy + oz * oz) { | |
vpAtomID[index] = idx; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
nind++; | |
} | |
} | |
} | |
__name(fillatom, "fillatom"); | |
function fillvoxels(btype) { | |
console.time("EDTSurface fillvoxels"); | |
var i, il; | |
for (i = 0, il = vpBits.length; i < il; ++i) { | |
vpBits[i] = 0; | |
if (btype) { | |
vpDistance[i] = -1; | |
} | |
if (setAtomID) { | |
vpAtomID[i] = -1; | |
} | |
} | |
for (i = 0, il = coordList.length / 3; i < il; ++i) { | |
fillatom(i); | |
} | |
for (i = 0, il = vpBits.length; i < il; ++i) { | |
if (vpBits[i] & INOUT) { | |
vpBits[i] |= ISDONE; | |
} | |
} | |
console.timeEnd("EDTSurface fillvoxels"); | |
} | |
__name(fillvoxels, "fillvoxels"); | |
function fillAtomWaals(idx) { | |
var ci = idx * 3; | |
var ri = idx; | |
var cx; | |
var cy; | |
var cz; | |
var ox; | |
var oy; | |
var oz; | |
var nind = 0; | |
var mi; | |
var mj; | |
var mk; | |
var si; | |
var sj; | |
var sk; | |
var i; | |
var j; | |
var k; | |
var ii; | |
var jj; | |
var kk; | |
var n; | |
cx = Math.floor(0.5 + scaleFactor * (coordList[ci] + ptran[0])); | |
cy = Math.floor(0.5 + scaleFactor * (coordList[ci + 1] + ptran[1])); | |
cz = Math.floor(0.5 + scaleFactor * (coordList[ci + 2] + ptran[2])); | |
var at = radiusList[ri]; | |
var pWH = pWidth * pHeight; | |
for (i = 0, n = widxz[at]; i < n; ++i) { | |
for (j = 0; j < n; ++j) { | |
if (depty[at][nind] !== -1) { | |
for (ii = -1; ii < 2; ++ii) { | |
for (jj = -1; jj < 2; ++jj) { | |
for (kk = -1; kk < 2; ++kk) { | |
if (ii !== 0 && jj !== 0 && kk !== 0) { | |
mi = ii * i; | |
mk = kk * j; | |
for (k = 0; k <= depty[at][nind]; ++k) { | |
mj = k * jj; | |
si = cx + mi; | |
sj = cy + mj; | |
sk = cz + mk; | |
if (si < 0 || sj < 0 || sk < 0 || si >= pLength || sj >= pWidth || sk >= pHeight) { | |
continue; | |
} | |
var index = si * pWH + sj * pHeight + sk; | |
if (!(vpBits[index] & ISDONE)) { | |
vpBits[index] |= ISDONE; | |
if (setAtomID) { | |
vpAtomID[index] = idx; | |
} | |
} else if (setAtomID) { | |
var ci2 = vpAtomID[index]; | |
ox = Math.floor(0.5 + scaleFactor * (coordList[ci2] + ptran[0])); | |
oy = Math.floor(0.5 + scaleFactor * (coordList[ci2 + 1] + ptran[1])); | |
oz = Math.floor(0.5 + scaleFactor * (coordList[ci2 + 2] + ptran[2])); | |
if (mi * mi + mj * mj + mk * mk < ox * ox + oy * oy + oz * oz) { | |
vpAtomID[index] = idx; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
nind++; | |
} | |
} | |
} | |
__name(fillAtomWaals, "fillAtomWaals"); | |
function fillvoxelswaals() { | |
var i, il; | |
for (i = 0, il = vpBits.length; i < il; ++i) { | |
vpBits[i] &= ~ISDONE; | |
} | |
for (i = 0, il = coordList.length / 3; i < il; ++i) { | |
fillAtomWaals(i); | |
} | |
} | |
__name(fillvoxelswaals, "fillvoxelswaals"); | |
function buildboundary() { | |
var i, j, k; | |
var pWH = pWidth * pHeight; | |
for (i = 0; i < pLength; ++i) { | |
for (j = 0; j < pHeight; ++j) { | |
for (k = 0; k < pWidth; ++k) { | |
var index = i * pWH + k * pHeight + j; | |
if (vpBits[index] & INOUT) { | |
var ii = 0; | |
while (ii < 26) { | |
var ti = i + nb[ii][0]; | |
var tj = j + nb[ii][2]; | |
var tk = k + nb[ii][1]; | |
if (ti > -1 && ti < pLength && tk > -1 && tk < pWidth && tj > -1 && tj < pHeight && !(vpBits[ti * pWH + tk * pHeight + tj] & INOUT)) { | |
vpBits[index] |= ISBOUND; | |
break; | |
} else { | |
ii++; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
__name(buildboundary, "buildboundary"); | |
function fastdistancemap() { | |
console.time("EDTSurface fastdistancemap"); | |
var i, j, k, n; | |
var boundPoint = makeGrid(pLength, pWidth, pHeight, Uint16Array, 3); | |
var pWH = pWidth * pHeight; | |
var cutRSq = cutRadius * cutRadius; | |
var totalsurfacevox = 0; | |
var index; | |
for (i = 0; i < pLength; ++i) { | |
for (j = 0; j < pWidth; ++j) { | |
for (k = 0; k < pHeight; ++k) { | |
index = i * pWH + j * pHeight + k; | |
vpBits[index] &= ~ISDONE; | |
if (vpBits[index] & INOUT) { | |
if (vpBits[index] & ISBOUND) { | |
boundPoint.set(i, j, k, i, j, k); | |
vpDistance[index] = 0; | |
vpBits[index] |= ISDONE; | |
totalsurfacevox += 1; | |
} | |
} | |
} | |
} | |
} | |
var inarray = new Int32Array(3 * totalsurfacevox); | |
var positin = 0; | |
var outarray = new Int32Array(3 * totalsurfacevox); | |
var positout = 0; | |
for (i = 0; i < pLength; ++i) { | |
for (j = 0; j < pWidth; ++j) { | |
for (k = 0; k < pHeight; ++k) { | |
index = i * pWH + j * pHeight + k; | |
if (vpBits[index] & ISBOUND) { | |
inarray[positin] = i; | |
inarray[positin + 1] = j; | |
inarray[positin + 2] = k; | |
positin += 3; | |
vpBits[index] &= ~ISBOUND; | |
} | |
} | |
} | |
} | |
do { | |
positout = fastoneshell(inarray, boundPoint, positin, outarray); | |
positin = 0; | |
for (i = 0, n = positout; i < n; i += 3) { | |
index = pWH * outarray[i] + pHeight * outarray[i + 1] + outarray[i + 2]; | |
vpBits[index] &= ~ISBOUND; | |
if (vpDistance[index] <= 1.0404 * cutRSq) { | |
inarray[positin] = outarray[i]; | |
inarray[positin + 1] = outarray[i + 1]; | |
inarray[positin + 2] = outarray[i + 2]; | |
positin += 3; | |
} | |
} | |
} while (positin > 0); | |
var cutoffSq = cutoff * cutoff; | |
var index2; | |
var bp = new Uint16Array(3); | |
for (i = 0; i < pLength; ++i) { | |
for (j = 0; j < pWidth; ++j) { | |
for (k = 0; k < pHeight; ++k) { | |
index = i * pWH + j * pHeight + k; | |
vpBits[index] &= ~ISBOUND; | |
if (vpBits[index] & INOUT) { | |
if (!(vpBits[index] & ISDONE) || vpBits[index] & ISDONE && vpDistance[index] >= cutoffSq) { | |
vpBits[index] |= ISBOUND; | |
if (setAtomID && vpBits[index] & ISDONE) { | |
boundPoint.toArray(i, j, k, bp); | |
index2 = bp[0] * pWH + bp[1] * pHeight + bp[2]; | |
vpAtomID[index] = vpAtomID[index2]; | |
} | |
} | |
} | |
} | |
} | |
} | |
console.timeEnd("EDTSurface fastdistancemap"); | |
} | |
__name(fastdistancemap, "fastdistancemap"); | |
function fastoneshell(inarray, boundPoint, positin, outarray) { | |
var tx, ty, tz; | |
var dx, dy, dz; | |
var i, j, n; | |
var square; | |
var index; | |
var nbj; | |
var bp = new Uint16Array(3); | |
var positout = 0; | |
if (positin === 0) { | |
return positout; | |
} | |
var tnvix = -1; | |
var tnviy = -1; | |
var tnviz = -1; | |
var pWH = pWidth * pHeight; | |
for (i = 0, n = positin; i < n; i += 3) { | |
tx = inarray[i]; | |
ty = inarray[i + 1]; | |
tz = inarray[i + 2]; | |
boundPoint.toArray(tx, ty, tz, bp); | |
for (j = 0; j < 6; ++j) { | |
nbj = nb[j]; | |
tnvix = tx + nbj[0]; | |
tnviy = ty + nbj[1]; | |
tnviz = tz + nbj[2]; | |
if (tnvix < pLength && tnvix > -1 && tnviy < pWidth && tnviy > -1 && tnviz < pHeight && tnviz > -1) { | |
index = tnvix * pWH + pHeight * tnviy + tnviz; | |
if (vpBits[index] & INOUT && !(vpBits[index] & ISDONE)) { | |
boundPoint.fromArray(tnvix, tnviy, tnviz, bp); | |
dx = tnvix - bp[0]; | |
dy = tnviy - bp[1]; | |
dz = tnviz - bp[2]; | |
square = dx * dx + dy * dy + dz * dz; | |
vpDistance[index] = square; | |
vpBits[index] |= ISDONE; | |
vpBits[index] |= ISBOUND; | |
outarray[positout] = tnvix; | |
outarray[positout + 1] = tnviy; | |
outarray[positout + 2] = tnviz; | |
positout += 3; | |
} else if (vpBits[index] & INOUT && vpBits[index] & ISDONE) { | |
dx = tnvix - bp[0]; | |
dy = tnviy - bp[1]; | |
dz = tnviz - bp[2]; | |
square = dx * dx + dy * dy + dz * dz; | |
if (square < vpDistance[index]) { | |
boundPoint.fromArray(tnvix, tnviy, tnviz, bp); | |
vpDistance[index] = square; | |
if (!(vpBits[index] & ISBOUND)) { | |
vpBits[index] |= ISBOUND; | |
outarray[positout] = tnvix; | |
outarray[positout + 1] = tnviy; | |
outarray[positout + 2] = tnviz; | |
positout += 3; | |
} | |
} | |
} | |
} | |
} | |
} | |
for (i = 0, n = positin; i < n; i += 3) { | |
tx = inarray[i]; | |
ty = inarray[i + 1]; | |
tz = inarray[i + 2]; | |
boundPoint.toArray(tx, ty, tz, bp); | |
for (j = 6; j < 18; j++) { | |
nbj = nb[j]; | |
tnvix = tx + nbj[0]; | |
tnviy = ty + nbj[1]; | |
tnviz = tz + nbj[2]; | |
if (tnvix < pLength && tnvix > -1 && tnviy < pWidth && tnviy > -1 && tnviz < pHeight && tnviz > -1) { | |
index = tnvix * pWH + pHeight * tnviy + tnviz; | |
if (vpBits[index] & INOUT && !(vpBits[index] & ISDONE)) { | |
boundPoint.fromArray(tnvix, tnviy, tnviz, bp); | |
dx = tnvix - bp[0]; | |
dy = tnviy - bp[1]; | |
dz = tnviz - bp[2]; | |
square = dx * dx + dy * dy + dz * dz; | |
vpDistance[index] = square; | |
vpBits[index] |= ISDONE; | |
vpBits[index] |= ISBOUND; | |
outarray[positout] = tnvix; | |
outarray[positout + 1] = tnviy; | |
outarray[positout + 2] = tnviz; | |
positout += 3; | |
} else if (vpBits[index] & INOUT && vpBits[index] & ISDONE) { | |
dx = tnvix - bp[0]; | |
dy = tnviy - bp[1]; | |
dz = tnviz - bp[2]; | |
square = dx * dx + dy * dy + dz * dz; | |
if (square < vpDistance[index]) { | |
boundPoint.fromArray(tnvix, tnviy, tnviz, bp); | |
vpDistance[index] = square; | |
if (!(vpBits[index] & ISBOUND)) { | |
vpBits[index] |= ISBOUND; | |
outarray[positout] = tnvix; | |
outarray[positout + 1] = tnviy; | |
outarray[positout + 2] = tnviz; | |
positout += 3; | |
} | |
} | |
} | |
} | |
} | |
} | |
for (i = 0, n = positin; i < n; i += 3) { | |
tx = inarray[i]; | |
ty = inarray[i + 1]; | |
tz = inarray[i + 2]; | |
boundPoint.toArray(tx, ty, tz, bp); | |
for (j = 18; j < 26; j++) { | |
nbj = nb[j]; | |
tnvix = tx + nbj[0]; | |
tnviy = ty + nbj[1]; | |
tnviz = tz + nbj[2]; | |
if (tnvix < pLength && tnvix > -1 && tnviy < pWidth && tnviy > -1 && tnviz < pHeight && tnviz > -1) { | |
index = tnvix * pWH + pHeight * tnviy + tnviz; | |
if (vpBits[index] & INOUT && !(vpBits[index] & ISDONE)) { | |
boundPoint.fromArray(tnvix, tnviy, tnviz, bp); | |
dx = tnvix - bp[0]; | |
dy = tnviy - bp[1]; | |
dz = tnviz - bp[2]; | |
square = dx * dx + dy * dy + dz * dz; | |
vpDistance[index] = square; | |
vpBits[index] |= ISDONE; | |
vpBits[index] |= ISBOUND; | |
outarray[positout] = tnvix; | |
outarray[positout + 1] = tnviy; | |
outarray[positout + 2] = tnviz; | |
positout += 3; | |
} else if (vpBits[index] & INOUT && vpBits[index] & ISDONE) { | |
dx = tnvix - bp[0]; | |
dy = tnviy - bp[1]; | |
dz = tnviz - bp[2]; | |
square = dx * dx + dy * dy + dz * dz; | |
if (square < vpDistance[index]) { | |
boundPoint.fromArray(tnvix, tnviy, tnviz, bp); | |
vpDistance[index] = square; | |
if (!(vpBits[index] & ISBOUND)) { | |
vpBits[index] |= ISBOUND; | |
outarray[positout] = tnvix; | |
outarray[positout + 1] = tnviy; | |
outarray[positout + 2] = tnviz; | |
positout += 3; | |
} | |
} | |
} | |
} | |
} | |
} | |
return positout; | |
} | |
__name(fastoneshell, "fastoneshell"); | |
function marchingcubeinit(stype) { | |
var i; | |
var n = vpBits.length; | |
if (stype === "vws") { | |
for (i = 0; i < n; ++i) { | |
vpBits[i] &= ~ISBOUND; | |
vpBits[i] = vpBits[i] & ISDONE ? 1 : 0; | |
} | |
} else if (stype === "ms") { | |
for (i = 0; i < n; ++i) { | |
vpBits[i] &= ~ISDONE; | |
if (vpBits[i] & ISBOUND) { | |
vpBits[i] |= ISDONE; | |
} | |
vpBits[i] &= ~ISBOUND; | |
vpBits[i] = vpBits[i] & ISDONE ? 1 : 0; | |
} | |
} else if (stype === "ses") { | |
for (i = 0; i < n; ++i) { | |
if (vpBits[i] & ISBOUND && vpBits[i] & ISDONE) { | |
vpBits[i] &= ~ISBOUND; | |
} else if (vpBits[i] & ISBOUND && !(vpBits[i] & ISDONE)) { | |
vpBits[i] |= ISDONE; | |
} | |
vpBits[i] = vpBits[i] & ISDONE ? 1 : 0; | |
} | |
} else if (stype === "sas") { | |
for (i = 0; i < n; ++i) { | |
vpBits[i] &= ~ISBOUND; | |
vpBits[i] = vpBits[i] & ISDONE ? 1 : 0; | |
} | |
} | |
} | |
__name(marchingcubeinit, "marchingcubeinit"); | |
} | |
function MarchingCubes(field, nx, ny, nz, atomindex) { | |
var isolevel = 0; | |
var noNormals = false; | |
var contour = false; | |
var wrap = false; | |
var isNegativeIso = false; | |
var normalFactor = -1; | |
var n = nx * ny * nz; | |
var yd = nx; | |
var zd = nx * ny; | |
var normalCache, vertexIndex; | |
var count, icount; | |
var ilist = new Int32Array(12); | |
var positionArray = []; | |
var normalArray = []; | |
var indexArray = []; | |
var atomindexArray = []; | |
var edgeTable = getEdgeTable(); | |
var triTable = getTriTable(); | |
var allowedContours = getAllowedContours(); | |
var mx, my, mz; | |
this.triangulate = function(_isolevel, _noNormals, _box2, _contour, _wrap) { | |
isolevel = _isolevel; | |
isNegativeIso = isolevel < 0; | |
contour = _contour; | |
wrap = _wrap; | |
noNormals = _noNormals || contour; | |
if (!noNormals) { | |
normalFactor = isolevel > 0 ? -1 : 1; | |
if (!normalCache) { | |
normalCache = new Float32Array(n * 3); | |
} | |
} | |
var vIndexLength = n * 3; | |
if (!vertexIndex || vertexIndex.length !== vIndexLength) { | |
vertexIndex = new Int32Array(vIndexLength); | |
} | |
count = 0; | |
icount = 0; | |
if (_box2 !== void 0) { | |
var min = _box2[0].map(Math.round); | |
var max = _box2[1].map(Math.round); | |
mx = nx * Math.ceil(Math.abs(min[0]) / nx); | |
my = ny * Math.ceil(Math.abs(min[1]) / ny); | |
mz = nz * Math.ceil(Math.abs(min[2]) / nz); | |
triangulate(min[0], min[1], min[2], max[0], max[1], max[2]); | |
} else { | |
mx = my = mz = 0; | |
triangulate(); | |
} | |
positionArray.length = count * 3; | |
if (!noNormals) { | |
normalArray.length = count * 3; | |
} | |
indexArray.length = icount; | |
if (atomindex) { | |
atomindexArray.length = count; | |
} | |
return { | |
position: new Float32Array(positionArray), | |
normal: noNormals ? void 0 : new Float32Array(normalArray), | |
index: getUintArray(indexArray, positionArray.length / 3), | |
atomindex: atomindex ? new Int32Array(atomindexArray) : void 0, | |
contour | |
}; | |
}; | |
function lerp2(a, b, t) { | |
return a + (b - a) * t; | |
} | |
__name(lerp2, "lerp"); | |
function index(x, y, z) { | |
x = (x + mx) % nx; | |
y = (y + my) % ny; | |
z = (z + mz) % nz; | |
return zd * z + yd * y + x; | |
} | |
__name(index, "index"); | |
function VIntX(q, offset, x, y, z, valp1, valp2) { | |
var _q = 3 * q; | |
if (vertexIndex[_q] < 0) { | |
var mu = (isolevel - valp1) / (valp2 - valp1); | |
var nc = normalCache; | |
var c = count * 3; | |
positionArray[c + 0] = x + mu; | |
positionArray[c + 1] = y; | |
positionArray[c + 2] = z; | |
if (!noNormals) { | |
var q3 = q * 3; | |
normalArray[c] = normalFactor * lerp2(nc[q3], nc[q3 + 3], mu); | |
normalArray[c + 1] = normalFactor * lerp2(nc[q3 + 1], nc[q3 + 4], mu); | |
normalArray[c + 2] = normalFactor * lerp2(nc[q3 + 2], nc[q3 + 5], mu); | |
} | |
if (atomindex) { | |
atomindexArray[count] = atomindex[q + Math.round(mu)]; | |
} | |
vertexIndex[_q] = count; | |
ilist[offset] = count; | |
count += 1; | |
} else { | |
ilist[offset] = vertexIndex[_q]; | |
} | |
} | |
__name(VIntX, "VIntX"); | |
function VIntY(q, offset, x, y, z, valp1, valp2) { | |
var _q = 3 * q + 1; | |
if (vertexIndex[_q] < 0) { | |
var mu = (isolevel - valp1) / (valp2 - valp1); | |
var nc = normalCache; | |
var c = count * 3; | |
positionArray[c] = x; | |
positionArray[c + 1] = y + mu; | |
positionArray[c + 2] = z; | |
if (!noNormals) { | |
var q3 = q * 3; | |
var q6 = q3 + yd * 3; | |
normalArray[c] = normalFactor * lerp2(nc[q3], nc[q6], mu); | |
normalArray[c + 1] = normalFactor * lerp2(nc[q3 + 1], nc[q6 + 1], mu); | |
normalArray[c + 2] = normalFactor * lerp2(nc[q3 + 2], nc[q6 + 2], mu); | |
} | |
if (atomindex) { | |
atomindexArray[count] = atomindex[q + Math.round(mu) * yd]; | |
} | |
vertexIndex[_q] = count; | |
ilist[offset] = count; | |
count += 1; | |
} else { | |
ilist[offset] = vertexIndex[_q]; | |
} | |
} | |
__name(VIntY, "VIntY"); | |
function VIntZ(q, offset, x, y, z, valp1, valp2) { | |
var _q = 3 * q + 2; | |
if (vertexIndex[_q] < 0) { | |
var mu = (isolevel - valp1) / (valp2 - valp1); | |
var nc = normalCache; | |
var c = count * 3; | |
positionArray[c] = x; | |
positionArray[c + 1] = y; | |
positionArray[c + 2] = z + mu; | |
if (!noNormals) { | |
var q3 = q * 3; | |
var q6 = q3 + zd * 3; | |
normalArray[c] = normalFactor * lerp2(nc[q3], nc[q6], mu); | |
normalArray[c + 1] = normalFactor * lerp2(nc[q3 + 1], nc[q6 + 1], mu); | |
normalArray[c + 2] = normalFactor * lerp2(nc[q3 + 2], nc[q6 + 2], mu); | |
} | |
if (atomindex) { | |
atomindexArray[count] = atomindex[q + Math.round(mu) * zd]; | |
} | |
vertexIndex[_q] = count; | |
ilist[offset] = count; | |
count += 1; | |
} else { | |
ilist[offset] = vertexIndex[_q]; | |
} | |
} | |
__name(VIntZ, "VIntZ"); | |
function compNorm(q) { | |
var q3 = q * 3; | |
if (normalCache[q3] === 0) { | |
normalCache[q3] = field[(q - 1 + n) % n] - field[(q + 1) % n]; | |
normalCache[q3 + 1] = field[(q - yd + n) % n] - field[(q + yd) % n]; | |
normalCache[q3 + 2] = field[(q - zd + n) % n] - field[(q + zd) % n]; | |
} | |
} | |
__name(compNorm, "compNorm"); | |
function polygonize(fx, fy, fz, q, edgeFilter) { | |
var q1; | |
var qy; | |
var qz; | |
var q1y; | |
var q1z; | |
var qyz; | |
var q1yz; | |
if (wrap) { | |
q = index(fx, fy, fz); | |
q1 = index(fx + 1, fy, fz); | |
qy = index(fx, fy + 1, fz); | |
qz = index(fx, fy, fz + 1); | |
q1y = index(fx + 1, fy + 1, fz); | |
q1z = index(fx + 1, fy, fz + 1); | |
qyz = index(fx, fy + 1, fz + 1); | |
q1yz = index(fx + 1, fy + 1, fz + 1); | |
} else { | |
q1 = q + 1; | |
qy = q + yd; | |
qz = q + zd; | |
q1y = qy + 1; | |
q1z = qz + 1; | |
qyz = qy + zd; | |
q1yz = qyz + 1; | |
} | |
var cubeindex = 0; | |
var field0 = field[q]; | |
var field1 = field[q1]; | |
var field2 = field[qy]; | |
var field3 = field[q1y]; | |
var field4 = field[qz]; | |
var field5 = field[q1z]; | |
var field6 = field[qyz]; | |
var field7 = field[q1yz]; | |
if (field0 < isolevel) { | |
cubeindex |= 1; | |
} | |
if (field1 < isolevel) { | |
cubeindex |= 2; | |
} | |
if (field2 < isolevel) { | |
cubeindex |= 8; | |
} | |
if (field3 < isolevel) { | |
cubeindex |= 4; | |
} | |
if (field4 < isolevel) { | |
cubeindex |= 16; | |
} | |
if (field5 < isolevel) { | |
cubeindex |= 32; | |
} | |
if (field6 < isolevel) { | |
cubeindex |= 128; | |
} | |
if (field7 < isolevel) { | |
cubeindex |= 64; | |
} | |
var bits = edgeTable[cubeindex]; | |
if (bits === 0) { | |
return 0; | |
} | |
var fx2 = fx + 1; | |
var fy2 = fy + 1; | |
var fz2 = fz + 1; | |
if (bits & 1) { | |
if (!noNormals) { | |
compNorm(q); | |
compNorm(q1); | |
} | |
VIntX(q, 0, fx, fy, fz, field0, field1); | |
} | |
if (bits & 2) { | |
if (!noNormals) { | |
compNorm(q1); | |
compNorm(q1y); | |
} | |
VIntY(q1, 1, fx2, fy, fz, field1, field3); | |
} | |
if (bits & 4) { | |
if (!noNormals) { | |
compNorm(qy); | |
compNorm(q1y); | |
} | |
VIntX(qy, 2, fx, fy2, fz, field2, field3); | |
} | |
if (bits & 8) { | |
if (!noNormals) { | |
compNorm(q); | |
compNorm(qy); | |
} | |
VIntY(q, 3, fx, fy, fz, field0, field2); | |
} | |
if (bits & 16) { | |
if (!noNormals) { | |
compNorm(qz); | |
compNorm(q1z); | |
} | |
VIntX(qz, 4, fx, fy, fz2, field4, field5); | |
} | |
if (bits & 32) { | |
if (!noNormals) { | |
compNorm(q1z); | |
compNorm(q1yz); | |
} | |
VIntY(q1z, 5, fx2, fy, fz2, field5, field7); | |
} | |
if (bits & 64) { | |
if (!noNormals) { | |
compNorm(qyz); | |
compNorm(q1yz); | |
} | |
VIntX(qyz, 6, fx, fy2, fz2, field6, field7); | |
} | |
if (bits & 128) { | |
if (!noNormals) { | |
compNorm(qz); | |
compNorm(qyz); | |
} | |
VIntY(qz, 7, fx, fy, fz2, field4, field6); | |
} | |
if (bits & 256) { | |
if (!noNormals) { | |
compNorm(q); | |
compNorm(qz); | |
} | |
VIntZ(q, 8, fx, fy, fz, field0, field4); | |
} | |
if (bits & 512) { | |
if (!noNormals) { | |
compNorm(q1); | |
compNorm(q1z); | |
} | |
VIntZ(q1, 9, fx2, fy, fz, field1, field5); | |
} | |
if (bits & 1024) { | |
if (!noNormals) { | |
compNorm(q1y); | |
compNorm(q1yz); | |
} | |
VIntZ(q1y, 10, fx2, fy2, fz, field3, field7); | |
} | |
if (bits & 2048) { | |
if (!noNormals) { | |
compNorm(qy); | |
compNorm(qyz); | |
} | |
VIntZ(qy, 11, fx, fy2, fz, field2, field6); | |
} | |
var triIndex = cubeindex << 4; | |
var e1; | |
var e2; | |
var e3; | |
var i = 0; | |
while (triTable[triIndex + i] !== -1) { | |
e1 = triTable[triIndex + i]; | |
e2 = triTable[triIndex + i + 1]; | |
e3 = triTable[triIndex + i + 2]; | |
if (contour) { | |
if (allowedContours[e1][e2] & edgeFilter) { | |
indexArray[icount++] = ilist[e1]; | |
indexArray[icount++] = ilist[e2]; | |
} | |
if (allowedContours[e2][e3] & edgeFilter) { | |
indexArray[icount++] = ilist[e2]; | |
indexArray[icount++] = ilist[e3]; | |
} | |
if (allowedContours[e1][e3] & edgeFilter) { | |
indexArray[icount++] = ilist[e1]; | |
indexArray[icount++] = ilist[e3]; | |
} | |
} else { | |
indexArray[icount++] = ilist[isNegativeIso ? e1 : e2]; | |
indexArray[icount++] = ilist[isNegativeIso ? e2 : e1]; | |
indexArray[icount++] = ilist[e3]; | |
} | |
i += 3; | |
} | |
} | |
__name(polygonize, "polygonize"); | |
function triangulate(xBeg, yBeg, zBeg, xEnd, yEnd, zEnd) { | |
var q; | |
var q3; | |
var x; | |
var y; | |
var z; | |
var yOffset; | |
var zOffset; | |
xBeg = xBeg !== void 0 ? xBeg : 0; | |
yBeg = yBeg !== void 0 ? yBeg : 0; | |
zBeg = zBeg !== void 0 ? zBeg : 0; | |
xEnd = xEnd !== void 0 ? xEnd : nx - 1; | |
yEnd = yEnd !== void 0 ? yEnd : ny - 1; | |
zEnd = zEnd !== void 0 ? zEnd : nz - 1; | |
if (!wrap) { | |
if (noNormals) { | |
xBeg = Math.max(0, xBeg); | |
yBeg = Math.max(0, yBeg); | |
zBeg = Math.max(0, zBeg); | |
xEnd = Math.min(nx - 1, xEnd); | |
yEnd = Math.min(ny - 1, yEnd); | |
zEnd = Math.min(nz - 1, zEnd); | |
} else { | |
xBeg = Math.max(1, xBeg); | |
yBeg = Math.max(1, yBeg); | |
zBeg = Math.max(1, zBeg); | |
xEnd = Math.min(nx - 2, xEnd); | |
yEnd = Math.min(ny - 2, yEnd); | |
zEnd = Math.min(nz - 2, zEnd); | |
} | |
} | |
var xBeg2, yBeg2, zBeg2, xEnd2, yEnd2, zEnd2; | |
if (!wrap) { | |
xBeg2 = Math.max(0, xBeg - 2); | |
yBeg2 = Math.max(0, yBeg - 2); | |
zBeg2 = Math.max(0, zBeg - 2); | |
xEnd2 = Math.min(nx, xEnd + 2); | |
yEnd2 = Math.min(ny, yEnd + 2); | |
zEnd2 = Math.min(nz, zEnd + 2); | |
for (z = zBeg2; z < zEnd2; ++z) { | |
zOffset = zd * z; | |
for (y = yBeg2; y < yEnd2; ++y) { | |
yOffset = zOffset + yd * y; | |
for (x = xBeg2; x < xEnd2; ++x) { | |
q = 3 * (yOffset + x); | |
vertexIndex[q] = -1; | |
vertexIndex[q + 1] = -1; | |
vertexIndex[q + 2] = -1; | |
} | |
} | |
} | |
} else { | |
xBeg2 = xBeg - 2; | |
yBeg2 = yBeg - 2; | |
zBeg2 = zBeg - 2; | |
xEnd2 = xEnd + 2; | |
yEnd2 = yEnd + 2; | |
zEnd2 = zEnd + 2; | |
for (z = zBeg2; z < zEnd2; ++z) { | |
for (y = yBeg2; y < yEnd2; ++y) { | |
for (x = xBeg2; x < xEnd2; ++x) { | |
q3 = index(x, y, z) * 3; | |
vertexIndex[q3] = -1; | |
vertexIndex[q3 + 1] = -1; | |
vertexIndex[q3 + 2] = -1; | |
} | |
} | |
} | |
} | |
if (!wrap) { | |
var __break; | |
var __xBeg = xBeg; | |
var __yBeg = yBeg; | |
var __zBeg = zBeg; | |
var __xEnd = xEnd; | |
var __yEnd = yEnd; | |
var __zEnd = zEnd; | |
__break = false; | |
for (z = zBeg; z < zEnd; ++z) { | |
for (y = yBeg; y < yEnd; ++y) { | |
for (x = xBeg; x < xEnd; ++x) { | |
q = nx * ny * z + nx * y + x; | |
if (field[q] >= isolevel) { | |
__zBeg = z; | |
__break = true; | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
__break = false; | |
for (y = yBeg; y < yEnd; ++y) { | |
for (z = __zBeg; z < zEnd; ++z) { | |
for (x = xBeg; x < xEnd; ++x) { | |
q = nx * ny * z + nx * y + x; | |
if (field[q] >= isolevel) { | |
__yBeg = y; | |
__break = true; | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
__break = false; | |
for (x = xBeg; x < xEnd; ++x) { | |
for (y = __yBeg; y < yEnd; ++y) { | |
for (z = __zBeg; z < zEnd; ++z) { | |
q = nx * ny * z + nx * y + x; | |
if (field[q] >= isolevel) { | |
__xBeg = x; | |
__break = true; | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
__break = false; | |
for (z = zEnd; z >= zBeg; --z) { | |
for (y = yEnd; y >= yBeg; --y) { | |
for (x = xEnd; x >= xBeg; --x) { | |
q = nx * ny * z + nx * y + x; | |
if (field[q] >= isolevel) { | |
__zEnd = z; | |
__break = true; | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
__break = false; | |
for (y = yEnd; y >= yBeg; --y) { | |
for (z = __zEnd; z >= zBeg; --z) { | |
for (x = xEnd; x >= xBeg; --x) { | |
q = nx * ny * z + nx * y + x; | |
if (field[q] >= isolevel) { | |
__yEnd = y; | |
__break = true; | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
__break = false; | |
for (x = xEnd; x >= xBeg; --x) { | |
for (y = __yEnd; y >= yBeg; --y) { | |
for (z = __zEnd; z >= zBeg; --z) { | |
q = nx * ny * z + nx * y + x; | |
if (field[q] >= isolevel) { | |
__xEnd = x; | |
__break = true; | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
if (__break) { | |
break; | |
} | |
} | |
if (noNormals) { | |
xBeg = Math.max(0, __xBeg - 1); | |
yBeg = Math.max(0, __yBeg - 1); | |
zBeg = Math.max(0, __zBeg - 1); | |
xEnd = Math.min(nx - 1, __xEnd + 1); | |
yEnd = Math.min(ny - 1, __yEnd + 1); | |
zEnd = Math.min(nz - 1, __zEnd + 1); | |
} else { | |
xBeg = Math.max(1, __xBeg - 1); | |
yBeg = Math.max(1, __yBeg - 1); | |
zBeg = Math.max(1, __zBeg - 1); | |
xEnd = Math.min(nx - 2, __xEnd + 1); | |
yEnd = Math.min(ny - 2, __yEnd + 1); | |
zEnd = Math.min(nz - 2, __zEnd + 1); | |
} | |
} | |
var edgeFilter = 15; | |
for (z = zBeg; z < zEnd; ++z, edgeFilter &= ~4) { | |
zOffset = zd * z; | |
edgeFilter |= 2; | |
for (y = yBeg; y < yEnd; ++y, edgeFilter &= ~2) { | |
yOffset = zOffset + yd * y; | |
edgeFilter |= 1; | |
for (x = xBeg; x < xEnd; ++x, edgeFilter &= ~1) { | |
q = yOffset + x; | |
polygonize(x, y, z, q, edgeFilter); | |
} | |
} | |
} | |
} | |
__name(triangulate, "triangulate"); | |
} | |
function VolumeSurface(data, nx, ny, nz, atomindex) { | |
var mc = new MarchingCubes(data, nx, ny, nz, atomindex); | |
function getSurface3(isolevel, smooth, box, matrix2, contour, wrap) { | |
if (wrap === void 0) | |
wrap = false; | |
var sd = mc.triangulate(isolevel, smooth, box, contour, wrap); | |
if (smooth && !contour) { | |
laplacianSmooth(sd.position, sd.index, smooth, true); | |
sd.normal = computeVertexNormals(sd.position, sd.index); | |
} | |
if (matrix2) { | |
applyMatrix4toVector3array(matrix2, sd.position); | |
if (sd.normal) { | |
var normalMatrix2 = m3new(); | |
m3makeNormal(normalMatrix2, matrix2); | |
applyMatrix3toVector3array(normalMatrix2, sd.normal); | |
} | |
} | |
return sd; | |
} | |
__name(getSurface3, "getSurface"); | |
this.getSurface = getSurface3; | |
} | |
function applyMatrix3toVector3array(m, a) { | |
for (var i = 0, il = a.length; i < il; i += 3) { | |
var x = a[i]; | |
var y = a[i + 1]; | |
var z = a[i + 2]; | |
a[i] = m[0] * x + m[3] * y + m[6] * z; | |
a[i + 1] = m[1] * x + m[4] * y + m[7] * z; | |
a[i + 2] = m[2] * x + m[5] * y + m[8] * z; | |
} | |
} | |
function applyMatrix4toVector3array(m, a) { | |
for (var i = 0, il = a.length; i < il; i += 3) { | |
var x = a[i]; | |
var y = a[i + 1]; | |
var z = a[i + 2]; | |
a[i] = m[0] * x + m[4] * y + m[8] * z + m[12]; | |
a[i + 1] = m[1] * x + m[5] * y + m[9] * z + m[13]; | |
a[i + 2] = m[2] * x + m[6] * y + m[10] * z + m[14]; | |
} | |
} | |
function computeBoundingBox(array) { | |
var minX = Infinity; | |
var minY = Infinity; | |
var minZ = Infinity; | |
var maxX = -Infinity; | |
var maxY = -Infinity; | |
var maxZ = -Infinity; | |
for (var i = 0, l = array.length; i < l; i += 3) { | |
var x = array[i]; | |
var y = array[i + 1]; | |
var z = array[i + 2]; | |
if (x < minX) { | |
minX = x; | |
} | |
if (y < minY) { | |
minY = y; | |
} | |
if (z < minZ) { | |
minZ = z; | |
} | |
if (x > maxX) { | |
maxX = x; | |
} | |
if (y > maxY) { | |
maxY = y; | |
} | |
if (z > maxZ) { | |
maxZ = z; | |
} | |
} | |
return [ | |
v3new([minX, minY, minZ]), | |
v3new([maxX, maxY, maxZ]) | |
]; | |
} | |
function computeVertexNormals(position, index, normal) { | |
var i, il; | |
if (normal === void 0) { | |
normal = new Float32Array(position.length); | |
} else { | |
for (i = 0, il = normal.length; i < il; i++) { | |
normal[i] = 0; | |
} | |
} | |
var a = new Float32Array(3); | |
var b = new Float32Array(3); | |
var c = new Float32Array(3); | |
var cb = new Float32Array(3); | |
var ab = new Float32Array(3); | |
if (index) { | |
for (i = 0, il = index.length; i < il; i += 3) { | |
var ai = index[i] * 3; | |
var bi = index[i + 1] * 3; | |
var ci = index[i + 2] * 3; | |
v3fromArray(a, position, ai); | |
v3fromArray(b, position, bi); | |
v3fromArray(c, position, ci); | |
v3sub(cb, c, b); | |
v3sub(ab, a, b); | |
v3cross(cb, cb, ab); | |
normal[ai] += cb[0]; | |
normal[ai + 1] += cb[1]; | |
normal[ai + 2] += cb[2]; | |
normal[bi] += cb[0]; | |
normal[bi + 1] += cb[1]; | |
normal[bi + 2] += cb[2]; | |
normal[ci] += cb[0]; | |
normal[ci + 1] += cb[1]; | |
normal[ci + 2] += cb[2]; | |
} | |
} else { | |
for (i = 0, il = position.length; i < il; i += 9) { | |
v3fromArray(a, position, i); | |
v3fromArray(b, position, i + 3); | |
v3fromArray(c, position, i + 6); | |
v3sub(cb, c, b); | |
v3sub(ab, a, b); | |
v3cross(cb, cb, ab); | |
normal[i] = cb[0]; | |
normal[i + 1] = cb[1]; | |
normal[i + 2] = cb[2]; | |
normal[i + 3] = cb[0]; | |
normal[i + 4] = cb[1]; | |
normal[i + 5] = cb[2]; | |
normal[i + 6] = cb[0]; | |
normal[i + 7] = cb[1]; | |
normal[i + 8] = cb[2]; | |
} | |
} | |
normalizeVector3array(normal); | |
return normal; | |
} | |
function defaults(value2, defaultValue) { | |
return value2 !== void 0 ? value2 : defaultValue; | |
} | |
function degToRad(deg) { | |
return deg * 0.01745; | |
} | |
function getAllowedContours() { | |
return [ | |
[0, 4, 4, 4, 2, 0, 0, 0, 2, 2, 0, 0], | |
[4, 0, 4, 4, 0, 8, 0, 0, 0, 8, 8, 0], | |
[4, 4, 0, 4, 0, 0, 8, 0, 0, 0, 8, 8], | |
[4, 4, 4, 0, 0, 0, 0, 1, 1, 0, 0, 1], | |
[2, 0, 0, 0, 0, 8, 8, 8, 2, 2, 0, 0], | |
[0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 8, 0], | |
[0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8], | |
[0, 0, 0, 1, 8, 8, 8, 0, 1, 0, 0, 1], | |
[2, 0, 0, 1, 2, 0, 0, 1, 0, 2, 0, 1], | |
[2, 8, 0, 0, 2, 8, 0, 0, 2, 0, 8, 0], | |
[0, 8, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8], | |
[0, 0, 8, 1, 0, 0, 8, 1, 1, 0, 8, 0] | |
]; | |
} | |
function getEdgeTable() { | |
return new Uint32Array([ | |
0, | |
265, | |
515, | |
778, | |
1030, | |
1295, | |
1541, | |
1804, | |
2060, | |
2309, | |
2575, | |
2822, | |
3082, | |
3331, | |
3593, | |
3840, | |
400, | |
153, | |
915, | |
666, | |
1430, | |
1183, | |
1941, | |
1692, | |
2460, | |
2197, | |
2975, | |
2710, | |
3482, | |
3219, | |
3993, | |
3728, | |
560, | |
825, | |
51, | |
314, | |
1590, | |
1855, | |
1077, | |
1340, | |
2620, | |
2869, | |
2111, | |
2358, | |
3642, | |
3891, | |
3129, | |
3376, | |
928, | |
681, | |
419, | |
170, | |
1958, | |
1711, | |
1445, | |
1196, | |
2988, | |
2725, | |
2479, | |
2214, | |
4010, | |
3747, | |
3497, | |
3232, | |
1120, | |
1385, | |
1635, | |
1898, | |
102, | |
367, | |
613, | |
876, | |
3180, | |
3429, | |
3695, | |
3942, | |
2154, | |
2403, | |
2665, | |
2912, | |
1520, | |
1273, | |
2035, | |
1786, | |
502, | |
255, | |
1013, | |
764, | |
3580, | |
3317, | |
4095, | |
3830, | |
2554, | |
2291, | |
3065, | |
2800, | |
1616, | |
1881, | |
1107, | |
1370, | |
598, | |
863, | |
85, | |
348, | |
3676, | |
3925, | |
3167, | |
3414, | |
2650, | |
2899, | |
2137, | |
2384, | |
1984, | |
1737, | |
1475, | |
1226, | |
966, | |
719, | |
453, | |
204, | |
4044, | |
3781, | |
3535, | |
3270, | |
3018, | |
2755, | |
2505, | |
2240, | |
2240, | |
2505, | |
2755, | |
3018, | |
3270, | |
3535, | |
3781, | |
4044, | |
204, | |
453, | |
719, | |
966, | |
1226, | |
1475, | |
1737, | |
1984, | |
2384, | |
2137, | |
2899, | |
2650, | |
3414, | |
3167, | |
3925, | |
3676, | |
348, | |
85, | |
863, | |
598, | |
1370, | |
1107, | |
1881, | |
1616, | |
2800, | |
3065, | |
2291, | |
2554, | |
3830, | |
4095, | |
3317, | |
3580, | |
764, | |
1013, | |
255, | |
502, | |
1786, | |
2035, | |
1273, | |
1520, | |
2912, | |
2665, | |
2403, | |
2154, | |
3942, | |
3695, | |
3429, | |
3180, | |
876, | |
613, | |
367, | |
102, | |
1898, | |
1635, | |
1385, | |
1120, | |
3232, | |
3497, | |
3747, | |
4010, | |
2214, | |
2479, | |
2725, | |
2988, | |
1196, | |
1445, | |
1711, | |
1958, | |
170, | |
419, | |
681, | |
928, | |
3376, | |
3129, | |
3891, | |
3642, | |
2358, | |
2111, | |
2869, | |
2620, | |
1340, | |
1077, | |
1855, | |
1590, | |
314, | |
51, | |
825, | |
560, | |
3728, | |
3993, | |
3219, | |
3482, | |
2710, | |
2975, | |
2197, | |
2460, | |
1692, | |
1941, | |
1183, | |
1430, | |
666, | |
915, | |
153, | |
400, | |
3840, | |
3593, | |
3331, | |
3082, | |
2822, | |
2575, | |
2309, | |
2060, | |
1804, | |
1541, | |
1295, | |
1030, | |
778, | |
515, | |
265, | |
0 | |
]); | |
} | |
function getRadiusDict(radiusList) { | |
var radiusDict = {}; | |
for (var i = 0, il = radiusList.length; i < il; ++i) { | |
radiusDict[radiusList[i]] = true; | |
} | |
return radiusDict; | |
} | |
function getSurfaceGrid(min, max, maxRadius2, scaleFactor, extraMargin) { | |
var margin = 1 / scaleFactor * 3; | |
margin += maxRadius2; | |
v3subScalar(min, min, extraMargin + margin); | |
v3addScalar(max, max, extraMargin + margin); | |
v3multiplyScalar(min, min, scaleFactor); | |
v3floor(min, min); | |
v3divideScalar(min, min, scaleFactor); | |
v3multiplyScalar(max, max, scaleFactor); | |
v3ceil(max, max); | |
v3divideScalar(max, max, scaleFactor); | |
var dim = new Float32Array(3); | |
v3sub(dim, max, min); | |
v3multiplyScalar(dim, dim, scaleFactor); | |
v3ceil(dim, dim); | |
v3addScalar(dim, dim, 1); | |
var maxSize = Math.pow(10, 6) * 256; | |
var tmpSize = dim[0] * dim[1] * dim[2] * 3; | |
if (maxSize <= tmpSize) { | |
scaleFactor *= Math.pow(maxSize / tmpSize, 1 / 3); | |
v3multiplyScalar(min, min, scaleFactor); | |
v3floor(min, min); | |
v3divideScalar(min, min, scaleFactor); | |
v3multiplyScalar(max, max, scaleFactor); | |
v3ceil(max, max); | |
v3divideScalar(max, max, scaleFactor); | |
v3sub(dim, max, min); | |
v3multiplyScalar(dim, dim, scaleFactor); | |
v3ceil(dim, dim); | |
v3addScalar(dim, dim, 1); | |
} | |
var tran = new Float32Array(min); | |
v3negate(tran, tran); | |
var matrix2 = m4new(); | |
var mroty = m4new(); | |
m4makeRotationY(mroty, degToRad(90)); | |
m4multiply(matrix2, matrix2, mroty); | |
var mscale = m4new(); | |
m4makeScale(mscale, -1 / scaleFactor, 1 / scaleFactor, 1 / scaleFactor); | |
m4multiply(matrix2, matrix2, mscale); | |
var mtrans = m4new(); | |
m4makeTranslation(mtrans, -scaleFactor * tran[2], -scaleFactor * tran[1], -scaleFactor * tran[0]); | |
m4multiply(matrix2, matrix2, mtrans); | |
return { | |
dim, | |
tran, | |
matrix: matrix2, | |
scaleFactor | |
}; | |
} | |
function getTriTable() { | |
return new Int32Array([ | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
1, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
8, | |
3, | |
9, | |
8, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
3, | |
1, | |
2, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
2, | |
10, | |
0, | |
2, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
8, | |
3, | |
2, | |
10, | |
8, | |
10, | |
9, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
11, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
11, | |
2, | |
8, | |
11, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
9, | |
0, | |
2, | |
3, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
11, | |
2, | |
1, | |
9, | |
11, | |
9, | |
8, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
10, | |
1, | |
11, | |
10, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
10, | |
1, | |
0, | |
8, | |
10, | |
8, | |
11, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
9, | |
0, | |
3, | |
11, | |
9, | |
11, | |
10, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
8, | |
10, | |
10, | |
8, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
7, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
3, | |
0, | |
7, | |
3, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
1, | |
9, | |
8, | |
4, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
1, | |
9, | |
4, | |
7, | |
1, | |
7, | |
3, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
10, | |
8, | |
4, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
4, | |
7, | |
3, | |
0, | |
4, | |
1, | |
2, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
2, | |
10, | |
9, | |
0, | |
2, | |
8, | |
4, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
10, | |
9, | |
2, | |
9, | |
7, | |
2, | |
7, | |
3, | |
7, | |
9, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
4, | |
7, | |
3, | |
11, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
4, | |
7, | |
11, | |
2, | |
4, | |
2, | |
0, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
0, | |
1, | |
8, | |
4, | |
7, | |
2, | |
3, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
7, | |
11, | |
9, | |
4, | |
11, | |
9, | |
11, | |
2, | |
9, | |
2, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
10, | |
1, | |
3, | |
11, | |
10, | |
7, | |
8, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
11, | |
10, | |
1, | |
4, | |
11, | |
1, | |
0, | |
4, | |
7, | |
11, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
7, | |
8, | |
9, | |
0, | |
11, | |
9, | |
11, | |
10, | |
11, | |
0, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
7, | |
11, | |
4, | |
11, | |
9, | |
9, | |
11, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
4, | |
0, | |
8, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
5, | |
4, | |
1, | |
5, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
5, | |
4, | |
8, | |
3, | |
5, | |
3, | |
1, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
10, | |
9, | |
5, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
0, | |
8, | |
1, | |
2, | |
10, | |
4, | |
9, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
2, | |
10, | |
5, | |
4, | |
2, | |
4, | |
0, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
10, | |
5, | |
3, | |
2, | |
5, | |
3, | |
5, | |
4, | |
3, | |
4, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
4, | |
2, | |
3, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
11, | |
2, | |
0, | |
8, | |
11, | |
4, | |
9, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
5, | |
4, | |
0, | |
1, | |
5, | |
2, | |
3, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
1, | |
5, | |
2, | |
5, | |
8, | |
2, | |
8, | |
11, | |
4, | |
8, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
3, | |
11, | |
10, | |
1, | |
3, | |
9, | |
5, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
9, | |
5, | |
0, | |
8, | |
1, | |
8, | |
10, | |
1, | |
8, | |
11, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
4, | |
0, | |
5, | |
0, | |
11, | |
5, | |
11, | |
10, | |
11, | |
0, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
4, | |
8, | |
5, | |
8, | |
10, | |
10, | |
8, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
7, | |
8, | |
5, | |
7, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
3, | |
0, | |
9, | |
5, | |
3, | |
5, | |
7, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
7, | |
8, | |
0, | |
1, | |
7, | |
1, | |
5, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
5, | |
3, | |
3, | |
5, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
7, | |
8, | |
9, | |
5, | |
7, | |
10, | |
1, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
1, | |
2, | |
9, | |
5, | |
0, | |
5, | |
3, | |
0, | |
5, | |
7, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
0, | |
2, | |
8, | |
2, | |
5, | |
8, | |
5, | |
7, | |
10, | |
5, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
10, | |
5, | |
2, | |
5, | |
3, | |
3, | |
5, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
9, | |
5, | |
7, | |
8, | |
9, | |
3, | |
11, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
7, | |
9, | |
7, | |
2, | |
9, | |
2, | |
0, | |
2, | |
7, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
3, | |
11, | |
0, | |
1, | |
8, | |
1, | |
7, | |
8, | |
1, | |
5, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
2, | |
1, | |
11, | |
1, | |
7, | |
7, | |
1, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
8, | |
8, | |
5, | |
7, | |
10, | |
1, | |
3, | |
10, | |
3, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
7, | |
0, | |
5, | |
0, | |
9, | |
7, | |
11, | |
0, | |
1, | |
0, | |
10, | |
11, | |
10, | |
0, | |
-1, | |
11, | |
10, | |
0, | |
11, | |
0, | |
3, | |
10, | |
5, | |
0, | |
8, | |
0, | |
7, | |
5, | |
7, | |
0, | |
-1, | |
11, | |
10, | |
5, | |
7, | |
11, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
6, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
3, | |
5, | |
10, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
0, | |
1, | |
5, | |
10, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
8, | |
3, | |
1, | |
9, | |
8, | |
5, | |
10, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
6, | |
5, | |
2, | |
6, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
6, | |
5, | |
1, | |
2, | |
6, | |
3, | |
0, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
6, | |
5, | |
9, | |
0, | |
6, | |
0, | |
2, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
9, | |
8, | |
5, | |
8, | |
2, | |
5, | |
2, | |
6, | |
3, | |
2, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
3, | |
11, | |
10, | |
6, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
0, | |
8, | |
11, | |
2, | |
0, | |
10, | |
6, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
1, | |
9, | |
2, | |
3, | |
11, | |
5, | |
10, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
10, | |
6, | |
1, | |
9, | |
2, | |
9, | |
11, | |
2, | |
9, | |
8, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
3, | |
11, | |
6, | |
5, | |
3, | |
5, | |
1, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
11, | |
0, | |
11, | |
5, | |
0, | |
5, | |
1, | |
5, | |
11, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
11, | |
6, | |
0, | |
3, | |
6, | |
0, | |
6, | |
5, | |
0, | |
5, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
5, | |
9, | |
6, | |
9, | |
11, | |
11, | |
9, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
10, | |
6, | |
4, | |
7, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
3, | |
0, | |
4, | |
7, | |
3, | |
6, | |
5, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
9, | |
0, | |
5, | |
10, | |
6, | |
8, | |
4, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
6, | |
5, | |
1, | |
9, | |
7, | |
1, | |
7, | |
3, | |
7, | |
9, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
1, | |
2, | |
6, | |
5, | |
1, | |
4, | |
7, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
5, | |
5, | |
2, | |
6, | |
3, | |
0, | |
4, | |
3, | |
4, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
4, | |
7, | |
9, | |
0, | |
5, | |
0, | |
6, | |
5, | |
0, | |
2, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
3, | |
9, | |
7, | |
9, | |
4, | |
3, | |
2, | |
9, | |
5, | |
9, | |
6, | |
2, | |
6, | |
9, | |
-1, | |
3, | |
11, | |
2, | |
7, | |
8, | |
4, | |
10, | |
6, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
10, | |
6, | |
4, | |
7, | |
2, | |
4, | |
2, | |
0, | |
2, | |
7, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
1, | |
9, | |
4, | |
7, | |
8, | |
2, | |
3, | |
11, | |
5, | |
10, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
2, | |
1, | |
9, | |
11, | |
2, | |
9, | |
4, | |
11, | |
7, | |
11, | |
4, | |
5, | |
10, | |
6, | |
-1, | |
8, | |
4, | |
7, | |
3, | |
11, | |
5, | |
3, | |
5, | |
1, | |
5, | |
11, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
1, | |
11, | |
5, | |
11, | |
6, | |
1, | |
0, | |
11, | |
7, | |
11, | |
4, | |
0, | |
4, | |
11, | |
-1, | |
0, | |
5, | |
9, | |
0, | |
6, | |
5, | |
0, | |
3, | |
6, | |
11, | |
6, | |
3, | |
8, | |
4, | |
7, | |
-1, | |
6, | |
5, | |
9, | |
6, | |
9, | |
11, | |
4, | |
7, | |
9, | |
7, | |
11, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
4, | |
9, | |
6, | |
4, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
10, | |
6, | |
4, | |
9, | |
10, | |
0, | |
8, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
0, | |
1, | |
10, | |
6, | |
0, | |
6, | |
4, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
3, | |
1, | |
8, | |
1, | |
6, | |
8, | |
6, | |
4, | |
6, | |
1, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
4, | |
9, | |
1, | |
2, | |
4, | |
2, | |
6, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
0, | |
8, | |
1, | |
2, | |
9, | |
2, | |
4, | |
9, | |
2, | |
6, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
2, | |
4, | |
4, | |
2, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
3, | |
2, | |
8, | |
2, | |
4, | |
4, | |
2, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
4, | |
9, | |
10, | |
6, | |
4, | |
11, | |
2, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
2, | |
2, | |
8, | |
11, | |
4, | |
9, | |
10, | |
4, | |
10, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
11, | |
2, | |
0, | |
1, | |
6, | |
0, | |
6, | |
4, | |
6, | |
1, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
4, | |
1, | |
6, | |
1, | |
10, | |
4, | |
8, | |
1, | |
2, | |
1, | |
11, | |
8, | |
11, | |
1, | |
-1, | |
9, | |
6, | |
4, | |
9, | |
3, | |
6, | |
9, | |
1, | |
3, | |
11, | |
6, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
11, | |
1, | |
8, | |
1, | |
0, | |
11, | |
6, | |
1, | |
9, | |
1, | |
4, | |
6, | |
4, | |
1, | |
-1, | |
3, | |
11, | |
6, | |
3, | |
6, | |
0, | |
0, | |
6, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
4, | |
8, | |
11, | |
6, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
10, | |
6, | |
7, | |
8, | |
10, | |
8, | |
9, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
7, | |
3, | |
0, | |
10, | |
7, | |
0, | |
9, | |
10, | |
6, | |
7, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
6, | |
7, | |
1, | |
10, | |
7, | |
1, | |
7, | |
8, | |
1, | |
8, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
6, | |
7, | |
10, | |
7, | |
1, | |
1, | |
7, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
6, | |
1, | |
6, | |
8, | |
1, | |
8, | |
9, | |
8, | |
6, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
6, | |
9, | |
2, | |
9, | |
1, | |
6, | |
7, | |
9, | |
0, | |
9, | |
3, | |
7, | |
3, | |
9, | |
-1, | |
7, | |
8, | |
0, | |
7, | |
0, | |
6, | |
6, | |
0, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
3, | |
2, | |
6, | |
7, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
3, | |
11, | |
10, | |
6, | |
8, | |
10, | |
8, | |
9, | |
8, | |
6, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
0, | |
7, | |
2, | |
7, | |
11, | |
0, | |
9, | |
7, | |
6, | |
7, | |
10, | |
9, | |
10, | |
7, | |
-1, | |
1, | |
8, | |
0, | |
1, | |
7, | |
8, | |
1, | |
10, | |
7, | |
6, | |
7, | |
10, | |
2, | |
3, | |
11, | |
-1, | |
11, | |
2, | |
1, | |
11, | |
1, | |
7, | |
10, | |
6, | |
1, | |
6, | |
7, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
9, | |
6, | |
8, | |
6, | |
7, | |
9, | |
1, | |
6, | |
11, | |
6, | |
3, | |
1, | |
3, | |
6, | |
-1, | |
0, | |
9, | |
1, | |
11, | |
6, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
8, | |
0, | |
7, | |
0, | |
6, | |
3, | |
11, | |
0, | |
11, | |
6, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
11, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
6, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
0, | |
8, | |
11, | |
7, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
1, | |
9, | |
11, | |
7, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
1, | |
9, | |
8, | |
3, | |
1, | |
11, | |
7, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
1, | |
2, | |
6, | |
11, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
10, | |
3, | |
0, | |
8, | |
6, | |
11, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
9, | |
0, | |
2, | |
10, | |
9, | |
6, | |
11, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
11, | |
7, | |
2, | |
10, | |
3, | |
10, | |
8, | |
3, | |
10, | |
9, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
2, | |
3, | |
6, | |
2, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
0, | |
8, | |
7, | |
6, | |
0, | |
6, | |
2, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
7, | |
6, | |
2, | |
3, | |
7, | |
0, | |
1, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
6, | |
2, | |
1, | |
8, | |
6, | |
1, | |
9, | |
8, | |
8, | |
7, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
7, | |
6, | |
10, | |
1, | |
7, | |
1, | |
3, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
7, | |
6, | |
1, | |
7, | |
10, | |
1, | |
8, | |
7, | |
1, | |
0, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
3, | |
7, | |
0, | |
7, | |
10, | |
0, | |
10, | |
9, | |
6, | |
10, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
6, | |
10, | |
7, | |
10, | |
8, | |
8, | |
10, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
8, | |
4, | |
11, | |
8, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
6, | |
11, | |
3, | |
0, | |
6, | |
0, | |
4, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
6, | |
11, | |
8, | |
4, | |
6, | |
9, | |
0, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
4, | |
6, | |
9, | |
6, | |
3, | |
9, | |
3, | |
1, | |
11, | |
3, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
8, | |
4, | |
6, | |
11, | |
8, | |
2, | |
10, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
10, | |
3, | |
0, | |
11, | |
0, | |
6, | |
11, | |
0, | |
4, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
11, | |
8, | |
4, | |
6, | |
11, | |
0, | |
2, | |
9, | |
2, | |
10, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
9, | |
3, | |
10, | |
3, | |
2, | |
9, | |
4, | |
3, | |
11, | |
3, | |
6, | |
4, | |
6, | |
3, | |
-1, | |
8, | |
2, | |
3, | |
8, | |
4, | |
2, | |
4, | |
6, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
4, | |
2, | |
4, | |
6, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
9, | |
0, | |
2, | |
3, | |
4, | |
2, | |
4, | |
6, | |
4, | |
3, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
9, | |
4, | |
1, | |
4, | |
2, | |
2, | |
4, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
1, | |
3, | |
8, | |
6, | |
1, | |
8, | |
4, | |
6, | |
6, | |
10, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
1, | |
0, | |
10, | |
0, | |
6, | |
6, | |
0, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
6, | |
3, | |
4, | |
3, | |
8, | |
6, | |
10, | |
3, | |
0, | |
3, | |
9, | |
10, | |
9, | |
3, | |
-1, | |
10, | |
9, | |
4, | |
6, | |
10, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
9, | |
5, | |
7, | |
6, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
3, | |
4, | |
9, | |
5, | |
11, | |
7, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
0, | |
1, | |
5, | |
4, | |
0, | |
7, | |
6, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
7, | |
6, | |
8, | |
3, | |
4, | |
3, | |
5, | |
4, | |
3, | |
1, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
4, | |
10, | |
1, | |
2, | |
7, | |
6, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
11, | |
7, | |
1, | |
2, | |
10, | |
0, | |
8, | |
3, | |
4, | |
9, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
6, | |
11, | |
5, | |
4, | |
10, | |
4, | |
2, | |
10, | |
4, | |
0, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
4, | |
8, | |
3, | |
5, | |
4, | |
3, | |
2, | |
5, | |
10, | |
5, | |
2, | |
11, | |
7, | |
6, | |
-1, | |
7, | |
2, | |
3, | |
7, | |
6, | |
2, | |
5, | |
4, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
4, | |
0, | |
8, | |
6, | |
0, | |
6, | |
2, | |
6, | |
8, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
6, | |
2, | |
3, | |
7, | |
6, | |
1, | |
5, | |
0, | |
5, | |
4, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
2, | |
8, | |
6, | |
8, | |
7, | |
2, | |
1, | |
8, | |
4, | |
8, | |
5, | |
1, | |
5, | |
8, | |
-1, | |
9, | |
5, | |
4, | |
10, | |
1, | |
6, | |
1, | |
7, | |
6, | |
1, | |
3, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
6, | |
10, | |
1, | |
7, | |
6, | |
1, | |
0, | |
7, | |
8, | |
7, | |
0, | |
9, | |
5, | |
4, | |
-1, | |
4, | |
0, | |
10, | |
4, | |
10, | |
5, | |
0, | |
3, | |
10, | |
6, | |
10, | |
7, | |
3, | |
7, | |
10, | |
-1, | |
7, | |
6, | |
10, | |
7, | |
10, | |
8, | |
5, | |
4, | |
10, | |
4, | |
8, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
9, | |
5, | |
6, | |
11, | |
9, | |
11, | |
8, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
6, | |
11, | |
0, | |
6, | |
3, | |
0, | |
5, | |
6, | |
0, | |
9, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
11, | |
8, | |
0, | |
5, | |
11, | |
0, | |
1, | |
5, | |
5, | |
6, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
6, | |
11, | |
3, | |
6, | |
3, | |
5, | |
5, | |
3, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
10, | |
9, | |
5, | |
11, | |
9, | |
11, | |
8, | |
11, | |
5, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
11, | |
3, | |
0, | |
6, | |
11, | |
0, | |
9, | |
6, | |
5, | |
6, | |
9, | |
1, | |
2, | |
10, | |
-1, | |
11, | |
8, | |
5, | |
11, | |
5, | |
6, | |
8, | |
0, | |
5, | |
10, | |
5, | |
2, | |
0, | |
2, | |
5, | |
-1, | |
6, | |
11, | |
3, | |
6, | |
3, | |
5, | |
2, | |
10, | |
3, | |
10, | |
5, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
8, | |
9, | |
5, | |
2, | |
8, | |
5, | |
6, | |
2, | |
3, | |
8, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
5, | |
6, | |
9, | |
6, | |
0, | |
0, | |
6, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
5, | |
8, | |
1, | |
8, | |
0, | |
5, | |
6, | |
8, | |
3, | |
8, | |
2, | |
6, | |
2, | |
8, | |
-1, | |
1, | |
5, | |
6, | |
2, | |
1, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
3, | |
6, | |
1, | |
6, | |
10, | |
3, | |
8, | |
6, | |
5, | |
6, | |
9, | |
8, | |
9, | |
6, | |
-1, | |
10, | |
1, | |
0, | |
10, | |
0, | |
6, | |
9, | |
5, | |
0, | |
5, | |
6, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
3, | |
8, | |
5, | |
6, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
5, | |
6, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
5, | |
10, | |
7, | |
5, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
5, | |
10, | |
11, | |
7, | |
5, | |
8, | |
3, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
11, | |
7, | |
5, | |
10, | |
11, | |
1, | |
9, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
7, | |
5, | |
10, | |
11, | |
7, | |
9, | |
8, | |
1, | |
8, | |
3, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
1, | |
2, | |
11, | |
7, | |
1, | |
7, | |
5, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
3, | |
1, | |
2, | |
7, | |
1, | |
7, | |
5, | |
7, | |
2, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
7, | |
5, | |
9, | |
2, | |
7, | |
9, | |
0, | |
2, | |
2, | |
11, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
7, | |
5, | |
2, | |
7, | |
2, | |
11, | |
5, | |
9, | |
2, | |
3, | |
2, | |
8, | |
9, | |
8, | |
2, | |
-1, | |
2, | |
5, | |
10, | |
2, | |
3, | |
5, | |
3, | |
7, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
2, | |
0, | |
8, | |
5, | |
2, | |
8, | |
7, | |
5, | |
10, | |
2, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
0, | |
1, | |
5, | |
10, | |
3, | |
5, | |
3, | |
7, | |
3, | |
10, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
8, | |
2, | |
9, | |
2, | |
1, | |
8, | |
7, | |
2, | |
10, | |
2, | |
5, | |
7, | |
5, | |
2, | |
-1, | |
1, | |
3, | |
5, | |
3, | |
7, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
7, | |
0, | |
7, | |
1, | |
1, | |
7, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
0, | |
3, | |
9, | |
3, | |
5, | |
5, | |
3, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
8, | |
7, | |
5, | |
9, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
8, | |
4, | |
5, | |
10, | |
8, | |
10, | |
11, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
0, | |
4, | |
5, | |
11, | |
0, | |
5, | |
10, | |
11, | |
11, | |
3, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
1, | |
9, | |
8, | |
4, | |
10, | |
8, | |
10, | |
11, | |
10, | |
4, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
10, | |
11, | |
4, | |
10, | |
4, | |
5, | |
11, | |
3, | |
4, | |
9, | |
4, | |
1, | |
3, | |
1, | |
4, | |
-1, | |
2, | |
5, | |
1, | |
2, | |
8, | |
5, | |
2, | |
11, | |
8, | |
4, | |
5, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
4, | |
11, | |
0, | |
11, | |
3, | |
4, | |
5, | |
11, | |
2, | |
11, | |
1, | |
5, | |
1, | |
11, | |
-1, | |
0, | |
2, | |
5, | |
0, | |
5, | |
9, | |
2, | |
11, | |
5, | |
4, | |
5, | |
8, | |
11, | |
8, | |
5, | |
-1, | |
9, | |
4, | |
5, | |
2, | |
11, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
5, | |
10, | |
3, | |
5, | |
2, | |
3, | |
4, | |
5, | |
3, | |
8, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
5, | |
10, | |
2, | |
5, | |
2, | |
4, | |
4, | |
2, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
10, | |
2, | |
3, | |
5, | |
10, | |
3, | |
8, | |
5, | |
4, | |
5, | |
8, | |
0, | |
1, | |
9, | |
-1, | |
5, | |
10, | |
2, | |
5, | |
2, | |
4, | |
1, | |
9, | |
2, | |
9, | |
4, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
4, | |
5, | |
8, | |
5, | |
3, | |
3, | |
5, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
4, | |
5, | |
1, | |
0, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
8, | |
4, | |
5, | |
8, | |
5, | |
3, | |
9, | |
0, | |
5, | |
0, | |
3, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
4, | |
5, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
11, | |
7, | |
4, | |
9, | |
11, | |
9, | |
10, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
8, | |
3, | |
4, | |
9, | |
7, | |
9, | |
11, | |
7, | |
9, | |
10, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
10, | |
11, | |
1, | |
11, | |
4, | |
1, | |
4, | |
0, | |
7, | |
4, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
1, | |
4, | |
3, | |
4, | |
8, | |
1, | |
10, | |
4, | |
7, | |
4, | |
11, | |
10, | |
11, | |
4, | |
-1, | |
4, | |
11, | |
7, | |
9, | |
11, | |
4, | |
9, | |
2, | |
11, | |
9, | |
1, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
7, | |
4, | |
9, | |
11, | |
7, | |
9, | |
1, | |
11, | |
2, | |
11, | |
1, | |
0, | |
8, | |
3, | |
-1, | |
11, | |
7, | |
4, | |
11, | |
4, | |
2, | |
2, | |
4, | |
0, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
11, | |
7, | |
4, | |
11, | |
4, | |
2, | |
8, | |
3, | |
4, | |
3, | |
2, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
9, | |
10, | |
2, | |
7, | |
9, | |
2, | |
3, | |
7, | |
7, | |
4, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
10, | |
7, | |
9, | |
7, | |
4, | |
10, | |
2, | |
7, | |
8, | |
7, | |
0, | |
2, | |
0, | |
7, | |
-1, | |
3, | |
7, | |
10, | |
3, | |
10, | |
2, | |
7, | |
4, | |
10, | |
1, | |
10, | |
0, | |
4, | |
0, | |
10, | |
-1, | |
1, | |
10, | |
2, | |
8, | |
7, | |
4, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
9, | |
1, | |
4, | |
1, | |
7, | |
7, | |
1, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
9, | |
1, | |
4, | |
1, | |
7, | |
0, | |
8, | |
1, | |
8, | |
7, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
0, | |
3, | |
7, | |
4, | |
3, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
4, | |
8, | |
7, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
10, | |
8, | |
10, | |
11, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
0, | |
9, | |
3, | |
9, | |
11, | |
11, | |
9, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
1, | |
10, | |
0, | |
10, | |
8, | |
8, | |
10, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
1, | |
10, | |
11, | |
3, | |
10, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
2, | |
11, | |
1, | |
11, | |
9, | |
9, | |
11, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
0, | |
9, | |
3, | |
9, | |
11, | |
1, | |
2, | |
9, | |
2, | |
11, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
2, | |
11, | |
8, | |
0, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
3, | |
2, | |
11, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
3, | |
8, | |
2, | |
8, | |
10, | |
10, | |
8, | |
9, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
9, | |
10, | |
2, | |
0, | |
9, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
2, | |
3, | |
8, | |
2, | |
8, | |
10, | |
0, | |
1, | |
8, | |
1, | |
10, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
10, | |
2, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
1, | |
3, | |
8, | |
9, | |
1, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
9, | |
1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
0, | |
3, | |
8, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1, | |
-1 | |
]); | |
} | |
function getUintArray(sizeOrArray, maxUint) { | |
var TypedArray = maxUint > 65535 ? Uint32Array : Uint16Array; | |
return new TypedArray(sizeOrArray); | |
} | |
function laplacianSmooth(verts, faces, numiter, inflate2) { | |
numiter = numiter || 1; | |
inflate2 = inflate2 || true; | |
var nv = verts.length / 3; | |
var nf = faces.length / 3; | |
var norms = void 0; | |
if (inflate2) { | |
norms = new Float32Array(nv * 3); | |
} | |
var tps = new Float32Array(nv * 3); | |
var i; | |
var ndeg = 20; | |
var vertdeg = new Array(ndeg); | |
for (i = 0; i < ndeg; ++i) { | |
vertdeg[i] = new Uint32Array(nv); | |
} | |
for (i = 0; i < nv; ++i) { | |
vertdeg[0][i] = 0; | |
} | |
var j, jl; | |
var flagvert; | |
for (i = 0; i < nf; ++i) { | |
var ao = i * 3; | |
var bo = i * 3 + 1; | |
var co = i * 3 + 2; | |
flagvert = true; | |
for (j = 0, jl = vertdeg[0][faces[ao]]; j < jl; ++j) { | |
if (faces[bo] === vertdeg[j + 1][faces[ao]]) { | |
flagvert = false; | |
break; | |
} | |
} | |
if (flagvert) { | |
vertdeg[0][faces[ao]]++; | |
vertdeg[vertdeg[0][faces[ao]]][faces[ao]] = faces[bo]; | |
} | |
flagvert = true; | |
for (j = 0, jl = vertdeg[0][faces[ao]]; j < jl; ++j) { | |
if (faces[co] === vertdeg[j + 1][faces[ao]]) { | |
flagvert = false; | |
break; | |
} | |
} | |
if (flagvert) { | |
vertdeg[0][faces[ao]]++; | |
vertdeg[vertdeg[0][faces[ao]]][faces[ao]] = faces[co]; | |
} | |
flagvert = true; | |
for (j = 0, jl = vertdeg[0][faces[bo]]; j < jl; ++j) { | |
if (faces[ao] === vertdeg[j + 1][faces[bo]]) { | |
flagvert = false; | |
break; | |
} | |
} | |
if (flagvert) { | |
vertdeg[0][faces[bo]]++; | |
vertdeg[vertdeg[0][faces[bo]]][faces[bo]] = faces[ao]; | |
} | |
flagvert = true; | |
for (j = 0, jl = vertdeg[0][faces[bo]]; j < jl; ++j) { | |
if (faces[co] === vertdeg[j + 1][faces[bo]]) { | |
flagvert = false; | |
break; | |
} | |
} | |
if (flagvert) { | |
vertdeg[0][faces[bo]]++; | |
vertdeg[vertdeg[0][faces[bo]]][faces[bo]] = faces[co]; | |
} | |
flagvert = true; | |
for (j = 0; j < vertdeg[0][faces[co]]; ++j) { | |
if (faces[ao] === vertdeg[j + 1][faces[co]]) { | |
flagvert = false; | |
break; | |
} | |
} | |
if (flagvert) { | |
vertdeg[0][faces[co]]++; | |
vertdeg[vertdeg[0][faces[co]]][faces[co]] = faces[ao]; | |
} | |
flagvert = true; | |
for (j = 0, jl = vertdeg[0][faces[co]]; j < jl; ++j) { | |
if (faces[bo] === vertdeg[j + 1][faces[co]]) { | |
flagvert = false; | |
break; | |
} | |
} | |
if (flagvert) { | |
vertdeg[0][faces[co]]++; | |
vertdeg[vertdeg[0][faces[co]]][faces[co]] = faces[bo]; | |
} | |
} | |
var wt = 1; | |
var wt2 = 0.5; | |
var i3, vi3, vdi, wtvi, wt2vi; | |
var ssign = -1; | |
var scaleFactor = 1; | |
var outwt = 0.75 / (scaleFactor + 3.5); | |
for (var k = 0; k < numiter; ++k) { | |
for (i = 0; i < nv; ++i) { | |
i3 = i * 3; | |
vdi = vertdeg[0][i]; | |
if (vdi < 3) { | |
tps[i3] = verts[i3]; | |
tps[i3 + 1] = verts[i3 + 1]; | |
tps[i3 + 2] = verts[i3 + 2]; | |
} else if (vdi === 3 || vdi === 4) { | |
tps[i3] = 0; | |
tps[i3 + 1] = 0; | |
tps[i3 + 2] = 0; | |
for (j = 0; j < vdi; ++j) { | |
vi3 = vertdeg[j + 1][i] * 3; | |
tps[i3] += verts[vi3]; | |
tps[i3 + 1] += verts[vi3 + 1]; | |
tps[i3 + 2] += verts[vi3 + 2]; | |
} | |
tps[i3] += wt2 * verts[i3]; | |
tps[i3 + 1] += wt2 * verts[i3 + 1]; | |
tps[i3 + 2] += wt2 * verts[i3 + 2]; | |
wt2vi = wt2 + vdi; | |
tps[i3] /= wt2vi; | |
tps[i3 + 1] /= wt2vi; | |
tps[i3 + 2] /= wt2vi; | |
} else { | |
tps[i3] = 0; | |
tps[i3 + 1] = 0; | |
tps[i3 + 2] = 0; | |
for (j = 0; j < vdi; ++j) { | |
vi3 = vertdeg[j + 1][i] * 3; | |
tps[i3] += verts[vi3]; | |
tps[i3 + 1] += verts[vi3 + 1]; | |
tps[i3 + 2] += verts[vi3 + 2]; | |
} | |
tps[i3] += wt * verts[i3]; | |
tps[i3 + 1] += wt * verts[i3 + 1]; | |
tps[i3 + 2] += wt * verts[i3 + 2]; | |
wtvi = wt + vdi; | |
tps[i3] /= wtvi; | |
tps[i3 + 1] /= wtvi; | |
tps[i3 + 2] /= wtvi; | |
} | |
} | |
verts.set(tps); | |
if (inflate2) { | |
computeVertexNormals(verts, faces, norms); | |
var nv3 = nv * 3; | |
for (i3 = 0; i3 < nv3; i3 += 3) { | |
verts[i3] += ssign * outwt * norms[i3]; | |
verts[i3 + 1] += ssign * outwt * norms[i3 + 1]; | |
verts[i3 + 2] += ssign * outwt * norms[i3 + 2]; | |
} | |
} | |
} | |
} | |
function m3makeNormal(out, m4) { | |
var r0 = v3new([m4[0], m4[1], m4[2]]); | |
var r1 = v3new([m4[4], m4[5], m4[6]]); | |
var r2 = v3new([m4[8], m4[9], m4[10]]); | |
var cp = v3new(); | |
v3cross(cp, r1, r2); | |
out[0] = cp[0]; | |
out[1] = cp[1]; | |
out[2] = cp[2]; | |
v3cross(cp, r2, r0); | |
out[3] = cp[0]; | |
out[4] = cp[1]; | |
out[5] = cp[2]; | |
v3cross(cp, r0, r1); | |
out[6] = cp[0]; | |
out[7] = cp[1]; | |
out[8] = cp[2]; | |
} | |
function m3new() { | |
return new Float32Array([ | |
1, | |
0, | |
0, | |
0, | |
1, | |
0, | |
0, | |
0, | |
1 | |
]); | |
} | |
function m4makeRotationY(out, theta) { | |
var c = Math.cos(theta); | |
var s = Math.sin(theta); | |
m4set(out, c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); | |
} | |
function m4makeScale(out, x, y, z) { | |
m4set(out, x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); | |
} | |
function m4makeTranslation(out, x, y, z) { | |
m4set(out, 1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); | |
} | |
function m4multiply(out, a, b) { | |
var a11 = a[0]; | |
var a12 = a[4]; | |
var a13 = a[8]; | |
var a14 = a[12]; | |
var a21 = a[1]; | |
var a22 = a[5]; | |
var a23 = a[9]; | |
var a24 = a[13]; | |
var a31 = a[2]; | |
var a32 = a[6]; | |
var a33 = a[10]; | |
var a34 = a[14]; | |
var a41 = a[3]; | |
var a42 = a[7]; | |
var a43 = a[11]; | |
var a44 = a[15]; | |
var b11 = b[0]; | |
var b12 = b[4]; | |
var b13 = b[8]; | |
var b14 = b[12]; | |
var b21 = b[1]; | |
var b22 = b[5]; | |
var b23 = b[9]; | |
var b24 = b[13]; | |
var b31 = b[2]; | |
var b32 = b[6]; | |
var b33 = b[10]; | |
var b34 = b[14]; | |
var b41 = b[3]; | |
var b42 = b[7]; | |
var b43 = b[11]; | |
var b44 = b[15]; | |
out[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; | |
out[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; | |
out[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; | |
out[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; | |
out[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; | |
out[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; | |
out[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; | |
out[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; | |
out[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; | |
out[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; | |
out[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; | |
out[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; | |
out[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; | |
out[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; | |
out[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; | |
out[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; | |
} | |
function m4new() { | |
return new Float32Array([ | |
1, | |
0, | |
0, | |
0, | |
0, | |
1, | |
0, | |
0, | |
0, | |
0, | |
1, | |
0, | |
0, | |
0, | |
0, | |
1 | |
]); | |
} | |
function m4set(out, n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { | |
out[0] = n11; | |
out[4] = n12; | |
out[8] = n13; | |
out[12] = n14; | |
out[1] = n21; | |
out[5] = n22; | |
out[9] = n23; | |
out[13] = n24; | |
out[2] = n31; | |
out[6] = n32; | |
out[10] = n33; | |
out[14] = n34; | |
out[3] = n41; | |
out[7] = n42; | |
out[11] = n43; | |
out[15] = n44; | |
} | |
function makeAVHash(atomsX, atomsY, atomsZ, atomsR, min, max, maxDistance) { | |
maxDistance = Math.max(0.1, maxDistance); | |
var nAtoms = atomsX.length; | |
var minX = min[0]; | |
var minY = min[1]; | |
var minZ = min[2]; | |
var maxX = max[0]; | |
var maxY = max[1]; | |
var maxZ = max[2]; | |
function hashFunc(w, minW) { | |
return Math.floor((w - minW) / maxDistance); | |
} | |
__name(hashFunc, "hashFunc"); | |
var iDim = hashFunc(maxX, minX) + 1; | |
var jDim = hashFunc(maxY, minY) + 1; | |
var kDim = hashFunc(maxZ, minZ) + 1; | |
var nCells = iDim * jDim * kDim; | |
var jkDim = jDim * kDim; | |
var cellID = /* @__PURE__ */ __name(function(x, y, z) { | |
return (hashFunc(x, minX) * jDim + hashFunc(y, minY)) * kDim + hashFunc(z, minZ); | |
}, "cellID"); | |
var preHash = []; | |
for (var i = 0; i < nAtoms; i++) { | |
var cid = cellID(atomsX[i], atomsY[i], atomsZ[i]); | |
if (preHash[cid] === void 0) { | |
preHash[cid] = [i]; | |
} else { | |
preHash[cid].push(i); | |
} | |
} | |
var cellOffsets = new Uint32Array(nCells); | |
var cellLengths = new Uint16Array(nCells); | |
var data = new Uint32Array(nAtoms); | |
var offset = 0; | |
var maxCellLength = 0; | |
for (i = 0; i < nCells; i++) { | |
var start = cellOffsets[i] = offset; | |
var subArray = preHash[i]; | |
if (subArray !== void 0) { | |
for (var j = 0; j < subArray.length; j++) { | |
data[offset] = subArray[j]; | |
offset++; | |
} | |
} | |
var cellLength = offset - start; | |
cellLengths[i] = cellLength; | |
if (cellLength > maxCellLength) { | |
maxCellLength = cellLength; | |
} | |
} | |
var neighbourListLength = 27 * maxCellLength + 1; | |
var withinRadii = /* @__PURE__ */ __name(function(x, y, z, rExtra, out) { | |
var outIdx = 0; | |
var nearI = hashFunc(x, minX); | |
var nearJ = hashFunc(y, minY); | |
var nearK = hashFunc(z, minZ); | |
var loI = Math.max(0, nearI - 1); | |
var loJ = Math.max(0, nearJ - 1); | |
var loK = Math.max(0, nearK - 1); | |
var hiI = Math.min(iDim, nearI + 2); | |
var hiJ = Math.min(jDim, nearJ + 2); | |
var hiK = Math.min(kDim, nearK + 2); | |
for (var i2 = loI; i2 < hiI; ++i2) { | |
var iOffset = i2 * jkDim; | |
for (var j2 = loJ; j2 < hiJ; ++j2) { | |
var jOffset = j2 * kDim; | |
for (var k = loK; k < hiK; ++k) { | |
var cid2 = iOffset + jOffset + k; | |
var cellStart = cellOffsets[cid2]; | |
var cellEnd = cellStart + cellLengths[cid2]; | |
for (var dataIndex = cellStart; dataIndex < cellEnd; dataIndex++) { | |
var atomIndex = data[dataIndex]; | |
var dx = atomsX[atomIndex] - x; | |
var dy = atomsY[atomIndex] - y; | |
var dz = atomsZ[atomIndex] - z; | |
var rSum = atomsR[atomIndex] + rExtra; | |
if (dx * dx + dy * dy + dz * dz <= rSum * rSum) { | |
out[outIdx++] = data[dataIndex]; | |
} | |
} | |
} | |
} | |
} | |
out[outIdx] = -1; | |
}, "withinRadii"); | |
return { | |
neighbourListLength, | |
withinRadii | |
}; | |
} | |
function makeGrid(length2, width, height, DataCtor, elemSize) { | |
DataCtor = DataCtor || Int32Array; | |
elemSize = elemSize || 1; | |
var data = new DataCtor(length2 * width * height * elemSize); | |
function index(x, y, z) { | |
return ((x * width + y) * height + z) * elemSize; | |
} | |
__name(index, "index"); | |
function set3(x, y, z) { | |
var args = [], len = arguments.length - 3; | |
while (len-- > 0) | |
args[len] = arguments[len + 3]; | |
var i = index(x, y, z); | |
for (var j = 0; j < elemSize; ++j) { | |
data[i + j] = args[j]; | |
} | |
} | |
__name(set3, "set"); | |
function toArray3(x, y, z, array, offset) { | |
if (array === void 0) | |
array = []; | |
if (offset === void 0) | |
offset = 0; | |
var i = index(x, y, z); | |
for (var j = 0; j < elemSize; ++j) { | |
array[offset + j] = data[i + j]; | |
} | |
} | |
__name(toArray3, "toArray"); | |
function fromArray(x, y, z, array, offset) { | |
if (offset === void 0) | |
offset = 0; | |
var i = index(x, y, z); | |
for (var j = 0; j < elemSize; ++j) { | |
data[i + j] = array[offset + j]; | |
} | |
} | |
__name(fromArray, "fromArray"); | |
function copy(grid) { | |
data.set(grid.data); | |
} | |
__name(copy, "copy"); | |
return {data, index, set: set3, toArray: toArray3, fromArray, copy}; | |
} | |
function normalizeVector3array(a) { | |
for (var i = 0, il = a.length; i < il; i += 3) { | |
var x = a[i]; | |
var y = a[i + 1]; | |
var z = a[i + 2]; | |
var len2 = x * x + y * y + z * z; | |
if (len2 > 0) { | |
var s = 1 / Math.sqrt(len2); | |
a[i] = x * s; | |
a[i + 1] = y * s; | |
a[i + 2] = z * s; | |
} | |
} | |
} | |
function uniformArray(n, a, optionalTarget) { | |
var array = optionalTarget || new Float32Array(n); | |
for (var i = 0; i < n; ++i) { | |
array[i] = a; | |
} | |
return array; | |
} | |
function v3addScalar(out, a, s) { | |
out[0] = a[0] + s; | |
out[1] = a[1] + s; | |
out[2] = a[2] + s; | |
} | |
function v3ceil(out, a) { | |
out[0] = Math.ceil(a[0]); | |
out[1] = Math.ceil(a[1]); | |
out[2] = Math.ceil(a[2]); | |
} | |
function v3cross(out, a, b) { | |
var ax = a[0]; | |
var ay = a[1]; | |
var az = a[2]; | |
var bx = b[0]; | |
var by = b[1]; | |
var bz = b[2]; | |
out[0] = ay * bz - az * by; | |
out[1] = az * bx - ax * bz; | |
out[2] = ax * by - ay * bx; | |
} | |
function v3divideScalar(out, a, s) { | |
v3multiplyScalar(out, a, 1 / s); | |
} | |
function v3floor(out, a) { | |
out[0] = Math.floor(a[0]); | |
out[1] = Math.floor(a[1]); | |
out[2] = Math.floor(a[2]); | |
} | |
function v3fromArray(out, array, offset) { | |
if (offset === void 0) | |
offset = 0; | |
out[0] = array[offset]; | |
out[1] = array[offset + 1]; | |
out[2] = array[offset + 2]; | |
} | |
function v3length2(a) { | |
return a[0] * a[0] + a[1] * a[1] + a[2] * a[2]; | |
} | |
function v3multiplyScalar(out, a, s) { | |
out[0] = a[0] * s; | |
out[1] = a[1] * s; | |
out[2] = a[2] * s; | |
} | |
function v3negate(out, a) { | |
out[0] = -a[0]; | |
out[1] = -a[1]; | |
out[2] = -a[2]; | |
} | |
function v3new(array) { | |
return new Float32Array(array || 3); | |
} | |
function v3normalize(out, a) { | |
var length2 = v3length2(a); | |
if (length2 == 0) { | |
out[0] = a[0]; | |
out[1] = a[1]; | |
out[2] = a[2]; | |
} else { | |
v3multiplyScalar(out, a, 1 / Math.sqrt(length2)); | |
} | |
} | |
function v3sub(out, a, b) { | |
out[0] = a[0] - b[0]; | |
out[1] = a[1] - b[1]; | |
out[2] = a[2] - b[2]; | |
} | |
function v3subScalar(out, a, s) { | |
out[0] = a[0] - s; | |
out[1] = a[1] - s; | |
out[2] = a[2] - s; | |
} | |
self.func = function func2(e, callback) { | |
var a = e.data.args; | |
var p = e.data.params; | |
if (a && p) { | |
var SurfClass = p.type === "av" ? AVSurface : EDTSurface; | |
var surf = new SurfClass(a.coordList, a.radiusList, a.indexList); | |
var sd = surf.getSurface(p.type, p.probeRadius, p.scaleFactor, p.cutoff, true, p.smooth, p.contour); | |
var transferList = [sd.position.buffer, sd.index.buffer]; | |
if (sd.normal) { | |
transferList.push(sd.normal.buffer); | |
} | |
if (sd.atomindex) { | |
transferList.push(sd.atomindex.buffer); | |
} | |
var data = { | |
sd, | |
p | |
}; | |
callback(data, transferList); | |
} | |
}; | |
self.onmessage = function onmessage(e) { | |
var name = e.data.__name; | |
var postId = e.data.__postId; | |
if (name === void 0) { | |
console.error("message __name undefined"); | |
} else if (self.func === void 0) { | |
console.error("worker func undefined", name); | |
} else { | |
var callback = /* @__PURE__ */ __name(function(aMessage, transferList) { | |
aMessage = aMessage || {}; | |
if (postId !== void 0) { | |
aMessage.__postId = postId; | |
} | |
try { | |
self.postMessage(aMessage, transferList); | |
} catch (error) { | |
console.error("self.postMessage:", error); | |
self.postMessage(aMessage); | |
} | |
}, "callback"); | |
self.func(e, callback); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file AV Surface | |
* @author Fred Ludlow <fred.ludlow@gmail.com> | |
* @private | |
*/ | |
import { getSurfaceGrid } from './surface-utils' | |
import { VolumeSurface } from './volume' | |
import { uniformArray } from '../math/array-utils' | |
import { | |
computeBoundingBox, v3multiplyScalar, v3cross, v3normalize | |
} from '../math/vector-utils' | |
import { defaults } from '../utils' | |
import { NumberArray } from '../types'; | |
/** | |
* Modifed from SpatialHash | |
* | |
* Main differences are: | |
* - Optimized grid size to ensure we only ever need to look +/-1 cell | |
* - Aware of atomic radii and will only output atoms within rAtom + rExtra | |
* (see withinRadii method) | |
* | |
* (Uses rounding rather than bitshifting as consequence of arbitrary grid size) | |
* @class | |
* @param {Float32Array} atomsX - x coordinates | |
* @param {Float32Array} atomsY - y coordinates | |
* @param {Float32Array} atomsZ - z coordinates | |
* @param {Float32Array} atomsR - atom radii | |
* @param {Float32Array} min - xyz min coordinates | |
* @param {Float32Array} max - xyz max coordinates | |
* @param {Float} maxDistance - max distance | |
*/ | |
export interface iAVHash { | |
neighbourListLength: number | |
withinRadii: (x: number, y: number, z: number, rExtra: number, out: Int32Array) => void | |
} | |
function makeAVHash (atomsX: Float32Array, atomsY: Float32Array, atomsZ: Float32Array, atomsR: Float32Array, min: Float32Array, max: Float32Array, maxDistance: number): iAVHash { | |
maxDistance = Math.max(0.1, maxDistance) // Avoid maxDistance of zero, see #802 | |
var nAtoms = atomsX.length | |
var minX = min[ 0 ] | |
var minY = min[ 1 ] | |
var minZ = min[ 2 ] | |
var maxX = max[ 0 ] | |
var maxY = max[ 1 ] | |
var maxZ = max[ 2 ] | |
function hashFunc (w: number, minW: number) { | |
return Math.floor((w - minW) / maxDistance) | |
} | |
var iDim = hashFunc(maxX, minX) + 1 | |
var jDim = hashFunc(maxY, minY) + 1 | |
var kDim = hashFunc(maxZ, minZ) + 1 | |
var nCells = iDim * jDim * kDim | |
var jkDim = jDim * kDim | |
/* Get cellID for cartesian x,y,z */ | |
var cellID = function (x: number, y: number, z: number) { | |
return (((hashFunc(x, minX) * jDim) + hashFunc(y, minY)) * kDim) + hashFunc(z, minZ) | |
} | |
/* Initial building, could probably be optimized further */ | |
var preHash = [] // preHash[ cellID ] = [ atomId1, atomId2 ]; | |
for (var i = 0; i < nAtoms; i++) { | |
var cid = cellID(atomsX[ i ], atomsY[ i ], atomsZ[ i ]) | |
if (preHash[ cid ] === undefined) { | |
preHash[ cid ] = [ i ] | |
} else { | |
preHash[ cid ].push(i) | |
} | |
} | |
var cellOffsets = new Uint32Array(nCells) | |
var cellLengths = new Uint16Array(nCells) | |
var data = new Uint32Array(nAtoms) | |
var offset = 0 | |
var maxCellLength = 0 | |
for (i = 0; i < nCells; i++) { | |
var start = cellOffsets[ i ] = offset | |
var subArray = preHash[ i ] | |
if (subArray !== undefined) { | |
for (var j = 0; j < subArray.length; j++) { | |
data[ offset ] = subArray[ j ] | |
offset++ | |
} | |
} | |
var cellLength = offset - start | |
cellLengths[ i ] = cellLength | |
if (cellLength > maxCellLength) { maxCellLength = cellLength } | |
} | |
// Maximum number of neighbours we could ever produce (27 adjacent cells of equal population) | |
const neighbourListLength = (27 * maxCellLength) + 1 | |
/** | |
* Populate the supplied out array with atom indices that are within rAtom + rExtra | |
* of x,y,z | |
* | |
* -1 in out array indicates the end of the list | |
* | |
* @param {Float} x - x coordinate | |
* @param {Float} y - y coordinate | |
* @param {Float} z - z coordinate | |
* @param {Float} rExtra - additional radius | |
* @param {Float32Array} out - pre-allocated output array | |
* @return {undefined} | |
*/ | |
const withinRadii = function (x: number, y: number, z: number, rExtra: number, out: Int32Array) { | |
var outIdx = 0 | |
var nearI = hashFunc(x, minX) | |
var nearJ = hashFunc(y, minY) | |
var nearK = hashFunc(z, minZ) | |
var loI = Math.max(0, nearI - 1) | |
var loJ = Math.max(0, nearJ - 1) | |
var loK = Math.max(0, nearK - 1) | |
var hiI = Math.min(iDim, nearI + 2) | |
var hiJ = Math.min(jDim, nearJ + 2) | |
var hiK = Math.min(kDim, nearK + 2) | |
for (var i = loI; i < hiI; ++i) { | |
var iOffset = i * jkDim | |
for (var j = loJ; j < hiJ; ++j) { | |
var jOffset = j * kDim | |
for (var k = loK; k < hiK; ++k) { | |
var cid = iOffset + jOffset + k | |
var cellStart = cellOffsets[ cid ] | |
var cellEnd = cellStart + cellLengths[ cid ] | |
for (var dataIndex = cellStart; dataIndex < cellEnd; dataIndex++) { | |
var atomIndex = data[ dataIndex ] | |
var dx = atomsX[ atomIndex ] - x | |
var dy = atomsY[ atomIndex ] - y | |
var dz = atomsZ[ atomIndex ] - z | |
var rSum = atomsR[ atomIndex ] + rExtra | |
if ((dx * dx + dy * dy + dz * dz) <= (rSum * rSum)) { | |
out[ outIdx++ ] = data[ dataIndex ] | |
} | |
} | |
} | |
} | |
} | |
// Add terminator | |
out[ outIdx ] = -1 | |
} | |
return { | |
neighbourListLength: neighbourListLength, | |
withinRadii: withinRadii | |
} | |
} | |
interface AVSurface { | |
getSurface: (type: string, probeRadius: number, scaleFactor: number, cutoff: number, setAtomID: boolean, smooth: number, contour: boolean) => any | |
} | |
function AVSurface (this: AVSurface, coordList: Float32Array, radiusList: Float32Array, indexList: Uint16Array|Uint32Array) { | |
// Field generation method adapted from AstexViewer (Mike Hartshorn) | |
// by Fred Ludlow. | |
// Other parts based heavily on NGL (Alexander Rose) EDT Surface class | |
// | |
// Should work as a drop-in alternative to EDTSurface (though some of | |
// the EDT paramters are not relevant in this method). | |
const nAtoms = radiusList.length | |
const x = new Float32Array(nAtoms) | |
const y = new Float32Array(nAtoms) | |
const z = new Float32Array(nAtoms) | |
for (let i = 0; i < nAtoms; i++) { | |
const ci = 3 * i | |
x[ i ] = coordList[ ci ] | |
y[ i ] = coordList[ ci + 1 ] | |
z[ i ] = coordList[ ci + 2 ] | |
} | |
let bbox = computeBoundingBox(coordList) | |
if (coordList.length === 0) { | |
bbox[ 0 ].set([ 0, 0, 0 ]) | |
bbox[ 1 ].set([ 0, 0, 0 ]) | |
} | |
const min = bbox[0] | |
const max = bbox[1] | |
let r: Float32Array, r2: Float32Array // Atom positions, expanded radii (squared) | |
let maxRadius: number | |
// Parameters | |
let probeRadius: number, scaleFactor: number, setAtomID: boolean, probePositions: number | |
// Cache last value for obscured test | |
let lastClip = -1 | |
// Grid params | |
let dim: Float32Array, matrix: Float32Array, grid: NumberArray, atomIndex: Int32Array | |
// grid indices -> xyz coords | |
let gridx: Float32Array, gridy: Float32Array, gridz: Float32Array | |
// Lookup tables: | |
let sinTable: Float32Array, cosTable: Float32Array | |
// Spatial Hash | |
let hash: iAVHash | |
// Neighbour array to be filled by hash | |
let neighbours: Int32Array | |
// Vectors for Torus Projection | |
const atob = new Float32Array([ 0.0, 0.0, 0.0 ]) | |
const mid = new Float32Array([ 0.0, 0.0, 0.0 ]) | |
const n1 = new Float32Array([ 0.0, 0.0, 0.0 ]) | |
const n2 = new Float32Array([ 0.0, 0.0, 0.0 ]) | |
let ngTorus: number | |
function init (_probeRadius?: number, _scaleFactor?: number, _setAtomID?: boolean, _probePositions?: number) { | |
probeRadius = defaults(_probeRadius, 1.4) | |
scaleFactor = defaults(_scaleFactor, 2.0) | |
setAtomID = defaults(_setAtomID, true) | |
probePositions = defaults(_probePositions, 30) | |
r = new Float32Array(nAtoms) | |
r2 = new Float32Array(nAtoms) | |
for (let i = 0; i < r.length; ++i) { | |
var rExt = radiusList[ i ] + probeRadius | |
r[ i ] = rExt | |
r2[ i ] = rExt * rExt | |
} | |
maxRadius = 0 | |
for (let j = 0; j < r.length; ++j) { | |
if (r[ j ] > maxRadius) maxRadius = r[ j ] | |
} | |
initializeGrid() | |
initializeAngleTables() | |
initializeHash() | |
lastClip = -1 | |
} | |
function fillGridDim (a: Float32Array, start: number, step: number) { | |
for (let i = 0; i < a.length; i++) { | |
a[i] = start + (step * i) | |
} | |
} | |
function initializeGrid () { | |
const surfGrid = getSurfaceGrid( | |
min, max, maxRadius, scaleFactor, 0.0 | |
) | |
scaleFactor = surfGrid.scaleFactor | |
dim = surfGrid.dim | |
matrix = surfGrid.matrix | |
ngTorus = Math.max(5, 2 + Math.floor(probeRadius * scaleFactor)) | |
grid = uniformArray(dim[0] * dim[1] * dim[2], -1001.0) | |
atomIndex = new Int32Array(grid.length) | |
gridx = new Float32Array(dim[0]) | |
gridy = new Float32Array(dim[1]) | |
gridz = new Float32Array(dim[2]) | |
fillGridDim(gridx, min[0], 1 / scaleFactor) | |
fillGridDim(gridy, min[1], 1 / scaleFactor) | |
fillGridDim(gridz, min[2], 1 / scaleFactor) | |
} | |
function initializeAngleTables () { | |
var theta = 0.0 | |
var step = 2 * Math.PI / probePositions | |
cosTable = new Float32Array(probePositions) | |
sinTable = new Float32Array(probePositions) | |
for (var i = 0; i < probePositions; i++) { | |
cosTable[ i ] = Math.cos(theta) | |
sinTable[ i ] = Math.sin(theta) | |
theta += step | |
} | |
} | |
function initializeHash () { | |
hash = makeAVHash(x, y, z, r, min, max, 2.01 * maxRadius) | |
neighbours = new Int32Array(hash.neighbourListLength) | |
} | |
function obscured (x: number, y: number, z: number, a: number, b: number) { | |
// Is the point at x,y,z obscured by any of the atoms | |
// specifeid by indices in neighbours. Ignore indices | |
// a and b (these are the relevant atoms in projectPoints/Torii) | |
// Cache the last clipped atom (as very often the same one in | |
// subsequent calls) | |
let ai: number | |
if (lastClip !== -1) { | |
ai = lastClip | |
if (ai !== a && ai !== b && singleAtomObscures(ai, x, y, z)) { | |
return ai | |
} else { | |
lastClip = -1 | |
} | |
} | |
var ni = 0 | |
ai = neighbours[ ni ] | |
while (ai >= 0) { | |
if (ai !== a && ai !== b && singleAtomObscures(ai, x, y, z)) { | |
lastClip = ai | |
return ai | |
} | |
ai = neighbours[ ++ni ] | |
} | |
lastClip = -1 | |
return -1 | |
} | |
function singleAtomObscures (ai: number, x: number, y: number, z: number) { | |
var ci = 3 * ai | |
var ra2 = r2[ ai ] | |
var dx = coordList[ ci ] - x | |
var dy = coordList[ ci + 1 ] - y | |
var dz = coordList[ ci + 2 ] - z | |
var d2 = dx * dx + dy * dy + dz * dz | |
return d2 < ra2 | |
} | |
function projectPoints () { | |
// For each atom: | |
// Iterate over a subsection of the grid, for each point: | |
// If current value < 0.0, unvisited, set positive | |
// | |
// In any case: Project this point onto surface of the atomic sphere | |
// If this projected point is not obscured by any other atom | |
// Calcualte delta distance and set grid value to minimum of | |
// itself and delta | |
// Should we alias frequently accessed closure variables?? | |
// Assume JS engine capable of optimizing this | |
// anyway... | |
for (var i = 0; i < nAtoms; i++) { | |
var ax = x[ i ] | |
var ay = y[ i ] | |
var az = z[ i ] | |
var ar = r[ i ] | |
var ar2 = r2[ i ] | |
hash.withinRadii(ax, ay, az, ar, neighbours) | |
// Number of grid points, round this up... | |
var ng = Math.ceil(ar * scaleFactor) | |
// Center of the atom, mapped to grid points (take floor) | |
var iax = Math.floor(scaleFactor * (ax - min[ 0 ])) | |
var iay = Math.floor(scaleFactor * (ay - min[ 1 ])) | |
var iaz = Math.floor(scaleFactor * (az - min[ 2 ])) | |
// Extents of grid to consider for this atom | |
var minx = Math.max(0, iax - ng) | |
var miny = Math.max(0, iay - ng) | |
var minz = Math.max(0, iaz - ng) | |
// Add two to these points: | |
// - iax are floor'd values so this ensures coverage | |
// - these are loop limits (exclusive) | |
var maxx = Math.min(dim[ 0 ], iax + ng + 2) | |
var maxy = Math.min(dim[ 1 ], iay + ng + 2) | |
var maxz = Math.min(dim[ 2 ], iaz + ng + 2) | |
for (var ix = minx; ix < maxx; ix++) { | |
var dx = gridx[ ix ] - ax | |
var xoffset = dim[ 1 ] * dim[ 2 ] * ix | |
for (var iy = miny; iy < maxy; iy++) { | |
var dy = gridy[ iy ] - ay | |
var dxy2 = dx * dx + dy * dy | |
var xyoffset = xoffset + dim[ 2 ] * iy | |
for (var iz = minz; iz < maxz; iz++) { | |
var dz = gridz[ iz ] - az | |
var d2 = dxy2 + dz * dz | |
if (d2 < ar2) { | |
var idx = iz + xyoffset | |
if (grid[idx] < 0.0) { | |
// Unvisited, make positive | |
grid[ idx ] = -grid[ idx ] | |
} | |
// Project on to the surface of the sphere | |
// sp is the projected point ( dx, dy, dz ) * ( ra / d ) | |
var d = Math.sqrt(d2) | |
var ap = ar / d | |
var spx = dx * ap | |
var spy = dy * ap | |
var spz = dz * ap | |
spx += ax | |
spy += ay | |
spz += az | |
if (obscured(spx, spy, spz, i, -1) === -1) { | |
var dd = ar - d | |
if (dd < grid[ idx ]) { | |
grid[ idx ] = dd | |
if (setAtomID) atomIndex[ idx ] = i | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
function projectTorii () { | |
for (var i = 0; i < nAtoms; i++) { | |
hash.withinRadii(x[ i ], y[ i ], z[ i ], r[ i ], neighbours) | |
var ia = 0 | |
var ni = neighbours[ ia ] | |
while (ni >= 0) { | |
if (i < ni) { | |
projectTorus(i, ni) | |
} | |
ni = neighbours[ ++ia ] | |
} | |
} | |
} | |
function projectTorus (a: number, b: number) { | |
var r1 = r[ a ] | |
var r2 = r[ b ] | |
var dx = atob[ 0 ] = x[ b ] - x[ a ] | |
var dy = atob[ 1 ] = y[ b ] - y[ a ] | |
var dz = atob[ 2 ] = z[ b ] - z[ a ] | |
var d2 = dx * dx + dy * dy + dz * dz | |
// This check now redundant as already done in AVHash.withinRadii | |
// if( d2 > (( r1 + r2 ) * ( r1 + r2 )) ){ return; } | |
var d = Math.sqrt(d2) | |
// Find angle between a->b vector and the circle | |
// of their intersection by cosine rule | |
var cosA = (r1 * r1 + d * d - r2 * r2) / (2.0 * r1 * d) | |
// distance along a->b at intersection | |
var dmp = r1 * cosA | |
v3normalize(atob, atob) | |
// Create normal to line | |
normalToLine(n1 as any, atob) | |
v3normalize(n1, n1) | |
// Cross together for second normal vector | |
v3cross(n2, atob, n1) | |
v3normalize(n2, n2) | |
// r is radius of circle of intersection | |
var rInt = Math.sqrt(r1 * r1 - dmp * dmp) | |
v3multiplyScalar(n1, n1, rInt) | |
v3multiplyScalar(n2, n2, rInt) | |
v3multiplyScalar(atob, atob, dmp) | |
mid[ 0 ] = atob[ 0 ] + x[ a ] | |
mid[ 1 ] = atob[ 1 ] + y[ a ] | |
mid[ 2 ] = atob[ 2 ] + z[ a ] | |
lastClip = -1 | |
var ng = ngTorus | |
for (var i = 0; i < probePositions; i++) { | |
var cost = cosTable[ i ] | |
var sint = sinTable[ i ] | |
var px = mid[ 0 ] + cost * n1[ 0 ] + sint * n2[ 0 ] | |
var py = mid[ 1 ] + cost * n1[ 1 ] + sint * n2[ 1 ] | |
var pz = mid[ 2 ] + cost * n1[ 2 ] + sint * n2[ 2 ] | |
if (obscured(px, py, pz, a, b) === -1) { | |
// As above, iterate over our grid... | |
// px, py, pz in grid coords | |
var iax = Math.floor(scaleFactor * (px - min[ 0 ])) | |
var iay = Math.floor(scaleFactor * (py - min[ 1 ])) | |
var iaz = Math.floor(scaleFactor * (pz - min[ 2 ])) | |
var minx = Math.max(0, iax - ng) | |
var miny = Math.max(0, iay - ng) | |
var minz = Math.max(0, iaz - ng) | |
var maxx = Math.min(dim[ 0 ], iax + ng + 2) | |
var maxy = Math.min(dim[ 1 ], iay + ng + 2) | |
var maxz = Math.min(dim[ 2 ], iaz + ng + 2) | |
for (var ix = minx; ix < maxx; ix++) { | |
dx = px - gridx[ ix ] | |
var xoffset = dim[ 1 ] * dim[ 2 ] * ix | |
for (var iy = miny; iy < maxy; iy++) { | |
dy = py - gridy[ iy ] | |
var dxy2 = dx * dx + dy * dy | |
var xyoffset = xoffset + dim[ 2 ] * iy | |
for (var iz = minz; iz < maxz; iz++) { | |
dz = pz - gridz[ iz ] | |
d2 = dxy2 + dz * dz | |
var idx = iz + xyoffset | |
var current = grid[ idx ] | |
if (current > 0.0 && d2 < (current * current)) { | |
grid[ idx ] = Math.sqrt(d2) | |
if (setAtomID) { | |
// Is this grid point closer to a or b? | |
// Take dot product of atob and gridpoint->p (dx, dy, dz) | |
const dp = dx * atob[ 0 ] + dy * atob [ 1 ] + dz * atob[ 2 ] | |
atomIndex[ idx ] = dp < 0.0 ? b : a | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
function normalToLine (out: Int32Array, p: Float32Array) { | |
out[ 0 ] = out[ 1 ] = out[ 2 ] = 1.0 | |
if (p[ 0 ] !== 0) { | |
out[ 0 ] = (p[ 1 ] + p[ 2 ]) / -p[ 0 ] | |
} else if (p[ 1 ] !== 0) { | |
out[ 1 ] = (p[ 0 ] + p[ 2 ]) / -p[ 1 ] | |
} else if (p[ 2 ] !== 0) { | |
out[ 2 ] = (p[ 0 ] + p[ 1 ]) / -p[ 2 ] | |
} | |
return out | |
} | |
function fixNegatives () { | |
for (var i = 0; i < grid.length; i++) { | |
if (grid[ i ] < 0) grid[ i ] = 0 | |
} | |
} | |
function fixAtomIDs () { | |
for (var i = 0; i < atomIndex.length; i++) { | |
atomIndex[ i ] = indexList[ atomIndex[ i ] ] | |
} | |
} | |
function getVolume (probeRadius: number, scaleFactor: number, setAtomID: boolean) { | |
// Basic steps are: | |
// 1) Initialize | |
// 2) Project points | |
// 3) Project torii | |
console.time('AVSurface.getVolume') | |
console.time('AVSurface.init') | |
init(probeRadius, scaleFactor, setAtomID) | |
console.timeEnd('AVSurface.init') | |
console.time('AVSurface.projectPoints') | |
projectPoints() | |
console.timeEnd('AVSurface.projectPoints') | |
console.time('AVSurface.projectTorii') | |
projectTorii() | |
console.timeEnd('AVSurface.projectTorii') | |
fixNegatives() | |
fixAtomIDs() | |
console.timeEnd('AVSurface.getVolume') | |
} | |
this.getSurface = function (type: string, probeRadius: number, scaleFactor: number, cutoff: number, setAtomID: boolean, smooth: number, contour: boolean) { | |
// type and cutoff left in for compatibility with EDTSurface.getSurface | |
// function signature | |
getVolume(probeRadius, scaleFactor, setAtomID) | |
var volsurf = new (VolumeSurface as any)( | |
grid, dim[ 2 ], dim[ 1 ], dim[ 0 ], atomIndex | |
) as VolumeSurface | |
return volsurf.getSurface!(probeRadius, false, undefined, matrix, contour) | |
} | |
} | |
Object.assign(AVSurface, {__deps: [ | |
getSurfaceGrid, VolumeSurface, uniformArray, computeBoundingBox, | |
v3multiplyScalar, v3cross, v3normalize, | |
makeAVHash, | |
defaults | |
]}) | |
export { AVSurface, makeAVHash } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment