videx-3d
Version:
React 3D component library designed for sub surface visualizations in the browser
682 lines (681 loc) • 19.3 kB
JavaScript
import { transfer as L } from "comlink";
import "p-limit";
import { j as x, d as T, t as it, D as ct, E as I, a as _, h as ot, x as ut, v as mt, a2 as lt, Z as pt, J as gt, K as dt, Y as ft, i as ht } from "./chunk-CkcLzcfd.js";
import { Vector3 as v, Matrix4 as $, Color as nt, BufferGeometry as yt, BufferAttribute as U } from "three";
import "three/src/math/MathUtils.js";
import "proj4";
import { clamp as Tt } from "curve-interpolator";
import { group as st } from "d3-array";
import { mergeGeometries as W } from "three/examples/jsm/utils/BufferGeometryUtils.js";
import { c as N, b as Mt, f as wt, d as vt, t as bt } from "./chunk-DEgGMqNw.js";
import { b as At, d as xt } from "./chunk-BX-cez1_.js";
async function Ht(e, n, u = 0, c, m = !1) {
const t = await this.get("position-logs", e), o = x(e, t);
if (!o) return null;
const a = c !== void 0 ? T(
(c - o.measuredTop) / o.measuredLength,
0,
1
) : 0, l = it(
o.curve,
a,
1,
n,
u
), s = new Float32Array(l.length * 3), p = m ? new Float32Array(l.length) : null;
l.forEach((d, f) => {
const w = o.curve.getPointAt(d);
s[f * 3] = w[0], s[f * 3 + 1] = w[1], s[f * 3 + 2] = w[2], p && (p[f] = d);
});
const i = {
position: {
array: s,
itemSize: 3
}
};
p && (i.lengths = {
array: p,
itemSize: 1
});
const [r, g] = ct({ attributes: i });
return L(r, g);
}
async function Jt(e) {
const n = await this.get("casings", e);
if (!n) return null;
const u = await this.get("position-logs", e), c = x(e, u);
return c ? n.filter((t) => t.mdBottomMsl > c.measuredTop).map((t) => {
const o = T(
(t.mdTopMsl + (t.mdBottomMsl - t.mdTopMsl) / 2 - c.measuredTop) / c.measuredLength,
0,
1
);
return {
name: `${t.properties.Diameter} ${t.properties.Type}`,
data: t.properties,
position: c.curve.getPointAt(o),
direction: c.curve.getTangentAt(o),
priority: t.type === "Shoe" ? 50 : t.innerDiameter
};
}) : null;
}
function Lt(e, n, u, c, m = 0) {
const t = T(
n.mdBottomMsl - n.mdTopMsl,
1e-4,
e.measuredLength
), o = 1 / e.measuredLength, a = [], l = T(
(n.mdTopMsl - e.measuredTop) / e.measuredLength,
0,
1
), s = T(
(n.mdBottomMsl - e.measuredTop) / e.measuredLength,
0,
1
), p = u * (n.outerDiameter / 2), i = Math.max(
(n.innerDiameter + (n.outerDiameter - n.innerDiameter) / 4) / 2 * u,
p * 0.95
);
a.push([l, i]);
const r = Math.min((p - i) * 2, t / 3) * o;
return a.push([l + r, p]), a.push([s - r, p]), a.push([s, i]), N(e.curve, {
...c,
from: Math.max(l, m),
to: s,
innerRadius: n.innerDiameter / 2 * u,
radiusModifier: {
type: "linear",
steps: a
}
});
}
function Bt(e, n, u, c, m, t = 0) {
const o = T(
(n.mdTopMsl - e.measuredTop) / e.measuredLength,
0,
1
), a = T(
(n.mdBottomMsl - e.measuredTop) / e.measuredLength,
0,
1
), l = n.outerDiameter / 2 * u, s = l * m, p = n.innerDiameter / 2 * u;
return N(e.curve, {
...c,
from: Math.max(o, t),
to: a,
radiusModifier: {
type: "linear",
steps: [
[o, l],
[o + (a - o) / 4, l],
[a, s]
]
},
innerRadius: p
});
}
async function Kt(e, n, u = 16, c = 1, m = 2, t = 0.1, o = 0) {
const a = await this.get("casings", e);
if (!a) return null;
const l = await this.get("position-logs", e), s = x(e, l);
if (!s) return null;
const p = n !== void 0 ? T(
(n - s.measuredTop) / s.measuredLength,
0,
1
) : 0, i = {
startCap: !0,
endCap: !0,
radialSegments: u,
addGroups: !0,
computeNormals: !0,
computeUvs: !0,
simplificationThreshold: o,
segmentsPerMeter: t
}, r = [], g = [], d = a.filter(
(M) => M.mdBottomMsl > s.measuredTop && (n === void 0 || M.mdBottomMsl > n)
).sort((M, h) => M.outerDiameter - h.outerDiameter);
if (d.length === 0) return null;
st(d, (M) => ({
category: ["Shoe", "Casing"].includes(M.type) ? M.type : "Generic",
dimmension: M.outerDiameter
})).forEach((M, h) => {
const B = M.map((D) => {
let F;
return h.category === "Shoe" ? F = Bt(
s,
D,
c,
i,
m,
p
) : F = Lt(
s,
D,
c,
i,
p
), F;
});
g.push(At[h.category]), r.push(W(B, !1));
});
const w = W(r, !0);
w.groups.forEach((M, h) => {
M.materialIndex = g[h];
});
const [b, y] = I(w);
return L({
geometry: b
}, y);
}
async function Zt(e) {
const n = await this.get("completion-tools", e);
if (!n) return null;
const u = await this.get("position-logs", e), c = x(e, u);
return c ? n.filter((t) => t.mdBottomMsl > c.measuredTop).map((t) => {
const o = T(
(t.mdTopMsl + t.length / 2 - c.measuredTop) / c.measuredLength,
0,
1
);
return {
name: t.name,
//data: d,
position: c.curve.getPointAt(o),
direction: c.curve.getTangentAt(o),
priority: t.diameterMax
};
}) : null;
}
function $t(e, n, u, c, m) {
const t = T(n.length, 1e-4, e.measuredLength), o = 1 / e.measuredLength, a = [], l = T(
(n.mdTopMsl - e.measuredTop) / e.measuredLength,
0,
1
), s = T(
(n.mdBottomMsl - e.measuredTop) / e.measuredLength,
0,
1
), p = u * ((n.diameterTop || n.diameterBottom) / 2), i = u * ((n.diameterBottom || n.diameterTop) / 2), r = u * ((n.diameterMax || n.diameterTop) / 2), g = Math.min(p, i, r);
a.push([l, p]);
const d = Math.min((r - g) * 2, t / 3) * o;
return r > g && (a.push([l + d, r]), a.push([s - d, r])), a.push([s, i]), N(e.curve, {
...m,
from: Math.max(l, c),
to: s,
computeLengths: !0,
radiusModifier: {
type: "linear",
steps: a
}
});
}
async function qt(e, n, u = 16, c = 1, m = 0.1, t = 0) {
const o = await this.get("completion-tools", e);
if (!o) return null;
const a = await this.get("position-logs", e), l = x(e, a);
if (!l) return null;
const s = n !== void 0 ? T(
(n - l.measuredTop) / l.measuredLength,
0,
1
) : 0, p = o.filter(
(y) => y.mdBottomMsl > l.measuredTop && (n === void 0 || y.mdBottomMsl > n)
).sort((y, A) => y.mdTopMsl - A.mdTopMsl), i = st(p, (y) => y.category), r = {
startCap: !0,
endCap: !0,
radialSegments: u,
computeNormals: !0,
computeUvs: !0,
segmentsPerMeter: m,
simplificationThreshold: t,
radius: 0
}, g = [], d = [];
if (i.forEach((y, A) => {
const M = y.map((h) => $t(
l,
h,
c,
s,
r
));
d.push(xt[A]), g.push(W(M, !1));
}), !g.length) return null;
const f = W(g, !0);
f.groups.forEach((y, A) => {
y.materialIndex = d[A];
});
const [w, b] = I(f);
return L(w, b);
}
async function Qt(e, n, u = "MSL", c) {
const m = await this.get(
"position-logs",
e
);
if (!m || m.length < 8) return null;
let t = 0;
if (u === "RT") {
const g = await this.get("wellbore-headers", e);
g && (t = g.depthReferenceElevation);
}
const o = x(e, m);
if (!o) return null;
const a = m[m.length - 1] + t, s = Math.max(
o.measuredTop,
c && Number.isFinite(c) ? c : o.measuredTop
) + t, p = [s];
let i = Math.floor(s / n) * n;
for (i <= s && (i += n); i < a; )
p.push(i), i += n;
return p.push(a), p.map((g) => {
const d = T(
(g - t - o.measuredTop) / o.measuredLength,
0,
1
), f = o.curve.getPointAt(d), w = o.curve.getTangentAt(d);
return {
id: `${e}_${g}`,
name: (Math.round(g * 10) / 10).toString(),
direction: w,
position: f
};
});
}
const P = new v(), J = new v(), K = new v(), Dt = new v(0, 1, 0), V = new $(), Ft = new $().makeRotationX(_), Z = new nt();
async function zt(e, n, u, c = 10) {
const m = await ot(e, n, this, u);
if (!m) return null;
const t = ut(m);
if (!t.length) return null;
const o = await this.get("position-logs", e), a = x(e, o);
if (!a) return null;
const l = t.map((r) => {
const g = Tt(
(r.mdMsl - a.measuredTop) / a.measuredLength,
0,
1
);
return {
...r,
position: a.curve.getPointAt(g),
direction: a.curve.getTangentAt(g)
};
}), s = new Float32Array(l.length * 16 * 3), p = new Float32Array(l.length * 3 * 3), i = [];
return l.forEach((r, g) => {
P.set(...r.position), V.identity();
const d = c;
K.set(d, d, d), J.set(
P.x + r.direction[0],
P.y + r.direction[1],
P.z + r.direction[2]
), V.lookAt(P, J, Dt), V.multiply(Ft), V.setPosition(P), V.scale(K), V.toArray(s, g * 16), Z.set(r.color), Z.toArray(p, g * 3), i[g] = {
id: `${e}_${g}`,
name: `${r.name} ${Mt(r.type)}`,
depth: r.mdMsl,
tvd: r.tvdMsl,
level: r.level,
direction: r.direction
};
}), L(
{
data: i,
transformations: s,
colors: p
},
[s.buffer]
);
}
const C = new v(), q = new v(), j = new v(), Pt = new v(0, 1, 0), G = new $(), Vt = new $().makeRotationX(_);
async function te(e, n, u = 1) {
const c = await this.get("perforations", e);
if (!c) return null;
const m = await this.get("position-logs", e), t = x(e, m);
if (!t) return null;
j.set(
Math.max(1, u / 2),
u,
Math.max(1, u / 2)
);
const o = [], a = c.filter(
(i) => i.status === "Open" && i.mdBottomMsl > t.measuredTop && (n === void 0 || i.mdBottomMsl > n)
).sort((i, r) => i.mdTopMsl - r.mdTopMsl);
for (let i = 0; i < a.length; i++) {
const r = a[i];
r.mdBottomMsl <= t.measuredTop || (!o.length || o[o.length - 1].bottom !== r.mdTopMsl ? o.push({
type: r.type,
top: Math.max(t.measuredTop, r.mdTopMsl),
bottom: r.mdBottomMsl,
density: wt(r.density || 0),
phase: r.phase || 0,
innerDiameter: 0,
outerDiameter: 0
}) : o.length && (o[o.length - 1].bottom = r.mdBottomMsl));
}
const l = [];
for (let i = 0; i < o.length; i++) {
const r = o[i], g = r.bottom - r.top, d = Math.max(
1,
Math.floor(g * r.density)
), f = T(
(r.top - t.measuredTop) / t.measuredLength,
0,
1
), b = (T(
(r.bottom - t.measuredTop) / t.measuredLength,
0,
1
) - f) / d, y = [];
for (let h = 0; h < d; h++)
y.push(f + b * h);
const A = mt(t.curve, y);
let M = _;
for (let h = 0; h < A.length; h++) {
const B = A[h], D = lt(
pt(B.tangent, [0, -1, 0]),
B.tangent,
M
);
l.push({
name: r.type,
position: B.position,
normal: D,
tangent: B.tangent
}), M += vt(r.phase);
}
}
const s = new Float32Array(l.length * 16 * 3), p = [];
for (let i = 0; i < l.length; i++) {
const r = l[i];
C.set(...r.position), q.set(
C.x + r.normal[0],
C.y + r.normal[1],
C.z + r.normal[2]
), j.setY(
u + u * (Math.random() - 0.5) * 0.25
), G.identity(), G.lookAt(C, q, Pt), G.multiply(Vt), G.setPosition(C), G.scale(j), G.toArray(s, i * 16), p[i] = {
id: `${e}_${i}`,
name: r.name,
direction: r.tangent
};
}
return L(
{
data: p,
transformations: s
},
[s.buffer]
);
}
async function ee(e, n, u = 0.1, c = 0) {
const m = await this.get("position-logs", e), t = x(e, m);
if (!t) return null;
const o = {
from: 0,
to: 1,
startCap: !1,
endCap: !1,
radialSegments: 32,
computeLengths: !0,
computeUvs: !0,
segmentsPerMeter: u,
simplificationThreshold: c,
radius: n
}, a = N(t.curve, o), [l, s] = I(a);
return L(l, s);
}
const k = new v(), Q = new v(), z = new v(), Ct = new v(0, 1, 0), R = new $(), Gt = new $().makeRotationX(_);
async function oe(e, n, u, c) {
const m = await this.get("position-logs", e), t = x(e, m);
if (!t) return null;
const o = t.measuredBottom, a = t.measuredLength, s = Math.max(
t.measuredTop,
c && Number.isFinite(c) ? c : t.measuredTop
), p = [s];
let i = Math.floor(s / u) * u;
for (i <= s && (i += u); i < o; )
p.push(i), i += u;
p.push(o);
const r = new Float32Array(p.length * 16 * 3), g = [];
return p.forEach((d, f) => {
const w = T((d - t.measuredTop) / a, 0, 1), b = t.curve.getPointAt(w), y = t.curve.getTangentAt(w);
k.set(...b), R.identity();
const A = n + 2 / n;
z.set(A, A, A), Q.set(
k.x + y[0],
k.y + y[1],
k.z + y[2]
), R.lookAt(k, Q, Ct), R.multiply(Gt), R.setPosition(k), R.scale(z), R.toArray(r, f * 16), g[f] = {
id: `${e}_${f}`,
depth: d,
position: b
};
}), L(
{
data: g,
transformations: r
},
[r.buffer]
);
}
const S = new v(), tt = new v(), et = new v(), kt = new v(0, 1, 0), E = new $(), Rt = new $().makeRotationX(_);
async function ne(e, n, u) {
const c = await this.get("casings", e);
if (!c) return null;
const m = await this.get("position-logs", e), t = x(e, m);
if (!t) return null;
const o = c.filter(
(s) => s.type === "Shoe" && s.mdBottomMsl > t.measuredTop && (n === void 0 || s.mdBottomMsl > n)
).map((s) => {
const p = T(
(s.mdBottomMsl - t.measuredTop) / t.measuredLength,
0,
1
);
return {
name: `${s.properties.Diameter} ${s.properties.Type}`,
data: s.properties,
position: t.curve.getPointAt(p),
direction: t.curve.getTangentAt(p),
radius: s.outerDiameter / 2
};
}), a = new Float32Array(o.length * 16 * 3), l = [];
return o.forEach((s, p) => {
S.set(...s.position), E.identity();
const i = s.radius * (u || 1);
et.set(i, i, i), tt.set(
S.x + s.direction[0],
S.y + s.direction[1],
S.z + s.direction[2]
), E.lookAt(S, tt, kt), E.multiply(Rt), E.setPosition(S), E.scale(et), E.toArray(a, p * 16), l[p] = {
id: `${e}_${p}`,
name: s.name,
direction: s.direction
};
}), L(
{
data: l,
transformations: a
},
[a.buffer]
);
}
const Y = -1;
async function se(e) {
const n = await this.get("surface-meta", e);
if (!n) return null;
const u = await this.get("surface-values", e);
if (!u) return null;
const c = gt(u, Y), m = dt(
u,
n.header.nx,
n.header.xinc,
n.header.yinc,
n.header.rot,
Y
);
return L({
elevationImageBuffer: c,
normalsImageBuffer: m
}, [c.buffer, m.buffer]);
}
async function re(e, n = 5) {
const u = await this.get("surface-meta", e);
if (!u) return null;
const c = u.max, m = await this.get("surface-values", e);
if (!m) return null;
const { header: t } = u, o = new yt(), { positions: a, uvs: l, indices: s } = bt(
m,
t.nx,
t.xinc,
t.yinc,
Y,
n
);
o.setAttribute("position", new U(a, 3)), o.setAttribute("uv", new U(l, 2)), o.setIndex(new U(s, 1)), o.translate(0, 0, -t.ny * t.yinc), o.rotateY(t.rot * (Math.PI / 180)), o.translate(0, -c, 0);
const [p, i] = I(o);
return L(p, i);
}
async function ae(e, n, u = 0, c, m = 0.5, t = 16, o = !1) {
const a = await this.get("position-logs", e), l = x(e, a);
if (!l) return null;
const p = {
from: c !== void 0 ? T(
(c - l.measuredTop) / l.measuredLength,
0,
1
) : 0,
radius: m,
startCap: !0,
endCap: !0,
segmentsPerMeter: n,
simplificationThreshold: u,
computeNormals: !0,
computeUvs: !0,
computeLengths: !!o,
radialSegments: t
}, i = N(l.curve, p), [r, g] = I(i);
return L(r, g);
}
async function ie(e, n, u = 250) {
const c = await this.get("position-logs", e), m = {
main: {
center: [0, 0, 0],
radius: 10
},
sampled: []
};
if (c) {
const a = x(e, c);
if (a) {
const l = n !== void 0 ? T(
(n - a.measuredTop) / a.measuredLength,
0,
1
) : 0, s = a.curve.getBoundingBox(l), p = (s.max[0] - s.min[0]) / 2, i = (s.max[1] - s.min[1]) / 2, r = (s.max[2] - s.min[2]) / 2, g = ft([p, i, r]) + u * 2, d = [
s.min[0] + p,
s.min[1] + i,
s.min[2] + r
];
if (m.main.center = d, m.main.radius = g, u > 0) {
const f = Math.ceil(
(1 - l) * a.curve.length / u
), w = a.curve.getPoints(f, l, 1), b = [];
w.forEach((y) => {
b.push({
center: y,
radius: u
});
}), m.sampled = b;
}
}
}
const t = new Float32Array(4 + m.sampled.length * 4);
let o = 0;
t[o] = m.main.center[0], t[o + 1] = m.main.center[1], t[o + 2] = m.main.center[2], t[o + 3] = m.main.radius, o = 4;
for (let a = 0; a < m.sampled.length; a++, o += 4)
t[o] = m.sampled[a].center[0], t[o + 1] = m.sampled[a].center[1], t[o + 2] = m.sampled[a].center[2], t[o + 3] = m.sampled[a].radius;
return L(t, [t.buffer]);
}
async function ce(e, n, u, c, m, t, o = 0.5, a = 2, l = !0, s = 16, p = 0) {
const i = await ot(e, n, this);
if (!i) return null;
const r = i.filter(
(h) => (t === void 0 || h.type && t.includes(h.type)) && (m === void 0 || m.includes(h.name))
);
if (!r.length) return null;
const g = ht(r), d = await this.get("position-logs", e), f = x(e, d);
if (!f) return null;
const w = {
startCap: l,
endCap: l,
segmentsPerMeter: u,
simplificationThreshold: p,
radialSegments: s,
computeRelativeLengths: !0
}, b = [];
if (g.forEach((h) => {
if (c === void 0 || h.mdMslTo > c) {
let B = h.mdMslFrom;
c !== void 0 && c > B && (B = c);
const D = f.getPositionAtDepth(B, !0), F = f.getPositionAtDepth(h.mdMslTo, !0);
if (D !== null && F !== null) {
const rt = a + o, at = new nt(h.color), O = N(f.curve, {
...w,
radius: rt,
from: D,
to: F
});
if (O.attributes.position.count) {
const H = new Float32Array(
O.attributes.position.count * 3
);
for (let X = 0; X < O.attributes.position.count; X++)
at.toArray(H, X * 3);
O.attributes.color = new U(H, 3), b.push(O);
}
}
}
}), !b.length) return null;
const y = W(b, !1), [A, M] = I(y);
return L(A, M);
}
async function ue(e, n, u) {
const c = await this.get("wellbore-headers", e);
if (!c) return null;
const m = await this.get("position-logs", e), t = x(e, m);
if (!t) return null;
let o = 1;
const { measuredTop: a, measuredLength: l, curve: s } = t;
if (n === "top")
o = T(((u || a) - a) / l, 0, 1);
else if (n === "center") {
const i = (u || a) + (l - (u || a)) / 2;
o = T((i - a) / l, 0, 1);
}
return [{
id: e,
name: `${c.name.replace("NO ", "")}`,
position: s.getPointAt(o),
direction: s.getTangentAt(o)
}];
}
export {
ie as calculateWellboreBounds,
Ht as generateBasicTrajectory,
Jt as generateCasingAnnotations,
Kt as generateCasings,
Zt as generateCompletionToolAnnotations,
qt as generateCompletionTools,
Qt as generateDepthMarkers,
zt as generateFormationMarkers,
te as generatePerforations,
ee as generatePerimeterGeometry,
oe as generatePositionMarkers,
ne as generateShoes,
re as generateSurfaceGeometry,
se as generateSurfaceTexturesData,
ae as generateTubeTrajectory,
ce as generateWellboreFormationColumnGeometries,
ue as generateWellboreLabel
};