Examples › object database › Object library · family tree (proposal 3)
Object library · family tree (proposal 3)
Taxonomy-first: the library as its own structure, family → material → type, every node with its library-wide instance count. A graph (React Flow) and an outline (the table's tree); a type's peek, and the prototype page's full-height stage, show its representative object in 3D.
The .base file and its data
Every tab above is one entry of this file; the views read these rows. ⋯ in the toolbar copies the current view as YAML.
# Proposal 3 · Taxonomy-first ("the family tree"). The library as its own structure: family -> material -> type, each
# node carrying the library-wide instance count (the producer's number, from taxonomy.json). The graph is React Flow
# (the graph view); the outline is the table's tree. A type's peek is its representative object in 3D, and on the
# prototype page a full-height stage beside the graph turns the selected type's model (3D as a full pane).
# Edges are the frontmatter's own links (type -> material, material -> family); nothing is inferred
# (feedback_do_not_invent_undefined_relationships). New views over a generated node list.
# Check it: node bin/data-ui.mjs check gallery/examples/object-db-taxonomy/views.base
data: ../object-db-shelf/taxonomy.json
facets:
- { property: kind, label: Level }
- { property: instances, as: slider-histogram, log: true, label: Instances }
properties:
name: { displayName: Name }
kind: { displayName: Level }
instances: { displayName: Instances }
example: { displayName: Example object }
density_g_cm3: { displayName: Density (g/cm³) }
views:
- type: graph
name: Families and materials
filters: 'kind != "type"'
edges: { property: parent }
# WHY RL: 26 materials in one rank fit to a hairline across the page (TB); stacked, they read
layout: { algorithm: dagre, direction: RL }
order: [instances, density_g_cm3]
- type: table
name: Outline
tree: { parent: parent }
order: [name, kind, instances, example, density_g_cm3]
display: { instances: bar }
sort:
- { property: instances, direction: DESC }
- type: graph
name: Family tree
edges: { property: parent }
layout: { algorithm: dagre, direction: RL }
order: [kind, instances]
- type: cards
name: Types as cards
filters: 'kind == "type"'
groupBy: { property: parent, direction: ASC }
order: [name, instances, example]
image: thumbnail
mesh: mesh
meshView: mesh_view
imageFit: contain
cardSize: 160
sort:
- { property: instances, direction: DESC }
// ../object-db-shelf/taxonomy.json: 110 rows, 33 KB; the first 3
{
"id": "bam-taxonomy",
"title": "Family → material → type",
"titleProperty": "name",
"imageProperty": "thumbnail",
"source": "types' and materials' frontmatter @ 3a3be7a; instances = library-wide counts",
"properties": {
"kind": {
"type": "text",
"display": "badge",
"facet": "values"
},
"instances": {
"type": "number",
"decimals": 0
},
"parent": {
"type": "text",
"hidden": true
},
"thumbnail": {
"type": "text",
"media": "image",
"hidden": true
},
"mesh": {
"type": "text",
"media": "mesh",
"hidden": true
},
"mesh_view": {
"type": "text",
"hidden": true
},
"id": {
"type": "text"
},
"name": {
"type": "text"
},
"example": {
"type": "text"
},
"density_g_cm3": {
"type": "number"
}
},
"rows": [
{
"id": "family:ceramic",
"name": "ceramic",
"kind": "family",
"parent": null,
"instances": 56,
"thumbnail": "thumbs/gen_rubble-piece_00.webp",
"mesh": "meshes/gen_rubble-piece_00.glb",
"mesh_view": {
"dir": [
0.6236,
0.4695,
0.6236
],
"fov": 45,
"camera": "mujoco",
"box": [
0.0039,
0.1484,
0.9961,
0.8477
],
"dist": 0.31453
},
"example": "Rubble piece (generated 00) (Rubble piece)"
},
{
"id": "family:composite",
"name": "composite",
"kind": "family",
"parent": null,
"instances": 441,
"thumbnail": "thumbs/med_pill_0016.webp",
"mesh": "meshes/med_pill_0016.glb",
"mesh_view": {
"dir": [
0.6236,
0.4695,
0.6236
],
"fov": 45,
"camera": "mujoco (assumed)",
"box": [
0.3633,
0.3633,
0.6367,
0.6523
],
"dist": 0.01623
},
"example": "Loose Pill #2 (Loose pill)"
},
{
"id": "family:electronic",
"name": "electronic",
"kind": "family",
"parent": null,
"instances": 58,
"thumbnail": "thumbs/gso_hey_you_pikachu_nintendo_64.webp",
"mesh": "meshes/gso_hey_you_pikachu_nintendo_64.glb",
"mesh_view": {
"dir": [
0.9,
0.8,
1.1
],
"fov": 30,
"camera": "scan",
"box": [
0.0039,
0.0273,
0.9961,
0.9727
]
},
"example": "Hey You Pikachu N64 cartridge (Electronic item)"
}
]
}README.md
# Object library · family tree (proposal 3)
Taxonomy-first: the library as its own structure, family → material → type, every node with its library-wide
instance count. A graph (React Flow) and an outline (the table's tree); a type's peek, and the prototype page's
full-height stage, show its representative object in 3D.
- **App:** object database
- **Replaces:** `~/bam-waste-objects/views/Types.base` and `Materials.base` (flat tables with a backlink formula)
- **Shows:** graph (dagre layout, edges from `parent`), table with `tree: {parent}`, cards of types with `mesh:`, a 3D stage beside the graph (prototype page)
- **Data:** `../object-db-shelf/taxonomy.json` (families, 26 materials and 72 types from their frontmatter links; built by `../object-db-shelf/source/build.py`)
- **Prior art:** ImageNet / WordNet's synset explorer, Objaverse-LVIS category browser, Greyparrot's waste taxonomy, the GBIF / iNaturalist taxon tree
The original UI it replaces
~/bam-waste-objects/views/Types.base and Materials.base (flat tables with a backlink formula)
What it shows
graph (dagre layout, edges from parent), table with tree: {parent}, cards of types with mesh:, a 3D stage beside the graph (prototype page)
Data
../object-db-shelf/taxonomy.json (families, 26 materials and 72 types from their frontmatter links; built by ../object-db-shelf/source/build.py)