Back to Body Journal
SOURCE / PINNED RELEASE

Made of little things.

Body Journal

Release
e8049f8da4e2…
Author-recorded commit
61c04bf0e8aa…
License
LICENSE
Author’s source reference
nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-6c4554844c7

Archive hash verified: 4369d778da046a8b…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

tests/mouth.test.mjs
import assert from 'node:assert/strict';
import test from 'node:test';
import {createHash} from 'node:crypto';
import {readFileSync} from 'node:fs';
import {resolve,dirname} from 'node:path';
import {runInNewContext} from 'node:vm';
import ts from 'typescript';
import * as three from 'three';
const cache=new Map();
function load(file){
 const path=resolve(file);if(cache.has(path))return cache.get(path).exports;
 const module={exports:{}};cache.set(path,module);
 runInNewContext(ts.transpileModule(readFileSync(path,'utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022}}).outputText,{module,exports:module.exports,TextEncoder,TextDecoder,require:name=>name==='three'?three:load(resolve(dirname(path),name.replace(/\.js$/,'.ts')))});return module.exports;
}
const {SkinModel,decodeSkin}=load('src/skin-model.ts'),{decodeMouth}=load('src/mouth-data.ts');
const {draftString,parseDraft,casePayload}=load('src/case-record.ts'),{parseSession,sessionString}=load('src/session-record.ts');
const {profile,makeConcern}=load('src/case.ts'),{parseJawOpening}=load('src/jaw-pose.ts');
const {BodyInspection}=load('src/body-inspection.ts'),{descendants,anatomyTree,visibilityState}=load('src/anatomy-tree.ts');
const bytes=file=>{const b=readFileSync(file);return b.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength);};
const data=decodeSkin(bytes('assets/skin/body-skin.bin')),mouth=decodeMouth(bytes('assets/mouth/mouth.bin'));
const {MeshStandardMaterial,Vector3,Raycaster,Box3}=three;
function model(){const m=new SkinModel(data,new MeshStandardMaterial(),undefined,[],mouth);m.setLayer('mouth');m.update();return m;}
function center(mesh){return new Box3().setFromObject(mesh).getCenter(new Vector3());}
function pick(m,id){const mesh=m.surfaces.find(s=>s.name===id),c=center(mesh);return new Raycaster(c.clone().add(new Vector3(0,0,1)),new Vector3(0,0,-1)).intersectObject(mesh,false)[0];}

test('mouth package contains 28 unique permanent FDI teeth, correctly sided, with valid geometry',()=>{
 const provenance=JSON.parse(readFileSync('assets/mouth/provenance.json','utf8'));
 assert.equal(createHash('sha256').update(readFileSync('assets/mouth/mouth.bin')).digest('hex'),provenance.sha256);
 assert.equal(provenance.structures,mouth.parts.length);
 const m=model(),teeth=mouth.parts.filter(p=>p.kind==='tooth');assert.equal(teeth.length,28);assert.equal(new Set(teeth.map(p=>p.fdi)).size,28);
 for(const p of mouth.parts){
  const mesh=m.surfaces.find(s=>s.name===p.id),positions=mesh.geometry.getAttribute('position');
  assert.ok([...positions.array].every(Number.isFinite));assert.ok([...mesh.geometry.index.array].every(i=>i<positions.count));
  if(p.kind!=='tooth')continue;
  const q=Math.floor(p.fdi/10),left=[2,3].includes(q),upper=[1,2].includes(q);
  assert.ok(p.fdi%10>=1&&p.fdi%10<=7);assert.equal(p.jaw,upper?'upper':'lower');assert.equal(center(mesh).x>0,left,p.label);
  assert.match(p.label,new RegExp(`^${left?'Left':'Right'} ${upper?'upper':'lower'}.*FDI ${p.fdi}$`));
 }
 m.dispose();
});
test('opening moves lower teeth and tongue downward while upper teeth stay fixed; anchors follow',()=>{
 const m=model(),upper=m.surfaces.find(s=>s.name==='FMA55682');
 // Choose the lower central incisor by catalog so the test also checks canonical labels.
 const info=mouth.parts.find(p=>p.fdi===31),hit=pick(m,info.id);assert.ok(hit);
 const {mark,label}=m.mark(hit,.002,1),saved=JSON.stringify(mark),before=m.anchor(mark).point.clone(),fixed=center(upper);
 const tongue=m.surfaces.find(s=>s.name==='FMA54640'),tongueBefore=center(tongue);
 m.jawOpening=1;m.update();const moved=m.anchor(mark).point;
 assert.ok(moved.y<before.y-.015);assert.ok(moved.distanceTo(before)>.02);assert.ok(center(upper).distanceTo(fixed)<1e-8);assert.ok(center(tongue).y<tongueBefore.y);
 assert.equal(label,info.label);assert.equal(mark.surface.model,'bp3d-mouth-1');assert.equal(JSON.stringify(mark),saved);
 m.shape(190,125,'Female');assert.equal(m.jawOpening,1);assert.ok(m.anchor(mark));assert.equal(JSON.stringify(mark),saved);
 m.jawOpening=0;m.shape(172,70,'');assert.ok(m.anchor(mark).point.distanceTo(before)<1e-7);
 m.dispose();
});
test('mouth focus, grouped visibility and picking remain independent across jaw opening',()=>{
 const m=model(),inspect=new BodyInspection(m);assert.ok(inspect.set('region:mouth'));const all=m.surfaces.length;assert.equal(all,32);
 assert.equal(descendants('mouth','region:upper-left-teeth').length,7);inspect.setVisible('region:lower-mouth',false);assert.equal(inspect.surfaces.length,16);
 const hidden=JSON.stringify(inspect.hidden);assert.ok(inspect.set('structure:FMA55682'));assert.equal(JSON.stringify(inspect.hidden),hidden);
 inspect.setVisible('region:upper-left-teeth',false);assert.equal(inspect.surfaces.length,9);assert.equal(visibilityState(anatomyTree('mouth'),new Set(inspect.hidden)),'mixed');
 inspect.setVisible('region:body',false);inspect.setVisible('structure:FMA54640',true);assert.equal(inspect.surfaces.length,1);
 assert.ok(inspect.set('structure:FMA54640'));m.jawOpening=.7;m.update();const hit=pick(m,'FMA54640');assert.ok(hit);assert.ok(inspect.accepts(hit));const {mark}=m.mark(hit,.003,1);assert.ok(inspect.includesMark(mark));assert.ok(inspect.bounds().containsPoint(m.anchor(mark).point));
 inspect.setVisible('region:body',true);assert.equal(inspect.surfaces.length,32);inspect.dispose();m.dispose();
});
test('mouth concern and working jaw pose round-trip independently; labels, limits and revisions reach AI',()=>{
 const m=model(),c=makeConcern(1,'Left upper central incisor · FDI 21','standing');c.layer='mouth';c.jawOpening=.4;c.marks=[m.mark(pick(m,'FMA55682'),.002,1).mark];
 const second=makeConcern(2,'Tongue','sitting');second.layer='mouth';second.jawOpening=.9;
 const draft=parseDraft(draftString(profile,[c,second]));assert.equal(draft.concerns[0].jawOpening,.4);assert.equal(draft.concerns[1].jawOpening,.9);
 const record={version:1,draft,view:{page:'map',panel:'body',selectedId:2,pose:'standing',layer:'mouth',jawOpening:.6,exampleAttachment:false,newObservation:true}};
 assert.equal(parseSession(sessionString(record)).view.jawOpening,.6);assert.equal(parseSession(sessionString(record)).draft.concerns[1].jawOpening,.9);
 const payload=casePayload(profile,[c]);assert.match(payload.concerns[0].illustratedPose,/jaw partly open/);assert.match(payload.concerns[0].approximatePaintedSurfaceAreas[0],/FDI 21/);assert.ok(payload.evidenceLimits.some(s=>s.includes('No wisdom teeth')));
 c.jawOpening=.8;assert.notEqual(casePayload(profile,[c]).bodyMapRevision,payload.bodyMapRevision);
 for(const value of [-.1,1.1,NaN,Infinity,null,'1',{}])assert.throws(()=>parseJawOpening(value));
 const bad=JSON.parse(draftString(profile,[c]));bad.concerns[0].jawOpening=2;assert.throws(()=>parseDraft(JSON.stringify(bad)));
 bad.concerns[0].jawOpening=.5;bad.concerns[0].marks[0].surface.zone='FDI21';assert.throws(()=>parseDraft(JSON.stringify(bad)));
 delete c.jawOpening;assert.equal(parseDraft(draftString(profile,[c])).concerns[0].jawOpening,undefined);assert.match(casePayload(profile,[c]).concerns[0].illustratedPose,/jaw closed/);
 m.dispose();
});

test('closed mouth fits behind the inner lips across body shapes, with an ear-adjacent hinge',()=>{
 const m=model();
 for(const sex of ['Male','Female',''])for(const weight of [48,75,110]){
  m.shape(172,weight,sex);m.update();
  const lip=m.mesh.getVertexPosition(537,new Vector3()),ear=m.mesh.getVertexPosition(12017,new Vector3());
  const bounds=new Box3();for(const part of mouth.parts.filter(p=>[11,21].includes(p.fdi)))bounds.union(new Box3().setFromObject(m.surfaces.find(s=>s.name===part.id)));
  assert.ok(lip.z-bounds.max.z>.002 && lip.z-bounds.max.z<.006,'upper incisors just inside inner lip');
  assert.ok(Math.abs(bounds.min.y-(lip.y-.002))<.001,'bite edge near lip seam');
  const jaw=m.surfaces.find(s=>s.name==='FMA52748'),hinge=jaw.parent.getWorldPosition(new Vector3());
  assert.ok(Math.abs(hinge.z-ear.z-.01)<.001,'hinge anterior to ear');
 }
 m.dispose();
});

test('working IK pose and anatomy drawer round-trip without an observation',()=>{
 const record={version:1,draft:JSON.parse(draftString(profile,[])),view:{page:'map',panel:'body',selectedId:null,pose:'standing',exampleAttachment:false,anatomyPanelOpen:false,joints:{'left-arm':[.3,.1,-.2]},fingers:{'left-index':[.4,.3,.2]}}};
 const saved=parseSession(sessionString(record));assert.equal(saved.view.anatomyPanelOpen,false);assert.equal(saved.view.joints['left-arm'][0],.3);assert.equal(saved.draft.concerns.length,0);
 for(const joints of [{'left-arm':[NaN,0,0]},{'bad-bone':[0,0,0]},{'left-arm':[0,0,100]}])assert.throws(()=>parseSession(JSON.stringify({...record,view:{...record.view,joints}})));
});