@volter/editor-blender 0.1.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.
Files changed (58) hide show
  1. package/LICENSE +1409 -0
  2. package/README.md +17 -0
  3. package/contributions/blender-header-menus.tsx +483 -0
  4. package/contributions/blender-icon-trace.mjs +403 -0
  5. package/contributions/blender-icons.source.mjs +2925 -0
  6. package/contributions/blender-node-editor.document.tsx +1402 -0
  7. package/contributions/blender-node-geometry.ts +1138 -0
  8. package/contributions/blender-node-panels.source.mjs +485 -0
  9. package/contributions/blender-outliner-authoring.ts +1729 -0
  10. package/contributions/blender-outliner-model.ts +389 -0
  11. package/contributions/blender-palette.source.mjs +319 -0
  12. package/contributions/blender-properties-model.ts +351 -0
  13. package/contributions/blender-properties-tab.tsx +100 -0
  14. package/contributions/blender-properties-view.tsx +1191 -0
  15. package/contributions/blender-runtime-skin.ts +619 -0
  16. package/contributions/blender-runtime.document.tsx +232 -0
  17. package/contributions/blender-timeline-geometry.ts +323 -0
  18. package/contributions/blender-timeline.document.tsx +1056 -0
  19. package/contributions/blender-uv-editor.document.tsx +483 -0
  20. package/contributions/blender-uv-geometry.ts +305 -0
  21. package/contributions/blender-version.status.tsx +93 -0
  22. package/contributions/blender.command.ts +102 -0
  23. package/contributions/blender.icons.json +1247 -0
  24. package/contributions/blender.icons.traced.json +1561 -0
  25. package/contributions/blender.keymap.ts +39 -0
  26. package/contributions/blender.node-panels.json +2436 -0
  27. package/contributions/blender.palette.json +93 -0
  28. package/contributions/blender.status.tsx +263 -0
  29. package/contributions/blender.style.ts +271 -0
  30. package/contributions/model.layout.ts +53 -0
  31. package/contributions/models.finder.ts +59 -0
  32. package/contributions/properties-bone-constraints.inspector.tsx +50 -0
  33. package/contributions/properties-bone.inspector.tsx +184 -0
  34. package/contributions/properties-collection.inspector.tsx +96 -0
  35. package/contributions/properties-constraints.inspector.tsx +69 -0
  36. package/contributions/properties-data.inspector.tsx +229 -0
  37. package/contributions/properties-material.inspector.tsx +121 -0
  38. package/contributions/properties-modifiers.inspector.tsx +74 -0
  39. package/contributions/properties-object.inspector.tsx +215 -0
  40. package/contributions/properties-output.inspector.tsx +210 -0
  41. package/contributions/properties-particles.inspector.tsx +494 -0
  42. package/contributions/properties-physics.inspector.tsx +614 -0
  43. package/contributions/properties-render.inspector.tsx +446 -0
  44. package/contributions/properties-scene.inspector.tsx +174 -0
  45. package/contributions/properties-texture.inspector.tsx +300 -0
  46. package/contributions/properties-view-layer.inspector.tsx +145 -0
  47. package/contributions/properties-world.inspector.tsx +130 -0
  48. package/contributions/sculpt.layout.ts +25 -0
  49. package/contributions/shading.layout.ts +99 -0
  50. package/contributions/texture.layout.ts +16 -0
  51. package/contributions/uv-editing.layout.ts +93 -0
  52. package/host/blender-runtime-host.ts +1256 -0
  53. package/package.json +77 -0
  54. package/src/layouts.tsx +48 -0
  55. package/src/looks.ts +14 -0
  56. package/src/node-view-state.ts +125 -0
  57. package/src/timeline-view-state.ts +154 -0
  58. package/src/uv-view-state.ts +125 -0
@@ -0,0 +1,446 @@
1
+ /**
2
+ * BLENDER'S RENDER TAB, as a Properties section (WORK.md §Blender in the tab
3
+ * is Blender, "Inspection parity", I2). Blender's own panels over the RNA
4
+ * door, with the generic view beneath under "All properties".
5
+ *
6
+ * THE SPECIFICATION IS `scripts/startup/bl_ui/properties_render.py` at the
7
+ * engine's pin — `classes` (`:1186-1236`) is the panel order, `bl_label` the
8
+ * title, each `layout.prop(…)` an entry, `bl_parent_id` a `sub`. Blender's UI
9
+ * layer is never run, ported or recorded.
10
+ *
11
+ * THIS TAB IS WHERE THE ENGINE POLLS BECOME REAL, and it is the ONE `poll`
12
+ * this transcription reads. Every other condition is dropped because RNA
13
+ * already answers it — a property a datablock does not carry does not draw.
14
+ * `COMPAT_ENGINES` is different in kind: `scene.eevee` and `scene.display`
15
+ * exist under every engine, so nothing about the datablock says whether
16
+ * Blender would draw the panel. Each panel below carries Blender's own LIST
17
+ * (`COMPAT_ENGINES`, once per class) and it is checked against the ENGINE's
18
+ * live answer — `rna_context`'s `engine`, which is `scene.render.engine`,
19
+ * which is what `context.engine` is. The three ids a script can name here are
20
+ * CYCLES, BLENDER_EEVEE and BLENDER_WORKBENCH (`session.py::_register_engine`);
21
+ * the factory engine is BLENDER_EEVEE (`wasm/BUNDLE.json`), so the EEVEE
22
+ * panels are what a fresh file draws. Cycles' own panels are the add-on's, not
23
+ * `bl_ui`'s, and are therefore not in this file's specification.
24
+ *
25
+ * SEVERAL PANELS DRAW TWO DATABLOCKS IN ONE LIST — `RENDER_PT_eevee_film`
26
+ * (`:757`) takes `filter_size` and `film_transparent` off `scene.render` and
27
+ * `use_overscan`/`overscan_size` off `scene.eevee`, in that order. The
28
+ * qualified property form keeps the row in Blender's position while naming
29
+ * the datablock it comes from (`BlenderCuratedProperty`); the context door
30
+ * names every one of them as this tab's own paths.
31
+ *
32
+ * WHAT THE TRANSCRIPTION DELIBERATELY DROPS:
33
+ * - every operator and preset menu: `RENDER_PT_format_presets`,
34
+ * `RENDER_PT_eevee_raytracing_presets` (`:380`), the light-probe bake
35
+ * buttons. Inspection parity, not editing parity.
36
+ * - `template_curve_mapping` (the motion-blur shutter curve `:283`, the
37
+ * colour-management curves `:185`) and `template_colormanaged_view_settings`
38
+ * — curve widgets, which this view does not draw; the datablock is one
39
+ * drill away in the generic view beneath.
40
+ * - `RENDER_PT_hydra_debug` (`:1165`): its engine is HYDRA_STORM, which this
41
+ * build does not register, and its poll also wants a developer-UI
42
+ * preference.
43
+ *
44
+ * It stands when: `buttons_context_path_scene` — a scene always resolves.
45
+ */
46
+ import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
47
+ import type { BlenderCuratedPanel } from './blender-properties-view';
48
+
49
+ const EEVEE = ['BLENDER_EEVEE'] as const;
50
+ const WORKBENCH = ['BLENDER_WORKBENCH'] as const;
51
+
52
+ /** `properties_render.py`, panel by panel. Line numbers are that file's. */
53
+ const CURATED: readonly BlenderCuratedPanel[] = [
54
+ {
55
+ // RENDER_PT_context, :28 — `bl_label = ""` and HIDE_HEADER: in Blender it
56
+ // is the bare engine row above the panels. Our panels always carry a
57
+ // header, so it is named for what it holds.
58
+ title: 'Render Engine',
59
+ properties: ['engine'],
60
+ },
61
+ {
62
+ // RENDER_PT_eevee_sampling, :675 — an empty body; the four children carry
63
+ // the properties. `props = scene.eevee`.
64
+ title: 'Sampling',
65
+ engine: EEVEE,
66
+ from: 'EEVEE',
67
+ properties: [],
68
+ sub: [
69
+ // RENDER_PT_eevee_sampling_viewport, :687.
70
+ {
71
+ title: 'Viewport',
72
+ from: 'EEVEE',
73
+ properties: ['taa_samples', 'use_taa_reprojection', 'use_shadow_jitter_viewport'],
74
+ },
75
+ // RENDER_PT_eevee_sampling_render, :712.
76
+ { title: 'Render', from: 'EEVEE', properties: ['taa_render_samples'] },
77
+ // RENDER_PT_eevee_sampling_shadows, :635.
78
+ {
79
+ title: 'Shadows',
80
+ closed: true,
81
+ from: 'EEVEE',
82
+ properties: [
83
+ 'use_shadows',
84
+ 'shadow_ray_count',
85
+ 'shadow_step_count',
86
+ 'use_volumetric_shadows',
87
+ 'volumetric_shadow_samples',
88
+ 'shadow_resolution_scale',
89
+ ],
90
+ },
91
+ // RENDER_PT_eevee_sampling_advanced, :735.
92
+ { title: 'Advanced', closed: true, from: 'EEVEE', properties: ['light_threshold'] },
93
+ ],
94
+ },
95
+ {
96
+ // RENDER_PT_eevee_light_paths, :546 — empty body, three descendants.
97
+ title: 'Light Paths',
98
+ closed: true,
99
+ engine: EEVEE,
100
+ from: 'EEVEE',
101
+ properties: [],
102
+ sub: [
103
+ {
104
+ // RENDER_PT_eevee_clamping, :559, itself empty.
105
+ title: 'Clamping',
106
+ from: 'EEVEE',
107
+ properties: [],
108
+ sub: [
109
+ // RENDER_PT_eevee_clamping_surface, :572.
110
+ {
111
+ title: 'Surface',
112
+ from: 'EEVEE',
113
+ properties: ['clamp_surface_direct', 'clamp_surface_indirect'],
114
+ },
115
+ // RENDER_PT_eevee_clamping_volume, :593.
116
+ {
117
+ title: 'Volume',
118
+ from: 'EEVEE',
119
+ properties: ['clamp_volume_direct', 'clamp_volume_indirect'],
120
+ },
121
+ ],
122
+ },
123
+ // RENDER_PT_eevee_light_paths_intensity, :614.
124
+ {
125
+ title: 'Intensity',
126
+ from: 'EEVEE',
127
+ properties: ['direct_light_intensity', 'indirect_light_intensity'],
128
+ },
129
+ ],
130
+ },
131
+ {
132
+ // RENDER_PT_eevee_raytracing, :387 — `props = scene.eevee` and
133
+ // `options = scene.eevee.ray_tracing_options` (:415), one list.
134
+ title: 'Raytracing',
135
+ closed: true,
136
+ engine: EEVEE,
137
+ from: 'EEVEE',
138
+ properties: [
139
+ 'use_raytracing',
140
+ 'ray_tracing_method',
141
+ { from: 'Raytracing', property: 'resolution_scale' },
142
+ ],
143
+ sub: [
144
+ // RENDER_PT_eevee_screen_trace, :420 — `props` is the OPTIONS struct
145
+ // here (:439), which is why every row names it.
146
+ {
147
+ title: 'Screen Tracing',
148
+ closed: true,
149
+ from: 'Raytracing',
150
+ properties: [
151
+ 'screen_trace_quality',
152
+ 'screen_trace_thickness',
153
+ 'use_backface_hit',
154
+ 'backface_radiance_scale',
155
+ ],
156
+ },
157
+ // RENDER_PT_eevee_denoise, :506 — `props = scene.eevee.ray_tracing_options`.
158
+ {
159
+ title: 'Denoising',
160
+ closed: true,
161
+ from: 'Raytracing',
162
+ properties: ['use_denoise', 'denoise_spatial', 'denoise_temporal', 'denoise_bilateral'],
163
+ },
164
+ // RENDER_PT_eevee_gi_approximation, :459 — `props = scene.eevee` (:476)
165
+ // with `options.trace_max_roughness` (:485) among them.
166
+ {
167
+ title: 'Fast GI Approximation',
168
+ closed: true,
169
+ from: 'EEVEE',
170
+ properties: [
171
+ 'use_fast_gi',
172
+ { from: 'Raytracing', property: 'trace_max_roughness' },
173
+ 'fast_gi_method',
174
+ 'fast_gi_resolution',
175
+ 'fast_gi_ray_count',
176
+ 'fast_gi_step_count',
177
+ 'fast_gi_quality',
178
+ 'fast_gi_distance',
179
+ 'fast_gi_thickness_near',
180
+ 'fast_gi_bias',
181
+ ],
182
+ },
183
+ ],
184
+ },
185
+ {
186
+ // RENDER_PT_eevee_volumes, :325.
187
+ title: 'Volumes',
188
+ closed: true,
189
+ engine: EEVEE,
190
+ from: 'EEVEE',
191
+ properties: [
192
+ 'volumetric_tile_size',
193
+ 'volumetric_samples',
194
+ 'volumetric_sample_distribution',
195
+ 'volumetric_ray_depth',
196
+ ],
197
+ sub: [
198
+ // RENDER_PT_eevee_volumes_range, :351.
199
+ {
200
+ title: 'Custom Range',
201
+ closed: true,
202
+ from: 'EEVEE',
203
+ properties: ['use_volume_custom_range', 'volumetric_start', 'volumetric_end'],
204
+ },
205
+ ],
206
+ },
207
+ {
208
+ // RENDER_PT_eevee_depth_of_field, :295.
209
+ title: 'Depth of Field',
210
+ closed: true,
211
+ engine: EEVEE,
212
+ from: 'EEVEE',
213
+ properties: [
214
+ 'bokeh_max_size',
215
+ 'bokeh_threshold',
216
+ 'bokeh_neighbor_max',
217
+ 'use_bokeh_jittered',
218
+ 'bokeh_overblur',
219
+ ],
220
+ },
221
+ {
222
+ // RENDER_PT_eevee_motion_blur, :235 — `props = scene.render` (:253) and
223
+ // `eevee_props = scene.eevee` (:254). The shutter-curve child (:266) is a
224
+ // curve widget and is not drawn here.
225
+ title: 'Motion Blur',
226
+ closed: true,
227
+ engine: EEVEE,
228
+ properties: [
229
+ 'use_motion_blur',
230
+ 'motion_blur_position',
231
+ 'motion_blur_shutter',
232
+ { from: 'EEVEE', property: 'motion_blur_depth_scale' },
233
+ { from: 'EEVEE', property: 'motion_blur_max' },
234
+ { from: 'EEVEE', property: 'motion_blur_steps' },
235
+ ],
236
+ },
237
+ {
238
+ // RENDER_PT_eevee_film, :757 — `rd = scene.render` and `props = scene.eevee`.
239
+ title: 'Film',
240
+ closed: true,
241
+ engine: EEVEE,
242
+ properties: [
243
+ 'filter_size',
244
+ 'film_transparent',
245
+ { from: 'EEVEE', property: 'use_overscan' },
246
+ { from: 'EEVEE', property: 'overscan_size' },
247
+ ],
248
+ },
249
+ {
250
+ // RENDER_PT_eevee_performance, :812 — `rd = scene.render` (:827).
251
+ title: 'Performance',
252
+ closed: true,
253
+ engine: EEVEE,
254
+ properties: ['use_high_quality_normals', 'anisotropic_filter'],
255
+ sub: [
256
+ // CompositorPerformanceButtonsPanel, :836, which
257
+ // RENDER_PT_eevee_performance_compositor (:872) is.
258
+ {
259
+ title: 'Compositor',
260
+ closed: true,
261
+ properties: ['compositor_device', 'compositor_precision'],
262
+ sub: [
263
+ // CompositorDenoisePerformanceButtonsPanel, :854.
264
+ {
265
+ title: 'Denoise Nodes',
266
+ closed: true,
267
+ properties: [
268
+ 'compositor_denoise_device',
269
+ 'compositor_denoise_preview_quality',
270
+ 'compositor_denoise_final_quality',
271
+ ],
272
+ },
273
+ ],
274
+ },
275
+ // RENDER_PT_eevee_performance_memory, :892 — `props = scene.eevee`.
276
+ {
277
+ title: 'Memory',
278
+ closed: true,
279
+ from: 'EEVEE',
280
+ properties: ['shadow_pool_size', 'gi_irradiance_pool_size'],
281
+ },
282
+ // RENDER_PT_eevee_performance_viewport, :914 — `rd = scene.render`.
283
+ { title: 'Viewport', closed: true, properties: ['preview_pixel_size'] },
284
+ ],
285
+ },
286
+ {
287
+ // RENDER_PT_opengl_sampling, :1004 — `props = scene.display`.
288
+ title: 'Sampling',
289
+ engine: WORKBENCH,
290
+ from: 'Workbench',
291
+ properties: ['render_aa', 'viewport_aa'],
292
+ },
293
+ {
294
+ // RENDER_PT_opengl_lighting, :1039 — delegates to
295
+ // `VIEW3D_PT_shading_lighting.draw` (`space_view3d.py:6635`), which draws
296
+ // `scene.display.shading`.
297
+ title: 'Lighting',
298
+ engine: WORKBENCH,
299
+ from: 'Workbench Shading',
300
+ properties: ['light', 'studio_light', 'use_world_space_lighting', 'studiolight_rotate_z'],
301
+ },
302
+ {
303
+ // RENDER_PT_opengl_color, :1051 — `VIEW3D_PT_shading_color._draw_color_type`
304
+ // (`space_view3d.py:6757`).
305
+ title: 'Object Color',
306
+ engine: WORKBENCH,
307
+ from: 'Workbench Shading',
308
+ properties: ['color_type', 'single_color'],
309
+ },
310
+ {
311
+ // RENDER_PT_opengl_options, :1063 — `VIEW3D_PT_shading_options.draw`
312
+ // (`space_view3d.py:6797`) then the cavity block (`:6896`).
313
+ title: 'Options',
314
+ engine: WORKBENCH,
315
+ from: 'Workbench Shading',
316
+ properties: [
317
+ 'show_backface_culling',
318
+ 'show_object_outline',
319
+ 'object_outline_color',
320
+ 'show_specular_highlight',
321
+ 'show_xray',
322
+ 'xray_alpha',
323
+ 'show_shadows',
324
+ 'shadow_intensity',
325
+ 'use_dof',
326
+ 'show_cavity',
327
+ 'cavity_type',
328
+ 'cavity_ridge_factor',
329
+ 'cavity_valley_factor',
330
+ 'curvature_ridge_factor',
331
+ 'curvature_valley_factor',
332
+ ],
333
+ },
334
+ {
335
+ // RENDER_PT_opengl_film, :1025 — `rd = scene.render`.
336
+ title: 'Film',
337
+ closed: true,
338
+ engine: WORKBENCH,
339
+ properties: ['film_transparent'],
340
+ },
341
+ {
342
+ // RENDER_PT_gpencil, :937 — `props = scene.grease_pencil_settings`.
343
+ title: 'Grease Pencil',
344
+ closed: true,
345
+ from: 'Grease Pencil',
346
+ properties: [],
347
+ sub: [
348
+ // RENDER_PT_grease_pencil_viewport, :955.
349
+ {
350
+ title: 'Viewport',
351
+ closed: true,
352
+ from: 'Grease Pencil',
353
+ properties: ['antialias_threshold'],
354
+ },
355
+ // RENDER_PT_grease_pencil_render, :977.
356
+ {
357
+ title: 'Render',
358
+ closed: true,
359
+ from: 'Grease Pencil',
360
+ properties: ['antialias_threshold_render', 'aa_samples', 'motion_blur_steps'],
361
+ },
362
+ ],
363
+ },
364
+ {
365
+ // RENDER_PT_simplify, :1079 — `rd.use_simplify` is the header checkbox.
366
+ title: 'Simplify',
367
+ closed: true,
368
+ properties: ['use_simplify'],
369
+ sub: [
370
+ // RENDER_PT_simplify_viewport, :1096.
371
+ {
372
+ title: 'Viewport',
373
+ properties: [
374
+ 'simplify_subdivision',
375
+ 'simplify_child_particles',
376
+ 'simplify_volumes',
377
+ 'use_simplify_normals',
378
+ ],
379
+ },
380
+ // RENDER_PT_simplify_render, :1128.
381
+ {
382
+ title: 'Render',
383
+ properties: ['simplify_subdivision_render', 'simplify_child_particles_render'],
384
+ },
385
+ ],
386
+ },
387
+ {
388
+ // RENDER_PT_color_management, :51 — `scene.display_settings.display_device`
389
+ // (:74) then `view = scene.view_settings` (:69).
390
+ title: 'Color Management',
391
+ closed: true,
392
+ from: 'View Settings',
393
+ properties: [
394
+ { from: 'Display Device', property: 'display_device' },
395
+ 'view_transform',
396
+ 'look',
397
+ 'exposure',
398
+ 'gamma',
399
+ ],
400
+ sub: [
401
+ // RENDER_PT_color_management_white_balance, :195.
402
+ {
403
+ title: 'White Balance',
404
+ closed: true,
405
+ from: 'View Settings',
406
+ properties: ['use_white_balance', 'white_balance_temperature', 'white_balance_tint'],
407
+ },
408
+ // RENDER_PT_color_management_curves, :157 — the curve widget itself is
409
+ // not drawn here; its toggle and the mapping pointer are.
410
+ {
411
+ title: 'Curves',
412
+ closed: true,
413
+ from: 'View Settings',
414
+ properties: ['use_curve_mapping', 'curve_mapping'],
415
+ },
416
+ // RENDER_PT_color_management_advanced, :135.
417
+ {
418
+ title: 'Advanced',
419
+ closed: true,
420
+ from: 'Display Device',
421
+ properties: ['emulation'],
422
+ },
423
+ ],
424
+ },
425
+ ];
426
+
427
+ const TAB = { id: 'render', standing: 'any', curated: CURATED } as const;
428
+
429
+ export const point = 'selection.inspector';
430
+ export const title = 'Render';
431
+ /** `blender.icons.json` — Blender's own mark, TRACED from
432
+ * `release/datafiles/icons_svg/` at the engine's pin (the icon this tab draws
433
+ * is named in `buttons_context_items`, `makesrna/intern/rna_space.cc:579`),
434
+ * and tinted by the group `UI_icons.hh` declares it in. */
435
+ export const icon = 'properties-render';
436
+ /** `ED_buttons_tabs_list` (`space_buttons.cc:218-252`) is the rail's order;
437
+ * these are that order, spaced so a tab can be inserted between two. */
438
+ export const order = 10;
439
+ /** THE RAIL'S GROUPS, from `ED_buttons_tabs_list`'s own `add_spacer()` calls
440
+ * (`space_buttons/space_buttons.cc:201-255`): the tool tab, then the scene
441
+ * group (Render, Output, View Layer, Scene, World), then Collection, then the
442
+ * object group (Object … Material), then Texture. The presentation draws a
443
+ * separator wherever this changes. */
444
+ export const railGroup = 'scene';
445
+ export const match = blenderPropertiesTabMatch(TAB);
446
+ export default blenderPropertiesTabSection(TAB);
@@ -0,0 +1,174 @@
1
+ /**
2
+ * BLENDER'S SCENE TAB, as a Properties section (WORK.md §Blender in the tab
3
+ * is Blender, "Inspection parity", I2). Blender's own panels over the RNA
4
+ * door, with the generic view beneath under "All properties".
5
+ *
6
+ * THE SPECIFICATION IS `scripts/startup/bl_ui/properties_scene.py` at the
7
+ * engine's pin — its `classes` tuple (`:471-488`) is the panel order,
8
+ * `bl_label` the title, each `layout.prop(scene, "x")` an entry in the order
9
+ * the draw function lists it, `bl_options = {'DEFAULT_CLOSED'}` a `closed`
10
+ * and `bl_parent_id` a `sub`. Blender's UI layer is never run, ported or
11
+ * recorded.
12
+ *
13
+ * SEVERAL OF THESE PANELS DRAW A SUB-STRUCT RATHER THAN THE SCENE: Units is
14
+ * `scene.unit_settings`, Rigid Body World is `scene.rigidbody_world`, Light
15
+ * Probes is `scene.eevee`. The context door names each of those beside the
16
+ * scene as one of this tab's own datablocks (`session.py::rna_context`), the
17
+ * way it already named the Output tab's `image_settings`, and each panel says
18
+ * which it reads with `from`. An absent one — a file with no rigid body world
19
+ * — is an absent path, and the panel does not draw: the same answer
20
+ * `RigidBodySubPanel.poll` gives (`:361-367`), from the door rather than from
21
+ * a copy of its condition.
22
+ *
23
+ * WHAT THE TRANSCRIPTION DELIBERATELY DROPS:
24
+ * - `SCENE_PT_context_scene` (`:37`, `bl_label = ""`) — the scene ID
25
+ * template, which is the host's identity row here.
26
+ * - the operator rows: `rigidbody.world_add`/`_remove` (`:357-359`), the
27
+ * keying-set list's add/remove, `object.lightprobe_cache_bake` (`:447`).
28
+ * Inspection parity, not editing parity (ARCHITECTURE-CORE §Blender north
29
+ * star) — an operator is not a property and this view draws properties.
30
+ * - `SCENE_PT_custom_props` (`:467`). Custom properties are IDProperties;
31
+ * they are not in `bl_rna.properties` and the door answers RNA. Same
32
+ * reading as the Object tab's.
33
+ *
34
+ * It stands when: `buttons_context_path_scene` — a scene always resolves.
35
+ */
36
+ import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
37
+ import type { BlenderCuratedPanel } from './blender-properties-view';
38
+
39
+ /** `properties_scene.py`, panel by panel. Line numbers are that file's. */
40
+ const CURATED: readonly BlenderCuratedPanel[] = [
41
+ {
42
+ // SCENE_PT_scene, :49.
43
+ title: 'Scene',
44
+ properties: ['camera', 'background_set', 'active_clip'],
45
+ },
46
+ {
47
+ // SCENE_PT_unit, :64 — `unit = scene.unit_settings` (:74).
48
+ title: 'Units',
49
+ closed: true,
50
+ from: 'Units',
51
+ properties: [
52
+ 'system',
53
+ 'scale_length',
54
+ 'use_separate',
55
+ 'system_rotation',
56
+ 'length_unit',
57
+ 'mass_unit',
58
+ 'time_unit',
59
+ 'temperature_unit',
60
+ ],
61
+ },
62
+ {
63
+ // SCENE_PT_physics, :302 — `use_gravity` is the panel's HEADER checkbox
64
+ // (`draw_header`, :307) and `gravity` its one row.
65
+ title: 'Gravity',
66
+ closed: true,
67
+ properties: ['use_gravity', 'gravity'],
68
+ },
69
+ {
70
+ // SCENE_PT_simulation, :320.
71
+ title: 'Simulation',
72
+ closed: true,
73
+ properties: ['use_custom_simulation_range', 'simulation_frame_start', 'simulation_frame_end'],
74
+ },
75
+ {
76
+ // SCENE_PT_keying_sets, :144 — a `template_list` over `scene.keying_sets`
77
+ // (:156). The collection row lists them by name and drills into one; the
78
+ // sub-panels SCENE_PT_keying_set_paths (:213) and
79
+ // SCENE_PT_keyframing_settings (:177) are the ACTIVE set's own, and the
80
+ // context door carries no active keying set, so they are one drill down
81
+ // rather than a second addressing scheme.
82
+ title: 'Keying Sets',
83
+ closed: true,
84
+ properties: ['keying_sets'],
85
+ },
86
+ {
87
+ // SCENE_PT_audio, :275.
88
+ title: 'Audio',
89
+ closed: true,
90
+ properties: [
91
+ 'audio_volume',
92
+ 'audio_distance_model',
93
+ 'audio_doppler_speed',
94
+ 'audio_doppler_factor',
95
+ ],
96
+ },
97
+ {
98
+ // SCENE_PT_rigid_body_world, :338 — `enabled` is its header checkbox
99
+ // (:346); the body is two operators, which are not ours to draw.
100
+ title: 'Rigid Body World',
101
+ closed: true,
102
+ from: 'Rigid Body World',
103
+ properties: ['enabled'],
104
+ sub: [
105
+ {
106
+ // SCENE_PT_rigid_body_world_settings, :370.
107
+ title: 'Settings',
108
+ from: 'Rigid Body World',
109
+ properties: [
110
+ 'collection',
111
+ 'constraints',
112
+ 'time_scale',
113
+ 'use_split_impulse',
114
+ 'substeps_per_frame',
115
+ 'solver_iterations',
116
+ ],
117
+ },
118
+ {
119
+ // SCENE_PT_rigid_body_cache, :402 — `point_cache_ui(self,
120
+ // rbw.point_cache, …)`, so the panel is that sub-struct; its pointer
121
+ // row stands and the values are one drill down.
122
+ title: 'Cache',
123
+ closed: true,
124
+ from: 'Rigid Body World',
125
+ properties: ['point_cache'],
126
+ },
127
+ {
128
+ // SCENE_PT_rigid_body_field_weights, :413 —
129
+ // `effector_weights_ui(self, rbw.effector_weights, …)`.
130
+ title: 'Field Weights',
131
+ closed: true,
132
+ from: 'Rigid Body World',
133
+ properties: ['effector_weights'],
134
+ },
135
+ ],
136
+ },
137
+ {
138
+ // SCENE_PT_eevee_light_probes, :425 — `props = scene.eevee` (:440), and
139
+ // COMPAT_ENGINES is `{'BLENDER_EEVEE'}` (:429). The engine gate is read
140
+ // from `rna_context`'s own `engine`; see `BlenderCuratedPanel.engine`.
141
+ title: 'Light Probes',
142
+ closed: true,
143
+ from: 'EEVEE',
144
+ engine: ['BLENDER_EEVEE'],
145
+ properties: ['gi_cubemap_resolution'],
146
+ },
147
+ {
148
+ // SCENE_PT_animation, :452.
149
+ title: 'Animation',
150
+ closed: true,
151
+ properties: ['animation_data'],
152
+ },
153
+ ];
154
+
155
+ const TAB = { id: 'scene', standing: 'any', curated: CURATED } as const;
156
+
157
+ export const point = 'selection.inspector';
158
+ export const title = 'Scene';
159
+ /** `blender.icons.json` — Blender's own mark, TRACED from
160
+ * `release/datafiles/icons_svg/` at the engine's pin (the icon this tab draws
161
+ * is named in `buttons_context_items`, `makesrna/intern/rna_space.cc:579`),
162
+ * and tinted by the group `UI_icons.hh` declares it in. */
163
+ export const icon = 'properties-scene';
164
+ /** `ED_buttons_tabs_list` (`space_buttons.cc:218-252`) is the rail's order;
165
+ * these are that order, spaced so a tab can be inserted between two. */
166
+ export const order = 40;
167
+ /** THE RAIL'S GROUPS, from `ED_buttons_tabs_list`'s own `add_spacer()` calls
168
+ * (`space_buttons/space_buttons.cc:201-255`): the tool tab, then the scene
169
+ * group (Render, Output, View Layer, Scene, World), then Collection, then the
170
+ * object group (Object … Material), then Texture. The presentation draws a
171
+ * separator wherever this changes. */
172
+ export const railGroup = 'scene';
173
+ export const match = blenderPropertiesTabMatch(TAB);
174
+ export default blenderPropertiesTabSection(TAB);