area515 / Photonic3D

Control software for resin 3D printers
http://photonic3d.com
GNU General Public License v3.0
132 stars 115 forks source link

Web Based Slicer Integration #139

Closed jmkao closed 7 years ago

jmkao commented 8 years ago

https://github.com/DanielJoyce/microtome is a browser based slicer with future roadmap for model layout and slice export (e.g. zip of pngs).

It seems to have a functional slicer now, but is only in the early stages of being a full build platform setup tool, but the fact that it's browser based makes it interesting in conjunction with what we can do for printer control.

WesGilster commented 8 years ago

I dropped him a message, about integrating into CWH via the JS control server.

I notice that he's using threejs as his 3d graphics engine... I've used that for simple model previewing, and it just dies under large models. I'm hoping he has something planned for that scalability. On the other hand, if he doesn't, there is no reason that his slicer can't perform well enough.

WesGilster commented 8 years ago

Let me know if you get his slicer up and running. I'm planning on putting together a "user friendly" feature release this weekend. After that I'll be getting back into a 3d modeling release and I don't want to waste any time in there if this has some potential.

jmkao commented 8 years ago

Ok, I'll spend some sustained time trying to assess this and see if this is anything that would be convenient to use.

jmkao commented 8 years ago

This repo doesn't seem ready for anyone other than the author to use yet, I think he's still in the middle of his dart to typescript migration and while the state of the tree is much better than what it was a few weeks ago, it doesn't quite run properly.

WesGilster commented 8 years ago

That's understandable, thanks for checking this out. It might still be a week before I'm ready to start the 3d stuff, so if he's made quite a bit of progress, I might delay this a bit longer.

jmkao commented 8 years ago

Not open source, but this might give us some ideas as to what is possible:

https://grid.space/

It's a browser based STL layout and FDM slicing tool that generates GCode. The way the STL layout works is pretty simple, but useful. Since you always want to snap the part to the bed, movements are just along the XY plane. It also has a great camera that, rather than zooming into the surface of the part, will take your point of view inside a part to visualize hollow areas, which is particularly useful for resin printing.

I was also able to throw some pretty gnarly STL files at it, like this 139MB model that was non-manifold and then badly "fixed" by makeprintable.com:

image

image

Which it rendered like a champ, although was unable to actually generate G-code for...

WesGilster commented 8 years ago

This is actually really promising. I have my "pet model" that I use for these tests and it loaded quickly and I can manipulate it very well. I did get it to lock up a couple of times, but I'm hoping that was a problem with their code and not the rendering engine. The most interesting facet is that they are using three.js rendering engine as well.

Three important points here:

  1. I believe I've prematurely ruled out three.js as a decent rendering engine.
  2. It looks like I can load stls without performing any smoothing algorithms for decreasing poly counts.
  3. It's time to start looking at building a simple 3d engine preview for the printables page(apparently I should have tried this long ago...)
jmkao commented 8 years ago

Formlabs released an open source WebGL based slicer:

http://formlabs.com/stories/open-source-dlp-slicer/ https://github.com/formlabs/hackathon-slicer

I haven't yet tried it out.

WesGilster commented 8 years ago

Well, that's pretty cool. A little humbling though cause I thought I built my slicer pretty quick. :) Plus, their's is also really fast.

Looks like this builds a file that you can upload directly into CWH... Then your org.area515.resinprinter.job.ZipImagesFileProcessor should work great from there...

I might look at some better ways of integrating this than a zip file though...

I keep wanting to get back to the 3d stuff, but I'm kindof glad I haven't until this area has settled down a bit.

jmkao commented 8 years ago

Yeah, off the top of my head we would probably validate that the XY resolution (both in overall screen pixels and pixels/mm) and the Z height are the same between the slicer and the printer settings. That's probably one of the most common errors in the Kudo3D toolchain, where you slice with CW but you print using a printer-specific modified projectlayer. People get the XY or Z settings wrong/different between the two and get distorted prints.

With the extra metadata visible with this slicer, or with more complex toolchains like Autodesk Spark, which I'm still hacking at on the side, we can prevent those sorts of problems.

kloknibor commented 8 years ago

When using chrome that software is great the only problem is this :

github

In IE it doesn't work at all and in firefox it crashes with larger models and freezes the whole browser... Still some work to do if we choose this way... But this interface looks like it will fit snugly in our interface ;)! Would be great!

kloknibor commented 8 years ago

try for example to upload this file in firefox: Squirrel.zip it will crash the browser but it will work in chrome...

jmkao commented 8 years ago

Well, the slicing uses WebGL, so it's stability probably relies upon the quality of the WebGL implementation.

jmkao commented 8 years ago

Hmm.. here's another more polished looking web based slicer that also appears to be quite fast:

https://github.com/lautr3k/SLAcer.js

The one remaining gap, which may not be able to be done at the STL slicer level, is to allow for build placement somewhere other than the dead center of the build plate. That might need to be done at the 2D level though, like some kind of "Edit Printable" tool that then helps the user setup an AffineTransform.

kloknibor commented 8 years ago

I was just about to post that one too! Slicing seems slow but the other parts work like a charm. There are transformation available ;)! But only rotate and scale :/ transform in location will be easy!

It'a released under MIT licence, so we can dow hat we want with it ;)! Probably it would be better to get some functions removed from this slicer and just retrieve that info from printer settinggs, I think it can be neat :)!

kloknibor commented 8 years ago

But will a raspberry pi take it... By the way, i'm gonna test an cloud aerver next week... I ain't satisfied with the speed of our site ;)

WesGilster commented 8 years ago

I really appreciate this research guys. I might hold off another week before I start working on this. I thought we were nearing the end of the research phase, but there are more ideas coming in...

I still have some questions about the best way to integrate the front end slicer. I really don't like the idea of pushing raster graphics from the client. Yes, I think we have enough bandwidth to deal with it, but it's such a waste. I was really hoping I could capture the vector version of the slices. Ultimately we have a few different integration theories:

  1. All clients are slaves of a the 3d slice process(or image display) occurring on the server.
  2. Some designated client(which is forced to be connected to the server for the duration of the print) is controlling the printer in real time by sending it slices.
  3. A client has performed a preslice operation on the integrated slicer and has built a sliced file of raster(wishfully vector with normals) and has uploaded the file for print.

No one is realistically considering 2 right? At this point I feel like 1 and 3 are the two options we want most. Implementing 3(with raster) is just a matter of making the gui "feel" more like our own gui and doesn't really have any technical challenges. Implementing 1 is a bit more challenging, but mostly just relies on the performance and stability of the implementation you guys feel is strongest. It would be great if I could get some opinions from you guys as to which of these implementation is the most stable and performant. You'll need to ignore https://grid.space/ since it's not open source. Also, you need to ignore the GUI as well since it will be pretty much gone.

@kloknibor since all of these slicers are client based, it's not really a question as to whether we have enough resources unless you are running from a mobile phone. Have you guys tried these slicers on Mobile. As to the Raspberry Pi question, I was kindof thinking that we had outgrown the first Raspberry Pi until we had that Repetier user that said it was working for him. As to the Raspberry Pi 2, we have plenty of room to grow even after slicing on the pi.

As you guys have already said the AffineTransforms can all be applied from a 2d standpoint, making that really simple. Although, keep in mind, the 2d AffineTransforms will not allow rotations against the z plane, those would need to be transported to server through further z plane transformation metadata.

jmkao commented 8 years ago

Z plane rotations are probably best done somewhere where there is a robust visualization UI anyway, so I think that's fine. The 2D affine transform, on the other hand, is very well suited to be done on the printer directly so that you could project a preview and precisely target your print at a specific location on your build setup. (I don't know how important this is for other printers, but the Kudo3D Titan 1 has two quirks that make positioning really important: the Acer 6510BD they use is only sharp in some parts of the image, so positioning the print in that spot produces better prints, and their build plate has a recess for a retaining bolt, so you often want to position a print so that it misses that bolt if printing something flat against the build plate).

Out of the 3 slicers, grid.space is both the fastest and most stable. However, as you say, it's not open source, so we can't host it. It does, however, generate vector output and he's working on adding layered filled SVG polygon output for DLP SLA (not a coincidence, I contacted the author and we had an interesting discussion over e-mail about the best format to export. He had the same conclusion as you, where he would prefer to output vectors than rasters.). Any integration here, however, would probably be at arm's length, involving transporting an SVG file.

I also don't like option 2. ChiliPeppr controls CNC machines this way, where you put a JSON server on your machine controller, and then your browser runs the JavaScript code hosted at the ChiliPeppr site and sends data to the JSON server in real time. It seems to work for them, but I find it pretty bizarre.

Between Matt Keeter's slicer and SLAcer.js, neither of them can handle my "dream print", a lattice-filled injection mold, but SLAcer.js can generate a few slices before crashing. SLAcer.js also seems to have a more active development team, and I think it's the better bet.

From the standpoint of expedience, I think option 3 might be the best to start with. Since we have calibration now, we can pre-populate almost all of the necessary parameters to the browser slicer based on the printer profile, and the user only needs to choose the layer height. I think having some browser based slicing would be a really strong differentiator for a "Photonic3D 1.0" release.

There might be a hybrid of options 1 and 3, where the client streams slices to Photonic3D, but we start printing as soon as there are 3 or 4 layers buffered. If the buffer becomes empty, then the print halts after the peel sequence until the next image arrives.

WesGilster commented 8 years ago

There might be a hybrid of options 1 and 3, where the client streams slices to Photonic3D, but we start printing as soon as there are 3 or 4 layers buffered. If the buffer becomes empty, then the print halts after the peel sequence until the next image arrives.

It seems like what you are describing is tiptoeing suspiciously close to option 2. I think that options 1 and 3 can work together quite a bit more. Assuming raster(which is quite a bit easier to implement) What if you uploaded the actual STL along with the slice images in your zip file. Then, when completely disassociated clients want to see the progress of the print, the stl is downloaded in the background and since they already know what slice count they are on, they just simply show the slice.

WesGilster commented 8 years ago

let me clarify "they just simply show the slice".

The print jobs screen simply performs a slice on the stl with the slice count that was given on the websocket.

jmkao commented 8 years ago

What I was more thinking about is that the advantage of browser based slicing is increased computational horsepower compared to the RPi (at least on most computers, not including mobile), but the disadvantage is that you can't incrementally render as you go along like you can when the RPi has the STL itself.

Additionally, STL slicing is algorithmically complex, thus we may want to centralize on a single location for the slicing engine based on where there is the broadest interest, sharing with other projects if necessary, in order to make sure that the engine is solid and has enough people working on it. In the current atmosphere, that attention seems to be in JavaScript based slicers, where there seems to be a lot of activity and additional developer interest we could tap into if we integrated with one of them.

My train of thought is then, how do we bring this two things together in a modular way that minimizes deep dependencies but maximizes the performance.

I hadn't been thinking as far ahead as to what browser slicing might be able to add to a multi-user or multi-browser experience. I've personally been fairly satisfied with the existing printing status page, so I hadn't thought about what that experience could be in a multi-browser environment if all browsers could be asked to render and slice.

kloknibor commented 8 years ago

Well in my opinion in a perfect scenario it would slice on the fly on the pi rather rhat client side , so option 1. This way the software makes the printer truly stand alone, but like stated it might have to less horsepower for a complex print... And all slicers I know of are indeed client side/javascript. If we choose that way, option 3, we will have make to show clearly how far the slicer process is going and that the user can't close the pc/browser untill done.

But I still like option 1 the most, this also opens better potential to like add a (touch)display to the printer and make it stand alone 100% but this will need a lot more work...

Maybe we can check complexity of the file, and if the pi can handle it slice it there and otherwise we return a pop-up to slice on client side? Is that really nuts to think?

WesGilster commented 8 years ago

I think I may have made a mistake by showing 1 and 3 opposing options. That really wasn't my intent. I guess what I'm trying to say is that all functionality is still on the table except for the "single lucky client drives the printer for the duration of the print." You could even put that model together rather easily, but it requires a brand new PrintFileProcessor that communicates with the client through a websocket. Certainly not hard, but I don't really understand it's purpose since it neuters the entire multi-user, multi-platform accessibility aspect of the web. I'm also not giving up on slice on the fly, because the overall goal of this project is to print any file(including stls), not just a zip of slices.

kloknibor commented 8 years ago

Hmm alright... One thing that bothers me are compex files...I made A pretty complex part with millions of triangles. CW crashes during print while it slices on the fly... Could it be possible to verify that prints will succeed with on the fly slicing?

jmkao commented 8 years ago

That's the downside of incremental slicing. You don't know whether or not a layer will have a problem until you get there. Even with "mature" slicers like CW or Asiga Stomp, when I slice on a PC I typically scan through the images in IrFanView to see if there are any wacky layers because any slicer would have problems with a non-manifold model, and most slicers have some failure conditions. I've even had problems on CAD generated STLs that I've then run through Netfabb Cloud, which should have eliminated any mesh problems, but somehow did not.

Unless you compute the slice, you can't know that it will have a problem. You can "guess" that there might be problems by looking for non-manifold geometry, but that won't help with cases where the slicer has problems.

kloknibor commented 8 years ago

Hmm yeah that's true, what might help is an automatix fix stl like materialise/miicraft software does. This will eliminate manifold errors if run properly... By the way the model That crashed CW sliced fine (but terrible slow) on SLAcer.js

jmkao commented 8 years ago

I've been interacting with Sebastien Mischler, the author of SLAcer.js, on the Google Plus OpenSLA group. He's gearing up to refactor and rebuild an SLAcer.js 2.0 that includes some of the layout features he has in a separate tool (https://onlfait.ch/Meshes.js/) and is taking feature requests.

I've opened lautr3k/SLAcer.js#10 to register some requests for REST API integration for print configuration and slice upload.

WesGilster commented 8 years ago

Fantastic. How close is Swagger-UI integration? Anything I can help on it? Once people know how easy it is to integrate with the backend, I think you could see a pretty push for new front ends...

jmkao commented 8 years ago

It's not much work, I should be able to close that item and the newstart fix this week.

WesGilster commented 8 years ago

I started looking at slicers again... I love slacer, but for my testing I use a pretty large 50mb stl file. It pretty much locks up(and crashes) every slicer we've mentioned except for: https://grid.space/ and http://formlabs.com/stories/open-source-dlp-slicer/

On formlabs slicer, Chrome even gets a little impatient and asks if I'd like to kill or wait for the script to finish. If I wait, it loads quite nicely.

My load process will happen silently in the background on a websocket thread, so I'm not too worried about a lockup, but the crashes are a concern. I'll see what I can do with Slacer first I suppose.

jmkao commented 8 years ago

What is the interface you're thinking of for the WebSocket based loader? This is the third project on the list for the interns (Flip and XY Translate are the first two, which both fall under AffineTransform).

WesGilster commented 8 years ago

So, I suppose I could support all functions through both WebSockets and a Restful interface, but that is a ton of maintenance. So what I've done is built a hybrid approach and drawn a line that is becoming pretty common now:

  1. If an event arises on the server, then push to all clients through a websocket. Sometimes a restful call by a single client will kick off a chain of events to all registered clients. In this case it's important to keep in mind that a client may receive their own websocket events.
  2. If an event arises on the client, then request an http restful call(no websockets). I'm hoping it's rare, but sometimes a WebSocket event doesn't have all of the information necessary to perform the event on the client and a subsequent restful call needs to be made as a result of the WebSocket event.

These aren't hard and fast rules, but it's made development with websockets surprising trivial which isn't always the case. The only thing keeping me from a full websocket implementation is that they aren't really easily consumable by mainstream web developers and frameworks yet.

The other thing I'll describe is the WebSocket Server implementation and the WebSocket Client implementation.

  1. WebSocketServer - Events are driven from the server through three major sources PrintJobs, Printers and the Host itself. Each of them are named something like: org.area515.resinprinter.notification.WebSocketXXXXXXNotifier. You'll notice that they have a handy @ServerEndpoint annotation at the top of the class that you can connect directly to any running PrintJob, Printer or the global Host. Most likely you'll simply be changing one of those classes unless you come up with a new way that the server might generate events(unlikely). However, if you did, you would simply register it in the register method of the notifier like this: container.addEndpoint(WebSocketPrinterNotifier.class); and then place it in the config.properties file like I recently did with: notify.org.area515.resinprinter.notification.PauseOnErrorNotifier=true
  2. WebSocketClient - Angular doesn't support websockets natively and that's a pretty big issue for a few reasons; two way binding, scope handling and websocket resource lifecycle handling. I've built a WebSocketClient implementation for Angular that solves these problems here: /photonic3d/resourcesnew/cwh/js/cwhsocket.js An example for how to connect a web socket connection to a printer might be attachToPrinter(printerName) in /photonic3d/resourcesnew/cwh/js/printerControls.js
WesGilster commented 8 years ago

Let me know if that is what you were looking for...

jmkao commented 8 years ago

Yeah, just looking to see what the easiest path is. Probably the shortest path to start will be to use the REST APIs to pull calibration info and then upload a zip of images.

WesGilster commented 8 years ago

Yeah I think so too. No service side changes necessary either.

WesGilster commented 7 years ago

Slacer has now been integrated into Photonic3d. Further integration requests can be opened as new features.