Skip to content

Commit

Permalink
Merge pull request #29 from bldrs-ai/server-refactor
Browse files Browse the repository at this point in the history
Server refactor
  • Loading branch information
pablo-mayrgundter authored Oct 16, 2023
2 parents 7222246 + f766a69 commit f1ebe4d
Show file tree
Hide file tree
Showing 75 changed files with 92,542 additions and 153 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ bundle.js
venv
.idea
dist/

# Test curl output
render.png
2 changes: 1 addition & 1 deletion jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ module.exports = {
transform: {'\\.[jt]sx?$': 'babel-jest'},
transformIgnorePatterns: [],
moduleNameMapper: {},
setupFilesAfterEnv: [],
setupFilesAfterEnv: ['./src/setupTests.js'],
}
16 changes: 0 additions & 16 deletions models/bld/axes.bld

This file was deleted.

18 changes: 9 additions & 9 deletions models/bld/bunnies.bld
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,38 @@
},
"objects": [
{
"href": "models/obj/Bunny.obj"
"href": "../obj/Bunny.obj"
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [0, 0, 0]
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [0, 0, 5]
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [0, 5, 0]
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [0, 5, 5]
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [5, 0, 0]
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [5, 0, 5]
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [5, 5, 0]
},
{
"href": "models/obj/Bunny.obj",
"href": "../obj/Bunny.obj",
"pos": [5, 5, 5]
}
]
Expand Down
Binary file added models/bld/bunnies.bld-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 3 additions & 4 deletions models/bld/mix.bld
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
},
"objects": [
{
"id": 0,
"href": "models/obj/Bunny.obj"
"href": "http://localhost:8090/models/obj/Bunny.obj"
},
{
"id": 0,
"href": "models/pdb/buckyball.pdb"
"href": "../pdb/buckyball.pdb",
"scale": 0.01
}
]
}
Binary file added models/bld/mix.bld-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified models/fbx/nurbs.fbx-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/fbx/nurbs.fbx-server-fit.png
Binary file not shown.
Binary file modified models/fbx/samba-dancing.fbx-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/fbx/stanford-bunny.fbx-server-fit.png
Binary file not shown.
Binary file modified models/ifc/box.ifc-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/ifc/box.ifc-server-fit.png
Binary file not shown.
Binary file modified models/ifc/index.ifc-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/ifc/index.ifc-server-fit.png
Binary file not shown.
Binary file added models/index.bld-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified models/obj/Bunny.obj-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/obj/Bunny.obj-server-fit.png
Binary file not shown.
Binary file modified models/obj/index.bld-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified models/obj/tree.obj-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/obj/tree.obj-server-fit.png
Binary file not shown.
Binary file removed models/pdb/Al2O3.pdb-server-fit.png
Binary file not shown.
Binary file removed models/pdb/aspirin.pdb-server-fit.png
Binary file not shown.
Binary file modified models/pdb/buckyball.pdb-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/pdb/buckyball.pdb-server-fit.png
Binary file not shown.
Binary file removed models/pdb/caf2.pdb-server-fit.png
Binary file not shown.
Binary file modified models/pdb/caffeine.pdb-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/pdb/caffeine.pdb-server-fit.png
Binary file not shown.
Binary file modified models/pdb/cholesterol.pdb-fit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed models/pdb/cholesterol.pdb-server-fit.png
Binary file not shown.
Binary file removed models/pdb/cocaine.pdb-server-fit.png
Diff not rendered.
Binary file removed models/pdb/cu.pdb-server-fit.png
Diff not rendered.
Binary file modified models/pdb/cubane.pdb-fit.png
Binary file removed models/pdb/cubane.pdb-server-fit.png
Diff not rendered.
Binary file removed models/pdb/diamond.pdb-server-fit.png
Diff not rendered.
Binary file modified models/pdb/ethanol.pdb-fit.png
Binary file removed models/pdb/ethanol.pdb-server-fit.png
Diff not rendered.
Binary file modified models/pdb/glucose.pdb-fit.png
Binary file removed models/pdb/glucose.pdb-server-fit.png
Diff not rendered.
Binary file removed models/pdb/graphite.pdb-server-fit.png
Diff not rendered.
Binary file modified models/pdb/index.bld-fit.png
Binary file modified models/pdb/lsd.pdb-fit.png
Binary file removed models/pdb/lsd.pdb-server-fit.png
Diff not rendered.
Binary file removed models/pdb/lycopene.pdb-server-fit.png
Diff not rendered.
Binary file removed models/pdb/nacl.pdb-server-fit.png
Diff not rendered.
Binary file modified models/pdb/nicotine.pdb-fit.png
Binary file removed models/pdb/nicotine.pdb-server-fit.png
Diff not rendered.
Binary file modified models/pdb/ybco.pdb-fit.png
Binary file removed models/pdb/ybco.pdb-server-fit.png
Diff not rendered.
Binary file modified models/stl/pr2_head_pan.stl-fit.png
Binary file modified models/stl/slotted_disk.stl-fit.png
Binary file modified models/xyz/helix_201.xyz-fit.png
Binary file removed models/xyz/helix_201.xyz-server-fit.png
Diff not rendered.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"babel-jest": "^28.1.3",
"esbuild": "^0.18.16",
"jest": "^29.6.2",
"jest-environment-jsdom": "^29.6.2"
"jest-environment-jsdom": "^29.6.2",
"msw": "^1.3.2"
}
}
Binary file removed screenshot.png
Diff not rendered.
Binary file removed server-render.png
Diff not rendered.
10 changes: 1 addition & 9 deletions src/BLDLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,8 @@ export default class BLDLoader {
root.scale.setScalar(model.scale)
}

const axes = new AxesHelper()
root.add(axes)

for (let objRef of model.objects) {
let subPath = objRef.href
if (basePath) {
subPath = `${basePath}/${subPath}`
}
const hrefUrl = new URL(`file:${subPath}`)
const subModel = await load(hrefUrl)
const subModel = await load(new URL(objRef.href, basePath))
root.add(subModel)

if (objRef.pos) {
Expand Down
4 changes: 4 additions & 0 deletions src/Filetype.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import {assertDefined} from './assert.js'


// TODO: 3dm, glb
export const supportedTypes = ['bld', 'fbx', 'ifc', 'obj', 'stl', 'pdb', 'xyz']

Expand Down Expand Up @@ -43,6 +46,7 @@ export function pathSuffixSupported(pathWithSuffix) {
* @return {{parts: Array.<string>, extension: string}}
*/
export function splitAroundExtension(filepath) {
assertDefined(filepath)
const match = fileSuffixRegex.exec(filepath)
if (!match) {
throw new FilenameParseError(`Filepath(${filepath}) must contain ".${typeRegexStr}" (case-insensitive)`)
Expand Down
2 changes: 1 addition & 1 deletion src/Filetype.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('Filetype', () => {
expect(extension).toStrictEqual(`.${ext}`)
}
expect(() => {
splitAroundExtension(`asdf.stl/blah`)
splitAroundExtension(`asdf.com/blah`)
}).toThrow(FilenameParseError)
})
})
74 changes: 31 additions & 43 deletions src/Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {XYZLoader} from 'three/addons/loaders/XYZLoader.js'
import {IFCLoader} from 'web-ifc-three/web-ifc-three/dist/web-ifc-three.js'
import BLDLoader from './BLDLoader.js'
import * as Filetype from './Filetype.js'
import {assertDefined, assertTrue} from './assert.js'
import debug from './debug.js'
import {maybeResolveLocalPath} from './urls.js'
import './fetch-polyfill.js'
import glbToThree from './glb.js'
import pdbToThree from './pdb.js'
Expand All @@ -29,67 +31,54 @@ export async function load(
onUnknownType = (errEvent) => {debug().error(errEvent)},
onError = (errEvent) => {debug().error('Loaders#load: error: ', errEvent)}
) {
debug().log('Loader#load: url:', url)
url = maybeResolveLocalPath(url) || url
assertDefined(url, onProgress, onUnknownType, onError)
assertTrue(url instanceof URL)

const isFileOrigin = url.protocol === 'file:'
const pathname = url.pathname
const [loader, isLoaderAsync, isFormatText, fixupCb] = await findLoader(pathname)
debug().log(`Loader#load, pathname(${pathname}), loader:`, loader.constructor)
const [loader, isLoaderAsync, isFormatText, fixupCb] = await findLoader(url.pathname)
debug().log(
`Loader#load, pathname=${url.pathname} loader=${loader.constructor.name} isLoaderAsync=${isLoaderAsync} isFormatText=${isFormatText}`)

if (loader === undefined) {
onUnknownType()
return undefined
}

const sourceBuffer = await readToBuffer(url, isFileOrigin, isFormatText)
let modelData = (await axios.get(
url.toString(),
{ responseType:
isFormatText
? 'text'
: 'arraybuffer' }
)).data

// In headless mode, this is a Node Buffer. Convert to js
// ArrayBuffer for local/network agnostic handling.
if (modelData instanceof Buffer) {
modelData = modelData.buffer.slice(modelData.byteOffset, modelData.byteOffset + modelData.length)
}

const basePath = pathname.substring(0, pathname.lastIndexOf('/'))
let model = await readModel(loader, basePath, sourceBuffer, isLoaderAsync)
// debug().log('Loader#load: result', model)
// Provide basePath for multi-file models. Keep the last '/' for
// correct resolution of subpaths with '../'.
const basePath = url.href.substring(0, url.href.lastIndexOf('/') + 1)
let model = await readModel(loader, modelData, basePath, isLoaderAsync)

if (fixupCb) {
// debug().log('Calling fixup: ', fixupCb, model)
model = fixupCb(model)
}

return model
}


export async function readToBuffer(url, isFileOrigin, isFormatText) {
let sourceBuffer
if (isFileOrigin) {
debug().log('Loader#readToBuffer: loading local file')
if (isFormatText) {
debug().log('Loader#readToBuffer: isLocalFile:', false)
sourceBuffer = fs.readFileSync(decodeURI(url.pathname), {encoding: 'utf-8'})
} else {
debug().log('Loader#readToBuffer: isLocalFile:', true)
sourceBuffer = fs.readFileSync(decodeURI(url.pathname))
sourceBuffer = Uint8Array.from(sourceBuffer).buffer
}
} else {
sourceBuffer = await axios.get(
url.toString(),
{ responseType:
isFormatText
? 'text'
: 'arraybuffer' }
)
sourceBuffer = sourceBuffer.data
}
return sourceBuffer
}


async function readModel(loader, basePath, sourceBuffer, isLoaderAsync) {
debug().log(`Loader#readModel: loader(${loader.constructor.name}) basePath(${basePath}) isAsync(${isLoaderAsync}), data type: `, typeof sourceBuffer)
async function readModel(loader, modelData, basePath, isLoaderAsync) {
// debug().log(`Loader#readModel: loader(${loader.constructor.name}) basePath(${basePath}) isAsync(${isLoaderAsync}), data type: `, typeof modelData)
let model
/* GLB
model = await new Promise((resolve, reject) => {
debug().log('Loader#readModel: promise in')
try {
loader.parse(sourceBuffer, './', (m) => {
loader.parse(modelData, './', (m) => {
// debug().log('Loader#readModel: promise: model:', m)
resolve(m)
}, (err) => {
Expand All @@ -103,9 +92,9 @@ async function readModel(loader, basePath, sourceBuffer, isLoaderAsync) {
// debug().log('Loader#readModel: promise out, model:', model)
*/
if (isLoaderAsync) {
model = await loader.parse(sourceBuffer, basePath)
model = await loader.parse(modelData, basePath)
} else {
model = loader.parse(sourceBuffer, basePath)
model = loader.parse(modelData, basePath)
}
if (!model) {
throw new Error('Loader could not read model')
Expand All @@ -117,7 +106,6 @@ async function readModel(loader, basePath, sourceBuffer, isLoaderAsync) {

async function delegateLoad(url) {
const urlStr = url.toString()
debug().log('Delegated load:', urlStr)
return await new Promise((resolve, reject) => {
loader.load(
urlStr,
Expand Down Expand Up @@ -176,7 +164,7 @@ async function findLoader(pathname) {
case '.stl': {
loader = new STLLoader
fixupCb = stlToThree
// depends isFormatText = true
isFormatText = false
break
}
case '.xyz': {
Expand Down
26 changes: 22 additions & 4 deletions src/Loader.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import {load} from './Loader'
import {MSW_TEST_PORT} from './setupTests'
import './fetch-polyfill'


let mathRandomSpy
describe('Loader', () => {
it('Loads an IFC model', async () => {

// three.js generates random UUIDs for loaded geometry and material
// and also references them later, so it's not trivial to freeze or
// delete them. So, intercept its call to Math.random instead.
// TODO(pablo): this should probably increment the value or smth to
// make each UUID unique.
beforeEach(() => {
mathRandomSpy = jest.spyOn(Math, 'random').mockReturnValue(0.5);
})
afterEach(() => {
mathRandomSpy.mockRestore()
})

// TODO(pablo): loop through all test models.
it('loads an IFC model', async () => {
const onProgress = jest.fn()
const onUnknownType = jest.fn()
const onError = jest.fn()
const model = await load(
'models/index.ifc',
`http://localhost:${MSW_TEST_PORT}/models/ifc/index.ifc`,
onProgress,
onUnknownType,
onError
Expand All @@ -19,15 +35,16 @@ describe('Loader', () => {
// expect(onProgress).toHaveBeenCalled()
expect(model).toBeDefined()
expect(model.isObject3D).toBe(true)
expect(model).toMatchSnapshot()
})


it('Loads an OBJ model', async () => {
it('loads an OBJ model', async () => {
const onProgress = jest.fn()
const onUnknownType = jest.fn()
const onError = jest.fn()
const model = await load(
'models/Bunny.obj',
`http://localhost:${MSW_TEST_PORT}/models/obj/Bunny.obj`,
onProgress,
onUnknownType,
onError
Expand All @@ -38,5 +55,6 @@ describe('Loader', () => {
// expect(onProgress).toHaveBeenCalled()
expect(model).toBeDefined()
expect(model.children[0].isObject3D).toBe(true)
expect(model).toMatchSnapshot()
})
})
Loading

0 comments on commit f1ebe4d

Please sign in to comment.