@volter/editor-blender 0.1.150 → 0.1.151
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 +18 -9
- package/README.md +5 -5
- package/contributions/blender-animation-editors.tsx +17 -69
- package/contributions/blender-display-settings.ts +36 -0
- package/contributions/blender-export-gltf.ts +228 -0
- package/contributions/blender-export.verbs.ts +39 -0
- package/contributions/blender-gltf-export.verbs.ts +312 -0
- package/contributions/blender-header-menus.tsx +37 -133
- package/contributions/blender-icon-trace.mjs +8 -98
- package/contributions/blender-icons.source.mjs +96 -860
- package/contributions/blender-mixer-pose.ts +369 -0
- package/contributions/blender-model-opening.tsx +3 -7
- package/contributions/blender-node-editor.document.tsx +28 -180
- package/contributions/blender-node-geometry.ts +44 -230
- package/contributions/blender-node-panels.source.mjs +7 -121
- package/contributions/blender-outliner-authoring.ts +61 -415
- package/contributions/blender-outliner-model.ts +15 -112
- package/contributions/blender-play-area.tsx +100 -0
- package/contributions/blender-playback-movie.ts +409 -0
- package/contributions/blender-pose.ts +18 -368
- package/contributions/blender-properties-context.ts +1 -1
- package/contributions/blender-properties-model.ts +15 -90
- package/contributions/blender-properties-tab.tsx +3 -50
- package/contributions/blender-properties-view.tsx +15 -147
- package/contributions/blender-remedy.ts +14 -0
- package/contributions/blender-runtime-skin.ts +103 -99
- package/contributions/blender-runtime.document.tsx +217 -339
- package/contributions/blender-scene-mixer.ts +51 -0
- package/contributions/blender-screenshot.service.ts +28 -0
- package/contributions/blender-timeline-geometry.ts +16 -136
- package/contributions/blender-timeline.document.tsx +142 -332
- package/contributions/blender-uv-editor.document.tsx +48 -112
- package/contributions/blender-uv-geometry.ts +14 -179
- package/contributions/blender-version.status.tsx +43 -23
- package/contributions/blender.environment.ts +2 -2
- package/contributions/blender.icons.json +0 -9
- package/contributions/blender.keymap.ts +9 -51
- package/contributions/blender.node-panels.json +4 -13
- package/contributions/blender.page.ts +63 -0
- package/contributions/blender.status.tsx +9 -145
- package/contributions/blender.style.ts +25 -152
- package/contributions/blender.verbs.ts +52 -0
- package/contributions/model.layout.ts +2 -34
- package/contributions/models.finder.ts +12 -32
- package/contributions/properties-bone-constraints.inspector.tsx +1 -16
- package/contributions/properties-bone.inspector.tsx +2 -31
- package/contributions/properties-collection.inspector.tsx +1 -34
- package/contributions/properties-constraints.inspector.tsx +1 -21
- package/contributions/properties-data.inspector.tsx +2 -39
- package/contributions/properties-material.inspector.tsx +2 -33
- package/contributions/properties-modifiers.inspector.tsx +2 -30
- package/contributions/properties-object.inspector.tsx +2 -44
- package/contributions/properties-output.inspector.tsx +1 -27
- package/contributions/properties-particles.inspector.tsx +2 -46
- package/contributions/properties-physics.inspector.tsx +2 -41
- package/contributions/properties-render.inspector.tsx +1 -45
- package/contributions/properties-scene.inspector.tsx +1 -35
- package/contributions/properties-texture.inspector.tsx +1 -49
- package/contributions/properties-view-layer.inspector.tsx +1 -29
- package/contributions/properties-world.inspector.tsx +2 -39
- package/contributions/shading.layout.ts +3 -78
- package/contributions/uv-editing.layout.ts +3 -70
- package/dist-node/serving.mjs +13 -30
- package/host/blender-runtime-host.ts +541 -372
- package/host/scene-sound.ts +143 -0
- package/node/blender-mcp.ts +49 -93
- package/package.json +1209 -46
- package/producticons/blender-icons.otf +0 -0
- package/producticons/blender-product-icon-theme.json +129 -0
- package/serving/blender-routes.ts +9 -43
- package/serving/blender-wasm-artifact.ts +29 -166
- package/serving/index.ts +1 -1
- package/src/api.ts +9 -0
- package/src/layouts.tsx +1 -17
- package/src/looks.ts +1 -12
- package/src/model-document-saving.ts +25 -0
- package/src/model-play-extension.ts +173 -0
- package/src/node-view-state.ts +3 -25
- package/src/play-mode.ts +64 -38
- package/src/presentation.ts +6 -18
- package/src/regions.ts +3 -43
- package/src/start-document.ts +15 -0
- package/src/timeline-view-state.ts +4 -39
- package/src/uv-view-state.ts +4 -20
- package/themes/blender.json +299 -0
- package/view/blender-view-routes.ts +1 -1
- package/contributions/blender-game-panel.tsx +0 -809
- package/contributions/blender-palette.source.mjs +0 -350
- package/contributions/blender-play-skin.ts +0 -508
- package/contributions/blender-screenshot.menu.ts +0 -32
- package/contributions/blender.command.ts +0 -109
- package/contributions/blender.palette.json +0 -102
- package/src/play-live.ts +0 -27
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Session Blender verbs relay to volter.<verb> commands registered by the page half. Each manifest entry owns its timeout and derived-refresh policy. Mutating commands present a frame and refresh the document; handlers use only SDK host doors. */
|
|
2
|
+
import type { VerbHandler } from '@volter/sdk/commands';
|
|
3
|
+
import { handleBlenderCommand } from '../host/blender-runtime-host';
|
|
4
|
+
|
|
5
|
+
/** The lane's one handler, for every verb. */
|
|
6
|
+
const handle: VerbHandler = (cmd) => handleBlenderCommand(cmd as { type: string; [key: string]: unknown });
|
|
7
|
+
|
|
8
|
+
export const blenderVerbs: Readonly<Record<string, VerbHandler>> = {
|
|
9
|
+
// Presentation-only comparison, no engine mutation or derived frame refresh.
|
|
10
|
+
'blender-draw-batching': handle,
|
|
11
|
+
'blender-start': handle,
|
|
12
|
+
// Stop drains accepted modeling work and persists it before teardown.
|
|
13
|
+
'blender-stop': handle,
|
|
14
|
+
'blender-execute': handle,
|
|
15
|
+
'blender-native-preview': handle,
|
|
16
|
+
'blender-scene-info': handle,
|
|
17
|
+
'blender-object-info': handle,
|
|
18
|
+
'blender-screenshot-view': handle,
|
|
19
|
+
'blender-read-file': handle,
|
|
20
|
+
'blender-write-file': handle,
|
|
21
|
+
// File listing uses the worker-read timeout while presentation and derived reads finish.
|
|
22
|
+
'blender-list-files': handle,
|
|
23
|
+
// RNA reads expose properties and context without presenting; RNA writes mutate, present and derive.
|
|
24
|
+
'blender-rna': handle,
|
|
25
|
+
'blender-rna-context': handle,
|
|
26
|
+
'blender-rna-set': handle,
|
|
27
|
+
// Outliner reads expose the View Layer tree; restriction writes mutate, present and derive.
|
|
28
|
+
'blender-outliner': handle,
|
|
29
|
+
// The node-tree door is read-only and requires no derivation.
|
|
30
|
+
'blender-node-tree': handle,
|
|
31
|
+
// The UV door reads one mesh layout; no UV writer is registered here.
|
|
32
|
+
'blender-uv-layout': handle,
|
|
33
|
+
// THE RIG AND CLIP DOORS (the Timeline). Both READS — the skin binding a
|
|
34
|
+
// `THREE.SkinnedMesh` is built from and the action as three.js tracks — so
|
|
35
|
+
// neither presents and neither owes a derivation. There is deliberately no
|
|
36
|
+
// writer beside them: keying, moving a key and setting a range are edits,
|
|
37
|
+
// and the ONE write the Timeline makes (`scene.frame_current`, once on
|
|
38
|
+
// pause and at scrub-end) goes through `blender-rna-set`, which already
|
|
39
|
+
// exists and already presents.
|
|
40
|
+
'blender-action-clip': handle,
|
|
41
|
+
// Node-view commands inspect and navigate view state. Editing gestures return the same named refusal as pointer handlers.
|
|
42
|
+
'blender-node-view': handle,
|
|
43
|
+
'blender-outliner-set': handle,
|
|
44
|
+
// A FILM, RENDERED (`cyclotron render-movie`, a film's Blender shots): started, answering at once, then followed
|
|
45
|
+
// until it ends. The frames are Blender's own renders; each chunk puts the scene's render settings and frame back, so
|
|
46
|
+
// none presents a change to the model.
|
|
47
|
+
'blender-render-movie': handle,
|
|
48
|
+
'blender-render-status': handle,
|
|
49
|
+
// A read of whether this tab HAS a session; it never starts one — and the
|
|
50
|
+
// one verb that answers before a project session exists.
|
|
51
|
+
'blender-status': handle,
|
|
52
|
+
};
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The MODEL workspace — Blender-shaped modeling: a dominant document, outliner
|
|
3
|
-
* above properties (`@volter/sdk/looks`, a `workspace.layout`
|
|
4
|
-
* contribution). Its arrangement carries Blender 5.2's own MODELING-workspace
|
|
5
|
-
* proportions; `../src/layouts.tsx` states the measurement and the host's
|
|
6
|
-
* fixed-pane clamp that bounds it.
|
|
7
|
-
*/
|
|
1
|
+
/** Model workspace: a dominant document, outliner above Properties and a lower Timeline area. The workbench owns pane geometry. */
|
|
8
2
|
|
|
9
3
|
import type { WorkspaceLayoutContribution } from '@volter/sdk/looks';
|
|
10
4
|
import { BLENDER_REGIONS } from '../src/regions';
|
|
@@ -26,32 +20,6 @@ export const layout: WorkspaceLayoutContribution = {
|
|
|
26
20
|
inspector: 'properties',
|
|
27
21
|
drawer: 'hidden',
|
|
28
22
|
},
|
|
29
|
-
//
|
|
30
|
-
// a timeline at the bottom?"). It does — and the workspace this Model
|
|
31
|
-
// document stands in is Blender's LAYOUT screen for us, not its Modeling
|
|
32
|
-
// one: Layout is the four-area screen with the Timeline, and Modeling is the
|
|
33
|
-
// same screen WITHOUT it (measured below).
|
|
34
|
-
//
|
|
35
|
-
// THE PROPORTION IS BLENDER'S OWN, measured through bpy on the installed
|
|
36
|
-
// Blender 5.2.1 at factory settings in a 1920-wide window
|
|
37
|
-
// (`bpy.data.workspaces['Layout'].screens[0].areas`):
|
|
38
|
-
//
|
|
39
|
-
// PROPERTIES x1579 y23 w339 h839
|
|
40
|
-
// OUTLINER x1579 y865 w339 h189
|
|
41
|
-
// DOPESHEET_EDITOR x2 y23 w1574 h74 ui_type TIMELINE ← this area
|
|
42
|
-
// VIEW_3D x2 y100 w1574 h954
|
|
43
|
-
//
|
|
44
|
-
// and the same screen at a 1600×929 window gives the Timeline 63 of an
|
|
45
|
-
// 880-px centre column. Both are the same ratio to three places: 74/1029 =
|
|
46
|
-
// 0.0719 and 63/880 = 0.0716. The Modeling screen's own reading, for the
|
|
47
|
-
// contrast: VIEW_3D `x2 y23 w1574 h1031` and no DOPESHEET area at all.
|
|
48
|
-
//
|
|
49
|
-
// It is stated to four places because it is a measurement, not a preference;
|
|
50
|
-
// the dock uses it once, to size the group the first time this workspace
|
|
51
|
-
// stands up, and a capture of the settled grid wins afterwards.
|
|
52
|
-
//
|
|
53
|
-
// IN GAME MODE THE SAME AREA HOLDS THE GAME PANEL (`../src/play-mode.ts`):
|
|
54
|
-
// the document below draws the Timeline or the panel by the model's mode,
|
|
55
|
-
// so the area, its proportion and a person's resize all carry over.
|
|
23
|
+
// The Model workspace’s bottom editor area hosts the Timeline or Game panel. Initial Timeline ratio is Blender Layout’s 74/1029 ≈ 0.0719; a person’s later resize takes precedence.
|
|
56
24
|
areas: [{ id: 'timeline', document: 'blender-timeline.document', place: 'below', ratio: 0.0719 }],
|
|
57
25
|
};
|
|
@@ -1,33 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* The `modelsFromBlendFiles` FINDER (ARCHITECTURE-CORE §The project model,
|
|
3
|
-
* "A model is Blender data, and a prefab is not a model"): every `.blend`
|
|
4
|
-
* under the selection's `include` globs is a `model` document — a Blender
|
|
5
|
-
* file the engine in the tab opens, edits and saves. The bpy scripts that
|
|
6
|
-
* authored it are ordinary project files beside it (`src/models/<name>.py`);
|
|
7
|
-
* this document does not run them, a person or an agent does, through the
|
|
8
|
-
* session's Blender (`volter blender-mcp`).
|
|
9
|
-
*
|
|
10
|
-
* It replaced `modelsFromMeshModules`, which listed every module exporting
|
|
11
|
-
* `build(): THREE.BufferGeometry` (owner ruling 2026-09-19, "do the delete":
|
|
12
|
-
* the TypeScript mesh kit was the modeling engine while Blender could not run
|
|
13
|
-
* in the tab; it now does, and a model is Blender data).
|
|
14
|
-
*
|
|
15
|
-
* Select it in `editor/volter.adapter.ts`:
|
|
16
|
-
*
|
|
17
|
-
* documents: { find: [{ finder: 'modelsFromBlendFiles', include: ['src/models/**\/*.blend'] }] }
|
|
18
|
-
*
|
|
19
|
-
* THE SESSION'S OWN MODEL. A project that holds no `.blend` of its own still
|
|
20
|
-
* needs ONE model — it is what `blender-start` presents into and what a first
|
|
21
|
-
* bpy call models in, saved to the session's default `models/model.blend` — so
|
|
22
|
-
* when the selection finds no file, the finder lists the standing
|
|
23
|
-
* `blender:runtime` entry instead. Never beside a real model.
|
|
24
|
-
*
|
|
25
|
-
* This module is a plain object the HOST registers; it mounts no UI. It reads
|
|
26
|
-
* the project only through `input.files` — the PATHS matching those globs.
|
|
27
|
-
* Deliberately not `input.sources`: a `.blend` is binary, there is nothing in
|
|
28
|
-
* it a text walk could honestly read, and the entry is the file itself. It says
|
|
29
|
-
* so (`reads: 'files'`), and the host then lists the files without fetching them.
|
|
30
|
-
*/
|
|
1
|
+
|
|
31
2
|
|
|
32
3
|
import { z } from 'zod';
|
|
33
4
|
|
|
@@ -43,10 +14,15 @@ export const finder = {
|
|
|
43
14
|
.array(z.string().min(1))
|
|
44
15
|
.min(1)
|
|
45
16
|
.describe('Project-relative globs of the Blender files to list (`src/models/**/*.blend`)'),
|
|
17
|
+
defaultIn: z
|
|
18
|
+
.string()
|
|
19
|
+
.regex(/^[^/].*\/$/)
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('A project folder (`levels/`): where exactly one listed Blender file is in it, that file is the default document'),
|
|
46
22
|
})
|
|
47
23
|
.strict(),
|
|
48
24
|
run(
|
|
49
|
-
|
|
25
|
+
selection: { finder: 'modelsFromBlendFiles'; include: readonly string[]; defaultIn?: string },
|
|
50
26
|
input: { files?: readonly string[] },
|
|
51
27
|
) {
|
|
52
28
|
const entries = [];
|
|
@@ -74,6 +50,10 @@ export const finder = {
|
|
|
74
50
|
reach: { kind: 'root-mount' as const },
|
|
75
51
|
});
|
|
76
52
|
}
|
|
77
|
-
|
|
53
|
+
// (the adapter's author names the folder whose lone file is the default: a std game's one level opens as its document)
|
|
54
|
+
const within = selection.defaultIn === undefined ? []
|
|
55
|
+
: (input.files ?? []).filter((path) => path.endsWith('.blend') && path.startsWith(selection.defaultIn!));
|
|
56
|
+
const only = within.length === 1 ? `model:${within[0]!}` : undefined;
|
|
57
|
+
return { entries, notes, ...(only === undefined ? {} : { default: only }) };
|
|
78
58
|
},
|
|
79
59
|
} as const;
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S BONE CONSTRAINTS TAB, as a Properties section (WORK.md §Blender in
|
|
3
|
-
* the tab is Blender, "Inspection parity", I2): the active POSE BONE's
|
|
4
|
-
* constraint stack, with the generic view beneath under "All properties".
|
|
5
|
-
*
|
|
6
|
-
* It is the Object Constraints tab over a different datablock, and Blender
|
|
7
|
-
* says so itself: `properties_constraint.py` registers
|
|
8
|
-
* `BONE_PT_constraints` beside `OBJECT_PT_constraints` with the same
|
|
9
|
-
* `template_constraints()` body, differing only in reading
|
|
10
|
-
* `context.pose_bone.constraints`. So it shares the header list that module
|
|
11
|
-
* exports rather than restating it — a second copy is a second thing to keep
|
|
12
|
-
* in step.
|
|
13
|
-
*
|
|
14
|
-
* It stands when: `buttons_context_path_pose_bone` — a pose channel for the
|
|
15
|
-
* active bone, and never in Edit mode.
|
|
16
|
-
*/
|
|
1
|
+
/** Blender’s Bone Constraints Properties tab follows scripts/startup/bl_ui/properties_constraint.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
17
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
18
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
19
4
|
import { CONSTRAINT_HEADER } from './properties-constraints.inspector';
|
|
@@ -1,26 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S BONE TAB, as a Properties section (WORK.md §Blender in the tab is
|
|
3
|
-
* Blender, "Inspection parity", I2). Blender's own panels over the RNA door,
|
|
4
|
-
* with the generic view beneath under "All properties".
|
|
5
|
-
*
|
|
6
|
-
* THE SPECIFICATION IS `scripts/startup/bl_ui/properties_data_bone.py` at the
|
|
7
|
-
* engine's pin: its `classes` tuple is the panel order, `bl_label` the title,
|
|
8
|
-
* each `layout.prop(bone, "x")` an entry. Blender's UI layer is never run,
|
|
9
|
-
* ported or recorded.
|
|
10
|
-
*
|
|
11
|
-
* TWO DATABLOCKS, AND THAT IS THE WHOLE STRUCTURE OF THIS TAB. Blender's panels
|
|
12
|
-
* read `bone` (the armature's `Bone`, or the `EditBone` in Edit mode) for the
|
|
13
|
-
* rest pose — head, tail, roll, envelope, collections, display — and `pchan`
|
|
14
|
-
* (the `PoseBone`) for the POSE: its location/rotation/scale and its inverse
|
|
15
|
-
* kinematics. `buttons_context_path_bone` and `_pose_bone` build both, and the
|
|
16
|
-
* door hands this tab both as "Bone" and "Pose Bone", so each panel names the
|
|
17
|
-
* one Blender's draw function reads. That is why Transform below is split in
|
|
18
|
-
* two the way `BONE_PT_transform` (:39) is: its first half is `pchan`, its
|
|
19
|
-
* second `bone`.
|
|
20
|
-
*
|
|
21
|
-
* It stands when: `buttons_context_path_bone` — an armature with an ACTIVE bone
|
|
22
|
-
* (the edit bone in Edit mode).
|
|
23
|
-
*/
|
|
1
|
+
/** Blender’s Bone Properties tab follows scripts/startup/bl_ui/properties_data_bone.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
24
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
25
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
26
4
|
|
|
@@ -44,14 +22,7 @@ const CURATED: readonly BlenderCuratedPanel[] = [
|
|
|
44
22
|
],
|
|
45
23
|
},
|
|
46
24
|
{
|
|
47
|
-
// BONE_PT_transform
|
|
48
|
-
// NO MATRICES. The first cut named `matrix` and `matrix_local` beside them
|
|
49
|
-
// and the live read showed why Blender does not: a 3x3 and a 4x4 draw as
|
|
50
|
-
// twenty-five numbered rows, which buries the five values the panel is
|
|
51
|
-
// about. They are still in "All properties" beneath, where a matrix is
|
|
52
|
-
// something you go looking for. (`roll` is an EditBone property, so it
|
|
53
|
-
// draws in Edit mode and not in Object mode — the datablock's answer, not
|
|
54
|
-
// a condition of ours.)
|
|
25
|
+
// BONE_PT_transform rest geometry excludes matrices; those remain under All properties. roll exists only on EditBone and draws only when that datablock exposes it.
|
|
55
26
|
title: 'Transform',
|
|
56
27
|
from: 'Bone',
|
|
57
28
|
properties: ['head', 'tail', 'roll', 'length', 'lock'],
|
|
@@ -1,37 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S COLLECTION 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_collection.py` at the
|
|
7
|
-
* engine's pin — `classes` (`:146-155`) is the panel order and `bl_label` the
|
|
8
|
-
* title. Blender's UI layer is never run, ported or recorded.
|
|
9
|
-
*
|
|
10
|
-
* THE FIRST PANEL IS CALLED "VISIBILITY" AT THIS PIN, not "Restrictions":
|
|
11
|
-
* `COLLECTION_PT_collection_flags.bl_label` is `"Visibility"` (`:32`). Its
|
|
12
|
-
* child View Layer (`:47`) does not read the collection at all — it reads
|
|
13
|
-
* `view_layer.active_layer_collection` (`:56`), a different datablock, which
|
|
14
|
-
* the context door now names beside the collection as this tab's second path.
|
|
15
|
-
*
|
|
16
|
-
* TWO CHECKBOXES BLENDER DRAWS INVERTED. `hide_select` is labelled
|
|
17
|
-
* "Selectable" with `invert_checkbox=True` (`:41`) and `exclude` is labelled
|
|
18
|
-
* "Include" the same way (`:60`). What stands here is the RNA's own value
|
|
19
|
-
* under the RNA's own name, because inverting a value in the presentation is
|
|
20
|
-
* exactly the fabrication the anti-shim rule forbids — the same reading the
|
|
21
|
-
* Object tab's Visibility panel already made.
|
|
22
|
-
*
|
|
23
|
-
* WHAT THE TRANSCRIPTION DELIBERATELY DROPS: `COLLECTION_PT_importer`
|
|
24
|
-
* (`:65`), whose poll is a PREFERENCE (`prefs.experimental.use_collection_
|
|
25
|
-
* importer`) and whose body is `template_collection_importer()` — an operator
|
|
26
|
-
* template. Exporters (`:80`) is the same widget over `collection.exporters`,
|
|
27
|
-
* and the collection itself is real RNA (`rna_collection.cc:954`), so its row
|
|
28
|
-
* stands. `COLLECTION_PT_collection_custom_props` (`:143`) is IDProperties
|
|
29
|
-
* rather than RNA.
|
|
30
|
-
*
|
|
31
|
-
* It stands when: `buttons_context_path_collection` — the view layer's ACTIVE
|
|
32
|
-
* collection, and never the scene's master collection, which only the engine
|
|
33
|
-
* knows.
|
|
34
|
-
*/
|
|
1
|
+
/** Blender’s Collection Properties tab follows scripts/startup/bl_ui/properties_collection.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
35
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
36
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
37
4
|
|
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S OBJECT CONSTRAINTS TAB, as a Properties section (WORK.md §Blender
|
|
3
|
-
* in the tab is Blender, "Inspection parity", I2): the STACK, each constraint
|
|
4
|
-
* its own panel with its own settings, the generic view beneath under "All
|
|
5
|
-
* properties".
|
|
6
|
-
*
|
|
7
|
-
* THE SPECIFICATION IS `scripts/startup/bl_ui/properties_constraint.py`, and
|
|
8
|
-
* it has the same shape `properties_data_modifier.py` does: `draw` is
|
|
9
|
-
* `layout.template_constraints()` and the per-type panels are built in C from
|
|
10
|
-
* each constraint's RNA. So the stack is derived the same way — the shared
|
|
11
|
-
* `Constraint` header properties named, then everything THIS constraint's own
|
|
12
|
-
* struct declares (`andDeclared`, which reads `BlenderRnaRow.group`). A Copy
|
|
13
|
-
* Location constraint gets `CopyLocationConstraint`'s target, subtarget, use_x
|
|
14
|
-
* / use_y / use_z, invert flags and offset, in RNA's order.
|
|
15
|
-
*
|
|
16
|
-
* The ACTIVE constraint (`buttons_context_path_constraint`, reported as
|
|
17
|
-
* `activeConstraint`) is marked.
|
|
18
|
-
*
|
|
19
|
-
* It stands when: `buttons_context_path_object` — Constraints shares Object's
|
|
20
|
-
* path, so the engine grants it whenever it grants Object.
|
|
21
|
-
*/
|
|
1
|
+
/** Blender’s Object Constraints Properties tab follows scripts/startup/bl_ui/properties_constraint.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
22
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
23
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
24
4
|
|
|
@@ -1,36 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S OBJECT DATA 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 of the whole datablock beneath under "All
|
|
5
|
-
* properties".
|
|
6
|
-
*
|
|
7
|
-
* THE SPECIFICATION IS `scripts/startup/bl_ui/properties_data_mesh.py`, read
|
|
8
|
-
* at the engine's pin: its `classes` tuple is the panel ORDER, each class's
|
|
9
|
-
* `bl_label` the title, each `layout.prop(me, "x")` an entry in the order the
|
|
10
|
-
* draw function lists it, `bl_options = {'DEFAULT_CLOSED'}` a `closed`, and a
|
|
11
|
-
* `template_list` a `collection` panel. Blender's UI layer is never run,
|
|
12
|
-
* ported or recorded.
|
|
13
|
-
*
|
|
14
|
-
* ONE TAB, MANY DATA TYPES, ONE LIST. `buttons_context_path_data` builds this
|
|
15
|
-
* tab for whatever the object's data IS, so the same section draws a Mesh, an
|
|
16
|
-
* Armature, a Camera or a Light — and the panels for all of them live in one
|
|
17
|
-
* list here, because a panel draws only where its properties exist. A Camera's
|
|
18
|
-
* data carries no `remesh_mode`, so the Remesh panel finds nothing and renders
|
|
19
|
-
* nothing; an Armature's carries no `uv_layers` and every mesh panel stands
|
|
20
|
-
* down for it. That is the same answer `MeshButtonsPanel.poll` /
|
|
21
|
-
* `ArmatureButtonsPanel.poll` give, from the datablock rather than from a copy
|
|
22
|
-
* of their conditions — which is why there is no per-type branch in this file
|
|
23
|
-
* and no second module per data type.
|
|
24
|
-
*
|
|
25
|
-
* NO "NORMALS" PANEL: the brief expected one and 5.2 does not have it. The
|
|
26
|
-
* mesh's `DATA_PT_normals` was folded away before this pin — `has_custom_normals`
|
|
27
|
-
* survives as the Geometry Data panel's operator condition (`:456`), and the
|
|
28
|
-
* shading-per-face data now lives on the Attributes list. Stated rather than
|
|
29
|
-
* invented.
|
|
30
|
-
*
|
|
31
|
-
* It stands when: `buttons_context_path_data` — the object HAS data (an Empty
|
|
32
|
-
* usually has none).
|
|
33
|
-
*/
|
|
1
|
+
/** Blender’s Object Data Properties tab follows scripts/startup/bl_ui/properties_data_mesh.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
34
2
|
import type { ToolContributionNode } from '@volter/sdk/contributions';
|
|
35
3
|
import { blenderPropertiesState, resolveBlenderSubject } from './blender-properties-model';
|
|
36
4
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
@@ -93,12 +61,7 @@ const CURATED: readonly BlenderCuratedPanel[] = [
|
|
|
93
61
|
],
|
|
94
62
|
},
|
|
95
63
|
{
|
|
96
|
-
//
|
|
97
|
-
// OPERATORS and one condition (`has_custom_normals`, :456) — no
|
|
98
|
-
// properties at all. Inspection parity is not editing parity
|
|
99
|
-
// (ARCHITECTURE-CORE §Blender north star), so what stands here is the
|
|
100
|
-
// condition the operators branch on, which is the only thing in the panel
|
|
101
|
-
// a reader can learn something from.
|
|
64
|
+
// Geometry Data exposes the condition and selection counts; its editing operators are not drawn here.
|
|
102
65
|
title: 'Geometry Data',
|
|
103
66
|
closed: true,
|
|
104
67
|
properties: ['has_custom_normals', 'total_vert_sel', 'total_edge_sel', 'total_face_sel'],
|
|
@@ -1,34 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S MATERIAL 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_material.py` at the
|
|
7
|
-
* engine's pin — its `classes` tuple is the panel order, `bl_label` the
|
|
8
|
-
* title, each `layout.prop(mat, "x")` an entry. Blender's UI layer is never
|
|
9
|
-
* run, ported or recorded.
|
|
10
|
-
*
|
|
11
|
-
* THE SLOTS LIST IS FIRST, and it is `MATERIAL_UL_matslots` over
|
|
12
|
-
* `ob.material_slots` (`:76`, `EEVEE_MATERIAL_PT_context_material`, whose
|
|
13
|
-
* `bl_label` is empty because in Blender it is the tab's header block rather
|
|
14
|
-
* than a panel). The context door hands it to this tab as its own path, with
|
|
15
|
-
* the ACTIVE slot named separately (`buttons_context_path_material`:
|
|
16
|
-
* `BKE_object_material_get(ob, ob->actcol)`), so the list marks it.
|
|
17
|
-
*
|
|
18
|
-
* SURFACE IS A NODE TREE, AND THIS IS NOT THE NODE VIEW. Blender's Surface
|
|
19
|
-
* panel (`:164`) calls `panel_node_draw`, which walks the material output
|
|
20
|
-
* node's `Surface` input back to the shader that feeds it and draws THAT
|
|
21
|
-
* node's inputs by name. Showing those values as a flat list needs the node
|
|
22
|
-
* tree walked, which is I5's read-only node view (§Inspection parity, I5) —
|
|
23
|
-
* and a half version of it here would be a second, worse implementation of
|
|
24
|
-
* the same walk. What stands in this panel instead is what the MATERIAL
|
|
25
|
-
* itself holds: `use_nodes` and the `node_tree` pointer, which drills into
|
|
26
|
-
* the generic view, plus the settings Blender's own EEVEE panels read off the
|
|
27
|
-
* material datablock directly.
|
|
28
|
-
*
|
|
29
|
-
* It stands when: `buttons_context_path_material` — the object's data holds a
|
|
30
|
-
* `materials` collection (the tab stands even when the active slot is empty).
|
|
31
|
-
*/
|
|
1
|
+
/** Blender’s Material Properties tab follows scripts/startup/bl_ui/properties_material.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
32
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
33
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
34
4
|
|
|
@@ -44,8 +14,7 @@ const CURATED: readonly BlenderCuratedPanel[] = [
|
|
|
44
14
|
properties: ['name', 'material', 'link', 'slot_index'],
|
|
45
15
|
},
|
|
46
16
|
{
|
|
47
|
-
// EEVEE_MATERIAL_PT_surface, :164
|
|
48
|
-
// material's own two node properties rather than the shader's inputs.
|
|
17
|
+
// EEVEE_MATERIAL_PT_surface, :164. Read the material’s node properties; shader inputs belong to its node tree.
|
|
49
18
|
title: 'Surface',
|
|
50
19
|
from: 'Material',
|
|
51
20
|
properties: ['use_nodes', 'node_tree', 'surface_render_method', 'use_backface_culling'],
|
|
@@ -1,32 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S MODIFIERS TAB, as a Properties section (WORK.md §Blender in the
|
|
3
|
-
* tab is Blender, "Inspection parity", I2): the STACK, each modifier its own
|
|
4
|
-
* panel with its own settings, with the generic view beneath under "All
|
|
5
|
-
* properties".
|
|
6
|
-
*
|
|
7
|
-
* THE SPECIFICATION IS `scripts/startup/bl_ui/properties_data_modifier.py` at
|
|
8
|
-
* the engine's pin, and reading it is what decided the shape here. That file
|
|
9
|
-
* is barely a panel list at all: `DATA_PT_modifiers.draw` is `Add Modifier`
|
|
10
|
-
* plus `layout.template_modifiers()`, and the per-modifier panels are built in
|
|
11
|
-
* C from each type's own RNA (`MOD_*.cc`'s `panel_draw`). There is no Python
|
|
12
|
-
* table of sixty modifier types to transcribe — and transcribing one would be
|
|
13
|
-
* a COPY of Blender's layout, which the ruling forbids, and would go stale the
|
|
14
|
-
* first time a modifier gained a property.
|
|
15
|
-
*
|
|
16
|
-
* So the stack is derived instead: each member of `ob.modifiers` is a panel
|
|
17
|
-
* headed by the four toggles every modifier has (`ModifierData`'s own
|
|
18
|
-
* `show_viewport` / `show_render` / `show_in_editmode` / `show_on_cage`,
|
|
19
|
-
* which is the header row `template_modifiers` draws), followed by every
|
|
20
|
-
* property THIS MODIFIER'S OWN struct declares — `andDeclared`, which reads
|
|
21
|
-
* `BlenderRnaRow.group`, RNA's own answer to "which struct declares this".
|
|
22
|
-
* For a Subdivision modifier that is exactly `SubsurfModifier`'s levels,
|
|
23
|
-
* render_levels, quality, uv_smooth and the rest, in RNA's order.
|
|
24
|
-
*
|
|
25
|
-
* The ACTIVE modifier (`buttons_context_path_modifier`, which the door reports
|
|
26
|
-
* as `activeModifier`) is marked, the way Blender outlines the active panel.
|
|
27
|
-
*
|
|
28
|
-
* It stands when: the object's type is in `buttons_context.cc`'s modifier set.
|
|
29
|
-
*/
|
|
1
|
+
/** Blender’s Modifiers Properties tab follows scripts/startup/bl_ui/properties_data_modifier.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
30
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
31
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
32
4
|
|
|
@@ -37,7 +9,7 @@ const CURATED: readonly BlenderCuratedPanel[] = [
|
|
|
37
9
|
collection: true,
|
|
38
10
|
active: 'activeModifier',
|
|
39
11
|
// `ModifierData`'s own, in the order `template_modifiers` heads a panel
|
|
40
|
-
// with them; everything after these is the type's own
|
|
12
|
+
// with them; everything after these is the type's own.
|
|
41
13
|
properties: [
|
|
42
14
|
'name',
|
|
43
15
|
'type',
|
|
@@ -1,34 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BLENDER'S OBJECT TAB, as a Properties section (WORK.md §Blender in the tab
|
|
3
|
-
* is Blender, "Inspection parity", I2). The body is Blender's own panels, in
|
|
4
|
-
* Blender's own order, over the RNA door; the generic view of every property
|
|
5
|
-
* the object has stays beneath them under "All properties".
|
|
6
|
-
*
|
|
7
|
-
* THE SPECIFICATION IS `scripts/startup/bl_ui/properties_object.py`, read at
|
|
8
|
-
* the engine's pin. Its `classes` tuple at the foot of the file is the panel
|
|
9
|
-
* ORDER, each class's `bl_label` the title, each `layout.prop(ob, "x")` an
|
|
10
|
-
* entry below in the order the draw function lists it, and `bl_options =
|
|
11
|
-
* {'DEFAULT_CLOSED'}` a `closed: true`. Blender's UI layer is never run,
|
|
12
|
-
* ported or recorded — the Python is read as a statement of WHICH properties
|
|
13
|
-
* this tab shows, and our widgets draw them from the door's rows.
|
|
14
|
-
*
|
|
15
|
-
* WHAT THE TRANSCRIPTION DELIBERATELY DROPS:
|
|
16
|
-
* - type-only `poll`/`if` branches. `show_all_edges` is mesh-only in Python; here
|
|
17
|
-
* it is simply not on a Camera's RNA, so it does not draw. Same outcome,
|
|
18
|
-
* from the datablock rather than from a copy of Blender's conditions.
|
|
19
|
-
* Rotation mode is a value on every object, so its draw branch is retained.
|
|
20
|
-
* - `OBJECT_PT_context_object` (`bl_label = ""`) — the breadcrumb row, which
|
|
21
|
-
* is the host's identity row here.
|
|
22
|
-
* - the four panels whose datablock is NOT the object: Motion Paths reads
|
|
23
|
-
* `ob.animation_visualization` and `ob.motion_path`, Light/Shadow Linking
|
|
24
|
-
* their collections. The context door names the object, so those are
|
|
25
|
-
* reached by drilling their POINTER row in the generic view beneath — a
|
|
26
|
-
* curated panel addresses one of the TAB's own datablocks, and inventing a
|
|
27
|
-
* second addressing scheme to reach a sub-struct is the kind of machinery
|
|
28
|
-
* the generic view exists to make unnecessary.
|
|
29
|
-
*
|
|
30
|
-
* It stands when: `buttons_context_path_object` — there is an active object.
|
|
31
|
-
*/
|
|
1
|
+
/** Blender’s Object Properties tab follows scripts/startup/bl_ui/properties_object.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
32
2
|
|
|
33
3
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
34
4
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
@@ -196,19 +166,7 @@ export const order = 70;
|
|
|
196
166
|
* object group (Object … Material), then Texture. The presentation draws a
|
|
197
167
|
* separator wherever this changes. */
|
|
198
168
|
export const railGroup = 'object';
|
|
199
|
-
/**
|
|
200
|
-
* per screen in the startup file, and at factory settings the Layout
|
|
201
|
-
* workspace's is OBJECT:
|
|
202
|
-
*
|
|
203
|
-
* bpy.data.screens['Layout'].areas[PROPERTIES].spaces[0].context -> 'OBJECT'
|
|
204
|
-
*
|
|
205
|
-
* (measured against Blender 5.2.0 LTS at `--factory-startup`, walk 5 parity
|
|
206
|
-
* row 3; the other screens read OBJECT, MODIFIER, WORLD, DATA, TOOL, OUTPUT
|
|
207
|
-
* and RENDER, so a per-workspace default is the next fidelity step and this
|
|
208
|
-
* one declaration is the Layout/Model answer). Without it the rail opened on
|
|
209
|
-
* Render — the first tab in `ED_buttons_tabs_list`'s order — and a person
|
|
210
|
-
* selecting the cube got Sampling and Light Paths where Blender shows
|
|
211
|
-
* Transform. */
|
|
169
|
+
/** The Model Properties rail opens on Object, matching the factory Layout workspace’s context. */
|
|
212
170
|
export const railDefault = true;
|
|
213
171
|
export const match = blenderPropertiesTabMatch(TAB);
|
|
214
172
|
export default blenderPropertiesTabSection(TAB);
|
|
@@ -1,30 +1,4 @@
|
|
|
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
|
-
*/
|
|
1
|
+
/** Blender’s Output Properties tab follows scripts/startup/bl_ui/properties_output.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
28
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
29
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
30
4
|
|
|
@@ -1,48 +1,4 @@
|
|
|
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
|
-
*/
|
|
1
|
+
/** Blender’s Particles Properties tab follows scripts/startup/bl_ui/properties_particle.py at the engine pin. Curated panels read the RNA context’s datablocks; the generic view remains under All properties. Match tab availability and engine-specific panels against the live context. */
|
|
46
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
47
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
48
4
|
|
|
@@ -193,7 +149,7 @@ const CURATED: readonly BlenderCuratedPanel[] = [
|
|
|
193
149
|
},
|
|
194
150
|
{
|
|
195
151
|
// PARTICLE_PT_physics, :730. `boids` and `fluid` are the two mode
|
|
196
|
-
// sub-structs whose own panels are one drill away
|
|
152
|
+
// sub-structs whose own panels are one drill away.
|
|
197
153
|
title: 'Physics',
|
|
198
154
|
closed: true,
|
|
199
155
|
from: 'Settings',
|
|
@@ -1,42 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* BLENDER'S PHYSICS 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 SEVEN FILES, not one: `properties_physics_common.py`
|
|
7
|
-
* carries the tab's own header block, and `properties_physics_rigidbody.py`,
|
|
8
|
-
* `_rigidbody_constraint.py`, `_cloth.py`, `_softbody.py`, `_field.py`
|
|
9
|
-
* (Force Fields AND Collision), `_fluid.py` and `_dynamicpaint.py` each carry
|
|
10
|
-
* one simulation. Each panel below cites its file and line. Blender's UI
|
|
11
|
-
* layer is never run, ported or recorded.
|
|
12
|
-
*
|
|
13
|
-
* THE "ENABLE BUTTONS" ROW IS NOT DRAWN, AND WHAT IT SAYS STILL IS.
|
|
14
|
-
* `PHYSICS_PT_add` (`properties_physics_common.py:55`) is a grid of
|
|
15
|
-
* `object.modifier_add` / `rigidbody.object_add` OPERATORS — editing, not
|
|
16
|
-
* inspection (ARCHITECTURE-CORE §Blender north star), and this view draws
|
|
17
|
-
* properties. What that row COMMUNICATES is which simulations the object has,
|
|
18
|
-
* and that is exactly which panels stand here: the context door resolves a
|
|
19
|
-
* path per simulation the way `physics_add`/`physics_add_special` test for
|
|
20
|
-
* one — the data for `obj.rigid_body`, `obj.rigid_body_constraint`,
|
|
21
|
-
* `obj.soft_body`, `obj.collision` and `obj.field`, and a MODIFIER of the
|
|
22
|
-
* right type for cloth, fluid and dynamic paint (Blender's `context.cloth` is
|
|
23
|
-
* the ClothModifier, and the panels read its `settings` structs). An absent
|
|
24
|
-
* simulation is an absent path and its panels do not draw.
|
|
25
|
-
*
|
|
26
|
-
* FLUID AND DYNAMIC PAINT STOP AT THEIR TYPE. Both are a modifier whose whole
|
|
27
|
-
* panel set is per-`fluid_type` / per-`ui_type` — domain, flow and effector
|
|
28
|
-
* are three different property surfaces, and dynamic paint's canvas splits
|
|
29
|
-
* again per surface. What stands here is the modifier's type row and the
|
|
30
|
-
* pointer to the settings struct the type selects, which drills into the
|
|
31
|
-
* generic view; transcribing three or four alternative panel sets each is the
|
|
32
|
-
* machinery the generic view exists to make unnecessary. Stated, not
|
|
33
|
-
* silently partial.
|
|
34
|
-
*
|
|
35
|
-
* It stands when: `buttons_context_path_object` — Physics shares Object's
|
|
36
|
-
* path, so the engine grants it whenever it grants Object. It is
|
|
37
|
-
* context-gated rather than standing because the Properties editor follows
|
|
38
|
-
* the ACTIVE OBJECT, not the row that was clicked.
|
|
39
|
-
*/
|
|
1
|
+
|
|
40
2
|
import { blenderPropertiesTabMatch, blenderPropertiesTabSection } from './blender-properties-tab';
|
|
41
3
|
import type { BlenderCuratedPanel } from './blender-properties-view';
|
|
42
4
|
|
|
@@ -578,8 +540,7 @@ const CURATED: readonly BlenderCuratedPanel[] = [
|
|
|
578
540
|
],
|
|
579
541
|
},
|
|
580
542
|
{
|
|
581
|
-
// properties_physics_fluid.py
|
|
582
|
-
// type and the settings pointer.
|
|
543
|
+
// properties_physics_fluid.py: show the type and settings pointers; each pointer drills into its properties.
|
|
583
544
|
title: 'Fluid',
|
|
584
545
|
from: 'Fluid',
|
|
585
546
|
properties: ['fluid_type', 'domain_settings', 'flow_settings', 'effector_settings'],
|