@volter/editor-blender 0.1.28 → 0.1.30
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.
|
@@ -76,6 +76,7 @@ import type {
|
|
|
76
76
|
} from '@volter/editor-project/adapter';
|
|
77
77
|
import type * as THREE from 'three';
|
|
78
78
|
import { threeObject } from '@volter/editor-threejs/adapter/three-contract';
|
|
79
|
+
import { viewportStages } from '@volter/editor-threejs/viewport-door';
|
|
79
80
|
import { blenderExecute, blenderRnaSet, beginBlenderGesture, endBlenderGesture } from '../host/blender-runtime-host';
|
|
80
81
|
import {
|
|
81
82
|
blenderEngineSelection,
|
|
@@ -1602,6 +1603,29 @@ export function blenderOutlinerAuthoringFor(
|
|
|
1602
1603
|
* callback in Code-OSS. These operators are undone by restoring Blender's
|
|
1603
1604
|
* state, never by constructing an inverse operator or replaying the script.
|
|
1604
1605
|
*/
|
|
1606
|
+
/**
|
|
1607
|
+
* ADD ▸ CAMERA LOOKS THE WAY THE VIEW LOOKS, AND IS THE SCENE'S CAMERA WHEN THERE IS NONE: what
|
|
1608
|
+
* `object_camera_add_exec` does with the 3D View it runs in (`object_add.cc`: `align` forced to
|
|
1609
|
+
* VIEW; `v3d->scenelock && scene->camera == nullptr` gives `scene->camera = ob`). This engine
|
|
1610
|
+
* runs the operator with no View3D, so both come from here: the area's own view, set on the new
|
|
1611
|
+
* camera the way the gizmo writes a pose (`blenderWorldMatrixRows`) with the operator's
|
|
1612
|
+
* location (the 3D cursor) kept, and the scene camera after it.
|
|
1613
|
+
*/
|
|
1614
|
+
const cameraAddCall = (): string => {
|
|
1615
|
+
const areaId = (defaultAdapter as { documentId?: string }).documentId?.replace(/^object3d-document:/, '');
|
|
1616
|
+
const camera = viewportStages().find((one) => one.documentId === areaId)?.rig().drawCamera() ?? null;
|
|
1617
|
+
const view = presented();
|
|
1618
|
+
const lines = ['bpy.ops.object.camera_add()', 'added = bpy.context.view_layer.objects.active'];
|
|
1619
|
+
if (camera !== null && view !== null)
|
|
1620
|
+
lines.push(
|
|
1621
|
+
'kept = added.location.copy()',
|
|
1622
|
+
`added.matrix_world = ${JSON.stringify(blenderWorldMatrixRows(camera, view.root))}`,
|
|
1623
|
+
'added.location = kept',
|
|
1624
|
+
);
|
|
1625
|
+
lines.push('if bpy.context.scene.camera is None:', ' bpy.context.scene.camera = added');
|
|
1626
|
+
return lines.join('\n');
|
|
1627
|
+
};
|
|
1628
|
+
|
|
1605
1629
|
const structure: StructureProvider = {
|
|
1606
1630
|
/**
|
|
1607
1631
|
* BLENDER'S ADD MENU, FOR EVERY PARENT — `parentId` is deliberately not
|
|
@@ -1633,7 +1657,7 @@ export function blenderOutlinerAuthoringFor(
|
|
|
1633
1657
|
// with this same sentence, so this arm is what answers a caller reaching
|
|
1634
1658
|
// the kind through the door instead of the menu.
|
|
1635
1659
|
if (entry.refusal !== undefined) return { id: '', ack: refuse(entry.refusal) };
|
|
1636
|
-
const call = addCall(entry);
|
|
1660
|
+
const call = entry.call === 'object.camera_add' ? cameraAddCall() : addCall(entry);
|
|
1637
1661
|
return {
|
|
1638
1662
|
id: '',
|
|
1639
1663
|
ack: (async (): Promise<WriteAck> => {
|
|
@@ -73,6 +73,10 @@ import {
|
|
|
73
73
|
subscribeObject3DDocumentSessions,
|
|
74
74
|
} from '@volter/editor-threejs/kit/authoring/object3d-document-session-registry';
|
|
75
75
|
import type { ToolObject3DAuthoringProps } from '@volter/editor-threejs/object3d-contributions';
|
|
76
|
+
import { stageStore, subscribeStageStores } from '@volter/editor-sdk/kit/stage-store-registry';
|
|
77
|
+
|
|
78
|
+
/** The second areas' stage stores whose overlays have been opened off (`BlenderViewportArea`). */
|
|
79
|
+
const overlaysOpened = new WeakSet<object>();
|
|
76
80
|
|
|
77
81
|
export const point = 'workspace.document';
|
|
78
82
|
export const title = 'Blender Model';
|
|
@@ -427,6 +431,24 @@ function BlenderViewportArea({
|
|
|
427
431
|
stopFrames();
|
|
428
432
|
};
|
|
429
433
|
}, [main, documentId, view]);
|
|
434
|
+
/**
|
|
435
|
+
* AND WITH THE AREA'S SHOW OVERLAYS OFF, the switch that makes a camera view read as the render
|
|
436
|
+
* does: no grid, no camera or light wires, no selection marks, no view text — and still the
|
|
437
|
+
* camera's outline and passepartout (`drawviewborder`: "When overlays are disabled, only show
|
|
438
|
+
* camera outline & passepartout"). Set once per stage store, which outlives the area's remounts,
|
|
439
|
+
* so turning them back on is the person's and stays.
|
|
440
|
+
*/
|
|
441
|
+
useEffect(() => {
|
|
442
|
+
if (main || !documentId) return;
|
|
443
|
+
const opened = (): void => {
|
|
444
|
+
const store = stageStore(documentId);
|
|
445
|
+
if (store === null || overlaysOpened.has(store)) return;
|
|
446
|
+
overlaysOpened.add(store);
|
|
447
|
+
if (store.showHelpers) store.toggleHelpers();
|
|
448
|
+
};
|
|
449
|
+
opened();
|
|
450
|
+
return subscribeStageStores(opened);
|
|
451
|
+
}, [main, documentId]);
|
|
430
452
|
/**
|
|
431
453
|
* THE INSPECTION OVERLAYS ARE HELPERS, and the Helpers menu owns them
|
|
432
454
|
* (WORK.md §Blender in the tab is Blender, "Inspection parity", I4).
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@volter/editor-blender",
|
|
3
3
|
"author": "Volter AI, Inc.",
|
|
4
4
|
"license": "AGPL-3.0-only AND GPL-3.0-or-later",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.30",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -70,14 +70,14 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
73
|
-
"@volter/blender-engine": "0.1.
|
|
74
|
-
"@volter/editor-threejs": "0.5.
|
|
73
|
+
"@volter/blender-engine": "0.1.28",
|
|
74
|
+
"@volter/editor-threejs": "0.5.90",
|
|
75
75
|
"zod": "^4.3.6"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@volter/editor-live": "0.5.
|
|
79
|
-
"@volter/editor-project": "0.5.
|
|
80
|
-
"@volter/editor-sdk": "0.5.
|
|
78
|
+
"@volter/editor-live": "0.5.90",
|
|
79
|
+
"@volter/editor-project": "0.5.90",
|
|
80
|
+
"@volter/editor-sdk": "0.5.90",
|
|
81
81
|
"react": "^19.0.0",
|
|
82
82
|
"react-dom": "^19.0.0",
|
|
83
83
|
"three": "^0.180.0",
|