@configura/web-core 1.3.0-alpha.1 → 1.3.0-alpha.5
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.
- package/dist/cm/core3D/ATriMeshF.d.ts +7 -1
- package/dist/cm/core3D/ATriMeshF.js +9 -5
- package/dist/cm/core3D/GMaterial3D.d.ts +4 -0
- package/dist/cm/core3D/GMaterial3D.js +4 -4
- package/dist/cm/core3D/GMaterialPBR.js +25 -13
- package/dist/cm/core3D/{UVMapEnv.d.ts → uvmapper/UVMapEnv.d.ts} +3 -1
- package/dist/cm/core3D/{UVMapEnv.js → uvmapper/UVMapEnv.js} +13 -1
- package/dist/cm/core3D/uvmapper/UVMapper.d.ts +42 -0
- package/dist/cm/core3D/uvmapper/UVMapper.js +94 -0
- package/dist/cm/core3D/uvmapper/UVMapperBox.d.ts +5 -0
- package/dist/cm/core3D/uvmapper/UVMapperBox.js +181 -0
- package/dist/cm/core3D/uvmapper/UVMapperCylinder.d.ts +10 -0
- package/dist/cm/core3D/uvmapper/UVMapperCylinder.js +96 -0
- package/dist/cm/core3D/uvmapper/UVMapperPlane.d.ts +4 -0
- package/dist/cm/core3D/uvmapper/UVMapperPlane.js +84 -0
- package/dist/cm/core3D/uvmapper/UVTransformer.d.ts +6 -0
- package/dist/cm/core3D/{UVTransformer.js → uvmapper/UVTransformer.js} +0 -0
- package/dist/cm/core3D/uvmapper/instantiateUVMapper.d.ts +4 -0
- package/dist/cm/core3D/uvmapper/instantiateUVMapper.js +4 -0
- package/dist/cm/format/cmsym/SymNode.d.ts +8 -0
- package/dist/cm/format/cmsym/SymNode.js +75 -0
- package/dist/cm/format/cmsym/components/SymBox.d.ts +1 -0
- package/dist/cm/format/cmsym/components/SymBox.js +8 -3
- package/dist/cm/format/cmsym/components/SymGMaterialSelector.d.ts +5 -0
- package/dist/cm/format/cmsym/components/SymGMaterialSelector.js +5 -3
- package/dist/cm/format/cmsym/components/SymMeasure.d.ts +3 -4
- package/dist/cm/format/cmsym/components/SymMeasure.js +20 -29
- package/dist/cm/format/cmsym/components/SymMultiSelector.js +7 -8
- package/dist/cm/format/cmsym/components/SymParams.d.ts +12 -0
- package/dist/cm/format/cmsym/components/SymParams.js +51 -0
- package/dist/cm/format/cmsym/components/SymPlane.d.ts +1 -1
- package/dist/cm/format/cmsym/components/SymPlane.js +4 -1
- package/dist/cm/format/cmsym/components/SymProgs.d.ts +28 -0
- package/dist/cm/format/cmsym/components/SymProgs.js +113 -0
- package/dist/cm/format/cmsym/components/SymProps.d.ts +1 -1
- package/dist/cm/format/cmsym/components/SymRep.d.ts +4 -4
- package/dist/cm/format/cmsym/components/SymRep.js +5 -5
- package/dist/cm/format/cmsym/components/SymReps.js +3 -3
- package/dist/cm/format/cmsym/components/SymShape.js +4 -1
- package/dist/cm/format/cmsym/components/SymSphere.d.ts +2 -0
- package/dist/cm/format/cmsym/components/SymSphere.js +6 -3
- package/dist/cm/format/cmsym/components/SymText2D.d.ts +1 -0
- package/dist/cm/format/cmsym/components/SymText2D.js +1 -1
- package/dist/cm/format/cmsym/components/SymText3D.d.ts +1 -0
- package/dist/cm/format/cmsym/components/SymText3D.js +1 -1
- package/dist/cm/format/cmsym/components/SymUVMapper.d.ts +4 -4
- package/dist/cm/format/cmsym/components/SymUVMapper.js +3 -3
- package/dist/cm/format/dex/DexObj.d.ts +1 -1
- package/dist/cm/format/dex/DexObj.js +1 -1
- package/dist/cm/format/dex/DexReader.d.ts +5 -1
- package/dist/cm/format/dex/DexReader.js +40 -0
- package/dist/cm/geometry/Angle.js +2 -2
- package/dist/cm/geometry/DetailMask.d.ts +5 -0
- package/dist/cm/geometry/DetailMask.js +7 -5
- package/dist/cm/geometry/Matrix22.d.ts +1 -0
- package/dist/cm/geometry/Matrix22.js +3 -0
- package/dist/cm/geometry/Plane.d.ts +2 -2
- package/dist/cm/geometry/Point.d.ts +3 -0
- package/dist/cm/geometry/Point.js +9 -0
- package/dist/cm/geometry/Point2D.d.ts +1 -0
- package/dist/cm/geometry/Point2D.js +3 -0
- package/dist/cm/geometry/Transform2D.d.ts +2 -2
- package/dist/cm/io/Semver.d.ts +1 -0
- package/dist/cm/io/Semver.js +4 -1
- package/package.json +4 -4
- package/dist/cm/core3D/DummyUVMapper.d.ts +0 -7
- package/dist/cm/core3D/DummyUVMapper.js +0 -6
- package/dist/cm/core3D/UVTransformer.d.ts +0 -6
- package/dist/cm/core3D/instantiateUVMapper.d.ts +0 -4
- package/dist/cm/core3D/instantiateUVMapper.js +0 -5
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { UVMapper } from "./UVMapper.js";
|
|
2
|
+
/**
|
|
3
|
+
* This mapper gives bad results in the "seam" where the wrapped texture meet itself. If you have
|
|
4
|
+
* access to prebaked UVs then use those, and if you do stretch use the for stretched method with
|
|
5
|
+
* the prebaked UVS as a start point
|
|
6
|
+
*/
|
|
7
|
+
export function createUVCylinderCoordinates(env, positions, bounds, normals) {
|
|
8
|
+
return createUV(env, positions, bounds, normals, undefined, undefined, undefined);
|
|
9
|
+
}
|
|
10
|
+
export function createUVCylinderCoordinatesForStretched(env, positions, bounds, normals, refPositions, refBounds, refUvs) {
|
|
11
|
+
return createUV(env, positions, bounds, normals, refPositions, refBounds, refUvs);
|
|
12
|
+
}
|
|
13
|
+
function createUV(env, positions, bounds, normals, refPositions, refBounds, refUvs) {
|
|
14
|
+
const refPositionsFallbackToPositions = refPositions || positions;
|
|
15
|
+
const transforms = env === null || env === void 0 ? void 0 : env.transforms;
|
|
16
|
+
const transformSide = transforms === null || transforms === void 0 ? void 0 : transforms[0];
|
|
17
|
+
const transformTopBottom = transforms === null || transforms === void 0 ? void 0 : transforms[1];
|
|
18
|
+
const xyzCount = positions.length;
|
|
19
|
+
const vertexCount = xyzCount / 3;
|
|
20
|
+
if (refPositions !== undefined && refPositions.length !== xyzCount) {
|
|
21
|
+
throw new Error(`Position count differs: ${refPositions.length} vs ${xyzCount}.`);
|
|
22
|
+
}
|
|
23
|
+
if (normals.length !== xyzCount) {
|
|
24
|
+
throw new Error(`Normal count differs: ${normals.length} vs ${xyzCount}.`);
|
|
25
|
+
}
|
|
26
|
+
const { refMin, refSize, textureFixMin, textureFixMax } = UVMapper.calculateLimits(bounds, refBounds);
|
|
27
|
+
// This is what this entire method aims at populating
|
|
28
|
+
const newUvs = new Float32Array(vertexCount * 2);
|
|
29
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
30
|
+
const xyzOffset = i * 3;
|
|
31
|
+
const uvOffset = i * 2;
|
|
32
|
+
if (normals[xyzOffset] === 0 &&
|
|
33
|
+
normals[xyzOffset + 1] === 0 &&
|
|
34
|
+
normals[xyzOffset + 2] !== 0) {
|
|
35
|
+
// This is Top / Bottom
|
|
36
|
+
let u = (positions[xyzOffset] - refMin[0]) / refSize[0];
|
|
37
|
+
let v = (positions[xyzOffset + 1] - refMin[1]) / refSize[1];
|
|
38
|
+
const isNegAxis = normals[xyzOffset + 2] < 0;
|
|
39
|
+
if (isNegAxis) {
|
|
40
|
+
// Weird irregularity in how mapping is done in CET
|
|
41
|
+
v -= 1;
|
|
42
|
+
}
|
|
43
|
+
if (refPositions !== undefined) {
|
|
44
|
+
u += textureFixMin[0];
|
|
45
|
+
if (isNegAxis) {
|
|
46
|
+
v += textureFixMax[1];
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
v += textureFixMin[1];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (transformTopBottom !== undefined) {
|
|
53
|
+
[u, v] = UVMapper.applyUvTransform([u, v], transformTopBottom);
|
|
54
|
+
}
|
|
55
|
+
newUvs[uvOffset] = u;
|
|
56
|
+
newUvs[uvOffset + 1] = v;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// This is a Side
|
|
60
|
+
// It is very, very hard to make a full proper cylindrical stretching UV-mapper.
|
|
61
|
+
// For the seam to look sensible there has to be double (split) vertices. Model Lab does
|
|
62
|
+
// this for us when saving a CmSym file. However, this seam will move as we stretch,
|
|
63
|
+
// and there are no guarantees that it will be straight.
|
|
64
|
+
// As a compromise we stretch the top and bottom and height, but not the curved side.
|
|
65
|
+
// This should give good results for table tops, where the edge is often narrow and not
|
|
66
|
+
// very detailed, and for table legs (where the radius is fairly constant).
|
|
67
|
+
let u = Math.atan2(refPositionsFallbackToPositions[xyzOffset + 1], refPositionsFallbackToPositions[xyzOffset]) /
|
|
68
|
+
(Math.PI * 2) +
|
|
69
|
+
0.5;
|
|
70
|
+
let refUTest = u;
|
|
71
|
+
let v = (positions[xyzOffset + 2] - refMin[2]) / refSize[2];
|
|
72
|
+
// CET fixes texture to same corner when stretching. This code makes this work
|
|
73
|
+
if (refPositions !== undefined) {
|
|
74
|
+
v += textureFixMin[2];
|
|
75
|
+
}
|
|
76
|
+
if (transformSide !== undefined) {
|
|
77
|
+
[u, v] = UVMapper.applyUvTransform([u, v], transformSide);
|
|
78
|
+
}
|
|
79
|
+
if (refUvs !== undefined && refPositions !== undefined) {
|
|
80
|
+
// We need to find vertices that are at the seam. The seam where nodes are double
|
|
81
|
+
// so that texture mapping can be sharp. By compensating the difference between our
|
|
82
|
+
// equations and what Model Lab has calculated we can adjust our stretched
|
|
83
|
+
// coordinates.
|
|
84
|
+
let refVTest = (refPositions[xyzOffset + 2] - refMin[2]) / refSize[2];
|
|
85
|
+
if (transformSide !== undefined) {
|
|
86
|
+
[refUTest, refVTest] = UVMapper.applyUvTransform([refUTest, refVTest], transformSide);
|
|
87
|
+
}
|
|
88
|
+
u -= refUTest - refUvs[uvOffset];
|
|
89
|
+
v -= refVTest - refUvs[uvOffset + 1];
|
|
90
|
+
}
|
|
91
|
+
newUvs[uvOffset] = u;
|
|
92
|
+
newUvs[uvOffset + 1] = v;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return newUvs;
|
|
96
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { UVMapEnv } from "./UVMapEnv.js";
|
|
2
|
+
export declare function createUVPlaneCoordinates(env: UVMapEnv | undefined, positions: Float32Array): Float32Array;
|
|
3
|
+
export declare function createUVPlaneCoordinatesForStretched(env: UVMapEnv | undefined, positions: Float32Array, refPositions: Float32Array): Float32Array;
|
|
4
|
+
//# sourceMappingURL=UVMapperPlane.d.ts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { UVMapper } from "./UVMapper.js";
|
|
2
|
+
/**
|
|
3
|
+
* Calculate base vectors for the mapping plane where the first is orthogonal with the
|
|
4
|
+
* normal-vector and flat along the ground and the other is orthogonal to the first two.
|
|
5
|
+
*/
|
|
6
|
+
function calculateMappingPlaneVectors(normal) {
|
|
7
|
+
const [normalX, normalY, normalZ] = normal;
|
|
8
|
+
const normalLen = Math.sqrt(normalX * normalX + normalY * normalY + normalZ * normalZ);
|
|
9
|
+
// Probably already normalized, but just to be sure
|
|
10
|
+
const normalNormalized = normal.map((n) => n / normalLen);
|
|
11
|
+
if (normalNormalized[0] === 0 && normalNormalized[1] === 0 && normalNormalized[2] === 1) {
|
|
12
|
+
return [
|
|
13
|
+
[0, 1, 0],
|
|
14
|
+
[-1, 0, 0],
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
const [normalNormalizedX, normalNormalizedY, normalNormalizedZ] = normalNormalized;
|
|
18
|
+
const base0Len = Math.sqrt(normalNormalizedX * normalNormalizedX + normalNormalizedY * normalNormalizedY);
|
|
19
|
+
// Along the ground (z is 0) as in CET
|
|
20
|
+
const base0 = [-normalNormalizedY / base0Len, normalNormalizedX / base0Len, 0];
|
|
21
|
+
const [base0X, base0Y, base0Z] = base0;
|
|
22
|
+
// Cross product, orthogonal to the plane normal and the "along the ground vector"
|
|
23
|
+
const base1 = [
|
|
24
|
+
normalNormalizedY * base0Z - normalNormalizedZ * base0Y,
|
|
25
|
+
normalNormalizedZ * base0X - normalNormalizedX * base0Z,
|
|
26
|
+
normalNormalizedX * base0Y - normalNormalizedY * base0X,
|
|
27
|
+
];
|
|
28
|
+
return [base0, base1];
|
|
29
|
+
}
|
|
30
|
+
/** From a point over to the UV-coordinates by projecting */
|
|
31
|
+
function toUv(point, mappingPlaneVectors) {
|
|
32
|
+
const [b0, b1] = mappingPlaneVectors;
|
|
33
|
+
const [x, y, z] = point;
|
|
34
|
+
return [b0[0] * x + b0[1] * y + b0[2] * z, b1[0] * x + b1[1] * y + b1[2] * z];
|
|
35
|
+
}
|
|
36
|
+
export function createUVPlaneCoordinates(env, positions) {
|
|
37
|
+
return createUV(env, positions, undefined);
|
|
38
|
+
}
|
|
39
|
+
export function createUVPlaneCoordinatesForStretched(env, positions, refPositions) {
|
|
40
|
+
return createUV(env, positions, refPositions);
|
|
41
|
+
}
|
|
42
|
+
function createUV(env, positions, refPositions) {
|
|
43
|
+
var _a;
|
|
44
|
+
if (env === undefined) {
|
|
45
|
+
throw new Error("env needed for plane mapper");
|
|
46
|
+
}
|
|
47
|
+
const xyzCount = positions.length;
|
|
48
|
+
const vertexCount = xyzCount / 3;
|
|
49
|
+
if (refPositions !== undefined && refPositions.length !== xyzCount) {
|
|
50
|
+
throw new Error(`Position count differs: ${refPositions.length} vs ${xyzCount}.`);
|
|
51
|
+
}
|
|
52
|
+
refPositions = refPositions || positions;
|
|
53
|
+
const normal = env.normal;
|
|
54
|
+
const transform = (_a = env.transforms) === null || _a === void 0 ? void 0 : _a[0];
|
|
55
|
+
const mappingPlaneVectors = calculateMappingPlaneVectors([normal.x, normal.y, normal.z]);
|
|
56
|
+
let refMinU = Number.POSITIVE_INFINITY;
|
|
57
|
+
let refMaxU = Number.NEGATIVE_INFINITY;
|
|
58
|
+
let refMinV = Number.POSITIVE_INFINITY;
|
|
59
|
+
let refMaxV = Number.NEGATIVE_INFINITY;
|
|
60
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
61
|
+
const xyzOffset = i * 3;
|
|
62
|
+
const [u, v] = toUv([refPositions[xyzOffset], refPositions[xyzOffset + 1], refPositions[xyzOffset + 2]], mappingPlaneVectors);
|
|
63
|
+
refMinU = Math.min(refMinU, u);
|
|
64
|
+
refMaxU = Math.max(refMaxU, u);
|
|
65
|
+
refMinV = Math.min(refMinV, v);
|
|
66
|
+
refMaxV = Math.max(refMaxV, v);
|
|
67
|
+
}
|
|
68
|
+
const refSizeU = refMaxU - refMinU;
|
|
69
|
+
const refSizeV = refMaxV - refMinV;
|
|
70
|
+
const newUvs = new Float32Array(vertexCount * 2);
|
|
71
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
72
|
+
const xyzOffset = i * 3;
|
|
73
|
+
const uvOffset = i * 2;
|
|
74
|
+
let [u, v] = toUv([positions[xyzOffset], positions[xyzOffset + 1], positions[xyzOffset + 2]], mappingPlaneVectors);
|
|
75
|
+
u = (u - refMinU) / refSizeU;
|
|
76
|
+
v = (v - refMinV) / refSizeV;
|
|
77
|
+
if (transform !== undefined) {
|
|
78
|
+
[u, v] = UVMapper.applyUvTransform([u, v], transform);
|
|
79
|
+
}
|
|
80
|
+
newUvs[uvOffset] = u;
|
|
81
|
+
newUvs[uvOffset + 1] = v;
|
|
82
|
+
}
|
|
83
|
+
return newUvs;
|
|
84
|
+
}
|
|
File without changes
|
|
@@ -7,7 +7,9 @@ import { DexObjKey, SymComponent, SymComponentKey } from "./components/SymCompon
|
|
|
7
7
|
import { SymDexObj } from "./components/SymDexObj.js";
|
|
8
8
|
import { SymGMaterial } from "./components/SymGMaterial.js";
|
|
9
9
|
import { SymGMaterialSelector } from "./components/SymGMaterialSelector.js";
|
|
10
|
+
import { SymMeasure } from "./components/SymMeasure.js";
|
|
10
11
|
import { SymMesh } from "./components/SymMesh.js";
|
|
12
|
+
import { SymPlane } from "./components/SymPlane.js";
|
|
11
13
|
import { SymProps } from "./components/SymProps.js";
|
|
12
14
|
import { SymReps } from "./components/SymReps.js";
|
|
13
15
|
import { SymSphere } from "./components/SymSphere.js";
|
|
@@ -15,6 +17,7 @@ import { SymTags } from "./components/SymTags.js";
|
|
|
15
17
|
import { SymTransform } from "./components/SymTransform.js";
|
|
16
18
|
import { SymUVMapper } from "./components/SymUVMapper.js";
|
|
17
19
|
import { SymImportEnv } from "./SymImportEnv.js";
|
|
20
|
+
export declare const VERBOSE_SYM_LOGGING = false;
|
|
18
21
|
export declare class SymNode {
|
|
19
22
|
id: string;
|
|
20
23
|
_children?: Map<string, SymNode>;
|
|
@@ -53,6 +56,8 @@ export declare class SymNode {
|
|
|
53
56
|
symSphere(safe?: boolean): SymSphere | undefined;
|
|
54
57
|
symBox(safe: true): SymBox;
|
|
55
58
|
symBox(safe?: boolean): SymBox | undefined;
|
|
59
|
+
symPlane(safe: true): SymPlane;
|
|
60
|
+
symPlane(safe?: boolean): SymPlane | undefined;
|
|
56
61
|
symProps(safe: true): SymProps;
|
|
57
62
|
symProps(safe?: boolean): SymProps | undefined;
|
|
58
63
|
symReps(safe: true): SymReps;
|
|
@@ -63,6 +68,9 @@ export declare class SymNode {
|
|
|
63
68
|
symTransform(safe?: boolean): SymTransform | undefined;
|
|
64
69
|
symUVMapper(safe: true): SymUVMapper;
|
|
65
70
|
symUVMapper(safe?: boolean): SymUVMapper | undefined;
|
|
71
|
+
getMeasure(): SymMeasure | undefined;
|
|
72
|
+
private _isStretch;
|
|
73
|
+
isStretch(logger: Logger, detailLevel: DetailLevel): boolean;
|
|
66
74
|
getComponent(key: SymComponentKey): SymComponent | undefined;
|
|
67
75
|
addComponent(component: SymComponent, invalidate?: boolean): void;
|
|
68
76
|
hasComponent(key: SymComponentKey | DexObjKey): boolean;
|
|
@@ -19,7 +19,9 @@ import { SymComponent } from "./components/SymComponent.js";
|
|
|
19
19
|
import { SymDexObj } from "./components/SymDexObj.js";
|
|
20
20
|
import { SymGMaterial } from "./components/SymGMaterial.js";
|
|
21
21
|
import { SymGMaterialSelector } from "./components/SymGMaterialSelector.js";
|
|
22
|
+
import { SymMeasure } from "./components/SymMeasure.js";
|
|
22
23
|
import { SymMesh } from "./components/SymMesh.js";
|
|
24
|
+
import { SymPlane } from "./components/SymPlane.js";
|
|
23
25
|
import { SymProps, SYM_FEATURES_KEY, SYM_GEOMETRY_KEY, SYM_LOCAL_BOUND_KEY, SYM_NODE_KEY, SYM_STRUCTURAL_KEY, } from "./components/SymProps.js";
|
|
24
26
|
import { SymReps } from "./components/SymReps.js";
|
|
25
27
|
import { SymSphere } from "./components/SymSphere.js";
|
|
@@ -28,10 +30,15 @@ import { SymTransform } from "./components/SymTransform.js";
|
|
|
28
30
|
import { SymUVMapper } from "./components/SymUVMapper.js";
|
|
29
31
|
import { appendInvalidation, invalidate } from "./invalidation.js";
|
|
30
32
|
import { SymImportEnv } from "./SymImportEnv.js";
|
|
33
|
+
export const VERBOSE_SYM_LOGGING = false;
|
|
31
34
|
export class SymNode {
|
|
32
35
|
constructor(id) {
|
|
33
36
|
this.id = id;
|
|
34
37
|
this.components = new Map();
|
|
38
|
+
this._isStretch = new Map();
|
|
39
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
40
|
+
console.log("SymNode: " + id);
|
|
41
|
+
}
|
|
35
42
|
}
|
|
36
43
|
setId(logger, newId) {
|
|
37
44
|
if (this.id === newId) {
|
|
@@ -305,6 +312,17 @@ export class SymNode {
|
|
|
305
312
|
return component;
|
|
306
313
|
}
|
|
307
314
|
}
|
|
315
|
+
symPlane(safe) {
|
|
316
|
+
const component = this.getComponent("symPlane");
|
|
317
|
+
if (component instanceof SymPlane) {
|
|
318
|
+
return component;
|
|
319
|
+
}
|
|
320
|
+
else if (safe) {
|
|
321
|
+
const component = new SymPlane();
|
|
322
|
+
this.addComponent(component);
|
|
323
|
+
return component;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
308
326
|
symProps(safe) {
|
|
309
327
|
const component = this.getComponent("symProps");
|
|
310
328
|
if (component instanceof SymProps) {
|
|
@@ -360,6 +378,20 @@ export class SymNode {
|
|
|
360
378
|
return component;
|
|
361
379
|
}
|
|
362
380
|
}
|
|
381
|
+
getMeasure() {
|
|
382
|
+
const component = this.components.get("symMeasure");
|
|
383
|
+
if (component instanceof SymMeasure) {
|
|
384
|
+
return component;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
isStretch(logger, detailLevel) {
|
|
388
|
+
let isStretch = this._isStretch.get(detailLevel);
|
|
389
|
+
if (isStretch === undefined) {
|
|
390
|
+
isStretch = symNodeIsStretch(logger, this, detailLevel);
|
|
391
|
+
this._isStretch.set(detailLevel, isStretch);
|
|
392
|
+
}
|
|
393
|
+
return isStretch;
|
|
394
|
+
}
|
|
363
395
|
// Components
|
|
364
396
|
getComponent(key) {
|
|
365
397
|
return this.components.get(key);
|
|
@@ -545,6 +577,8 @@ function toSymXRefNode(_obj, _parent, _env, _putImportEnv = false) {
|
|
|
545
577
|
function toSymFileRoot(logger, obj, parent) {
|
|
546
578
|
const version = obj.get("version");
|
|
547
579
|
const semver = loadVersion(version);
|
|
580
|
+
// Enable to get CmSym version statistics in the Exerciser
|
|
581
|
+
// logger.info("CmSym version " + semver.toDisplayString());
|
|
548
582
|
const env = new SymImportEnv(semver);
|
|
549
583
|
const sym = obj.get("sym");
|
|
550
584
|
if (!(sym instanceof DexObj)) {
|
|
@@ -575,3 +609,44 @@ export function makeSymFromDex(logger, root) {
|
|
|
575
609
|
node.ensureChildrenLoaded(logger);
|
|
576
610
|
return node;
|
|
577
611
|
}
|
|
612
|
+
function symNodeIsStretch(logger, symNode, detailLevel) {
|
|
613
|
+
const symMeasure = symNode.getMeasure();
|
|
614
|
+
if (symMeasure === undefined) {
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
const children = symNode.children(logger, true, true);
|
|
618
|
+
let nodeName;
|
|
619
|
+
for (const [name, node] of children) {
|
|
620
|
+
if (name.startsWith("3D") || name.startsWith("2D")) {
|
|
621
|
+
const symReps = node.symReps(true);
|
|
622
|
+
const details = symReps._details;
|
|
623
|
+
if (details === undefined) {
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
const detailMask = details.values().next().value;
|
|
627
|
+
if (detailMask.includes(detailLevel)) {
|
|
628
|
+
nodeName = name;
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (nodeName === undefined) {
|
|
634
|
+
logger.warn(`No 3D/2D SymNode which covers the detailLevel ${detailLevel} found`);
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
const node = children.get(nodeName);
|
|
638
|
+
if (node === undefined) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
const progsNode = node.components.get("symProgs");
|
|
642
|
+
if (progsNode === undefined) {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
const symProgs = progsNode;
|
|
646
|
+
for (const prog of symProgs.progs) {
|
|
647
|
+
if (prog.isStretch) {
|
|
648
|
+
return true;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
@@ -4,6 +4,7 @@ import { Point } from "../../../geometry/Point.js";
|
|
|
4
4
|
import { DexObj } from "../../dex/DexObj.js";
|
|
5
5
|
import { SymImportEnv } from "../SymImportEnv.js";
|
|
6
6
|
import { SymComponent, SymComponentKey } from "./SymComponent.js";
|
|
7
|
+
/** @see http://web.git.configura.com/webteam/docs/cmsym/#SymBox */
|
|
7
8
|
export declare class SymBox extends SymComponent {
|
|
8
9
|
private _box?;
|
|
9
10
|
id: SymComponentKey;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { fcastNumber } from "../../../basic/number.js";
|
|
2
2
|
import { Box } from "../../../geometry/Box.js";
|
|
3
3
|
import { Point } from "../../../geometry/Point.js";
|
|
4
|
+
import { VERBOSE_SYM_LOGGING } from "../SymNode.js";
|
|
4
5
|
import { SymComponent } from "./SymComponent.js";
|
|
5
|
-
|
|
6
|
+
/** @see http://web.git.configura.com/webteam/docs/cmsym/#SymBox */
|
|
6
7
|
export class SymBox extends SymComponent {
|
|
7
8
|
constructor(_box, src) {
|
|
8
9
|
super(src);
|
|
@@ -21,14 +22,18 @@ export class SymBox extends SymComponent {
|
|
|
21
22
|
const p0 = Point.cast(obj.get("p0"));
|
|
22
23
|
const p1 = Point.cast(obj.get("p1"));
|
|
23
24
|
if (p0 !== undefined && p1 !== undefined) {
|
|
24
|
-
|
|
25
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
26
|
+
logger.info(`SymBox (<${p0.x},${p0.y},${p0.z}>, <${p1.x},${p1.y},${p1.z}>)`);
|
|
27
|
+
}
|
|
25
28
|
this._box = new Box(p0, p1);
|
|
26
29
|
return;
|
|
27
30
|
}
|
|
28
31
|
const w = fcastNumber(obj.get("w"));
|
|
29
32
|
const d = fcastNumber(obj.get("d"));
|
|
30
33
|
const h = fcastNumber(obj.get("h"));
|
|
31
|
-
|
|
34
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
35
|
+
logger.info(`SymBox (w ${w}, d ${d}, h ${h})`);
|
|
36
|
+
}
|
|
32
37
|
this._box = new Box(new Point(0, 0, 0), new Point(w, d, h));
|
|
33
38
|
}
|
|
34
39
|
}
|
|
@@ -4,6 +4,11 @@ import { DexObj } from "../../dex/DexObj.js";
|
|
|
4
4
|
import { SymImportEnv } from "../SymImportEnv.js";
|
|
5
5
|
import { SymComponent, SymComponentKey } from "./SymComponent.js";
|
|
6
6
|
import { SymGMaterial } from "./SymGMaterial.js";
|
|
7
|
+
/**
|
|
8
|
+
* The specification says that the last option is the default / fallback if there isn't any match
|
|
9
|
+
* among the layers, so we only load and use that one.
|
|
10
|
+
* @see http://web.git.configura.com/webteam/docs/cmsym/#SymGMaterialSelector
|
|
11
|
+
*/
|
|
7
12
|
export declare class SymGMaterialSelector extends SymComponent {
|
|
8
13
|
id: SymComponentKey;
|
|
9
14
|
gm?: GMaterial3D;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { SymComponent } from "./SymComponent.js";
|
|
2
2
|
import { SymGMaterial } from "./SymGMaterial.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The specification says that the last option is the default / fallback if there isn't any match
|
|
5
|
+
* among the layers, so we only load and use that one.
|
|
6
|
+
* @see http://web.git.configura.com/webteam/docs/cmsym/#SymGMaterialSelector
|
|
7
|
+
*/
|
|
6
8
|
export class SymGMaterialSelector extends SymComponent {
|
|
7
9
|
constructor() {
|
|
8
10
|
super(...arguments);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Logger } from "@configura/web-utilities";
|
|
2
2
|
import { DexObj } from "../../dex/DexObj.js";
|
|
3
3
|
import { SymImportEnv } from "../SymImportEnv.js";
|
|
4
|
-
import { SymComponent, SymComponentKey } from "./SymComponent.js";
|
|
4
|
+
import { SymComponent, SymComponentKey, SymGfxMode } from "./SymComponent.js";
|
|
5
5
|
import { SymMultiSelector } from "./SymMultiSelector.js";
|
|
6
|
-
import { SymRep } from "./SymRep.js";
|
|
7
6
|
export declare class SymMeasure extends SymComponent {
|
|
8
7
|
id: SymComponentKey;
|
|
9
8
|
private _sections;
|
|
@@ -21,7 +20,7 @@ export declare class SymMeasure extends SymComponent {
|
|
|
21
20
|
get dividerSubpaths(): SymMeasureDivider[];
|
|
22
21
|
}
|
|
23
22
|
export declare class SymMeasureDivider {
|
|
24
|
-
readonly repToPath: Map<
|
|
23
|
+
readonly repToPath: Map<string, string>;
|
|
25
24
|
readonly currentStretch: number;
|
|
26
25
|
constructor(obj: DexObj, logger: Logger);
|
|
27
26
|
}
|
|
@@ -29,7 +28,7 @@ export declare class SymMeasureSection {
|
|
|
29
28
|
readonly sizeChange: number;
|
|
30
29
|
readonly move: boolean;
|
|
31
30
|
readonly currentStretch: number;
|
|
32
|
-
readonly
|
|
31
|
+
readonly gfxModeToDetailLevelToMultiSelector: Map<SymGfxMode, Map<number, SymMultiSelector>>;
|
|
33
32
|
constructor(obj: DexObj, logger: Logger);
|
|
34
33
|
}
|
|
35
34
|
//# sourceMappingURL=SymMeasure.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DexObj } from "../../dex/DexObj.js";
|
|
2
|
+
import { VERBOSE_SYM_LOGGING } from "../SymNode.js";
|
|
2
3
|
import { SymComponent } from "./SymComponent.js";
|
|
3
4
|
import { SymMultiSelector } from "./SymMultiSelector.js";
|
|
4
5
|
import { SymRep } from "./SymRep.js";
|
|
@@ -43,17 +44,9 @@ export class SymMeasure extends SymComponent {
|
|
|
43
44
|
}
|
|
44
45
|
this._sections.push(new SymMeasureSection(section, logger));
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
// `measureParam ${this.measureParam}`,
|
|
50
|
-
// `spOffsetParam ${this.spOffsetParam}`,
|
|
51
|
-
// `stretchingEPParam ${this._stretchingEPParam}`,
|
|
52
|
-
// "sections:",
|
|
53
|
-
// this.sections,
|
|
54
|
-
// "dividerSubpaths",
|
|
55
|
-
// this.dividerSubpaths
|
|
56
|
-
// );
|
|
47
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
48
|
+
logger.info(`SymMeasure`, `originalLength ${this.originalLength}`, `measureParam ${this.measureParam}`, `spOffsetParam ${this.spOffsetParam}`, `stretchingEPParam ${this._stretchingEPParam}`, "sections:", this.sections, "dividerSubpaths", this.dividerSubpaths);
|
|
49
|
+
}
|
|
57
50
|
}
|
|
58
51
|
get measureParam() {
|
|
59
52
|
return this._measureParam;
|
|
@@ -100,19 +93,16 @@ export class SymMeasureDivider {
|
|
|
100
93
|
logger.warn("SymMeasureDivider loading error", "SymRep or path not correct type");
|
|
101
94
|
continue;
|
|
102
95
|
}
|
|
103
|
-
this.repToPath.set(symRep, path);
|
|
96
|
+
this.repToPath.set(JSON.stringify(symRep), path);
|
|
97
|
+
}
|
|
98
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
99
|
+
logger.info(`SymMeasureDivider`, `currentStretch ${this.currentStretch}`, "repToPath:", this.repToPath);
|
|
104
100
|
}
|
|
105
|
-
// logger.info(
|
|
106
|
-
// `SymMeasureDivider`,
|
|
107
|
-
// `currentStretch ${this.currentStretch}`,
|
|
108
|
-
// "repToPath:",
|
|
109
|
-
// this.repToPath
|
|
110
|
-
// );
|
|
111
101
|
}
|
|
112
102
|
}
|
|
113
103
|
export class SymMeasureSection {
|
|
114
104
|
constructor(obj, logger) {
|
|
115
|
-
this.
|
|
105
|
+
this.gfxModeToDetailLevelToMultiSelector = new Map();
|
|
116
106
|
const sizeChange = obj.get("sizeChange");
|
|
117
107
|
const move = obj.get("move");
|
|
118
108
|
const currentStretch = obj.get("currentStretch");
|
|
@@ -139,20 +129,21 @@ export class SymMeasureSection {
|
|
|
139
129
|
continue;
|
|
140
130
|
}
|
|
141
131
|
const symRep = SymRep.load(rep);
|
|
142
|
-
const symMultiSelector = new SymMultiSelector(selector, logger);
|
|
143
132
|
if (!(symRep instanceof SymRep)) {
|
|
144
133
|
logger.warn("SymMeasureSection loading error", "SymRep failed to load");
|
|
145
134
|
continue;
|
|
146
135
|
}
|
|
147
|
-
|
|
136
|
+
const { mode, detail } = symRep;
|
|
137
|
+
let detailLevelToMultiSelector = this.gfxModeToDetailLevelToMultiSelector.get(mode);
|
|
138
|
+
if (detailLevelToMultiSelector === undefined) {
|
|
139
|
+
detailLevelToMultiSelector = new Map();
|
|
140
|
+
this.gfxModeToDetailLevelToMultiSelector.set(mode, detailLevelToMultiSelector);
|
|
141
|
+
}
|
|
142
|
+
const symMultiSelector = new SymMultiSelector(selector, logger);
|
|
143
|
+
detailLevelToMultiSelector.set(detail, symMultiSelector);
|
|
144
|
+
}
|
|
145
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
146
|
+
logger.info(`SymMeasureSection`, `sizeChange ${this.sizeChange}`, `move ${this.move}`, `currentStretch ${this.currentStretch}`, "repToSelector:", this.gfxModeToDetailLevelToMultiSelector);
|
|
148
147
|
}
|
|
149
|
-
// logger.info(
|
|
150
|
-
// `SymMeasureSection`,
|
|
151
|
-
// `sizeChange ${this.sizeChange}`,
|
|
152
|
-
// `move ${this.move}`,
|
|
153
|
-
// `currentStretch ${this.currentStretch}`,
|
|
154
|
-
// "repToSelector:",
|
|
155
|
-
// this.repToSelector
|
|
156
|
-
// );
|
|
157
148
|
}
|
|
158
149
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DexObj } from "../../dex/DexObj.js";
|
|
2
|
+
import { VERBOSE_SYM_LOGGING } from "../SymNode.js";
|
|
2
3
|
export class SymMultiSelector {
|
|
3
4
|
constructor(obj, logger) {
|
|
4
5
|
this.selectors = [];
|
|
@@ -14,7 +15,9 @@ export class SymMultiSelector {
|
|
|
14
15
|
}
|
|
15
16
|
this.selectors.push(new SymDividerSelector(selector, logger));
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
19
|
+
logger.info(`SymMultiSelector`, "selectors:", this.selectors);
|
|
20
|
+
}
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
23
|
export class SymDividerSelector {
|
|
@@ -38,12 +41,8 @@ export class SymDividerSelector {
|
|
|
38
41
|
this.ownerId = ownerId;
|
|
39
42
|
this.outside = outside;
|
|
40
43
|
this.includes = includes;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// `ownerId ${this.ownerId}`,
|
|
45
|
-
// `outside ${this.outside}`,
|
|
46
|
-
// `includes ${this.includes}`
|
|
47
|
-
// );
|
|
44
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
45
|
+
logger.info(`SymDividerSelector`, `dividerId ${this.dividerId}`, `ownerId ${this.ownerId}`, `outside ${this.outside}`, `includes ${this.includes}`);
|
|
46
|
+
}
|
|
48
47
|
}
|
|
49
48
|
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
import { Logger } from "@configura/web-utilities";
|
|
2
|
+
import { DexObj } from "../../dex/DexObj.js";
|
|
3
|
+
import { SymImportEnv } from "../SymImportEnv.js";
|
|
1
4
|
import { SymComponent, SymComponentKey } from "./SymComponent.js";
|
|
2
5
|
export declare class SymParams extends SymComponent {
|
|
3
6
|
id: SymComponentKey;
|
|
7
|
+
private _params;
|
|
8
|
+
load(logger: Logger, obj: DexObj, _env: SymImportEnv, force?: boolean): undefined;
|
|
9
|
+
get params(): Map<string, ParamValue>;
|
|
10
|
+
}
|
|
11
|
+
export declare class ParamValue {
|
|
12
|
+
readonly progDependencies: Set<string>;
|
|
13
|
+
readonly value: number;
|
|
14
|
+
constructor(progDependencies: Set<string>, value: number);
|
|
15
|
+
static load(obj: DexObj, logger: Logger): ParamValue | undefined;
|
|
4
16
|
}
|
|
5
17
|
//# sourceMappingURL=SymParams.d.ts.map
|
|
@@ -1,7 +1,58 @@
|
|
|
1
|
+
import { DexObj } from "../../dex/DexObj.js";
|
|
2
|
+
import { VERBOSE_SYM_LOGGING } from "../SymNode.js";
|
|
1
3
|
import { SymComponent } from "./SymComponent.js";
|
|
2
4
|
export class SymParams extends SymComponent {
|
|
3
5
|
constructor() {
|
|
4
6
|
super(...arguments);
|
|
5
7
|
this.id = "symParams";
|
|
8
|
+
this._params = new Map();
|
|
9
|
+
}
|
|
10
|
+
load(logger, obj, _env, force = false) {
|
|
11
|
+
if (obj.get("paramsTrie") !== undefined) {
|
|
12
|
+
// After some digging it appears that "paramsTrie" was dropped in CmSym 4.0.0 but there
|
|
13
|
+
// might still be CmSym files out there using it.
|
|
14
|
+
//
|
|
15
|
+
// It is however very unlikely that such files would be used in conjunction with
|
|
16
|
+
// Catalogue Stretch which is when we need the params, so it is only an "info".
|
|
17
|
+
logger.info("CmSym file contains an outdated and unsupported version of SymParams. It is advised to re-save the CmSym using a modern version of CET.", "CmSym version used: " + _env.fileVersion.toDisplayString());
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const params = obj.get("params");
|
|
21
|
+
if (!(params instanceof DexObj)) {
|
|
22
|
+
logger.warn("SymParams loading error", "invalid properties");
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
for (const key of params.props.keys()) {
|
|
26
|
+
const dexParamValue = params.get(key);
|
|
27
|
+
if (!(dexParamValue instanceof DexObj)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const paramValue = ParamValue.load(dexParamValue, logger);
|
|
31
|
+
if (paramValue !== undefined) {
|
|
32
|
+
this._params.set(key, paramValue);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (VERBOSE_SYM_LOGGING) {
|
|
36
|
+
logger.info(`SymParams`, "params", this.params);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
get params() {
|
|
40
|
+
return this._params;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class ParamValue {
|
|
44
|
+
constructor(progDependencies, value) {
|
|
45
|
+
this.progDependencies = new Set();
|
|
46
|
+
this.progDependencies = progDependencies;
|
|
47
|
+
this.value = value;
|
|
48
|
+
}
|
|
49
|
+
static load(obj, logger) {
|
|
50
|
+
const progDependencies = obj.get("progDependencies");
|
|
51
|
+
const value = obj.get("v");
|
|
52
|
+
if (!(progDependencies instanceof Set && typeof value === "number")) {
|
|
53
|
+
logger.warn("ParamValue loading error", "invalid properties");
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
return new this(progDependencies, value);
|
|
6
57
|
}
|
|
7
58
|
}
|