@volter/editor-blender 0.1.152 → 0.1.154
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.
|
@@ -21,7 +21,7 @@ import type {
|
|
|
21
21
|
import type * as THREE from 'three';
|
|
22
22
|
import { threeObject } from '@volter/editor-threejs/adapter/three-contract';
|
|
23
23
|
import { viewportStages } from '@volter/editor-threejs/viewport-door';
|
|
24
|
-
import { blenderExecute, blenderRnaSet, beginBlenderGesture, endBlenderGesture } from '../host/blender-runtime-host';
|
|
24
|
+
import { blenderExecute, blenderRnaSet, blenderSelectionSet, beginBlenderGesture, endBlenderGesture } from '../host/blender-runtime-host';
|
|
25
25
|
import {
|
|
26
26
|
blenderEngineSelection,
|
|
27
27
|
blenderOutlinerState,
|
|
@@ -798,28 +798,13 @@ async function runBlenderOperator(
|
|
|
798
798
|
}
|
|
799
799
|
|
|
800
800
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
active
|
|
804
|
-
)
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
'for _o in _vl.objects:',
|
|
809
|
-
' _o.select_set(_o.name in _sel)',
|
|
810
|
-
// object_select.cc::base_deselect_all_ex changes BASE_SELECTED without
|
|
811
|
-
// clearing the active base. Properties continues to inspect that object.
|
|
812
|
-
...(active === null ? [] : [`_vl.objects.active = bpy.data.objects.get(${py(active)})`]),
|
|
813
|
-
].join('\n');
|
|
814
|
-
const answer = await blenderExecute(body, false);
|
|
815
|
-
// THE ENGINE'S REFUSAL, VERBATIM — never a shrug. A selection that did not
|
|
816
|
-
// land is the difference between the Properties rail showing this object and
|
|
817
|
-
// showing the last one, so it is said out loud on the editor's console.
|
|
818
|
-
if (answer.error !== null)
|
|
819
|
-
editorHost().console.error(
|
|
820
|
-
`Blender refused the selection write: ${answer.error}`,
|
|
821
|
-
'blender-outliner',
|
|
822
|
-
);
|
|
801
|
+
/** Blender's selection set to the editor's (`session.py::selection_set`), written only where the two differ:
|
|
802
|
+
* selection is saved in the .blend, so a write that matches what Blender holds would ask for a save of nothing.
|
|
803
|
+
* A null `active` leaves the active object as it is (`object_select.cc::base_deselect_all_ex` changes
|
|
804
|
+
* BASE_SELECTED without clearing the active base), so Properties keeps inspecting it. A refusal rejects, and the
|
|
805
|
+
* caller says it on the editor's console. */
|
|
806
|
+
async function writeBlenderSelection(names: readonly string[], active: string | null): Promise<void> {
|
|
807
|
+
await blenderSelectionSet(names, active);
|
|
823
808
|
}
|
|
824
809
|
|
|
825
810
|
/**
|
|
@@ -645,15 +645,23 @@ function BlenderViewportArea({
|
|
|
645
645
|
}, [main, documentId, view]);
|
|
646
646
|
/**
|
|
647
647
|
* A SHADING PICK IS KEPT WHERE BLENDER KEEPS IT: in the file's own 3D View, the one it reopens
|
|
648
|
-
* on (`blenderViewShading`), so the next save carries it and
|
|
649
|
-
*
|
|
650
|
-
*
|
|
648
|
+
* on (`blenderViewShading`), so the next save carries it and Blender opens the file in it. The
|
|
649
|
+
* editor reopens the document in the person's last view whether or not the file was saved (the
|
|
650
|
+
* view state, `document-view-states.ts` in editor-core); the file's shading is what a document
|
|
651
|
+
* with none opens in. Only a pick made while this area stands is written: the shading a recorded
|
|
652
|
+
* view state brings back is the checkout's, and writing it would let the person's next save
|
|
653
|
+
* carry it over the file's own. Noted on the view at once, so a remount before the next frame
|
|
654
|
+
* reads the pick and not the file's old shading. Modes Blender's four cells do not name (Clay,
|
|
655
|
+
* Matcap…) stay the editor's.
|
|
651
656
|
*/
|
|
652
657
|
useEffect(() => {
|
|
653
658
|
if (!main || !documentId) return;
|
|
659
|
+
let shown = viewPresentation(documentId).drawMode;
|
|
654
660
|
const keep = (): void => {
|
|
655
|
-
const saved = view.savedView();
|
|
656
661
|
const mode = viewPresentation(documentId).drawMode;
|
|
662
|
+
if (mode === shown) return;
|
|
663
|
+
shown = mode;
|
|
664
|
+
const saved = view.savedView();
|
|
657
665
|
const shading = BLENDER_SHADING[mode as keyof typeof BLENDER_SHADING];
|
|
658
666
|
if (!saved || shading === undefined || saved.drawMode === mode) return;
|
|
659
667
|
view.noteSavedShading(shading);
|
|
@@ -1140,6 +1140,13 @@ export async function blenderOutlinerSet(
|
|
|
1140
1140
|
return written;
|
|
1141
1141
|
}
|
|
1142
1142
|
|
|
1143
|
+
/** The editor's selection into Blender's view layer (`session.py`'s `selection_set`): written,
|
|
1144
|
+
* saved and presented only when it differs from what Blender holds. */
|
|
1145
|
+
export async function blenderSelectionSet(names: readonly string[], active: string | null): Promise<void> {
|
|
1146
|
+
const { changed } = await blenderRuntime().selectionSet(names, active);
|
|
1147
|
+
if (changed) noteBlenderRnaChanged();
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1143
1150
|
/** Node-view actions share driveNodeView between page commands and the session relay. State reads, focus, framing, zoom and pan update inspection state; editing gestures refuse by name. */
|
|
1144
1151
|
export const NODE_VIEW_VERBS: readonly ViewVerb[] = (['state', 'look', 'view-all', 'zoom', 'pan', 'move', 'link', 'set-value', 'use-nodes', 'collapse-panel'] as const).map((id) => ({
|
|
1145
1152
|
id,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publisher": "volter",
|
|
4
4
|
"author": "Volter AI, Inc.",
|
|
5
5
|
"license": "AGPL-3.0-only AND GPL-3.0-or-later",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.154",
|
|
7
7
|
"engines": {
|
|
8
8
|
"vscode": "*"
|
|
9
9
|
},
|
|
@@ -1245,17 +1245,17 @@
|
|
|
1245
1245
|
}
|
|
1246
1246
|
},
|
|
1247
1247
|
"dependencies": {
|
|
1248
|
-
"@volter/editor-movie": "0.5.
|
|
1248
|
+
"@volter/editor-movie": "0.5.215",
|
|
1249
1249
|
"@modelcontextprotocol/sdk": "1.32.1",
|
|
1250
|
-
"@volter/blender-engine": "0.1.
|
|
1251
|
-
"@volter/editor-threejs": "0.5.
|
|
1250
|
+
"@volter/blender-engine": "0.1.152",
|
|
1251
|
+
"@volter/editor-threejs": "0.5.215",
|
|
1252
1252
|
"zod": "^4.3.6",
|
|
1253
1253
|
"@fortawesome/free-solid-svg-icons": "^7.2.0"
|
|
1254
1254
|
},
|
|
1255
1255
|
"peerDependencies": {
|
|
1256
|
-
"@volter/live": "0.5.
|
|
1257
|
-
"@volter/project": "0.5.
|
|
1258
|
-
"@volter/sdk": "0.5.
|
|
1256
|
+
"@volter/live": "0.5.215",
|
|
1257
|
+
"@volter/project": "0.5.215",
|
|
1258
|
+
"@volter/sdk": "0.5.215",
|
|
1259
1259
|
"react": "^19.0.0",
|
|
1260
1260
|
"react-dom": "^19.0.0",
|
|
1261
1261
|
"three": "^0.186.1",
|
package/src/layouts.tsx
CHANGED
|
@@ -19,12 +19,12 @@ export const ModelArrangement: WorkspaceArrangement = {
|
|
|
19
19
|
},
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
/** Blender-shaped modeling
|
|
22
|
+
/** Blender-shaped modeling. */
|
|
23
23
|
export function ModelLayout() {
|
|
24
24
|
return (
|
|
25
25
|
<EditorFrame>
|
|
26
26
|
<EditorHeader />
|
|
27
|
-
<Workspace arrangement={ModelArrangement}
|
|
27
|
+
<Workspace arrangement={ModelArrangement} />
|
|
28
28
|
<EditorFooter />
|
|
29
29
|
</EditorFrame>
|
|
30
30
|
);
|