@things-factory/figure-ui 10.1.88 → 10.1.90
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/client/modeller/editor.ts +29 -3
- package/client/modeller/figure-parts.ts +2 -0
- package/client/modeller/figure-section-editor.ts +93 -8
- package/client/modeller/figure-section-panel.ts +3 -1
- package/client/modeller/maturity.ts +8 -1
- package/client/modeller/palette.ts +13 -0
- package/client/modeller/section-drawing.ts +25 -5
- package/client/modeller/starting-shape.ts +5 -3
- package/dist-client/modeller/clips.d.ts +1 -1
- package/dist-client/modeller/editor.d.ts +6 -0
- package/dist-client/modeller/editor.js +27 -3
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/figure-parts.js +2 -0
- package/dist-client/modeller/figure-parts.js.map +1 -1
- package/dist-client/modeller/figure-section-editor.d.ts +8 -0
- package/dist-client/modeller/figure-section-editor.js +89 -8
- package/dist-client/modeller/figure-section-editor.js.map +1 -1
- package/dist-client/modeller/figure-section-panel.js +3 -1
- package/dist-client/modeller/figure-section-panel.js.map +1 -1
- package/dist-client/modeller/maturity.js +8 -1
- package/dist-client/modeller/maturity.js.map +1 -1
- package/dist-client/modeller/palette.js +13 -0
- package/dist-client/modeller/palette.js.map +1 -1
- package/dist-client/modeller/section-drawing.d.ts +12 -0
- package/dist-client/modeller/section-drawing.js +22 -5
- package/dist-client/modeller/section-drawing.js.map +1 -1
- package/dist-client/modeller/starting-shape.d.ts +3 -2
- package/dist-client/modeller/starting-shape.js +4 -0
- package/dist-client/modeller/starting-shape.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/test/browser/acceptance-page.js +9 -0
- package/test/palette-icons.test.ts +5 -2
- package/test/parts-wiring.test.ts +1 -1
- package/test/section-editor.test.ts +57 -3
- package/translations/en.json +7 -1
- package/translations/ja.json +7 -1
- package/translations/ko.json +7 -1
- package/translations/ms.json +7 -1
- package/translations/zh.json +7 -1
|
@@ -26,6 +26,19 @@ export function paletteRecipe(kind, id) {
|
|
|
26
26
|
{ x: 0, z: 43 }
|
|
27
27
|
]
|
|
28
28
|
};
|
|
29
|
+
case 'pyramid':
|
|
30
|
+
/* A tetrahedron: the drawn triangle's, drawn up to one point over its middle. */
|
|
31
|
+
return {
|
|
32
|
+
...standing(100),
|
|
33
|
+
kind,
|
|
34
|
+
dimensions: { height: 100 },
|
|
35
|
+
points: [
|
|
36
|
+
{ x: -50, z: -43 },
|
|
37
|
+
{ x: 50, z: -43 },
|
|
38
|
+
{ x: 0, z: 43 }
|
|
39
|
+
],
|
|
40
|
+
apex: { x: 0, z: 0 }
|
|
41
|
+
};
|
|
29
42
|
case 'plate':
|
|
30
43
|
return { ...standing(10), kind: 'box', dimensions: { width: 600, height: 10, depth: 400 } };
|
|
31
44
|
case 'wall':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"palette.js","sourceRoot":"","sources":["../../client/modeller/palette.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FigurePrimitiveCreation } from '@hatiolab/figure-model'\n\nimport type { FigurePaletteKind } from './figure-parts.js'\n\n/**\n * What a palette button makes: the part at a starting size a person then changes. Standing on the floor (its lowest\n * point at y 0) where the provider's frame is centred; a portal's frame already rises from its bottom.\n */\nexport function paletteRecipe(kind: FigurePaletteKind, id: string): FigurePrimitiveCreation {\n const standing = (height: number) => ({ id, position: { x: 0, y: height / 2, z: 0 } })\n switch (kind) {\n case 'box':\n return { ...standing(100), kind, dimensions: { width: 100, height: 100, depth: 100 } }\n case 'cylinder':\n return { ...standing(100), kind, dimensions: { radius: 50, length: 100 } }\n case 'rounded-box':\n return { ...standing(100), kind, dimensions: { width: 100, height: 100, depth: 100, round: 10 } }\n case 'sphere':\n return { ...standing(100), kind, dimensions: { radiusX: 50, radiusY: 50, radiusZ: 50 } }\n case 'frustum':\n return { ...standing(100), kind, dimensions: { radiusTop: 0, radiusBottom: 50, height: 100 } }\n case 'polygon':\n return {\n ...standing(100),\n kind,\n dimensions: { height: 100 },\n points: [\n { x: -50, z: -43 },\n { x: 50, z: -43 },\n { x: 0, z: 43 }\n ]\n }\n case 'plate':\n return { ...standing(10), kind: 'box', dimensions: { width: 600, height: 10, depth: 400 } }\n case 'wall':\n return { ...standing(2400), kind: 'box', dimensions: { width: 1000, height: 2400, depth: 100 } }\n case 'hollow-box':\n /* A tote at a tote's size: walls and floor that keep their thickness when it grows. */\n return { ...standing(300), kind: 'hollow-box', dimensions: { width: 600, height: 300, depth: 400, roundX: 20, roundZ: 20, wallX: 10, wallZ: 10, floor: 15 } }\n case 'portal':\n return {\n id,\n position: { x: 0, y: 0, z: 0 },\n kind: 'portal',\n /* A door frame at a door's size, as a wall is a wall's: its width, height, depth and the jambs' and head's thickness. */\n dimensions: { width: 1000, height: 2200, depth: 150, jamb: 100, head: 100 }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"palette.js","sourceRoot":"","sources":["../../client/modeller/palette.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FigurePrimitiveCreation } from '@hatiolab/figure-model'\n\nimport type { FigurePaletteKind } from './figure-parts.js'\n\n/**\n * What a palette button makes: the part at a starting size a person then changes. Standing on the floor (its lowest\n * point at y 0) where the provider's frame is centred; a portal's frame already rises from its bottom.\n */\nexport function paletteRecipe(kind: FigurePaletteKind, id: string): FigurePrimitiveCreation {\n const standing = (height: number) => ({ id, position: { x: 0, y: height / 2, z: 0 } })\n switch (kind) {\n case 'box':\n return { ...standing(100), kind, dimensions: { width: 100, height: 100, depth: 100 } }\n case 'cylinder':\n return { ...standing(100), kind, dimensions: { radius: 50, length: 100 } }\n case 'rounded-box':\n return { ...standing(100), kind, dimensions: { width: 100, height: 100, depth: 100, round: 10 } }\n case 'sphere':\n return { ...standing(100), kind, dimensions: { radiusX: 50, radiusY: 50, radiusZ: 50 } }\n case 'frustum':\n return { ...standing(100), kind, dimensions: { radiusTop: 0, radiusBottom: 50, height: 100 } }\n case 'polygon':\n return {\n ...standing(100),\n kind,\n dimensions: { height: 100 },\n points: [\n { x: -50, z: -43 },\n { x: 50, z: -43 },\n { x: 0, z: 43 }\n ]\n }\n case 'pyramid':\n /* A tetrahedron: the drawn triangle's, drawn up to one point over its middle. */\n return {\n ...standing(100),\n kind,\n dimensions: { height: 100 },\n points: [\n { x: -50, z: -43 },\n { x: 50, z: -43 },\n { x: 0, z: 43 }\n ],\n apex: { x: 0, z: 0 }\n }\n case 'plate':\n return { ...standing(10), kind: 'box', dimensions: { width: 600, height: 10, depth: 400 } }\n case 'wall':\n return { ...standing(2400), kind: 'box', dimensions: { width: 1000, height: 2400, depth: 100 } }\n case 'hollow-box':\n /* A tote at a tote's size: walls and floor that keep their thickness when it grows. */\n return { ...standing(300), kind: 'hollow-box', dimensions: { width: 600, height: 300, depth: 400, roundX: 20, roundZ: 20, wallX: 10, wallZ: 10, floor: 15 } }\n case 'portal':\n return {\n id,\n position: { x: 0, y: 0, z: 0 },\n kind: 'portal',\n /* A door frame at a door's size, as a wall is a wall's: its width, height, depth and the jambs' and head's thickness. */\n dimensions: { width: 1000, height: 2200, depth: 150, jamb: 100, head: 100 }\n }\n }\n}\n"]}
|
|
@@ -36,7 +36,19 @@ export interface SectionWorking {
|
|
|
36
36
|
/** Along each plane axis: a rectangle's size, an ellipse's diameter. Empty for a drawn section. */
|
|
37
37
|
across: Partial<Record<Axis, number>>;
|
|
38
38
|
length: number;
|
|
39
|
+
/** A drawn section's end drawn to one point (a pyramid), across the plane axes; null for a push. */
|
|
40
|
+
apex: Partial<Record<Axis, number>> | null;
|
|
39
41
|
}
|
|
42
|
+
/** A pushed part's section, axis and ends -- or a pyramid's, whose end is its apex (figure-model `loft@1`). */
|
|
43
|
+
export declare function drawnOf(shape: FigureEvaluatedShape): {
|
|
44
|
+
axis: Axis;
|
|
45
|
+
section: FigureSection;
|
|
46
|
+
start: number;
|
|
47
|
+
end: number;
|
|
48
|
+
apex: Partial<Record<Axis, number>> | null;
|
|
49
|
+
} | undefined;
|
|
50
|
+
/** Where a new apex goes: over the middle of the points' span, whole millimetres. */
|
|
51
|
+
export declare function apexOver(points: Points, axis: Axis): Partial<Record<Axis, number>>;
|
|
40
52
|
/** The working state of a pushed part as it stands. */
|
|
41
53
|
export declare function workingOf(shape: FigureEvaluatedShape): SectionWorking;
|
|
42
54
|
/** The section the working state makes, of the part's own kind: its corners kept, its points or widths the working ones. */
|
|
@@ -81,9 +81,23 @@ export function extentOf(points, axis) {
|
|
|
81
81
|
return Math.ceil((far * 1.4 + 40) / 50) * 50;
|
|
82
82
|
}
|
|
83
83
|
export const POINT_LIMIT = FIGURE_SECTION_POINT_LIMIT;
|
|
84
|
+
/** A pushed part's section, axis and ends -- or a pyramid's, whose end is its apex (figure-model `loft@1`). */
|
|
85
|
+
export function drawnOf(shape) {
|
|
86
|
+
if (shape.extrusion)
|
|
87
|
+
return { ...shape.extrusion, apex: null };
|
|
88
|
+
if (shape.loft)
|
|
89
|
+
return { ...shape.loft, apex: shape.loft.apex };
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
/** Where a new apex goes: over the middle of the points' span, whole millimetres. */
|
|
93
|
+
export function apexOver(points, axis) {
|
|
94
|
+
const [u, v] = FIGURE_SECTION_PLANE[axis];
|
|
95
|
+
const mid = (x) => Math.round((Math.min(...points.map(p => p[x])) + Math.max(...points.map(p => p[x]))) / 2);
|
|
96
|
+
return { [u]: mid(u), [v]: mid(v) };
|
|
97
|
+
}
|
|
84
98
|
/** The working state of a pushed part as it stands. */
|
|
85
99
|
export function workingOf(shape) {
|
|
86
|
-
const e = shape
|
|
100
|
+
const e = drawnOf(shape);
|
|
87
101
|
const s = e.section;
|
|
88
102
|
const [u, v] = FIGURE_SECTION_PLANE[e.axis];
|
|
89
103
|
const across = s.kind === 'rectangle'
|
|
@@ -91,12 +105,13 @@ export function workingOf(shape) {
|
|
|
91
105
|
: s.kind === 'ellipse'
|
|
92
106
|
? { [u]: 2 * s.radius[u], [v]: 2 * s.radius[v] }
|
|
93
107
|
: {};
|
|
94
|
-
return { points: s.kind === 'polygon' ? s.points.map(p => ({ ...p })) : [], across, length: e.end - e.start };
|
|
108
|
+
return { points: s.kind === 'polygon' ? s.points.map(p => ({ ...p })) : [], across, length: e.end - e.start, apex: e.apex ? { ...e.apex } : null };
|
|
95
109
|
}
|
|
96
110
|
/** The section the working state makes, of the part's own kind: its corners kept, its points or widths the working ones. */
|
|
97
111
|
export function sectionOf(shape, w) {
|
|
98
|
-
const
|
|
99
|
-
const
|
|
112
|
+
const e = drawnOf(shape);
|
|
113
|
+
const s = e.section;
|
|
114
|
+
const [u, v] = FIGURE_SECTION_PLANE[e.axis];
|
|
100
115
|
if (s.kind === 'polygon')
|
|
101
116
|
return { kind: 'polygon', points: w.points };
|
|
102
117
|
if (s.kind === 'ellipse')
|
|
@@ -105,12 +120,14 @@ export function sectionOf(shape, w) {
|
|
|
105
120
|
}
|
|
106
121
|
/** What would be refused, as words, with the section's own issues for marking points and sides. By the kernel's checks. */
|
|
107
122
|
export function workingIssuesOf(shape, w) {
|
|
108
|
-
const e = shape
|
|
123
|
+
const e = drawnOf(shape);
|
|
109
124
|
const section = sectionOf(shape, w);
|
|
110
125
|
const issues = checkFigureSection(section, e.axis);
|
|
111
126
|
const words = issues.map(i => issueWords(i, w.points, e.axis));
|
|
112
127
|
if (!(Number.isFinite(w.length) && w.length > 0))
|
|
113
128
|
words.push({ key: 'figure.text.section-issue-length', params: {} });
|
|
129
|
+
if (w.apex && !Object.values(w.apex).every(n => Number.isFinite(n)))
|
|
130
|
+
words.push({ key: 'figure.text.section-issue-number', params: {} });
|
|
114
131
|
if (!issues.length && words.length === 0 && shape.cavity) {
|
|
115
132
|
const made = figureExtrusionFeaturesOf({ axis: e.axis, section, start: e.start, end: e.start + w.length }, [shape.cavity]);
|
|
116
133
|
if ('refused' in made) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-drawing.js","sourceRoot":"","sources":["../../client/modeller/section-drawing.ts"],"names":[],"mappings":"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","sourcesContent":["import { FIGURE_SECTION_PLANE, FIGURE_SECTION_POINT_LIMIT, checkFigureSection, figureExtrusionFeaturesOf, figureSectionSidesOf } from '@hatiolab/figure-model'\nimport type { FigureEvaluatedShape, FigureSection, FigureSectionIssue, FigureSectionPoint } from '@hatiolab/figure-model'\n\n/*\n * What the section editor does to a drawn section's points, and how it says what is wrong with them (ADR-0100 §3.2).\n * The points are the kernel's own (`{ id, x, z }` for a push along Y), their validity is the kernel's own check, and a\n * point's number on screen is its own name's number (Q9): p3 is 「3」 before and after any edit, and deleting it leaves\n * 1, 2 and 4.\n */\n\ntype Axis = 'x' | 'y' | 'z'\nexport type Points = readonly FigureSectionPoint[]\n\n/** The number a point is shown by: its name's number. */\nexport const pointLabel = (id: string) => /^p(\\d+)$/.exec(id)?.[1] ?? id\n\n/** The next point's name: one past the highest number the loop has, so a new point never takes a gap's number. */\nexport function nextPointId(points: Points): string {\n return `p${Math.max(0, ...points.map(p => Number(/^p(\\d+)$/.exec(p.id)?.[1] ?? 0))) + 1}`\n}\n\n/** A point in the middle of the side from `from` to the point after it, whole millimetres; the new point's id with it. */\nexport function insertAfter(points: Points, from: string, axis: Axis): { points: FigureSectionPoint[]; id: string } {\n const [u, v] = FIGURE_SECTION_PLANE[axis]\n const i = points.findIndex(p => p.id === from)\n const a = points[i]!,\n b = points[(i + 1) % points.length]!\n const id = nextPointId(points)\n const mid = { id, [u]: Math.round((a[u]! + b[u]!) / 2), [v]: Math.round((a[v]! + b[v]!) / 2) } as FigureSectionPoint\n return { points: [...points.slice(0, i + 1), mid, ...points.slice(i + 1)], id }\n}\n\n/** The points less one, or why not: a section is three points or more. */\nexport function removePoint(points: Points, id: string): FigureSectionPoint[] | { refused: 'too-few' } {\n if (points.length <= 3) return { refused: 'too-few' }\n return points.filter(p => p.id !== id)\n}\n\nexport function movePoint(points: Points, id: string, at: Partial<Record<Axis, number>>): FigureSectionPoint[] {\n return points.map(p => (p.id === id ? { ...p, ...at } : p))\n}\n\n/** What is wrong with the points, by the kernel's own check. */\nexport const issuesOf = (points: Points, axis: Axis) => checkFigureSection({ kind: 'polygon', points: [...points] }, axis)\n\n/** A side said in the loop's order, 3–4 not 4–3: its id is the pair in name order, which a person never sees. */\nfunction sideLabel(points: Points, axis: Axis, side: string): string {\n const s = figureSectionSidesOf({ kind: 'polygon', points: [...points] }, axis).find(x => x.id === side)\n const [a, b] = s?.from ? [s.from, s.to!] : side.split('~')\n return `${pointLabel(a!)}–${pointLabel(b!)}`\n}\n\n/** An issue as the words that say it: an i18n key and its values. */\nexport function issueWords(issue: FigureSectionIssue, points: Points, axis: Axis): { key: string; params: Record<string, string> } {\n const line = (s: string) => sideLabel(points, axis, s)\n switch (issue.code) {\n case 'SIDES_CROSS':\n return { key: 'figure.text.section-issue-cross', params: { a: line(issue.sides[0]), b: line(issue.sides[1]) } }\n case 'SIDES_TOUCH':\n return { key: 'figure.text.section-issue-touch', params: { a: line(issue.sides[0]), b: line(issue.sides[1]) } }\n case 'SIDES_FOLD':\n return { key: 'figure.text.section-issue-fold', params: { a: line(issue.sides[0]), b: line(issue.sides[1]) } }\n case 'ZERO_LENGTH_SIDE':\n return { key: 'figure.text.section-issue-zero-length', params: { a: line(issue.side) } }\n case 'ZERO_AREA':\n return { key: 'figure.text.section-issue-zero-area', params: {} }\n case 'TOO_FEW_POINTS':\n return { key: 'figure.text.section-issue-too-few', params: {} }\n case 'TOO_MANY_POINTS':\n return { key: 'figure.text.section-issue-too-many', params: { limit: String(issue.limit) } }\n case 'CORNER_TOO_LARGE':\n return { key: 'figure.text.section-issue-corner', params: { max: String(Math.round(issue.max * 1000) / 1000) } }\n default:\n return { key: 'figure.text.section-issue-number', params: {} }\n }\n}\n\n/** Every side and point an issue names, to mark on the drawing -- by more than colour: the list says them too. */\nexport function markedBy(issues: readonly FigureSectionIssue[]): { sides: Set<string>; points: Set<string> } {\n const sides = new Set<string>(),\n points = new Set<string>()\n for (const i of issues) {\n if ('sides' in i) for (const s of i.sides) sides.add(s)\n if ('side' in i) sides.add(i.side)\n if ('point' in i) points.add(i.point)\n if ('at' in i) points.add(String(i.at).split('.')[0]!)\n }\n for (const s of sides) for (const p of s.split('~')) points.add(p)\n return { sides, points }\n}\n\n/** How far the drawing reaches from the origin: the points' farthest coordinate with room around, in 50 mm steps. */\nexport function extentOf(points: Points, axis: Axis): number {\n const [u, v] = FIGURE_SECTION_PLANE[axis]\n const far = Math.max(1, ...points.flatMap(p => [Math.abs(p[u] ?? 0), Math.abs(p[v] ?? 0)]))\n return Math.ceil((far * 1.4 + 40) / 50) * 50\n}\n\nexport const POINT_LIMIT = FIGURE_SECTION_POINT_LIMIT\n\n/** What the section editor holds while it is open: the points of a drawn section, the widths across, the length. */\nexport interface SectionWorking {\n points: FigureSectionPoint[]\n /** Along each plane axis: a rectangle's size, an ellipse's diameter. Empty for a drawn section. */\n across: Partial<Record<Axis, number>>\n length: number\n}\n\n/** The working state of a pushed part as it stands. */\nexport function workingOf(shape: FigureEvaluatedShape): SectionWorking {\n const e = shape.extrusion!\n const s = e.section\n const [u, v] = FIGURE_SECTION_PLANE[e.axis]\n const across =\n s.kind === 'rectangle'\n ? { [u]: s.size[u]!, [v]: s.size[v]! }\n : s.kind === 'ellipse'\n ? { [u]: 2 * s.radius[u]!, [v]: 2 * s.radius[v]! }\n : {}\n return { points: s.kind === 'polygon' ? s.points.map(p => ({ ...p })) : [], across, length: e.end - e.start }\n}\n\n/** The section the working state makes, of the part's own kind: its corners kept, its points or widths the working ones. */\nexport function sectionOf(shape: FigureEvaluatedShape, w: SectionWorking): FigureSection {\n const s = shape.extrusion!.section\n const [u, v] = FIGURE_SECTION_PLANE[shape.extrusion!.axis]\n if (s.kind === 'polygon') return { kind: 'polygon', points: w.points }\n if (s.kind === 'ellipse') return { kind: 'ellipse', radius: { [u]: w.across[u]! / 2, [v]: w.across[v]! / 2 } }\n return { kind: 'rectangle', size: { [u]: w.across[u]!, [v]: w.across[v]! }, ...(s.corner ? { corner: s.corner } : {}) }\n}\n\n/** What would be refused, as words, with the section's own issues for marking points and sides. By the kernel's checks. */\nexport function workingIssuesOf(\n shape: FigureEvaluatedShape,\n w: SectionWorking\n): { issues: FigureSectionIssue[]; words: Array<{ key: string; params: Record<string, string> }> } {\n const e = shape.extrusion!\n const section = sectionOf(shape, w)\n const issues = checkFigureSection(section, e.axis)\n const words = issues.map(i => issueWords(i, w.points, e.axis))\n if (!(Number.isFinite(w.length) && w.length > 0)) words.push({ key: 'figure.text.section-issue-length', params: {} })\n if (!issues.length && words.length === 0 && shape.cavity) {\n const made = figureExtrusionFeaturesOf({ axis: e.axis, section, start: e.start, end: e.start + w.length }, [shape.cavity])\n if ('refused' in made) {\n const r = made.refused\n words.push({ key: r.code === 'CAVITY_NO_LENGTH' ? 'figure.text.section-issue-cavity-length' : 'figure.text.section-issue-cavity-walls', params: {} })\n }\n }\n return { issues, words }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"section-drawing.js","sourceRoot":"","sources":["../../client/modeller/section-drawing.ts"],"names":[],"mappings":"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","sourcesContent":["import { FIGURE_SECTION_PLANE, FIGURE_SECTION_POINT_LIMIT, checkFigureSection, figureExtrusionFeaturesOf, figureSectionSidesOf } from '@hatiolab/figure-model'\nimport type { FigureEvaluatedShape, FigureSection, FigureSectionIssue, FigureSectionPoint } from '@hatiolab/figure-model'\n\n/*\n * What the section editor does to a drawn section's points, and how it says what is wrong with them (ADR-0100 §3.2).\n * The points are the kernel's own (`{ id, x, z }` for a push along Y), their validity is the kernel's own check, and a\n * point's number on screen is its own name's number (Q9): p3 is 「3」 before and after any edit, and deleting it leaves\n * 1, 2 and 4.\n */\n\ntype Axis = 'x' | 'y' | 'z'\nexport type Points = readonly FigureSectionPoint[]\n\n/** The number a point is shown by: its name's number. */\nexport const pointLabel = (id: string) => /^p(\\d+)$/.exec(id)?.[1] ?? id\n\n/** The next point's name: one past the highest number the loop has, so a new point never takes a gap's number. */\nexport function nextPointId(points: Points): string {\n return `p${Math.max(0, ...points.map(p => Number(/^p(\\d+)$/.exec(p.id)?.[1] ?? 0))) + 1}`\n}\n\n/** A point in the middle of the side from `from` to the point after it, whole millimetres; the new point's id with it. */\nexport function insertAfter(points: Points, from: string, axis: Axis): { points: FigureSectionPoint[]; id: string } {\n const [u, v] = FIGURE_SECTION_PLANE[axis]\n const i = points.findIndex(p => p.id === from)\n const a = points[i]!,\n b = points[(i + 1) % points.length]!\n const id = nextPointId(points)\n const mid = { id, [u]: Math.round((a[u]! + b[u]!) / 2), [v]: Math.round((a[v]! + b[v]!) / 2) } as FigureSectionPoint\n return { points: [...points.slice(0, i + 1), mid, ...points.slice(i + 1)], id }\n}\n\n/** The points less one, or why not: a section is three points or more. */\nexport function removePoint(points: Points, id: string): FigureSectionPoint[] | { refused: 'too-few' } {\n if (points.length <= 3) return { refused: 'too-few' }\n return points.filter(p => p.id !== id)\n}\n\nexport function movePoint(points: Points, id: string, at: Partial<Record<Axis, number>>): FigureSectionPoint[] {\n return points.map(p => (p.id === id ? { ...p, ...at } : p))\n}\n\n/** What is wrong with the points, by the kernel's own check. */\nexport const issuesOf = (points: Points, axis: Axis) => checkFigureSection({ kind: 'polygon', points: [...points] }, axis)\n\n/** A side said in the loop's order, 3–4 not 4–3: its id is the pair in name order, which a person never sees. */\nfunction sideLabel(points: Points, axis: Axis, side: string): string {\n const s = figureSectionSidesOf({ kind: 'polygon', points: [...points] }, axis).find(x => x.id === side)\n const [a, b] = s?.from ? [s.from, s.to!] : side.split('~')\n return `${pointLabel(a!)}–${pointLabel(b!)}`\n}\n\n/** An issue as the words that say it: an i18n key and its values. */\nexport function issueWords(issue: FigureSectionIssue, points: Points, axis: Axis): { key: string; params: Record<string, string> } {\n const line = (s: string) => sideLabel(points, axis, s)\n switch (issue.code) {\n case 'SIDES_CROSS':\n return { key: 'figure.text.section-issue-cross', params: { a: line(issue.sides[0]), b: line(issue.sides[1]) } }\n case 'SIDES_TOUCH':\n return { key: 'figure.text.section-issue-touch', params: { a: line(issue.sides[0]), b: line(issue.sides[1]) } }\n case 'SIDES_FOLD':\n return { key: 'figure.text.section-issue-fold', params: { a: line(issue.sides[0]), b: line(issue.sides[1]) } }\n case 'ZERO_LENGTH_SIDE':\n return { key: 'figure.text.section-issue-zero-length', params: { a: line(issue.side) } }\n case 'ZERO_AREA':\n return { key: 'figure.text.section-issue-zero-area', params: {} }\n case 'TOO_FEW_POINTS':\n return { key: 'figure.text.section-issue-too-few', params: {} }\n case 'TOO_MANY_POINTS':\n return { key: 'figure.text.section-issue-too-many', params: { limit: String(issue.limit) } }\n case 'CORNER_TOO_LARGE':\n return { key: 'figure.text.section-issue-corner', params: { max: String(Math.round(issue.max * 1000) / 1000) } }\n default:\n return { key: 'figure.text.section-issue-number', params: {} }\n }\n}\n\n/** Every side and point an issue names, to mark on the drawing -- by more than colour: the list says them too. */\nexport function markedBy(issues: readonly FigureSectionIssue[]): { sides: Set<string>; points: Set<string> } {\n const sides = new Set<string>(),\n points = new Set<string>()\n for (const i of issues) {\n if ('sides' in i) for (const s of i.sides) sides.add(s)\n if ('side' in i) sides.add(i.side)\n if ('point' in i) points.add(i.point)\n if ('at' in i) points.add(String(i.at).split('.')[0]!)\n }\n for (const s of sides) for (const p of s.split('~')) points.add(p)\n return { sides, points }\n}\n\n/** How far the drawing reaches from the origin: the points' farthest coordinate with room around, in 50 mm steps. */\nexport function extentOf(points: Points, axis: Axis): number {\n const [u, v] = FIGURE_SECTION_PLANE[axis]\n const far = Math.max(1, ...points.flatMap(p => [Math.abs(p[u] ?? 0), Math.abs(p[v] ?? 0)]))\n return Math.ceil((far * 1.4 + 40) / 50) * 50\n}\n\nexport const POINT_LIMIT = FIGURE_SECTION_POINT_LIMIT\n\n/** What the section editor holds while it is open: the points of a drawn section, the widths across, the length. */\nexport interface SectionWorking {\n points: FigureSectionPoint[]\n /** Along each plane axis: a rectangle's size, an ellipse's diameter. Empty for a drawn section. */\n across: Partial<Record<Axis, number>>\n length: number\n /** A drawn section's end drawn to one point (a pyramid), across the plane axes; null for a push. */\n apex: Partial<Record<Axis, number>> | null\n}\n\n/** A pushed part's section, axis and ends -- or a pyramid's, whose end is its apex (figure-model `loft@1`). */\nexport function drawnOf(shape: FigureEvaluatedShape):\n | { axis: Axis; section: FigureSection; start: number; end: number; apex: Partial<Record<Axis, number>> | null }\n | undefined {\n if (shape.extrusion) return { ...shape.extrusion, apex: null }\n if (shape.loft) return { ...shape.loft, apex: shape.loft.apex }\n return undefined\n}\n\n/** Where a new apex goes: over the middle of the points' span, whole millimetres. */\nexport function apexOver(points: Points, axis: Axis): Partial<Record<Axis, number>> {\n const [u, v] = FIGURE_SECTION_PLANE[axis]\n const mid = (x: Axis) => Math.round((Math.min(...points.map(p => p[x]!)) + Math.max(...points.map(p => p[x]!))) / 2)\n return { [u]: mid(u), [v]: mid(v) }\n}\n\n/** The working state of a pushed part as it stands. */\nexport function workingOf(shape: FigureEvaluatedShape): SectionWorking {\n const e = drawnOf(shape)!\n const s = e.section\n const [u, v] = FIGURE_SECTION_PLANE[e.axis]\n const across =\n s.kind === 'rectangle'\n ? { [u]: s.size[u]!, [v]: s.size[v]! }\n : s.kind === 'ellipse'\n ? { [u]: 2 * s.radius[u]!, [v]: 2 * s.radius[v]! }\n : {}\n return { points: s.kind === 'polygon' ? s.points.map(p => ({ ...p })) : [], across, length: e.end - e.start, apex: e.apex ? { ...e.apex } : null }\n}\n\n/** The section the working state makes, of the part's own kind: its corners kept, its points or widths the working ones. */\nexport function sectionOf(shape: FigureEvaluatedShape, w: SectionWorking): FigureSection {\n const e = drawnOf(shape)!\n const s = e.section\n const [u, v] = FIGURE_SECTION_PLANE[e.axis]\n if (s.kind === 'polygon') return { kind: 'polygon', points: w.points }\n if (s.kind === 'ellipse') return { kind: 'ellipse', radius: { [u]: w.across[u]! / 2, [v]: w.across[v]! / 2 } }\n return { kind: 'rectangle', size: { [u]: w.across[u]!, [v]: w.across[v]! }, ...(s.corner ? { corner: s.corner } : {}) }\n}\n\n/** What would be refused, as words, with the section's own issues for marking points and sides. By the kernel's checks. */\nexport function workingIssuesOf(\n shape: FigureEvaluatedShape,\n w: SectionWorking\n): { issues: FigureSectionIssue[]; words: Array<{ key: string; params: Record<string, string> }> } {\n const e = drawnOf(shape)!\n const section = sectionOf(shape, w)\n const issues = checkFigureSection(section, e.axis)\n const words = issues.map(i => issueWords(i, w.points, e.axis))\n if (!(Number.isFinite(w.length) && w.length > 0)) words.push({ key: 'figure.text.section-issue-length', params: {} })\n if (w.apex && !Object.values(w.apex).every(n => Number.isFinite(n))) words.push({ key: 'figure.text.section-issue-number', params: {} })\n if (!issues.length && words.length === 0 && shape.cavity) {\n const made = figureExtrusionFeaturesOf({ axis: e.axis, section, start: e.start, end: e.start + w.length }, [shape.cavity])\n if ('refused' in made) {\n const r = made.refused\n words.push({ key: r.code === 'CAVITY_NO_LENGTH' ? 'figure.text.section-issue-cavity-length' : 'figure.text.section-issue-cavity-walls', params: {} })\n }\n }\n return { issues, words }\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a person calls a part's shape (ADR-0100 §2.1): the starting shape it reads as -- 상자, 둥근 상자, 위가 열린 상자,
|
|
3
|
-
* 원기둥, 문틀, 구, 원뿔, 그린
|
|
3
|
+
* 원기둥, 문틀, 구, 원뿔, 그린 단면, 뿔. A word for the screen, read from the shape node's own params; it is not a kind of
|
|
4
4
|
* stored shape, and nothing is decided by it.
|
|
5
5
|
*/
|
|
6
|
-
export type StartingShapeKind = 'cube' | 'rounded-box' | 'hollow-box' | 'cylinder' | 'portal' | 'sphere' | 'frustum' | 'polygon';
|
|
6
|
+
export type StartingShapeKind = 'cube' | 'rounded-box' | 'hollow-box' | 'cylinder' | 'portal' | 'sphere' | 'frustum' | 'polygon' | 'pyramid';
|
|
7
7
|
export declare function startingShapeKindOf(shape: {
|
|
8
8
|
op: string;
|
|
9
9
|
params?: Record<string, unknown>;
|
|
@@ -27,6 +27,7 @@ export declare function startingShapeKindOfBody(shape: {
|
|
|
27
27
|
kind: string;
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
|
+
loft?: unknown;
|
|
30
31
|
} | undefined): StartingShapeKind | undefined;
|
|
31
32
|
/** Whether a body is round across -- a circle or an ellipse pushed, anything turned: it takes a segment count. */
|
|
32
33
|
export declare const isRoundBody: (shape: Parameters<typeof startingShapeKindOfBody>[0]) => boolean;
|
|
@@ -2,6 +2,8 @@ export function startingShapeKindOf(shape) {
|
|
|
2
2
|
const p = shape?.params ?? {};
|
|
3
3
|
if (shape?.op === 'revolve@1')
|
|
4
4
|
return p.profile === 'taper' ? 'frustum' : 'sphere';
|
|
5
|
+
if (shape?.op === 'loft@1')
|
|
6
|
+
return 'pyramid';
|
|
5
7
|
if (shape?.op !== 'extrude@1')
|
|
6
8
|
return undefined;
|
|
7
9
|
if (p.section === 'ellipse')
|
|
@@ -19,6 +21,8 @@ export function startingShapeKindOf(shape) {
|
|
|
19
21
|
* a door frame is the section with jambs, a drawn section the rest of the drawn ones.
|
|
20
22
|
*/
|
|
21
23
|
export function startingShapeKindOfBody(shape) {
|
|
24
|
+
if (shape?.loft)
|
|
25
|
+
return 'pyramid';
|
|
22
26
|
if (shape?.revolution)
|
|
23
27
|
return shape.revolution.profile.kind === 'taper' ? 'frustum' : 'sphere';
|
|
24
28
|
const s = shape?.extrusion?.section;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"starting-shape.js","sourceRoot":"","sources":["../../client/modeller/starting-shape.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,mBAAmB,CAAC,KAAmE;IACrG,MAAM,CAAC,GAAG,KAAK,EAAE,MAAM,IAAI,EAAE,CAAA;IAC7B,IAAI,KAAK,EAAE,EAAE,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAA;IAClF,IAAI,KAAK,EAAE,EAAE,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA;IAC/C,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,UAAU,CAAA;IAC9C,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC7C,IAAI,CAAC,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAC3C,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,YAAY,CAAA;IACjC,OAAO,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAA;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,
|
|
1
|
+
{"version":3,"file":"starting-shape.js","sourceRoot":"","sources":["../../client/modeller/starting-shape.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,mBAAmB,CAAC,KAAmE;IACrG,MAAM,CAAC,GAAG,KAAK,EAAE,MAAM,IAAI,EAAE,CAAA;IAC7B,IAAI,KAAK,EAAE,EAAE,KAAK,WAAW;QAAE,OAAO,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAA;IAClF,IAAI,KAAK,EAAE,EAAE,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC5C,IAAI,KAAK,EAAE,EAAE,KAAK,WAAW;QAAE,OAAO,SAAS,CAAA;IAC/C,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,UAAU,CAAA;IAC9C,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC7C,IAAI,CAAC,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAC3C,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,YAAY,CAAA;IACjC,OAAO,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAA;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAwN;IAC9P,IAAI,KAAK,EAAE,IAAI;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,KAAK,EAAE,UAAU;QAAE,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC9F,MAAM,CAAC,GAAG,KAAK,EAAE,SAAS,EAAE,OAAO,CAAA;IACnC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IACxB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,UAAU,CAAA;IAC3C,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAM,CAAC,UAAU,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7F,IAAI,KAAM,CAAC,MAAM;QAAE,OAAO,YAAY,CAAA;IACtC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAA;AAC1C,CAAC;AAED,kHAAkH;AAClH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAoD,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA","sourcesContent":["/**\n * What a person calls a part's shape (ADR-0100 §2.1): the starting shape it reads as -- 상자, 둥근 상자, 위가 열린 상자,\n * 원기둥, 문틀, 구, 원뿔, 그린 단면, 뿔. A word for the screen, read from the shape node's own params; it is not a kind of\n * stored shape, and nothing is decided by it.\n */\nexport type StartingShapeKind = 'cube' | 'rounded-box' | 'hollow-box' | 'cylinder' | 'portal' | 'sphere' | 'frustum' | 'polygon' | 'pyramid'\n\nexport function startingShapeKindOf(shape: { op: string; params?: Record<string, unknown> } | undefined): StartingShapeKind | undefined {\n const p = shape?.params ?? {}\n if (shape?.op === 'revolve@1') return p.profile === 'taper' ? 'frustum' : 'sphere'\n if (shape?.op === 'loft@1') return 'pyramid'\n if (shape?.op !== 'extrude@1') return undefined\n if (p.section === 'ellipse') return 'cylinder'\n if (p.section === 'polygon') return 'polygon'\n if (p.section === 'portal') return 'portal'\n if (p.cavity) return 'hollow-box'\n return p.corner === 'round' ? 'rounded-box' : 'cube'\n}\n\n/**\n * The same word for an evaluated body, when only the shape the kernel evaluated is in hand (a row of the parts list):\n * a door frame is the section with jambs, a drawn section the rest of the drawn ones.\n */\nexport function startingShapeKindOfBody(shape: { provider?: string; dimensions?: Record<string, number>; extrusion?: { section: { kind: string; corner?: unknown } }; cavity?: unknown; revolution?: { profile: { kind: string } }; loft?: unknown } | undefined): StartingShapeKind | undefined {\n if (shape?.loft) return 'pyramid'\n if (shape?.revolution) return shape.revolution.profile.kind === 'taper' ? 'frustum' : 'sphere'\n const s = shape?.extrusion?.section\n if (!s) return undefined\n if (s.kind === 'ellipse') return 'cylinder'\n if (s.kind === 'polygon') return shape!.dimensions?.jamb !== undefined ? 'portal' : 'polygon'\n if (shape!.cavity) return 'hollow-box'\n return s.corner ? 'rounded-box' : 'cube'\n}\n\n/** Whether a body is round across -- a circle or an ellipse pushed, anything turned: it takes a segment count. */\nexport const isRoundBody = (shape: Parameters<typeof startingShapeKindOfBody>[0]) => ['cylinder', 'sphere', 'frustum'].includes(startingShapeKindOfBody(shape) ?? '')\n"]}
|
package/dist-client/route.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function route(page: string): "figure-
|
|
1
|
+
export default function route(page: string): "figure-modeller" | "figure-list" | undefined;
|