@equinor/esv-intersection 3.0.1 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/index.cjs +2 -2
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.mjs +2241 -1938
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/index.umd.js +2 -2
  6. package/dist/index.umd.js.map +1 -1
  7. package/package.json +21 -22
  8. package/dist/components/axis.d.ts +0 -47
  9. package/dist/components/index.d.ts +0 -1
  10. package/dist/control/ExtendedCurveInterpolator.d.ts +0 -58
  11. package/dist/control/IntersectionReferenceSystem.d.ts +0 -96
  12. package/dist/control/LayerManager.d.ts +0 -76
  13. package/dist/control/MainController.d.ts +0 -154
  14. package/dist/control/ZoomPanHandler.d.ts +0 -158
  15. package/dist/control/index.d.ts +0 -5
  16. package/dist/control/interfaces.d.ts +0 -37
  17. package/dist/control/overlay.d.ts +0 -20
  18. package/dist/datautils/colortable.d.ts +0 -1
  19. package/dist/datautils/findsample.d.ts +0 -2
  20. package/dist/datautils/index.d.ts +0 -6
  21. package/dist/datautils/interfaces.d.ts +0 -63
  22. package/dist/datautils/picks.d.ts +0 -74
  23. package/dist/datautils/schematicShapeGenerator.d.ts +0 -59
  24. package/dist/datautils/seismicimage.d.ts +0 -45
  25. package/dist/datautils/surfacedata.d.ts +0 -10
  26. package/dist/datautils/trajectory.d.ts +0 -14
  27. package/dist/layers/CalloutCanvasLayer.d.ts +0 -60
  28. package/dist/layers/CustomDisplayObjects/ComplexRope.d.ts +0 -22
  29. package/dist/layers/CustomDisplayObjects/ComplexRopeGeometry.d.ts +0 -27
  30. package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRope.d.ts +0 -20
  31. package/dist/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.d.ts +0 -26
  32. package/dist/layers/CustomDisplayObjects/UniformTextureStretchRope.d.ts +0 -17
  33. package/dist/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.d.ts +0 -24
  34. package/dist/layers/GeomodelCanvasLayer.d.ts +0 -28
  35. package/dist/layers/GeomodelLabelsLayer.d.ts +0 -49
  36. package/dist/layers/GeomodelLayerV2.d.ts +0 -12
  37. package/dist/layers/GridLayer.d.ts +0 -29
  38. package/dist/layers/ImageCanvasLayer.d.ts +0 -20
  39. package/dist/layers/ReferenceLineLayer.d.ts +0 -29
  40. package/dist/layers/SchematicLayer.d.ts +0 -113
  41. package/dist/layers/SeismicCanvasLayer.d.ts +0 -18
  42. package/dist/layers/WellborePathLayer.d.ts +0 -17
  43. package/dist/layers/base/CanvasLayer.d.ts +0 -19
  44. package/dist/layers/base/HTMLLayer.d.ts +0 -13
  45. package/dist/layers/base/Layer.d.ts +0 -69
  46. package/dist/layers/base/PixiLayer.d.ts +0 -32
  47. package/dist/layers/base/SVGLayer.d.ts +0 -13
  48. package/dist/layers/base/index.d.ts +0 -5
  49. package/dist/layers/index.d.ts +0 -16
  50. package/dist/layers/schematicInterfaces.d.ts +0 -208
  51. package/dist/utils/arc-length.d.ts +0 -23
  52. package/dist/utils/binary-search.d.ts +0 -8
  53. package/dist/utils/color.d.ts +0 -5
  54. package/dist/utils/index.d.ts +0 -1
  55. package/dist/utils/root-finder.d.ts +0 -34
  56. package/dist/utils/text.d.ts +0 -14
  57. package/dist/utils/vectorUtils.d.ts +0 -15
  58. package/dist/vendor/pixi-dashed-line/index.d.ts +0 -57
  59. package/src/components/axis.ts +0 -247
  60. package/src/components/index.ts +0 -1
  61. package/src/control/ExtendedCurveInterpolator.ts +0 -155
  62. package/src/control/IntersectionReferenceSystem.ts +0 -391
  63. package/src/control/LayerManager.ts +0 -294
  64. package/src/control/MainController.ts +0 -296
  65. package/src/control/ZoomPanHandler.ts +0 -436
  66. package/src/control/index.ts +0 -5
  67. package/src/control/interfaces.ts +0 -42
  68. package/src/control/overlay.ts +0 -118
  69. package/src/datautils/colortable.ts +0 -14
  70. package/src/datautils/findsample.ts +0 -64
  71. package/src/datautils/index.ts +0 -6
  72. package/src/datautils/interfaces.ts +0 -68
  73. package/src/datautils/picks.ts +0 -328
  74. package/src/datautils/schematicShapeGenerator.ts +0 -1007
  75. package/src/datautils/seismicimage.ts +0 -180
  76. package/src/datautils/surfacedata.ts +0 -318
  77. package/src/datautils/trajectory.ts +0 -206
  78. package/src/layers/CalloutCanvasLayer.ts +0 -338
  79. package/src/layers/CustomDisplayObjects/ComplexRope.ts +0 -45
  80. package/src/layers/CustomDisplayObjects/ComplexRopeGeometry.ts +0 -190
  81. package/src/layers/CustomDisplayObjects/FixedWidthSimpleRope.ts +0 -41
  82. package/src/layers/CustomDisplayObjects/FixedWidthSimpleRopeGeometry.ts +0 -149
  83. package/src/layers/CustomDisplayObjects/UniformTextureStretchRope.ts +0 -39
  84. package/src/layers/CustomDisplayObjects/UniformTextureStretchRopeGeometry.ts +0 -174
  85. package/src/layers/GeomodelCanvasLayer.ts +0 -176
  86. package/src/layers/GeomodelLabelsLayer.ts +0 -619
  87. package/src/layers/GeomodelLayerV2.ts +0 -110
  88. package/src/layers/GridLayer.ts +0 -145
  89. package/src/layers/ImageCanvasLayer.ts +0 -55
  90. package/src/layers/ReferenceLineLayer.ts +0 -185
  91. package/src/layers/SchematicLayer.ts +0 -871
  92. package/src/layers/SeismicCanvasLayer.ts +0 -46
  93. package/src/layers/WellborePathLayer.ts +0 -129
  94. package/src/layers/base/CanvasLayer.ts +0 -102
  95. package/src/layers/base/HTMLLayer.ts +0 -70
  96. package/src/layers/base/Layer.ts +0 -217
  97. package/src/layers/base/PixiLayer.ts +0 -190
  98. package/src/layers/base/SVGLayer.ts +0 -63
  99. package/src/layers/base/index.ts +0 -5
  100. package/src/layers/index.ts +0 -16
  101. package/src/layers/schematicInterfaces.ts +0 -470
  102. package/src/utils/arc-length.ts +0 -66
  103. package/src/utils/binary-search.ts +0 -26
  104. package/src/utils/color.ts +0 -22
  105. package/src/utils/index.ts +0 -1
  106. package/src/utils/root-finder.ts +0 -78
  107. package/src/utils/text.ts +0 -88
  108. package/src/utils/vectorUtils.ts +0 -67
  109. package/src/vendor/pixi-dashed-line/index.ts +0 -394
@@ -1,871 +0,0 @@
1
- import { max } from 'd3-array';
2
- import { scaleLinear, ScaleLinear } from 'd3-scale';
3
- import { Graphics, groupD8, IPoint, Point, Rectangle, SimpleRope, Texture } from 'pixi.js';
4
- import { DashLine } from '../vendor/pixi-dashed-line';
5
- import { LayerOptions, PixiLayer, PixiRenderApplication } from '.';
6
- import { DEFAULT_TEXTURE_SIZE, EXAGGERATED_DIAMETER, HOLE_OUTLINE, SCREEN_OUTLINE } from '../constants';
7
- import {
8
- assertNever,
9
- Casing,
10
- CasingOptions,
11
- Cement,
12
- CementOptions,
13
- CementPlugOptions,
14
- CementSqueeze,
15
- CementSqueezeOptions,
16
- foldCompletion,
17
- HoleOptions,
18
- HoleSize,
19
- isCementSqueeze,
20
- PAndA,
21
- SchematicData,
22
- ScreenOptions,
23
- TubingOptions,
24
- Screen,
25
- Tubing,
26
- CompletionSymbol,
27
- isPAndASymbol,
28
- isCementPlug,
29
- CementPlug,
30
- PAndASymbol,
31
- InternalLayerOptions,
32
- defaultHoleOptions,
33
- defaultCasingOptions,
34
- defaultCementOptions,
35
- defaultCementSqueezeOptions,
36
- defaultCementPlugOptions,
37
- defaultScreenOptions,
38
- defaultTubingOptions,
39
- defaultInternalLayerOptions,
40
- Perforation,
41
- PerforationOptions,
42
- defaultPerforationOptions,
43
- Completion,
44
- OutlineClosure,
45
- hasPacking,
46
- hasFracLines,
47
- hasSpikes,
48
- } from './schematicInterfaces';
49
- import {
50
- CasingRenderObject,
51
- createCementTexture,
52
- createComplexRopeSegmentsForCement,
53
- createComplexRopeSegmentsForCementSqueeze,
54
- createComplexRopeSegmentsForCementPlug,
55
- createHoleBaseTexture,
56
- createScreenTexture,
57
- createTubingTexture,
58
- createTubularRenderingObject,
59
- prepareCasingRenderObject,
60
- createCementPlugTexture,
61
- createComplexRopeSegmentsForPerforation,
62
- createPerforationPackingTexture,
63
- PerforationShape,
64
- createCementSqueezeTexture,
65
- createPerforationFracLineTexture,
66
- createPerforationSpikeTexture,
67
- } from '../datautils/schematicShapeGenerator';
68
- import { OnUpdateEvent, OnRescaleEvent, OnUnmountEvent } from '../interfaces';
69
- import { convertColor } from '../utils/color';
70
- import { createNormals, offsetPoint, offsetPoints } from '../utils/vectorUtils';
71
- import { ComplexRope, ComplexRopeSegment } from './CustomDisplayObjects/ComplexRope';
72
- import { FixedWidthSimpleRope } from './CustomDisplayObjects/FixedWidthSimpleRope';
73
- import { UniformTextureStretchRope } from './CustomDisplayObjects/UniformTextureStretchRope';
74
-
75
- interface ScalingFactors {
76
- height: number;
77
- zFactor: number;
78
- yScale: ScaleLinear<number, number, never>;
79
- }
80
-
81
- interface SymbolRenderObject {
82
- pathPoints: Point[];
83
- referenceDiameter: number;
84
- symbolKey: string;
85
- }
86
-
87
- interface CementRenderObject {
88
- kind: 'cement';
89
- segments: ComplexRopeSegment[];
90
- casingIds: string[];
91
- zIndex?: number;
92
- }
93
-
94
- interface CementSqueezeRenderObject {
95
- kind: 'cementSqueeze';
96
- segments: ComplexRopeSegment[];
97
- casingIds: string[];
98
- zIndex?: number;
99
- }
100
-
101
- type InterlacedRenderObjects = CasingRenderObject | CementRenderObject | CementSqueezeRenderObject;
102
-
103
- const foldInterlacedRenderObjects =
104
- <T>(fCasing: (obj: CasingRenderObject) => T, fCement: (obj: CementRenderObject) => T, fCementSqueeze: (obj: CementSqueezeRenderObject) => T) =>
105
- (renderObject: InterlacedRenderObjects): T => {
106
- switch (renderObject.kind) {
107
- case 'casing':
108
- return fCasing(renderObject);
109
- case 'cement':
110
- return fCement(renderObject);
111
- case 'cementSqueeze':
112
- return fCementSqueeze(renderObject);
113
- default:
114
- return assertNever(renderObject);
115
- }
116
- };
117
-
118
- export interface SchematicLayerOptions<T extends SchematicData> extends LayerOptions<T> {
119
- exaggerationFactor?: number;
120
- internalLayerOptions?: InternalLayerOptions;
121
- holeOptions?: HoleOptions;
122
- casingOptions?: CasingOptions;
123
- cementOptions?: CementOptions;
124
- cementSqueezeOptions?: CementSqueezeOptions;
125
- screenOptions?: ScreenOptions;
126
- tubingOptions?: TubingOptions;
127
- cementPlugOptions?: CementPlugOptions;
128
- perforationOptions?: PerforationOptions;
129
- }
130
-
131
- const defaultSchematicLayerOptions = (layerId: string): SchematicLayerOptions<SchematicData> => ({
132
- exaggerationFactor: 2,
133
- internalLayerOptions: defaultInternalLayerOptions(layerId),
134
- holeOptions: defaultHoleOptions,
135
- casingOptions: defaultCasingOptions,
136
- cementOptions: defaultCementOptions,
137
- cementSqueezeOptions: defaultCementSqueezeOptions,
138
- screenOptions: defaultScreenOptions,
139
- tubingOptions: defaultTubingOptions,
140
- cementPlugOptions: defaultCementPlugOptions,
141
- perforationOptions: defaultPerforationOptions,
142
- });
143
-
144
- type InternalLayerVisibility = { [K in keyof InternalLayerOptions]: boolean };
145
-
146
- export class SchematicLayer<T extends SchematicData> extends PixiLayer<T> {
147
- private internalLayerVisibility: InternalLayerVisibility = {
148
- holeLayerId: true,
149
- casingLayerId: true,
150
- completionLayerId: true,
151
- cementLayerId: true,
152
- pAndALayerId: true,
153
- perforationLayerId: true,
154
- };
155
-
156
- private cementTextureCache: Texture;
157
- private cementSqueezeTextureCache: Texture;
158
- private cementPlugTextureCache: Texture;
159
- private holeTextureCache: Texture;
160
- private screenTextureCache: Texture;
161
- private tubingTextureCache: Texture;
162
- private textureSymbolCacheArray: { [key: string]: Texture };
163
-
164
- protected scalingFactors: ScalingFactors = {
165
- height: 600,
166
- zFactor: 1,
167
- yScale: scaleLinear(),
168
- };
169
-
170
- constructor(ctx: PixiRenderApplication, id?: string, options?: SchematicLayerOptions<T>) {
171
- super(ctx, id, options);
172
- this.options = <SchematicLayerOptions<T>>{
173
- ...this.options,
174
- ...defaultSchematicLayerOptions(this.id),
175
- ...options,
176
- };
177
- }
178
-
179
- public onUnmount(event?: OnUnmountEvent): void {
180
- super.onUnmount(event);
181
- this.scalingFactors = null;
182
- this.cementTextureCache = null;
183
- this.cementSqueezeTextureCache = null;
184
- this.holeTextureCache = null;
185
- this.screenTextureCache = null;
186
- this.tubingTextureCache = null;
187
- this.textureSymbolCacheArray = null;
188
- this.internalLayerVisibility = null;
189
- }
190
-
191
- public onUpdate(event: OnUpdateEvent<T>): void {
192
- super.onUpdate(event);
193
- this.clearLayer();
194
- this.preRender();
195
- this.render();
196
- }
197
-
198
- public override onRescale(event: OnRescaleEvent): void {
199
- const shouldRecalculate = this.scalingFactors.zFactor !== event.zFactor;
200
-
201
- this.scalingFactors = { height: event.height, zFactor: event.zFactor, yScale: event.yScale };
202
- super.optionsRescale(event);
203
- const yRatio = this.yRatio();
204
- const flippedX = event.xBounds[0] > event.xBounds[1];
205
- const flippedY = event.yBounds[0] > event.yBounds[1];
206
- this.setContainerPosition(event.xScale(0), event.yScale(0));
207
- this.setContainerScale(event.xRatio * (flippedX ? -1 : 1), yRatio * (flippedY ? -1 : 1));
208
- if (shouldRecalculate) {
209
- this.clearLayer();
210
- this.preRender();
211
- }
212
-
213
- this.render();
214
- }
215
-
216
- public override setVisibility(isVisible: boolean, layerId: string) {
217
- if (layerId === this.id) {
218
- super.setVisibility(isVisible, layerId);
219
- return;
220
- }
221
-
222
- const { internalLayerOptions } = this.options as SchematicLayerOptions<T>;
223
-
224
- const [keyFound] = Object.entries(internalLayerOptions).find(([_key, id]: [string, string]) => id === layerId);
225
- if (keyFound) {
226
- this.internalLayerVisibility[keyFound as keyof InternalLayerVisibility] = isVisible;
227
- this.clearLayer();
228
- this.preRender();
229
- this.render();
230
- }
231
- }
232
-
233
- public override getInternalLayerIds(): string[] {
234
- const { internalLayerOptions } = this.options as SchematicLayerOptions<T>;
235
- return Object.values(internalLayerOptions);
236
- }
237
-
238
- /**
239
- * Calculate yRatio without zFactor
240
- * TODO consider to move this into ZoomPanHandler
241
- */
242
- protected yRatio(): number {
243
- const domain = this.scalingFactors.yScale.domain();
244
- const ySpan = domain[1] - domain[0];
245
- const baseYSpan = ySpan * this.scalingFactors.zFactor;
246
- const baseDomain = [domain[0], domain[0] + baseYSpan];
247
- return Math.abs(this.scalingFactors.height / (baseDomain[1] - baseDomain[0]));
248
- }
249
-
250
- protected getZFactorScaledPathForPoints = (start: number, end: number): Point[] => {
251
- const y = (y: number): number => y * this.scalingFactors.zFactor;
252
-
253
- const path = this.referenceSystem.getCurtainPath(start, end, true);
254
- return path.map((p) => new Point(p.point[0], y(p.point[1])));
255
- };
256
-
257
- protected drawBigPolygon = (coords: IPoint[], color = 0x000000) => {
258
- const polygon = new Graphics();
259
- polygon.beginFill(color);
260
- polygon.drawPolygon(coords);
261
- polygon.endFill();
262
-
263
- this.addChild(polygon);
264
- };
265
-
266
- protected drawRope(path: Point[], texture: Texture, tint?: number): void {
267
- if (path.length === 0) {
268
- return null;
269
- }
270
-
271
- const rope: SimpleRope = new SimpleRope(texture, path, 1);
272
-
273
- rope.tint = tint || rope.tint;
274
-
275
- this.addChild(rope);
276
- }
277
-
278
- /**
279
- *
280
- * @param leftPath Points for line on left side
281
- * @param rightPath Points for line on right side
282
- * @param lineColor Color of line
283
- * @param lineWidth Width of line
284
- * @param outlineClosure If line should be drawn at top and/or bottom of the paths
285
- * @param lineAlignment alignment of the line to draw, (0 = inner, 0.5 = middle, 1 = outer).
286
- */
287
- protected drawOutline(
288
- leftPath: Point[],
289
- rightPath: Point[],
290
- lineColor: number,
291
- lineWidth = 1,
292
- outlineClosure: OutlineClosure = 'None',
293
- lineAlignment = 1,
294
- ): void {
295
- const leftPathReverse = leftPath.map<Point>((d) => d.clone()).reverse();
296
-
297
- const startPointRight = rightPath[0];
298
- const startPointLeft = leftPathReverse[0];
299
-
300
- const line = new Graphics();
301
- line.lineStyle(lineWidth, lineColor, undefined, lineAlignment);
302
- line.moveTo(startPointRight.x, startPointRight.y);
303
- rightPath.forEach((p: Point) => line.lineTo(p.x, p.y));
304
-
305
- if (outlineClosure === 'None' || outlineClosure === 'Top') {
306
- line.moveTo(startPointLeft.x, startPointLeft.y);
307
- }
308
-
309
- leftPathReverse.forEach((p: Point) => line.lineTo(p.x, p.y));
310
-
311
- if (outlineClosure === 'TopAndBottom' || outlineClosure === 'Top') {
312
- line.lineTo(startPointRight.x, startPointRight.y);
313
- }
314
-
315
- this.addChild(line);
316
- }
317
-
318
- /**
319
- * Uses a dashed outline on one side to represent casing window
320
- * The casing window should be visualized at the upper side of the wellbore path
321
- * @param leftPath Points for line on left side
322
- * @param pointPath Points for line on right side
323
- * @param lineColor Color of line
324
- * @param lineWidth Width of line
325
- * @param lineAlignment alignment of the line to draw, (0 = inner, 0.5 = middle, 1 = outer).
326
- */
327
- protected drawCasingWindowOutline(leftPath: Point[], rightPath: Point[], { lineColor, windowOptions }: CasingOptions, lineWidth = 1): void {
328
- // Correct the dashed path. Should always be displayed on the upper side of the wellbore path.
329
- const flippedPaths = !!this.referenceSystem?.options?.calculateDisplacementFromBottom;
330
- const [linePath, dashedPath] = flippedPaths ? [leftPath, rightPath] : [rightPath, leftPath];
331
- const [dashedAlignment, solidAlignment] = flippedPaths ? [1, 0] : [0, 1];
332
-
333
- const graphics = new Graphics();
334
- graphics.lineStyle(lineWidth, convertColor(lineColor), undefined, solidAlignment);
335
-
336
- const startPointLinePath = linePath[0];
337
- graphics.moveTo(startPointLinePath.x, startPointLinePath.y);
338
- linePath.forEach((p: Point) => graphics.lineTo(p.x, p.y));
339
-
340
- const dashedLine = new DashLine(graphics, {
341
- dash: [windowOptions.dashLength, windowOptions.spaceLength],
342
- color: convertColor(windowOptions.dashColor),
343
- width: lineWidth,
344
- alignment: dashedAlignment,
345
- });
346
-
347
- const startPointDashedPath = dashedPath[0];
348
- dashedLine.moveTo(startPointDashedPath.x, startPointDashedPath.y);
349
- dashedPath.forEach((currentPoint: Point) => {
350
- dashedLine.lineTo(currentPoint.x, currentPoint.y);
351
- });
352
-
353
- this.addChild(graphics);
354
- }
355
-
356
- private perforationRopeAndTextureReferences: { rope: ComplexRope; texture: Texture }[] = [];
357
-
358
- public preRender(): void {
359
- if (!this.data || !this.referenceSystem) {
360
- return;
361
- }
362
-
363
- const { exaggerationFactor } = this.options as SchematicLayerOptions<T>;
364
- const { holeSizes, casings, cements, completion, symbols, pAndA, perforations } = this.data;
365
-
366
- this.updateSymbolCache(symbols);
367
-
368
- holeSizes.sort((a: HoleSize, b: HoleSize) => b.diameter - a.diameter);
369
- const maxHoleDiameter = holeSizes.length > 0 ? max(holeSizes, (d) => d.diameter) * exaggerationFactor : EXAGGERATED_DIAMETER * exaggerationFactor;
370
- if (this.internalLayerVisibility.holeLayerId) {
371
- holeSizes.forEach((hole: HoleSize) => this.drawHoleSize(maxHoleDiameter, hole));
372
- }
373
-
374
- casings.sort((a: Casing, b: Casing) => b.diameter - a.diameter);
375
- const casingRenderObjects: CasingRenderObject[] = casings.map((casing: Casing) => this.createCasingRenderObject(casing));
376
-
377
- const cementShapes: CementRenderObject[] = cements.map(
378
- (cement: Cement): CementRenderObject => ({
379
- kind: 'cement',
380
- segments: createComplexRopeSegmentsForCement(cement, casings, completion, holeSizes, exaggerationFactor, this.getZFactorScaledPathForPoints),
381
- casingIds: (cement.referenceIds || []).filter((id) => id),
382
- }),
383
- );
384
-
385
- const [cementSqueezes, remainingPAndA] = pAndA.reduce<[CementSqueeze[], Exclude<PAndA, CementSqueeze>[]]>(
386
- ([squeezes, remaining], current: PAndA) =>
387
- isCementSqueeze(current) ? [[current, ...squeezes], remaining] : [squeezes, [current, ...remaining]],
388
- [[], []],
389
- );
390
-
391
- const cementSqueezesShape: CementSqueezeRenderObject[] = cementSqueezes.map((squeeze) => ({
392
- kind: 'cementSqueeze',
393
- segments: this.createCementSqueezeShape(squeeze, casings, completion, holeSizes),
394
- casingIds: squeeze.referenceIds,
395
- }));
396
-
397
- this.sortCementAndCasingRenderObjects(casingRenderObjects, cementShapes, cementSqueezesShape).forEach(
398
- foldInterlacedRenderObjects(
399
- (casingRO: CasingRenderObject) => {
400
- if (this.internalLayerVisibility.casingLayerId) {
401
- this.drawCasing(casingRO);
402
-
403
- if (casingRO.hasShoe) {
404
- this.drawShoe(casingRO.bottom, casingRO.referenceRadius);
405
- }
406
- }
407
- },
408
- (cementRO: CementRenderObject) => {
409
- if (this.internalLayerVisibility.cementLayerId) {
410
- this.drawComplexRope(cementRO.segments, this.getCementTexture());
411
- }
412
- },
413
- (cementSqueezesRO: CementSqueezeRenderObject) => {
414
- if (this.internalLayerVisibility.pAndALayerId) {
415
- this.drawComplexRope(cementSqueezesRO.segments, this.getCementSqueezeTexture());
416
- }
417
- },
418
- ),
419
- );
420
-
421
- this.perforationRopeAndTextureReferences.forEach(({ rope, texture }) => {
422
- rope.destroy({
423
- children: true,
424
- texture: true,
425
- baseTexture: true,
426
- });
427
- texture.destroy(true);
428
- });
429
- this.perforationRopeAndTextureReferences = [];
430
-
431
- if (this.internalLayerVisibility.perforationLayerId) {
432
- const { perforationOptions } = this.options as SchematicLayerOptions<T>;
433
- const packings = perforations.filter(hasPacking);
434
- const fracLines = perforations.filter(hasFracLines);
435
- const spikes = perforations.filter(hasSpikes);
436
- packings.forEach((perforation) => {
437
- const perfShapes = this.createPerforationShape(perforation, casings, holeSizes);
438
- const perfShapesByDiameter: { [key: number]: ComplexRopeSegment[] } = perfShapes.reduce(
439
- (dict: { [key: number]: ComplexRopeSegment[] }, ps) => {
440
- if (!dict[ps.diameter]) {
441
- dict[ps.diameter] = [];
442
- }
443
- dict[ps.diameter] = [...dict[ps.diameter], ps];
444
- return dict;
445
- },
446
- {},
447
- );
448
- Object.values(perfShapesByDiameter).forEach((perfShapesWithSameDiameter) => {
449
- const texture = createPerforationPackingTexture(perforation, perfShapesWithSameDiameter[0], perforationOptions);
450
- const rope = this.drawComplexRope(perfShapesWithSameDiameter, texture);
451
- this.perforationRopeAndTextureReferences.push({ rope, texture });
452
- });
453
- });
454
-
455
- fracLines.forEach((perforation) => {
456
- const perfShapes = this.createPerforationShape(perforation, casings, holeSizes);
457
- const thiccPerfShapes = perfShapes.map((ps) => ({ ...ps, diameter: ps.diameter * 3 }));
458
- const perfShapesByDiameter: { [key: number]: ComplexRopeSegment[] } = thiccPerfShapes.reduce(
459
- (dict: { [key: number]: ComplexRopeSegment[] }, ps) => {
460
- if (!dict[ps.diameter]) {
461
- dict[ps.diameter] = [];
462
- }
463
- dict[ps.diameter] = [...dict[ps.diameter], ps];
464
- return dict;
465
- },
466
- {},
467
- );
468
- Object.values(perfShapesByDiameter).forEach((perfShapesWithSameDiameter) => {
469
- perfShapesWithSameDiameter.forEach((perfShape) => {
470
- const texture = createPerforationFracLineTexture(perforation, perfShape, perforationOptions);
471
- const rope = this.drawComplexRope([perfShape], texture);
472
- this.perforationRopeAndTextureReferences.push({ rope, texture });
473
- });
474
- });
475
- });
476
- spikes.forEach((perforation) => {
477
- const perfShapes = this.createPerforationShape(perforation, casings, holeSizes);
478
- const thiccPerfShapes = perfShapes.map((ps) => ({ ...ps, diameter: ps.diameter * 3 }));
479
- const perfShapesByDiameter: { [key: number]: ComplexRopeSegment[] } = thiccPerfShapes.reduce(
480
- (dict: { [key: number]: ComplexRopeSegment[] }, ps) => {
481
- if (!dict[ps.diameter]) {
482
- dict[ps.diameter] = [];
483
- }
484
- dict[ps.diameter] = [...dict[ps.diameter], ps];
485
- return dict;
486
- },
487
- {},
488
- );
489
- Object.values(perfShapesByDiameter).forEach((perfShapesWithSameDiameter) => {
490
- perfShapesWithSameDiameter.forEach((perfShape) => {
491
- const texture = createPerforationSpikeTexture(perforation, perforations, perfShape, perforationOptions);
492
- const rope = this.drawComplexRope([perfShape], texture);
493
- this.perforationRopeAndTextureReferences.push({ rope, texture });
494
- });
495
- });
496
- });
497
- }
498
-
499
- if (this.internalLayerVisibility.completionLayerId) {
500
- completion.forEach(
501
- foldCompletion(
502
- (obj: Screen) => this.drawScreen(obj),
503
- (obj: Tubing) => this.drawTubing(obj),
504
- (obj: CompletionSymbol) => {
505
- const symbolRenderObject = this.prepareSymbolRenderObject(obj);
506
- this.drawSymbolComponent(symbolRenderObject);
507
- },
508
- ),
509
- );
510
- }
511
-
512
- if (this.internalLayerVisibility.pAndALayerId) {
513
- remainingPAndA.forEach((obj) => {
514
- if (isPAndASymbol(obj)) {
515
- const symbolRenderObject = this.prepareSymbolRenderObject(obj);
516
- this.drawSymbolComponent(symbolRenderObject);
517
- }
518
- if (isCementPlug(obj)) {
519
- this.drawCementPlug(obj, casings, completion, holeSizes);
520
- }
521
- });
522
- }
523
- }
524
-
525
- private updateSymbolCache(symbols: { [key: string]: string }) {
526
- if (!this.textureSymbolCacheArray) {
527
- this.textureSymbolCacheArray = {};
528
- }
529
- if (!symbols) {
530
- return;
531
- }
532
-
533
- const existingKeys = Object.keys(this.textureSymbolCacheArray);
534
- Object.entries(symbols).forEach(([key, symbol]: [string, string]) => {
535
- if (!existingKeys.includes(key)) {
536
- this.textureSymbolCacheArray[key] = Texture.from(symbol);
537
- }
538
- });
539
- }
540
-
541
- private drawCementPlug(cementPlug: CementPlug, casings: Casing[], completion: Completion[], holes: HoleSize[]) {
542
- const { exaggerationFactor, cementPlugOptions } = this.options as SchematicLayerOptions<T>;
543
-
544
- const cementPlugSegments = createComplexRopeSegmentsForCementPlug(
545
- cementPlug,
546
- casings,
547
- completion,
548
- holes,
549
- exaggerationFactor,
550
- this.getZFactorScaledPathForPoints,
551
- );
552
- this.drawComplexRope(cementPlugSegments, this.getCementPlugTexture(cementPlugOptions));
553
-
554
- const { rightPath, leftPath } = cementPlugSegments.reduce<{ rightPath: Point[]; leftPath: Point[] }>(
555
- (acc, current) => {
556
- const { leftPath, rightPath } = createTubularRenderingObject(current.diameter / 2, current.points);
557
-
558
- return {
559
- rightPath: [...acc.rightPath, ...rightPath],
560
- leftPath: [...acc.leftPath, ...leftPath],
561
- };
562
- },
563
- { rightPath: [], leftPath: [] },
564
- );
565
- // eslint-disable-next-line no-magic-numbers
566
- this.drawOutline(leftPath, rightPath, convertColor('black'), 0.25, 'TopAndBottom');
567
- }
568
-
569
- private createCasingRenderObject(casing: Casing): CasingRenderObject {
570
- const { exaggerationFactor } = this.options as SchematicLayerOptions<T>;
571
- return prepareCasingRenderObject(exaggerationFactor, casing, this.getZFactorScaledPathForPoints);
572
- }
573
-
574
- private getCementPlugTexture(cementPlugOptions: CementPlugOptions): Texture {
575
- if (!this.cementPlugTextureCache) {
576
- this.cementPlugTextureCache = createCementPlugTexture(cementPlugOptions);
577
- }
578
- return this.cementPlugTextureCache;
579
- }
580
-
581
- private prepareSymbolRenderObject = (component: CompletionSymbol | PAndASymbol): SymbolRenderObject => {
582
- const { exaggerationFactor } = this.options as SchematicLayerOptions<T>;
583
-
584
- const exaggeratedDiameter = component.diameter * exaggerationFactor;
585
-
586
- const pathPoints = this.getZFactorScaledPathForPoints(component.start, component.end);
587
-
588
- return {
589
- pathPoints,
590
- referenceDiameter: exaggeratedDiameter,
591
- symbolKey: component.symbolKey,
592
- };
593
- };
594
-
595
- private drawSymbolComponent = ({ pathPoints, referenceDiameter, symbolKey }: SymbolRenderObject): void => {
596
- const texture = this.getSymbolTexture(symbolKey, referenceDiameter);
597
- // The rope renders fine in CANVAS/fallback mode
598
- this.drawSVGRope(pathPoints, texture);
599
- };
600
-
601
- private drawSVGRope(path: Point[], texture: Texture): void {
602
- if (path.length === 0) {
603
- return null;
604
- }
605
-
606
- const rope: UniformTextureStretchRope = new UniformTextureStretchRope(texture, path);
607
-
608
- this.addChild(rope);
609
- }
610
-
611
- private getSymbolTexture(symbolKey: string, diameter: number): Texture {
612
- return new Texture(this.textureSymbolCacheArray[symbolKey].baseTexture, null, new Rectangle(0, 0, 0, diameter), null, groupD8.MAIN_DIAGONAL);
613
- }
614
-
615
- private drawHoleSize = (maxHoleDiameter: number, holeObject: HoleSize): void => {
616
- if (holeObject == null) {
617
- return;
618
- }
619
-
620
- const pathPoints = this.getZFactorScaledPathForPoints(holeObject.start, holeObject.end);
621
- if (pathPoints.length === 0) {
622
- return;
623
- }
624
-
625
- const { exaggerationFactor, holeOptions } = this.options as SchematicLayerOptions<T>;
626
- const exaggeratedDiameter = holeObject.diameter * exaggerationFactor;
627
- const { rightPath, leftPath } = createTubularRenderingObject(exaggeratedDiameter / 2, pathPoints);
628
- const texture = this.getHoleTexture(holeOptions, exaggeratedDiameter, maxHoleDiameter);
629
-
630
- this.drawHoleRope(pathPoints, texture, maxHoleDiameter);
631
-
632
- this.drawOutline(leftPath, rightPath, convertColor(holeOptions.lineColor), HOLE_OUTLINE * exaggerationFactor, 'TopAndBottom', 0);
633
- };
634
-
635
- private drawHoleRope(path: Point[], texture: Texture, maxHoleDiameter: number): void {
636
- if (path.length === 0) {
637
- return null;
638
- }
639
-
640
- const rope: SimpleRope = new SimpleRope(texture, path, maxHoleDiameter / DEFAULT_TEXTURE_SIZE);
641
-
642
- this.addChild(rope);
643
- }
644
-
645
- private getHoleTexture(holeOptions: HoleOptions, diameter: number, maxHoleDiameter: number): Texture {
646
- const size = DEFAULT_TEXTURE_SIZE;
647
- const height = size;
648
- const width = size;
649
-
650
- const textureDiameter = (diameter / maxHoleDiameter) * size;
651
-
652
- if (!this.holeTextureCache) {
653
- this.holeTextureCache = createHoleBaseTexture(holeOptions, width, height);
654
- }
655
-
656
- const baseTexture = this.holeTextureCache.baseTexture;
657
- const sidePadding = (height - textureDiameter) / 2;
658
- const frame = new Rectangle(0, sidePadding, width, textureDiameter);
659
- const texture = new Texture(baseTexture, frame);
660
-
661
- return texture;
662
- }
663
-
664
- /**
665
- * The rendering order of these components needs to be aligned
666
- * @param casingRenderObjects
667
- * @param cementRenderObject
668
- * @param cementSqueezes
669
- * @returns ordered rendering list
670
- */
671
- private sortCementAndCasingRenderObjects(
672
- casingRenderObjects: CasingRenderObject[],
673
- cementRenderObject: CementRenderObject[],
674
- cementSqueezes: CementSqueezeRenderObject[],
675
- ): InterlacedRenderObjects[] {
676
- type InterlaceReducerAcc = {
677
- result: InterlacedRenderObjects[];
678
- remainingCement: CementRenderObject[];
679
- remainingCementSqueezes: CementSqueezeRenderObject[];
680
- };
681
-
682
- let zIndex = 0;
683
-
684
- const { result } = casingRenderObjects.reduce(
685
- (acc: InterlaceReducerAcc, casingRenderObject: CasingRenderObject): InterlaceReducerAcc => {
686
- const foundCementShape = acc.remainingCement.find((cement) => cement.casingIds.includes(casingRenderObject.id));
687
- const foundCementSqueezes = acc.remainingCementSqueezes.filter((squeeze) => squeeze.casingIds.includes(casingRenderObject.id));
688
-
689
- if (foundCementShape) {
690
- foundCementShape.zIndex = zIndex++;
691
- }
692
- foundCementSqueezes.forEach((item) => (item.zIndex = zIndex++));
693
- casingRenderObject.zIndex = zIndex++;
694
-
695
- return {
696
- result: [...acc.result, foundCementShape, casingRenderObject, ...foundCementSqueezes],
697
- remainingCement: acc.remainingCement.filter((c) => c !== foundCementShape),
698
- remainingCementSqueezes: acc.remainingCementSqueezes.filter((squeeze) => !foundCementSqueezes.includes(squeeze)),
699
- };
700
- },
701
- { result: [], remainingCement: cementRenderObject, remainingCementSqueezes: cementSqueezes },
702
- );
703
-
704
- return result.filter((item) => item !== undefined).sort((a, b) => a.zIndex - b.zIndex);
705
- }
706
-
707
- /**
708
- *
709
- * @param intervals
710
- * @param texture
711
- * optionally fetch the exaggerationFactor from a different options prop
712
- * options.perforationOptions for example
713
- * @param getExaggerationFactor
714
- * @returns
715
- */
716
- private drawComplexRope(intervals: ComplexRopeSegment[], texture: Texture): ComplexRope {
717
- if (intervals.length === 0) {
718
- return null;
719
- }
720
- const { exaggerationFactor } = this.options as SchematicLayerOptions<T>;
721
-
722
- const rope = new ComplexRope(texture, intervals, exaggerationFactor);
723
-
724
- this.addChild(rope);
725
-
726
- return rope;
727
- }
728
-
729
- private static getOutlineClosureType = (index: number, maxIndex: number): OutlineClosure => {
730
- if (index === 0) {
731
- if (index === maxIndex) {
732
- return 'TopAndBottom';
733
- }
734
- return 'Top';
735
- }
736
- if (index === maxIndex) {
737
- return 'Bottom';
738
- }
739
-
740
- return 'None';
741
- };
742
-
743
- private drawCasing = (casingRenderObject: CasingRenderObject): void => {
744
- const { casingOptions } = this.options as SchematicLayerOptions<T>;
745
- const casingSolidColorNumber = convertColor(casingOptions.solidColor);
746
- const casingLineColorNumber = convertColor(casingOptions.lineColor);
747
-
748
- casingRenderObject.sections.forEach((section, index, list) => {
749
- const outlineClosureType = SchematicLayer.getOutlineClosureType(index, list.length - 1);
750
-
751
- const texture = this.createCasingTexture(casingRenderObject.referenceDiameter);
752
- this.drawRope(section.pathPoints, texture, casingSolidColorNumber);
753
-
754
- if (section.kind === 'casing-window') {
755
- this.drawCasingWindowOutline(section.leftPath, section.rightPath, casingOptions, casingRenderObject.casingWallWidth);
756
- } else {
757
- this.drawOutline(section.leftPath, section.rightPath, casingLineColorNumber, casingRenderObject.casingWallWidth, outlineClosureType);
758
- }
759
- });
760
- };
761
-
762
- private createCasingTexture(diameter: number): Texture {
763
- const textureWidthPO2 = 16;
764
- return new Texture(Texture.WHITE.baseTexture, null, new Rectangle(0, 0, textureWidthPO2, diameter));
765
- }
766
-
767
- private drawShoe(casingEnd: number, casingRadius: number): void {
768
- const { exaggerationFactor, casingOptions } = this.options as SchematicLayerOptions<T>;
769
- const shoeWidth = casingOptions.shoeSize.width * exaggerationFactor;
770
- const shoeLength = casingOptions.shoeSize.length * exaggerationFactor;
771
-
772
- const shoeCoords = this.generateShoe(casingEnd, casingRadius, shoeLength, shoeWidth);
773
- const shoeCoords2 = this.generateShoe(casingEnd, casingRadius, shoeLength, -shoeWidth);
774
- this.drawBigPolygon(shoeCoords2);
775
- this.drawBigPolygon(shoeCoords);
776
- }
777
-
778
- private generateShoe = (casingEnd: number, casingRadius: number, length: number, width: number): Point[] => {
779
- const start = casingEnd - length;
780
- const end = casingEnd;
781
-
782
- const points = this.getZFactorScaledPathForPoints(start, end);
783
-
784
- const normal = createNormals(points);
785
- const shoeEdge: Point[] = offsetPoints(points, normal, casingRadius * (width < 0 ? -1 : 1));
786
-
787
- const shoeTipPoint = points[points.length - 1];
788
- const shoeTipNormal = normal[normal.length - 1];
789
- const shoeTip: Point = offsetPoint(shoeTipPoint, shoeTipNormal, width + casingRadius * (width < 0 ? -1 : 1));
790
-
791
- return [...shoeEdge, shoeTip];
792
- };
793
-
794
- private createCementSqueezeShape = (
795
- squeeze: CementSqueeze,
796
- casings: Casing[],
797
- completion: Completion[],
798
- holes: HoleSize[],
799
- ): ComplexRopeSegment[] => {
800
- const { exaggerationFactor } = this.options as SchematicLayerOptions<T>;
801
- return createComplexRopeSegmentsForCementSqueeze(squeeze, casings, completion, holes, exaggerationFactor, this.getZFactorScaledPathForPoints);
802
- };
803
-
804
- private getCementTexture(): Texture {
805
- if (!this.cementTextureCache) {
806
- const { cementOptions } = this.options as SchematicLayerOptions<T>;
807
- this.cementTextureCache = createCementTexture(cementOptions);
808
- }
809
- return this.cementTextureCache;
810
- }
811
-
812
- private createPerforationShape = (perforation: Perforation, casings: Casing[], holes: HoleSize[]): PerforationShape[] => {
813
- const { exaggerationFactor } = this.options as SchematicLayerOptions<T>;
814
- return createComplexRopeSegmentsForPerforation(perforation, casings, holes, exaggerationFactor, this.getZFactorScaledPathForPoints);
815
- };
816
-
817
- private getCementSqueezeTexture(): Texture {
818
- if (!this.cementSqueezeTextureCache) {
819
- const { cementSqueezeOptions } = this.options as SchematicLayerOptions<T>;
820
- this.cementSqueezeTextureCache = createCementSqueezeTexture(cementSqueezeOptions);
821
- }
822
- return this.cementSqueezeTextureCache;
823
- }
824
-
825
- private drawScreen({ start, end, diameter }: Screen): void {
826
- const { exaggerationFactor, screenOptions } = this.options as SchematicLayerOptions<T>;
827
- const exaggeratedDiameter = exaggerationFactor * diameter;
828
-
829
- const pathPoints = this.getZFactorScaledPathForPoints(start, end);
830
- const { leftPath, rightPath } = createTubularRenderingObject(exaggeratedDiameter / 2, pathPoints);
831
-
832
- const texture = this.getScreenTexture();
833
-
834
- this.drawCompletionRope(pathPoints, texture, exaggeratedDiameter);
835
- this.drawOutline(leftPath, rightPath, convertColor(screenOptions.lineColor), SCREEN_OUTLINE * exaggerationFactor, 'TopAndBottom');
836
- }
837
-
838
- private drawTubing({ diameter, start, end }: Tubing): void {
839
- const { exaggerationFactor, tubingOptions } = this.options as SchematicLayerOptions<T>;
840
- const exaggeratedDiameter = exaggerationFactor * diameter;
841
-
842
- const pathPoints = this.getZFactorScaledPathForPoints(start, end);
843
- const texture = this.getTubingTexture(tubingOptions);
844
-
845
- this.drawCompletionRope(pathPoints, texture, exaggeratedDiameter);
846
- }
847
-
848
- private getTubingTexture(tubingOptions: TubingOptions): Texture {
849
- if (!this.tubingTextureCache) {
850
- this.tubingTextureCache = createTubingTexture(tubingOptions);
851
- }
852
- return this.tubingTextureCache;
853
- }
854
-
855
- private getScreenTexture(): Texture {
856
- if (!this.screenTextureCache) {
857
- const { screenOptions } = this.options as SchematicLayerOptions<T>;
858
- this.screenTextureCache = createScreenTexture(screenOptions);
859
- }
860
- return this.screenTextureCache;
861
- }
862
-
863
- private drawCompletionRope(path: Point[], texture: Texture, diameter: number): void {
864
- if (path.length === 0) {
865
- return;
866
- }
867
-
868
- const rope: FixedWidthSimpleRope = new FixedWidthSimpleRope(texture, path, diameter);
869
- this.addChild(rope);
870
- }
871
- }