@constructorfleet/sketchforge-engine 1.19.0 → 1.21.0
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/README.md +3 -3
- package/dist/domain/sketchforge.d.ts +43 -0
- package/dist/domain/sketchforge.d.ts.map +1 -1
- package/dist/engine.d.ts +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +482 -29
- package/dist/engine.js.map +1 -1
- package/dist/faceDraftSegmentLineage.d.ts +45 -0
- package/dist/faceDraftSegmentLineage.d.ts.map +1 -0
- package/dist/faceDraftSegmentLineage.js +200 -0
- package/dist/faceDraftSegmentLineage.js.map +1 -0
- package/dist/faceLineage.d.ts +10 -0
- package/dist/faceLineage.d.ts.map +1 -0
- package/dist/faceLineage.js +84 -0
- package/dist/faceLineage.js.map +1 -0
- package/dist/parametricRecompute.d.ts +2 -0
- package/dist/parametricRecompute.d.ts.map +1 -1
- package/dist/parametricRecompute.js +152 -0
- package/dist/parametricRecompute.js.map +1 -1
- package/dist/revolveRequests.d.ts +12 -0
- package/dist/revolveRequests.d.ts.map +1 -1
- package/dist/serverCadOperations.d.ts +54 -3
- package/dist/serverCadOperations.d.ts.map +1 -1
- package/dist/serverCadOperations.js +224 -6
- package/dist/serverCadOperations.js.map +1 -1
- package/dist/serverCadShell.d.ts +3 -1
- package/dist/serverCadShell.d.ts.map +1 -1
- package/dist/serverCadShell.js +15 -5
- package/dist/serverCadShell.js.map +1 -1
- package/dist/sketchExtrusionRequest.d.ts.map +1 -1
- package/dist/sketchExtrusionRequest.js +1 -0
- package/dist/sketchExtrusionRequest.js.map +1 -1
- package/dist/skfProject.d.ts.map +1 -1
- package/dist/skfProject.js +210 -8
- package/dist/skfProject.js.map +1 -1
- package/dist/stepComponentMetadata.d.ts.map +1 -1
- package/dist/stepComponentMetadata.js +55 -2
- package/dist/stepComponentMetadata.js.map +1 -1
- package/dist/stepExport.d.ts.map +1 -1
- package/dist/stepExport.js +54 -8
- package/dist/stepExport.js.map +1 -1
- package/dist/stepGlbColors.d.ts.map +1 -1
- package/dist/stepGlbColors.js +10 -2
- package/dist/stepGlbColors.js.map +1 -1
- package/dist/support/lib/operator-configuration.json +10 -0
- package/package.json +1 -1
package/dist/skfProject.js
CHANGED
|
@@ -8,6 +8,7 @@ import { canonicalizeShape } from "./workplaneShapes.js";
|
|
|
8
8
|
import { importedShapeFromStl } from "./stlImport.js";
|
|
9
9
|
import { importedShapeFromSvg } from "./svgImport.js";
|
|
10
10
|
import { normalizeSnapGrid, normalizeWorkspaceSettings } from "./workplaneSettings.js";
|
|
11
|
+
import { cadSketchRegions, cadSketchSweepPaths } from "./sketchCadProfile.js";
|
|
11
12
|
export const SKF_SCHEMA_ID = "com.sketchforge.project";
|
|
12
13
|
export const SKF_FORMAT_VERSION = 2;
|
|
13
14
|
export const SKF_MINIMUM_READER_VERSION = 2;
|
|
@@ -30,7 +31,7 @@ const SHAPE_KINDS = new Set([
|
|
|
30
31
|
]);
|
|
31
32
|
const LOFT_PROFILE_SHAPES = new Set(["Oval", "Rectangle", "Triangle", "Pentagon", "Hexagon"]);
|
|
32
33
|
const FEATURE_TYPES = new Set([
|
|
33
|
-
"group", "boolean-subtraction", "boolean-intersection", "mirror", "sketch-extrusion", "sketch-revolve", "sketch-sweep", "fillet", "chamfer",
|
|
34
|
+
"group", "boolean-subtraction", "boolean-intersection", "mirror", "sketch-extrusion", "sketch-revolve", "sketch-sweep", "fillet", "chamfer", "face-draft",
|
|
34
35
|
]);
|
|
35
36
|
function exactArrayBuffer(bytes) {
|
|
36
37
|
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
@@ -438,6 +439,9 @@ async function serializeShapeNode(shape, nodeId, nodes, builder, sourceAssetsByA
|
|
|
438
439
|
sketchRevolve: undefined,
|
|
439
440
|
sketchSourceId: undefined,
|
|
440
441
|
sketchSourceNodeId: undefined,
|
|
442
|
+
faceDraft: undefined,
|
|
443
|
+
faceDraftSourceFrame: undefined,
|
|
444
|
+
faceDraftSourceSegmentId: undefined,
|
|
441
445
|
sketchSourceOfObjectId: shape.id,
|
|
442
446
|
},
|
|
443
447
|
});
|
|
@@ -576,6 +580,19 @@ function activeProjectIndexes(state) {
|
|
|
576
580
|
});
|
|
577
581
|
previous = featureId;
|
|
578
582
|
}
|
|
583
|
+
const faceDraft = node.definition.faceDraft;
|
|
584
|
+
if (faceDraft) {
|
|
585
|
+
const featureId = `feature/${safeNodeToken(node.nodeId)}/face-draft`;
|
|
586
|
+
features.push({
|
|
587
|
+
id: featureId,
|
|
588
|
+
type: "face-draft",
|
|
589
|
+
outputObjectId: node.objectId,
|
|
590
|
+
inputObjectIds: [node.objectId],
|
|
591
|
+
dependsOnFeatureIds: previous ? [previous] : [],
|
|
592
|
+
parameters: { ...faceDraft },
|
|
593
|
+
});
|
|
594
|
+
previous = featureId;
|
|
595
|
+
}
|
|
579
596
|
const treatments = Array.isArray(node.definition.edgeTreatments) ? node.definition.edgeTreatments : [];
|
|
580
597
|
treatments.forEach((treatment, index) => {
|
|
581
598
|
const type = treatment.kind === "fillet" ? "fillet" : "chamfer";
|
|
@@ -866,12 +883,19 @@ function validateSketchProfile(value, label) {
|
|
|
866
883
|
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${constraintLabel}.id` });
|
|
867
884
|
constraintIds.add(id);
|
|
868
885
|
const kind = stringValue(constraint.kind, `${constraintLabel}.kind`);
|
|
869
|
-
if (kind === "
|
|
886
|
+
if (kind === "fixed") {
|
|
887
|
+
const pointId = stringValue(constraint.pointId, `${constraintLabel}.pointId`);
|
|
888
|
+
if (!pointIds.has(pointId))
|
|
889
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${constraintLabel}.pointId` });
|
|
890
|
+
finiteNumber(constraint.xMm, `${constraintLabel}.xMm`);
|
|
891
|
+
finiteNumber(constraint.zMm, `${constraintLabel}.zMm`);
|
|
892
|
+
}
|
|
893
|
+
else if (kind === "horizontal" || kind === "vertical") {
|
|
870
894
|
if (!segmentIds.has(stringValue(constraint.segmentId, `${constraintLabel}.segmentId`))) {
|
|
871
895
|
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${constraintLabel}.segmentId` });
|
|
872
896
|
}
|
|
873
897
|
}
|
|
874
|
-
else if (kind === "perpendicular") {
|
|
898
|
+
else if (kind === "perpendicular" || kind === "parallel") {
|
|
875
899
|
if (!Array.isArray(constraint.segmentIds) || constraint.segmentIds.length !== 2 || constraint.segmentIds[0] === constraint.segmentIds[1] || !constraint.segmentIds.every((segmentId) => typeof segmentId === "string" && segmentIds.has(segmentId))) {
|
|
876
900
|
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${constraintLabel}.segmentIds` });
|
|
877
901
|
}
|
|
@@ -890,7 +914,7 @@ function validateSketchProfile(value, label) {
|
|
|
890
914
|
});
|
|
891
915
|
}
|
|
892
916
|
}
|
|
893
|
-
function validateShapeDefinition(definition, label) {
|
|
917
|
+
function validateShapeDefinition(definition, label, options = {}) {
|
|
894
918
|
const id = stringValue(definition.id, `${label}.id`);
|
|
895
919
|
stringValue(definition.name, `${label}.name`);
|
|
896
920
|
const kind = stringValue(definition.kind, `${label}.kind`);
|
|
@@ -919,13 +943,13 @@ function validateShapeDefinition(definition, label) {
|
|
|
919
943
|
if (definition.faceColors !== undefined) {
|
|
920
944
|
const colors = objectRecord(definition.faceColors, `${label}.faceColors`);
|
|
921
945
|
for (const [faceId, color] of Object.entries(colors)) {
|
|
922
|
-
if (!(
|
|
946
|
+
if (!faceId.trim() || typeof color !== "string" || !/^#[0-9a-fA-F]{6}(?:[0-9a-fA-F]{2})?$/.test(color)) {
|
|
923
947
|
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceColors.${faceId}` });
|
|
924
948
|
}
|
|
925
949
|
}
|
|
926
950
|
}
|
|
927
951
|
if (definition.faceIds !== undefined && (!Array.isArray(definition.faceIds)
|
|
928
|
-
|| definition.faceIds.some((faceId) => typeof faceId !== "string" || !faceId.
|
|
952
|
+
|| definition.faceIds.some((faceId) => typeof faceId !== "string" || !faceId.trim())
|
|
929
953
|
|| new Set(definition.faceIds).size !== definition.faceIds.length)) {
|
|
930
954
|
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceIds` });
|
|
931
955
|
}
|
|
@@ -960,6 +984,178 @@ function validateShapeDefinition(definition, label) {
|
|
|
960
984
|
finiteNumber(settings[field], `${label}.sketchRevolve.${field}`);
|
|
961
985
|
});
|
|
962
986
|
}
|
|
987
|
+
if (definition.faceDraft !== undefined) {
|
|
988
|
+
const draft = objectRecord(definition.faceDraft, `${label}.faceDraft`);
|
|
989
|
+
const revolveSettings = definition.sketchRevolve && typeof definition.sketchRevolve === "object" && !Array.isArray(definition.sketchRevolve)
|
|
990
|
+
? definition.sketchRevolve
|
|
991
|
+
: undefined;
|
|
992
|
+
const plainFullTurnRevolve = definition.sketchOperation === "revolve" && revolveSettings
|
|
993
|
+
&& typeof revolveSettings.sweepAngle === "number"
|
|
994
|
+
&& Math.abs(Math.abs(revolveSettings.sweepAngle) - 360) <= 1e-6
|
|
995
|
+
&& (revolveSettings.pitch === undefined || revolveSettings.pitch === 0)
|
|
996
|
+
&& (revolveSettings.coreRadius === undefined || revolveSettings.coreRadius === 0);
|
|
997
|
+
const treatments = Array.isArray(definition.edgeTreatments) ? definition.edgeTreatments : [];
|
|
998
|
+
const treatment = treatments[0] && typeof treatments[0] === "object" && !Array.isArray(treatments[0])
|
|
999
|
+
? treatments[0]
|
|
1000
|
+
: undefined;
|
|
1001
|
+
const history = options.edgeTreatmentHistory ?? [];
|
|
1002
|
+
const historyFeature = history[0]?.feature;
|
|
1003
|
+
const isPersistedRevolveDraftTreatment = Boolean(plainFullTurnRevolve
|
|
1004
|
+
&& definition.sketchProfile !== undefined
|
|
1005
|
+
&& cadSketchRegions(definition.sketchProfile).length === 1
|
|
1006
|
+
&& definition.draftPrismAngle === undefined
|
|
1007
|
+
&& treatments.length === 1
|
|
1008
|
+
&& (treatment?.kind === "chamfer" || treatment?.kind === "fillet")
|
|
1009
|
+
&& treatment.allEdges === true
|
|
1010
|
+
&& treatment.edges === undefined
|
|
1011
|
+
&& (treatment.kind === "fillet"
|
|
1012
|
+
|| typeof treatment.chamferAngle === "number" && Math.abs(treatment.chamferAngle - 45) < 0.001)
|
|
1013
|
+
&& typeof treatment.amount === "number"
|
|
1014
|
+
&& Number.isFinite(treatment.amount)
|
|
1015
|
+
&& treatment.amount > 0
|
|
1016
|
+
&& Number.isInteger(treatment.edgeCount)
|
|
1017
|
+
&& treatment.edgeCount > 0
|
|
1018
|
+
&& history.length === 1
|
|
1019
|
+
&& historyFeature?.kind === treatment.kind
|
|
1020
|
+
&& historyFeature.allEdges === treatment.allEdges
|
|
1021
|
+
&& (treatment.kind === "fillet" || historyFeature.chamferAngle === treatment.chamferAngle)
|
|
1022
|
+
&& historyFeature.amount === treatment.amount
|
|
1023
|
+
&& historyFeature.edgeCount === treatment.edgeCount);
|
|
1024
|
+
const extrusionRegions = definition.sketchOperation === "extrude" && definition.sketchProfile !== undefined
|
|
1025
|
+
? cadSketchRegions(definition.sketchProfile)
|
|
1026
|
+
: [];
|
|
1027
|
+
const isPersistedExtrusionDraftTreatment = Boolean(definition.sketchOperation === "extrude"
|
|
1028
|
+
&& extrusionRegions.length === 1
|
|
1029
|
+
&& extrusionRegions[0]?.holes.length === 0
|
|
1030
|
+
&& definition.draftPrismAngle === undefined
|
|
1031
|
+
&& treatments.length === 1
|
|
1032
|
+
&& (treatment?.kind === "fillet" || treatment?.kind === "chamfer")
|
|
1033
|
+
&& treatment.allEdges === true
|
|
1034
|
+
&& treatment.edges === undefined
|
|
1035
|
+
&& (treatment.kind === "fillet"
|
|
1036
|
+
|| typeof treatment.chamferAngle === "number" && Math.abs(treatment.chamferAngle - 45) < 0.001)
|
|
1037
|
+
&& typeof treatment.amount === "number"
|
|
1038
|
+
&& Number.isFinite(treatment.amount)
|
|
1039
|
+
&& treatment.amount > 0
|
|
1040
|
+
&& Number.isInteger(treatment.edgeCount)
|
|
1041
|
+
&& treatment.edgeCount > 0
|
|
1042
|
+
&& history.length === 1
|
|
1043
|
+
&& historyFeature?.kind === treatment.kind
|
|
1044
|
+
&& historyFeature.allEdges === true
|
|
1045
|
+
&& (treatment.kind === "fillet" || historyFeature.chamferAngle === treatment.chamferAngle)
|
|
1046
|
+
&& historyFeature.amount === treatment.amount
|
|
1047
|
+
&& historyFeature.edgeCount === treatment.edgeCount);
|
|
1048
|
+
let isPersistedSweepDraftTreatment = false;
|
|
1049
|
+
if (definition.sketchOperation === "sweep" && definition.sketchProfile !== undefined) {
|
|
1050
|
+
try {
|
|
1051
|
+
const { sections, spine } = cadSketchSweepPaths(definition.sketchProfile);
|
|
1052
|
+
isPersistedSweepDraftTreatment = Boolean(sections.length === 1
|
|
1053
|
+
&& sections[0]?.holes.length === 0
|
|
1054
|
+
&& spine.steps.length > 0
|
|
1055
|
+
&& definition.draftPrismAngle === undefined
|
|
1056
|
+
&& treatments.length === 1
|
|
1057
|
+
&& (treatment?.kind === "fillet" || treatment?.kind === "chamfer")
|
|
1058
|
+
&& treatment.allEdges === true
|
|
1059
|
+
&& treatment.edges === undefined
|
|
1060
|
+
&& (treatment.kind === "fillet"
|
|
1061
|
+
|| typeof treatment.chamferAngle === "number" && Math.abs(treatment.chamferAngle - 45) < 0.001)
|
|
1062
|
+
&& typeof treatment.amount === "number"
|
|
1063
|
+
&& Number.isFinite(treatment.amount)
|
|
1064
|
+
&& treatment.amount > 0
|
|
1065
|
+
&& Number.isInteger(treatment.edgeCount)
|
|
1066
|
+
&& treatment.edgeCount > 0
|
|
1067
|
+
&& history.length === 1
|
|
1068
|
+
&& historyFeature?.kind === treatment.kind
|
|
1069
|
+
&& historyFeature.allEdges === true
|
|
1070
|
+
&& (treatment.kind === "fillet" || historyFeature.chamferAngle === treatment.chamferAngle)
|
|
1071
|
+
&& historyFeature.amount === treatment.amount
|
|
1072
|
+
&& historyFeature.edgeCount === treatment.edgeCount);
|
|
1073
|
+
}
|
|
1074
|
+
catch {
|
|
1075
|
+
isPersistedSweepDraftTreatment = false;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
if (kind !== "mesh"
|
|
1079
|
+
|| (definition.sketchOperation !== "extrude" && definition.sketchOperation !== "sweep" && !plainFullTurnRevolve)
|
|
1080
|
+
|| definition.sketchProfile === undefined
|
|
1081
|
+
|| plainFullTurnRevolve && cadSketchRegions(definition.sketchProfile).length !== 1
|
|
1082
|
+
|| definition.sketchSourceId === undefined
|
|
1083
|
+
|| definition.draftPrismAngle !== undefined
|
|
1084
|
+
|| (treatments.length > 0 || options.hasEdgeTreatmentHistory)
|
|
1085
|
+
&& !isPersistedRevolveDraftTreatment && !isPersistedExtrusionDraftTreatment && !isPersistedSweepDraftTreatment) {
|
|
1086
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraft` });
|
|
1087
|
+
}
|
|
1088
|
+
const sourceFaceId = stringValue(draft.sourceFaceId, `${label}.faceDraft.sourceFaceId`);
|
|
1089
|
+
if (!sourceFaceId.trim())
|
|
1090
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraft.sourceFaceId` });
|
|
1091
|
+
const angle = finiteNumber(draft.angle, `${label}.faceDraft.angle`);
|
|
1092
|
+
if (angle === 0 || Math.abs(angle) >= 45)
|
|
1093
|
+
throw new LocalizedError("errors.skf.outOfRange", { label: `${label}.faceDraft.angle` });
|
|
1094
|
+
if (!["x", "y", "z", "-x", "-y", "-z"].includes(draft.pullDirection)) {
|
|
1095
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraft.pullDirection` });
|
|
1096
|
+
}
|
|
1097
|
+
const normal = objectRecord(draft.sourceFaceNormal, `${label}.faceDraft.sourceFaceNormal`);
|
|
1098
|
+
const coordinates = ["x", "y", "z"].map((axis) => finiteNumber(normal[axis], `${label}.faceDraft.sourceFaceNormal.${axis}`));
|
|
1099
|
+
const magnitude = Math.hypot(...coordinates);
|
|
1100
|
+
if (Math.abs(magnitude - 1) > 1e-4)
|
|
1101
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraft.sourceFaceNormal` });
|
|
1102
|
+
}
|
|
1103
|
+
if (definition.faceDraftSourceFrame !== undefined) {
|
|
1104
|
+
const frame = objectRecord(definition.faceDraftSourceFrame, `${label}.faceDraftSourceFrame`);
|
|
1105
|
+
["x", "z", "elevation", "width", "depth", "height"].forEach((field) => finiteNumber(frame[field], `${label}.faceDraftSourceFrame.${field}`));
|
|
1106
|
+
if (["width", "depth", "height"].some((field) => frame[field] <= 0)) {
|
|
1107
|
+
throw new LocalizedError("errors.skf.nonPositiveDimensions", { label: `${label}.faceDraftSourceFrame` });
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
if (definition.faceDraftSourceScale !== undefined) {
|
|
1111
|
+
const scale = objectRecord(definition.faceDraftSourceScale, `${label}.faceDraftSourceScale`);
|
|
1112
|
+
["width", "depth", "height"].forEach((field) => {
|
|
1113
|
+
if (finiteNumber(scale[field], `${label}.faceDraftSourceScale.${field}`) <= 0) {
|
|
1114
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraftSourceScale.${field}` });
|
|
1115
|
+
}
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
if (definition.faceDraftSourceFaceIds !== undefined) {
|
|
1119
|
+
if (!Array.isArray(definition.faceDraftSourceFaceIds) || definition.faceDraftSourceFaceIds.length === 0) {
|
|
1120
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraftSourceFaceIds` });
|
|
1121
|
+
}
|
|
1122
|
+
const sourceFaceIds = definition.faceDraftSourceFaceIds.map((id, index) => stringValue(id, `${label}.faceDraftSourceFaceIds[${index}]`));
|
|
1123
|
+
if (sourceFaceIds.some((id) => !id.trim()) || new Set(sourceFaceIds).size !== sourceFaceIds.length
|
|
1124
|
+
|| typeof definition.faceDraft === "object" && definition.faceDraft !== null
|
|
1125
|
+
&& !sourceFaceIds.includes(definition.faceDraft.sourceFaceId)) {
|
|
1126
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraftSourceFaceIds` });
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
if (definition.faceDraftSourceSegmentId !== undefined) {
|
|
1130
|
+
const sourceSegmentId = stringValue(definition.faceDraftSourceSegmentId, `${label}.faceDraftSourceSegmentId`);
|
|
1131
|
+
const profile = definition.sketchProfile;
|
|
1132
|
+
let regions = [];
|
|
1133
|
+
try {
|
|
1134
|
+
if (profile)
|
|
1135
|
+
regions = cadSketchRegions(profile);
|
|
1136
|
+
}
|
|
1137
|
+
catch {
|
|
1138
|
+
regions = [];
|
|
1139
|
+
}
|
|
1140
|
+
const segments = profile?.segments ?? [];
|
|
1141
|
+
const pointsById = new Map(profile?.points.map((point) => [point.id, point]) ?? []);
|
|
1142
|
+
const sourceSegmentMatches = segments.filter((segment) => segment.id === sourceSegmentId);
|
|
1143
|
+
const containsBezier = segments.some((segment) => {
|
|
1144
|
+
if (segment.kind !== undefined && segment.kind !== "line")
|
|
1145
|
+
return true;
|
|
1146
|
+
if (segment.kind !== undefined)
|
|
1147
|
+
return false;
|
|
1148
|
+
const start = pointsById.get(segment.startId);
|
|
1149
|
+
const end = pointsById.get(segment.endId);
|
|
1150
|
+
return Boolean(start && end && ((start.handleOut && end.handleIn) || (start.handleIn && end.handleOut)));
|
|
1151
|
+
});
|
|
1152
|
+
if (!sourceSegmentId.trim() || kind !== "mesh" || definition.sketchOperation !== "extrude"
|
|
1153
|
+
|| definition.faceDraft === undefined || !profile || regions.length !== 1 || regions[0]?.holes.length !== 0
|
|
1154
|
+
|| regions[0]?.outer.steps.length !== segments.length || containsBezier
|
|
1155
|
+
|| sourceSegmentMatches.length !== 1) {
|
|
1156
|
+
throw new LocalizedError("errors.skf.fieldInvalid", { label: `${label}.faceDraftSourceSegmentId` });
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
963
1159
|
if (kind === "gear") {
|
|
964
1160
|
const teeth = finiteNumber(definition.teeth, `${label}.teeth`);
|
|
965
1161
|
if (!Number.isInteger(teeth) || teeth < 6 || teeth > 64)
|
|
@@ -1128,7 +1324,10 @@ async function validateDocumentAndAssets(raw, files) {
|
|
|
1128
1324
|
if (nodeById.has(nodeId))
|
|
1129
1325
|
throw new LocalizedError("errors.skf.stateDuplicateNodeId", { state: stateId, id: nodeId });
|
|
1130
1326
|
const definition = objectRecord(node.definition, `node '${nodeId}'.definition`);
|
|
1131
|
-
const objectId = validateShapeDefinition(definition, `node '${nodeId}'
|
|
1327
|
+
const objectId = validateShapeDefinition(definition, `node '${nodeId}'`, {
|
|
1328
|
+
hasEdgeTreatmentHistory: Boolean(node.edgeTreatmentHistory?.length),
|
|
1329
|
+
edgeTreatmentHistory: node.edgeTreatmentHistory,
|
|
1330
|
+
});
|
|
1132
1331
|
if (node.objectId !== objectId)
|
|
1133
1332
|
throw new LocalizedError("errors.skf.nodeObjectIdMismatch", { id: nodeId });
|
|
1134
1333
|
if (node.importedMesh) {
|
|
@@ -1461,7 +1660,10 @@ function validateLegacyRuntimeShape(shape, label) {
|
|
|
1461
1660
|
delete definition.groupedShapes;
|
|
1462
1661
|
delete definition.edgeTreatmentHistory;
|
|
1463
1662
|
delete definition.cadBrep;
|
|
1464
|
-
validateShapeDefinition(definition, label
|
|
1663
|
+
validateShapeDefinition(definition, label, {
|
|
1664
|
+
hasEdgeTreatmentHistory: Array.isArray(edgeHistory) && edgeHistory.length > 0,
|
|
1665
|
+
edgeTreatmentHistory: Array.isArray(edgeHistory) ? edgeHistory : undefined,
|
|
1666
|
+
});
|
|
1465
1667
|
if (importedMesh) {
|
|
1466
1668
|
const mesh = objectRecord(importedMesh, `${label}.importedMesh`);
|
|
1467
1669
|
if (!Array.isArray(mesh.positions) || mesh.positions.length > SKF_LIMITS.meshNumbers || mesh.positions.some((value) => typeof value !== "number" || !Number.isFinite(value))) {
|