UNPKG

videx-3d

Version:

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

728 lines (727 loc) 20.2 kB
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 };