@things-factory/figure-ui 10.1.86 → 10.1.87

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/figure-ui",
3
- "version": "10.1.86",
3
+ "version": "10.1.87",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "@things-factory:registry": "https://registry.npmjs.org"
@@ -27,7 +27,7 @@
27
27
  "clean": "npm run clean:server && npm run clean:client"
28
28
  },
29
29
  "dependencies": {
30
- "@hatiolab/figure-model": "^0.2.2",
30
+ "@hatiolab/figure-model": "^0.2.3",
31
31
  "@hatiolab/things-scene": "^10.1.63",
32
32
  "@material/web": "^2.0.0",
33
33
  "@operato/data-grist": "^10.0.0",
@@ -40,9 +40,9 @@
40
40
  "@operato/shell": "^10.0.0",
41
41
  "@operato/styles": "^10.0.0",
42
42
  "@operato/utils": "^10.0.0",
43
- "@things-factory/ai-assistant": "^10.1.81",
43
+ "@things-factory/ai-assistant": "^10.1.87",
44
44
  "@things-factory/figure-service": "^10.1.84",
45
45
  "three": "^0.185.1"
46
46
  },
47
- "gitHead": "8e56ed31b1c81934257f2938b9b1a51f1852773f"
47
+ "gitHead": "dc552c2a7b7f97e3377a26c378ee15d3a1de612a"
48
48
  }
@@ -40,7 +40,7 @@ const pointsOf = (asset: FigureAsset) => {
40
40
  return s.kind === 'polygon' ? s.points : []
41
41
  }
42
42
  const apply = (asset: FigureAsset, points: readonly FigureSectionPoint[]) =>
43
- applyFigureAuthoring(asset, { kind: 'set-section-points', part: 'wedge', points: [...points] })
43
+ applyFigureAuthoring(asset, { kind: 'set-section', part: 'wedge', points: [...points] })
44
44
 
45
45
  test('삼각형 → 사다리꼴: 선을 눌러 점을 더하고 옮기면, 한 명령으로 들어가고 옛 점은 제 번호를 지킨다', () => {
46
46
  const t = triangle()
@@ -107,7 +107,7 @@ test('치는 동안 입체는 그 점으로 그려지고, 잘못된 동안은
107
107
  { id: 'p3', x: 50, z: 40 },
108
108
  { id: 'p4', x: -50, z: 40 }
109
109
  ]
110
- const drawn = livePartsOf(t, { values: {}, action: { kind: 'set-section-points', part: 'wedge', points: square } })!
110
+ const drawn = livePartsOf(t, { values: {}, action: { kind: 'set-section', part: 'wedge', points: square } })!
111
111
  const body = drawn.find(p => p.id === 'wedge') as unknown as { shape: FigureEvaluatedShape }
112
112
  assert.equal((body.shape.extrusion!.section as { points: unknown[] }).points.length, 4)
113
113
  assert.equal(pointsOf(t).length, 3, 'the figure itself is not changed')
@@ -116,7 +116,7 @@ test('치는 동안 입체는 그 점으로 그려지고, 잘못된 동안은
116
116
  })
117
117
 
118
118
  test('적용은 한 명령, 취소·Esc 는 아무것도 보내지 않는다 — 창을 연 뒤 도형이 바뀌면 적용을 막는다', () => {
119
- has(editorPanel, /private apply\(\) \{\s*if \(this\.stale \|\| issuesOf\(this\.working, this\.axis\)\.length\) return/)
119
+ has(editorPanel, /private apply\(\) \{\s*if \(this\.stale \|\| !this\.valid\(this\.working\)\) return/)
120
120
  has(editorPanel, /private cancel\(\) \{\s*this\.dispatchEvent\(new CustomEvent\('command-live', \{ detail: \{ action: null \}/)
121
121
  has(editorPanel, /return this\.revision !== this\.openedAt/)
122
122
  has(editor, /<figure-section-editor[\s\S]*?\.revision=\$\{this\.session\?\.read\(\)\.revision \?\? 0\}[\s\S]*?@command=\$\{\(e: CustomEvent\) => this\.linkCommand\(e\.detail\.action\)\}/)
@@ -160,7 +160,7 @@ test('치는 동안의 명령이 쓴 입력은 명령의 값으로 그린다 —
160
160
  const { liveOverSession } = await import('../client/modeller/live.ts')
161
161
  const t = triangle()
162
162
  const moved = pointsOf(t).map(p => (p.id === 'p3' ? { ...p, x: -30 } : p))
163
- const drawn = liveOverSession(t, { ...t.designInputs }, { values: {}, action: { kind: 'set-section-points', part: 'wedge', points: moved } })!
163
+ const drawn = liveOverSession(t, { ...t.designInputs }, { values: {}, action: { kind: 'set-section', part: 'wedge', points: moved } })!
164
164
  const wedge = drawn.find(p => p.id === 'wedge') as unknown as { shape: FigureEvaluatedShape }
165
165
  assert.equal((wedge.shape.extrusion!.section as { points: FigureSectionPoint[] }).points.find(p => p.id === 'p3')!.x, -30)
166
166
  /* Stage 1's corner, typed a second time: the radius drawn is the one typed, not the one applied before. */
@@ -190,3 +190,43 @@ test('편집 창 옆에 입체를 볼 자리가 없으면 윤곽과 입체 결
190
190
  has(editorPanel, /:host\(\[narrow\]\[show='solid'\]\) div\[body\] \{\s*display: none;/)
191
191
  has(editorPanel, /this\.room\.observe\(this\.parentElement\)/)
192
192
  })
193
+
194
+ test('사각형·원도 같은 창에서 — 폭·지름·길이를 한 명령으로, 바꾸지 않은 치수는 보내지 않는다', async () => {
195
+ const { addFigureBox, figureSectionMeasuresOf } = await import('@hatiolab/figure-model')
196
+ const { workingOf, workingIssuesOf, sectionOf } = await import('../client/modeller/section-drawing.ts')
197
+ const box = applyFigureAuthoring(addFigureBox(createFigureAsset('B'), { id: 'b', size: { x: 400, y: 200, z: 300 }, position: { x: 0, y: 100, z: 0 } }), { kind: 'set-placement', placement: 'floor' })
198
+ const shape = (compileFigureAsset(box).evaluate().geometry.find(g => (g as { id: string }).id === 'b') as unknown as { shape: FigureEvaluatedShape }).shape
199
+ const w = workingOf(shape)
200
+ assert.deepEqual(w, { points: [], across: { x: 400, z: 300 }, length: 200 })
201
+ assert.deepEqual(sectionOf(shape, { ...w, across: { x: 500, z: 300 } }), { kind: 'rectangle', size: { x: 500, z: 300 } })
202
+ assert.deepEqual(figureSectionMeasuresOf(box, 'b')!.measures, { y: 'editable', x: 'editable', z: 'editable' })
203
+ /* The editor sends only what changed: a measure left alone may follow another value and must not be written. */
204
+ has(editorPanel, /const across = Object\.fromEntries\(Object\.entries\(w\.across\)\.filter\(\(\[k, v\]\) => changed\(v, o\.across\[k as Axis\]\)\)\)/)
205
+ const next = applyFigureAuthoring(box, { kind: 'set-section', part: 'b', across: { x: 500 }, length: 260 })
206
+ const b = (compileFigureAsset(next).evaluate().geometry.find(g => (g as { id: string }).id === 'b') as unknown as { shape: FigureEvaluatedShape; pose: { t: number[] } })
207
+ assert.deepEqual(b.shape.extrusion!.section, { kind: 'rectangle', size: { x: 500, z: 300 } })
208
+ assert.equal(b.pose.t[1]! + b.shape.extrusion!.start, 0, 'a floor figure keeps its bottom')
209
+ /* A corner that no longer fits, and a length of 0, are said before anything is sent. */
210
+ const rounded = applyFigureAuthoring(box, { kind: 'set-section-corner', part: 'b', corner: 100 })
211
+ const r = (compileFigureAsset(rounded).evaluate().geometry.find(g => (g as { id: string }).id === 'b') as unknown as { shape: FigureEvaluatedShape }).shape
212
+ const narrow = workingIssuesOf(r, { ...workingOf(r), across: { x: 150, z: 300 } }).words
213
+ assert.equal(say(narrow[0]!.key, narrow[0]!.params), '이 폭에서는 모서리 반지름이 75 mm 까지입니다. 폭을 넓히거나 모서리를 줄입니다.')
214
+ assert.equal(workingIssuesOf(r, { ...workingOf(r), length: 0 }).words[0]!.key, 'figure.text.section-issue-length')
215
+ })
216
+
217
+ test('속 공간이 있으면 폭·길이가 그 벽과 막힌 끝을 남기는지도 커널로 묻는다', async () => {
218
+ const { addFigureBox } = await import('@hatiolab/figure-model')
219
+ const { workingOf, workingIssuesOf } = await import('../client/modeller/section-drawing.ts')
220
+ const tray = applyFigureAuthoring(addFigureBox(createFigureAsset('T'), { id: 't', size: { x: 400, y: 200, z: 300 }, position: { x: 0, y: 100, z: 0 } }), { kind: 'set-cavity', part: 't', cavity: { wall: 40, start: { closed: 30 }, end: 'open' } })
221
+ const shape = (compileFigureAsset(tray).evaluate().geometry.find(g => (g as { id: string }).id === 't') as unknown as { shape: FigureEvaluatedShape }).shape
222
+ assert.equal(workingIssuesOf(shape, { ...workingOf(shape), across: { x: 70, z: 300 } }).words[0]!.key, 'figure.text.section-issue-cavity-walls')
223
+ assert.equal(workingIssuesOf(shape, { ...workingOf(shape), length: 25 }).words[0]!.key, 'figure.text.section-issue-cavity-length')
224
+ assert.deepEqual(workingIssuesOf(shape, { ...workingOf(shape), across: { x: 90, z: 300 } }).words, [])
225
+ })
226
+
227
+ test('길이를 바꿀 때 남는 면은 부품의 관계가 정한 것을 읽어 보여 준다 (§4.1) — 다른 값을 따르는 치수는 칸을 막는다', () => {
228
+ has(editor, /const kept = figureScaleAnchorOf\(asset, this\.selected\)\?\.\[part\.shape\.extrusion\.axis\]/)
229
+ has(editorPanel, /m\?\.\[this\.axis\] === 'linked' \? linked : this\.keptWords\(\)/)
230
+ has(editorPanel, /m\?\.\[this\.axis\] !== 'editable'/)
231
+ assert.equal(say('figure.text.section-editor-keeps', { face: ko['figure.label.face-bottom']! }), '아랫면 유지')
232
+ })
@@ -188,9 +188,19 @@
188
188
  "figure.label.palette-token": "palette token",
189
189
  "figure.label.part": "part",
190
190
  "figure.label.part-material": "material",
191
+ "figure.text.section-editor-hint-sized": "Drag a handle or type the measures.",
192
+ "figure.label.section-editor-length": "push length (mm)",
193
+ "figure.label.section-editor-across": "{axis} width (mm)",
194
+ "figure.label.section-editor-diameter": "diameter (mm)",
195
+ "figure.text.section-editor-linked": "Follows another value.",
196
+ "figure.text.section-editor-keeps": "keeps {face}",
197
+ "figure.text.section-editor-keeps-centre": "keeps the centre",
198
+ "figure.text.section-issue-corner": "At this width the corner radius can be at most {max} mm. Widen it or make the corner smaller.",
199
+ "figure.text.section-issue-length": "The push length must be more than 0.",
200
+ "figure.text.section-issue-cavity-walls": "The inside walls take the whole width. Widen it or make the walls thinner.",
201
+ "figure.text.section-issue-cavity-length": "The closed ends take the whole length. Lengthen it or make the ends thinner.",
191
202
  "figure.button.section-editor-open": "edit section",
192
203
  "figure.label.section-editor": "edit section",
193
- "figure.text.section-editor-length": "pushed {length} mm",
194
204
  "figure.label.section-editor-outline": "outline",
195
205
  "figure.label.section-editor-solid": "solid",
196
206
  "figure.button.section-editor-back": "undo",
@@ -188,9 +188,19 @@
188
188
  "figure.label.palette-token": "palette token",
189
189
  "figure.label.part": "part",
190
190
  "figure.label.part-material": "material",
191
+ "figure.text.section-editor-hint-sized": "ハンドルをドラッグするか寸法を入力します。",
192
+ "figure.label.section-editor-length": "押し出し長さ (mm)",
193
+ "figure.label.section-editor-across": "{axis} 幅 (mm)",
194
+ "figure.label.section-editor-diameter": "直径 (mm)",
195
+ "figure.text.section-editor-linked": "他の値に従います。",
196
+ "figure.text.section-editor-keeps": "{face}を保持",
197
+ "figure.text.section-editor-keeps-centre": "中心を保持",
198
+ "figure.text.section-issue-corner": "この幅では角の半径は {max} mm までです。幅を広げるか角を小さくしてください。",
199
+ "figure.text.section-issue-length": "押し出し長さは 0 より大きくしてください。",
200
+ "figure.text.section-issue-cavity-walls": "内部の壁が幅全体を占めています。幅を広げるか壁を薄くしてください。",
201
+ "figure.text.section-issue-cavity-length": "閉じた端が長さ全体を占めています。長さを伸ばすか端を薄くしてください。",
191
202
  "figure.button.section-editor-open": "断面を編集",
192
203
  "figure.label.section-editor": "断面を編集",
193
- "figure.text.section-editor-length": "押し出し {length} mm",
194
204
  "figure.label.section-editor-outline": "輪郭",
195
205
  "figure.label.section-editor-solid": "立体",
196
206
  "figure.button.section-editor-back": "元に戻す",
@@ -188,9 +188,19 @@
188
188
  "figure.label.palette-token": "팔레트 토큰",
189
189
  "figure.label.part": "부품",
190
190
  "figure.label.part-material": "재질",
191
+ "figure.text.section-editor-hint-sized": "손잡이를 끌거나 치수를 입력합니다.",
192
+ "figure.label.section-editor-length": "돌출 길이 (mm)",
193
+ "figure.label.section-editor-across": "{axis} 폭 (mm)",
194
+ "figure.label.section-editor-diameter": "지름 (mm)",
195
+ "figure.text.section-editor-linked": "다른 값을 따릅니다.",
196
+ "figure.text.section-editor-keeps": "{face} 유지",
197
+ "figure.text.section-editor-keeps-centre": "가운데 유지",
198
+ "figure.text.section-issue-corner": "이 폭에서는 모서리 반지름이 {max} mm 까지입니다. 폭을 넓히거나 모서리를 줄입니다.",
199
+ "figure.text.section-issue-length": "돌출 길이는 0 보다 커야 합니다.",
200
+ "figure.text.section-issue-cavity-walls": "속 공간의 벽이 폭을 다 차지합니다. 폭을 넓히거나 벽을 얇게 합니다.",
201
+ "figure.text.section-issue-cavity-length": "막힌 끝이 길이를 다 차지합니다. 길이를 늘리거나 끝을 얇게 합니다.",
191
202
  "figure.button.section-editor-open": "단면 편집",
192
203
  "figure.label.section-editor": "단면 편집",
193
- "figure.text.section-editor-length": "돌출 길이 {length} mm",
194
204
  "figure.label.section-editor-outline": "윤곽",
195
205
  "figure.label.section-editor-solid": "입체 결과",
196
206
  "figure.button.section-editor-back": "되돌리기",
@@ -188,9 +188,19 @@
188
188
  "figure.label.palette-token": "palette token",
189
189
  "figure.label.part": "part",
190
190
  "figure.label.part-material": "material",
191
+ "figure.text.section-editor-hint-sized": "Seret pemegang atau taip ukurannya.",
192
+ "figure.label.section-editor-length": "panjang tolakan (mm)",
193
+ "figure.label.section-editor-across": "lebar {axis} (mm)",
194
+ "figure.label.section-editor-diameter": "diameter (mm)",
195
+ "figure.text.section-editor-linked": "Mengikut nilai lain.",
196
+ "figure.text.section-editor-keeps": "kekalkan {face}",
197
+ "figure.text.section-editor-keeps-centre": "kekalkan tengah",
198
+ "figure.text.section-issue-corner": "Pada lebar ini jejari sudut paling banyak {max} mm. Lebarkan atau kecilkan sudut.",
199
+ "figure.text.section-issue-length": "Panjang tolakan mesti lebih daripada 0.",
200
+ "figure.text.section-issue-cavity-walls": "Dinding dalam memenuhi seluruh lebar. Lebarkan atau nipiskan dinding.",
201
+ "figure.text.section-issue-cavity-length": "Hujung tertutup memenuhi seluruh panjang. Panjangkan atau nipiskan hujung.",
191
202
  "figure.button.section-editor-open": "sunting keratan",
192
203
  "figure.label.section-editor": "sunting keratan",
193
- "figure.text.section-editor-length": "tolakan {length} mm",
194
204
  "figure.label.section-editor-outline": "garis luar",
195
205
  "figure.label.section-editor-solid": "pepejal",
196
206
  "figure.button.section-editor-back": "buat asal",
@@ -188,9 +188,19 @@
188
188
  "figure.label.palette-token": "palette token",
189
189
  "figure.label.part": "part",
190
190
  "figure.label.part-material": "material",
191
+ "figure.text.section-editor-hint-sized": "拖动手柄或输入尺寸。",
192
+ "figure.label.section-editor-length": "拉伸长度 (mm)",
193
+ "figure.label.section-editor-across": "{axis} 宽度 (mm)",
194
+ "figure.label.section-editor-diameter": "直径 (mm)",
195
+ "figure.text.section-editor-linked": "跟随其他值。",
196
+ "figure.text.section-editor-keeps": "保持{face}",
197
+ "figure.text.section-editor-keeps-centre": "保持中心",
198
+ "figure.text.section-issue-corner": "此宽度下圆角半径最大为 {max} mm。请加宽或减小圆角。",
199
+ "figure.text.section-issue-length": "拉伸长度必须大于 0。",
200
+ "figure.text.section-issue-cavity-walls": "内壁占满了整个宽度。请加宽或减薄壁。",
201
+ "figure.text.section-issue-cavity-length": "封闭端占满了整个长度。请加长或减薄端部。",
191
202
  "figure.button.section-editor-open": "编辑截面",
192
203
  "figure.label.section-editor": "编辑截面",
193
- "figure.text.section-editor-length": "拉伸 {length} mm",
194
204
  "figure.label.section-editor-outline": "轮廓",
195
205
  "figure.label.section-editor-solid": "立体",
196
206
  "figure.button.section-editor-back": "撤销",