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