3D Annotation Guide
How to create TEI/XML with 3D models
Guide to Creating TEI/XML with 3D Models
This guide explains how to add annotations to 3D models and export them in TEI/XML format.
Overview
The 3D annotation feature allows you to associate text information with specific positions or regions on a 3D model. Created annotations can be exported in TEI (Text Encoding Initiative) compliant XML format for use in academic digital archives.
Workflow
1. Prepare GLB file
↓
2. Edit in Annotation Editor
↓
3. Export XML
↓
4. (Optional) Create XSL
↓
5. View in Viewer
1. Preparing the 3D Model
Supported Format
Currently, only GLB format (glTF Binary) is supported.
- Convert from other formats (OBJ, FBX, etc.) using 3D software like Blender
- File size under 50MB is recommended
GLB File Compression (Recommended)
To improve web loading performance, compressing GLB files is strongly recommended.
Compression Tools: gltf-transform or glTF-Pipeline
Compression example using gltf-transform:
# Install
npm install -g @gltf-transform/cli
# Apply Draco compression (mesh data compression)
gltf-transform optimize input.glb output.glb --compress draco
# Optimize including textures
gltf-transform optimize input.glb output.glb --compress draco --texture-compress webp
Compression results example:
| File | Before | After | Reduction |
|---|---|---|---|
| Sample model | 28MB | 8.8MB | ~69% |
Compression significantly improves page load times.
Model Placement
Place GLB files in a location accessible via URL.
Placement options:
- Your own web server
- GitHub Pages
- Cloud storage (Amazon S3, Google Cloud Storage, etc.)
- This project's
public/data/models/directory
Note: When accessing from the annotation editor, CORS (Cross-Origin Resource Sharing) configuration may be required. Either place files on the same domain or set appropriate CORS headers.
2. Using the Annotation Editor
Opening the Editor
Access the 3D Annotation Editor.
Loading a Model
Two methods are available:
- URL Input: Enter the GLB file URL and click "Load"
- File Upload: Drag and drop a local GLB file, or use file selection
Annotation Types
Three types of annotations can be created:
| Type | Description | Use Case |
|---|---|---|
| Point | Single point | Mark specific positions |
| Box | Cuboid defined by 2 points | Specify area boundaries |
| Polygon | Polygon defined by 3+ points | Complex shaped regions |
Adding a Point
- Click "+ Point" in the toolbar
- Click the target position on the model
- Enter ID, note, and radius in the right panel
- Click "Add"
Adding a Box
- Click "+ Box" in the toolbar
- Click the first corner
- Click the opposite corner
- Enter details and click "Add"
Adding a Polygon
- Click "+ Polygon" in the toolbar
- Click vertices in order (minimum 3 points)
- Enter details and click "Add"
Editing and Deleting Annotations
- Select an annotation from the list in the left panel
- Click "Edit" to modify content
- Click "Delete" to remove
3. XML Export
Export Procedure
- Click "Export XML" in the toolbar
- XML will be displayed in a new tab
- Copy or save as needed
Output XML Structure
The exported XML is structured to work with IIIF 3D manifests:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Export output example -->
<facsimile xmlns="http://www.tei-c.org/ns/1.0">
<surface xml:id="surface-3d" type="threejs"
corresp="your-model.glb">
<!-- Point type -->
<zone xml:id="zone-point-1" type="point"
ana="points3d:0.5,1.2,0.3" radius="0.05">
<note>Description text</note>
</zone>
<!-- Box type -->
<zone xml:id="zone-box-1" type="box"
ana="points3d:0.1,0.2,0.3 0.8,0.9,0.6">
<note>Area description</note>
</zone>
<!-- Polygon type -->
<zone xml:id="zone-poly-1" type="polygon"
ana="points3d:0.1,0.5,0.2 0.3,0.5,0.2 0.2,0.8,0.2">
<note>Polygon area description</note>
</zone>
</surface>
</facsimile>
Integration with IIIF 3D Manifests
When creating complete TEI/XML, add references to the IIIF manifest:
<facsimile sameAs="https://example.com/iiif/3/0001/manifest.json">
<surface xml:id="surface-3d" type="threejs"
sameAs="https://example.com/iiif/3/0001/manifest.json/scene/1">
<graphic url="https://example.com/models/your-model.glb"
mimeType="model/gltf-binary"/>
<zone xml:id="zone-point-1" type="point"
ana="points3d:0.5,1.2,0.3" radius="0.05">
<note>Description text</note>
</zone>
<!-- Other zone elements -->
</surface>
</facsimile>
Attribute Descriptions
facsimile element
| Attribute | Description |
|---|---|
sameAs | Link to IIIF 3D manifest |
surface element
| Attribute | Description |
|---|---|
xml:id | Surface identifier |
type | threejs (for 3D viewer) |
sameAs | Link to scene within IIIF 3D manifest |
graphic element
| Attribute | Description |
|---|---|
url | GLB file URL |
mimeType | model/gltf-binary |
zone element
| Attribute | Description |
|---|---|
xml:id | Unique identifier |
type | Annotation type (point/box/polygon) |
ana | 3D coordinates (points3d:x,y,z format, space-separated for multiple) |
radius | Radius for point type |
Note: The TEI standard expects the points attribute to contain 2D coordinates. To pass TEI All schema validation, 3D coordinates are stored in the ana attribute with the points3d: prefix.
4. Creating Complete TEI/XML
Only the <facsimile> section is exported. To create complete TEI/XML, combine it with the text body and add IIIF manifest references:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/data/xsl/your-style.xsl"?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng"
type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader>
<fileDesc>
<titleStmt>
<title>Work Title</title>
</titleStmt>
<publicationStmt>
<p>Publication information</p>
</publicationStmt>
<sourceDesc>
<p>Source material information</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<!-- Link to annotations with corresp attribute -->
<p corresp="#zone-point-1">
This text is related to point 1.
</p>
<p corresp="#zone-poly-1">
This text is related to the polygon area.
</p>
</body>
</text>
<!-- Facsimile with IIIF 3D manifest link -->
<facsimile sameAs="https://example.com/iiif/3/0001/manifest.json">
<surface xml:id="surface-3d" type="threejs"
sameAs="https://example.com/iiif/3/0001/manifest.json/scene/1">
<graphic url="https://example.com/models/your-model.glb"
mimeType="model/gltf-binary"/>
<zone xml:id="zone-point-1" type="point"
ana="points3d:0.5,1.2,0.3" radius="0.05">
<note>Description text</note>
</zone>
<!-- Other zone elements -->
</surface>
</facsimile>
</TEI>
About IIIF 3D Manifests
Using the IIIF 3D extension allows you to describe 3D model metadata in a standardized format. By linking from TEI/XML's facsimile element to the manifest:
- Manage 3D model metadata (title, copyright, etc.) externally
- Ensure interoperability between multiple viewers
- Integrate with other IIIF resources (images, video, etc.)
Manifest URL structure example:
https://example.com/iiif/3/0001/manifest.json # Manifest
https://example.com/iiif/3/0001/manifest.json/scene/1 # Scene (for surface@sameAs)
Linking Text to Annotations
Use the corresp attribute to link text elements to annotations:
- Text side:
<p corresp="#zone-point-1"> - Annotation side:
<zone xml:id="zone-point-1">
5. Creating XSL Stylesheets (Optional)
To customize text display styles, create an XSLT stylesheet.
Integration with TEI 3D Viewer
To link text with the 3D model in TEI 3D Viewer, the XSL must convert corresp attributes to data-corresp attributes. This enables clicking on text to focus on the corresponding 3D position.
Basic XSL Template
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
exclude-result-prefixes="tei">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="/">
<html>
<head>
<style>
body {
font-family: serif;
line-height: 1.8;
padding: 2rem;
}
/* For vertical writing */
.vertical {
writing-mode: vertical-rl;
}
</style>
</head>
<body>
<xsl:apply-templates select="//tei:text/tei:body"/>
</body>
</html>
</xsl:template>
<!-- Paragraph template -->
<xsl:template match="tei:p">
<p>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</p>
</xsl:template>
</xsl:stylesheet>
Bulk Attribute Processing (Recommended)
Instead of writing corresp attribute handling for each element, use attribute templates for bulk processing:
<!-- ================================================== -->
<!-- Attribute Templates (Bulk Processing) -->
<!-- ================================================== -->
<!-- xml:id → id -->
<xsl:template match="@xml:id">
<xsl:attribute name="id">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!-- corresp → data-corresp -->
<xsl:template match="@corresp">
<xsl:attribute name="data-corresp">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!-- Ignore other attributes -->
<xsl:template match="@*"/>
In each element template, a single line processes all attributes:
<xsl:apply-templates select="@*"/>
Generic TEI Element Template
To automatically preserve attributes for TEI elements without specific templates, add a fallback template:
<!-- ================================================== -->
<!-- Generic TEI Element Template (Fallback) -->
<!-- ================================================== -->
<!-- Convert undefined TEI elements under text to span (exclude facsimile etc.) -->
<xsl:template match="tei:text//tei:*" priority="-1">
<span>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</span>
</xsl:template>
<!-- Ignore metadata elements like facsimile -->
<xsl:template match="tei:facsimile"/>
<xsl:template match="tei:teiHeader"/>
This provides:
- New TEI elements are automatically converted to
<span>with attributes preserved - Adding new attributes (e.g.,
@ref→data-ref) requires only one new attribute template
Elements Requiring Special Styles
Define individual templates for elements needing visual customization:
<!-- Title (with special class) -->
<xsl:template match="tei:head">
<div class="title-column">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</div>
</xsl:template>
<!-- Person names (highlighted) -->
<xsl:template match="tei:persName">
<span class="person-name">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</span>
</xsl:template>
<!-- Dates -->
<xsl:template match="tei:date">
<span class="date">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</span>
</xsl:template>
| Element | Why Individual Template Is Needed |
|---|---|
head | Large font for titles |
dateline | Signature/date styling |
persName | Person name highlighting |
| Others | Handled by generic template |
XSL File Placement
public/data/xsl/
├── your-style.xsl
6. Viewing in the Viewer
Created TEI/XML can be displayed in the TEI 3D Viewer.
Usage
Specify the XML file via URL parameter:
/tei-3d-viewer?url=/data/xml/your-file.xml
Viewer Features
- Simultaneous display of 3D model and text
- Click text to focus on corresponding 3D position
- Highlight display of annotation regions
Sample Files
Refer to these samples:
- Inutabu Misaki Song - Polygon annotation example
- Hanta Tadatoshi Statue Inscription - Memorial text example
Troubleshooting
Model Won't Load
- Verify the file is in GLB format
- Check if file size is too large
- For CORS errors, place on the same domain
Annotations Not Displaying
- Check coordinate format in
anaattribute (points3d:x,y,zspace-separated) - Verify no duplicate
xml:idvalues - Confirm correct filename in
correspattribute
Text Linking Not Working
- Verify
correspattribute value starts with# - Confirm
xml:idandcorrespvalues match