@configura/babylon-view 1.3.0-alpha.2 → 1.3.0-alpha.7

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 (47) hide show
  1. package/dist/animation/coordinator/CoordinatorDropAndSpin.js +1 -1
  2. package/dist/animation/coordinator/CoordinatorPulseBounce.js +1 -1
  3. package/dist/animation/coordinator/CoordinatorPulseHighlight.js +1 -1
  4. package/dist/animation/coordinator/CoordinatorPulseInflate.js +1 -1
  5. package/dist/camera/CfgArcRotateCameraPointersInput.d.ts +16 -0
  6. package/dist/camera/CfgArcRotateCameraPointersInput.js +17 -15
  7. package/dist/geometry/CfgGeometry.d.ts +22 -5
  8. package/dist/geometry/CfgGeometry.js +131 -102
  9. package/dist/geometry/CfgMesh.d.ts +4 -1
  10. package/dist/geometry/CfgMesh.js +32 -2
  11. package/dist/geometry/stretch/CfgMorphTarget.d.ts +16 -0
  12. package/dist/geometry/stretch/CfgMorphTarget.js +65 -0
  13. package/dist/geometry/stretch/CfgStretchData.d.ts +115 -0
  14. package/dist/geometry/stretch/CfgStretchData.js +340 -0
  15. package/dist/geometry/stretch/CfgStretchMorphGeometry.d.ts +17 -0
  16. package/dist/geometry/stretch/CfgStretchMorphGeometry.js +95 -0
  17. package/dist/material/CfgMaterial.d.ts +19 -4
  18. package/dist/material/CfgMaterial.js +38 -30
  19. package/dist/material/material.js +3 -3
  20. package/dist/material/texture.js +10 -8
  21. package/dist/nodes/CfgDeferredMeshNode.d.ts +8 -1
  22. package/dist/nodes/CfgDeferredMeshNode.js +48 -18
  23. package/dist/nodes/CfgProductNode.d.ts +68 -3
  24. package/dist/nodes/CfgProductNode.js +130 -38
  25. package/dist/nodes/CfgSymNode.d.ts +14 -6
  26. package/dist/nodes/CfgSymNode.js +50 -17
  27. package/dist/nodes/CfgSymRootNode.d.ts +18 -6
  28. package/dist/nodes/CfgSymRootNode.js +62 -17
  29. package/dist/nodes/CfgTransformNode.d.ts +4 -0
  30. package/dist/nodes/CfgTransformNode.js +4 -2
  31. package/dist/utilities/CfgBoundingBox.d.ts +5 -0
  32. package/dist/utilities/CfgBoundingBox.js +18 -1
  33. package/dist/utilities/anchor/anchor.d.ts +52 -0
  34. package/dist/utilities/anchor/anchor.js +136 -0
  35. package/dist/utilities/anchor/anchorMap.d.ts +21 -0
  36. package/dist/utilities/anchor/anchorMap.js +111 -0
  37. package/dist/utilities/utilities3D.d.ts +44 -0
  38. package/dist/utilities/utilities3D.js +97 -19
  39. package/dist/utilities/utilitiesSymRootIdentifier.d.ts +3 -1
  40. package/dist/utilities/utilitiesSymRootIdentifier.js +10 -4
  41. package/dist/view/BaseView.d.ts +9 -1
  42. package/dist/view/BaseView.js +16 -10
  43. package/dist/view/RenderEnv.d.ts +6 -1
  44. package/dist/view/SingleProductDefaultCameraView.js +1 -1
  45. package/dist/view/SingleProductView.d.ts +8 -1
  46. package/dist/view/SingleProductView.js +1 -0
  47. package/package.json +5 -5
@@ -11,6 +11,8 @@ import { Matrix } from "@babylonjs/core/Maths/math.vector.js";
11
11
  import { InspectableType } from "@babylonjs/core/Misc/iInspectable.js";
12
12
  import { aggregateAllMaterialApplications, CfgMtrlApplication, CfgMtrlApplicationSource, logMaterialMappingToConsole, } from "@configura/web-api";
13
13
  import { LogObservable, readFileToArrayBuffer } from "@configura/web-utilities";
14
+ import { CfgAnchorRef, getAnchorTargetPriorityComparer, updatedStretchedAnchorPointMatrix, } from "../utilities/anchor/anchor.js";
15
+ import { makeAnchoredToAnchorMap } from "../utilities/anchor/anchorMap.js";
14
16
  import { CfgBoundingBox } from "../utilities/CfgBoundingBox.js";
15
17
  import { modelTransformToSymTransform, symTransformToMatrix } from "../utilities/utilities3D.js";
16
18
  import { isSameRootNodeSource } from "../utilities/utilitiesSymRootIdentifier.js";
@@ -22,6 +24,9 @@ export function isProductNode(value) {
22
24
  export function isCfgSymRootNode(value) {
23
25
  return value instanceof CfgSymRootNode;
24
26
  }
27
+ export function isCfgAnchorableNode(value) {
28
+ return isProductNode(value) || isCfgSymRootNode(value);
29
+ }
25
30
  export class CfgProductNode extends CfgTransformNode {
26
31
  constructor(renderEnvironment, _product) {
27
32
  super(renderEnvironment, `(Product) ${_product.sku}`);
@@ -32,9 +37,12 @@ export class CfgProductNode extends CfgTransformNode {
32
37
  this._mtrlApplications = [];
33
38
  this._debugMtrlApplications = [];
34
39
  this._scheduledForRemoval = [];
40
+ this._anchoredToAnchors = new Map();
35
41
  this._symRootLoadings = [];
36
- /// The passed function is recursively applied on every descendant CfgProductNode in
37
- /// the tree. This node is included. Destroyed products are not included.
42
+ /**
43
+ * The passed function is recursively applied on every descendant CfgProductNode in the tree.
44
+ * This node is included. Destroyed products are not included.
45
+ */
38
46
  this._applyOnDescendantProductNodes = (fn) => {
39
47
  const result = [];
40
48
  result.push(fn(this));
@@ -44,17 +52,21 @@ export class CfgProductNode extends CfgTransformNode {
44
52
  return result;
45
53
  };
46
54
  this.key = _product.key;
55
+ // Useful debug tool:
56
+ if (false) {
57
+ window.product = this;
58
+ console.log(`Use "window.product" to access "${this.key}" product node.`);
59
+ }
60
+ this.anchorRef = CfgAnchorRef.make(this._product._internal.anchor);
47
61
  const modelTransform = _product.transform;
48
- let modelMatrix = Matrix.Identity();
49
62
  if (modelTransform !== undefined) {
50
63
  const modelSymTransform = modelTransformToSymTransform(modelTransform);
51
- modelMatrix = symTransformToMatrix(modelSymTransform.transform());
64
+ this._modelMatrix = symTransformToMatrix(modelSymTransform.transform());
52
65
  }
53
- this.originalMatrix = modelMatrix;
54
- this.setPreTransformMatrix(modelMatrix);
66
+ this.initTransform();
55
67
  }
56
68
  static make(renderEnvironment, product) {
57
- return new CfgProductNode(renderEnvironment, product);
69
+ return new this(renderEnvironment, product);
58
70
  }
59
71
  get cfgClassName() {
60
72
  return "CfgProductNode";
@@ -69,8 +81,10 @@ export class CfgProductNode extends CfgTransformNode {
69
81
  get product() {
70
82
  return this._product;
71
83
  }
72
- /// We want to be able to animate nodes that are on the way out.
73
- /// So we do not immediately remove them from the tree
84
+ /**
85
+ * We want to be able to animate nodes that are on the way out.
86
+ * So we do not immediately remove them from the tree.
87
+ */
74
88
  scheduleForRemoval(node) {
75
89
  node.destroy();
76
90
  this._scheduledForRemoval.push(node);
@@ -78,9 +92,11 @@ export class CfgProductNode extends CfgTransformNode {
78
92
  isDestroyed() {
79
93
  return this._destroyed;
80
94
  }
81
- /// This function will apply either of tree passed functions on the additional products
82
- /// in the passed CfgProduct and the additional products in the CfgProductNode.
83
- /// It is not applied recursively.
95
+ /**
96
+ * This function will apply either of tree passed functions on the additional products/ in the
97
+ * passed CfgProduct and the additional products in the CfgProductNode.
98
+ * It is not applied recursively.
99
+ */
84
100
  _syncAdditionalProductNodes(parentProduct, fn) {
85
101
  const { both, productNodeButNoProduct, productButNoProductNode } = fn;
86
102
  const additionalProducts = parentProduct.additionalProducts.filter((c) => c.selected);
@@ -108,15 +124,19 @@ export class CfgProductNode extends CfgTransformNode {
108
124
  productButNoProductNode(additionalProduct);
109
125
  }
110
126
  }
111
- /// Application areas are essentially catalogue level material mappings
112
- /// This function is recursively applied on additional products.
127
+ /**
128
+ * Application areas are essentially catalogue level material mappings.
129
+ * This function is recursively applied on additional products.
130
+ */
113
131
  setApplicationAreas(applicationAreas) {
114
132
  this._applyOnDescendantProductNodes((p) => {
115
133
  p._applicationAreas = applicationAreas;
116
134
  });
117
135
  }
118
- /// Start loading the geometry, but do not yet show it
119
- /// This function is recursively applied on additional products.
136
+ /**
137
+ * Start loading the geometry, but do not yet show it.
138
+ * This function is recursively applied on additional products.
139
+ */
120
140
  loadGeo(coordinatorWithMeta) {
121
141
  return __awaiter(this, void 0, void 0, function* () {
122
142
  const product = this._product;
@@ -134,7 +154,7 @@ export class CfgProductNode extends CfgTransformNode {
134
154
  }
135
155
  }
136
156
  for (const symRootChild of this._getSymRootChildren().filter((c) => !c.isForDebug)) {
137
- const updateIndex = updateRootNodeSources.findIndex((m) => symRootChild.isSameIdentifierAndTransform(m));
157
+ const updateIndex = updateRootNodeSources.findIndex((m) => symRootChild.isSameIdentifierTransformAndAnchor(m));
138
158
  if (updateIndex === -1) {
139
159
  // Not found, remove
140
160
  this.scheduleForRemoval(symRootChild);
@@ -149,7 +169,7 @@ export class CfgProductNode extends CfgTransformNode {
149
169
  if (symRootLoading === undefined) {
150
170
  symRootLoading = {
151
171
  rootNodeSource,
152
- rootNodePromise: CfgSymRootNode.makeCfgSymRootFromRootNodeSource(this.logger, false, this._renderEnvironment, rootNodeSource),
172
+ rootNodePromise: CfgSymRootNode.makeCfgSymRootFromRootNodeSource(this.logger, false, this._renderEnvironment, this, rootNodeSource),
153
173
  };
154
174
  allSymRootLoadings.push(symRootLoading);
155
175
  }
@@ -162,7 +182,7 @@ export class CfgProductNode extends CfgTransformNode {
162
182
  const addedSymRoots = (yield Promise.all(batchSymRootLoadings.map((s) => s.rootNodePromise)))
163
183
  .filter((symRoot) => symRoot !== undefined)
164
184
  .filter((symRoot) => {
165
- const loadInProgressIndex = allSymRootLoadings.findIndex((symRootLoadInProgress) => symRoot.isSameIdentifierAndTransform(symRootLoadInProgress.rootNodeSource));
185
+ const loadInProgressIndex = allSymRootLoadings.findIndex((symRootLoadInProgress) => symRoot.isSameIdentifierTransformAndAnchor(symRootLoadInProgress.rootNodeSource));
166
186
  if (loadInProgressIndex === -1) {
167
187
  // This node no longer shall be added
168
188
  return false;
@@ -172,6 +192,15 @@ export class CfgProductNode extends CfgTransformNode {
172
192
  this.add(symRoot);
173
193
  return true;
174
194
  });
195
+ // Updated symRootChildren
196
+ const anchorableChildren = this._getAnchorableNodes();
197
+ // Make a map of who is anchored to who
198
+ const anchoredToAnchors = makeAnchoredToAnchorMap(anchorableChildren, getAnchorTargetPriorityComparer(this.product._internal.measureDefinitions));
199
+ this._anchoredToAnchors = anchoredToAnchors;
200
+ for (const child of anchorableChildren) {
201
+ child.setAnchorTarget(anchoredToAnchors.get(child));
202
+ }
203
+ this.refreshStretch();
175
204
  for (const symRoot of addedSymRoots) {
176
205
  if (coordinatorWithMeta === undefined) {
177
206
  continue;
@@ -200,8 +229,10 @@ export class CfgProductNode extends CfgTransformNode {
200
229
  yield Promise.all(additionalProductLoadPromises);
201
230
  });
202
231
  }
203
- /// Run any animations and then permanently removes the nodes from the tree
204
- /// This function is recursively applied on additional products.
232
+ /**
233
+ * Run any animations and then permanently removes the nodes from the tree
234
+ * This function is recursively applied on additional products.
235
+ */
205
236
  flushScheduledForRemove(animationCoordinator) {
206
237
  return __awaiter(this, void 0, void 0, function* () {
207
238
  const thisBatch = this._scheduledForRemoval.slice();
@@ -218,14 +249,17 @@ export class CfgProductNode extends CfgTransformNode {
218
249
  }))()));
219
250
  });
220
251
  }
221
- /// Are all materials currently needed loaded and ready to be applied?
222
- /// This function does not take additional products into account.
252
+ /**
253
+ * Are all materials currently needed loaded and ready to be applied?
254
+ * This function does not take additional products into account.
255
+ */
223
256
  _isAllMeshMaterialsReady() {
224
257
  return this._getSymRootChildren().reduce((a, c) => a && c.isAllMeshMaterialsReady(), true);
225
258
  }
226
- /// Resolves when all materials currently needed have been loaded and are
227
- /// ready to be applied.
228
- /// This function does not take additional products into account.
259
+ /**
260
+ * Resolves when all materials currently needed have been loaded and are ready to be applied.
261
+ * This function does not take additional products into account.
262
+ */
229
263
  _awaitAllMeshMaterialsReady() {
230
264
  return __awaiter(this, void 0, void 0, function* () {
231
265
  return new Promise((resolve, reject) => {
@@ -246,8 +280,10 @@ export class CfgProductNode extends CfgTransformNode {
246
280
  });
247
281
  });
248
282
  }
249
- /// Loads the materials needed.
250
- /// This function is recursively applied on additional products.
283
+ /**
284
+ * Loads the materials needed.
285
+ * This function is recursively applied on additional products.
286
+ */
251
287
  loadMaterials(animationCoordinator) {
252
288
  return __awaiter(this, void 0, void 0, function* () {
253
289
  const product = this._product;
@@ -260,8 +296,10 @@ export class CfgProductNode extends CfgTransformNode {
260
296
  ]);
261
297
  });
262
298
  }
263
- /// Update the tag (area) to material mapping and gives them to sym children
264
- /// This function does not take additional products into account.
299
+ /**
300
+ * Update the tag (area) to material mapping and gives them to sym children
301
+ * This function does not take additional products into account.
302
+ */
265
303
  _aggregateMaterialsPushToChildrenAndLoad(animationCoordinator) {
266
304
  return __awaiter(this, void 0, void 0, function* () {
267
305
  if (this._applicationAreas === undefined || this._configuration === undefined) {
@@ -272,8 +310,10 @@ export class CfgProductNode extends CfgTransformNode {
272
310
  yield this._pushMaterialToSymRootChildrenAndLoad(animationCoordinator);
273
311
  });
274
312
  }
275
- /// Starts loading the materials on the sym children (but does not apply)
276
- /// This function does not take additional products into account.
313
+ /**
314
+ * Starts loading the materials on the sym children (but does not apply)
315
+ * This function does not take additional products into account.
316
+ */
277
317
  _pushMaterialToSymRootChildrenAndLoad(animationCoordinator) {
278
318
  return __awaiter(this, void 0, void 0, function* () {
279
319
  const areasToMaterials = this._areasToMaterials;
@@ -293,8 +333,15 @@ export class CfgProductNode extends CfgTransformNode {
293
333
  .filter(isProductNode)
294
334
  .filter((c) => includeDestroyed || !c.isDestroyed());
295
335
  }
296
- /// Applies and thereby shows the geometry. Finally flushes scheduled for remove.
297
- /// This function is recursively applied on additional products.
336
+ _getAnchorableNodes() {
337
+ return this.getChildren()
338
+ .filter(isCfgAnchorableNode)
339
+ .filter((c) => !c.isDestroyed());
340
+ }
341
+ /**
342
+ * Applies and thereby shows the geometry. Finally flushes scheduled for remove.
343
+ * This function is recursively applied on additional products.
344
+ */
298
345
  applyGeo(animationCoordinator) {
299
346
  return __awaiter(this, void 0, void 0, function* () {
300
347
  yield Promise.all(this._applyOnDescendantProductNodes((p) => (() => __awaiter(this, void 0, void 0, function* () {
@@ -309,8 +356,10 @@ export class CfgProductNode extends CfgTransformNode {
309
356
  this.flushScheduledForRemove(animationCoordinator);
310
357
  });
311
358
  }
312
- /// Applies and thereby shows the right materials.
313
- /// This function is recursively applied on additional products.
359
+ /**
360
+ * Applies and thereby shows the right materials.
361
+ * This function is recursively applied on additional products.
362
+ */
314
363
  applyMaterials() {
315
364
  return __awaiter(this, void 0, void 0, function* () {
316
365
  yield Promise.all(this._applyOnDescendantProductNodes((p) => (() => __awaiter(this, void 0, void 0, function* () {
@@ -324,6 +373,49 @@ export class CfgProductNode extends CfgTransformNode {
324
373
  }))()));
325
374
  });
326
375
  }
376
+ setAnchorTarget(anchorTarget) {
377
+ this._anchorTarget = anchorTarget;
378
+ }
379
+ refreshStretch() {
380
+ const updated = updatedStretchedAnchorPointMatrix(this.anchorRef, this._anchorTarget, this._stretchedAnchorPointMatrix, true);
381
+ if (updated !== undefined) {
382
+ this._stretchedAnchorPointMatrix = updated;
383
+ this._originalMatrixWithModelTransform = undefined; // Reset the matrix
384
+ this.initTransform();
385
+ }
386
+ // anchoredToAnchors is sorted so that anchors always are before what
387
+ // is anchored to them. That way we know that if we refreshStretch on
388
+ // them first anchor-on-anchor will work correctly.
389
+ const anchorableChildren = this._getAnchorableNodes().slice();
390
+ for (const anchor of this._anchoredToAnchors.values()) {
391
+ const i = anchorableChildren.indexOf(anchor);
392
+ if (i === -1) {
393
+ // As multiple anchors can anchor to the same anchor this will happen
394
+ continue;
395
+ }
396
+ anchor.refreshStretch();
397
+ anchorableChildren.splice(i, 1);
398
+ }
399
+ // Refresh for the un-anchored
400
+ for (const child of anchorableChildren) {
401
+ child.refreshStretch();
402
+ }
403
+ }
404
+ get originalMatrix() {
405
+ var _a;
406
+ if (this._originalMatrixWithModelTransform === undefined) {
407
+ let originalMatrix = (_a = this._modelMatrix) !== null && _a !== void 0 ? _a : Matrix.Identity();
408
+ const stretchedAnchorPointMatrix = this._stretchedAnchorPointMatrix;
409
+ if (stretchedAnchorPointMatrix !== undefined) {
410
+ originalMatrix = originalMatrix.multiply(stretchedAnchorPointMatrix);
411
+ }
412
+ this._originalMatrixWithModelTransform = originalMatrix;
413
+ }
414
+ return this._originalMatrixWithModelTransform;
415
+ }
416
+ initTransform() {
417
+ this.setPreTransformMatrix(this.originalMatrix);
418
+ }
327
419
  _applyDebugSymRoots(symRootPromises) {
328
420
  return __awaiter(this, void 0, void 0, function* () {
329
421
  const allSymRoots = yield Promise.all(symRootPromises);
@@ -463,7 +555,7 @@ export class CfgProductNode extends CfgTransformNode {
463
555
  const files = fileUpload.files;
464
556
  if (files !== null) {
465
557
  const symRootPromises = Array.from(files).map((file) => {
466
- return CfgSymRootNode.makeCfgSymRootFromFile(logger, true, renderEnvironment, file);
558
+ return CfgSymRootNode.makeCfgSymRootFromFile(logger, true, renderEnvironment, this, file);
467
559
  });
468
560
  this._applyDebugSymRoots(symRootPromises);
469
561
  }
@@ -480,7 +572,7 @@ export class CfgProductNode extends CfgTransformNode {
480
572
  alert("You must provide an URL to a CmSym-file");
481
573
  return;
482
574
  }
483
- const symRootNode = CfgSymRootNode.makeCfgSymRootFromUrl(this.logger, true, this._renderEnvironment, url, undefined);
575
+ const symRootNode = CfgSymRootNode.makeCfgSymRootFromUrl(this.logger, true, this._renderEnvironment, this, url, undefined, undefined);
484
576
  this._applyDebugSymRoots([symRootNode]);
485
577
  }
486
578
  }
@@ -5,27 +5,35 @@ import { DetailLevel } from "@configura/web-core/dist/cm/geometry/DetailMask.js"
5
5
  import { LogObservable, LogProducer } from "@configura/web-utilities";
6
6
  import { AnimatableObject } from "../animation/AnimatableObject.js";
7
7
  import { CoordinatorWithMeta } from "../animation/coordinator/Coordinator.js";
8
+ import { CfgStretchData } from "../geometry/stretch/CfgStretchData.js";
8
9
  import { CfgBoundingBox } from "../utilities/CfgBoundingBox.js";
9
10
  import { RenderEnv } from "../view/RenderEnv.js";
11
+ import { CfgProductNode } from "./CfgProductNode.js";
10
12
  import { CfgTransformNode } from "./CfgTransformNode.js";
11
13
  export declare class CfgSymNode extends CfgTransformNode implements LogProducer, AnimatableObject {
12
- _detailLevel: DetailLevel;
13
- _symNode: SymNode;
14
- private _symNodeParent?;
15
- static makeCfgSymNode(renderEnvironment: RenderEnv, detailLevel: DetailLevel, symNode: SymNode, symNodeParent?: CfgSymNode): Promise<CfgSymNode | undefined>;
14
+ readonly cfgProductNode: CfgProductNode;
15
+ private readonly _cfgSymNodeParent;
16
+ readonly _detailLevel: DetailLevel;
17
+ readonly _symNode: SymNode;
18
+ static makeCfgSymNode(renderEnvironment: RenderEnv, cfgProductNode: CfgProductNode, cfgSymNodeParent: CfgSymNode, detailLevel: DetailLevel, symNode: SymNode): Promise<CfgSymNode | undefined>;
16
19
  get cfgClassName(): string;
17
- static initCfgSymNode(node: CfgSymNode): Promise<void>;
20
+ protected static initCfgSymNode(node: CfgSymNode): Promise<void>;
18
21
  logger: LogObservable;
19
22
  _tag: string | undefined;
20
23
  private _gMaterial;
21
24
  private _symNodeChildren;
22
25
  private _deferredMesh;
23
26
  private _originalMatrix;
24
- protected constructor(renderEnvironment: RenderEnv, _detailLevel: DetailLevel, _symNode: SymNode, _symNodeParent?: CfgSymNode | undefined);
27
+ private _invertedOriginalMatrix;
28
+ private _accumulatedStretchDatas;
29
+ protected constructor(renderEnvironment: RenderEnv, cfgProductNode: CfgProductNode, _cfgSymNodeParent: CfgSymNode | undefined, _detailLevel: DetailLevel, _symNode: SymNode);
30
+ get accumulatedStretchDatas(): CfgStretchData[];
31
+ refreshStretch(): void;
25
32
  getChildrenForAnimation(): CfgTransformNode[];
26
33
  private initTag;
27
34
  private initGMaterial;
28
35
  get originalMatrix(): Matrix;
36
+ get invertedOriginalMatrix(): Matrix;
29
37
  protected initTransform(): void;
30
38
  private initChildren;
31
39
  get isEmpty(): boolean;
@@ -16,27 +16,35 @@ import { symTransformToMatrix } from "../utilities/utilities3D.js";
16
16
  import { CfgDeferredMeshNode } from "./CfgDeferredMeshNode.js";
17
17
  import { CfgTransformNode } from "./CfgTransformNode.js";
18
18
  function isNoRender(symNode) {
19
- var _a;
20
- const symTags = symNode.symTags();
21
- return symTags instanceof SymTags && !!((_a = symTags.node) === null || _a === void 0 ? void 0 : _a.components.has("symConnector"));
19
+ var _a, _b;
20
+ // Do not render SymPlanes. Disable to debug Stretch. Search for aTriMeshPlane to set radius.
21
+ if (symNode.symPlane() !== undefined) {
22
+ return true;
23
+ }
24
+ // Do not render connectors. Disable to debug connectors, only boxes will show up for now.
25
+ if (((_b = (_a = symNode.symTags()) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.components.has("symConnector")) === true) {
26
+ return true;
27
+ }
28
+ return false;
22
29
  }
23
30
  export class CfgSymNode extends CfgTransformNode {
24
- constructor(renderEnvironment, _detailLevel, _symNode, _symNodeParent) {
31
+ constructor(renderEnvironment, cfgProductNode, _cfgSymNodeParent, _detailLevel, _symNode) {
25
32
  super(renderEnvironment, "(SymNode) " + _symNode.id);
33
+ this.cfgProductNode = cfgProductNode;
34
+ this._cfgSymNodeParent = _cfgSymNodeParent;
26
35
  this._detailLevel = _detailLevel;
27
36
  this._symNode = _symNode;
28
- this._symNodeParent = _symNodeParent;
29
37
  this.logger = new LogObservable();
30
38
  this._symNodeChildren = [];
31
39
  this.initTransform();
32
40
  }
33
- static makeCfgSymNode(renderEnvironment, detailLevel, symNode, symNodeParent) {
41
+ static makeCfgSymNode(renderEnvironment, cfgProductNode, cfgSymNodeParent, detailLevel, symNode) {
34
42
  return __awaiter(this, void 0, void 0, function* () {
35
43
  if (isNoRender(symNode)) {
36
44
  return undefined;
37
45
  }
38
- const node = new CfgSymNode(renderEnvironment, detailLevel, symNode, symNodeParent);
39
- yield CfgSymNode.initCfgSymNode(node);
46
+ const node = new this(renderEnvironment, cfgProductNode, cfgSymNodeParent, detailLevel, symNode);
47
+ yield this.initCfgSymNode(node);
40
48
  if (node.isEmpty) {
41
49
  if (renderEnvironment.cullEmptyNodes) {
42
50
  node.dispose();
@@ -61,6 +69,21 @@ export class CfgSymNode extends CfgTransformNode {
61
69
  yield node.loadGeo();
62
70
  });
63
71
  }
72
+ get accumulatedStretchDatas() {
73
+ var _a;
74
+ if (this._accumulatedStretchDatas === undefined) {
75
+ this._accumulatedStretchDatas = (((_a = this._cfgSymNodeParent) === null || _a === void 0 ? void 0 : _a.accumulatedStretchDatas) || []).map((stretchData) => stretchData.applyMatrix(this.invertedOriginalMatrix));
76
+ }
77
+ return this._accumulatedStretchDatas;
78
+ }
79
+ refreshStretch() {
80
+ if (this._deferredMesh !== undefined) {
81
+ this._deferredMesh.refreshStretch();
82
+ }
83
+ for (const child of this._symNodeChildren) {
84
+ child.refreshStretch();
85
+ }
86
+ }
64
87
  getChildrenForAnimation() {
65
88
  const target = super.getChildrenForAnimation();
66
89
  if (this._deferredMesh !== undefined) {
@@ -84,7 +107,7 @@ export class CfgSymNode extends CfgTransformNode {
84
107
  }
85
108
  }
86
109
  if ((material === null || material === void 0 ? void 0 : material.gm) === undefined) {
87
- const parentMaterial = (_b = this._symNodeParent) === null || _b === void 0 ? void 0 : _b._gMaterial;
110
+ const parentMaterial = (_b = this._cfgSymNodeParent) === null || _b === void 0 ? void 0 : _b._gMaterial;
88
111
  if ((parentMaterial === null || parentMaterial === void 0 ? void 0 : parentMaterial.gm) !== undefined) {
89
112
  material = parentMaterial;
90
113
  }
@@ -104,15 +127,25 @@ export class CfgSymNode extends CfgTransformNode {
104
127
  }
105
128
  return this._originalMatrix;
106
129
  }
130
+ get invertedOriginalMatrix() {
131
+ if (this._invertedOriginalMatrix === undefined) {
132
+ this._invertedOriginalMatrix = this.originalMatrix.clone().invert();
133
+ }
134
+ return this._invertedOriginalMatrix;
135
+ }
107
136
  initTransform() {
108
137
  this.setPreTransformMatrix(this.originalMatrix);
109
138
  }
110
139
  initChildren() {
111
140
  return __awaiter(this, void 0, void 0, function* () {
112
141
  const promises = [];
142
+ const { logger, _detailLevel: detailLevel } = this;
113
143
  for (const childNode of (this._symNode.children(this.logger, false, true) || []).values()) {
144
+ if (childNode.isStretch(logger, detailLevel)) {
145
+ continue;
146
+ }
114
147
  promises.push((() => __awaiter(this, void 0, void 0, function* () {
115
- const childSymNode = yield CfgSymNode.makeCfgSymNode(this._renderEnvironment, this._detailLevel, childNode, this);
148
+ const childSymNode = yield CfgSymNode.makeCfgSymNode(this._renderEnvironment, this.cfgProductNode, this, this._detailLevel, childNode);
116
149
  if (childSymNode === undefined) {
117
150
  return;
118
151
  }
@@ -130,14 +163,14 @@ export class CfgSymNode extends CfgTransformNode {
130
163
  if (this._tag !== undefined && areasToMaterials.has(this._tag)) {
131
164
  return areasToMaterials.get(this._tag);
132
165
  }
133
- if (this._symNodeParent !== undefined) {
134
- return this._symNodeParent.findMaterial(areasToMaterials);
166
+ if (this._cfgSymNodeParent !== undefined) {
167
+ return this._cfgSymNodeParent.findMaterial(areasToMaterials);
135
168
  }
136
169
  return undefined;
137
170
  }
138
171
  loadGeo() {
139
172
  return __awaiter(this, void 0, void 0, function* () {
140
- this._deferredMesh = yield CfgDeferredMeshNode.makeCfgDeferredMesh(this.logger, this._renderEnvironment, this._detailLevel, this._symNode, this._gMaterial);
173
+ this._deferredMesh = yield CfgDeferredMeshNode.makeCfgDeferredMesh(this.logger, this._renderEnvironment, this.cfgProductNode, this._detailLevel, this._symNode, this._gMaterial, this.accumulatedStretchDatas);
141
174
  if (this._deferredMesh === undefined) {
142
175
  return;
143
176
  }
@@ -179,10 +212,10 @@ export class CfgSymNode extends CfgTransformNode {
179
212
  });
180
213
  }
181
214
  get boundingBox() {
182
- const bb = this._symNodeChildren.reduce((a, m) => {
183
- a.expand(m.boundingBox);
184
- return a;
185
- }, new CfgBoundingBox());
215
+ const bb = new CfgBoundingBox();
216
+ for (const symNodeChild of this._symNodeChildren) {
217
+ bb.expand(symNodeChild.boundingBox);
218
+ }
186
219
  if (this._deferredMesh !== undefined) {
187
220
  bb.expand(this._deferredMesh.boundingBox);
188
221
  }
@@ -1,24 +1,32 @@
1
1
  import { Matrix } from "@babylonjs/core/Maths/math.vector.js";
2
2
  import { CfgMaterialMapping, RootNodeSource, Transform as ModelTransform } from "@configura/web-api";
3
3
  import { SymNode } from "@configura/web-core/dist/cm/format/cmsym/SymNode.js";
4
- import { Logger } from "@configura/web-utilities";
4
+ import { LengthUnit, Logger } from "@configura/web-utilities";
5
5
  import { CoordinatorWithMeta } from "../animation/coordinator/Coordinator.js";
6
+ import { CfgStretchData } from "../geometry/stretch/CfgStretchData.js";
7
+ import { CfgAnchorRef, CfgAnchorTargetNode } from "../utilities/anchor/anchor.js";
6
8
  import { RenderEnv } from "../view/RenderEnv.js";
9
+ import { CfgProductNode } from "./CfgProductNode.js";
7
10
  import { CfgSymNode } from "./CfgSymNode.js";
11
+ export declare const MESH_UNIT: LengthUnit;
8
12
  export declare function isSymRootNode(value: unknown): value is CfgSymRootNode;
9
13
  export declare class CfgSymRootNode extends CfgSymNode {
10
14
  private _isForDebug;
11
15
  _identifier: string;
12
- static makeCfgSymRootFromRootNodeSource(logger: Logger, isForDebug: boolean, renderEnvironment: RenderEnv, rootNodeSource: RootNodeSource): Promise<CfgSymRootNode | undefined>;
13
- static makeCfgSymRootFromUrl(logger: Logger, isForDebug: boolean, renderEnvironment: RenderEnv, symUrl: string, transform: ModelTransform | undefined): Promise<CfgSymRootNode | undefined>;
14
- static makeCfgSymRootFromFile(logger: Logger, isForDebug: boolean, renderEnvironment: RenderEnv, file: File): Promise<CfgSymRootNode | undefined>;
16
+ readonly anchorRef: CfgAnchorRef | undefined;
17
+ static makeCfgSymRootFromRootNodeSource(logger: Logger, isForDebug: boolean, renderEnvironment: RenderEnv, cfgProductNodeParent: CfgProductNode, rootNodeSource: RootNodeSource): Promise<CfgSymRootNode | undefined>;
18
+ static makeCfgSymRootFromUrl(logger: Logger, isForDebug: boolean, renderEnvironment: RenderEnv, cfgProductNodeParent: CfgProductNode, symUrl: string, transform: ModelTransform | undefined, anchorRef: CfgAnchorRef | undefined): Promise<CfgSymRootNode | undefined>;
19
+ static makeCfgSymRootFromFile(logger: Logger, isForDebug: boolean, renderEnvironment: RenderEnv, cfgProductNodeParent: CfgProductNode, file: File): Promise<CfgSymRootNode | undefined>;
15
20
  get cfgClassName(): string;
16
- static makeCfgSymRootFromSymNode(logger: Logger, renderEnvironment: RenderEnv, isForDebug: boolean, identifier: string, transform: ModelTransform | undefined, symNode: SymNode): Promise<CfgSymRootNode | undefined>;
21
+ static makeCfgSymRootFromSymNode(logger: Logger, renderEnvironment: RenderEnv, cfgProductNodeParent: CfgProductNode, isForDebug: boolean, identifier: string, transform: ModelTransform | undefined, anchorRef: CfgAnchorRef | undefined, symNode: SymNode): Promise<CfgSymRootNode | undefined>;
17
22
  private _destroyed;
18
23
  private _originalMatrixWithModelTransform;
24
+ private _stretchDatas;
25
+ private _anchorTarget;
26
+ private _stretchedAnchorPointMatrix;
19
27
  private constructor();
20
28
  get isForDebug(): boolean;
21
- isSameIdentifierAndTransform(rootNodeSource: RootNodeSource): boolean;
29
+ isSameIdentifierTransformAndAnchor(rootNodeSource: RootNodeSource): boolean;
22
30
  destroy(): void;
23
31
  isDestroyed(): boolean;
24
32
  applyGeo(): void;
@@ -28,6 +36,10 @@ export declare class CfgSymRootNode extends CfgSymNode {
28
36
  private get modelTransform();
29
37
  private set modelTransform(value);
30
38
  get originalMatrix(): Matrix;
39
+ get stretchDatas(): CfgStretchData[];
40
+ get accumulatedStretchDatas(): CfgStretchData[];
41
+ setAnchorTarget(anchorTarget: CfgAnchorTargetNode | undefined): void;
42
+ refreshStretch(): void;
31
43
  protected addInspectorProperties(): void;
32
44
  private get _inspectorIsForDebug();
33
45
  }