UNPKG

videx-3d

Version:

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

682 lines (681 loc) 19.3 kB
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 };