Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify CadView#loadIfc #1203

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 64 additions & 106 deletions src/Containers/CadView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,136 +259,94 @@ export default function CadView({

// NB: for LFS targets, this will now be media.githubusercontent.com, so
// don't use for further API endpoint construction.
const ifcURL = (uploadedFile || filepath.indexOf('/') === 0) ?
const ifcUrl = (uploadedFile || filepath.indexOf('/') === 0) ?
filepath : await getFinalUrl(filepath, accessToken)

const isCamHashSet = onHash(location, viewer.IFC.context.ifcCamera.cameraControls)

let loadedModel
if (!isOpfsAvailable) {
// fallback to loadIfcUrl
loadedModel = await viewer.loadIfcUrl(
ifcURL,
!isCamHashSet,
(progressEvent) => {
if (Number.isFinite(progressEvent.loaded)) {
const loadedBytes = progressEvent.loaded
// eslint-disable-next-line no-magic-numbers
const loadedMegs = (loadedBytes / (1024 * 1024)).toFixed(2)
setSnackMessage(`${loadingMessageBase}: ${loadedMegs} MB`)
debug().log(`CadView#loadIfc$onProgress, ${loadedBytes} bytes`)
}
},
(error) => {
debug().log('CadView#loadIfc$onError: ', error)
setIsModelLoading(false)
setSnackMessage('')
}, customViewSettings)
} else if (uploadedFile) {
const file = await getModelFromOPFS('BldrsLocalStorage', 'V1', 'Projects', filepath)

if (file instanceof File) {
setOpfsFile(file)
} else {
debug().error('Retrieved object is not of type File.')
const onProgress = (progressEvent) => {
if (Number.isFinite(progressEvent.loaded)) {
const loadedBytes = progressEvent.loaded
// eslint-disable-next-line no-magic-numbers
const loadedMegs = (loadedBytes / (1024 * 1024)).toFixed(2)
setSnackMessage(`${loadingMessageBase}: ${loadedMegs} MB`)
debug().log(`CadView#loadIfc$onProgress, ${loadedBytes} bytes`)
}
}

loadedModel = await viewer.loadIfcFile(
file,
true, // ignore current camera for new load
(error) => {
debug().log('CadView#loadIfc$onError: ', error)
}, customViewSettings)
// TODO(nickcastel50): need a more permanent way to
// prevent redirect here for bundled ifc files
} else if (ifcURL === '/index.ifc') {
const file = await downloadToOPFS(
const onError = (error) => {
debug().log('CadView#loadIfc$onError: ', error)
setIsModelLoading(false)
setSnackMessage(`Could not load file: ${filepath}. Please try logging in if the repository is private.`)
}

let file
let fitToFrame = !isCamHashSet
let loadedModel
if (isOpfsAvailable) {
if (uploadedFile) {
file = await getModelFromOPFS('BldrsLocalStorage', 'V1', 'Projects', filepath)
// There's never a camera URL param for an uploadedFile to always fitToFrame
fitToFrame = true
} else if (ifcUrl === '/index.ifc') {
// TODO(nickcastel50): need a more permanent way to
// prevent redirect here for bundled ifc files
file = await downloadToOPFS(
navigate,
appPrefix,
handleBeforeUnload,
ifcURL,
ifcUrl,
'index.ifc',
'bldrs-ai',
'BldrsLocalStorage',
'V1',
'Projects',
(progressEvent) => {
if (Number.isFinite(progressEvent.receivedLength)) {
const loadedBytes = progressEvent.receivedLength
// eslint-disable-next-line no-magic-numbers
const loadedMegs = (loadedBytes / (1024 * 1024)).toFixed(2)
setSnackMessage(`${loadingMessageBase}: ${loadedMegs} MB`)
debug().log(`CadView#loadIfc$onProgress, ${loadedBytes} bytes`)
}
})

if (file instanceof File) {
setOpfsFile(file)
onProgress)
} else {
debug().error('Retrieved object is not of type File.')
}
// TODO(pablo): probably already available in this scope, or use
// parseGitHubRepositoryURL instead.
const {isPublic, owner, repo, branch, filePath} = parseGitHubPath(new URL(gitpath).pathname)
const commitHash = isPublic ?
await getLatestCommitHash(owner, repo, filePath, '', branch) :
await getLatestCommitHash(owner, repo, filePath, accessToken, branch)

if (commitHash === null) {
// downloadToOpfs below will error out as well.
debug().error(
`Error obtaining commit hash for: ` +
`owner:${owner}, repo:${repo}, filePath:${filePath}, branch:${branch} ` +
`accessToken (present?):${accessToken ? 'true' : 'false'}`)
}

loadedModel = await viewer.loadIfcFile(
file,
!isCamHashSet,
(error) => {
debug().log('CadView#loadIfc$onError: ', error)
setIsModelLoading(false)
setSnackMessage('')
}, customViewSettings)
} else {
// TODO(pablo): probably already available in this scope, or use
// parseGitHubRepositoryURL instead.
const {isPublic, owner, repo, branch, filePath} = parseGitHubPath(new URL(gitpath).pathname)
const commitHash = isPublic ?
await getLatestCommitHash(owner, repo, filePath, '', branch) :
await getLatestCommitHash(owner, repo, filePath, accessToken, branch)

if (commitHash === null) {
// downloadToOpfs below will error out as well.
debug().error(
`Error obtaining commit hash for: ` +
`owner:${owner}, repo:${repo}, filePath:${filePath}, branch:${branch} ` +
`accessToken (present?):${accessToken ? 'true' : 'false'}`)
file = await downloadToOPFS(
navigate,
appPrefix,
handleBeforeUnload,
ifcUrl,
filePath,
commitHash,
owner,
repo,
branch,
onProgress)
}
}

const file = await downloadToOPFS(
navigate,
appPrefix,
handleBeforeUnload,
ifcURL,
filePath,
commitHash,
owner,
repo,
branch,
(progressEvent) => {
if (Number.isFinite(progressEvent.receivedLength)) {
const loadedBytes = progressEvent.receivedLength
// eslint-disable-next-line no-magic-numbers
const loadedMegs = (loadedBytes / (1024 * 1024)).toFixed(2)
setSnackMessage(`${loadingMessageBase}: ${loadedMegs} MB`)
debug().log(`CadView#loadIfc$onProgress, ${loadedBytes} bytes`)
}
})

if (file) {
if (file instanceof File) {
setOpfsFile(file)
} else {
debug().error('Retrieved object is not of type File.')
}

loadedModel = await viewer.loadIfcFile(
file,
!isCamHashSet,
(error) => {
debug().log('CadView#loadIfc$onError: ', error)
// TODO(pablo): error modal.
setIsModelLoading(false)
setAlertMessage(`Could not load file: ${filepath}. Please try logging in if the repository is private.`)
}, customViewSettings)
loadedModel = await viewer.loadIfcFile(file, fitToFrame, onError, customViewSettings)
} else {
// Fallback to load from origin if not found locally
loadedModel = await viewer.loadIfcUrl(ifcUrl, fitToFrame, onProgress, onError, customViewSettings)
}

// This may not have been called by onError yet.
setIsModelLoading(false)

if (loadedModel) {
// Fix for https://github.com/bldrs-ai/Share/issues/91
//
Expand All @@ -399,7 +357,7 @@ export default function CadView({
// always be 0.
loadedModel.modelID = 0
setModel(loadedModel)
updateLoadedFileInfo(uploadedFile, ifcURL)
updateLoadedFileInfo(uploadedFile, ifcUrl)

await viewer.isolator.setModel(loadedModel)

Expand Down
10 changes: 7 additions & 3 deletions src/OPFS/OPFS.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,15 @@ async function downloadModelToOPFS(objectUrl, commitHash, originalFilePath, owne
receivedLength += value.length

if (onProgress) {
// Variable names reflect MDN ProgressEvent field names
// https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent
self.postMessage({
progressEvent: onProgress,
progressEvent: onProgress, // REVIEW: should this really be a function
// value for an event varname, and tests
// pass it a boolean?
lengthComputable: contentLength !== 0,
contentLength: contentLength,
receivedLength: receivedLength,
total: contentLength,
loaded: receivedLength,
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/OPFS/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ export function downloadToOPFS(
if (onProgress) {
onProgress({
lengthComputable: event.data.contentLength !== 0,
contentLength: event.data.contentLength,
receivedLength: event.data.receivedLength,
total: event.data.total,
loaded: event.data.loaded,
}) // Custom progress event
}
} else if (event.data.completed) {
Expand Down
6 changes: 3 additions & 3 deletions src/OPFS/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ describe('OPFS Test Suite', () => {
const mockWorker = {
addEventListener: jest.fn((_, handler) => {
process.nextTick(() => {
handler({data: {progressEvent: true, contentLength: 100, receivedLength: 50}}) // Simulate a progress update
handler({data: {progressEvent: true, total: 100, loaded: 50}}) // Simulate a progress update
handler({data: {completed: true, event: 'download', file: new Blob(['content'])}}) // Then complete
})
}),
Expand All @@ -145,8 +145,8 @@ describe('OPFS Test Suite', () => {

expect(onProgressMock).toHaveBeenCalledWith({
lengthComputable: true,
contentLength: 100,
receivedLength: 50,
total: 100,
loaded: 50,
})
})
})
Expand Down
Loading