DSchroer / dslcad

DSLCad is a programming language & interpreter for building 3D models.
https://dslcad.com
GNU Lesser General Public License v2.1
470 stars 14 forks source link

Web compiler with Three.js #8

Closed jpillora closed 1 year ago

jpillora commented 1 year ago

Thoughts?

DSchroer commented 1 year ago

The core dslcad library can be built under wasm32-unknown-emscripten. I haven't setup an API for it yet but I would be happy to accept a PR. It is certainly on my plans to release a WASM port similar to the one I made for OpenSCAD here:

https://github.com/DSchroer/openscad-wasm

DSchroer commented 1 year ago

Ive also played around with compiling the entire editor to WASM. Its close but needs some work in the bevy dependencies before it will work.

jpillora commented 1 year ago

Sounds good and it’s great it’s on the radar

I think it’d help uptake of this project if there was a live demo. In my experience, showing a easy and useful end to end example is the best way to get more users

in my case, I want to build something in three js and I want to keep everything as code and avoid blender. Would be nice to quickly validate the project to see if it might suit

gedw99 commented 1 year ago

This would be so useful

I presume the editor uses the file system to hold the files used to describe each part ?

If so then how to use in the web ?

I have seen wasm file System abstractions using indexeddb as the file system.

I have also seen web API that can work off the users real file system. But not sure how cross platform is is yet

https://developer.mozilla.org/en-US/docs/Web/API/FileSystem

DSchroer commented 1 year ago

I presume the editor uses the file system to hold the files used to describe each part ?

yes and no. Right now the editor uses a filysystem but it was designed to be optional. I think that would be something that can be left to the JS side of the web compiler.

Now the question is how much leg work are you willing to put in vs have included in the web compiler version. Do you want the entire package with the UI and editor? Or is just a compiler interface enough?

jpillora commented 1 year ago

IMO, web version is most useful as a live demonstration of the tool, maybe useful for quick prototyping too

I think for v1, aim for something simple, text left, render right

For v2, aim for something more functional, but it’d depend on what people want to do

Could add a feedback button, prefills a GitHub feature request issue to collect what people want - might turn out that v1 is all you need

On Mon, 13 Mar 2023 at 3:08 am Dominick @.***> wrote:

I presume the editor uses the file system to hold the files used to describe each part ?

yes and no. Right now the editor uses a filysystem but it was designed to be optional. I think that would be something that can be left to the JS side of the web compiler.

Now the question is how much leg work are you willing to put in vs have included in the web compiler version. Do you want the entire package with the UI and editor? Or is just a compiler interface enough?

— Reply to this email directly, view it on GitHub https://github.com/DSchroer/dslcad/issues/8#issuecomment-1465237535, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE2X46J7EEH3NQREROY2CLW3X7JLANCNFSM6AAAAAAUY6SNN4 . You are receiving this because you authored the thread.Message ID: @.***>

DSchroer commented 1 year ago

I'm hoping to be able to compile the full editor for demo purposes. Right now Bevy and dependencies are having trouble compiling with the wasm32-unknown-emscripten target. Until that gets resolved I don't think there will be much progress on this front.

gedw99 commented 1 year ago

will if it helps i am happy with it just as a library.

Maybe that makes the bevy wasm compilation easier at the moment ?

can then get fancy with FS and Editor later...

gedw99 commented 1 year ago

I presume the editor uses the file system to hold the files used to describe each part ?

yes and no. Right now the editor uses a filysystem but it was designed to be optional. I think that would be something that can be left to the JS side of the web compiler.

Now the question is how much leg work are you willing to put in vs have included in the web compiler version. Do you want the entire package with the UI and editor? Or is just a compiler interface enough?

@jpillora want the whole editor it seems which is great for demos on web.

I am happy to do the leg work on the File IO aspects. I can see how some want the files inside the Web, and others want it outside or even on a backend file system. People's use cases will determine what option of the 3 suits them. This is why a simple JS level API is good. Deno is a pretty good layer here because your can use typescript and run the Core 3D on web or backend and the File API is the same in both places.

https://deno.land/manual

I have used rust, bevy and deno to good effect.

think of deno as the glue together layer :)

DSchroer commented 1 year ago

Well for a start we need the program to build for web. If you run this right now you will get build errors from dependencies of Bevy. We can work to get those resolved.

export EMCC_CFLAGS="--no-entry"
cargo build --target wasm32-unknown-emscripten 
gedw99 commented 1 year ago

I know. Sorry was getting ahead of myself .

will try to get it going on wasm too

DSchroer commented 1 year ago

I think I am of the opinion that its best to keep everything together and have the editor fully compile for WASM. Now I went off on a tangent this weekend and tried a new way to get everything to work:

  1. Modify the dslcad crate to be a cdylib with c style exports
  2. Generate c bindings for the exports
  3. Generate rust bindings for the c bindings
  4. Modify the dslcad_app crate to use those FFI style bindings.

After some trial and error this ended up working but has some major drawbacks:

  1. Its hard to maintain
  2. Its unsafe
  3. Memory management of all those objects needs to be handled manually

I'm not sure I want to go this route due to all those major drawbacks. It would likely sacrifice development speed and flexibility too much.

gedw99 commented 1 year ago

Yep i know its extra work.. Would be happy to help if we use some tooling...

Did you use the following tools ?

https://github.com/rustwasm/wasm-bindgen

https://github.com/rust-lang/rust-bindgen

DSchroer commented 1 year ago

I used https://github.com/rust-lang/rust-bindgen and https://github.com/eqrion/cbindgen however that's really not where the work is. I would say don't bother with this approach. Focus on getting bevy to compile under wasm32-unknown-emscripten

gedw99 commented 1 year ago

@DSchroer

right - now we know the path forward. thanks for all this due diligence.

I will take a crack at it and watch for updates on the repo etc.

DSchroer commented 1 year ago

So I have made some progress on this. Might have the next step out soon. I did a mix of the approach that I described above:

  1. Created a RPC system that passes messages using serde and Vec<u8> between the two parts. This way the native code boundary is super small and manageable. This will be slightly slower but way easier to work with.
  2. Split the two parts using binding generation like I mentioned before
  3. Create a glue layer in JS to hook the two together.

This should work and will allow the editor and CAD system to work on the web.

DSchroer commented 1 year ago

Progress is being made

image

gedw99 commented 1 year ago

Wow great architecture solution. Way less pain than before .

can’t wait to try this out.

DSchroer commented 1 year ago

Im going to push what I have now but not make a release.

Workflow wise I don't have this figured out yet. Web + files doesn't work well. If someone wants to contribute and help build a simple text editor in the UI it would be appreciated.

Things work fine natively. Lots of tweaking needed for the WASM side of things. Mostly memory layout and such.

image

gedw99 commented 1 year ago

I will have a look when you commit

https://github.com/DSchroer/dslcad/blob/master/Dockerfile needs updating fro wasm / web build ?

About web and files. I assume its client / server, and the files stay on the server ?

I have only built text editor in golang and wasm with gioui. This is partly why i asked for the 3D screen to be a separate wasm. Cause then other languages that compile to wasm etc can be used with it.

DSchroer commented 1 year ago

@gedw99

needs updating fro wasm / web build ?

Yes. At the moment I just have the script ./scripts/wasm.sh that builds everything that you need. It puts all the files in the browser folder. Ill try to update the docker file soon.

I assume its client / server, and the files stay on the server?

Nope. No server involved. Its a 100% wasm, client side build. You setup a plain http server and point it to the browser folder. The page will load everything it needs. That way it can be hosted as a static site on things like Github Pages.

I have only built text editor in golang and wasm with gioui. This is partly why i asked for the 3D screen to be a separate wasm. Cause then other languages that compile to wasm etc can be used with it.

I don't think this is the best plan. Its really hard to make two WASM programs interoperate. If you wanted to make an editor in Go and use it, you would have to expose a C API and copy all the data in JavaScript. That means manually handling things like memeory allocation and de-allocation in both applications. In this case I recommend we build the editor directly in Rust in the program. I am using egui to build the editor UI so it should feel very similar to using gioui.

gedw99 commented 1 year ago

equi looks pretty good - I will have a go after you have docker building the wasm.

DSchroer commented 1 year ago

This is what I have now. So we have enough to make a MVP. image

gedw99 commented 1 year ago

You got me thinking ...

I built a client / server wasm thing a few months ago as an experiment in WASM authouriing.

As the server changes the files it pumps the new data up to the clients for them to render. it.

Its a unidirectional data flow :

You can also do exactly the same with a Service worker. It's replaces the server. The only change is the bus then.

You can then use tiered caching, with the Service Worker acting as an offline cache ( or in mem), and it updating its own data based on the Backend Server sending it data diffs too.

Then you can do collaboration..

I would like to take a crack at it sometime once things settle down.

DSchroer commented 1 year ago

That makes sense. Its already close to that architecture:

One thing I want to avoid is too much web only development. Lets try to make everything converge on a single UX, for all platforms. So before we dive too far in, the next step should be to make the feature set identical for all platforms as much as possible.

DSchroer commented 1 year ago

Also. You dont need docker to build the app. I would suggest just trying:

cargo run

It should build and run the app locally.

gedw99 commented 1 year ago

Thanks - will try tomorrow.

i have been running desktops and mobile in a webview. Sort of the old Cordova approach.

I found the drivers embedded in browsers can sometimes be better than native. It’s very much on a vase by case basis though I found.

we can try it out later and see…

DSchroer commented 1 year ago

So I have this enabled on CI now. You can download a pre-built version to test in the latest pre-release. https://github.com/DSchroer/dslcad/releases/tag/v0.0.3-pre.2 Just download and use the browser.zip file.

DSchroer commented 1 year ago

I'm going to close this thread as complete. There is more work to do but we can start tasking and implementing that work in new threads. That way we can track each need individually.

jpillora commented 1 year ago

Thanks for your work guys

as a final step, you could enable gh pages - either pointing at a different branch, or a subdirectory containing an ‘index.html’ and GH will host it for you for free

DSchroer commented 1 year ago

Done. You can find it in the Web Editor page in the docs.

https://dslcad.com/editor/

image