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