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

Streaming loader #656

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"express": "^4.12.3",
"extend": "^3.0.0",
"filesaver.js": "^0.1.1",
"filestream": "^4.0.0",
"font-awesome": "^4.3.0",
"fs-promise": "^0.3.1",
"jade": "^1.10.0",
Expand All @@ -45,7 +46,6 @@
"mkdirp": "^0.5.0",
"morgan": "^1.4.1",
"mousetrap": "^1.4.6",
"nanobar": "^0.2.1",
"nib": "^1.0.4",
"node-png": "^0.4.3",
"operative": "^0.4.0-rc1",
Expand All @@ -54,7 +54,7 @@
"serve-favicon": "^2.1.6",
"spin": "0.0.1",
"stl-exporter": "^0.3.2",
"stl-parser": "^0.8.0",
"stl-parser": "^0.9.1",
"string.prototype.endswith": "^0.2.0",
"stringify": "^3.1.0",
"stylus": "^0.50.0",
Expand Down
3 changes: 3 additions & 0 deletions public/styles/app/sidebar.styl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
left 0
user-select none

#loadButton
position relative

.navbar-toggle
margin-top 5px
.icon-bar
Expand Down
3 changes: 3 additions & 0 deletions public/styles/landingpage/teaser.styl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ header
margin-left 30px
top -0.4em

#loadButton
position relative

#educators
display block
text-align center
Expand Down
7 changes: 7 additions & 0 deletions public/styles/progressBar.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#progressBar
position absolute
top 0
left 0
background-color rgba(255, 255, 255, 0.5)
width 0%
height 0.3em
1 change: 1 addition & 0 deletions public/styles/screen.styl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ $icon-font-path ?= '/node_modules/bootstrap-styl/fonts/'

@import bootstrap
@import '../../node_modules/font-awesome/css/font-awesome.css'
@import progressBar
@import nib

@import spinner
Expand Down
57 changes: 33 additions & 24 deletions src/client/landingpage.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ piwikTracking = require './piwikTracking'
globalConfig = require '../common/globals.yaml'
Bundle = require './bundle'
clone = require 'clone'
fileLoader = require './modelLoading/fileLoader'
fileDropper = require './modelLoading/fileDropper'
modelCache = require './modelLoading/modelCache'
readFiles = require './modelLoading/readFiles'


# Set renderer size to fit to 3 bootstrap columns
globalConfig.staticRendererSize = true
Expand Down Expand Up @@ -71,35 +73,42 @@ b1 = bundle1.init().then ->
#load and process model
loadAndConvert 'goggles'

dropAndInputCallback = (event) ->
files = event.target.files ? event.dataTransfer.files
fileInputCallback = (files) ->
if files.length
piwikTracking.trackEvent 'Landingpage', 'LoadModel', files[0].name
fileLoader.onLoadFile files, $('#loadButton')[0], shadow: false
.then loadAndConvert
piwikTracking.trackEvent(
'Landingpage'
'LoadModel'
files[0].name
)

readFiles files
.then loadAndConvert
else
identifier = event.dataTransfer.getData 'text/plain'
piwikTracking.trackEvent 'Landingpage', 'LoadModelFromImage', identifier
modelCache.exists identifier
.then -> loadAndConvert identifier
.catch -> bootbox.alert(
title: 'This is not a valid model!'
message: 'You can only drop stl files or our example images.'
piwikTracking.trackEvent(
'Landingpage'
'LoadModelFromImage'
identifier
)
modelCache.exists identifier
.then -> loadAndConvert identifier
.catch -> bootbox.alert(
title: 'This is not a valid model!'
message: 'You can only drop stl files or our example images.'
)

fileDropper = require './modelLoading/fileDropper'
fileDropper.init dropAndInputCallback
fileDropper.init fileInputCallback

fileInput = document.getElementById('fileInput')
fileInput.addEventListener 'change', (event) ->
dropAndInputCallback event
fileInput.value = ''
document
.getElementById 'fileInput'
.addEventListener 'change', (event) ->
fileInputCallback @files
@value = ''

$('.dropper').text 'Drop an stl file'
$('#preview img, #preview a').on( 'dragstart'
(e) ->
e.originalEvent.dataTransfer.setData(
$('#loadButton img').hide()
$('#loadingStatus').text 'Drop an STL file'
$('#preview img, #preview a').on 'dragstart', (event) ->
event.originalEvent.dataTransfer.setData(
'text/plain'
e.originalEvent.target.getAttribute 'data-identifier'
event.originalEvent.target.getAttribute 'data-identifier'
)
)
2 changes: 1 addition & 1 deletion src/client/modelLoading/fileDropper.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ addOverlay = (target) ->
bindDropHandler = (target, overlay, callback) ->
target.addEventListener 'drop', (event) ->
hideOverlay overlay
callback event
callback event.dataTransfer.files
stopEvent event
target.addEventListener 'dragover', (event) ->
stopEvent event
Expand Down
83 changes: 0 additions & 83 deletions src/client/modelLoading/fileLoader.coffee

This file was deleted.

111 changes: 111 additions & 0 deletions src/client/modelLoading/readFiles.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
ReadableFileStream = require('filestream').read
stlParser = require 'stl-parser'
meshlib = require 'meshlib'
log = require 'loglevel'

modelCache = require './modelCache'

averageFaceSize = 240 # Bytes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls replace with e.g. progress of read bytes / file size

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed in another pull request.
…but it's already noted: ad-si/stl-parser#7


loadingPercentage = 80
processingPercentage = 90

idleText = 'Drop an STL File'
processingText = 'Processing Geometry'
viewPreparationText = 'Preparing View'

$loadingTextElement = $ '#loadingStatus'
progressBarElement = document.getElementById 'progressBar'

module.exports = (files) ->

return new Promise (resolve, reject) ->

if files.length > 1
errorObject = {
title: 'Import failed'
message: 'Loading of multiple files is not supported.'
}
bootbox.alert errorObject
return reject errorObject

file = files[0]

if not /stl$/i.test file.name
bootbox.alert(
title: 'Your file does not have the right format!'
message: 'Only .stl files are supported at the moment.
We are working on adding more file formats'
)
return Promise.reject('Wrong file format')

faceCounter = file.size / averageFaceSize

progressBarElement.style.width = 0
$loadingTextElement.text 'Loading File'

fileStream = new ReadableFileStream file
fileStream.on 'error', (error) ->
bootbox.alert {
title: 'Import failed'
message: 'Your file contains errors that we could not fix.
You can try to fix your model with e.g.
<a href=http://meshlab.sourceforge.net>meshlab</a>
before uploading it.'
}
reject error

streamingStlParser = stlParser {blocking: false}
modelBuilder = new meshlib.ModelBuilder()

streamingStlParser.on 'data', (data) ->
# if data-chunk is the header
if data.faceCount?
faceCounter = data.faceCount
# or a face
else
progress = (data.number / faceCounter) * loadingPercentage
if progress < loadingPercentage
progressBarElement.style.width = progress + '%'

streamingStlParser.on 'warning', log.warn

streamingStlParser.on 'error', (error) ->
@end()
streamingStlParser.unpipe modelBuilder
bootbox.alert {
title: 'Invalid STL-file'
message: error.message
callback: ->
progressBarElement.style.width = 0
$loadingTextElement.text idleText
}
reject error


modelBuilder.on 'model', (model) ->
progressBarElement.style.width = loadingPercentage + '%'
$loadingTextElement.text processingText

processModel = ->
model
.setFileName file.name
.calculateNormals()
.buildFaceVertexMesh()
.done()
.then ->
progressBarElement.style.width = processingPercentage + '%'
$loadingTextElement.text viewPreparationText
return modelCache.store model
.then (hash) ->
progressBarElement.style.width = '100%'
$loadingTextElement.text idleText
resolve hash
progressBarElement.style.width = 0

# Give time to render text
setTimeout processModel, 50

fileStream
.pipe streamingStlParser
.pipe modelBuilder
42 changes: 22 additions & 20 deletions src/client/ui/workflowUi/LoadUi.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fileDropper = require '../../modelLoading/fileDropper'
fileLoader = require '../../modelLoading/fileLoader'
readFiles = require '../../modelLoading/readFiles'
piwikTracking = require '../../piwikTracking'

class LoadUi
Expand All @@ -14,25 +14,27 @@ class LoadUi
fileDropper.init @fileLoadHandler

$('#fileInput').on 'change', (event) =>
@fileLoadHandler(event).then =>
$('#fileInput').val('')
@workflowUi.hideMenuIfPossible()

fileLoadHandler: (event) =>
files = event.target.files ? event.dataTransfer.files
@_checkReplaceModel().then (loadConfirmed) =>
return unless loadConfirmed
piwikTracking.trackEvent 'Editor', 'LoadModel', files[0].name
spinnerOptions =
length: 5
radius: 3
width: 2
shadow: false
fileLoader.onLoadFile(
files
document.getElementById 'loadButtonFeedback'
spinnerOptions
).then @workflowUi.bundle.modelLoader.loadByIdentifier
@fileLoadHandler(event.target.files)
.then =>
$('#fileInput').val('')
@workflowUi.hideMenuIfPossible()

fileLoadHandler: (files) =>
return unless files.length

@_checkReplaceModel()
.then (loadConfirmed) ->
return unless loadConfirmed

piwikTracking.trackEvent(
'Editor'
'LoadModel'
files[0].name
)

return readFiles files

.then @workflowUi.bundle.modelLoader.loadByIdentifier

_checkReplaceModel: =>
question = 'You already have a model in your scene.
Expand Down
Loading