@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.
- package/LICENSE +1409 -0
- package/README.md +17 -0
- package/contributions/blender-header-menus.tsx +483 -0
- package/contributions/blender-icon-trace.mjs +403 -0
- package/contributions/blender-icons.source.mjs +2925 -0
- package/contributions/blender-node-editor.document.tsx +1402 -0
- package/contributions/blender-node-geometry.ts +1138 -0
- package/contributions/blender-node-panels.source.mjs +485 -0
- package/contributions/blender-outliner-authoring.ts +1729 -0
- package/contributions/blender-outliner-model.ts +389 -0
- package/contributions/blender-palette.source.mjs +319 -0
- package/contributions/blender-properties-model.ts +351 -0
- package/contributions/blender-properties-tab.tsx +100 -0
- package/contributions/blender-properties-view.tsx +1191 -0
- package/contributions/blender-runtime-skin.ts +619 -0
- package/contributions/blender-runtime.document.tsx +232 -0
- package/contributions/blender-timeline-geometry.ts +323 -0
- package/contributions/blender-timeline.document.tsx +1056 -0
- package/contributions/blender-uv-editor.document.tsx +483 -0
- package/contributions/blender-uv-geometry.ts +305 -0
- package/contributions/blender-version.status.tsx +93 -0
- package/contributions/blender.command.ts +102 -0
- package/contributions/blender.icons.json +1247 -0
- package/contributions/blender.icons.traced.json +1561 -0
- package/contributions/blender.keymap.ts +39 -0
- package/contributions/blender.node-panels.json +2436 -0
- package/contributions/blender.palette.json +93 -0
- package/contributions/blender.status.tsx +263 -0
- package/contributions/blender.style.ts +271 -0
- package/contributions/model.layout.ts +53 -0
- package/contributions/models.finder.ts +59 -0
- package/contributions/properties-bone-constraints.inspector.tsx +50 -0
- package/contributions/properties-bone.inspector.tsx +184 -0
- package/contributions/properties-collection.inspector.tsx +96 -0
- package/contributions/properties-constraints.inspector.tsx +69 -0
- package/contributions/properties-data.inspector.tsx +229 -0
- package/contributions/properties-material.inspector.tsx +121 -0
- package/contributions/properties-modifiers.inspector.tsx +74 -0
- package/contributions/properties-object.inspector.tsx +215 -0
- package/contributions/properties-output.inspector.tsx +210 -0
- package/contributions/properties-particles.inspector.tsx +494 -0
- package/contributions/properties-physics.inspector.tsx +614 -0
- package/contributions/properties-render.inspector.tsx +446 -0
- package/contributions/properties-scene.inspector.tsx +174 -0
- package/contributions/properties-texture.inspector.tsx +300 -0
- package/contributions/properties-view-layer.inspector.tsx +145 -0
- package/contributions/properties-world.inspector.tsx +130 -0
- package/contributions/sculpt.layout.ts +25 -0
- package/contributions/shading.layout.ts +99 -0
- package/contributions/texture.layout.ts +16 -0
- package/contributions/uv-editing.layout.ts +93 -0
- package/host/blender-runtime-host.ts +1256 -0
- package/package.json +77 -0
- package/src/layouts.tsx +48 -0
- package/src/looks.ts +14 -0
- package/src/node-view-state.ts +125 -0
- package/src/timeline-view-state.ts +154 -0
- package/src/uv-view-state.ts +125 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BLENDER'S OUTPUT 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_output.py` at the
|
|
7
|
+
* engine's pin — `classes` (`:728-748`) is the panel order, `bl_label` the
|
|
8
|
+
* title, each `layout.prop(rd, "x")` an entry in the order the draw function
|
|
9
|
+
* lists it. Blender's UI layer is never run, ported or recorded.
|
|
10
|
+
*
|
|
11
|
+
* THE TAB'S DATABLOCK IS `scene.render`, and three panels reach past it: Frame
|
|
12
|
+
* Range is the SCENE's own `frame_start`/`frame_end`/`frame_step` (`:151`),
|
|
13
|
+
* Output's Color Management is `rd.image_settings` (`:371`), and Encoding is
|
|
14
|
+
* `rd.ffmpeg` (`:499`). The context door names each beside the render
|
|
15
|
+
* settings as one of this tab's paths and the rows say which they come from
|
|
16
|
+
* ({@link BlenderCuratedProperty}).
|
|
17
|
+
*
|
|
18
|
+
* WHAT THE TRANSCRIPTION DELIBERATELY DROPS:
|
|
19
|
+
* - the preset menus (`RENDER_PT_format_presets` `:15`,
|
|
20
|
+
* `RENDER_MT_framerate_presets` `:28`, `RENDER_PT_ffmpeg_presets` `:22`)
|
|
21
|
+
* and `template_image_settings`/`template_image_views` — operator and
|
|
22
|
+
* template widgets. Inspection parity, not editing parity.
|
|
23
|
+
* - `RENDER_PT_output_pixel_density` (`:396`), whose body is a preset menu
|
|
24
|
+
* plus two properties behind it; the two are named here.
|
|
25
|
+
*
|
|
26
|
+
* It stands when: `buttons_context_path_scene` — the same path as Render.
|
|
27
|
+
*/
|
|
28
|
+
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
29
|
+
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
30
|
+
|
|
31
|
+
/** `properties_output.py`, panel by panel. Line numbers are that file's. */
|
|
32
|
+
const CURATED: readonly BlenderCuratedPanel[] = [
|
|
33
|
+
{
|
|
34
|
+
// RENDER_PT_format, :53 — the draw order is resolution, aspect, border,
|
|
35
|
+
// then the frame rate block (`draw_framerate`, :95).
|
|
36
|
+
title: 'Format',
|
|
37
|
+
properties: [
|
|
38
|
+
'resolution_x',
|
|
39
|
+
'resolution_y',
|
|
40
|
+
'resolution_percentage',
|
|
41
|
+
'pixel_aspect_x',
|
|
42
|
+
'pixel_aspect_y',
|
|
43
|
+
'use_border',
|
|
44
|
+
'use_crop_to_border',
|
|
45
|
+
'fps',
|
|
46
|
+
'fps_base',
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
// RENDER_PT_frame_range, :135 — the SCENE's, not the render settings'.
|
|
51
|
+
title: 'Frame Range',
|
|
52
|
+
properties: [
|
|
53
|
+
{ from: 'Scene', property: 'frame_start' },
|
|
54
|
+
{ from: 'Scene', property: 'frame_end' },
|
|
55
|
+
{ from: 'Scene', property: 'frame_step' },
|
|
56
|
+
],
|
|
57
|
+
sub: [
|
|
58
|
+
// RENDER_PT_time_stretching, :156.
|
|
59
|
+
{ title: 'Time Stretching', closed: true, properties: ['frame_map_old', 'frame_map_new'] },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
// RENDER_PT_stereoscopy, :676 — `use_multiview` is the header checkbox
|
|
64
|
+
// (:687); the views themselves are a `template_list` over `rd.views`.
|
|
65
|
+
title: 'Stereoscopy',
|
|
66
|
+
closed: true,
|
|
67
|
+
properties: ['use_multiview', 'views_format', 'views'],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
// RENDER_PT_output, :291.
|
|
71
|
+
title: 'Output',
|
|
72
|
+
properties: [
|
|
73
|
+
'save_output',
|
|
74
|
+
'filepath',
|
|
75
|
+
'use_file_extension',
|
|
76
|
+
'use_render_cache',
|
|
77
|
+
'use_overwrite',
|
|
78
|
+
'use_placeholder',
|
|
79
|
+
],
|
|
80
|
+
sub: [
|
|
81
|
+
// RENDER_PT_output_color_management, :351 — `image_settings.color_management`
|
|
82
|
+
// then the display device beneath it.
|
|
83
|
+
{
|
|
84
|
+
title: 'Color Management',
|
|
85
|
+
closed: true,
|
|
86
|
+
from: 'Image',
|
|
87
|
+
properties: ['color_management'],
|
|
88
|
+
},
|
|
89
|
+
// RENDER_PT_output_pixel_density, :396.
|
|
90
|
+
{ title: 'Pixel Density', closed: true, properties: ['ppm_factor', 'ppm_base'] },
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
// RENDER_PT_encoding, :473 — `rd.ffmpeg`, and its poll is the image
|
|
95
|
+
// format being one of FFMPEG/XVID/H264/THEORA (:496).
|
|
96
|
+
title: 'Encoding',
|
|
97
|
+
closed: true,
|
|
98
|
+
from: 'FFmpeg',
|
|
99
|
+
when: [
|
|
100
|
+
{
|
|
101
|
+
from: 'Image',
|
|
102
|
+
property: 'file_format',
|
|
103
|
+
is: ['FFMPEG', 'XVID', 'H264', 'THEORA'],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
properties: ['format', 'use_autosplit'],
|
|
107
|
+
sub: [
|
|
108
|
+
// RENDER_PT_encoding_video, :503.
|
|
109
|
+
{
|
|
110
|
+
title: 'Video',
|
|
111
|
+
from: 'FFmpeg',
|
|
112
|
+
properties: [
|
|
113
|
+
'codec',
|
|
114
|
+
{ from: 'Image', property: 'color_depth' },
|
|
115
|
+
'use_lossless_output',
|
|
116
|
+
'ffmpeg_prores_profile',
|
|
117
|
+
'constant_rate_factor',
|
|
118
|
+
'custom_constant_rate_factor',
|
|
119
|
+
'ffmpeg_preset',
|
|
120
|
+
'gopsize',
|
|
121
|
+
'use_max_b_frames',
|
|
122
|
+
'max_b_frames',
|
|
123
|
+
'video_bitrate',
|
|
124
|
+
'minrate',
|
|
125
|
+
'maxrate',
|
|
126
|
+
'buffersize',
|
|
127
|
+
'muxrate',
|
|
128
|
+
'packetsize',
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
// RENDER_PT_encoding_audio, :633.
|
|
132
|
+
{
|
|
133
|
+
title: 'Audio',
|
|
134
|
+
from: 'FFmpeg',
|
|
135
|
+
properties: [
|
|
136
|
+
'audio_codec',
|
|
137
|
+
'audio_channels',
|
|
138
|
+
'audio_mixrate',
|
|
139
|
+
'audio_volume',
|
|
140
|
+
'audio_bitrate',
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
// RENDER_PT_stamp, :200 — `metadata_input` is drawn first (:217), then
|
|
147
|
+
// the flag grid.
|
|
148
|
+
title: 'Metadata',
|
|
149
|
+
closed: true,
|
|
150
|
+
properties: [
|
|
151
|
+
'metadata_input',
|
|
152
|
+
'use_stamp_date',
|
|
153
|
+
'use_stamp_time',
|
|
154
|
+
'use_stamp_render_time',
|
|
155
|
+
'use_stamp_frame',
|
|
156
|
+
'use_stamp_frame_range',
|
|
157
|
+
'use_stamp_memory',
|
|
158
|
+
'use_stamp_hostname',
|
|
159
|
+
'use_stamp_camera',
|
|
160
|
+
'use_stamp_lens',
|
|
161
|
+
'use_stamp_scene',
|
|
162
|
+
'use_stamp_marker',
|
|
163
|
+
'use_stamp_filename',
|
|
164
|
+
'use_stamp_sequencer_strip',
|
|
165
|
+
],
|
|
166
|
+
sub: [
|
|
167
|
+
// RENDER_PT_stamp_note, :237 — `use_stamp_note` is its header checkbox.
|
|
168
|
+
{ title: 'Note', closed: true, properties: ['use_stamp_note', 'stamp_note_text'] },
|
|
169
|
+
// RENDER_PT_stamp_burn, :261 — `use_stamp` is its header checkbox.
|
|
170
|
+
{
|
|
171
|
+
title: 'Burn Into Image',
|
|
172
|
+
closed: true,
|
|
173
|
+
properties: [
|
|
174
|
+
'use_stamp',
|
|
175
|
+
'stamp_font_size',
|
|
176
|
+
'stamp_foreground',
|
|
177
|
+
'stamp_background',
|
|
178
|
+
'use_stamp_labels',
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
// RENDER_PT_post_processing, :178.
|
|
185
|
+
title: 'Post Processing',
|
|
186
|
+
closed: true,
|
|
187
|
+
properties: ['use_compositing', 'use_sequencer', 'dither_intensity'],
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
const TAB = { id: 'output', standing: 'any', curated: CURATED } as const;
|
|
192
|
+
|
|
193
|
+
export const point = 'selection.inspector';
|
|
194
|
+
export const title = 'Output';
|
|
195
|
+
/** `blender.icons.json` — Blender's own mark, TRACED from
|
|
196
|
+
* `release/datafiles/icons_svg/` at the engine's pin (the icon this tab draws
|
|
197
|
+
* is named in `buttons_context_items`, `makesrna/intern/rna_space.cc:579`),
|
|
198
|
+
* and tinted by the group `UI_icons.hh` declares it in. */
|
|
199
|
+
export const icon = 'properties-output';
|
|
200
|
+
/** `ED_buttons_tabs_list` (`space_buttons.cc:218-252`) is the rail's order;
|
|
201
|
+
* these are that order, spaced so a tab can be inserted between two. */
|
|
202
|
+
export const order = 20;
|
|
203
|
+
/** THE RAIL'S GROUPS, from `ED_buttons_tabs_list`'s own `add_spacer()` calls
|
|
204
|
+
* (`space_buttons/space_buttons.cc:201-255`): the tool tab, then the scene
|
|
205
|
+
* group (Render, Output, View Layer, Scene, World), then Collection, then the
|
|
206
|
+
* object group (Object … Material), then Texture. The presentation draws a
|
|
207
|
+
* separator wherever this changes. */
|
|
208
|
+
export const railGroup = 'scene';
|
|
209
|
+
export const match = blenderPropertiesTabMatch(TAB);
|
|
210
|
+
export default blenderPropertiesTabSection(TAB);
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BLENDER'S PARTICLES TAB, as a Properties section (WORK.md §Blender in the
|
|
3
|
+
* tab 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_particle.py` at the
|
|
7
|
+
* engine's pin — `classes` (`:2248-2302`) is the panel order, `bl_label` the
|
|
8
|
+
* title, each `layout.prop(part, "x")` an entry. Blender's UI layer is never
|
|
9
|
+
* run, ported or recorded.
|
|
10
|
+
*
|
|
11
|
+
* NEARLY EVERY PANEL DRAWS `psys.settings`, NOT THE SYSTEM. `part` in these
|
|
12
|
+
* draw functions is `particle_get_settings(context)` (`:40-46`), which is the
|
|
13
|
+
* active system's ParticleSettings — a datablock of its own. The system
|
|
14
|
+
* itself carries only a handful (`seed`, `parent`, `child_seed`, the
|
|
15
|
+
* vertex-group names, `use_hair_dynamics`). The context door names both, plus
|
|
16
|
+
* the hair-dynamics cloth settings, as this tab's paths, and each row says
|
|
17
|
+
* which it comes from.
|
|
18
|
+
*
|
|
19
|
+
* THE TYPE POLLS ARE READ, and this tab is why `when` exists. Blender gates
|
|
20
|
+
* these panels on values rather than on structure: `settings.type == 'HAIR'`
|
|
21
|
+
* (Hair Dynamics `:362`, Hair Shape `:2205`), `settings.physics_type` in
|
|
22
|
+
* NEWTON/FLUID or == BOIDS (`:1161`, `:1195`, `:1222`, `:934`),
|
|
23
|
+
* `settings.render_type` (`:1449`, `:1507`, `:1536`), `settings.child_type`
|
|
24
|
+
* (`:1743`, `:1778`), `settings.is_fluid` (`:272`). Every one of those
|
|
25
|
+
* properties is on the same struct under every mode, so RNA cannot answer the
|
|
26
|
+
* poll and the condition is read from the ENGINE's live value instead — a copy
|
|
27
|
+
* of Blender's test, never of its branching.
|
|
28
|
+
*
|
|
29
|
+
* WHAT THE TRANSCRIPTION DELIBERATELY DROPS:
|
|
30
|
+
* - `PARTICLE_PT_context_particles` (`:156`, `bl_label = ""`) — the systems
|
|
31
|
+
* list plus the settings ID template. The list itself is the first panel
|
|
32
|
+
* here, as a collection with the active system marked; the `template_ID`
|
|
33
|
+
* row is an editing widget.
|
|
34
|
+
* - the Boids panels (`:931`-`:1045`) and the fluid-spring panels
|
|
35
|
+
* (`:835`-`:928`): both read sub-structs of the settings (`part.boids`,
|
|
36
|
+
* `part.fluid`), which stand as POINTER rows in the Physics panel and
|
|
37
|
+
* drill. Naming a fourth and fifth datablock on this tab to reach a mode
|
|
38
|
+
* almost nothing uses is the machinery the generic view exists to avoid.
|
|
39
|
+
* - `PARTICLE_PT_boidbrain` (`:1254`) — a rules list with per-rule operators.
|
|
40
|
+
* - `template_curve_mapping` (the clump and roughness curves) — a curve
|
|
41
|
+
* widget this view does not draw.
|
|
42
|
+
* - `PARTICLE_PT_custom_props` (`:2243`), IDProperties rather than RNA.
|
|
43
|
+
*
|
|
44
|
+
* It stands when: `buttons_context_path_particle` — `ob->type == OB_MESH`.
|
|
45
|
+
*/
|
|
46
|
+
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
47
|
+
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
48
|
+
|
|
49
|
+
/** `settings.type == 'HAIR'` — the poll Hair Dynamics and Hair Shape share. */
|
|
50
|
+
const HAIR = [{ from: 'Settings', property: 'type', is: ['HAIR'] }] as const;
|
|
51
|
+
|
|
52
|
+
/** `properties_particle.py`, panel by panel. Line numbers are that file's. */
|
|
53
|
+
const CURATED: readonly BlenderCuratedPanel[] = [
|
|
54
|
+
{
|
|
55
|
+
// PARTICLE_UL_particle_systems, :131, drawn by
|
|
56
|
+
// PARTICLE_PT_context_particles' `template_list` (:183).
|
|
57
|
+
title: 'Particle Systems',
|
|
58
|
+
from: 'Particle Systems',
|
|
59
|
+
collection: true,
|
|
60
|
+
active: 'activeParticleSystem',
|
|
61
|
+
properties: ['name', 'settings'],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
// PARTICLE_PT_emission, :256. `psys.seed` (:293) is the SYSTEM's.
|
|
65
|
+
title: 'Emission',
|
|
66
|
+
from: 'Settings',
|
|
67
|
+
when: [{ from: 'Settings', property: 'is_fluid', is: [false] }],
|
|
68
|
+
properties: [
|
|
69
|
+
'count',
|
|
70
|
+
{ from: 'Active', property: 'seed' },
|
|
71
|
+
'hair_length',
|
|
72
|
+
'hair_step',
|
|
73
|
+
'frame_start',
|
|
74
|
+
'frame_end',
|
|
75
|
+
'lifetime',
|
|
76
|
+
'lifetime_random',
|
|
77
|
+
],
|
|
78
|
+
sub: [
|
|
79
|
+
{
|
|
80
|
+
// PARTICLE_PT_emission_source, :311.
|
|
81
|
+
title: 'Source',
|
|
82
|
+
closed: true,
|
|
83
|
+
from: 'Settings',
|
|
84
|
+
properties: [
|
|
85
|
+
'emit_from',
|
|
86
|
+
'use_modifier_stack',
|
|
87
|
+
'distribution',
|
|
88
|
+
'use_emit_random',
|
|
89
|
+
'invert_grid',
|
|
90
|
+
'hexagonal_grid',
|
|
91
|
+
'use_even_distribution',
|
|
92
|
+
'userjit',
|
|
93
|
+
'jitter_factor',
|
|
94
|
+
'grid_resolution',
|
|
95
|
+
'grid_random',
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
// PARTICLE_PT_hair_dynamics, :353 — `psys.use_hair_dynamics` is the header
|
|
102
|
+
// checkbox (:374) and the body is `psys.cloth.settings` (:390).
|
|
103
|
+
title: 'Hair Dynamics',
|
|
104
|
+
closed: true,
|
|
105
|
+
from: 'Hair Dynamics',
|
|
106
|
+
when: HAIR,
|
|
107
|
+
properties: [{ from: 'Active', property: 'use_hair_dynamics' }, 'quality', 'pin_stiffness'],
|
|
108
|
+
sub: [
|
|
109
|
+
{
|
|
110
|
+
// PARTICLE_PT_hair_dynamics_collision, :445 —
|
|
111
|
+
// `psys.cloth.collision_settings` (:463).
|
|
112
|
+
title: 'Collisions',
|
|
113
|
+
closed: true,
|
|
114
|
+
from: 'Hair Collisions',
|
|
115
|
+
properties: ['collision_quality', 'distance_min', 'impulse_clamp', 'collection'],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
// PARTICLE_PT_hair_dynamics_structure, :481 — `bending_random` is the
|
|
119
|
+
// SETTINGS', the rest the cloth's.
|
|
120
|
+
title: 'Structure',
|
|
121
|
+
closed: true,
|
|
122
|
+
from: 'Hair Dynamics',
|
|
123
|
+
properties: [
|
|
124
|
+
'mass',
|
|
125
|
+
'bending_stiffness',
|
|
126
|
+
{ from: 'Settings', property: 'bending_random' },
|
|
127
|
+
'bending_damping',
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
// PARTICLE_PT_hair_dynamics_volume, :516.
|
|
132
|
+
title: 'Volume',
|
|
133
|
+
closed: true,
|
|
134
|
+
from: 'Hair Dynamics',
|
|
135
|
+
properties: [
|
|
136
|
+
'air_damping',
|
|
137
|
+
'internal_friction',
|
|
138
|
+
'voxel_cell_size',
|
|
139
|
+
'density_target',
|
|
140
|
+
'density_strength',
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
// PARTICLE_PT_cache, :552 — `point_cache_ui(self, psys.point_cache, …)`,
|
|
147
|
+
// so the panel is that sub-struct and its pointer row stands.
|
|
148
|
+
title: 'Cache',
|
|
149
|
+
closed: true,
|
|
150
|
+
from: 'Active',
|
|
151
|
+
when: [{ from: 'Settings', property: 'physics_type', isNot: ['NO', 'KEYED'] }],
|
|
152
|
+
properties: ['point_cache'],
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
// PARTICLE_PT_velocity, :589.
|
|
156
|
+
title: 'Velocity',
|
|
157
|
+
closed: true,
|
|
158
|
+
from: 'Settings',
|
|
159
|
+
when: [{ from: 'Settings', property: 'physics_type', isNot: ['BOIDS'] }],
|
|
160
|
+
properties: [
|
|
161
|
+
'normal_factor',
|
|
162
|
+
'tangent_factor',
|
|
163
|
+
'tangent_phase',
|
|
164
|
+
'object_align_factor',
|
|
165
|
+
'particle_factor',
|
|
166
|
+
'object_factor',
|
|
167
|
+
'factor_random',
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
// PARTICLE_PT_rotation, :642 — `use_rotations` is the header checkbox.
|
|
172
|
+
title: 'Rotation',
|
|
173
|
+
closed: true,
|
|
174
|
+
from: 'Settings',
|
|
175
|
+
when: [{ from: 'Settings', property: 'physics_type', isNot: ['BOIDS'] }],
|
|
176
|
+
properties: [
|
|
177
|
+
'use_rotations',
|
|
178
|
+
'rotation_mode',
|
|
179
|
+
'rotation_factor_random',
|
|
180
|
+
'phase_factor',
|
|
181
|
+
'phase_factor_random',
|
|
182
|
+
'use_dynamic_rotation',
|
|
183
|
+
],
|
|
184
|
+
sub: [
|
|
185
|
+
{
|
|
186
|
+
// PARTICLE_PT_rotation_angular_velocity, :700.
|
|
187
|
+
title: 'Angular Velocity',
|
|
188
|
+
closed: true,
|
|
189
|
+
from: 'Settings',
|
|
190
|
+
properties: ['angular_velocity_mode', 'angular_velocity_factor'],
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
// PARTICLE_PT_physics, :730. `boids` and `fluid` are the two mode
|
|
196
|
+
// sub-structs whose own panels are one drill away (see the header).
|
|
197
|
+
title: 'Physics',
|
|
198
|
+
closed: true,
|
|
199
|
+
from: 'Settings',
|
|
200
|
+
properties: [
|
|
201
|
+
'physics_type',
|
|
202
|
+
'mass',
|
|
203
|
+
'use_multiply_size_mass',
|
|
204
|
+
'keyed_loops',
|
|
205
|
+
{ from: 'Active', property: 'use_keyed_timing' },
|
|
206
|
+
'fluid',
|
|
207
|
+
'boids',
|
|
208
|
+
],
|
|
209
|
+
sub: [
|
|
210
|
+
{
|
|
211
|
+
// PARTICLE_PT_physics_forces, :1187.
|
|
212
|
+
title: 'Forces',
|
|
213
|
+
from: 'Settings',
|
|
214
|
+
when: [{ from: 'Settings', property: 'physics_type', is: ['NEWTON', 'FLUID'] }],
|
|
215
|
+
properties: ['brownian_factor', 'drag_factor', 'damping'],
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
// PARTICLE_PT_physics_deflection, :1156.
|
|
219
|
+
title: 'Deflection',
|
|
220
|
+
closed: true,
|
|
221
|
+
from: 'Settings',
|
|
222
|
+
when: [{ from: 'Settings', property: 'physics_type', is: ['NEWTON', 'FLUID'] }],
|
|
223
|
+
properties: ['use_size_deflect', 'use_die_on_collision', 'collision_collection'],
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
// PARTICLE_PT_physics_integration, :1217.
|
|
227
|
+
title: 'Integration',
|
|
228
|
+
closed: true,
|
|
229
|
+
from: 'Settings',
|
|
230
|
+
when: [{ from: 'Settings', property: 'physics_type', is: ['NEWTON', 'FLUID'] }],
|
|
231
|
+
properties: [
|
|
232
|
+
'integrator',
|
|
233
|
+
'timestep',
|
|
234
|
+
'subframes',
|
|
235
|
+
'use_adaptive_subframes',
|
|
236
|
+
'courant_target',
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
// PARTICLE_PT_render, :1362 — `psys.parent` (:1407) is the SYSTEM's.
|
|
243
|
+
title: 'Render',
|
|
244
|
+
closed: true,
|
|
245
|
+
from: 'Settings',
|
|
246
|
+
properties: [
|
|
247
|
+
'render_type',
|
|
248
|
+
'particle_size',
|
|
249
|
+
'size_random',
|
|
250
|
+
'material_slot',
|
|
251
|
+
{ from: 'Active', property: 'parent' },
|
|
252
|
+
],
|
|
253
|
+
sub: [
|
|
254
|
+
{
|
|
255
|
+
// PARTICLE_PT_render_path, :1443.
|
|
256
|
+
title: 'Path',
|
|
257
|
+
from: 'Settings',
|
|
258
|
+
when: [{ from: 'Settings', property: 'render_type', is: ['PATH'] }],
|
|
259
|
+
properties: ['use_hair_bspline', 'render_step'],
|
|
260
|
+
sub: [
|
|
261
|
+
{
|
|
262
|
+
// PARTICLE_PT_render_path_timing, :1468.
|
|
263
|
+
title: 'Timing',
|
|
264
|
+
closed: true,
|
|
265
|
+
from: 'Settings',
|
|
266
|
+
properties: ['use_absolute_path_time', 'path_start', 'path_end', 'length_random'],
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
// PARTICLE_PT_render_object, :1501.
|
|
272
|
+
title: 'Object',
|
|
273
|
+
from: 'Settings',
|
|
274
|
+
when: [{ from: 'Settings', property: 'render_type', is: ['OBJECT'] }],
|
|
275
|
+
properties: [
|
|
276
|
+
'instance_object',
|
|
277
|
+
'use_global_instance',
|
|
278
|
+
'use_rotation_instance',
|
|
279
|
+
'use_scale_instance',
|
|
280
|
+
],
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
// PARTICLE_PT_render_collection, :1530, with its Use Count child
|
|
284
|
+
// (:1563) over `part.instance_weights`.
|
|
285
|
+
title: 'Collection',
|
|
286
|
+
from: 'Settings',
|
|
287
|
+
when: [{ from: 'Settings', property: 'render_type', is: ['COLLECTION'] }],
|
|
288
|
+
properties: [
|
|
289
|
+
'instance_collection',
|
|
290
|
+
'use_whole_collection',
|
|
291
|
+
'use_collection_pick_random',
|
|
292
|
+
'use_global_instance',
|
|
293
|
+
'use_rotation_instance',
|
|
294
|
+
'use_scale_instance',
|
|
295
|
+
],
|
|
296
|
+
sub: [
|
|
297
|
+
{
|
|
298
|
+
title: 'Use Count',
|
|
299
|
+
closed: true,
|
|
300
|
+
from: 'Settings',
|
|
301
|
+
properties: ['use_collection_count', 'instance_weights'],
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
// PARTICLE_PT_render_extra, :1414.
|
|
307
|
+
title: 'Extra',
|
|
308
|
+
closed: true,
|
|
309
|
+
from: 'Settings',
|
|
310
|
+
when: [{ from: 'Settings', property: 'render_type', isNot: ['NONE'] }],
|
|
311
|
+
properties: ['use_parent_particles', 'show_unborn', 'use_dead'],
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
// PARTICLE_PT_draw, :1618.
|
|
317
|
+
title: 'Viewport Display',
|
|
318
|
+
closed: true,
|
|
319
|
+
from: 'Settings',
|
|
320
|
+
properties: [
|
|
321
|
+
'display_method',
|
|
322
|
+
'display_color',
|
|
323
|
+
'color_maximum',
|
|
324
|
+
'display_percentage',
|
|
325
|
+
'display_step',
|
|
326
|
+
'display_size',
|
|
327
|
+
],
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
// PARTICLE_PT_children, :1680 — `psys.child_seed` (:1718) is the SYSTEM's.
|
|
331
|
+
title: 'Children',
|
|
332
|
+
closed: true,
|
|
333
|
+
from: 'Settings',
|
|
334
|
+
properties: [
|
|
335
|
+
'child_type',
|
|
336
|
+
'child_percent',
|
|
337
|
+
'rendered_child_count',
|
|
338
|
+
'child_length',
|
|
339
|
+
'child_length_threshold',
|
|
340
|
+
{ from: 'Active', property: 'child_seed' },
|
|
341
|
+
'virtual_parents',
|
|
342
|
+
'create_long_hair_children',
|
|
343
|
+
'child_size',
|
|
344
|
+
'child_size_random',
|
|
345
|
+
'child_radius',
|
|
346
|
+
'child_roundness',
|
|
347
|
+
],
|
|
348
|
+
sub: [
|
|
349
|
+
{
|
|
350
|
+
// PARTICLE_PT_children_parting, :1737.
|
|
351
|
+
title: 'Parting',
|
|
352
|
+
closed: true,
|
|
353
|
+
from: 'Settings',
|
|
354
|
+
when: [{ from: 'Settings', property: 'child_type', is: ['INTERPOLATED'] }],
|
|
355
|
+
properties: ['child_parting_factor', 'child_parting_min', 'child_parting_max'],
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
// PARTICLE_PT_children_clumping, :1772, with Clump Noise (:1812).
|
|
359
|
+
title: 'Clumping',
|
|
360
|
+
closed: true,
|
|
361
|
+
from: 'Settings',
|
|
362
|
+
when: [{ from: 'Settings', property: 'child_type', isNot: ['NONE'] }],
|
|
363
|
+
properties: ['use_clump_curve', 'clump_factor', 'clump_shape', 'twist', 'use_twist_curve'],
|
|
364
|
+
sub: [
|
|
365
|
+
{
|
|
366
|
+
title: 'Clump Noise',
|
|
367
|
+
closed: true,
|
|
368
|
+
from: 'Settings',
|
|
369
|
+
properties: ['use_clump_noise', 'clump_noise_size'],
|
|
370
|
+
},
|
|
371
|
+
],
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
// PARTICLE_PT_children_roughness, :1839.
|
|
375
|
+
title: 'Roughness',
|
|
376
|
+
closed: true,
|
|
377
|
+
from: 'Settings',
|
|
378
|
+
when: [{ from: 'Settings', property: 'child_type', isNot: ['NONE'] }],
|
|
379
|
+
properties: [
|
|
380
|
+
'use_roughness_curve',
|
|
381
|
+
'roughness_1',
|
|
382
|
+
'roughness_1_size',
|
|
383
|
+
'roughness_endpoint',
|
|
384
|
+
'roughness_end_shape',
|
|
385
|
+
'roughness_2',
|
|
386
|
+
'roughness_2_size',
|
|
387
|
+
'roughness_2_threshold',
|
|
388
|
+
],
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
// PARTICLE_PT_children_kink, :1885.
|
|
392
|
+
title: 'Kink',
|
|
393
|
+
closed: true,
|
|
394
|
+
from: 'Settings',
|
|
395
|
+
when: [{ from: 'Settings', property: 'child_type', isNot: ['NONE'] }],
|
|
396
|
+
properties: [
|
|
397
|
+
'kink',
|
|
398
|
+
'kink_amplitude',
|
|
399
|
+
'kink_amplitude_random',
|
|
400
|
+
'kink_amplitude_clump',
|
|
401
|
+
'kink_axis',
|
|
402
|
+
'kink_axis_random',
|
|
403
|
+
'kink_frequency',
|
|
404
|
+
'kink_shape',
|
|
405
|
+
'kink_extra_steps',
|
|
406
|
+
'kink_flat',
|
|
407
|
+
],
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
// PARTICLE_PT_hair_shape, :2196.
|
|
413
|
+
title: 'Hair Shape',
|
|
414
|
+
closed: true,
|
|
415
|
+
from: 'Settings',
|
|
416
|
+
when: HAIR,
|
|
417
|
+
properties: ['shape', 'root_radius', 'tip_radius', 'radius_scale', 'use_close_tip'],
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
// PARTICLE_PT_field_weights, :1940 — `effector_weights_ui` over
|
|
421
|
+
// `part.effector_weights`, plus two of the settings' own.
|
|
422
|
+
title: 'Field Weights',
|
|
423
|
+
closed: true,
|
|
424
|
+
from: 'Settings',
|
|
425
|
+
properties: ['effector_weights', 'apply_effector_to_children', 'effect_hair'],
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
// PARTICLE_PT_force_fields, :1965, and its two type children (:1985,
|
|
429
|
+
// :2006), which draw `part.force_field_1` / `_2`.
|
|
430
|
+
title: 'Force Field Settings',
|
|
431
|
+
closed: true,
|
|
432
|
+
from: 'Settings',
|
|
433
|
+
properties: ['use_self_effect', 'effector_amount', 'force_field_1', 'force_field_2'],
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
// PARTICLE_PT_vertexgroups, :2067 — every row is the SYSTEM's.
|
|
437
|
+
title: 'Vertex Groups',
|
|
438
|
+
closed: true,
|
|
439
|
+
from: 'Active',
|
|
440
|
+
properties: [
|
|
441
|
+
'vertex_group_density',
|
|
442
|
+
'invert_vertex_group_density',
|
|
443
|
+
'vertex_group_length',
|
|
444
|
+
'invert_vertex_group_length',
|
|
445
|
+
'vertex_group_clump',
|
|
446
|
+
'invert_vertex_group_clump',
|
|
447
|
+
'vertex_group_kink',
|
|
448
|
+
'invert_vertex_group_kink',
|
|
449
|
+
'vertex_group_roughness_1',
|
|
450
|
+
'invert_vertex_group_roughness_1',
|
|
451
|
+
'vertex_group_roughness_2',
|
|
452
|
+
'invert_vertex_group_roughness_2',
|
|
453
|
+
'vertex_group_roughness_end',
|
|
454
|
+
'invert_vertex_group_roughness_end',
|
|
455
|
+
'vertex_group_twist',
|
|
456
|
+
'invert_vertex_group_twist',
|
|
457
|
+
],
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
// PARTICLE_PT_textures, :2160 — `template_list` over `part.texture_slots`.
|
|
461
|
+
title: 'Textures',
|
|
462
|
+
closed: true,
|
|
463
|
+
from: 'Settings',
|
|
464
|
+
properties: ['texture_slots', 'active_texture'],
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
// PARTICLE_PT_animation, :2230.
|
|
468
|
+
title: 'Animation',
|
|
469
|
+
closed: true,
|
|
470
|
+
from: 'Settings',
|
|
471
|
+
properties: ['animation_data'],
|
|
472
|
+
},
|
|
473
|
+
];
|
|
474
|
+
|
|
475
|
+
const TAB = { id: 'particle', curated: CURATED } as const;
|
|
476
|
+
|
|
477
|
+
export const point = 'selection.inspector';
|
|
478
|
+
export const title = 'Particles';
|
|
479
|
+
/** `blender.icons.json` — Blender's own mark, TRACED from
|
|
480
|
+
* `release/datafiles/icons_svg/` at the engine's pin (the icon this tab draws
|
|
481
|
+
* is named in `buttons_context_items`, `makesrna/intern/rna_space.cc:579`),
|
|
482
|
+
* and tinted by the group `UI_icons.hh` declares it in. */
|
|
483
|
+
export const icon = 'properties-particles';
|
|
484
|
+
/** `ED_buttons_tabs_list` (`space_buttons.cc:218-252`) is the rail's order;
|
|
485
|
+
* these are that order, spaced so a tab can be inserted between two. */
|
|
486
|
+
export const order = 90;
|
|
487
|
+
/** THE RAIL'S GROUPS, from `ED_buttons_tabs_list`'s own `add_spacer()` calls
|
|
488
|
+
* (`space_buttons/space_buttons.cc:201-255`): the tool tab, then the scene
|
|
489
|
+
* group (Render, Output, View Layer, Scene, World), then Collection, then the
|
|
490
|
+
* object group (Object … Material), then Texture. The presentation draws a
|
|
491
|
+
* separator wherever this changes. */
|
|
492
|
+
export const railGroup = 'object';
|
|
493
|
+
export const match = blenderPropertiesTabMatch(TAB);
|
|
494
|
+
export default blenderPropertiesTabSection(TAB);
|