Initial commit

This commit is contained in:
Robert Nasarek 2026-06-25 09:11:23 +02:00
commit 05c65aad4d
155 changed files with 93617 additions and 0 deletions

View file

@ -0,0 +1,183 @@
{
"@context": "http://iiif.io/api/presentation/4/context.json",
"id": "http://127.0.0.1:8080/examples/box.stl/manifest.json",
"type": "Manifest",
"label": {
"en": [
"box"
]
},
"items": [
{
"id": "http://127.0.0.1:8080/examples/box.stl/scene",
"type": "Scene",
"label": {
"en": [
"box"
]
},
"backgroundColor": "#000000",
"items": [
{
"id": "http://127.0.0.1:8080/examples/box.stl/scene/page/model",
"type": "AnnotationPage",
"items": [
{
"id": "http://127.0.0.1:8080/examples/box.stl/scene/annotation/model",
"type": "Annotation",
"motivation": [
"painting"
],
"body": {
"id": "http://127.0.0.1:8080/examples/box.stl",
"type": "Model"
},
"target": {
"id": "http://127.0.0.1:8080/examples/box.stl/scene",
"type": "Scene"
}
}
]
}
],
"annotations": [
{
"id": "http://127.0.0.1:8080/examples/box.stl/scene/page/annotations",
"type": "AnnotationPage",
"items": []
}
]
}
],
"AIM3DViewer": {
"version": "1.0",
"generatedAt": "2026-06-19T09:34:04.459Z",
"camera": {
"position": [
-1.6694479537305902,
1.8347239768652952,
3.3388959074611804
],
"target": [
0,
1,
0
],
"up": [
0,
1,
0
],
"fov": 45,
"distance": 3.825185808379782,
"perspectiveMode": "orthographic"
},
"viewer": {
"container": "DFG_3DViewer",
"mailUrl": "localhost",
"baseNamespace": "https://localhost",
"metadataUrl": "https://localhost",
"environmentMap": {
"intensity": 1,
"preset": "neutral",
"enabled": true
},
"presentationMode": false,
"sandbox": false,
"scale": {
"x": "1.0",
"y": "1.0"
},
"performance": {
"Performance": "high-performance"
},
"gallery": {
"build": true,
"container": "block-bootstrap5-content",
"imageClass": "field--name-fd6a974b7120d422c7b21b5f1f2315d9",
"imageId": "field--name-fd6a974b7120d422c7b21b5f1f2315d9",
"buildFake": true,
"testImages": [
null
]
}
},
"integration": {
"type": "drupal",
"bundle": "bd1220d6ec7f07e726c65fd215d8e493",
"fieldDf": "field_df",
"exportViewer": "field_df",
"idUri": "\\/wisski\\/navigate\\/(.*)\\/view",
"viewEntityPath": "\\/wisski\\/navigate\\/",
"attributeId": "wisski_id",
"metadata": {
"source": ""
},
"fileUpload": "fad29437cb2a561b91b26aca5dbb7c42",
"fileName": "fb76901eb219495fee0512b5cdfdaa18",
"imageGeneration": "fd6a974b7120d422c7b21b5f1f2315d9"
},
"lights": [
{
"type": "AmbientLight",
"position": [
0,
0,
0
],
"color": "#404040",
"intensity": 1
},
{
"type": "DirectionalLight",
"position": [
0,
100,
50
],
"target": [
0,
0,
0
],
"color": "#ffffff",
"intensity": 1
},
{
"type": "DirectionalLight",
"position": [
0,
5.000799774279585e-11,
0.00010000444491510899
],
"target": [
0,
0,
0
],
"color": "#ffffff",
"intensity": 0.3
}
],
"modelTransform": {
"position": [
0,
0,
0
],
"rotation": {
"x": 0,
"y": 0,
"z": 0,
"order": "XYZ"
},
"scale": [
1,
1,
1
],
"wireframe": false
}
},
"modified": "2026-06-19T09:34:04.459Z"
}

View file

@ -0,0 +1,77 @@
import { AIM3DManifest } from "./manifesto";
export async function loadAIM3IFManifest(manifestUrlOrJson) {
const aim3dManifest = new AIM3DManifest(manifestUrlOrJson);
await aim3dManifest.loadManifest();
const modelUrls = [];
let modelTarget = null;
let filteredAnnos = [];
for (const scene of aim3dManifest.scenes) {
scene.background =
scene.backgroundColor ||
"#000000";
const annos = aim3dManifest.annotationsFromScene(scene);
filteredAnnos = annos.filter(
anno =>
anno.motivation?.includes("painting") &&
anno.body?.type === "Model"
);
for (const anno of filteredAnnos) {
const modelUrl = anno.body?.id;
if (modelUrl) {
modelUrls.push(modelUrl);
}
modelTarget = anno.target;
}
}
aim3dManifest.modelUrls = modelUrls;
aim3dManifest.modelTarget = modelTarget;
return {
manifest: aim3dManifest.manifest,
scenes: aim3dManifest.scenes,
annotations: filteredAnnos,
modelUrls,
modelTarget
};
}
export function applyManifestConfig(manifest, objectsConfig) {
const transform =
manifest.AIM3DViewer?.modelTransform;
if (!transform) return;
const model = objectsConfig.models[0];
model.position = {
x: transform.position?.[0] ?? 0,
y: transform.position?.[1] ?? 0,
z: transform.position?.[2] ?? 0
};
model.rotation = {
x: transform.rotation?.x ?? 0,
y: transform.rotation?.y ?? 0,
z: transform.rotation?.z ?? 0
};
model.scale = {
x: transform.scale?.[0] ?? 1,
y: transform.scale?.[1] ?? 1,
z: transform.scale?.[2] ?? 1
};
model.wireframe =
transform.wireframe ?? false;
}

View file

@ -0,0 +1,41 @@
export class AIM3DManifest {
constructor(manifest) {
if (typeof manifest === "string" && manifest.trim().startsWith("{")) {
this.manifestJson = JSON.parse(manifest);
this.manifestUrl = null;
} else if (typeof manifest === "object") {
this.manifestJson = manifest;
this.manifestUrl = null;
} else {
this.manifestUrl = manifest;
this.manifestJson = null;
}
}
async loadManifest() {
if (this.manifestUrl) {
const response = await fetch(this.manifestUrl);
this.manifestJson = await response.json();
}
this.manifest = this.manifestJson;
this.scenes = this.manifest?.items?.filter(
item => item.type === "Scene"
) || [];
}
annotationsFromScene(scene) {
const result = [];
for (const page of scene?.items || []) {
if (page.type !== "AnnotationPage") continue;
for (const annotation of page.items || []) {
result.push(annotation);
}
}
return result;
}
}