@photivra/engine 2.5.0 → 2.7.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/CHANGELOG.md +129 -1
- package/CITATION.cff +1 -1
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +1 -0
- package/dist/capture/native-environment-lean.d.ts +1 -1
- package/dist/capture/native-environment-lean.js +17 -3
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-raw.d.ts +0 -4
- package/dist/capture/native-environment-raw.js +6 -2
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/color/illuminants.d.ts +15 -0
- package/dist/color/illuminants.js +81 -24
- package/dist/color/illuminants.js.map +1 -1
- package/dist/color/srgb-transfer.d.ts +6 -0
- package/dist/color/srgb-transfer.js +9 -0
- package/dist/color/srgb-transfer.js.map +1 -1
- package/dist/color/white-balance.d.ts +6 -0
- package/dist/color/white-balance.js +15 -2
- package/dist/color/white-balance.js.map +1 -1
- package/dist/core/internal-radiance-evaluator.d.ts +6 -0
- package/dist/core/internal-radiance-evaluator.js +33 -0
- package/dist/core/internal-radiance-evaluator.js.map +1 -0
- package/dist/core/portable-math.d.ts +33 -0
- package/dist/core/portable-math.js +342 -0
- package/dist/core/portable-math.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/facade/chart-radiance-batch.js +3 -2
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/chart-scenes.d.ts +11 -0
- package/dist/facade/chart-scenes.js +21 -7
- package/dist/facade/chart-scenes.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +10 -0
- package/dist/facade/diffraction-provider.js +38 -17
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view.d.ts +213 -0
- package/dist/facade/display-view.js +1543 -0
- package/dist/facade/display-view.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +45 -5
- package/dist/facade/scene-radiance.js +97 -28
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +233 -5
- package/dist/facade/simulate-capture.js +120 -37
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +45 -0
- package/dist/facade/simulate-display-view.js +214 -0
- package/dist/facade/simulate-display-view.js.map +1 -0
- package/dist/facade/subject-framing.d.ts +16 -0
- package/dist/facade/subject-framing.js +8 -2
- package/dist/facade/subject-framing.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/optics/diffraction-psf-profile.d.ts +9 -2
- package/dist/optics/diffraction-psf-profile.js +33 -4
- package/dist/optics/diffraction-psf-profile.js.map +1 -1
- package/dist/optics/irradiance-convolution.js +1 -1
- package/dist/optics/irradiance-convolution.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +7 -0
- package/dist/optics/scene-to-sensor-irradiance.js +10 -5
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/output/print-plan.d.ts +8 -1
- package/dist/output/print-plan.js +8 -1
- package/dist/output/print-plan.js.map +1 -1
- package/dist/schema/scene-radiance.d.ts +16 -0
- package/dist/schema/scene-radiance.js +25 -4
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +12 -0
- package/dist/sensor/raw-readout.js +131 -9
- package/dist/sensor/raw-readout.js.map +1 -1
- package/dist/sensor/stochastic-seed.d.ts +13 -0
- package/dist/sensor/stochastic-seed.js +42 -8
- package/dist/sensor/stochastic-seed.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/API_REFERENCE.md +19 -1
- package/docs/QUICK_START.md +203 -4
- package/docs/USAGE.md +15 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/exports.json +52 -2
- package/docs/api/facade-scene-radiance.md +34 -1
- package/docs/api/facade-simulate-capture.md +66 -2
- package/docs/api/facade-simulate-display-view.md +57 -0
- package/docs/api/facade-subject-framing.md +16 -0
- package/docs/api/output-print-plan.md +8 -1
- package/package.json +3 -2
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* levels, like the grey ramp: the step (below 0.1 % of the range) is far below sensor noise.
|
|
24
24
|
* @see docs/QUICK_START.md for the chart catalogue and their analytic definitions.
|
|
25
25
|
*/
|
|
26
|
+
import { portablePow } from "../core/portable-math.js";
|
|
26
27
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
27
28
|
import { prepareColorimetricSpectrum } from "../color/color-matching-functions.js";
|
|
28
29
|
import { requireInputObject, requireInputKeys } from "../core/record-validation.js";
|
|
@@ -69,7 +70,8 @@ function finiteIn(value, name, minimum, maximum, open = false) {
|
|
|
69
70
|
}
|
|
70
71
|
/** Wavelength range every chart spectrum must cover (the facade's sensor quadrature range). */
|
|
71
72
|
export const CHART_SPECTRAL_RANGE_NANOMETERS = Object.freeze({ minimum: 380, maximum: 780 });
|
|
72
|
-
|
|
73
|
+
/** Internal: validates a chart reflectance input (a neutral number or a reflectance spectrum covering 380–780 nm) as a material. */
|
|
74
|
+
export function resolveChartMaterial(value, name) {
|
|
73
75
|
if (typeof value === "number")
|
|
74
76
|
return { kind: "neutral", reflectance: reflectance(value, name) };
|
|
75
77
|
let spectrum;
|
|
@@ -124,6 +126,15 @@ export function resolveChartScene(input) {
|
|
|
124
126
|
throw new InvalidConfigurationError("Chart aspect must be positive.");
|
|
125
127
|
return resolveScene(scene, aspect, { pictureHeight: 2 * aspect, nested: false });
|
|
126
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Internal (not exported from the package): {@link resolveChartScene} with the step wedge's geometric levels computed
|
|
131
|
+
* with the portable power (`portablePow`, within 1 ulp) instead of `**`, whose last bit differs between JavaScript
|
|
132
|
+
* engines. Every other value, the geometry and the material order are the same. The display view uses its materials.
|
|
133
|
+
*/
|
|
134
|
+
export function resolvePortableChartScene(input) {
|
|
135
|
+
requireInputObject(input, "resolveChartScene input");
|
|
136
|
+
return resolveScene(input.scene, input.aspect, { pictureHeight: 2 * input.aspect, nested: false, pow: portablePow });
|
|
137
|
+
}
|
|
127
138
|
function resolveScene(scene, aspect, context) {
|
|
128
139
|
requireInputObject(scene, "chart scene");
|
|
129
140
|
const preset = scene.preset;
|
|
@@ -163,7 +174,7 @@ function resolveScene(scene, aspect, context) {
|
|
|
163
174
|
};
|
|
164
175
|
switch (preset) {
|
|
165
176
|
case "uniform": {
|
|
166
|
-
const raw = get("reflectance"), m =
|
|
177
|
+
const raw = get("reflectance"), m = resolveChartMaterial(raw, "reflectance");
|
|
167
178
|
return done({ reflectance: typeof raw === "number" ? raw : "caller-spectrum" }, [m], () => 0, [typeof raw === "number" ? undefined : raw]);
|
|
168
179
|
}
|
|
169
180
|
case "slanted-edge": {
|
|
@@ -209,7 +220,7 @@ function resolveScene(scene, aspect, context) {
|
|
|
209
220
|
throw new InvalidConfigurationError("spacing must be equal-density or linear.");
|
|
210
221
|
if (!(hi > lo) || (spacing === "equal-density" && lo <= 0))
|
|
211
222
|
throw new InvalidConfigurationError("Step wedge needs 0 < minimum < maximum reflectance.");
|
|
212
|
-
const values =
|
|
223
|
+
const values = stepWedgeReflectances(steps, lo, hi, spacing, context.pow);
|
|
213
224
|
return done({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing, stepReflectances: values }, values.map((reflectanceValue) => ({ kind: "neutral", reflectance: reflectanceValue })), (u) => Math.min(steps - 1, Math.max(0, Math.floor((u + 1) / 2 * steps))));
|
|
214
225
|
}
|
|
215
226
|
case "grey-ramp": {
|
|
@@ -250,7 +261,7 @@ function resolveScene(scene, aspect, context) {
|
|
|
250
261
|
if (typeof p.patchId !== "string" || p.patchId.trim() === "" || ids.has(p.patchId))
|
|
251
262
|
throw new InvalidConfigurationError("Each patch needs a unique non-empty patchId.");
|
|
252
263
|
ids.add(p.patchId);
|
|
253
|
-
materials.push(
|
|
264
|
+
materials.push(resolveChartMaterial(p.reflectance, "patches[" + index + "].reflectance"));
|
|
254
265
|
inputs.push(typeof p.reflectance === "number" ? undefined : p.reflectance);
|
|
255
266
|
}
|
|
256
267
|
const columnsRaw = record.columns === undefined ? Math.ceil(Math.sqrt(list.length)) : record.columns;
|
|
@@ -390,7 +401,7 @@ function resolveScene(scene, aspect, context) {
|
|
|
390
401
|
const list = record.elements;
|
|
391
402
|
if (!Array.isArray(list) || list.length < 1 || list.length > 256)
|
|
392
403
|
throw new InvalidConfigurationError("elements must list 1 to 256 chart elements.");
|
|
393
|
-
const nested = { pictureHeight: context.pictureHeight, nested: true };
|
|
404
|
+
const nested = { pictureHeight: context.pictureHeight, nested: true, ...(context.pow ? { pow: context.pow } : {}) };
|
|
394
405
|
const background = resolveScene(get("background"), aspect, nested);
|
|
395
406
|
const materials = [...background.materials], inputs = [...chartMaterialInputs(background)];
|
|
396
407
|
for (const key of background.defaultedParameters)
|
|
@@ -410,7 +421,7 @@ function resolveScene(scene, aspect, context) {
|
|
|
410
421
|
if (e.mask === undefined)
|
|
411
422
|
defaulted.push("elements." + index + ".placement.mask");
|
|
412
423
|
// The element's own frame: u = ±1 across its width; frequencies keep the composite's picture height.
|
|
413
|
-
const chart = resolveScene(e.scene, height / width, { pictureHeight: context.pictureHeight * 2 / width, nested: true });
|
|
424
|
+
const chart = resolveScene(e.scene, height / width, { pictureHeight: context.pictureHeight * 2 / width, nested: true, ...(context.pow ? { pow: context.pow } : {}) });
|
|
414
425
|
for (const key of chart.defaultedParameters)
|
|
415
426
|
defaulted.push("elements." + index + ".parameters." + key);
|
|
416
427
|
const offset = materials.length;
|
|
@@ -636,11 +647,14 @@ export function calculateStepWedgeReflectances(input) {
|
|
|
636
647
|
throw new InvalidConfigurationError("spacing must be equal-density or linear.");
|
|
637
648
|
if (!(hi > lo) || (input.spacing === "equal-density" && lo <= 0))
|
|
638
649
|
throw new InvalidConfigurationError("Step wedge needs 0 < minimum < maximum reflectance.");
|
|
650
|
+
return stepWedgeReflectances(steps, lo, hi, input.spacing, undefined);
|
|
651
|
+
}
|
|
652
|
+
function stepWedgeReflectances(steps, lo, hi, spacing, pow) {
|
|
639
653
|
return Array.from({ length: steps }, (_, k) => {
|
|
640
654
|
if (k === steps - 1)
|
|
641
655
|
return hi;
|
|
642
656
|
const t = k / (steps - 1);
|
|
643
|
-
return
|
|
657
|
+
return spacing === "linear" ? lo + (hi - lo) * t : lo * (pow ? pow(hi / lo, t) : (hi / lo) ** t);
|
|
644
658
|
});
|
|
645
659
|
}
|
|
646
660
|
/** Centres (frame units) of a point grid: one disk centred in each of columns × rows equal cells, row-major from the top-left. */
|