ole00 / PrusaSlicer

G-code generator for 3D printers (RepRap, Makerbot, Ultimaker etc.)
https://www.prusa3d.com/prusaslicer/
GNU Affero General Public License v3.0
0 stars 1 forks source link

Add export for other Anycubic SLA printers #1

Open ole00 opened 2 years ago

ole00 commented 2 years ago

Support for Anycubic Photon SLA export formats similar to .pwmx. It looks like the format for Anycubic SLA printers is quite similar, differences seem to be mainly the resolution of the LCD and size of the printing base.

properlypurple commented 2 years ago

I have a Photon Mono 4k. The specs are

Screenshot of settings from Anycubic's slicer

image

The test pwma file available on their site https://drive.google.com/file/d/1HX9YYRI6KGxk4ySAX1ZUHL4SQaXS-9EZ/view

Zipped version in case they take it down TEST(1).zip

ole00 commented 2 years ago

Thanks for the files and the information - it will be handy.

gudvinr commented 2 years ago

Photon Mono

TEST.pwmo from anycubic website and TEST.zip

ole00 commented 2 years ago

I have added support for both printers. The source code changes are in the following branch: sla_anyphoton_export

I have also made a Ubuntu 18.04 release if you do not want to build the whole slicer application from scratch. Check the github Releases section (https://github.com/ole00/PrusaSlicer/releases).

I could not verify the exported files myself as I do not have the printers, so test the files with caution.

properlypurple commented 2 years ago

I've been trying to build this for a bit, but haven't been able to(on Ubuntu 22.04 and Fedora 36. Mainly with the error that split is not a member of boost.

https://gist.githubusercontent.com/properlypurple/f4247b4d8ecb17a9688787b85a6a9750/raw/a7cc4a19ccb89b096d6290a6e3813b3f98a837c8/gistfile1.txt

The release build also doesn't work on newer systems. I'll probably set up a VM to test this,but maybe you can package that release in an appimage for people to test.

ole00 commented 2 years ago

Could you add this line: #include <boost/algorithm/string.hpp>

above this line: #include <boost/algorithm/string/replace.hpp> in /root/PrusaSlicer/src/libslic3r/Format/pwmx.cpp and rebuild? Thanks.

gudvinr commented 2 years ago

Could you add this line: #include <boost/algorithm/string.hpp>

above this line: #include <boost/algorithm/string/replace.hpp> in /root/PrusaSlicer/src/libslic3r/Format/pwmx.cpp and rebuild? Thanks.

Yes, that fixes build process.

But I have a question about SPEED parameters in material settings. Those are in mm/s as opposed to mm/min which is used by chitu and lichee, right?
I think it should be mentioned somewhere.

ole00 commented 2 years ago

Yes, that fixes build process.

Thanks for the confirmation.

Those are in mm/s as opposed to mm/min which is used by chitu and lichee, right

That's correct, they are in mm/s.

I think it should be mentioned somewhere.

Good point, I'll add them to the material notes as a comment.

Let me know whether you were able to export and print.

properlypurple commented 2 years ago

I've tried building this on Fedora 36, CentOS, Ubuntu 22.04, and Ubuntu 20.04 until now. The build fails with this for some reason

[ 96%] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/TCPConsole.cpp.o
In file included from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/smart_ptr/detail/sp_thread_sleep.hpp:22,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/smart_ptr/detail/yield_k.hpp:23,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp:14,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/smart_ptr/detail/spinlock.hpp:42,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/smart_ptr/detail/spinlock_pool.hpp:25,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/smart_ptr/shared_ptr.hpp:29,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/shared_ptr.hpp:17,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/date_time/time_clock.hpp:17,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/date_time/posix_time/posix_time_types.hpp:10,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/time_traits.hpp:23,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/detail/timer_queue_ptime.hpp:22,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/detail/deadline_timer_service.hpp:31,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/basic_waitable_timer.hpp:22,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/steady_timer.hpp:22,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/basic_socket_streambuf.hpp:36,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/basic_socket_iostream.hpp:24,
                 from /home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/asio/ip/tcp.hpp:20,
                 from /home/k/PrusaSlicer/src/slic3r/Utils/TCPConsole.cpp:3:
/home/k/PrusaSlicer/deps/build/destdir/usr/local/include/boost/bind.hpp:36:1: note: #pragma message: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated. Please use <boost/bind/bind.hpp> + using namespace boost::placeholders, or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior.
   36 | BOOST_PRAGMA_MESSAGE(
      | ^~~~~~~~~~~~~~~~~~~~
[ 96%] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/MKS.cpp.o
[ 96%] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/WinRegistry.cpp.o
[ 96%] Linking CXX static library liblibslic3r_gui.a
[ 96%] Built target libslic3r_gui
make: *** [Makefile:141: all] Error 2

Adding #define BOOST_BIND_GLOBAL_PLACEHOLDERS to src/slic3r/Utils/TCPConsole.cpp shows other errors about qhull not being found.

I'm building using the steps here https://github.com/prusa3d/PrusaSlicer/blob/master/doc/How%20to%20build%20-%20Linux%20et%20al.md

@ole00 Can you share what kind of build environment/OS do you have, so I can use the exact same to try and build this?

EDIT: I tried building with Ninja instead, and that gave me this

[124/184] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/TCPConsole.cpp.o
In file included from ../deps/build/destdir/usr/local/include/boost/smart_ptr/detail/sp_thread_sleep.hpp:22,
                 from ../deps/build/destdir/usr/local/include/boost/smart_ptr/detail/yield_k.hpp:23,
                 from ../deps/build/destdir/usr/local/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp:14,
                 from ../deps/build/destdir/usr/local/include/boost/smart_ptr/detail/spinlock.hpp:42,
                 from ../deps/build/destdir/usr/local/include/boost/smart_ptr/detail/spinlock_pool.hpp:25,
                 from ../deps/build/destdir/usr/local/include/boost/smart_ptr/shared_ptr.hpp:29,
                 from ../deps/build/destdir/usr/local/include/boost/shared_ptr.hpp:17,
                 from ../deps/build/destdir/usr/local/include/boost/date_time/time_clock.hpp:17,
                 from ../deps/build/destdir/usr/local/include/boost/date_time/posix_time/posix_time_types.hpp:10,
                 from ../deps/build/destdir/usr/local/include/boost/asio/time_traits.hpp:23,
                 from ../deps/build/destdir/usr/local/include/boost/asio/detail/timer_queue_ptime.hpp:22,
                 from ../deps/build/destdir/usr/local/include/boost/asio/detail/deadline_timer_service.hpp:31,
                 from ../deps/build/destdir/usr/local/include/boost/asio/basic_waitable_timer.hpp:22,
                 from ../deps/build/destdir/usr/local/include/boost/asio/steady_timer.hpp:22,
                 from ../deps/build/destdir/usr/local/include/boost/asio/basic_socket_streambuf.hpp:36,
                 from ../deps/build/destdir/usr/local/include/boost/asio/basic_socket_iostream.hpp:24,
                 from ../deps/build/destdir/usr/local/include/boost/asio/ip/tcp.hpp:20,
                 from ../src/slic3r/Utils/TCPConsole.cpp:3:
../deps/build/destdir/usr/local/include/boost/bind.hpp:36:1: note: #pragma message: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated. Please use <boost/bind/bind.hpp> + using namespace boost::placeholders, or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior.
   36 | BOOST_PRAGMA_MESSAGE(
      | ^~~~~~~~~~~~~~~~~~~~
[126/184] Linking CXX executable tests/libnest2d/libnest2d_tests
FAILED: tests/libnest2d/libnest2d_tests 
: && /usr/bin/c++  -fext-numeric-literals -Wall -Wno-reorder -O3 -DNDEBUG   tests/libnest2d/CMakeFiles/libnest2d_tests.dir/libnest2d_tests_main.cpp.o tests/libnest2d/CMakeFiles/libnest2d_tests.dir/printer_parts.cpp.o  -o tests/libnest2d/libnest2d_tests  ../deps/build/destdir/usr/local/lib/libtbb.a  src/libnest2d/liblibnest2d.a  src/libslic3r/liblibslic3r.a  src/libnest2d/liblibnest2d.a  src/libslic3r/liblibslic3r.a  ../deps/build/destdir/usr/local/lib/libnlopt.a  src/admesh/libadmesh.a  src/miniz/libminiz_static.a  ../deps/build/destdir/usr/local/lib/libboost_log.a  ../deps/build/destdir/usr/local/lib/libboost_filesystem.a  ../deps/build/destdir/usr/local/lib/libboost_thread.a  -lrt  ../deps/build/destdir/usr/local/lib/libboost_locale.a  ../deps/build/destdir/usr/local/lib/libboost_regex.a  ../deps/build/destdir/usr/local/lib/libboost_chrono.a  ../deps/build/destdir/usr/local/lib/libboost_atomic.a  ../deps/build/destdir/usr/local/lib/libboost_date_time.a  src/clipper/libclipper.a  src/boost/libnowide.a  ../deps/build/destdir/usr/local/lib/libexpat.a  src/glu-libtess/libglu-libtess.a  -lm  -lqhullcpp  -lqhullstatic_r  src/semver/libsemver.a  src/libslic3r/liblibslic3r_cgal.a  ../deps/build/destdir/usr/local/lib/libgmpxx.a  ../deps/build/destdir/usr/local/lib/libmpfr.a  ../deps/build/destdir/usr/local/lib/libgmp.a  ../deps/build/destdir/usr/local/lib/libpng.a  ../deps/build/destdir/usr/local/lib/libjpeg.a  src/qoi/libqoi.a  ../deps/build/destdir/usr/local/lib/libopenvdb.a  ../deps/build/destdir/usr/local/lib/libtbb.a  -ldl  ../deps/build/destdir/usr/local/lib/libboost_system.a  ../deps/build/destdir/usr/local/lib/libboost_iostreams.a  -lz  ../deps/build/destdir/usr/local/lib/libHalf-2_5.a  ../deps/build/destdir/usr/local/lib/libblosc.a  -pthread  /usr/lib/x86_64-linux-gnu/libz.so && :
/usr/bin/ld: cannot find -lqhullcpp
/usr/bin/ld: cannot find -lqhullstatic_r
collect2: error: ld returned 1 exit status
[129/184] Building CXX object src/slic3r/CMakeFiles/libslic3r_gui.dir/Utils/UndoRedo.cpp.o
ninja: build stopped: subcommand failed.
ole00 commented 2 years ago

It seems the solution is suggested in the pragma message:

...or define BOOST_BIND_GLOBAL_PLACEHOLDERS ...

The simplest thing how to achieve that is to open the "src/slic3r/Utils/TCPConsole.cpp" file and add:

#define BOOST_BIND_GLOBAL_PLACEHOLDERS 

at the very top of the file (before the #include <boost/....>

Other solutions are suggested here: https://stackoverflow.com/questions/53203970/why-boostbind-insists-pulling-boostplaceholders-into-global-namespace

My build environment is Ubuntu 18.04, but is is not a trivial build either, because Ubuntu 18.04 is relatively old and PrusaSlicer requires more recent versions of many libraries which I had to build from sources. I use cmake build like this: 1) clone the repo 2) cd PrusaSlicer 3) mkdir build && cd build 4) cmake .. If all required iibraries are found then cmake generator finishes OK and produces a makefile 5) make -j8 The above runs the makefile and produces PrusaSlicer executable in the src directory. I think you got nearly to the very end of the compilation by using cmake (96%) so the fix I described above might help you to finish the build.

properlypurple commented 2 years ago

I have tried that, but that leads to lqhullcpp not being found, unfortunately.

I'm going to try and do a non-static build later today, even though I don't want to pollute my /usr with randomly placed untracked files. I've only tried the static option that Prusa directly supports. I wish the Appimage build was documented, so I could set up a CI or something to build this automatically.

gudvinr commented 2 years ago

@properlypurple you can build binary inside docker or systemd container and copy output

ole00 commented 2 years ago

I don't want to pollute my /usr with randomly placed untracked files

Simple: do not build as a superuser and as long as /usr permissions do not let ordinary users/processes to write to its subdirectories (normally it is like that) it will not happen. Looking at your previous build log you posted it seems you did exactly that - build was run from inside /root directory - that indicates you were root. Also, there is no need to run "make install". You can run the newly built PrusaSlicer from the build directory without installation. I do that as well.

but that leads to lqhullcpp not being found, unfortunately.

can you send the error listing ? That might be a linking phase, not compilation, in such case you'd need another fix. You can possibly try to undo my commit related to qhull cmake: c11b224

properlypurple commented 2 years ago

Simple: do not build as a superuser and as long as /usr permissions do not let ordinary users/processes to write to its subdirectories (normally it is like that) it will not happen. Looking at your previous build log you posted it seems you did exactly that - build was run from inside /root directory - that indicates you were root. Also, there is no need to run "make install". You can run the newly built PrusaSlicer from the build directory without installation. I do that as well.

I'm actually trying to build with statically linked dependencies, so I can keep it all in one place. That particular build log was from a VM, where I didn't care about this.

You can possibly try to undo my commit related to qhull cmake: c11b224

Thank you for this. Reverting this commit fixes the issue, and I was able to build successfully.

The pwma files generated by the slicer open properly in Photon workshop, and I can see that the layers are okay. I'll try the files on the actual printer today, after that bottle of IPA is delivered.

gudvinr commented 2 years ago

@ole00 you do this in your pwm writer: h.antialiasing = 1;

Can you please add override so it is possible to disable or enable AA from slicer settings?

ole00 commented 2 years ago

I could do that, but I have no idea of side effects. If I turn this off - can the sliced images have antialised pixels or not? If turned off does the printer expect completely different image format? If the exporter would have to convert antialiased layer picture to non-aliased image, how it should trim the aliasing ? Also, what would be the benefit of turning it off? So far it seems to me if turned off the resolution of the layer image (and the print-out) drops 16x.

gudvinr commented 2 years ago

To compare difference from slicer perspective I think best bet is to compare output from other slicers like chitubox or photon workshop with AA turned on and off.

From practical standpoint disabled AA is important for running calibration prints so you know that you get results without any post processing.

ole00 commented 2 years ago

AA is important for running calibration prints

can you point to some information what are the calibration prints and how the antialiased images affect (positively / negatively) the calibration? Can you not use the calibration files specifically designed for your printer and supplied by the manufacturer (the R_E_R_F file)?

... get results without any post processing

I might be wrong, but there does not seem to be an option in PusaSlicer to produce non-antialiased layer images - therefore in order to convert an aliased image to non-aliased image I would introduce a some processing error which may possibly affect the calibrated print.

gudvinr commented 2 years ago

I might be wrong, but there does not seem to be an option in PusaSlicer to produce non-antialiased layer images

There is gamma_correction option.

#: src/libslic3r/PrintConfig.cpp:3234
msgid ""
"This will apply a gamma correction to the rasterized 2D polygons. A gamma "
"value of zero means thresholding with the threshold in the middle. This "
"behaviour eliminates antialiasing without losing holes in polygons."
msgstr ""
ole00 commented 2 years ago

So possibly I could use the "gamma_correction" value and if it is set to 0 I'd export the "h.antialiasing = 0".

ole00 commented 2 years ago

OK. I think I now understand your point. You probably think that Antialaiasing export flag causes the printer's firmware to smudge (post-process) the layer images even more they might already be (depending on the gamma_correction). If that's the case (and if the printer really does that) it would make sense to control that antialising export parameter independently of gamma_correction. I thought the antialiasing export parameter merely indicates the presence of semitransparent pixels in the exported file.

gudvinr commented 2 years ago

I probably found explanation about how their implementation works on reddit.

Apparently they apply different exposure settings using grayscale levels in a presence of this flag. I think it is possible to test pretty easily with single layer print using gradient stairs and just modify AA flag in output file without touching anything. Chances are, without AA you'll get solid exposure and different pattern in case of enabled AA.

ole00 commented 2 years ago

link: good find. They are giving the PWM exporter name a justice by doing antialiasing via PWM (pulse with modulation) :) I did not know the screen is really a binary monochrome. I thought it is at least grey-scale capable.

Stipple pattern: yes that should work, To inspect the results one would need a microscope. Preferably a USB one, not the direct optical one (eye damage via UV). Or maybe using a UV transfer/sensitive foil to expose the pattern first, then inspect the results from the foil.

gudvinr commented 2 years ago

It is not really needed if goal is to just see what is happening. I think it is possible to check just by using decent exposure value (so you can see difference) and put regular paper to block a big portion of UV. Regular glass blocks 80% of UV and most plastics non-transparent for UV too.

In any case it is possible to set a phone, start recording and just look away from a printer.

ole00 commented 2 years ago

Well, feel free to try it. I've made the source code changes. They are in the following branch: sla_anyphoton_export2 The ANTIALIASING parameter is now in the material notes. You may need to delete/update your ~/.config/PrusaSlicer-alpha/sla_material/.ini or manually add ANTIALIASING=0 to your existing material notes (the PrusaSlicer needs to be pulled from git and recompiled before trying that). If you delete the .config/PrusaSlicer directory then after starting PS the printer setup Wizard will run again and the material notes will contain the new antialising option.

gudvinr commented 2 years ago

image So gamma_correction indeed removes grayscale data from image.

Images for non-antialiased version look exactly the same but of course header contains Antialiasing 1.

Regarding relation between gamma and AA, I think it should be other way around. When you set ANTIALIASING=0 generated images should produce monochrome images with applied gamma_correction, e.g. you make pixels with value less than 0.5 black and otherwise white.

For example, compare images for gamma=0.5 (top) and gamma=1.0 (bottom). Some areas become darker and some become whiter. image

Those are different settings because essentially gamma_correction is a property of slicer (despite of it being in printer settings) because it changes produced images but antialiasing is a setting of machine itself.

However, one thing that I'd add is ability to set ANTIALIASING through printer notes with overriding them from material properties.
That way you can avoid material clutter and create 2 printer profiles instead.

It would be better to have proper configuration UI of course but what you did so far is great to get things going and I don't think that prusa guys will approve UI change for SLA without solid ground anyway.

ole00 commented 2 years ago

I would expect that 90% of user will not even know what antialiasing is and if they know they will leave it on the default values (both PS gamma and Exporter's Antialiasing values). For the rest - the expert users - both options are now available and can be independently set. So I think I'll leave it as it is now. I thought about putting ANTIALIASING parameter to the Printer notes instead, but decided against it because Printer notes are more critical for the correct export on the specific printer and if the user screws-up some of the values the exporter could produce incorrect type of the PWM* format. The Material notes are a safer place, even though not an ideal place.

I agree the best solution would be a dynamic menu system where either the printer or material setting are extended (using GUI widgets) based on the printer configuration. Such system would require more programming work and - as you mentioned - might not be accepted to PS mainline code anyway.

gudvinr commented 2 years ago

Okay. It makes it somewhat less convenient but I don't consider that a deal breaker.

What do you think about using gamma_correction to make binary images with ANTIALIASING=0 instead of grayscale ones though?

ole00 commented 2 years ago

I have no strong opinion on antialiasing and gamma. I have only used it once, the print-out was OK, did not see any degradation in print quality when AA was OFF and gamma was 0 (but I did not do identical print with AA on, so can't directly compare). I think AA can be useful on low resolution (low DPI) screens, but may have diminishing returns on high DPI printers. My opinion on the benefit of using such feature depends on what kind of pos-processing the printer does when the AA flag is on. If it keeps the layer image intact (no image post-processing) and just treats the AA pixels with "variable light intensity" (ie PWM), then that's OK by me. OTOH if it would try to 'smudge' or blur the image (which either has or has no AA pixels) to improve soft edges then I'd personally turn it off on my export files. But the actual behaviour depends on the printer maker, printer model and possibly also on firmware version. At the end of the day it is a similar question of which color you like more : red or blue - it's subjective and both options may have some benefits in certain cases.

gudvinr commented 2 years ago

But the actual behaviour depends on the printer maker, printer model and possibly also on firmware version.

True, but since we do anycubics here so I think we should only consider how our printers do this since there's nothing we can do about it. Also important thing here is that prusa has their own SLA and up until your PR it was the only printer supported so it is safe to assume that most things there tailored to their way of interpreting sliced images.

I don't think that having grayscale images in layer data with AA off seems like correct thing to do. It can be solved by using some custom gamma function but considering that resin is liquid and doesn't block all of the light, it will bleed through neighbor pixels anyway to some degree so this kind of fine tuning seems meaningless on a scale of 50 micrometers.

In that case why even bother doing stuff like this? Maybe it is better to ditch new parameter whatsoever as you suggested before because essentially you can do same thing with gamma_correction=0 and set antialiasing=0 in header for the sake of correctness.

ole00 commented 2 years ago

I don't know what the AA parameter currently does in the firmware - and even if I'd known, the future firmware releases might change the behaviour. Therefore this current solution (both parameters independent and settable) gives the most flexibility and control to the user (even though some combinations might not make sense on current firmware or printer model, but may make sense on other printer model or firmware version). I'll leave it as it is - the defaults are set to enable gamma and export with AA On. For regular user this should be good enough. For others: they are now free to experiment and tweak the values.

gudvinr commented 2 years ago

Okay, that's fine by me too. My printer is out of commission right now but I'll test some cases when I get it to work later and post it either here or in another issue maybe. We'll see how it goes.

In any case, thank you for this work.

ole00 commented 2 years ago

@properlypurple, @gudvinr: just wondering whether you were able to print things exported from the modified PrusaSlicer on your printer. If so, are you happy with the exported files / results or would you suggest some modifications? If you did not have time to test it properly, that's fine.

gudvinr commented 2 years ago

I wasn't able to run print with resin, however printer seems to recognize files and screen showing what it is supposed to show on initial layers.

I didn't test edge cases with AA that I described earlier though.

If it is possible to build windows version, I can ask some people to test.

gudvinr commented 1 year ago

With release of 2.5 do you think you can manage to send PR to include in 2.6 release, @ole00?

Maybe even split in 2: AA support and new format/printers support.

ole00 commented 1 year ago

I'd need to rebase the changes on top of the latest upstream commits. Hopefully if there would be no code conflicts I can submit the PR quite quickly. I was waiting on you (both of you) to give some feedback from real printing before I attempt to do a PR.