function filterReteBiByBit( contentFilename ){ let file = filesWithMetadata[contentFilename] if (!file) return // can be removed for URLs as those are not with metadata let contentType = file.contentType // mereology option let openingOptions = filesWithMetadata[contentFilename].openingOptions // can be used via e.g. showFile("https://fabien.benetou.fr/?action=source",{ mereology:"whole"}) // filtering, only applying what's next to a certain content type and/or with filename filtering with .startsWith() .endsWith() .includes() or regex if ( contentType.includes("") && (contentFilename.endsWith("-rete.bitbybit") || contentFilename.endsWith("rete-runner.bitbybit") )) { console.log('it is a Rete BitByBit file', contentFilename) // assuming non minified code... but maybe works the same way // TODO try with minified code, would be preferred in order to do execution after const filenameIdPrefix = "retebitbybit_id_" if (contentFilename.endsWith("rete-runner.bitbybit") ) { fetch( contentFilename ).then( r => r.text() ).then( txt => { executeBitbybit(txt) // can keep track of generate meshes via // AFRAME.scenes[0].object3D.children.filter( o => o.name.includes("brepMesh") ) // filtering with before the call and after (even though async) }) } else { fetch( contentFilename ).then( r => r.json() ).then( txt => { let nodes = Object.entries( JSON.parse(txt.script).nodes ) //console.log( nodes ) const rootEl = document.createElement("a-entity") file.filteredEl = rootEl rootEl.execute = _ => console.warn( 'Not implemented for now, see executeBitbybit()') // TODO see executeBitbybit() , needs runner code too // function that can then be called on the created element later on // e.g. filesWithMetadata["https://companion.benetou.fr/saved/pdfxml/3209542.3209570.xml"].filteredEl.nextPage('ok') nodes.map( n => { let el = document.createElement("a-troika-text") let boxEl = document.createElement("a-box") boxEl.setAttribute("wireframe", "true" ) boxEl.setAttribute("width", .3 ) boxEl.setAttribute("height", .4 ) boxEl.setAttribute("depth", .01 ) boxEl.setAttribute("position", "0 -.18 0" ) el.setAttribute("value", n[1].customName ) el.setAttribute("font-size", ".05") el.setAttribute("target", "") let x = 1+n[1].position[0]/1000 let y = 2-n[1].position[1]/1000 let z = -1 el.setAttribute("position", ""+x+" "+y+" "+z) rootEl.appendChild(el) el.appendChild(boxEl) el.id = filenameIdPrefix + n[1].id }) nodes.map( p => { let n = p[1] let inputs = Object.entries( n.inputs ).map( o => o[1] ) if (inputs.length) { // console.log( n.id, inputs ) inputs.map( c => { let el = document.createElement("a-entity") el.setAttribute('live-selector-line', 'start: #'+(filenameIdPrefix+n.id) +'; end: #'+(filenameIdPrefix+c.connections[0].node) +';' ) el.classList.add('retebitbybit_export_link') rootEl.appendChild(el) }) } }) AFRAME.scenes[0].appendChild(rootEl) AFRAME.scenes[0].emit('retebitbybitloaded', contentFilename) // to use the event consider : //AFRAME.scenes[0].addEventListener("retebitbybitloaded", e => console.log(e)) } ); } } applyNextFilter( contentFilename ) // can stop here or move on to the next filter that might or not be applied } sequentialFilters.push( filterReteBiByBit ) // adding this to the list of filters to go through, order matters // typically one would be generic filters first then more specific ones after async function executeBitbybit(code){ window.THREEJS = window.THREE; await import("https://cdn.jsdelivr.net/gh/bitbybit-dev/bitbybit-assets@0.20.4/runner/bitbybit-runner-lite-threejs.js") const aframeScene = document.querySelector('a-scene').object3D; const runnerOptions = { canvasZoneClass: 'myCanvasZone', enableOCCT: true, enableJSCAD: false, enableManifold: false, loadFonts: ['Roboto'], externalThreeJSSettings: { scene: aframeScene, camera: AFRAME.systems.camera, } }; const runner = window.bitbybitRunner.getRunnerInstance(); const { bitbybit, Bit, camera, scene, renderer } = await runner.run( runnerOptions); window.bitbybit = bitbybit; window.Bit = Bit; window.runner = runner runner.executeScript(code) }