UNPKG

videx-3d

Version:

React 3D component library designed for sub surface visualizations in the browser

712 lines (711 loc) 19.9 kB
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 };