@deepblend/dsh-blender-tool 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/tools.js +30 -0
  2. package/package.json +2 -2
package/lib/tools.js CHANGED
@@ -38,6 +38,8 @@ import {
38
38
  CREATION_REQUEST_VERSION,
39
39
  BlenderWarningCode,
40
40
  warning,
41
+ verifyGeometryReport,
42
+ validateGeometrySelection,
41
43
  } from '@deepblend/dsh-blender-contracts'
42
44
 
43
45
  import {
@@ -388,10 +390,18 @@ function sceneGet(ctx) {
388
390
  'location and visibility, camera parameters, animation tracks and the render profiles. That is ' +
389
391
  'usually everything you need to decide what to change. Pass full:true to also get the complete ' +
390
392
  'SceneSpec document, which you should do only when you actually need exact field values. ' +
393
+ 'To measure saved native parts, pass geometryEntityIds (1–8 IDs from this scene) and an explicit geometryFrame. ' +
394
+ 'This returns source-verified world-axis spans in millimeters and transforms without rendering or creating a revision. ' +
395
+ 'Spans include rotation, handles and protrusions; they are not body diameter, wall thickness, clearance or quality approval. ' +
396
+ 'Do not subtract shell/liner spans or radii to claim a gap, or use unchanged height/scale to certify wall thickness. Those surface conditions remain unmeasured. ' +
391
397
  'ALWAYS use the revision this returns as `baseRevision` for your next blender_scene_patch.',
392
398
  parameters: {
393
399
  projectId: { type: 'string', required: true, description: 'The project id.' },
394
400
  revision: { type: 'string', description: 'Read a specific revision instead of the current one.' },
401
+ geometryEntityIds: { type: 'array', items: { type: 'string' },
402
+ description: 'Optional: measure 1–8 distinct saved native entity IDs. Requires geometryFrame. Hidden viewport objects and non-mesh roots are explicitly unavailable.' },
403
+ geometryFrame: { type: 'integer',
404
+ description: 'Explicit integer frame from 0 to 1000000 for native geometry measurement. Use the frame of the preview being checked. Requires geometryEntityIds.' },
395
405
  full: {
396
406
  type: 'boolean',
397
407
  description: 'Also return the complete SceneSpec and its compiled form. Costs a lot of context — ' +
@@ -403,10 +413,27 @@ function sceneGet(ctx) {
403
413
  const resolved = resolveStudio(ctx)
404
414
  if (resolved.unavailable !== undefined) return { ok: false, ...resolved.unavailable }
405
415
  try {
416
+ if ((args.geometryEntityIds === undefined) !== (args.geometryFrame === undefined)) {
417
+ throw new BlenderError(BlenderErrorCode.SCRIPT_ERROR, 'Native measurements require both geometryEntityIds and geometryFrame.')
418
+ }
419
+ if (args.geometryEntityIds !== undefined) validateGeometrySelection({ entityIds: args.geometryEntityIds,
420
+ frame: args.geometryFrame, checkpointSha256: '0'.repeat(64) })
406
421
  const { data, canonicalWarnings } = await canonicalCall(resolved.studio.getScene(args.projectId, {
407
422
  ...definedFields({ revision: args.revision }),
408
423
  full: args.full === true,
424
+ ...(args.geometryEntityIds === undefined ? {} : { geometry: { entityIds: args.geometryEntityIds, frame: args.geometryFrame }, signal: exec?.signal }),
409
425
  }), warning)
426
+ if (args.geometryEntityIds !== undefined && (!data.geometryInspection || data.geometryInspection.schemaVersion !== 'deepblend.scene-geometry/v1' ||
427
+ data.geometryInspection.projectId !== args.projectId || data.geometryInspection.sourceRevision !== data.revision ||
428
+ data.geometryInspection.sourceDigest !== data.digest || data.geometryInspection.sourceUnchanged !== true || data.geometryInspection.frame !== args.geometryFrame ||
429
+ !Array.isArray(data.geometryInspection.limitations) ||
430
+ JSON.stringify(data.geometryInspection.objects?.map(o => o.entityId)) !== JSON.stringify(args.geometryEntityIds))) {
431
+ throw new BlenderError(BlenderErrorCode.RUNTIME_UNAVAILABLE, 'The Host did not return measurements for the requested source and frame. Upgrade DeepBlend before measuring; ordinary scene reads remain available.')
432
+ }
433
+ if (data.geometryInspection) verifyGeometryReport({ frame: data.geometryInspection.frame, blenderVersion: data.geometryInspection.blenderVersion, objects: data.geometryInspection.objects,
434
+ schemaVersion: 'deepblend.geometry-inspection/v1', checkpointSha256: data.geometryInspection.sourceCheckpointSha256,
435
+ checkpointUnchanged: data.geometryInspection.sourceUnchanged }, { entityIds: args.geometryEntityIds, frame: args.geometryFrame,
436
+ checkpointSha256: data.geometryInspection.sourceCheckpointSha256 })
410
437
  const counts = data.counts ?? {}
411
438
  const notes = [
412
439
  `Revision ${data.revision}${data.isCurrent ? ' (current)' : ' (NOT current — patches against it will be refused)'}`,
@@ -417,6 +444,9 @@ function sceneGet(ctx) {
417
444
  '',
418
445
  'Entities:',
419
446
  ]
447
+ if (data.geometryInspection) notes.splice(notes.length - 2, 0,
448
+ `Measured saved native geometry at frame ${data.geometryInspection.frame}; source SHA256 ${data.geometryInspection.sourceCheckpointSha256}.`,
449
+ ...data.geometryInspection.limitations)
420
450
  for (const entity of data.entities ?? []) {
421
451
  notes.push(
422
452
  ` ${entity.id.padEnd(22)} ${String(entity.type).padEnd(15)} ${String(entity.shape ?? '-').padEnd(12)}` +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepblend/dsh-blender-tool",
3
- "version": "0.8.1",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "Agent-preset tool consumer: registers the model-visible DeepBlend Blender tools. Publishes no service.",
6
6
  "main": "lib/index.js",
@@ -11,7 +11,7 @@
11
11
  "./package.json": "./package.json"
12
12
  },
13
13
  "dependencies": {
14
- "@deepblend/dsh-blender-contracts": "0.8.1"
14
+ "@deepblend/dsh-blender-contracts": "0.9.0"
15
15
  },
16
16
  "license": "MIT",
17
17
  "repository": {