@hatiolab/figure-model 0.1.20 → 0.1.22
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/blueprint-shape.d.ts.map +1 -1
- package/dist/blueprint-shape.js +4 -0
- package/dist/blueprint-shape.js.map +1 -1
- package/dist/blueprint.d.ts +7 -0
- package/dist/blueprint.d.ts.map +1 -1
- package/dist/blueprint.js +11 -40
- package/dist/blueprint.js.map +1 -1
- package/dist/grouping.d.ts +18 -0
- package/dist/grouping.d.ts.map +1 -1
- package/dist/grouping.js +14 -0
- package/dist/grouping.js.map +1 -1
- package/dist/origin.d.ts +29 -0
- package/dist/origin.d.ts.map +1 -0
- package/dist/origin.js +39 -0
- package/dist/origin.js.map +1 -0
- package/dist/sizing.d.ts.map +1 -1
- package/dist/sizing.js +4 -2
- package/dist/sizing.js.map +1 -1
- package/dist/types.d.ts +136 -43
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +88 -16
- package/dist/types.js.map +1 -1
- package/dist/validate.d.ts +0 -6
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +85 -11
- package/dist/validate.js.map +1 -1
- package/dist/visual-evidence.d.ts +1 -1
- package/dist/visual-evidence.d.ts.map +1 -1
- package/dist/visual-evidence.js +3 -1
- package/dist/visual-evidence.js.map +1 -1
- package/docs/format.md +142 -23
- package/docs/validation.md +72 -15
- package/package.json +2 -2
package/docs/validation.md
CHANGED
|
@@ -49,6 +49,7 @@ const { errors, violations } = validate(source)
|
|
|
49
49
|
| 코드 | 언제 | 왜 |
|
|
50
50
|
| --------------- | ----------------------------------------- | --------------------------------------------------------- |
|
|
51
51
|
| `missing-type` | `type` 이 없거나 빈 문자다 | **저장되는 식별자다.** 씬이 이 이름으로 청사진을 찾는다 |
|
|
52
|
+
| `source-version-unsupported` | `version` 이 2 가 아니거나 없다 | 판 1 은 y 를 상자 중심에서 쟀다. 판을 적지 않은 원본도 판 1 이다. 옮긴 원본만 읽는다 |
|
|
52
53
|
| `missing-base` | `base` 가 없다 | 배치 크기가 이 비율에서 나온다 |
|
|
53
54
|
| `missing-parts` | `parts` 가 없거나 비었다 | 부품이 하나는 있어야 한다. 여기서 검사를 멈춘다 |
|
|
54
55
|
| `bad-style-kit` | `styleKit` 이 빈 문자이거나 문자가 아니다 | |
|
|
@@ -97,8 +98,9 @@ const { errors, violations } = validate(source)
|
|
|
97
98
|
| `keys-out-of-order` | 키의 시각이 앞의 것보다 크지 않다 | 표본추출이 뜻을 잃는다. 화면에서는 「이상하게 움직인다」로만 보인다 |
|
|
98
99
|
|
|
99
100
|
clip 의 이름은 부품과 같은 코드를 쓴다 — 없으면 `missing-name`, 겹치면 `duplicate-name`.
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
경로와 `interpolation` 이 목록 밖이면 `not-allowed`, 키의 시각이 음수면 `not-positive` 다.
|
|
102
|
+
|
|
103
|
+
**같은 검사가 파라미터의 곡선에도 그대로 돈다.** 채널 모양은 어느 쪽이든 같아야 한다.
|
|
102
104
|
|
|
103
105
|
### 예외 표면
|
|
104
106
|
|
|
@@ -115,16 +117,26 @@ clip 의 이름은 부품과 같은 코드를 쓴다 — 없으면 `missing-name
|
|
|
115
117
|
|
|
116
118
|
### 능력 (`capabilities`)
|
|
117
119
|
|
|
118
|
-
배치된 도형이 씬 컴포넌트로서 부여받는 능력의 선언이다.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
배치된 도형이 씬 컴포넌트로서 부여받는 능력의 선언이다. **이름도 여기서 본다** — 한동안
|
|
121
|
+
아니었다.
|
|
122
|
+
|
|
123
|
+
목록이 things-scene 에만 있던 동안 이 검사가 이름을 못 봤고, AI 가 낸
|
|
124
|
+
`capabilities: ['hoist']` 가 **검증을 지나고 발행을 지나** 렌더링에서 죽었다. 저작자는 자산을
|
|
125
|
+
내보내고 나서야 그것이 안 선다는 것을 알았다. 게이트는 사실이 사는 곳에 있어야 한다 —
|
|
126
|
+
`base` 상자 때와 같은 구멍이었다.
|
|
127
|
+
|
|
128
|
+
쓸 수 있는 이름은 넷이다(`FIGURE_CAPABILITIES`). 자세한 것은 `docs/format.md`.
|
|
129
|
+
|
|
130
|
+
| 코드 | 뜻 |
|
|
131
|
+
| ------------------------ | -------------------------------------------------------------- |
|
|
132
|
+
| `bad-capability` | 배열이 아니거나, 이름이 비어 있거나, **목록 밖의 이름이거나**, 혼자 설 수 없는 것을 혼자 적었다 |
|
|
133
|
+
| `duplicate-capability` | 같은 능력을 두 번 선언했다 |
|
|
134
|
+
| `bad-part-capability` | 부품의 `capability` 모양이 틀렸다 — 역할·accepts·capacity |
|
|
135
|
+
|
|
136
|
+
거절할 때는 **쓸 수 있는 넷을 함께 말한다.** 「틀렸다」만으로는 AI 도 사람도 다음 수가 없다.
|
|
122
137
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
| `bad-capability` | 배열이 아니거나 이름이 비어 있다 |
|
|
126
|
-
| `duplicate-capability` | 같은 능력을 두 번 선언했다 |
|
|
127
|
-
| `bad-part-capability` | 부품의 `capability` 모양이 틀렸다 — 역할·accepts·capacity |
|
|
138
|
+
`Transferable` 은 자리를 찾는 일을 `Capacity` 에게 맡기므로 혼자 못 선다. 씬이 조립할 때도
|
|
139
|
+
같은 이유로 던지는데, **그때는 이미 발행된 뒤다** — 그래서 여기서 본다.
|
|
128
140
|
|
|
129
141
|
### 파라미터 (`parameters`)
|
|
130
142
|
|
|
@@ -144,11 +156,19 @@ things-scene** 이므로(`registerCapabilityMeta`), 여기서는 **모양만**
|
|
|
144
156
|
| --------------- | ------------------------------------------------------------------ |
|
|
145
157
|
| `missing-range` | `range` 나 `range.unit` 이 없다 — 인스턴스가 어느 값을 줄지 모른다 |
|
|
146
158
|
| `bad-range` | `max` 가 `min` 이하이거나, `default` 가 그 밖이다 |
|
|
159
|
+
| `out-of-range` | `clip` 의 키 `at` 이 1 을 넘는다 — `at` 은 초가 아니라 값의 구간(0~1)이다 |
|
|
160
|
+
| `not-positive` | `clip.duration` 이 음수다 — 없거나 0 이면 즉시다 |
|
|
161
|
+
|
|
162
|
+
**키의 `at` 은 값의 구간에 앉는다.** 1 을 넘는 키는 어떤 값으로도 닿지 않는 자세라서 거절한다. 구간을
|
|
163
|
+
다 덮을 필요는 없다 — 첫 키 앞과 마지막 키 뒤는 끝 키의 자세에 머문다. 전이 시간은 `clip.duration`
|
|
164
|
+
(초, 0→1 전 구간)이 따로 말한다.
|
|
147
165
|
|
|
148
166
|
이름은 `animations` 의 clip 이름과도 겹칠 수 없다. 인스턴스는 둘을 이름으로 부르므로 겹치면 어느 쪽에
|
|
149
167
|
값을 준 것인지 알 수 없다.
|
|
150
168
|
|
|
151
|
-
|
|
169
|
+
clip 에 `drive` 칸이 있으면 `not-allowed` 다. 값으로 움직이는 자세가 `drive: 'hold'` 로 애니메이션 안에 있던
|
|
170
|
+
원본은 판 2 로 옮길 때 파라미터로 함께 옮겼다(키는 마지막 키의 시각으로 나눠 값의 구간에, `duration` 없음).
|
|
171
|
+
형식은 옛 모양을 읽지 않는다.
|
|
152
172
|
|
|
153
173
|
부품의 `capability` 는 **그 능력을 어느 부품이 받쳐 주나**를 말한다. 역할은 셋이다.
|
|
154
174
|
|
|
@@ -198,7 +218,7 @@ things-scene** 이므로(`registerCapabilityMeta`), 여기서는 **모양만**
|
|
|
198
218
|
| --------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
199
219
|
| `detail-level-missing` | — | 등급이 없으면 부품 수 예산을 잡을 수 없다 |
|
|
200
220
|
| `too-many-parts` | `PART_LIMIT[detailLevel]` (S 3 · M 8 · L 20) | |
|
|
201
|
-
| `too-many-animated-parts` | `LIMITS.animatedParts` (2) | 움직이는 부품마다 묶음이 하나 늘고, 프레임마다 갱신이
|
|
221
|
+
| `too-many-animated-parts` | `LIMITS.animatedParts` (2) | 움직이는 부품마다 묶음이 하나 늘고, 프레임마다 갱신이 는다. clip 과 parameter 가 움직이는 부품을 함께 센다 |
|
|
202
222
|
| `too-many-material-groups` | `LIMITS.materialGroups` (3) | **자산당 draw call 이 는다.** 세는 단위는 `groupKeyOf` — 컴파일러가 합치는 단위와 같은 식이다 |
|
|
203
223
|
| `too-many-transparent` | `LIMITS.transparentMaterials` (1) | 투명 재질은 별도 정렬 경로를 탄다 |
|
|
204
224
|
| `too-many-always-labels` | 1 | `'always'` 라벨은 대량 배치에서 DOM·텍스처를 늘린다 |
|
|
@@ -218,7 +238,7 @@ things-scene** 이므로(`registerCapabilityMeta`), 여기서는 **모양만**
|
|
|
218
238
|
|
|
219
239
|
| 코드 | 언제 | 왜 |
|
|
220
240
|
| --------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
|
|
221
|
-
| `part-outside-base` | 부품이 `±base/2
|
|
241
|
+
| `part-outside-base` | 부품이 상자 밖으로 나간다(x·z 는 중심에서 `±base/2`, y 는 밑면 0 에서 `base.y`). 회전을 포함한 실제 부피로 잰다 | `base` 는 **나누는 수**다(`instanceScale = width/base.x`). 넘치면 그 수가 거짓말을 하고 도면에서 크기와 높이가 둘 다 틀린다 |
|
|
222
242
|
| `parts-off-placement-face` | 바닥 기반인데 상자 밑면에 안 닿는다 · 천정 기반인데 윗면에 안 닿는다 | 「선다」·「매달린다」고 선언해 놓고 떠 있다. **원점 규약이 어긋난 것**이지 상자가 큰 것이 아니다 |
|
|
223
243
|
|
|
224
244
|
허용 오차는 `SKIN`(0.5) 하나다 — 발행 관문이 「덩어리가 갈라졌나」를 재는 값과 같다. 오차 상수가
|
|
@@ -231,6 +251,22 @@ things-scene** 이므로(`registerCapabilityMeta`), 여기서는 **모양만**
|
|
|
231
251
|
|
|
232
252
|
**이 둘은 발행을 막는다.** 이미 발행된 것은 그대로 서 있고, 고치기 전에는 다시 발행하지 못한다.
|
|
233
253
|
|
|
254
|
+
### type 이름
|
|
255
|
+
|
|
256
|
+
`type` 은 도면이 `{ type, left, top, width, height }` 로 적는 **저장되는 식별자**다. 발행된 이름은 이미 놓인
|
|
257
|
+
도면들과의 약속이라 바꿀 수 없다. 그래서 규칙은 **초안 저장이 아니라 발행을 막는다** — 이름을 정하기 전에
|
|
258
|
+
만들어 보는 것은 막을 이유가 없다.
|
|
259
|
+
|
|
260
|
+
| 코드 | 언제 | 왜 |
|
|
261
|
+
| --------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
262
|
+
| `type-not-identifier` | 대문자 `SCREAMING_SNAKE_CASE`(`TYPE_PATTERN`) 가 아니거나 3~32 자 밖이다 | 대문자가 figure 의 이름공간이다. 씬의 내장 컴포넌트는 소문자라, 이 모양이면 겹칠 수 없다 |
|
|
263
|
+
| `type-is-placeholder` | 이름을 짓기 전의 임시 이름(`FIGURE_` + 8 자, `placeholderType()`)이다 | 모양은 맞아서 위 규칙으로는 안 걸린다. **아직 사람이 이름을 안 지은 것**이다 |
|
|
264
|
+
|
|
265
|
+
임시 이름은 저작 화면이 만들고(`placeholderType`) 게이트와 AI 도구가 알아본다(`isPlaceholderType`). 만드는
|
|
266
|
+
쪽과 알아보는 쪽이 같은 규칙을 쓰도록 형식이 갖는다. 범주 접두(`EQ_` · `VEH_` …)는 규칙으로 세우지 않는다.
|
|
267
|
+
|
|
268
|
+
형식이 깨진 원본에서는 이름을 보지 않는다 — 다른 정책 위반과 같은 단계다.
|
|
269
|
+
|
|
234
270
|
### draw call 을 세는 법
|
|
235
271
|
|
|
236
272
|
```
|
|
@@ -243,7 +279,7 @@ draw call = 합쳐진 묶음 하나당 1
|
|
|
243
279
|
|
|
244
280
|
| 무엇 | 왜 |
|
|
245
281
|
| --- | --- |
|
|
246
|
-
| clip
|
|
282
|
+
| clip 이나 parameter 가 움직이는 부품 | 합치면 그 부품만 따로 움직일 수 없다 |
|
|
247
283
|
| `sizing` 이 `scale` 이 아닌 부품 | 합친 geometry 는 변환을 하나만 받는다 |
|
|
248
284
|
| `repeat` 부품 | 한 부품이 여러 mesh 다 |
|
|
249
285
|
|
|
@@ -278,3 +314,24 @@ const blueprint = compile(source)
|
|
|
278
314
|
|
|
279
315
|
`violations` 는 던지지 않고 **청사진에 실려 나간다**(`blueprint.violations`). 저작
|
|
280
316
|
화면이 그것을 보인다.
|
|
317
|
+
|
|
318
|
+
## 문은 둘이다 — 저작할 때와 세울 때
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
validate(source) // 저작 형식을 본다. 사람이 고치는 것
|
|
322
|
+
blueprintProblems(blueprint) // 그 결과물을 본다. 씬이 등록할 때
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
`validate` 는 저작 중에 돌고, 무엇이 왜 틀렸는지 저작자에게 말하는 것이 일이다.
|
|
326
|
+
|
|
327
|
+
`blueprintProblems` 는 **씬에 들어가기 직전**에 한 번 돈다. 서버나 파일에서 온 청사진이
|
|
328
|
+
이 형식대로 생겼는지 묻는 자리다. 그리는 시점이 아니라 등록 시점에 보는 이유는, 잘못된
|
|
329
|
+
청사진이 **프레임마다 조용히 실패하는 것**보다 등록에서 한 번 크게 실패하는 편이 낫기
|
|
330
|
+
때문이다.
|
|
331
|
+
|
|
332
|
+
여기서 특히 보는 것은 **그려지지 않는 것들**이다. 자리(`anchors`)와 파라미터가 그렇다 —
|
|
333
|
+
틀려도 화면에는 아무 일도 안 일어난다. 물건을 앉히려는 순간, 값을 주는 순간에야 드러난다.
|
|
334
|
+
|
|
335
|
+
`range` 를 여기서 한 번 더 보는 이유가 그것이다. 그 값이 **런타임의 나누는 수**라서
|
|
336
|
+
(`(값 − min) / (max − min)`), `max` 가 `min` 이하면 mm 를 0~1 로 맵할 수 없고 **준 값이
|
|
337
|
+
통째로 조용히 버려진다.**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hatiolab/figure-model",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "Figure 저작 결과의 정본 형식과 검증 — 재질별로 병합되고 이름이 붙은 부품 그래프. 3D 로 저작한 형상 하나가 씬 컴포넌트로 서는 데 필요한 것을 담는다.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"figure",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "tsc -p tsconfig.build.json",
|
|
66
66
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
67
|
-
"test": "node --test src/*.test.ts",
|
|
67
|
+
"test": "npm run check && node --test src/*.test.ts",
|
|
68
68
|
"test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=100 --test-coverage-branches=95 --test-coverage-functions=100 src/*.test.ts",
|
|
69
69
|
"bench": "node src/perf.bench.ts",
|
|
70
70
|
"format": "prettier --write \"src/**/*.ts\" \"docs/**/*.md\" \"*.md\" \"*.json\"",
|