2791 Commits

Author SHA1 Message Date
Lukas Matena
4dae6cbf60 Merge branch 'master' into wipe_tower_improvements 2018-06-26 12:58:04 +02:00
Lukas Matena
e2126c2dd6 Dedicated objects are now not ignored 2018-06-22 14:03:34 +02:00
Lukas Matena
e622401599 Wipe tower bugfix - the tower was printed incorrectly when the rotation angle was close to 90 degrees 2018-06-21 14:05:07 +02:00
Vojtech Kral
7cf3922707 Http: Fix nowide fstream usage 2018-06-21 12:06:55 +02:00
Vojtech Kral
9ee10a8779 Octoprint: Fix unicode support 2018-06-21 10:44:29 +02:00
Vojtech Kral
1ba81655e2 Octoprint: Add a dialog for setting the filename/path
and a "print now" option
cf. #880, #245, #55, #87
2018-06-21 10:44:29 +02:00
Enrico Turri
a3a8333d20 Force update when changing selected printer using the GUI 2018-06-21 10:43:01 +02:00
Lukas Matena
6669357c81 Merge branch 'master' into wipe_tower_improvements 2018-06-21 10:41:01 +02:00
Enrico Turri
80e4155cbc Bed textures selection using config inheritance 2018-06-21 10:24:57 +02:00
Lukas Matena
bc5bd1b42b Assigning of wiping extrusions improved 2018-06-21 10:16:52 +02:00
Enrico Turri
b386f52acc Removed error dialog when texture file does not exist 2018-06-21 09:54:43 +02:00
Vojtech Kral
f8bbfad152 avrdude: Line noise prevention on MK3 xflash boot 2018-06-20 17:31:29 +02:00
Enrico Turri
cea5b97cad Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-06-20 14:34:46 +02:00
Enrico Turri
4803e7fc84 Fixed crash at startup on OpenGL 1.1 cards 2018-06-20 14:34:20 +02:00
Lukas Matena
8a47852be2 Refactoring of perimeters/infills wiping (ToolOrdering::WipingExtrusions now takes care of the agenda)
Squashed commit of the following:

commit 931eb2684103e8571b4a2e9804765fef268361c3
Author: Lukas Matena <lukasmatena@seznam.cz>
Date:   Wed Jun 20 12:50:27 2018 +0200

    ToolOrdering::WipingExtrusions now holds all information necessary for infill/perimeter wiping

commit cc8becfbdd771f7e279434c8bd6be147e4b321ee
Author: Lukas Matena <lukasmatena@seznam.cz>
Date:   Tue Jun 19 10:52:03 2018 +0200

    Wiping is now done as normal print would be (less extra code in process_layer)

commit 1b120754b0691cce46ee5e10f3840480c559ac1f
Author: Lukas Matena <lukasmatena@seznam.cz>
Date:   Fri Jun 15 15:55:15 2018 +0200

    Refactoring: ObjectByExtruder changed so that it is aware of the wiping extrusions

commit 1641e326bb5e0a0c69d6bfc6efa23153dc2e4543
Author: Lukas Matena <lukasmatena@seznam.cz>
Date:   Thu Jun 14 12:22:18 2018 +0200

    Refactoring: new class WipingExtrusion in ToolOrdering.hpp
2018-06-20 12:52:00 +02:00
YuSanka
86b02224ae Updated PL language 2018-06-20 09:42:14 +02:00
Vojtech Kral
725b8524f2 avrdude: Fix error handling in arduino, fix various outputs 2018-06-19 18:46:37 +02:00
Vojtech Kral
635bb1e484 Firmware updater: Add support for l10n firmware images 2018-06-19 18:46:37 +02:00
Vojtech Kral
15f943938b avrdude: add file offset to update operation spec, refactoring 2018-06-19 18:46:37 +02:00
bubnikv
7863412687 Firwmare updater for the Einsy external flash memory,
to be used as a storage for localization strings.

Hacked into the avrdude Arduino STK500 (not STK500v2) protocol.
2018-06-19 18:46:37 +02:00
Vojtech Kral
5414f7379d FirmwareDialog: Fix progress display 2018-06-19 18:46:37 +02:00
Vojtech Kral
2a07f3a0d5 Firmware updater: Fix filename encoding on Windows 2018-06-19 18:46:37 +02:00
Vojtech Kral
1602ddd56c avrdude: Reduce retries to make timeout time more reasonable 2018-06-19 18:46:37 +02:00
Vojtech Kral
478488972c Updating bugfixes (#973)
* ConfigWizard: Fix MM legacy profile detect

* Remove Perl BedShapeDialog

* PresetUpdater: Look for updates in resources as well

* ConfigWizard: Startup condition based on printer profiles only rather than all profiles
Previously wizard would not run if there was a leftover filament profile but no printer profiles

* ConfigWizard: Fix button labels

* ConfigWizard: Pick the very first printer variant by default
2018-06-19 18:26:38 +02:00
bubnikv
27faaa27f6 Merge remote-tracking branch 'remotes/origin/3mf_io' 2018-06-19 16:14:57 +02:00
bubnikv
7499a4dea4 Disabled the UI gizmos, they are not yet ready for the prime time 2018-06-19 16:14:10 +02:00
bubnikv
6fef5a07ab Merge remote-tracking branch 'remotes/origin/scene_manipulators'
Disabled the gizmos.
2018-06-19 16:12:36 +02:00
bubnikv
5a56f08aad Merge remote-tracking branch 'remotes/origin/opengl_to_cpp' 2018-06-19 16:08:53 +02:00
bubnikv
734273a33a Merge remote-tracking branch 'remotes/origin/fix_model_by_win10' 2018-06-19 10:02:49 +02:00
Enrico Turri
a3949b9f01 Object updated by scale gizmo 2018-06-18 15:07:17 +02:00
Enrico Turri
56ea84fef8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-18 15:06:04 +02:00
Vojtech Kral
5bf5213d67 Merge pull request #976 from kant/patch-1
Typo on string
2018-06-18 11:35:38 +02:00
Enrico Turri
53f8706805 Rotate gizmo interaction with mouse 2018-06-15 16:16:55 +02:00
Enrico Turri
6874949556 Scale gizmo interaction with mouse 2018-06-15 14:10:28 +02:00
Darío Hereñú
859e13ece5 Typo on string #20 2018-06-14 21:03:20 -03:00
Enrico Turri
52a7d7ed09 Partial perl code cleanup 2018-06-14 16:09:36 +02:00
Enrico Turri
c624d6bb0a Hover on gizmo grabbers rendering 2018-06-14 15:32:26 +02:00
Enrico Turri
4d405977dd Keep selection when panning/rotating 3D view 2018-06-14 12:34:19 +02:00
Enrico Turri
7fb6e2aa03 Use mipmaps for bed textures 2018-06-14 10:37:28 +02:00
Enrico Turri
bc5640eef4 Rotate gizmo rendering 2018-06-14 10:00:59 +02:00
Enrico Turri
3a19b81cef Scale gizmo rendering 2018-06-13 15:44:04 +02:00
Enrico Turri
099d59ad27 Selection on gizmo overlay 2018-06-13 13:14:17 +02:00
Lukas Matena
29dd305aaa Wiping into perimeters - bugfix (wrong order of perimeters and infills) 2018-06-13 11:48:43 +02:00
Enrico Turri
c657654c02 Hovering on gizmo overlay 2018-06-13 10:49:59 +02:00
Enrico Turri
6079fed951 Fixed compile on Linux 2018-06-13 09:26:58 +02:00
Enrico Turri
b2cf576bf3 1st installment of gizmos 2018-06-13 09:12:16 +02:00
Enrico Turri
2d97d8e7fe Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-13 08:31:30 +02:00
bubnikv
2cd0c64b96 Merge branch 'dev' 2018-06-12 17:11:45 +02:00
bubnikv
0ec06e6981 Fixed missing dependencies in Prusa's profiles for 0.25 and 0.6mm nozzles. 2018-06-12 17:10:12 +02:00
YuSanka
a4b42f44f3 Added translation for FR 2018-06-12 15:30:55 +02:00
Enrico Turri
0faaef76e8 C++ code cleanup 2018-06-12 12:18:16 +02:00
Enrico Turri
f8664fce71 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-12 11:55:57 +02:00
bubnikv
303ed0e6c9 Bumped up the version number to a final. 2018-06-12 11:53:09 +02:00
bubnikv
6cf508e124 Updated slic3r_min_version in prusa3d config version index. 2018-06-12 11:46:15 +02:00
Enrico Turri
756064810c Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-12 11:08:16 +02:00
YuSanka
b134fb8c39 Fixed typo bug 2018-06-12 11:01:14 +02:00
YuSanka
07815891dc Added translations for CZ, DE, ES, IT & PL 2018-06-12 09:55:39 +02:00
Enrico Turri
af3d07bb05 Attempt to workaround bug in wxWidgets IsShownOnScreen() method 2018-06-12 09:18:25 +02:00
Enrico Turri
5f02669d2d Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-12 08:32:34 +02:00
Vojtech Kral
a194d28b14 ConfigWizard: Use scrollbars on smaller screens 2018-06-11 18:52:18 +02:00
Vojtech Kral
7426291e9f PresetUpdater: Fix of the fix 2018-06-11 18:30:40 +02:00
Vojtech Kral
43e8fe32aa Add MK2.5 icon, remove testing icons 2018-06-11 18:24:41 +02:00
bubnikv
69705b5e66 Split the MK2.5 profile from the MK2S 2018-06-11 18:20:29 +02:00
Vojtech Kral
a54e587751 Fix: PresetUpdater: Set bundle & index file permissions #962 (#970) 2018-06-11 17:34:06 +02:00
bubnikv
7b6a0ba9ad Merge remote-tracking branch 'origin/ys_master_bug_fixes' 2018-06-11 16:58:46 +02:00
bubnikv
49cd06407a There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952.
The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely.
2018-06-11 16:56:35 +02:00
YuSanka
fba1bf7afc Fixed bug from issue #969 2018-06-11 16:23:10 +02:00
Enrico Turri
44220530cb Use a single gl context created in c++ 2018-06-11 15:49:04 +02:00
Enrico Turri
a02ea39525 GLCanvas3D volumes as a stack variable 2018-06-11 15:13:13 +02:00
Enrico Turri
085110c4d9 Removed 3DScene volumes from perl 2018-06-11 13:48:02 +02:00
Enrico Turri
efe6a29032 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-11 13:46:35 +02:00
Lukas Matena
dc9a46b269 Updated POT file (added PresetUpdater.cpp and FirmwareDialog.cpp, changed keys in WipeTowerDialog.cpp) 2018-06-11 13:44:40 +02:00
Enrico Turri
7b4870d1cb Fixed selection and rendering in object settings dialog 2018-06-11 11:40:11 +02:00
bubnikv
6cafc7f121 Fix of a regression issue, which was certainly in 1.34.0, probably
even longer. An infill / perimeter overlap was not applied
when defined with absolute coordinates.
Fixes https://github.com/prusa3d/Slic3r/issues/964
2018-06-11 10:59:02 +02:00
Enrico Turri
7b1187992c Added bed texture for Prusa printers 2018-06-11 10:46:32 +02:00
Enrico Turri
96d9879d72 class 3D on_select callback moved to c++ 2018-06-08 11:37:07 +02:00
Enrico Turri
bf2fd54578 reload_scene method of 3D class moved to c++ 2018-06-08 09:40:00 +02:00
Enrico Turri
f4a687703c Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-08 08:30:55 +02:00
bubnikv
95047c1953 Fixed typos from the previous commit. 2018-06-07 22:54:26 +02:00
bubnikv
2b5a1f3e60 Merge remote-tracking branch 'remotes/origin/vk-bugfixes' 2018-06-07 22:10:49 +02:00
bubnikv
7dfe2e2595 Fixed mangling of UTF characters when converted implicitely to
wxString on Windows through the + operator.
2018-06-07 22:10:23 +02:00
Lukas Matena
b6455b66bd Wiping into infill/objects - invalidation of the wipe tower, bugfixes 2018-06-07 16:19:57 +02:00
Enrico Turri
766d1d52a9 Fixed import of model rotated clockwise from 3mf 2018-06-07 16:13:32 +02:00
Vojtech Kral
aef0c489e3 Fix: Dialog initialization ordering on OS X
Perform update_check after MainFrame is created
2018-06-07 15:41:36 +02:00
Vojtech Kral
2e061994d4 Fix: GCodeSender: Line number resynchronisation 2018-06-07 15:41:34 +02:00
Enrico Turri
a8500d6bae class 3D callbacks moved to c++ 2018-06-07 11:18:28 +02:00
Enrico Turri
ff86407840 Key down and char event handlers of class 3D moved to c++ 2018-06-07 09:22:19 +02:00
Lukas Matena
73452fd79d More progress on 'wipe into dedicated object' feature (e.g. new value in object settings) 2018-06-06 18:24:42 +02:00
bubnikv
ce6a23ef3b Repair by the netfabb service: Implemented progress dialog and cancelation. 2018-06-06 15:19:06 +02:00
Enrico Turri
f6ef28becc Removed method update_bed_size from 3D perl class 2018-06-06 15:17:10 +02:00
Enrico Turri
66b4620d9b Fixed runtime error on Linux when removing canvases 2018-06-06 14:33:04 +02:00
Enrico Turri
8192580b5f Removed DestroyGL method from 3DScene 2018-06-06 14:19:28 +02:00
Enrico Turri
e79037c44d 3DScene member variables moved to c++ 2018-06-06 12:36:52 +02:00
Enrico Turri
2dee4d1a83 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-06 12:18:52 +02:00
Enrico Turri
b2b95d590f Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-06-06 12:17:16 +02:00
bubnikv
92875709e1 Fixed a bug reporting incorrect compatible_printers and
compatible_printers_condition inside the Config Bundle.
2018-06-06 12:01:11 +02:00
Enrico Turri
c6e44509e0 3DScene load_object method moved to c++ 2018-06-06 10:16:58 +02:00
Enrico Turri
40bb0b6f55 Fixed overflow in Polygon::area() 2018-06-05 16:07:09 +02:00
Enrico Turri
a8254e0053 Generation of preview paths moved to c++ 2018-06-05 14:09:36 +02:00
Lukas Matena
4830593cac Started to work on the 'wipe into dedicated object feature' 2018-06-05 12:50:34 +02:00
Enrico Turri
f262ec9094 Modified logic to finalize volumes geometry 2018-06-05 12:24:26 +02:00
Enrico Turri
5392008916 Generation of gcode paths moved to c++ 2018-06-05 10:56:55 +02:00
Enrico Turri
fe3f5471e7 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-06-05 10:54:25 +02:00
Enrico Turri
1f79713c15 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-05 10:54:15 +02:00
Enrico Turri
489bce5a18 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-06-05 10:53:20 +02:00
bubnikv
adcf869eee Fixed printer_variant fields for the i3 MK3 0.25 and 0.6mm nozzles. 2018-06-05 10:11:28 +02:00
bubnikv
d05d3cb652 Initial working implementation of the "Fix by Netfabb" function. 2018-06-04 21:22:42 +02:00
bubnikv
e65fac5e84 Added initial implementation of fixing 3MFs through the Netfabb
API provided through the Windows 10 Universal Windows Platform API.
2018-06-04 17:27:33 +02:00
bubnikv
1343a22dc6 Added Prusa profiles from https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/PrusaResearch 2018-06-04 15:58:44 +02:00
bubnikv
03518d2ff2 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-06-04 15:47:51 +02:00
bubnikv
03fea392d5 Merge remote-tracking branch 'remotes/origin/wipe_tower_gcode_preview' 2018-06-04 15:45:10 +02:00
Enrico Turri
d74b85f3fe Another set of 3DScene methods moved to c++ 2018-06-04 15:42:34 +02:00
Enrico Turri
9729c71691 Fixed opengl initialization on linux 2018-06-04 14:38:41 +02:00
Enrico Turri
af8e869880 3rd attempt to fix opengl initialization on linux 2018-06-04 14:28:59 +02:00
Enrico Turri
548f773074 2nd attempt to fix opengl initialization on linux 2018-06-04 13:52:57 +02:00
Enrico Turri
fa60917580 Fixed Linux compile 2018-06-04 13:18:04 +02:00
Enrico Turri
ac47ba5864 1st attempt to fix opengl initialization on linux 2018-06-04 13:15:28 +02:00
Enrico Turri
adca3035f9 Fixed Linux compile 2018-06-04 12:32:23 +02:00
Enrico Turri
676210d6f4 Fixed typo 2018-06-04 12:30:40 +02:00
Enrico Turri
95e7d96f52 3DScene paint event handler moved to c++ 2018-06-04 12:26:39 +02:00
Enrico Turri
34a944bd1c Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-06-04 12:25:14 +02:00
Enrico Turri
109dde00b2 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-04 12:25:04 +02:00
Enrico Turri
78c32bdf9a Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-06-04 12:24:14 +02:00
Lukas Matena
7c9d594ff6 Fixed behaviour of infill wiping for multiple copies of an object 2018-06-04 12:15:59 +02:00
YuSanka
16a5029d58 Fixed issue #875 and updated Slic3rPE.pot 2018-06-04 12:13:07 +02:00
Enrico Turri
8911cf6051 OpenGL info moved to c++ 2018-06-04 10:14:09 +02:00
Enrico Turri
ac3408a4ab Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-06-04 09:29:07 +02:00
Enrico Turri
7d56b38e40 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-06-04 09:28:55 +02:00
Enrico Turri
2e710289eb Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-06-04 09:28:05 +02:00
Enrico Turri
56f0c8fe93 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-06-04 09:25:12 +02:00
Enrico Turri
dab2652cb5 Fixed preference dialog behavior 2018-06-04 09:24:48 +02:00
Vojtech Kral
4df0b94b79 Beta bugfixes (#931)
* Fix: Function signature in avrdude

* Fix: Remove mockup vendor bundles

* Fix: Make ConfigWizard error handling more friendly

* Fix: Opening the datadir in AppImage-based Slic3r
2018-06-04 09:07:29 +02:00
Enrico Turri
364134515b Refactoring and cleanup 2018-06-01 15:54:41 +02:00
Lukas Matena
d6c444fefa Merge branch 'wipe_tower_improvements' of https://github.com/prusa3d/Slic3r into wipe_tower_improvements 2018-06-01 15:45:35 +02:00
Lukas Matena
bdaa1cbdfd Wiping into infill - no infills are now inadvertedly printed twice (hopefully) 2018-06-01 15:43:22 +02:00
Lukas Matena
a6c3acdf02 Wiping into infill - no infills are now inadvertedly printed twice (hopefully) 2018-06-01 15:38:49 +02:00
Enrico Turri
2bccb43122 Attempt to fix 3DScene key event on Linux 2018-06-01 09:18:10 +02:00
Enrico Turri
94d608c6c1 3DScene mouse event handler move to c++ completed 2018-06-01 09:00:30 +02:00
Lukas Matena
2d24bf5f73 Wipe into infill - copies of one object are properly processed 2018-05-31 16:21:10 +02:00
Enrico Turri
6bf009edee 3DScene mouse event handler partially moved to c++ - part 2 2018-05-31 16:04:59 +02:00
Enrico Turri
276533e236 3DScene mouse event handler partially moved to c++ 2018-05-31 13:51:50 +02:00
Enrico Turri
cf8e7475ca Removed unused methods from 3DScene 2018-05-31 08:44:39 +02:00
Enrico Turri
30a3b2179b 3DScene timer and _variable_layer_thickness_action method moved to c++ 2018-05-30 15:18:45 +02:00
Lukas Matena
8bdbe41505 Wiping into infill should respect infill_first setting, marking moved to separate function 2018-05-30 11:56:30 +02:00
Lukas Matena
db22b2f504 Bugfix: first color of the wipe tower preview was incorrect with some models 2018-05-30 11:02:00 +02:00
Enrico Turri
2f773a89df 3DScene set_viewport_from_scene method moved to c++ 2018-05-29 15:36:09 +02:00
Lukas Matena
b95a6f2626 Fix of previous commit 2018-05-29 15:29:20 +02:00
Enrico Turri
df14a3c399 3DScene update_volumes_colors_by_extruder method moved to c++ 2018-05-29 15:07:06 +02:00
Enrico Turri
5ee5465f94 3DScene mark_volumes_for_layer_height method moved to c++ 2018-05-29 14:34:45 +02:00
Enrico Turri
c3b1eca2c7 Fixed a crash 2018-05-29 14:09:02 +02:00
Enrico Turri
ece27ac6f8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-29 13:56:53 +02:00
Enrico Turri
5c745485e1 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-29 13:56:41 +02:00
Enrico Turri
38d0c964d8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-05-29 13:55:46 +02:00
Enrico Turri
363a964ebb 3DScene render method partially moved to c++ 2018-05-29 13:54:34 +02:00
Lukas Matena
cb5f5c65b0 Analyzer tags for the wipe tower also generate layer height and line width (so the priming lines+brim are visible and ramming lines are correct width) 2018-05-29 12:41:40 +02:00
Lukas Matena
549351bbb4 Analyzer tags for the wipe tower also generate layer height and line width (so the priming lines+brim are visible and ramming lines are correct width) 2018-05-29 12:32:04 +02:00
Lukas Matena
e4aff5b08a Feedrate on the first layer of the wipe tower properly set (bugfix) 2018-05-29 09:07:23 +02:00
Lukas Matena
c72ecb382d Reduction is now correctly calculated for each region, soluble filament excluded from infill wiping 2018-05-28 15:33:19 +02:00
Enrico Turri
db260a669c 3DScene mouse wheel event moved to c++ 2018-05-28 15:23:01 +02:00
Enrico Turri
aacdcd4add 3DScene layers editing mouse containment methods moved to c++ 2018-05-28 14:39:59 +02:00
Enrico Turri
994222c317 3DScene _first_selected_object_id_for_variable_layer_height_editing method moved to c++ 2018-05-28 14:10:02 +02:00
Enrico Turri
951e8528b4 3DScene layers editing parameters moved to c++ 2018-05-28 13:43:29 +02:00
Enrico Turri
d5268fdc97 Removed unneeded debug output 2018-05-28 13:04:01 +02:00
Enrico Turri
a8311bd1bd 3DScene layer_editing_allowed method moved to c++ 2018-05-25 16:28:24 +02:00
Lukas Matena
bfe4350a89 Calculation of wipe tower reduction corrected, new config option (wipe into infill) 2018-05-25 16:11:55 +02:00
Enrico Turri
c51ce63b9b 3DScene layer editing overlay completely moved to c++ 2018-05-25 15:56:14 +02:00
Enrico Turri
455076231b Layers editing shader moved to c++ 2018-05-25 14:05:08 +02:00
Enrico Turri
bdbc86167c 3DScene volume selection methods moved to c++ 2018-05-25 09:03:55 +02:00
Lukas Matena
132a67edb2 Wipe tower changes to reduce wiping volumes where appropriate 2018-05-24 17:24:37 +02:00
Enrico Turri
f121817501 Removed from Perl all 3DScene methods already moved to c++ 2018-05-24 16:11:34 +02:00
Enrico Turri
c2e38fc6fe Fixed compile on Linux 2018-05-24 15:22:53 +02:00
Enrico Turri
70664122af 3DScene layer height profile rendering moved to c++ 2018-05-24 15:17:01 +02:00
Lukas Matena
95795f249a First steps in reorganizing infill order (to use infill instead of the wipe tower) 2018-05-24 14:05:51 +02:00
Enrico Turri
f31c55ceed 3DScene layer editing overlay textures rendering moved to c++ 2018-05-24 13:46:17 +02:00
Enrico Turri
157a34bcd9 AMF I/O - Automatic detection if open file is zip archive or xml format 2018-05-24 09:57:12 +02:00
Lukas Matena
1d1c69f300 Merge branch 'master' into wipe_tower_improvements 2018-05-23 19:34:33 +02:00
Enrico Turri
751b41b94b 3DScene picking pass moved to c++ 2018-05-23 15:35:11 +02:00
Enrico Turri
6519b1dde8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-23 15:33:48 +02:00
Enrico Turri
486180c422 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-23 15:33:25 +02:00
YuSanka
a4261b11d4 Updated translations (de, fr, es, it & pl) 2018-05-23 14:22:52 +02:00
Enrico Turri
90c50b281a 3DScene mouse variables moved to c++ 2018-05-23 13:56:54 +02:00
bubnikv
a9499ae45c Fix of a crash intruduced with e8247c5646 2018-05-23 13:19:25 +02:00
Enrico Turri
91b9b8aebf Fixed wrong layer height texture updates when using multiple objects 2018-05-23 12:49:56 +02:00
Enrico Turri
b36243ba10 Objects rendering moved to c++ 2018-05-23 11:14:49 +02:00
Enrico Turri
b4beb7aae9 3DScene plain shader moved to c++ 2018-05-23 09:57:44 +02:00
Enrico Turri
c5c90620ca Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-23 08:38:40 +02:00
Enrico Turri
37ab7594fc Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-23 08:38:29 +02:00
bubnikv
076b293fec Bumped up version numbers of the PrusaResearch.ini and the Slic3r itself. 2018-05-22 15:18:38 +02:00
Enrico Turri
85b6784dcb Merge with master 2018-05-22 15:03:40 +02:00
Enrico Turri
e8ab724382 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-22 14:57:45 +02:00
Vojtech Kral
360b34944d ErrorDialog: Fix size and message encoding 2018-05-22 14:33:37 +02:00
bubnikv
306d77559e Merge remote-tracking branch 'remotes/origin/scene_manipulators' 2018-05-22 14:32:07 +02:00
bubnikv
e8247c5646 When loading a config bundle, make sure a config value is not accepted
if it is placed in a wrong group (for example, max_print_height
does not belong to print settings, but a printer settings, so Slic3r
will now complain about it being in print settings, and it will
remove the value from the print settings).
2018-05-22 14:17:27 +02:00
YuSanka
6ea81279ff Fixed correct updating of the modified preset on Plater tab. 2018-05-22 14:00:42 +02:00
Enrico Turri
ae394ca97d Fixed remember output directory default value set to true 2018-05-22 13:57:28 +02:00
Enrico Turri
507bd1a567 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-22 11:48:56 +02:00
Enrico Turri
4e29147756 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-22 11:48:45 +02:00
bubnikv
36b337b7e7 Moved max_print_height from [print:*common*] to [printer:*common*],
there is a bug still in Slic3r, it should refuse to load config keys
from a wrong location.
2018-05-22 11:45:15 +02:00
bubnikv
81fb408671 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-22 11:26:05 +02:00
bubnikv
eef1d500ec Merge remote-tracking branch 'remotes/origin/brim_width_calculation' 2018-05-22 11:08:37 +02:00
Eric
ca3ea125e2 Partial french translation (#914)
* partial french translation progress (45%)

* partial french translation progress (60%)
2018-05-22 11:01:05 +02:00
Lukas Matena
e2f44a231e A fix to use correct spacing with multiloop skirts 2018-05-22 10:50:38 +02:00
Enrico Turri
451c58d58f 3DScene's enable_picking variable moved to c++ 2018-05-22 09:02:42 +02:00
Enrico Turri
59af3fb866 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-22 08:33:23 +02:00
Enrico Turri
369d027544 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-22 08:30:30 +02:00
bubnikv
b694f1ac89 One day I will fix it! 2018-05-21 23:40:17 +02:00
bubnikv
512b6dfd88 Yet another fix of the previous commit. 2018-05-21 23:24:18 +02:00
bubnikv
6b4fe7975f Fix of the previous commit: When asking the operating system to open
the datadir using the platform specific file explorer, enquote
and escape the path.
2018-05-21 22:10:38 +02:00
bubnikv
7b4aeef40c Moved the "Flash firmware" menu to "Configuration",
removed the "Check for updates" from the "Configuration" menu,
added an "Open file explorer at the datadir" item to the Help menu.
2018-05-21 21:04:03 +02:00
Vojtech Kral
2fab254ff6 Merge branch 'fwupdater' 2018-05-21 19:12:40 +02:00
Vojtech Kral
5697754c5e avrdude: Fix exit hook not being adapted properly 2018-05-21 18:59:15 +02:00
Vojtech Kral
ee5a5df2a7 Serial port friendly name on Linux 2018-05-21 18:59:13 +02:00
bubnikv
3307dbc0fb Another fix for linux & osx 2018-05-21 18:58:22 +02:00
bubnikv
1e8a0b69b2 Yet another fix for OSX 2018-05-21 18:58:22 +02:00
bubnikv
0a328789ef Fixed compilation on Linux. 2018-05-21 18:58:22 +02:00
bubnikv
8917f18ef1 Fix of previous commit, fix of compilation on OSX. 2018-05-21 18:58:22 +02:00
bubnikv
d4e939fd04 Serial port fix, get description for serial ports on OSX. 2018-05-21 18:58:22 +02:00
bubnikv
33f21422e6 Added friendly names to serial ports, added automatic selection of Prusa's printers in the firmware updater dialog 2018-05-21 18:58:22 +02:00
Vojtech Kral
7f8265e2be FirmwareDialog: Fix log clearing 2018-05-21 18:58:22 +02:00
Vojtech Kral
a43e72f696 Firmware updater: rework cancelling 2018-05-21 18:58:22 +02:00
bubnikv
4f4649d046 avrdude: Fix serial I/O timeout on Windows 2018-05-21 18:58:22 +02:00
Vojtech Kral
4723a99b15 FirmwareDialog: Fix dialog sizing 2018-05-21 18:58:22 +02:00
Vojtech Kral
e1930d57f3 Firmware updater: Disable dictionary flashing menu entry for the time being 2018-05-21 18:58:22 +02:00
Vojtech Kral
fd00ea0ca7 Firmware updater: Add cancelation 2018-05-21 18:58:22 +02:00
Vojtech Kral
98ae20c3df Firmware updater: Perform work in a background thread 2018-05-21 18:58:22 +02:00
Vojtech Kral
a54672fb54 Firmware updater: Make the GUI less scary 2018-05-21 18:58:22 +02:00
Vojtech Kral
c5f1acfbfb FirmwareUpdater: Disable dialog close while flashing 2018-05-21 18:58:22 +02:00
Vojtech Kral
fe21ca5510 avrdude: Build fixes 2018-05-21 18:58:22 +02:00
Vojtech Kral
404fdbcfdf avrdude: Fixes in error handling 2018-05-21 18:58:22 +02:00
Vojtech Kral
97b3c38148 avrdude: Fix h_addr 2018-05-21 18:58:22 +02:00
Vojtech Kral
839c0451f7 avrdude: Fix PATH_MAX 2018-05-21 18:58:22 +02:00
Vojtech Kral
4ac17daad2 avrdude: Use C99, fix alloca include in stk500 2018-05-21 18:58:22 +02:00
Vojtech Kral
af360d7097 Firmware updater GUI 2018-05-21 18:58:22 +02:00
Vojtech Kral
3d09f2a980 avrdude: bugfixes 2018-05-21 18:58:22 +02:00
Vojtech Kral
07817c8ee5 avrdude: Compilation on Windows/MSVC 2018-05-21 18:58:22 +02:00
Vojtech Kral
68a570221b avrdude.conf: Remove unsupported stuff 2018-05-21 18:58:22 +02:00
Vojtech Kral
c7e4d1d06f avrdude.conf base 2018-05-21 18:58:22 +02:00
Vojtech Kral
53b42bf921 CMake: Fix C compiler warning about C++ flags 2018-05-21 18:58:22 +02:00
Vojtech Kral
11a00b025f avrdude integration basics (WIP) 2018-05-21 18:58:20 +02:00
Vojtech Kral
1caeab913b avrdude base 2018-05-21 18:55:03 +02:00
Enrico Turri
ae53c7cb2e Volumes rendering moved to c++ 2018-05-21 15:57:03 +02:00
Enrico Turri
0f035d0bae Background rendering moved to c++ 2018-05-21 15:24:52 +02:00
Enrico Turri
bf7b9eb3e7 Legend texture moved to c++ 2018-05-21 14:57:43 +02:00
Enrico Turri
3fdc5e20a7 Warning texture moved to c++ 2018-05-21 14:40:09 +02:00
YuSanka
c4478ccffa Fixed wrong updating of the options group tree 2018-05-21 14:36:09 +02:00
Enrico Turri
7cff6ef6db Shaders loaded from files 2018-05-21 13:08:02 +02:00
Enrico Turri
84a0712c05 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-21 13:06:25 +02:00
Enrico Turri
3fb96ff636 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-21 13:06:16 +02:00
YuSanka
64b905820d Fixed bugs with non-correct update of buttons enable.
Set minimum size for the scrolled_window_panel.
2018-05-21 12:34:31 +02:00
Enrico Turri
308a0b5709 Remember output directory default value set to true 2018-05-21 11:50:48 +02:00
Enrico Turri
3291cbfdad Fix of #889 2018-05-21 11:19:03 +02:00
Enrico Turri
67f7ec2d20 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-21 11:17:55 +02:00
Enrico Turri
ad5eab8fd7 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-21 11:17:45 +02:00
Enrico Turri
53ddf724e1 Fixed object setting dialog on NVIDIA cards 2018-05-21 10:51:47 +02:00
Enrico Turri
01b6bc1dc8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-21 08:38:05 +02:00
Enrico Turri
05dcda8ef7 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-21 08:37:53 +02:00
YuSanka
deabeaaa7f Aligned frequently changing parameters according to presets settings on the Plater tab.
Fixed missing adding of the Filaments preset settings(for multy material case) to the right_panel
2018-05-20 23:58:09 +02:00
Vojtech Kral
fd43e53aeb PresetUpdater: Add some more logging 2018-05-18 14:59:24 +02:00
Enrico Turri
a7fd1b6741 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-18 14:13:06 +02:00
Enrico Turri
effaef024d Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-18 14:12:44 +02:00
Enrico Turri
a7fc57a176 3DScene reset_object method moved to c++ 2018-05-18 14:08:59 +02:00
YuSanka
5e1e43f478 Resolved problem with Flickering.
Right column of the Plater is passed to own panel to be able be updated separately from whole Plater panel
2018-05-18 13:56:51 +02:00
Enrico Turri
5fc8fdee11 3DScene axes moved to c++ 2018-05-18 13:02:47 +02:00
Lukas Matena
99293011e6 Corrected brim generation (width), enabling continuity with skirt 2018-05-18 12:19:54 +02:00
Enrico Turri
1e0a8de5b1 3DScene cutting plane moved to c++ 2018-05-18 11:05:48 +02:00
Enrico Turri
0584990b65 Fixed z layers indices under 3D preview sliders 2018-05-18 10:14:47 +02:00
Enrico Turri
5224acad59 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-18 09:55:30 +02:00
Enrico Turri
6c6b8ccc42 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-18 09:55:21 +02:00
bubnikv
3f08ef70f1 Fix of extraneous infill over thin walls.
Fixes https://github.com/prusa3d/Slic3r/issues/670
and some of https://github.com/prusa3d/Slic3r/issues/895

PerimeterGenerator was using an unsafe clipper offset function,
which performed offset for both a contour and its holes together.
With this commit the offsets were replaced with their safe counterparts,
though these safe counterparts may be somehow slower
(performing offset on ExPolygon or ExPolygons, piece by piece).

Also there was a bug, where if the infill & gap fill consumed
everything of the polygon, a polygon one onion shell above was still
used for infill.
2018-05-18 09:52:09 +02:00
Enrico Turri
f34250ea6a Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-18 09:29:14 +02:00
Enrico Turri
255bec7432 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-18 09:29:05 +02:00
bubnikv
651c4ab0ae Fixed a typo in AppConfig 2018-05-18 08:46:33 +02:00
Enrico Turri
d56b543ff8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-18 08:32:19 +02:00
Enrico Turri
d85fd5501c Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-18 08:32:09 +02:00
bubnikv
19221b749c Fix of https://github.com/prusa3d/Slic3r/issues/869 2018-05-18 08:21:24 +02:00
Vojtech Kral
5fd2164612 ConfigWizard: Fix incorrent wizard run after a language change 2018-05-17 17:19:33 +02:00
Vojtech Kral
e783e00578 AppConfig: Remember previous Slic3r version 2018-05-17 16:19:58 +02:00
Enrico Turri
de0b8226e1 Tweaks to logic for sliders update in 3D Preview 2018-05-17 16:02:31 +02:00
Enrico Turri
f7702c05f2 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-17 15:22:55 +02:00
Enrico Turri
c9dc54bed7 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-17 15:20:25 +02:00
Enrico Turri
9b4afb77d1 Hide legend texture when invalidating gcode by editing config data 2018-05-17 15:18:52 +02:00
Enrico Turri
7ca9f46b9c Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-17 14:43:27 +02:00
Enrico Turri
f26bce2538 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-17 14:43:18 +02:00
bubnikv
37c498d6dc Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-17 14:09:08 +02:00
bubnikv
35bf4aee7d Fixed loading of configuraton values octoprint_host, support_material_threshold
They were incorrectly handled by the handle_legacy() function, which has been
ported from the upstream Slic3r without inspecting its content.
2018-05-17 14:08:50 +02:00
Vojtech Kral
96c7c4a58b PresetUpdater: Remove obsolete presets 2018-05-17 13:48:11 +02:00
Enrico Turri
2cb108fbf8 Fix in File menu 2018-05-17 12:56:14 +02:00
Enrico Turri
15f35a9e9e Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-17 12:12:27 +02:00
Enrico Turri
74b0ed4b23 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-17 12:12:18 +02:00
Lukas Matena
d98dec3a7c Merge branch 'gcode_preview_dropdown_ui' 2018-05-17 11:22:38 +02:00
bubnikv
c5dc47c647 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-17 10:30:24 +02:00
bubnikv
e3d84407e0 Fix of https://github.com/prusa3d/Slic3r/issues/896
Fixed a bug in parsering a Point from a config file.
2018-05-17 10:30:20 +02:00
Lukas Matena
6f792b7ffb Horrible workaround to make the gcode preview dropdown (show feature types) work on all platforms 2018-05-17 10:23:02 +02:00
Enrico Turri
24b5d61eb3 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-17 09:53:46 +02:00
Enrico Turri
4a4f4db6a5 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-17 09:53:36 +02:00
Enrico Turri
e13564cb19 Fixed shell visualization in g-code preview 2018-05-17 09:50:40 +02:00
Enrico Turri
ee4f95bce5 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-17 09:31:06 +02:00
Enrico Turri
36ce8e395e Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-17 09:30:55 +02:00
Enrico Turri
b6b7945830 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-05-17 09:27:16 +02:00
Enrico Turri
77578f4a3e Reset tooltips for manifold objects into object info panel 2018-05-17 09:26:50 +02:00
YuSanka
cc52654db3 Set minimum width for the right sizer 2018-05-17 08:50:05 +02:00
Enrico Turri
7a6d83e7eb Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-17 08:33:32 +02:00
Enrico Turri
853ebf6ad2 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-17 08:33:16 +02:00
bubnikv
e329f6f5f2 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-16 16:34:19 +02:00
bubnikv
687c91d6e9 Parsing of obsolete presets from Config Bundle to remove them
from user's profile when upgrading to a new configuration structure.
2018-05-16 16:34:07 +02:00
YuSanka
b8fe48c563 Modification of the AboutDialog to be correct showing on dark theme of Linux 2018-05-16 13:56:03 +02:00
bubnikv
6d98c2b1ce Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-16 12:16:53 +02:00
bubnikv
0b4a61a8ba Fix of https://github.com/prusa3d/Slic3r/issues/791
The preset names have to be set at the PlaceholderParser
before querying Print for a recommended file name.
2018-05-16 12:16:30 +02:00
Vojtech Kral
a97226ae54 PresetUpdater: Fix: Don't offer updates on legacy datadir 2018-05-16 10:15:05 +02:00
bubnikv
5c44453ced Fixed loading of configuration files after reverting to a snapshot
storing the old configuration format.
2018-05-16 10:11:00 +02:00
Enrico Turri
41c51d7614 3DScene's char event handler moved to c++ 2018-05-15 16:09:04 +02:00
Enrico Turri
2b4829a4b9 3DScene bed variables moved to c++ 2018-05-15 15:38:25 +02:00
bubnikv
4b87f71bbc Fix of the previous commmit. gcc and clang rightfully complained about a typo. 2018-05-15 14:20:32 +02:00
bubnikv
868b400120 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-15 14:04:49 +02:00
bubnikv
7645e9cb7a Added layer_num, layer_z variables to the end_gcode, end_filament_gcode,
added min(.,.), max(.,.) functions to the placeholder parser syntax.
2018-05-15 14:04:29 +02:00
Enrico Turri
c60bf694ef Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-15 12:22:44 +02:00
Enrico Turri
43784f3409 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-15 12:22:35 +02:00
Enrico Turri
a612b5b648 Replacement of xml escape characters when exporting to amf 2018-05-15 12:19:43 +02:00
Enrico Turri
f0d1888ca9 3DScene select_view() function moved to c++ 2018-05-15 11:30:11 +02:00
Lukas Matena
1f62978251 Merge branch 'master' into wipe_tower_improvements 2018-05-15 11:22:58 +02:00
Enrico Turri
75f1f832aa 3DScene bed origin moved to c++ 2018-05-15 11:07:32 +02:00
Enrico Turri
7519e34507 3DScene zoom functions moved to c++ 2018-05-15 10:32:38 +02:00
Enrico Turri
f4303ebdb8 1st attempt of perl callback from c++ for 3DScene 2018-05-15 09:50:01 +02:00
Enrico Turri
e31244e8a5 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-15 09:46:57 +02:00
Enrico Turri
328eba5610 Removed auto zoom to volumes when changing view 2018-05-15 09:41:58 +02:00
Enrico Turri
0155f4a7f7 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-15 08:41:59 +02:00
Enrico Turri
986630c2dc 3DScene's idle even handler moved to c++ 2018-05-14 14:47:13 +02:00
Enrico Turri
a12e3c1cc9 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-14 14:15:31 +02:00
Enrico Turri
0c1655b884 3DScene::Resize() method moved to c++ 2018-05-14 14:14:19 +02:00
YuSanka
3bc8d7517a Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-05-14 13:57:08 +02:00
YuSanka
b51197b52c Updated POT-file, added Spanish and Polish, fixed bug with Ctrl+U,O,L in Italian 2018-05-14 13:56:40 +02:00
Dan Kortschak
b07e16a3e7 Fix build failure (#884) 2018-05-14 13:44:33 +02:00
Enrico Turri
a73cb45792 Camera angle clamping moved to c++ 2018-05-14 12:08:23 +02:00
Enrico Turri
1fd59144c7 Camera data moved to c++ - WIP 2018-05-14 11:31:58 +02:00
Enrico Turri
32063cbe23 Merge branch 'master' of https://github.com/prusa3d/Slic3r into opengl_to_cpp 2018-05-14 10:02:28 +02:00
Enrico Turri
1edd2d01f0 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-14 10:01:27 +02:00
Enrico Turri
5fb81bacd5 Added layer index under sliders in 3D view 2018-05-14 09:54:38 +02:00
Enrico Turri
e90bc3fcab Fix in _3DScene::_load_gcode_extrusion_paths::Helper::path_color() 2018-05-14 09:00:19 +02:00
YuSanka
4cf74d6dcf Object information is pasted to the ScrolledWindow 2018-05-13 21:00:03 +02:00
Lukas Matena
b6db3767a2 Bugfix: extruder temperature only changes when the temperature differs from the one last set (wipe tower) 2018-05-11 17:35:42 +02:00
bubnikv
4a99fe6d84 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-11 16:03:18 +02:00
bubnikv
ae1a015494 Fixed Perl array addressing issues, leading to crashes when loading
additional objects at the 3D path preview window.
2018-05-11 16:03:07 +02:00
Lukas Matena
60121025e2 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-05-11 15:42:11 +02:00
Lukas Matena
613bcf8055 Updated PrusaResearch.ini with the latest version from Slic3r-settings repository 2018-05-11 15:41:26 +02:00
YuSanka
d53127fa44 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-11 14:42:19 +02:00
YuSanka
8c4c392cb8 Fixed enable/disable of the tooltips on GTK 2018-05-11 14:41:21 +02:00
Lukas Matena
03c6efe0d6 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-05-11 12:29:34 +02:00
Lukas Matena
d89f8128cd Fixed a GCode preview crash on Linux due to returning a reference to temporary (issue #872) 2018-05-11 12:28:31 +02:00
YuSanka
e91ebddeea Added possibility of select all TextCtrl context using Ctrl+A 2018-05-11 09:53:35 +02:00
bubnikv
0fc422544b Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-10 18:38:13 +02:00
bubnikv
d620961c34 Fixed the version number. We have an alpha state as of today. 2018-05-10 18:37:57 +02:00
Lukas Matena
9af6a89f20 Fixed a crash when loading multipart objects 2018-05-10 18:07:22 +02:00
Lukas Matena
5e231bf874 New wipe tower parameters added to INI file with profiles 2018-05-10 17:44:04 +02:00
YuSanka
98d9ce31de Corrected error message to last commit 2018-05-10 12:54:02 +02:00
YuSanka
754bfd926b Auto-correction of the input values according to the admissible range 2018-05-10 11:10:44 +02:00
Enrico Turri
5024fc4be7 OpenGL to c++ 1st installment - WIP 2018-05-09 10:47:04 +02:00
Enrico Turri
86155ae4c0 Fixed conflict in previous merge 2018-05-09 10:28:26 +02:00
Enrico Turri
bd4061c3b0 Merge with master branch 2018-05-09 10:16:28 +02:00
Enrico Turri
8eb9ddc2eb Max count of auto assigned extruders when splitting object set as dependent of current printer 2018-05-07 16:13:58 +02:00
Enrico Turri
c579ec7f5f Fixed wrong extrusion paths detection with multimaterial objects 2018-05-07 14:23:07 +02:00
Enrico Turri
ec8b8a6a98 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-04 12:01:14 +02:00
Enrico Turri
c488550636 Fixed update of 3D view when selecting objects on Linux 2018-05-04 11:57:37 +02:00
Enrico Turri
678cbd9d47 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-04 08:56:16 +02:00
bubnikv
19977edae2 Removed the "Broken croak" support, which was useful on broken
64bit Strawberry perl only. We don't use Strawberry perl anymore,
so this has been removed for clarity.

Added a PerlCallback wrapper to call a Perl subroutine from a C++ code.
2018-05-03 21:45:43 +02:00
bubnikv
81bfd8ce7e Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-05-03 21:35:10 +02:00
Enrico Turri
471f90659f Fixed typo preventing to build on Win 2018-05-03 16:28:41 +02:00
Enrico Turri
6d88d0d39b Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-03 16:13:22 +02:00
Enrico Turri
dd4669d1a0 Fixed crash when reducing objects from 2D/preview/layers tabs 2018-05-03 16:08:41 +02:00
YuSanka
af4e0308ae Fixed visibility of the contents of the GCode fields 2018-05-03 13:49:37 +02:00
Enrico Turri
717fbc1196 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-03 11:11:48 +02:00
Enrico Turri
d19b1162b3 Fixed normals on wipe tower box 2018-05-03 11:09:13 +02:00
YuSanka
20d9bda87e Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-05-03 09:22:10 +02:00
YuSanka
20b83c5b53 Save the Canonical Language Name instead of the Enumerator to the Slic3r.ini 2018-05-03 09:21:01 +02:00
Enrico Turri
97ea02d974 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-03 09:11:26 +02:00
Enrico Turri
a02bfdd2bc Initial zoom set to bed extent 2018-05-03 09:10:12 +02:00
Enrico Turri
e8d5c939b0 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-03 08:29:08 +02:00
Vojtech Kral
8ad6053544 PresetUpdater: More logging 2018-05-02 17:14:09 +02:00
YuSanka
4131a92cec Merge remote-tracking branch 'origin/master' into updating 2018-05-02 16:13:00 +02:00
YuSanka
16d5faac20 Preparations to the localization update & new Slic3rPE.pot 2018-05-02 16:06:35 +02:00
Enrico Turri
65f3b52cad Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-02 15:17:32 +02:00
Enrico Turri
cb486522a8 Fixed crash when pressing 'A' with empty print bed 2018-05-02 14:55:17 +02:00
Enrico Turri
81636abaa9 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-02 14:45:42 +02:00
Vojtech Kral
3deeda0f73 Merge pull request #859 from prusa3d/updating
Updating
2018-05-02 14:35:43 +02:00
Enrico Turri
e2e4310322 Removed unneeded scene reloads when selecting objects 2018-05-02 13:55:04 +02:00
Enrico Turri
65679975ce Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-05-02 13:50:46 +02:00
Vojtech Kral
9d9bcfe03f MSVC: Rename props file #857 2018-05-02 13:03:04 +02:00
Vojtech Kral
97a948fa52 Fix Perl path MSVC props file #857 2018-05-02 12:49:48 +02:00
Vojtech Kral
e9b83a20d0 ConfigWizard: Add additional logging 2018-05-02 12:44:53 +02:00
Lukas Matena
de0d1f34f3 Label in filament settings changed 2018-05-02 10:57:25 +02:00
Lukas Matena
b4e63d47cb Yet another attempt to fix the layer height profile validation 2018-05-02 10:56:06 +02:00
Lukas Matena
71b4337036 Label in filament settings changed 2018-05-02 10:52:17 +02:00
Vojtech Kral
4758b68e55 Fix: Turn two Preset & PresetUpdater exceptions into error logs 2018-05-01 11:20:44 +02:00
Vojtech Kral
28effac0f1 Fix bitmap loading in new dialogs 2018-05-01 10:35:30 +02:00
YuSanka
6d34db352d Merge branch 'updating' of https://github.com/prusa3d/Slic3r into updating 2018-04-30 16:30:23 +02:00
YuSanka
2d4cac0018 Added ability to change color of the labels of the system or modified values 2018-04-30 16:29:13 +02:00
Enrico Turri
3c13c4f103 Added versioning to 3mf file 2018-04-30 15:27:01 +02:00
Vojtech Kral
5624b8afd2 Add a new error dialog 2018-04-30 14:34:47 +02:00
Enrico Turri
4344eaebca Added versioning to amf file 2018-04-30 12:03:06 +02:00
YuSanka
dd10ccfcef Merge branch 'updating' of https://github.com/prusa3d/slic3r into updating 2018-04-30 11:12:41 +02:00
YuSanka
43d2027b76 ToolTips are showing on GTK 2018-04-30 11:11:48 +02:00
Enrico Turri
a208639ce7 Fixed initial view on Linux Ubuntu 2018-04-30 08:57:41 +02:00
Vojtech Kral
bb4c4d9ecf Legacy data update dialog: Add link to wiki 2018-04-27 15:45:04 +02:00
YuSanka
9fb8ee9377 Merge branch 'updating' of https://github.com/prusa3d/Slic3r into updating 2018-04-27 15:40:25 +02:00
YuSanka
879d22c7ca Added Freeze/Thaw and BusyCursor to selection_changed in object list (on Plater),
It fixes visible rendering on MSW
2018-04-27 15:39:00 +02:00
Vojtech Kral
285ded8bbb Add documentation for system profiles, snapshots & updating 2018-04-27 15:19:07 +02:00
Enrico Turri
b67064ef81 Keyboard capture by 3D view on Linux 2018-04-27 14:08:22 +02:00
Enrico Turri
ad54210c3e 3mf I/O - Added import/export of layer heights profile 2018-04-27 12:56:35 +02:00
Vojtech Kral
6d38943222 Fix & refactor legacy datadir dialog 2018-04-27 12:29:18 +02:00
Vojtech Kral
a3d5251b8e Merge branch 'cpp_ui_optimization' into updating 2018-04-27 12:04:43 +02:00
Enrico Turri
4811abfa99 Apply gradient to colors in GCode Preview 2018-04-27 09:54:21 +02:00
bubnikv
86e4c7b6ad Merge branch 'new_cooling_logic' into updating 2018-04-26 19:03:21 +02:00
bubnikv
7a8f68cfe6 Merge branch 'new_cooling_logic' 2018-04-26 19:00:49 +02:00
bubnikv
25d47c1da8 Fix of the new cooling logic. 2018-04-26 18:56:16 +02:00
YuSanka
19f8e0bc63 Changed background color in AboutDialog from wxWHITE to wxSYS_COLOUR_WINDOW,
AboutDialogLogo is replaced to wxStaticBitmap.
2018-04-26 17:46:24 +02:00
YuSanka
6467513f60 Set default bitmap (white_bullet) when creating Field's reset buttons 2018-04-26 16:33:37 +02:00
YuSanka
7698ba168e Merge branch 'updating' of https://github.com/prusa3d/Slic3r into updating 2018-04-26 15:11:48 +02:00
YuSanka
9548593b57 Forbid tabstop on resert buttons 2018-04-26 15:11:02 +02:00
Enrico Turri
a223655973 Inverted order of range items in legend texture 2018-04-26 13:40:29 +02:00
Enrico Turri
ad9dca2bd9 Fixed update of ranges for GCode paths colors selection 2018-04-26 13:03:54 +02:00
YuSanka
4d07b63b5a Merge remote-tracking branch 'origin/profile_changes_reset' into updating 2018-04-26 12:47:32 +02:00
YuSanka
b3859c49c1 Updated description preset line for each type of presets...
Disabled m_btn_delete_preset for default and system presets.
Enabled update of the current preset if it was modified and selected again.
2018-04-26 12:40:17 +02:00
Enrico Turri
a4df0bdcc3 Fixed division by zero in get_zoom_to_bounding_box_factor on Linux 2018-04-26 12:14:49 +02:00
Lukas Matena
24dc4c0f23 Yet another attempt to fix the layer height profile validation 2018-04-26 11:19:51 +02:00
Enrico Turri
fd16357b6e Increase z buffer range to avoid clipping while panning/rotating the 3D view 2018-04-26 11:03:15 +02:00
bubnikv
cbaf0ccc51 Refactored cooling logic for readibility and maintainability. 2018-04-25 22:54:52 +02:00
bubnikv
269770bbbc Fix of a new cooling logic. 2018-04-25 22:06:44 +02:00
Vojtech Kral
dce0aa6771 Updating: Start using proper URLs 2018-04-25 17:43:01 +02:00
Vojtech Kral
03e9da804a Update PrusaResearch bundle & index 2018-04-25 16:42:33 +02:00
Enrico Turri
166ee4c2c8 Export of print config enabled as default in save file dialog when exporting to amf and 3mf files 2018-04-25 15:31:37 +02:00
Vojtech Kral
f23f86d91c PresetUpdate: Fix UpdateConfig dialog 2018-04-25 15:21:38 +02:00
Enrico Turri
b7bcf27cde Merge branch 'updating' of https://github.com/prusa3d/Slic3r into updating 2018-04-25 15:16:45 +02:00
Enrico Turri
8096ef6844 Fixed wrong countours for multipart objects in cut dialog 3D view 2018-04-25 15:16:39 +02:00
Vojtech Kral
933c0eb650 Fixes in SemVer and MsgUpdateConfig 2018-04-25 15:14:01 +02:00
Enrico Turri
1a4827ba33 Fixed incorrect z values set into GCode Preview sliders 2018-04-25 14:38:44 +02:00
Vojtech Kral
bbc3c890ea Snapshots: Disable activation of incompatible snapshots 2018-04-25 14:00:29 +02:00
Enrico Turri
df3e84d580 Merge branch 'updating' of https://github.com/prusa3d/Slic3r into updating 2018-04-25 13:56:26 +02:00
Enrico Turri
e93391e0f8 Fixed get_zoom_to_bounding_box_factor on linux 2018-04-25 13:55:45 +02:00
YuSanka
91db0a6e05 Merge remote-tracking branch 'origin/profile_changes_reset' into updating 2018-04-25 13:53:22 +02:00
Vojtech Kral
eeb436931b Merge branch 'master' into updating 2018-04-25 11:57:56 +02:00
YuSanka
cfac6c0ebb Aligned printer settings on Plater tab 2018-04-25 11:10:34 +02:00
Enrico Turri
449aff0f62 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-04-25 11:01:32 +02:00
Enrico Turri
3cd7987af4 Fixed layer heights profile invalidated when loading model from amf file 2018-04-25 10:59:06 +02:00
bubnikv
6c627be4c1 New cooling logic to equalize extrusion velocity. The old behavior caused bad outer surface print quality on Prusa i3 MK3 2018-04-25 10:37:31 +02:00
Vojtech Kral
0feb4d823f PresetUpdater: Fix string type 2018-04-25 10:17:43 +02:00
Vojtech Kral
60f62a6463 Fix text in UpdateDialogs 2018-04-24 18:29:36 +02:00
Vojtech Kral
62d67d35ec Merge branch 'profile_changes_reset' into updating 2018-04-24 18:15:23 +02:00
Vojtech Kral
a50bde4267 Merge branch 'master' into updating 2018-04-24 18:11:34 +02:00
Vojtech Kral
fea5603409 PresetUpdater: Bundle incompatibility / Slic3r downgrade scnario 2018-04-24 18:06:42 +02:00
Enrico Turri
ccd1c01d0b Fixed automatic view type selection when changing printer 2018-04-24 14:21:31 +02:00
YuSanka
7c7c37a4f4 Added tooltips for reset buttons near each option 2018-04-24 14:11:23 +02:00
Lukas Matena
650489dd8a New parameters actually connected to the wipe tower generator 2018-04-24 13:43:39 +02:00
Lukas Matena
ec2d37451b Merge branch 'master' into wipe_tower_improvements 2018-04-24 13:10:33 +02:00
Lukas Matena
8c77b9645c Loading, unloading and cooling reworked, new filament parameters regarding cooling were added 2018-04-24 13:02:08 +02:00
YuSanka
92b67fb62e Change reset buttons tooltips according to its state 2018-04-24 12:12:15 +02:00
YuSanka
1e8d302fd4 Fixed wrong updating of "Top/Bottom fill pattern" 2018-04-24 10:33:11 +02:00
Enrico Turri
71d9500b2e More robust fix for 3D view and GUI buttons not in synch when object's size is almost identical to print volume's size 2018-04-24 09:00:33 +02:00
YuSanka
e31f5fc4b6 Modified text for tooltips and ButtonsDescription 2018-04-24 08:49:37 +02:00
YuSanka
b0841f78f4 Experiment failed 2018-04-23 15:39:55 +02:00
Enrico Turri
973060c728 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-04-23 15:34:56 +02:00
Enrico Turri
a3c3eb5d2a Fixed GCode Preview not invalidated when deleting an object 2018-04-23 15:30:41 +02:00
YuSanka
6432ec8a9b Experiment with extruders count change 2018-04-23 15:09:01 +02:00
Enrico Turri
cd3be74e3b Workaround for 3D view and GUI buttons not in synch when object's size is almost identical to print volume's size 2018-04-23 15:03:38 +02:00
Vojtech Kral
a7a8030fea PresetUpdater: Don't install updates that are already present in a snapshot 2018-04-23 13:58:50 +02:00
YuSanka
ec7e10e068 Fixed wrong behavior of options group Tree after extruders count change 2018-04-23 11:52:03 +02:00
Vojtech Kral
33c0d1dca3 PresetUpdater: Add/fix logging, comments 2018-04-23 11:16:47 +02:00
YuSanka
9a1dbfa6cf Updated action_undo.png icon and added sys_unlock_grey.png & action_undo_grey.png for dark themes of OS 2018-04-23 10:27:42 +02:00
Enrico Turri
f8b1dc5506 Tweaks to zooming logic 2018-04-23 08:44:24 +02:00
YuSanka
b8cb936973 Added effective update of ComboBoxes on Plater 2018-04-20 17:32:08 +02:00
YuSanka
27f77c7680 Added little more information to ButtonsDescription dialog 2018-04-20 15:40:43 +02:00
YuSanka
48bbd2d22a Added new files to MackList 2018-04-20 15:02:54 +02:00
Vojtech Kral
e0421a3ba6 PresetUpdater: Don't display new Slic3r version notifications multiple times for the same version 2018-04-20 14:53:11 +02:00
YuSanka
669b0b68ab Added missed files to commit 2018-04-20 13:27:25 +02:00
YuSanka
1e1bf03f61 Added reset buttons description 2018-04-20 12:58:07 +02:00
Vojtech Kral
134a083662 Merge branch 'config_snapshots' into updating 2018-04-20 11:08:23 +02:00
Vojtech Kral
93a902a757 PresetUpdater: Fix double free from Perl 2018-04-20 11:06:12 +02:00
Vojtech Kral
9b5480b7ba PresetUpdater: Use PID in cache tmp filenames 2018-04-20 11:05:00 +02:00
bubnikv
ab397e5ce1 Added SnapshotDB::snapshot_with_vendor_preset() utility function
to find out whether there has ever been a snapshot taken with a given
configuration version.

Implemented an "on snapshot" flag, which indicates, whether the current
state equals to some snapshot. If so, a new snapshot is not taken
in upgrade / downgrade case.
2018-04-20 10:26:23 +02:00
Vojtech Kral
2e61420747 Sync index file 2018-04-19 18:31:14 +02:00
Vojtech Kral
d671e06c32 Fix alpha legacy dir detection, Fix SemVer value ctor 2018-04-19 18:29:19 +02:00
Vojtech Kral
bdaf1b01be ConfigWizard: Fix reset checkbox 2018-04-19 16:49:22 +02:00
YuSanka
88dadcec78 Added tooltips for reverse buttons
* Corrected default size of undo buttons for GTK
* Experiment with rich tooltips
2018-04-19 16:20:30 +02:00
Enrico Turri
ad4cd05850 Fixed hovering while panning/rotating camera 2018-04-19 13:31:50 +02:00
YuSanka
7083f58326 Added lock icons to system presets in ComboBoxes.
Added right event handling if informative string is selected in ComboBoxes
2018-04-19 12:08:59 +02:00
bubnikv
d1580f67df Fix of the previous commit. Once the Slic3r::GUI::Tab was rewritten
from Ref<TabIface> to TabIface*, Perl takes ownership and the Tab is
being incorrectly deleted by the background threads.
2018-04-18 18:57:34 +02:00
Vojtech Kral
c3c9ebdd12 Fix wxPerl warning annoyance 2018-04-18 18:48:32 +02:00
bubnikv
8ab62d702c Fixed memory leak of TabIface.
Added documentation of the XS interface on how the Ref<> and Clone<>
wrappers work.
2018-04-18 18:06:07 +02:00
YuSanka
f38f0edaaf Cleaned code from commented code 2018-04-18 14:15:13 +02:00
bubnikv
fa97a86751 Implemented merging of system profiles from various vendors. 2018-04-18 13:35:51 +02:00
YuSanka
3ca2dfbc1d Added some performance changes 2018-04-18 13:32:21 +02:00
Vojtech Kral
0711f84ea0 Add version check & preset update options to Preferences 2018-04-18 12:33:07 +02:00
Vojtech Kral
81c6ad3ab7 ConfigWizard: Add reset option, fixes
Fix mock vendors
2018-04-18 11:40:43 +02:00
Enrico Turri
c9e4c831c2 Axes with fixed size in 3D previews 2018-04-18 10:17:22 +02:00
Enrico Turri
2ef164eeef Fixed cut contours in cut dialog 3D view 2018-04-18 09:44:49 +02:00
Vojtech Kral
c884f3b213 Display app update notification with the main frame 2018-04-17 17:11:56 +02:00
Vojtech Kral
df03b8e4e8 PresetUpdater: Notify about Slic3r updates 2018-04-17 16:59:53 +02:00
Enrico Turri
61ee633cd2 Fixed color specular component in shaders 2018-04-17 16:16:25 +02:00
Enrico Turri
3bedcf4413 Tweaks in generation of rendering geometry for preview toolpaths. Fixes #240 and #348 2018-04-17 15:04:14 +02:00
Vojtech Kral
6286c9ee7c ConfigWizard & updating: Fixes & cleanups 2018-04-17 11:54:59 +02:00
bubnikv
5e6cc5ddcb Updated max_print_height of PrusaResearch.ini 2018-04-17 11:06:15 +02:00
bubnikv
98785e47b1 Removed the
"The Wipe Tower currently supports only:\n"
"- first layer height 0.2mm\n"
"- layer height from 0.15mm to 0.35mm\n"
message as the new wipe tower is more generic.
2018-04-17 10:55:58 +02:00
bubnikv
a05c440263 Fixed potential crashes due to the Perl worker thread releasing
memory allocated by the GUI thread.
2018-04-17 10:55:18 +02:00
bubnikv
3b0eb6b786 Merge remote-tracking branch 'origin/updating' into cpp_ui_optimization 2018-04-17 10:38:02 +02:00
Vojtech Kral
b506aa11fa PresetUpdater: Fix: Compare versions when installing indices 2018-04-17 10:28:32 +02:00
YuSanka
d254c39a77 Added "smart" setting of label color 2018-04-17 10:15:48 +02:00
Lukas Matena
d7dc04eb57 Removed parameter filament_cooling_time (fixed value of 14s for now) 2018-04-17 08:18:12 +02:00
Vojtech Kral
37cf839b27 ConfigWizard: Fix regression 2018-04-16 18:33:33 +02:00
Vojtech Kral
d26c8e5336 Fix: Avoid the infamous major & minor macros on GCC 2018-04-16 17:43:23 +02:00
Vojtech Kral
214ad2925b Merge branch 'master' into updating 2018-04-16 17:32:58 +02:00
Vojtech Kral
7710b541da Merge branch 'config_snapshots' into updating 2018-04-16 17:00:31 +02:00
Vojtech Kral
c733e3151b Updating: Detect legacy datadir, remove conflicting presets 2018-04-16 16:55:24 +02:00
YuSanka
6e870e8466 Merge remote-tracking branch 'origin/cpp_ui_optimization' into profile_changes_reset 2018-04-16 14:30:10 +02:00
Lukas Matena
a154fd34ee Added parameter extra_loading_move, prevented high feedrate moves during loading 2018-04-16 14:26:57 +02:00
YuSanka
5d39126989 Changes to performance. 2018-04-16 13:43:01 +02:00
Lukas Matena
2726267748 Bugfix: validation of equal layering rejected even some valid configurations 2018-04-16 11:47:35 +02:00
bubnikv
c18b28e27c Implemented caching of often rendered bitmaps on the Tab UI. 2018-04-16 11:03:08 +02:00
bubnikv
b881ae936f Updated preset from Jindra. 2018-04-13 18:36:52 +02:00
bubnikv
eb58e29245 Merge remote-tracking branch 'origin/profile_changes_reset' 2018-04-13 18:31:19 +02:00
YuSanka
215c2082d3 Decorated "bed_shape" and "compatible_printers" labels 2018-04-13 18:22:06 +02:00
bubnikv
5d363c1bb9 Removed printf debugging output 2018-04-13 17:25:36 +02:00
bubnikv
913cdef297 Merge remote-tracking branch 'origin/scene_manipulators' 2018-04-13 16:54:22 +02:00
bubnikv
56f19f01dd Merge remote-tracking branch 'origin/3mf_io' 2018-04-13 16:50:33 +02:00
bubnikv
b79692c35e Merge remote-tracking branch 'remotes/origin/wipe_tower_improvements' 2018-04-13 16:43:35 +02:00
bubnikv
c5af8bfe78 Merged with Vojtech's branch 2018-04-13 16:19:27 +02:00
bubnikv
6d25ed2b00 Version's compatibility with Slic3r extended with pre-release
compatibility check:
A release Slic3r is not compatible with alpha and beta configs,
a beta Slic3r is not compatible with alpha configs, but is compatible
with beta configs etc.
2018-04-13 16:15:30 +02:00
Vojtech Kral
7dbb2ed6a3 Configuration updates downloading 2018-04-13 15:24:55 +02:00
bubnikv
82890ec815 Removed some obsolete Perl binding.
Added Version Index "version" method.
Implemented automatic selection of default_print_profile and
default_filament_profile, when the print / filament profiles are
not compatible with the selected printer profile.
Fixed selection of a printer profile, if the currently selected
printer profile becomes invisible.
2018-04-13 14:49:33 +02:00
Enrico Turri
659eb3412b Fixed value of z in cut dialog when object is scaled 2018-04-13 14:40:42 +02:00
Enrico Turri
359e7e4d32 Scale down meshes of too big objects after loading them 2018-04-13 13:59:36 +02:00
Lukas Matena
68c3749696 Gyroid infill - automatic discretization steps and refactoring 2018-04-13 13:46:31 +02:00
Lukas Matena
abe6e8a783 Bugfix: legacy config options were not properly processed 2018-04-13 13:43:53 +02:00
YuSanka
64976c249d Added @bubnikv's changes to BitmapCache 2018-04-13 12:49:12 +02:00
YuSanka
120c1978ae Cleaned code 2018-04-13 12:35:04 +02:00
Enrico Turri
7b29ecb15c Fixed cutting plane z in 3D view when object is scaled 2018-04-13 12:15:43 +02:00
Vojtech Kral
b49b59cbb2 Configuration update application at startup 2018-04-13 11:04:39 +02:00
Enrico Turri
acd8d2df98 Fixed layer height profile editing for multipart objects 2018-04-13 09:01:48 +02:00
YuSanka
d82505984a Rollback changes in BitmapCache 2018-04-12 16:46:17 +02:00
Lukas Matena
52a3f4a2bb Default purging volumes set to more appropriate values 2018-04-12 16:13:59 +02:00
YuSanka
3bc7580e8c Merge remote-tracking branch 'origin/master' into profile_changes_reset 2018-04-12 15:58:46 +02:00
Lukas Matena
adbaa42b2b Bugfix: cooling tubes parameters change invalidates generated wipe tower 2018-04-12 15:38:05 +02:00
Enrico Turri
a3fc49ee76 Fixed hovering not shown on out of print bed objects 2018-04-12 13:54:26 +02:00
Enrico Turri
b062cddeea Fixed object cutting 2018-04-12 12:56:42 +02:00
bubnikv
0f6fc689aa Merge remote-tracking branch 'remotes/origin/updating' into config_snapshots 2018-04-12 11:24:48 +02:00
bubnikv
9ab38f416d Improvement of the snapshot dialog, fixed storing of the snapshot "reason"
field.
2018-04-12 11:24:03 +02:00
Enrico Turri
1a274a253a Fixed object/instance transformation after import from 3mf files 2018-04-12 10:10:15 +02:00
Vojtech Kral
b030791384 Semver fixes, misc fixes 2018-04-12 09:33:17 +02:00
Vojtech Kral
12b3132b1a Perform init_vendors at startup 2018-04-11 18:05:21 +02:00
Vojtech Kral
31ea03feb0 ConfigWizard: Make bundle installation more intelligent, fixes 2018-04-11 18:05:12 +02:00
YuSanka
723bd22b96 Changed icons for lock/unlock filament_presets on Plater tab
Experiment with filament_presets transparency on GTK
2018-04-11 15:35:04 +02:00
bubnikv
aaa8f133c0 Fixed parsing of the config index. 2018-04-11 15:17:41 +02:00
YuSanka
762306d985 Added preset grouping to all presets ComboBoxes
Changed icons for action_undo, sys_lock and sys_unlock.
There are used same icons for all OS now.

Deleted/Commented temporarily used wxDataViewTreeCtrl
2018-04-11 13:56:37 +02:00
bubnikv
da2878958b Wizard runs from the new Config menu,
snapshots could be rolled back / forward.
2018-04-11 12:21:15 +02:00
bubnikv
4275b15dcd Merge remote-tracking branch 'origin/updating' into config_snapshots 2018-04-10 16:46:15 +02:00
bubnikv
0694fad016 Initial implementation of the config snapshot dialog. 2018-04-10 16:27:42 +02:00
YuSanka
e7520c3d18 Don't use select_preset on OS X 2018-04-10 14:52:03 +02:00
Enrico Turri
d789b5c0df Fixed warning texture not disappearing when deleting object out of bed 2018-04-10 14:12:16 +02:00
YuSanka
c1d25ba259 Experiments with wxDataViewTreeCtrl 2018-04-10 14:00:48 +02:00
Enrico Turri
b961711f28 Fixed autoscale of objects after loading 2018-04-10 13:39:10 +02:00
Enrico Turri
a81f78045b Delete key enabled in Object's Settings Dialog also for 3D view 2018-04-10 12:47:09 +02:00
Enrico Turri
9993f2215d Auto assignement of extruder, after object's splitting to parts 2018-04-10 12:17:55 +02:00
Enrico Turri
e92cf311db Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-04-10 11:46:51 +02:00
Vojtech Kral
a541f5dfe1 Fix of the fix 2018-04-10 11:43:04 +02:00
Lukas Matena
f49a7be90c An attempt to get RammingChart background colour consistent with its parent(s) on all platforms 2018-04-10 10:50:18 +02:00
YuSanka
fa4462514b Added preset grouping to PresetCollection::update_tab_ui 2018-04-10 10:31:58 +02:00
Enrico Turri
30a1fea8a0 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-04-10 08:52:12 +02:00
YuSanka
0cca7bb5e7 Dont use select_preset from preset_tree... 2018-04-09 17:09:00 +02:00
bubnikv
32c4cddb91 Ported the AboutDialog to C++, thanks @alexrj for the work.
New "configuration" menu over the snapshots, user preferences etc.
2018-04-09 17:03:37 +02:00
YuSanka
674ddcd73a Show preset_tree according to preset inheritance 2018-04-09 16:50:17 +02:00
Vojtech Kral
26511deec0 Add '-alpha' suffix to data directory for now 2018-04-09 16:39:50 +02:00
Vojtech Kral
b8a06d728a Fixes in 2DBed 2018-04-09 16:24:34 +02:00
Enrico Turri
df32817992 Auto assign multi-part extruders 2018-04-09 14:57:23 +02:00
Vojtech Kral
a8e831e04a rm stray file 2018-04-09 14:52:57 +02:00
Lukas Matena
bbbb5c9a93 Ramming chart is now drawn with double-buffering 2018-04-09 14:49:32 +02:00
Vojtech Kral
388deb71ab Adapt settings label colors to light vs dark UI themes 2018-04-09 14:46:19 +02:00
Enrico Turri
254592c849 Delete key enabled in Object's Settings Dialog 2018-04-09 14:20:44 +02:00
Lukas Matena
9ebff9ce00 Bugfix: a sign mistake was causing unnecessary travel moves 2018-04-09 13:35:39 +02:00
YuSanka
affaeef2ab Default presets are visible only if it's selected from Preferences 2018-04-09 12:41:25 +02:00
Vojtech Kral
57f6601c9d ConfigWizard: Fix logo rendering 2018-04-09 11:07:15 +02:00
YuSanka
e33db203d8 Next try to use wxDataViewTreeCtrlComboPopup on macOS and Linux:
Added: m_cc_presets_choice->UseAltPopupWindow();
       m_cc_presets_choice->EnablePopupAnimation(false);
like for wxCheckListBoxComboPopup
2018-04-09 09:55:24 +02:00
bubnikv
601185f113 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-04-06 16:49:59 +02:00
bubnikv
670061ac33 Initial implementation of configuration snapshotting. 2018-04-06 16:49:33 +02:00
YuSanka
004f9ba1e5 Added update_tab_presets functions to m_cc_preset_choise filling 2018-04-06 15:42:52 +02:00
Vojtech Kral
90a8ef8e9f Cleanup 2018-04-06 15:17:02 +02:00
YuSanka
e4b767e840 Experiment with own ComboCtrl for preset_choice. 2018-04-06 13:37:00 +02:00
Lukas Matena
abe94706f6 Gyroid infill bug fix: abs vs std::abs 2018-04-06 13:27:51 +02:00
Vojtech Kral
9dcec6662e ConfigWizard: Other vendor sample data, minor fixes 2018-04-06 13:24:02 +02:00
Vojtech Kral
d1c1dcbe8f ConfigWizard: Factor out a PrinterPicker widget, finalize other vendors page 2018-04-06 13:24:02 +02:00
Vojtech Kral
8422cf93c0 ConfigWizard: Finalize custom setup 2018-04-06 13:24:02 +02:00
Vojtech Kral
e53949f2c8 Apply printer model / variant preferences when loading presets 2018-04-06 13:24:02 +02:00
Vojtech Kral
57e47a3296 AppConfig: Support for vendor / model / variant enable state 2018-04-06 13:24:02 +02:00
Vojtech Kral
3fcf194e39 ConfigWizard: Basic structure / WIP 2018-04-06 13:23:49 +02:00
Lukas Matena
7253028d79 Merge branch 'master' into wipe_tower_improvements 2018-04-06 12:33:12 +02:00
Lukas Matena
cb9937cde4 Corrected wipe tower comments in GCode 2018-04-06 12:02:52 +02:00
Enrico Turri
b4efff1d95 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-04-06 08:40:38 +02:00
bubnikv
e37cbdfcfc Merge remote-tracking branch 'remotes/origin/profile_changes_reset' 2018-04-05 19:53:53 +02:00
Enrico Turri
3a61833d13 Update view in object's setting dialog when changing extruder 2018-04-05 15:55:50 +02:00
Vojtech Kral
2b8da333ef Semver: Semantic version parsing and arithmetics 2018-04-05 14:22:11 +02:00
YuSanka
6053c8f54d Try to fix bug with CheckBox selection if cursor is in TextCtrl. 2018-04-05 13:52:30 +02:00
Enrico Turri
76beaa6421 Objects colored by extruder color 2018-04-05 12:52:29 +02:00
YuSanka
28b6d222f2 Next try to fix bug with CheckBox selection if cursor is in SpinCtrl. 2018-04-05 12:12:35 +02:00
Lukas Matena
6af45362ce Purging volumes button is only shown when the wipe tower is enabled and we have single extruder MM printer with more than one extruder 2018-04-05 10:44:31 +02:00
bubnikv
a866011574 Merge branch 'master' of https://github.com/prusa3d/slic3r 2018-04-05 10:32:26 +02:00
bubnikv
4611b5094e Fixed regression of the gyroid infill. 2018-04-05 10:31:53 +02:00
Enrico Turri
1e185dacc4 Out of bed detection - GUI buttons disabled after object load if model detected as out of bed 2018-04-05 09:02:03 +02:00
Enrico Turri
4bdfb68ac5 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-04-05 08:44:01 +02:00
YuSanka
2eee3a64b7 First try to fix bug with CheckBox selection if cursor is in SpinCtrl. 2018-04-04 20:37:37 +02:00
Lukas Matena
706dd7020f New extruder temperature is only set when it differs from the old one 2018-04-04 14:59:31 +02:00
Lukas Matena
290e3e66c0 Merge correction 2018-04-04 14:41:23 +02:00
Lukas Matena
eb9917536c Merge branch 'master' into wipe_tower_improvements 2018-04-04 13:06:46 +02:00
Lukas Matena
597e8650a6 Fixed incorrect redraw of Purging volumes button in certain cases 2018-04-04 12:49:16 +02:00
Lukas Matena
1afe0af343 Merge branch 'wipe_tower_ui' into wipe_tower_improvements 2018-04-04 12:28:46 +02:00
Vojtech Kral
b0840065ed Octoprint (#804)
* Octoprint progress dialog

* Fix curl version on Windows
2018-04-04 11:18:22 +02:00
YuSanka
1b08bc94f0 Added g_wiping_dialog_button status update to update_frequently_changed_parameters() 2018-04-04 11:13:28 +02:00
bubnikv
00324a14b8 Merge remote-tracking branch 'origin/scene_manipulators' 2018-04-04 11:06:45 +02:00
bubnikv
261f391ee3 Merge remote-tracking branch 'origin/3mf_io' 2018-04-04 11:05:29 +02:00
bubnikv
40bbabb6d0 Merge remote-tracking branch 'origin/time_estimate' 2018-04-04 11:04:31 +02:00
bubnikv
76360d698c Merge branch 'gcode_preview' 2018-04-04 11:00:49 +02:00
bubnikv
2f6fbfb338 Fix of SPE-183: Incorrect z values set into GCode Preview sliders.
Rework to replace layer top heights with averages of EPSILON intervals.
2018-04-04 11:00:25 +02:00
Lukas Matena
91d6deee03 Merge branch 'wipe_tower_config' into wipe_tower_improvements 2018-04-04 10:37:18 +02:00
bubnikv
be8acc5ac4 Moved "wiping_volumes_extruders", "wiping_volumes_matrix" from
print settings to project settings.
2018-04-04 10:18:26 +02:00
Lukas Matena
719adfbaf3 The layer height check for multiple objects is now only enabled when variable layer height is enabled 2018-04-04 09:59:41 +02:00
Lukas Matena
42baeee0ed Fixed a bug regarding the sparse infill 2018-04-04 09:44:05 +02:00
YuSanka
d54425a901 Added show/hide of "Purging volumes" button depending on a state of "wipe_tower" 2018-04-03 22:07:59 +02:00
Lukas Matena
e5f23bc11d Fixed bug - negative feedrate was issued during loading of a new filament 2018-04-03 14:35:54 +02:00
Lukas Matena
89686b808d Added a check that all objects have the same layer height profile 2018-04-03 13:51:12 +02:00
Lukas Matena
281732ca38 Variable layer height enabled, nozzle diameters properly passed to the wipe tower generator 2018-03-29 15:32:09 +02:00
Enrico Turri
bf295b9039 Time Estimator and GCode Analyzer - Fixed handling of commands G90, G91, M82 and M83 - Fixes #812 2018-03-29 14:46:11 +02:00
Lukas Matena
6fd3f38717 Warning to show before ramming adjustements, vertical text in wiping dialog positioned better 2018-03-29 14:23:45 +02:00
Lukas Matena
572008546d Vertical label in wiping matrix dialog 2018-03-29 12:04:09 +02:00
Lukas Matena
c73d564004 Merge branch 'wipe_tower_ui' into wipe_tower_improvements 2018-03-29 09:47:12 +02:00
YuSanka
415bbd7860 Merge branch 'wipe_tower_ui' of https://github.com/prusa3d/Slic3r into wipe_tower_ui 2018-03-28 20:32:22 +02:00
YuSanka
c61ffe9f6b Corrected UI for RammingDialog 2018-03-28 20:31:36 +02:00
Lukas Matena
1b4dc685f4 Connected filament_ramming_parameters to respective dialog, other minor changes 2018-03-28 15:37:10 +02:00
Lukas Matena
7951349a1f Another t-test change to avoid fails 2018-03-28 10:32:23 +02:00
Lukas Matena
0d2637fede t tests changed so they don't fail on the extruder number check 2018-03-28 10:16:04 +02:00
YuSanka
4da6085ef8 Corrected UI for WipingDialog 2018-03-28 02:17:51 +02:00
Lukas Matena
56fef5302c Added axis-labels to RammingChart 2018-03-27 14:42:47 +02:00
Lukas Matena
7d9e892edc Added a button to open purging volumes dialog directly from Plater 2018-03-27 13:44:18 +02:00
Enrico Turri
c166af5cce GCode Preview - Fixed z values set on sliders 2018-03-27 11:35:48 +02:00
Enrico Turri
903a90f37a AMF I/O - Forces .zip.amf extension on export 2018-03-26 08:58:44 +02:00
YuSanka
e7edb512b8 Saved bed_shape changes.
*code review
2018-03-23 17:27:43 +01:00
Enrico Turri
c6623bb258 Increased camera theta max to 180 degrees. Fixes #666 2018-03-23 15:40:26 +01:00
YuSanka
01c37ac987 Merge remote-tracking branch 'origin/master' into wipe_tower_ui 2018-03-23 13:35:48 +01:00
YuSanka
77f5ed6851 Fixed bugs from SPE-180 2018-03-23 12:52:37 +01:00
YuSanka
53e100b890 Changed PrusaResearch.ini.
*(Uncommented "printer_model","printer_vendor", "printer_variant", "default_filament_profile")
* Added msg "It's system preset" to Dependencies
2018-03-23 09:41:52 +01:00
Lukas Matena
3fdd182f0c Parameters describing cooling tubes position etc moved to separate page in Printer Settings 2018-03-22 16:13:41 +01:00
YuSanka
1c5970d0a2 Added sys_lock and sys_unlock icons. 2018-03-22 15:16:30 +01:00
YuSanka
08a8fe84a4 Merge remote-tracking branch 'origin/master' into profile_changes_reset 2018-03-22 14:18:48 +01:00
YuSanka
57b61470a3 "Advanced" options alignment 2018-03-22 14:12:29 +01:00
Enrico Turri
4b8bd48663 AMF and 3MF export - Export of print config customizable by user in the select file dialog 2018-03-22 13:49:48 +01:00
Lukas Matena
985b414c64 Removed parameter 'wipe_tower_per_color_wipe' from UI and configuration layer 2018-03-22 13:37:01 +01:00
Lukas Matena
036e41ae69 Wiping dialog - first experiments with sizers 2018-03-22 13:07:45 +01:00
YuSanka
44b711953f Added preset parent description line to Dependencies 2018-03-22 11:46:15 +01:00
YuSanka
d7e2305686 "Undo"-buttons work 2018-03-22 10:56:57 +01:00
YuSanka
78208620c0 Correct updating of "Undo"-buttons according to the option changes 2018-03-22 09:37:42 +01:00
Enrico Turri
d384ed6e96 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-22 08:34:51 +01:00
Enrico Turri
d634378193 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-03-22 08:34:37 +01:00
Enrico Turri
48fe019302 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-22 08:34:00 +01:00
Enrico Turri
4173628a31 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-22 08:33:43 +01:00
YuSanka
82f4e16a27 "Decorated" UI for options groups.
* Added prototype of undo-buttons for options groups;
* Fixed bugs with "decoration" updating after preset changing;
* Fixed wrong Ukrainian translation.
2018-03-21 22:21:37 +01:00
Lukas Matena
e7a5bc1afe Added a check that no object uses extruder the printer doesn't have 2018-03-21 16:01:31 +01:00
Lukas Matena
9519fae490 Partial refactoring of wipe tower code (got rid of global constants, etc) 2018-03-21 15:57:17 +01:00
Enrico Turri
ebb2d45761 Out of bed detection - Disabled GUI buttons when object outside bed 2018-03-21 15:21:03 +01:00
YuSanka
5c9ba1399f Updated Czech to localization 2018-03-21 14:28:51 +01:00
YuSanka
c425169db0 Added Italian and updated German to localization 2018-03-21 14:00:06 +01:00
Lukas Matena
e30405d672 Merge branch 'master' into wipe_tower_improvements 2018-03-21 11:33:37 +01:00
Lukas Matena
1a1be94c99 Purging volume parameters normalization - minor changes 2018-03-21 10:20:36 +01:00
Enrico Turri
4a179c81d2 GCode Preview - Added visualization of volumetric flow rate 2018-03-21 10:03:10 +01:00
Lukas Matena
ac9db81820 Normalization of purging volume parameters when number of extruders is changed 2018-03-21 09:36:27 +01:00
Enrico Turri
ec14e94cec Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-21 08:40:34 +01:00
Enrico Turri
85d158525f Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-03-21 08:40:21 +01:00
Enrico Turri
78d1d83583 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-21 08:39:41 +01:00
Enrico Turri
65a815a06f Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-21 08:39:14 +01:00
Chow Loong Jin
a32281c268 Fix format-security violations (#802)
croak() expects printf-style format strings. Calling croak(e.what()) directly
causes compilations to fail with -Werror=format-security
2018-03-21 08:38:33 +01:00
bubnikv
86b79f89ad Removed BonjourBrowser.pm, SectionCut.pm and the associated
command line section cut tool.
2018-03-20 21:09:54 +01:00
Lukas Matena
0fc2da5a32 Wipe tower generator should now work for more than 4 extruders (actual number extracted from wiping_volumes_matrix) 2018-03-20 15:45:11 +01:00
Lukas Matena
a782424d5f Wipe tower generator connected to purging volumes from the configuration layer 2018-03-20 15:07:18 +01:00
Lukas Matena
a923062167 Purging volume dialog improved and connected to configuration layer 2018-03-20 13:50:51 +01:00
Enrico Turri
f99aaa1191 Out of bed detection - New colors for out of bed state 2018-03-20 13:01:50 +01:00
Enrico Turri
6298a28494 Disabled back face culling to show broken geometry 2018-03-20 11:59:33 +01:00
Enrico Turri
1f3f109263 Out of bed detection - Fixed false detection due to float precision 2018-03-20 09:31:42 +01:00
Enrico Turri
6db7e63e1c Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-20 08:34:32 +01:00
Enrico Turri
6c038d405b Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-03-20 08:34:19 +01:00
Enrico Turri
99f7bd90db Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-20 08:33:53 +01:00
Enrico Turri
557ea9baa6 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-20 08:33:25 +01:00
YuSanka
f72bb89521 Reset to system value works for Extruders too 2018-03-19 17:21:37 +01:00
bubnikv
abbfac0404 Modified the Triangles / Stars / Cubic infill types to lessen overfill
along the perimeters:
Only the two first hatching lines (0 and 60 degrees) will be connected
along the perimeter lines. The 3rd hatching direction will not.
Inspired by a fix done by @alexrj.
2018-03-19 16:51:43 +01:00
bubnikv
ebf0ef48f1 Extended the Cooling Buffer G-code filter to remove repeated
G1 Fxx entries to reduce the G-code size and printer stutter.
Fixes https://github.com/prusa3d/Slic3r/issues/448
2018-03-19 16:38:32 +01:00
Lukas Matena
76b280c64c Removed parameter 'wipe_tower_adhesion', it will always be true 2018-03-19 15:53:49 +01:00
Lukas Matena
349a8a88ae Bug fix: speed for finish_layer was not properly set 2018-03-19 15:35:31 +01:00
Lukas Matena
e41eff9186 Wiping volumes options temporarily added to Print Settings 2018-03-19 15:30:54 +01:00
bubnikv
bfc9678839 why is strlen() defined by different include on different systems? 2018-03-16 19:26:13 +01:00
bubnikv
f353b098e5 Missing include on Linux/GCC 2018-03-16 19:11:08 +01:00
bubnikv
34a0f87395 Fixed the previous commit on Linux: The older GCC we are using
on our Debian build server does not support C++11 <codecvt>,
so the utf8 to utf16 conversion was replaced with Boost counterparts.
2018-03-16 18:56:01 +01:00
bubnikv
0bd9918643 Implements SPE-159 "substitute accented letters with non-accented ones" 2018-03-16 18:20:47 +01:00
YuSanka
7e6887cca8 Completed UI for system value changes 2018-03-16 17:25:11 +01:00
Lukas Matena
3d6f6530c0 Merge branch 'master' into wipe_tower_improvements 2018-03-16 14:06:23 +01:00
Lukas Matena
b556cec42d Got rid of wipe_tower_advanced option 2018-03-16 13:58:58 +01:00
bubnikv
efeda3dcdc Merge branch 'mesh_repair' 2018-03-16 13:36:58 +01:00
bubnikv
9ae2fa6621 Removed Perl Slic3r::GUI::Notifier module.
The Growl for OSX is dead and the D-bus support for Linux/X was broken.
2018-03-16 13:13:27 +01:00
YuSanka
7f5bfe3ddc First visualization of system value changes 2018-03-16 12:56:03 +01:00
bubnikv
63a98269bb Merge branch 'master' into mesh_repair 2018-03-16 12:33:53 +01:00
bubnikv
e162c47167 Removed some dependencies on Perl IO module. 2018-03-16 12:07:54 +01:00
bubnikv
a38cbac312 Removed the LWP and Growl Perl dependencies. 2018-03-16 11:56:37 +01:00
bubnikv
1b23f9cd6e Fixing compilation errors: A non-const reference does not accept
a temporary variable.
2018-03-16 10:04:42 +01:00
Vojtech Kral
c88d2780ce Octoprint (#796)
* Octoprint: GUI for CA file, improvements

* Octoprint: Add GUI for Bonjour lookup, bugfixes

* Octoprint: Bonjour browser: Cleanup Perl interaction

* Octoprint: Bonjour: Perform several broadcast, UI fixes

* Octoprint: Add files to localization list

* Http: Disable CA File setting on SSL backends that don't support it
2018-03-15 18:06:26 +01:00
bubnikv
4f0c6dd879 Reworked the fix of #784 for efficiency and robustness:
First, the same direction segments are chained as before, but this time
the remaining open polylines are collected to be processed in the 2nd step.

Second, the remaining open polylines are connected by a greedy algorithm
disregarding their original orientation. As the orientation of loops
created by the 2nd step is mixed, the orientation of these loops is
unknown, therfore a CCW orientation is enforced. The CCW heuristics
may fill holes and cavities, but no outer geometry will be lost.
2018-03-15 17:14:13 +01:00
Lukas Matena
e864238609 Merge branch 'project_specific_config' into wipe_tower_improvements 2018-03-15 14:05:45 +01:00
Lukas Matena
67009d80fd Ramming parameters reduced to one and connected to the wipe tower generator again 2018-03-15 14:04:12 +01:00
YuSanka
8d4b603572 Correct updated Show/Hide of object_info_manifold_warning_icon 2018-03-15 11:59:12 +01:00
bubnikv
888b480250 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-03-15 11:07:15 +01:00
bubnikv
75230a790c Prusa specific Config Bundle: Commented out the config values,
which this Slic3r version does not understand yet.
Fixes https://github.com/prusa3d/Slic3r/issues/795
2018-03-15 11:06:33 +01:00
YuSanka
d97a8f5740 Merge remote-tracking branch 'origin/master' into profile_changes_reset 2018-03-15 10:24:54 +01:00
YuSanka
22330c0cae Showed correct "Info" box on initial Plater 2018-03-15 10:13:40 +01:00
YuSanka
c3ec40c3cc Added prototype of an "Undo to system" button 2018-03-15 09:55:31 +01:00
bubnikv
61ae78432c Removed the unsupported "pillars" support pattern. 2018-03-14 20:08:34 +01:00
bubnikv
4351187ce5 Fixed Print::validate() to allow for objects protruding below the print bed.
The part of the object below the print bed will simply not be sliced.
This fix also fixes integration tests, which often work with boxes
centered around (0,0,0).
2018-03-14 18:16:17 +01:00
bubnikv
5812ca06d6 Fixed ctest on Windows (should call Perl's prove.bat, not just prove) 2018-03-14 18:09:31 +01:00
bubnikv
7c027ee2ff Removed the old Prusa specific config bundles. 2018-03-14 16:44:29 +01:00
YuSanka
a41e55a773 Merge remote-tracking branch 'origin/profile_inheritance' into profile_changes_reset 2018-03-14 16:34:51 +01:00
bubnikv
b62f721ea6 Replaced the Prusa specific config bundles with a single PrusaResearch.ini,
so the Wizard will now offer just a single file. This file was copied
from the profile_inheritance branch to test the new profile hierarchy
before the branch gets merged into the master.
2018-03-14 16:30:51 +01:00
bubnikv
757b0788ae Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-03-14 16:16:18 +01:00
bubnikv
ab654f6319 Merge branch 'scene_manipulators' 2018-03-14 16:15:26 +01:00
bubnikv
b43a21d1be Extended Print::validate() to check, whether the objects
are inside the print volume.
2018-03-14 16:11:57 +01:00
Vojtech Kral
37f1429400 Yet another fix of the unix static Makefile (#793) 2018-03-14 16:05:51 +01:00
Lukas Matena
9f18b639a8 Added filament_ramming_parameters and filament_ramming_buttons into configuration layer 2018-03-14 15:48:37 +01:00
YuSanka
639f2bc2f3 Update m_initial_extruders_count after preset changing 2018-03-14 15:38:54 +01:00
YuSanka
15b2522ed9 Update "fill_density" to initial preset value instead of to 40% 2018-03-14 15:10:16 +01:00
bubnikv
de2d08f626 Update of G-code preview colors by Jindra. 2018-03-14 15:00:12 +01:00
bubnikv
08bea91197 Merge remote-tracking branch 'remotes/origin/3mf_io' 2018-03-14 13:35:51 +01:00
bubnikv
56c2267d19 Merge branch 'gui_improvements' 2018-03-14 13:33:53 +01:00
bubnikv
e680658cf5 Fixed selection of sensible active print / filament / printer profile
after the initial wizard run.
2018-03-14 13:29:50 +01:00
bubnikv
1969a8b2c1 Fixed crash on start of the application in case there is no
profile available.
2018-03-14 13:12:17 +01:00
bubnikv
317f651b78 Fixed a crash at the start of the application when the datadir is
missing, due to the option "default_filament_profile" not being
part of the FullPrinterConfig.
2018-03-14 12:44:53 +01:00
bubnikv
5f28b89ae0 Added a project specific config to the PresetBundle class.
This project specific config will be stored into the config.ini,
into .3mf and .amf and .gcode,
and recover it from the same files.
2018-03-14 11:54:11 +01:00
YuSanka
6d5d38eb6a Fixed bug_2 with update infill parameters 2018-03-14 11:45:31 +01:00
YuSanka
d9e2e37da7 Fixed bug with update infill parameters 2018-03-14 10:14:48 +01:00
YuSanka
30f6e33656 Completed update of frequently changed parameters 2018-03-13 16:14:36 +01:00
Lukas Matena
cf5dfb9673 Started to move ramming dialog into filament settings 2018-03-13 15:54:29 +01:00
Enrico Turri
b3b094eda3 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-13 14:53:54 +01:00
Enrico Turri
14ca4552a0 Merge branch 'master' of https://github.com/prusa3d/Slic3r into scene_manipulators 2018-03-13 14:53:41 +01:00
Enrico Turri
10572717ca Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-13 14:52:58 +01:00
Enrico Turri
88cdb2339f Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-13 14:52:44 +01:00
Enrico Turri
523b297738 Out of bed detection - Volume colors changed while dragging them 2018-03-13 14:37:59 +01:00
Enrico Turri
d91e35f820 Shaders tweaking 2018-03-13 14:21:41 +01:00
bubnikv
e845f3b864 Merge branch 'master' into profile_inheritance 2018-03-13 13:49:23 +01:00
Vojtech Kral
0781dd8271 Fix unix build: set openssl path directly rather than via pkg-config (#789) 2018-03-13 13:41:19 +01:00
bubnikv
7f31f7a3ab Added lock and lock_open icons. 2018-03-13 13:39:46 +01:00
Enrico Turri
1ae8684af1 Modified TriangleMeshSlicer::make_loops() to fix #784 2018-03-13 13:32:50 +01:00
bubnikv
729d879b0e Added the Prusa's vendor specific Config Bundle.
Added the "unlocked lock" icon when the system profile gets modified.
2018-03-13 09:45:04 +01:00
Vojtech Kral
bd61c233a5 CMake target to generate the main pot file (#786) 2018-03-12 20:38:47 +01:00
YuSanka
5bb736daf2 Infill(Plater) updates with Infill (Print Settings).
*Updated some fuctions
2018-03-12 16:52:21 +01:00
bubnikv
30c859ac7f Added a lock icon to the list of filaments, added some
helper methods to PresetBundle.
2018-03-12 16:04:32 +01:00
Lukas Matena
27ab8ff4e1 Configuration layer changes (cooling_time, bridging, adhesion moved from dedicated dialog to filament/print settings) 2018-03-12 15:41:25 +01:00
Vojtech Kral
58788ef43a MSVC: Fix run and debug project settings (#771)
* MSVC: Fix run and debug project settings

* MSVC: Fix CMake infinite loop
2018-03-12 09:39:32 +01:00
Enrico Turri
79dc862498 Out of bed detection - Shaders refactoring 2018-03-12 09:23:59 +01:00
Lukas Matena
b5fd4ddb8c Removed an unnecessary wait 2018-03-12 08:35:35 +01:00
YuSanka
e8adbd7303 First prototype of adding of UI for frequently changed parameters 2018-03-09 18:34:30 +01:00
YuSanka
d5e136a6d5 Fixed bug with updating of the value of "Wipe while retracting" CheckBox. 2018-03-09 17:17:51 +01:00
bubnikv
f55becd43c Introduced the system profiles.
The Config Wizard now just copies the Vendor's Config Bundle
into user_dir/vendor/ directory and Slic3r uses the configs
from the bundles found in user_dir/vendor directly.
2018-03-09 16:37:33 +01:00
Enrico Turri
d68804772a GCode Preview - Added handling of G10 and G11 commands 2018-03-09 15:27:38 +01:00
Lukas Matena
1c6fa6660e Merge branch 'master' into wipe_tower_improvements 2018-03-09 15:10:15 +01:00
Enrico Turri
50d74dfd20 Out of bed detection - Fixed compile on MacOS 2018-03-09 14:50:25 +01:00
Enrico Turri
7a2df9f54f Out of bed detection - Volumes' layer texture rendering moved to cpp 2018-03-09 14:33:44 +01:00
Lukas Matena
6e39f61198 Priming extrusions, nozzle-wipes when leaving tower, removed few unnecessary moves 2018-03-09 12:40:39 +01:00
Enrico Turri
bdd2d725c8 Out of bed detection - 1st installment 2018-03-09 10:40:42 +01:00
YuSanka
419721ce22 Fixed bug with highlighting of modified parameters after changing the profile 2018-03-09 08:34:32 +01:00
Enrico Turri
58ffb27ff6 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-09 08:34:30 +01:00
Enrico Turri
1fcc7fcdd8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-09 08:33:56 +01:00
Enrico Turri
27d2247d9d Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-09 08:33:41 +01:00
Lukas Matena
8340a71f88 Lots of unnecessary code removed, minor refactoring changes 2018-03-08 16:44:52 +01:00
YuSanka
9ebb0f27c1 Fixed bugs with spiral_vase and standby_temperature_delta 2018-03-08 16:33:38 +01:00
YuSanka
418e083781 Fixed Linux build 2018-03-08 14:01:14 +01:00
bubnikv
83a2d2af4b Separated the soluble settings from the printer profiles. 2018-03-08 12:27:20 +01:00
YuSanka
986ee50437 Completed UI to visualize changes and to reset to initial value 2018-03-08 11:58:06 +01:00
Enrico Turri
00381988bf Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-08 08:37:50 +01:00
Enrico Turri
124c37641d Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-08 08:36:55 +01:00
Enrico Turri
107bba02f8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-08 08:36:43 +01:00
bubnikv
4e58c9dab9 Split the 0.25mm and 0.6mm nozzle parameters from the printer profiles. 2018-03-07 18:30:58 +01:00
bubnikv
f0fde26295 Implemented inheritance of profiles inside a config bundle.
Updated the Prusa's presets to match the initial flat config bundle.
2018-03-07 16:48:28 +01:00
Lukas Matena
f5cf181372 Sparse infill repositioned always to the same side 2018-03-07 15:34:12 +01:00
YuSanka
38dca8396f Updated back_to_initial_value and fixed some bugs for Extruders 2018-03-07 15:25:24 +01:00
Lukas Matena
76aa134f66 Ramming lines that would end unsupported are made longer to reach to the edge 2018-03-07 11:44:47 +01:00
Enrico Turri
fe59958ea8 GCode Preview - Unified preview data ranges to ensure proper paths colors 2018-03-07 09:17:59 +01:00
Lukas Matena
e1922cb2c5 Supressed preview on unloadingmoves 2018-03-07 08:55:53 +01:00
bubnikv
77e142553a First take on the config inheritance / config hierarchy. 2018-03-06 21:50:12 +01:00
Lukas Matena
af281e13db Last wipe on layer accounts of border and sparse infill (ugly, yet working) 2018-03-06 19:14:12 +01:00
YuSanka
dd7712d4d3 Fixed bug with case-sensitive name of icon (for Linux build) 2018-03-06 14:58:51 +01:00
YuSanka
c52f51b1e4 Fixed bug with resizing 3DScene 2018-03-06 14:45:03 +01:00
YuSanka
254e311593 Delete background color changing (except of MSW) 2018-03-06 13:34:39 +01:00
YuSanka
d0d83526b4 Merge remote-tracking branch 'origin/master' into gui_improvements 2018-03-06 12:47:20 +01:00
YuSanka
3caf54c359 Undo buttons work 2018-03-06 12:34:20 +01:00
Enrico Turri
b04697d730 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-06 12:28:15 +01:00
Enrico Turri
d0587d6e83 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-06 12:18:04 +01:00
Enrico Turri
d91f59379b GCode Preview - Fixed values in range labels of legend texture 2018-03-06 12:12:00 +01:00
Enrico Turri
6dd241921f Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-06 11:43:19 +01:00
bubnikv
4a90ab1f6a Merge branch 'octoprint' 2018-03-06 11:39:44 +01:00
bubnikv
e26ccfc247 Fixed compilation on Windows,
removed debugging menu and debugging output.
2018-03-06 11:39:24 +01:00
Enrico Turri
9f7607c064 3mf I/O - Fixed object sinking into bed after import 2018-03-06 10:26:39 +01:00
bubnikv
51da42734a Merge remote-tracking branch 'origin/http+build' 2018-03-06 10:15:17 +01:00
YuSanka
4547755221 Update UI for visualize changes:
* Added changing of text color and inserted undo_button when some option is modified.
* Call wxSetlocale(LC_NUMERIC, "C") when do language changing.
2018-03-06 09:46:26 +01:00
Enrico Turri
aab0ffa044 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-06 08:37:20 +01:00
Enrico Turri
a600dbc06c Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-03-06 08:36:37 +01:00
Enrico Turri
c46eaf36e3 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-06 08:35:50 +01:00
Enrico Turri
7320a87183 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-06 08:35:28 +01:00
Vojtech Kral
ca0f6131a1 WIP: Bonjour: TXT + improvements 2018-03-05 18:33:15 +01:00
Vojtech Kral
fc05eb898d WIP: Bonjour 2018-03-05 18:33:15 +01:00
Vojtech Kral
7cfc5204c8 WIP: OctoPrint 2018-03-05 18:33:15 +01:00
Vojtech Kral
79ee7c9a36 Fix #608 Credit: Dylan "smellyfis" Thies 2018-03-05 18:32:09 +01:00
bubnikv
b897209e0d Removed -DCURL_STATIC on OSX,
added dynamic linking of OpenSSL on Linux, even if libcurl is linked
statically.
2018-03-05 18:02:47 +01:00
Vojtech Kral
f67d70941e Doc: Add dependency build scripts and building how-tos 2018-03-05 18:02:36 +01:00
Lukas Matena
6c223c2f84 Fixed cooling time calculation, removed unnecessary diagonal moves, fixed 'stringing' on start and end of narrower wipe tower layers 2018-03-05 16:51:31 +01:00
Vojtech Kral
751e86cd4d libcurl linking and cmake usage improvements 2018-03-05 16:31:24 +01:00
Vojtech Kral
14929e9d15 Http client via libcurl 2018-03-05 15:52:17 +01:00
bubnikv
3c64eb9215 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-03-05 15:31:32 +01:00
Lukas Matena
4058f00275 Added print head moves after ramming and removed one unnecessary diagonal move 2018-03-05 13:53:49 +01:00
bubnikv
5ea584280c Merge remote-tracking branch 'remotes/origin/gui_improvements' 2018-03-05 12:12:40 +01:00
Enrico Turri
5f3ee74e0e Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-05 11:54:52 +01:00
Enrico Turri
f43b2760ab Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-03-05 11:53:59 +01:00
Enrico Turri
3d19982d41 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-05 11:53:26 +01:00
Enrico Turri
352d5d0baa Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-05 11:53:15 +01:00
bubnikv
91b5853aa3 Merge remote-tracking branch 'remotes/origin/gui_change_extruders_color' 2018-03-05 11:47:13 +01:00
Enrico Turri
802579ad20 Fixed crash while exporting to .amf and .gcode files (#753) - (improves previous fix: d4f1ed0036) 2018-03-05 10:53:18 +01:00
Lukas Matena
5aca3045b9 (Un)loading speed and delay introduced into wipe tower generator 2018-03-05 10:45:35 +01:00
Enrico Turri
6049e0c42c Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-03-05 08:42:55 +01:00
Enrico Turri
df06b4b6b2 Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-03-05 08:42:32 +01:00
Enrico Turri
b2de3dd241 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-03-05 08:41:56 +01:00
Enrico Turri
f0ec8c0967 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-03-05 08:41:45 +01:00
YuSanka
f750abb9db Refactor load_config() function 2018-03-04 15:21:01 +01:00
bubnikv
ed7c02d578 Disabled the CMake BOOST debugging. 2018-03-02 23:11:57 +01:00
bubnikv
15dbeff0c9 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-03-02 18:15:15 +01:00
bubnikv
777bcf5865 Enabled Boost_DEBUG in CMake to get some debug info when something
goes wrong.
2018-03-02 18:14:19 +01:00
Lukas Matena
b3e9b82280 (Un)loading speed and time delay parameters introduced into GUI and conf. layer (not yet into wipe tower generator) 2018-03-02 15:52:16 +01:00
YuSanka
2a378f6590 Fixed problem with changing extruders color 2018-03-02 13:41:37 +01:00
Lukas Matena
e1421da5e8 Integrating cooling tube parameters into wipe tower generator 2018-03-02 13:26:16 +01:00
YuSanka
222368f7e8 Start of realization UI to visualize changes 2018-03-02 09:08:11 +01:00
Lukas Matena
d2006c8d8e Cooling tubes parameters added into GUI and configuration layer (not yet into wipe tower generator) 2018-03-01 16:15:00 +01:00
Lukas Matena
1d787a15a0 Fix for win builds 2018-03-01 09:57:51 +01:00
Lukas Matena
c76c075569 Yet another attempt to fix Win builds 2018-03-01 09:19:34 +01:00
Lukas Matena
b1b16359d9 Changes in includes in order to fix Win builds 2018-03-01 08:43:43 +01:00
Lukas Matena
9ea803b000 Attempts to fix OSX and Win builds 2018-02-28 19:53:32 +01:00
Lukas Matena
a62ad3323f First naive implementation of wipe tower settings dialog 2018-02-28 16:04:56 +01:00
YuSanka
541b51c524 Merge dictionaries from the upstream Slic3r. Update existing dictionaries according to new Slic3rPE.pot 2018-02-28 15:44:45 +01:00
YuSanka
751c97c503 Localize the Plater tab
* Marking and translation of Plater tab are complited
* GUI.pm is marked to l10n
* Fix small bug with Extruder adding at Printer Settings tab
2018-02-28 15:41:35 +01:00
Enrico Turri
0e896e48e4 3mf I/O - Added import and export of modifiers 2018-02-28 12:11:41 +01:00
Enrico Turri
6ec1b61cbc Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-28 11:46:16 +01:00
Enrico Turri
4e0d104afd Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-28 11:45:53 +01:00
Enrico Turri
d5959922f3 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-02-28 11:45:34 +01:00
Enrico Turri
8cd42966d6 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-02-28 11:45:23 +01:00
Enrico Turri
0ec68eb35b Fix for issue #661 (ExPolygons generation) 2018-02-28 11:41:04 +01:00
Enrico Turri
ecac4ab175 3mf I/O - Added import and export of object's and volume's name 2018-02-27 15:46:54 +01:00
Enrico Turri
2a2bdaa0e0 3mf I/O - Added import and export of object's and volume's config data 2018-02-27 10:49:51 +01:00
YuSanka
0596660dda Fix bug with not displaying flags for incompatible presets 2018-02-27 09:51:14 +01:00
Lukas Matena
3099c32d08 GUI - reenabling rotation angle settings for the wipe tower (was disabled by the merge with master) 2018-02-27 08:56:11 +01:00
Enrico Turri
8bb1f93b8d Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-02-27 08:33:50 +01:00
YuSanka
7047f4365a Update localization:
* 2D.pm, 3DPreview.pm, PreviewData.cpp are marked by L()
* use translating function in 3DScene.cpp
2018-02-26 16:23:44 +01:00
Enrico Turri
14d19356f3 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-02-26 16:19:36 +01:00
YuSanka
e05493bd90 Fixed wrong printing of recommended_thin_wall_thickness_description_line 2018-02-26 13:57:36 +01:00
YuSanka
f3f78ebc5a Fix #742 2018-02-26 09:57:08 +01:00
Enrico Turri
14359e5025 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-26 08:32:27 +01:00
Enrico Turri
eb2d689971 Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-26 08:32:04 +01:00
Enrico Turri
8f8d7d3d95 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-02-26 08:31:36 +01:00
Enrico Turri
69b0caa38f Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-02-26 08:31:24 +01:00
YuSanka
bcc68ca450 Added Slic3rPE.pot and list.txt to localization. 2018-02-26 08:31:07 +01:00
YuSanka
4c90e2bbc6 Rename localization guide to emphasize markdown format 2018-02-25 22:45:31 +01:00
YuSanka
b5d96e4ed6 Update localization guide 2018-02-25 22:41:28 +01:00
bubnikv
edb756c084 Refactored the gyroid infill. 2018-02-23 18:32:35 +01:00
Enrico Turri
d25a472267 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-23 16:17:47 +01:00
Enrico Turri
6765722a3a Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-23 16:17:25 +01:00
Enrico Turri
f43d989368 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-02-23 16:16:44 +01:00
Enrico Turri
27075e479e Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-02-23 16:16:06 +01:00
bubnikv
2edb96062e Removed the Perl Preferences dialog,
fixed the CMake after the GUI merge.
2018-02-23 15:53:16 +01:00
bubnikv
69fc99edbb Merge remote-tracking branch 'remotes/origin/gui_translate_to_cpp' 2018-02-23 15:32:13 +01:00
YuSanka
1948daec53 Added Manual for Localization 2018-02-23 15:10:36 +01:00
YuSanka
d61295eb10 Added Preferences files 2018-02-23 14:55:27 +01:00
YuSanka
3e09e93037 Updated POfile for CS 2018-02-23 14:54:08 +01:00
bubnikv
68c51be130 Merge remote-tracking branch 'remotes/origin/mesh_repair' 2018-02-23 14:38:37 +01:00
bubnikv
d0df673c82 Merge remote-tracking branch 'remotes/origin/time_estimate' 2018-02-23 14:34:01 +01:00
bubnikv
8fb443522b Merge remote-tracking branch 'remotes/origin/gcode_preview' 2018-02-23 14:33:16 +01:00
YuSanka
baa5726532 All project is ready to localization.
* Macro _LC is changed to _CHB. [to put translated string into std::string correctly]
* Macro _LS is changed to L.    [to mark string to translation]
* Standard wxWidgets macro _() is used for translation now.
* Updated POfile for EN
2018-02-23 14:25:49 +01:00
Enrico Turri
ce4b5c5252 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-23 08:56:39 +01:00
Enrico Turri
d4f5db39fa Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-23 08:56:16 +01:00
Enrico Turri
37fa1f296d Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-02-23 08:55:54 +01:00
Enrico Turri
52c1395626 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-02-23 08:55:39 +01:00
bubnikv
c3d7be5994 Merge remote-tracking branch 'remotes/origin/3mf_io' 2018-02-22 18:57:07 +01:00
bubnikv
acce8dbff6 A workaround of the dreaded Intel HD Graphics driver issue at least
on the laptop of @roesel.
fixes https://github.com/prusa3d/Slic3r/issues/672

The Intel HD Graphics hangs on the glFinish() call for some reason
with one particular graphics driver revision. Also the glFinish() call
was superfluous and it only may have had negative effect over the performance.

Both glFinish() and glFlush() were removed for performance reasons
where they were not needed, see
https://www.khronos.org/opengl/wiki/Common_Mistakes
2018-02-22 18:56:37 +01:00
Enrico Turri
30ca38793e Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-22 15:32:13 +01:00
Enrico Turri
95965b7b89 Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-22 15:31:48 +01:00
Enrico Turri
c6c0878fa9 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-02-22 15:31:22 +01:00
Enrico Turri
7efe0234a7 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-02-22 15:31:07 +01:00
Enrico Turri
52eb6f6bcf Remove .zip from file extension on import to avoid having it added again and again when exporting 2018-02-22 15:27:32 +01:00
YuSanka
cec12e203a Plater.pm is marked by L() to localization. 2018-02-22 15:13:07 +01:00
YuSanka
bc97184c63 Fixed #735 & PresetHints.cpp is marked to localization
* Macro _LC is created to put translated string into std::string correctly.
* Macro _LU8 is changed to function L_str.
* Created function from_u8
2018-02-22 14:19:41 +01:00
Lukas Matena
d17229efd5 Gyroid infill - minor correction for standard-conforming compilers 2018-02-22 12:00:24 +01:00
YuSanka
3d805a0f43 PreferencesDialog moved to C++ part 2018-02-22 11:12:29 +01:00
Lukas Matena
5f5a59328b Minor refactoring, actualized comments, etc. 2018-02-22 11:03:29 +01:00
Merill
d59bb027eb Gyroid infill type (#733)
Gyroid infill type.
2018-02-22 09:56:05 +01:00
Lukas Matena
5a02bde170 Fix of merge conflict and uninitialized variables in writer class 2018-02-22 09:28:31 +01:00
Enrico Turri
81eff20ad1 GCode Preview - Added Custom extrusion role + extended layers range for GCode preview 2018-02-22 08:59:47 +01:00
YuSanka
916378097c MainFrame.pm is marked by L() to localization. 2018-02-21 13:44:42 +01:00
Lukas Matena
de92f45eaf Merge with master 2018-02-21 13:22:51 +01:00
Lukas Matena
5ca0a2f37d Parametrized toolchanges, experiments with sparse wipe tower, etc 2018-02-21 13:07:32 +01:00
Enrico Turri
36601723a2 4th attempt to fix JIRA SPE-26 (Feature types on MAC) 2018-02-20 15:22:30 +01:00
Enrico Turri
23b1c8f1d2 3rd attempt to fix JIRA SPE-26 (Feature types on MAC) 2018-02-20 14:44:00 +01:00
Enrico Turri
26409cbade 2nd attempt to fix JIRA SPE-26 (Feature types on MAC) 2018-02-20 14:25:40 +01:00
YuSanka
faca2d027b Updated Slic3rPE.mo for CS & UK localization 2018-02-20 14:22:25 +01:00
YuSanka
bb7ec485f7 Updated Slic3rPE.mo for CS localization 2018-02-20 13:39:39 +01:00
YuSanka
23f96e30c3 Fixed wrong saving of "percent or millimeters" parameters 2018-02-20 12:30:13 +01:00
Enrico Turri
a569de44b6 1st attempt to fix JIRA SPE-26 (Feature types on MAC) 2018-02-20 11:40:15 +01:00
Enrico Turri
662ea15c23 3rd attempt to fix JIRA SPE-22 (wrong file export on MAC) 2018-02-20 11:33:38 +01:00
Enrico Turri
e13a9adff2 2nd attempt to fix JIRA SPE-22 (wrong file export on MAC) 2018-02-20 11:10:54 +01:00
YuSanka
6ad38f80fb Language configuration is saved now in AppConfig instead of wxConfig. 2018-02-20 08:58:46 +01:00
Enrico Turri
4d727263c5 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-20 08:40:28 +01:00
Enrico Turri
6af8805920 Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-20 08:40:03 +01:00
Enrico Turri
eeada56c1f 1st attempt to fix JIRA SPE-22 (wrong file export on MAC) 2018-02-19 15:33:01 +01:00
YuSanka
f5ae470e5e Completed translation to Ukrainian.
* Signs of degree are returned to UTF-8 in PrintConfig.
* Changed _LU8 macro. It's translated now like string explicitly specified as a string is already in UTF-8 encoding.
2018-02-19 15:32:22 +01:00
Enrico Turri
d4f1ed0036 Fixed crash while exporting MultiMaterial 2018-02-19 13:46:36 +01:00
Enrico Turri
7375f6a6f5 Fixed camera shifting after generating gcode 2018-02-19 11:28:56 +01:00
Enrico Turri
59bda19f3e Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-19 11:20:28 +01:00
Enrico Turri
4dbd4d0316 Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-19 11:20:14 +01:00
YuSanka
c6ff5ccbf4 Updated TextCtrl::BUILD() 2018-02-19 09:15:15 +01:00
YuSanka
867e867cdd Merge remote-tracking branch 'origin/master' into gui_translate_to_cpp 2018-02-19 08:41:41 +01:00
YuSanka
f330eb9567 Fixed set_value() bug. Fixed Infill density.
* Got rid of try/catch at PointCtrl::set_value().
* Optimized localization: got rid of redundant macro _LU8(s).
2018-02-19 00:01:11 +01:00
fsantini
ac904b2731 Error messages in parsing variables (#722)
Making error messages more clear when a vector or scalar is found in macro parsing, and the other type is expected.
2018-02-16 17:27:50 +01:00
bubnikv
8dd5fe83fc Humbly re-added the BedShapeDialog.pm. Even though we have a C++
implementation now, the Perl BedShapeDialog.pm is used by the wizard.
2018-02-16 17:20:34 +01:00
YuSanka
4d9eac0750 Fix porting Tab.title() from cpp to Perl 2018-02-16 15:49:18 +01:00
YuSanka
12b9a513c1 Escape from try/catch in Tab and OptionsGroup
* Deleted  macro _LU8 from GUI.hpp. It's used only in Option class now.
* Added macro _LS to mark string used at localization (It returns same string)
2018-02-16 15:41:33 +01:00
bubnikv
7436d58045 Merge remote-tracking branch 'origin/gui_translate_to_cpp' 2018-02-16 11:38:11 +01:00
YuSanka
53006384d5 Fixed converting of Unicode codepoint (\uXXXX) into a character in Perl. 2018-02-16 10:29:28 +01:00
YuSanka
1167458acd Fixed converting of Unicode codepoint (\uXXXX) into a character in Perl. 2018-02-16 09:38:03 +01:00
Enrico Turri
7575d53cbf Merge branch 'master' of https://github.com/prusa3d/Slic3r into mesh_repair 2018-02-16 08:46:27 +01:00
Enrico Turri
66b6447fc1 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-16 08:45:38 +01:00
bubnikv
4ee620b57d Fixed Perl dependencies after some obsolete modules were removed. 2018-02-15 18:41:37 +01:00
bubnikv
f876946358 Merge remote-tracking branch 'origin/gui_translate_to_cpp' 2018-02-15 18:32:51 +01:00
YuSanka
7014902341 Updated *.po & *.mo files for EN & CS 2018-02-15 18:30:48 +01:00
bubnikv
39100068c1 Removed the Perl Tab & BedDialog as they were replaced by their C++
counterparts.
2018-02-15 18:16:19 +01:00
bubnikv
f1840a52db Merged the C++ port of the GUI Tabs / OptionGroup / Option classes
by @YuSanka, thanks @lordofhyphens for the initial port
of the OptionGroup / Option.
2018-02-15 18:13:37 +01:00
YuSanka
59cee4a3aa Thanks @stelgenhof Corrected units of measure that had exponents displayed with caret. 2018-02-15 18:06:37 +01:00
YuSanka
e0933786e3 Marked string used at localization.
* Correct save changed color
2018-02-15 17:30:33 +01:00
bubnikv
b695089bc4 Merge remote-tracking branch 'remotes/origin/3mf_io' 2018-02-15 17:02:47 +01:00
bubnikv
1fa3ffbf83 Fixed a bug, when a color selection popped up when clicking
on the print or printer combo box icon.
2018-02-15 16:41:26 +01:00
bubnikv
4a35fd655c Disable some of the G-code preview controls for the old 3D path preview,
re-enable them when the G-code preview is ready.

Resurrected the old logic to automatically switch to the tool preview
for a multi-material print, and to switch automatically to the feature
preview for a single material print.
2018-02-15 16:30:35 +01:00
Enrico Turri
1489b9901b Added workaround into admesh stl_fix_normal_directions() function to prevent meshes to be broken by the repairing process (fixes #716, #574, #413, #269, #262, #259, #230, #228, #206) 2018-02-15 16:10:47 +01:00
bubnikv
f9cdda7bfd Delayed loading of the opengl texture for the G-code preview legend,
as the opengl context may not be ready on some platforms (Linux)
at the time the window gets its focus for the first time.

Changed the G-code preview invalidation to trigger when the print
gets invalidated. At that time the 3D path preview switches to the old
preview, if there is anything valid left.
2018-02-15 14:37:53 +01:00
bubnikv
b5bdb46268 Added logging of the G-code export. 2018-02-14 22:25:09 +01:00
bubnikv
7f51b07f69 First take on restoring the old 3D path preview before the G-code preview is ready 2018-02-14 21:59:33 +01:00
bubnikv
ff3ae40aeb Fixed compilation issues caused by the previous commits 2018-02-14 21:57:46 +01:00
bubnikv
2caba92623 GCode/PreviewData.cpp,hpp has been split from GCode/Analyzer.cpp,hpp 2018-02-14 20:38:03 +01:00
bubnikv
b1f5e7e8fa Removed the GCodePreviewData from the Print class, it does not belong here,
as the GCode is generated outside of the Print class.
Exported the GCodePreviewData as GCode::PreviewData to Perl.
When exporting the G-code with a command line Slic3r,
the GCodeAnalyzer is now supressed for performance reasons.
Removed obsolete Perl module Slic3r::GUI::Plater::3DToolpaths.
2018-02-14 20:35:59 +01:00
bubnikv
3a6436f6f0 Split the GCodePreviewData from the GCodeAnalyzer,
as in the next step the GCodePreviewData will be exported to Perl.
2018-02-14 18:42:09 +01:00
Enrico Turri
dcc667cdc7 AMF I/O - Fixed error messages 2018-02-14 15:52:39 +01:00
Enrico Turri
f5f27859e0 AMF I/O - Embedded config data + zip formatting 2018-02-14 14:30:03 +01:00
bubnikv
f38e0f2b4f Merge branch 'gcode_preview' 2018-02-14 13:29:57 +01:00
bubnikv
6e80a9111c Reworked the plater UI messages to standard wxWidgets wxCommandEvent
messages to support receiving status line updates from the C++ code.
2018-02-13 18:31:34 +01:00
bubnikv
6cf8264362 Re-enabled $combochecklist_features->UseAltPopupWindow(), without this
line the combo box popup was not reacting to mouse events on Windows 10.
2018-02-13 17:46:23 +01:00
YuSanka
39fae3777c Marked all informative strings by macros _L and _LU8. 2018-02-13 16:05:53 +01:00
Enrico Turri
bacb36eb10 3mf - Fixed include for Linux build 2018-02-13 15:33:45 +01:00
Enrico Turri
8885f5e344 3mf import/export of config data 2018-02-13 15:19:55 +01:00
bubnikv
030fc9c320 Merge branch 'master' into gcode_preview 2018-02-13 14:55:54 +01:00
YuSanka
752d089814 Fixed Issue #478 2018-02-13 13:39:20 +01:00
Enrico Turri
f4522cd2fc GCode Preview - Customizable extrusion role colors by editing 3DPreview.pm 2018-02-13 13:16:23 +01:00
bubnikv
a5e48cdf4d Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-02-13 11:19:34 +01:00
bubnikv
e7f05f8516 Fix of "Crash while trying to slice with a raft" #686
This was an issue specific to multi-material print with raft
and no support.
2018-02-13 11:18:58 +01:00
Enrico Turri
e77111bf98 Fixed crash when importing .prusa files 2018-02-13 10:25:55 +01:00
bubnikv
81a80ebd61 Synchronized the GCodeSender with the upstream Slic3r, thanks @alexrj.
Fixes https://github.com/prusa3d/Slic3r/issues/654
2018-02-12 20:44:06 +01:00
bubnikv
6f92424bab Fix of https://github.com/prusa3d/Slic3r/issues/709
A regression error has been introduced into Slic3r 1.38.xx series
for the float/percent config value, where the value was considered
unchanged if the percent sign has been added or removed.
2018-02-12 19:06:05 +01:00
bubnikv
47d904a628 Changed the Slic3r coordinate type from long to int32 to match
the point type on Windows / Linux / OSX
to achieve the same behavior on all the 32 / 64bit systems.
(Windows always treats the long as 32bit int, while Linux treats
long as a 64bit int).
2018-02-12 18:16:10 +01:00
bubnikv
adc9e749c4 Clipper should always throw clipperExceptions, not strings. 2018-02-12 16:34:39 +01:00
bubnikv
0571d22d5f Fix of https://github.com/prusa3d/Slic3r/issues/707
This is a crash due to the recommended thin wall thickness hint.
2018-02-12 15:37:42 +01:00
YuSanka
77bac4c17a Fixed wrong filling of TextControl, when value is double. 2018-02-12 15:29:21 +01:00
Enrico Turri
3f006dc11a GCode Preview - Added objects and wipe tower transparent shells 2018-02-12 09:04:05 +01:00
YuSanka
badeb2f64c Save language preset.
* Added global variable g_local_dir to get "localization" directory.
* Chage/Set language works correctly now.
* Probably, fixed work on Linux
2018-02-12 08:57:32 +01:00
YuSanka
d18a200b0f Fix biuld on Linux a OSX 2018-02-09 12:07:59 +01:00
YuSanka
abcfd5bad9 Implemented Application recreate after changing of language.
* Implementation of C++ to Perl callbacks from menu item Localization.
* Added global variable g_tabs_list to control existing Tabs.
2018-02-09 11:04:34 +01:00
Enrico Turri
33553e1c50 3mf Exporter - 1st installment 2018-02-08 13:26:50 +01:00
YuSanka
143f9d7d84 Added missing po-files 2018-02-08 10:59:43 +01:00
YuSanka
43aa1680cb Added menu item for selection of application language from the list of installed languages.
* m_Local and its functions moved to GUI.cpp.
* Strings in some files(GUI.cpp, Tab.cpp, Tab.hpp & Field.cpp) marked by _L() macro.
* Updated mo-files for En and Uk languages.
2018-02-08 10:58:13 +01:00
YuSanka
28115a847c First steps for implementing localization
* Created mo-files for Ukrainian and English languages
* For this moment it works only on BedShapeDialog.
2018-02-07 17:13:52 +01:00
Enrico Turri
6b14e7cc54 GCode Preview - Fixed behavior of the feature types combo 2018-02-07 10:22:35 +01:00
Enrico Turri
0d6a013658 GCode Preview - Coloring by tool 2018-02-07 09:07:37 +01:00
YuSanka
407f50a66f Deleted on more EVT_NOTEBOOK_PAGE_CHANGE hangling of TabPanel 2018-02-06 14:53:38 +01:00
Enrico Turri
6ff9021e04 GCode Preview - Legend texture shown only when gcode is available 2018-02-06 12:43:25 +01:00
YuSanka
6bff67a865 First experiments with wxLocale 2018-02-05 16:12:16 +01:00
Enrico Turri
824c2567c8 Merge branch 'master' of https://github.com/prusa3d/Slic3r into time_estimate 2018-02-05 13:46:31 +01:00
Enrico Turri
593d794655 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-02-05 13:28:10 +01:00
Enrico Turri
6e14e6ef17 Merge branch 'master' of https://github.com/prusa3d/Slic3r into 3mf_io 2018-02-05 13:18:56 +01:00
Enrico Turri
f9dd251276 GCode Preview - Added feature type for wipe tower 2018-02-05 13:16:08 +01:00
YuSanka
a72184684c Fix compilation on Linux and OSX 2018-02-05 12:49:23 +01:00
YuSanka
2d3c2dc595 Fix of #696 in cpp's Tabs,
using changes from commit 36bbd6a
2018-02-05 11:03:13 +01:00
bubnikv
ea9920e5d6 Fix of Negative Feedrates: G1 F-3.84007e+006 stops smoothie
The problem was caused by the gap fill algorithm, which worked
with square extrusion width values as with rounded extrusion widths,
which sometimes lead to negative extrusion cross sections
for high height to width ratios.

The extrusion width logic has been changed to consider the input width
to be the extrusion spacing, not the extrusion width. The change certainly
removed the negative feed rates, but it also certainly increased the gap
fill width to some exent. It needs to be verified now, whether the gap fill
does not extrude too much.

https://github.com/prusa3d/Slic3r/issues/677
2018-02-02 19:48:16 +01:00
Enrico Turri
f20beeab7a 3mf Importer - fixed Linux build (makefile) 2018-02-02 15:03:06 +01:00
Enrico Turri
fe8dfb9c9b GCode Preview - fixed Linux build (include in GUI.cpp) 2nd attempt 2018-02-02 13:56:25 +01:00
Enrico Turri
556c9c236f GCode Preview - fixed Linux build (include in GUI.cpp) 2018-02-02 13:28:37 +01:00
Enrico Turri
a5c4751718 GCode Preview - void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt) fixed for OsX and Linux 2018-02-02 12:58:31 +01:00
Enrico Turri
787a5f1715 GCode Preview - New Layout 2018-02-02 12:38:35 +01:00
bubnikv
b4483fdcbd Fix of "Conditional gcode with "<=" condition fails"
https://github.com/prusa3d/Slic3r/issues/683
2018-02-02 11:49:09 +01:00
bubnikv
8932055ed5 Fixed spelling of Elephant foot compensation from Elefant to Elephant.
Unfortunately the settings is out in the wild, so we did not fix
the spelling of the config value name.
2018-02-02 11:38:30 +01:00
bubnikv
c9887e13bb Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-02-02 11:32:52 +01:00
bubnikv
36bbd6a73f Fix of https://github.com/prusa3d/Slic3r/issues/696 2018-02-02 11:32:32 +01:00
bubnikv
4f427f8387 Updated the bundled Slic3r profiles to match the current stable release
profiles, adjusted the speed / acceleration / jerk limits to match
the current MK3 firmware.
2018-02-02 10:51:08 +01:00
YuSanka
d9521fe733 One more try to fix compilation on OSX 2018-02-01 12:09:09 +01:00
YuSanka
e375a0d5ac Try fix compilation on OSX 2018-02-01 10:39:27 +01:00
YuSanka
46c39d6ef7 Try fix compilation on OSX 2018-02-01 10:24:12 +01:00
YuSanka
33280b7069 Next try fix compilation on OSX 2018-02-01 10:01:05 +01:00
YuSanka
d414c6e118 Fix compilation on OSX & Linux 2018-02-01 09:29:07 +01:00
YuSanka
733c85936b Eliminated the g-code pop up text description
(switch Enable of Tooltip to false,
when clicking mouse left button inside the control).
2018-01-31 16:46:17 +01:00
YuSanka
54dbc916a8 Fixed strange behavior of Text- and Spin- control on KillFocus event 2018-01-31 14:59:44 +01:00
Enrico Turri
c550ad2268 GCode Preview - Travel moves colored by speed 2018-01-31 11:35:35 +01:00
Enrico Turri
d2d2a3fa8e speed in mm/s 2018-01-31 10:34:00 +01:00
Enrico Turri
29853a3a45 GCodeTimeEstimator - Added move statistics log (for debug purpose) 2018-01-30 13:18:21 +01:00
YuSanka
667ffa6101 Added changes missing from the previous commit. 2018-01-30 12:13:55 +01:00
YuSanka
7d29a7b45a BedShapeDialog and Bed_2D (as a part of it) are completed.
Added new_scale function to Polyline.
Fixed small bug in PointCtrl.
Extended change_opt_value for coPoints case.
2018-01-30 12:10:12 +01:00
Enrico Turri
475f892413 3mf Importer - 1st installment 2018-01-30 09:27:10 +01:00
Enrico Turri
893201d3d9 3mf Importer - Added miniz library 2018-01-30 08:48:58 +01:00
YuSanka
f90ea5060d Fixed performance of preset switching. 2018-01-27 17:39:00 +01:00
YuSanka
8c7a56d4ea Eliminated the g-code pop up text description.
Fixed correct writing of TextCtrl values.
2018-01-27 14:21:16 +01:00
YuSanka
6ef5e6bd3d Deleted Perl's Tabs,
but still printer preset switching work very slowly.
2018-01-26 03:24:01 +01:00
YuSanka
4056978731 Implementation of C++ to Perl callbacks from Browse & Test buttons. 2018-01-26 01:44:34 +01:00
YuSanka
4d234e90ae Some modifications:
- Added no_controller to create_preset_tab().
- Small changes in Tab"Setting" constructor.
2018-01-25 21:45:39 +01:00
YuSanka
fced9a85ec Merge remote-tracking branch 'origin/master' into gui_translate_to_cpp 2018-01-25 13:59:15 +01:00
YuSanka
f0b035059a Merge with bibnikv.
Added some functions to TabIface.
Added BedShapeDialog & Bed2D classes.
Added new_scale to Polygon.
In class Field: Point renamed to PointCtrl and added set_value for PointCtrl, extended get_value for Choice.
2018-01-25 13:46:04 +01:00
bubnikv
a1705c093b Renamed Tab.h to Tab.hpp 2018-01-23 11:42:04 +01:00
bubnikv
91c7bc43d3 Added new files missing from the previous commit. 2018-01-23 11:37:45 +01:00
bubnikv
09c9f6bdc3 Added TabIface C++ wrapper for GUI::Tab C++ class,
exported the TabIface to Perl.
2018-01-23 11:37:19 +01:00
bubnikv
1d10a2293a Example implementation of C++ to Perl callbacks using wxWidgets command events. 2018-01-21 23:35:00 +01:00
bubnikv
ea8b3a5dc0 Will clang & gcc eat it now? 2018-01-21 22:23:59 +01:00
bubnikv
f529269f62 GCC requires explicit conversion from wxString to std::string. 2018-01-21 22:04:57 +01:00
bubnikv
a78fa58b51 Fix compilation on OSX 2018-01-21 21:56:20 +01:00
bubnikv
28c929f14d Replaced UTF8 characters in string literals with \uxxxx.
Replaced std::make_unique with Slic3r::make_unique to support old C++11
compilers.
2018-01-21 21:42:06 +01:00
bubnikv
8add843ee8 Temporary, or maybe not so temporary fix to handle empty
post processing scripts.
2018-01-21 21:08:30 +01:00
Enrico Turri
be63cb7d12 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-01-19 08:49:11 +01:00
YuSanka
bd113ea882 Extended load_config and deleted call of CallAfter,
because of in some cases it causes undate() function to be recalled again.
2018-01-18 16:36:26 +01:00
YuSanka
5162cddd5e Added SavePresetWindow dialog. 2018-01-18 11:45:25 +01:00
Enrico Turri
6591620200 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2018-01-18 09:16:37 +01:00
Enrico Turri
d34f3ffc83 Fix for #574, #413, #269, #262, #259, #230, #228, #206 2018-01-18 09:15:04 +01:00
Enrico Turri
a417cf955d GCode Preview - Code cleanup 2018-01-17 10:39:05 +01:00
YuSanka
d6568f9ce7 To Tab added functions to save/delete/upload presets...
Changed m_options OptionsGroup from const t_optiondef_map& to std::map<t_config_option_key, Option>.
2018-01-16 16:28:01 +01:00
Enrico Turri
c63e6b74fa GCode Preview - Added legend texture 2018-01-16 14:59:06 +01:00
YuSanka
636af8933c Added class ogStaticText to the static text shown among the options.
Fixed bugs in Tab.
2018-01-15 12:13:05 +01:00
YuSanka
8e0cd35c23 Merge remote-tracking branch 'origin/master' into gui_translate_to_cpp 2018-01-14 21:58:21 +01:00
YuSanka
bd02174f40 Fixed a bug in "on_change_OG" 2018-01-14 21:52:55 +01:00
YuSanka
2809b4b2b5 Added "update", "update_serial_ports" & "extruders_count_changed" for TabPrinter.
Extended "build" for TabPrinter.
2018-01-12 17:16:59 +01:00
YuSanka
d3b4dbf8bc Added "update" for TabFilament.
Added "reload_compatible_printers_widget" and extended "load_key_value" for Tab.
Extended "change_opt_value" in GIU
2018-01-12 12:41:13 +01:00
Enrico Turri
9e0dd2a96a fix-attempt to build on linux and osx 2018-01-12 11:42:50 +01:00
Enrico Turri
cc1aaceea6 fixed compile on linux and osx 2018-01-12 11:09:53 +01:00
Enrico Turri
f62c66f460 merge with master 2018-01-12 10:26:01 +01:00
Enrico Turri
2cbde291e4 Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-01-12 10:18:06 +01:00
Enrico Turri
473bd024fe removed debug code 2018-01-12 08:55:55 +01:00
Enrico Turri
a8a4c11b5b New algorithm for GLVolumes generation and reuse of already generated geometry 2018-01-11 14:09:54 +01:00
YuSanka
3567981089 Complited "update" for TabPrint.
!->It's one unresolved problem - dlg->ShowModal() call update().
Added "get_field" at Tab & Page.
Extended "change_opt_value"
Extended "get_value" to Choise.
2018-01-11 10:33:17 +01:00
Enrico Turri
bbc9a0abe6 Parallelization of extrude path render geometry generation 2018-01-10 13:43:00 +01:00
YuSanka
129bd898cd Extended "get_value" to Choice & TextCtrl fields.
Extended "change_opt_value".
2018-01-09 13:52:01 +01:00
YuSanka
59432d50ff To OptionsGroup added "reload_config" to reload configurations after changes in any fields & "get_config_value" to get current option value from config.
In Field extended "set_value" to Choice.
In PrintConfig added default_value to "post_process".
2018-01-09 09:41:07 +01:00
Enrico Turri
6a744238b9 Added preview of retractions and unretractions 2018-01-08 16:05:01 +01:00
Enrico Turri
c9839dd7cc Merge branch 'master' of https://github.com/prusa3d/Slic3r into gcode_preview 2018-01-08 13:45:57 +01:00
Enrico Turri
0f4bec8af0 gcode preview - first installment - wip 2018-01-08 13:44:10 +01:00
Enrico Turri
e94491ee8c GCodeTimeEstimator - Fixed _simulate_st_synchronize() 2018-01-08 13:23:54 +01:00
Enrico Turri
aeca5def00 GCodeTimeEstimator - Added credits for CuraEngine 2018-01-08 12:27:18 +01:00
Enrico Turri
dfcb502ef4 GCodeTimeEstimator - Fixed square roots of negative numbers 2018-01-08 12:17:39 +01:00
fredizzimo
ad5fcce6e4 Fix environment variable setting on Windows (#674)
The previous way of checking that _putenv_s is defined does not work,
because _putenv_s is a function and not a define. This is a partial
application of commit 31115e0369747b1e1c45cbe3f2a90f6dff66666a from
alexrj/Slic3r.

I tried cherry picking the whole commit, but unicode is already handled
diffrently here, so that would have been a lot of work.
2018-01-07 22:20:02 +01:00
YuSanka
16458e070a get_option moved from Tab to ConfigOptionsGroup and extended. Added change_opt_value to changing option value in config 2018-01-07 18:41:40 +01:00
bubnikv
fec1fcdca8 Separated the Marlin G-code flavor from the RepRap G-code flavor
due to the differences in the M203 code
(RepRap firmware has it in mm/min, Marlin in mm/sec).
This difference is important to the G-code time estimator.

Changed the g-code flavor to Marlin for all Prusa3D bundled profiles.
2018-01-06 18:49:28 +01:00
bubnikv
60a6e7ba8e Included the velocity, acceleration and jerk settings into the Prusa3D
printer profiles.
2018-01-06 15:23:02 +01:00
bubnikv
7012c04005 Updated the printer profiles. 2018-01-06 15:06:21 +01:00
bubnikv
40a6125d73 Updated printer profiles. 2018-01-06 15:06:11 +01:00
bubnikv
eaac587467 Merge remote-tracking branch 'origin/time_estimate' 2018-01-06 15:04:57 +01:00
YuSanka
e62c17bddf "on_change" function call correctly work now. Start adding of Tab::update().
It's need to think about config->set_key_value(...): at cpp side it's non-trivial.
2018-01-05 15:11:33 +01:00
Enrico Turri
ae0688f351 GCodeTimeEstimator - added processing of commands M221 (Set extrude factor override percentage) 2018-01-05 10:35:04 +01:00
Enrico Turri
69e3ea6581 GCodeTimeEstimator - simulate firmware st_synchronize() for commands G4, G92, M1 2018-01-05 09:46:09 +01:00
bubnikv
696d420dc8 New feature: Recommended object thin wall thickness hint. 2018-01-04 15:38:06 +01:00
Enrico Turri
3f57e20235 GCodeTimeEstimator: refactoring of forward and reverse passes on blocks 2018-01-04 13:00:34 +01:00
Lukas Matena
37bbeeb9d0 Parametrization of ramming and loading sequence - first steps 2018-01-04 12:03:06 +01:00
bubnikv
011281df86 Fix of the Spiral Vase after the GCodeReader rework.
A patch of the GCodeTimeEstimator to avoid crashes. This is not a final fix though.
2018-01-03 21:55:32 +01:00
bubnikv
998157fc9b Fixed an issue with vsprintf and on demand buffer allocation.
Improved the GCodeReader to support spaces before the G-code.
2018-01-03 20:53:39 +01:00
bubnikv
9d98a27b98 Fix of compilation on OSX and Linux. By the standard, a temporary
value cannot be passed to a reference.
2018-01-03 17:57:37 +01:00
bubnikv
b292554fd8 Optimized the GCodeReader.
Fixed the profiling build.
2018-01-03 17:29:49 +01:00
YuSanka
f8a48f5c13 Start adding functions to work with presets 2018-01-03 10:12:42 +01:00
bubnikv
0e4ecfaf56 Fix of time estimator (int abs used instead of float abs) 2018-01-02 13:29:40 +01:00
YuSanka
72d1f51146 Correct adding of extruder_pages 2018-01-02 12:50:27 +01:00
bubnikv
fec05d430b Fixed a typo in fprintf 2018-01-02 11:14:22 +01:00
bubnikv
02256e900f Merged the branch time_estimate 2018-01-02 10:57:30 +01:00
bubnikv
c6bc55e4f9 Added a comment on disabling ICU integration when compiling Boost on Linux. 2018-01-02 10:36:45 +01:00
bubnikv
0de0e4ff41 Bumped up the version number. 2018-01-02 10:34:32 +01:00
bubnikv
d7998870c7 Bumped up the minimum firmware version of the MK3 printers to 3.1.1-RC4 2017-12-29 21:39:55 +01:00
bubnikv
4c35d98d7d Bumped up the version number. 2017-12-29 21:21:26 +01:00
bubnikv
f58d66fe5e Disabled the object auto centering by default. 2017-12-29 21:17:30 +01:00
bubnikv
a056eadc1e Changed perimeter-infill overlap of the bundled Prusa i3 MK3 printer
profiles from 35% to 25%.
2017-12-29 21:15:20 +01:00
YuSanka
838a0885fe Fixed code review issues 2017-12-26 23:04:54 +01:00
YuSanka
61247fe8d3 Filling the Filament's and Printer's Tabs. Finished. It's need to adding functions to work with presets 2017-12-26 18:12:05 +01:00
YuSanka
67f2469e70 Filling the Print's Tab. Finished. It's need to adding functions to work with presets 2017-12-26 18:12:05 +01:00
YuSanka
281fd26e06 Filling the Print's Tab. Continued. All Controls are on they own places. It's need to adding only SideWidget 2017-12-26 18:12:04 +01:00
YuSanka
67b9b1b273 Filling the Print's Tab. Continued. All labels are on they own places, but still without Controls 2017-12-26 18:12:04 +01:00
YuSanka
d60fac42d6 Start filling the Print's Tab, using @lordofhyphens's Optionsgroup 2017-12-26 18:12:04 +01:00
YuSanka
c5e21c1fbf First steps 2017-12-26 18:12:03 +01:00
Lukas Matena
180967484e Correction of wipe tower brim generation 2017-12-22 11:26:43 +01:00
bubnikv
5cf9cd5395 Bumped up the build version. 2017-12-21 21:07:43 +01:00
bubnikv
d9985c0575 Updated the initial presets for the MK3. 2017-12-21 20:15:51 +01:00
bubnikv
472946be32 Removed Original Prusa i3 MK3, MK2S, MK2 and MK2S-MMU.ini 2017-12-21 20:13:16 +01:00
bubnikv
48ba7e5f73 Removed dependency on Perl Encode::encode_utf8. 2017-12-21 20:11:19 +01:00
bubnikv
e71b021b6e Updated the bundled presets for the Prusa3D printers. 2017-12-21 19:26:29 +01:00
bubnikv
3addeb57b4 Fix of "Program crashes when [Suppress "- default -" presets:] is DISABLED"
https://github.com/prusa3d/Slic3r/issues/643
2017-12-21 19:19:07 +01:00
bubnikv
9d3ade81fa Fixed placeholder parser tests. 2017-12-21 17:27:24 +01:00
bubnikv
1eef6d3552 Improved error reporting of the PlaceholderParser. 2017-12-21 17:07:57 +01:00
bubnikv
f5160b7a72 Fixed "Slic3r crashes when sending STLs with special characters to the printer"
https://github.com/prusa3d/Slic3r/issues/597
The "Send to OctoPrint" function will now send the file name encoded
in UTF-8, so the file name will not get mangled.

The C++ Slic3r::encode_path() function was returning a string to Perl,
which was marked as UTF-8. This has been fixed, now encode_path() returns
a plain Perl string.

Added path_to_filename, path_to_stem, path_to_extension, path_to_parent_path
Perl wrappers to boost::filesystem::path splitting functionality
to be able to split UTF-8 encoded files on Windows correctly.
2017-12-21 16:56:33 +01:00
Lukas Matena
c6718c94bf Merge fix 2017-12-21 14:24:47 +01:00
Lukas Matena
4583d62edd Merge branch 'master' into wipe_tower_improvements 2017-12-21 13:47:33 +01:00
Lukas Matena
b7a326a550 First attempts of variable wipe implementation, sparse infill modified to sawtooth 2017-12-21 13:28:26 +01:00
bubnikv
1bf67b4b62 Added boost::regex to cmakelists. 2017-12-20 22:13:19 +01:00
bubnikv
fed5128b7f Reverted regex to boost::regex as the C++11 regex seems to be broken
on Linux/gcc 4.9.
2017-12-20 21:54:47 +01:00
bubnikv
8acd51fc62 Replaced boost::regex with std::regex. 2017-12-20 18:25:53 +01:00
bubnikv
b2ba4ee34c Fixes volumetric speed "Hint-Text" ignores "First Layer Speed"
and "Extrusion multiplier" #641
Implements first layer speed adjustments.
2017-12-20 14:51:18 +01:00
bubnikv
4572fe69de Fix of a regression update issue of the "modified" flag
at the active profile, specific to OSX.
https://github.com/prusa3d/Slic3r/issues/632
2017-12-20 13:46:43 +01:00
bubnikv
7142126609 Grey out the compatible_printers_condition edit field in case
the compatible_printers list is non empty.
Changed the precendence of compatible_printers_condition over
compatible_printers. Now compatible_printers has precedence.
2017-12-20 13:32:02 +01:00
bubnikv
c8d14fb617 The wipe tower generator does not call start_filament_gcode when
returning from a wipe tower and the particular wipe tower layer
is only sparsely filled without a tool change.
https://github.com/prusa3d/Slic3r/issues/642
2017-12-20 12:03:54 +01:00
bubnikv
558a0753c1 Improved loading of the config wizard results.
Fixed some updates of the "compatible with printer" flags
at the print and filament presets.
2017-12-20 11:28:16 +01:00
bubnikv
c49d6a3ec7 Try to fix the config wizard initialization on OSX.
There is an issue when the config wizard is started from the help
menu and the "other" workflow is followed without clearing
the user profile directory.
2017-12-19 21:43:24 +01:00
bubnikv
67c6823dde Fixed a regression bug in the display of a filament name on the print
controller tab.
2017-12-19 21:12:24 +01:00
bubnikv
c3468f2ad9 Fix of preset selection. 2017-12-19 20:58:16 +01:00
bubnikv
0b6bd3cbde Implemented a "Reset user profile" on the first page of the configuration
wizard if the wizard is opened from the menu. This allows one
to reinstall the bundled printer profile cleanly.

Fixed a bug when loading a config bundle as a config: The config bundle
should not be unpacked into the user profile directory.
2017-12-19 19:51:22 +01:00
bubnikv
5a768ddd7b Updated the bundled config profile with the new compatible_printers_condition. 2017-12-19 17:10:28 +01:00
bubnikv
a402b1b83d Implemented <,>,<=,>=,or,and,||,&& operators. 2017-12-19 16:48:14 +01:00
Enrico Turri
b2eb522f55 GCodeTimeEstimator - clean up unused code 2017-12-19 09:29:04 +01:00
bubnikv
6b81f43206 First implementation of the "compatible_printers_condition"
for the print and filament profiles.
Added documentation for building the boost library for Slic3r on Linux.
2017-12-18 15:07:38 +01:00
bubnikv
bb61de8379 Fixed a regression error: The "current_extruder" identifier was not set
at the placeholder parser.
Implemented a new PlaceholderParser::evaluate_boolean_expression()
functionality to evaluate just a boolean expression using the full
expressive power of the macro processing syntax. This function
will now be used for deciding, which print or filament preset
is compatible with which printer preset.
2017-12-18 12:14:09 +01:00
bubnikv
bbfb9a4190 Added regex matching operators to the conditional G-code processor
in a form similar to Perl:

Following expression returns true, if the variable matches the regex:
	variable =~ /regex/
Following expression returns true, if the variable does not match the regex:
	variable !~ /regex/
2017-12-15 17:14:24 +01:00
bubnikv
88e9ba510b Run the wizard from OnIdle routine to be executed first after the UI
is initialized. This is necessary for the UI to initialize correctly
on OSX.
2017-12-14 17:35:06 +01:00
bubnikv
4bbe328117 Config wizard will prompt user to copy the profiles from Slic3r to Slic3rPE
if the datadir is left to the default value (which is Slic3r),
and Slic3rPE directory exists.
2017-12-14 13:47:22 +01:00
bubnikv
d65835f89b Improvement of region classification numerical stability.
The Clipper library is not stable when calcuating offsets of contours
with holes. Replaced a single call of offset2 with offset_ex(offset_ex()).
This is not the most efficient solution, but it fixes this problem.
Fixes https://github.com/prusa3d/Slic3r/issues/456
2017-12-14 13:26:44 +01:00
bubnikv
eaaac8b2a4 Fixed a regression bug due to some Perl to C++ porting
of a configuration layer. Fixes https://github.com/prusa3d/Slic3r/issues/627
2017-12-14 11:35:38 +01:00
bubnikv
cdab27d337 Enabled a long wipe when moving away from the wipe tower
to reduce stringing.
2017-12-14 09:50:38 +01:00
bubnikv
d30c154e79 Reverted the introduction of the "presets" subdir to store
the print/filament/printer profiles.
The change has been reverted to support the upstream slic3r
using the --datadir. While there are breaking changes
in the PlaceholderParser, if the new macro processing is not used,
the two slic3rs are still mostly interchangeable.

The "presets" subdir may be enabled with the SLIC3R_PROFILE_USE_PRESETS_SUBDIR
and it may happen, that it will be activated one day if ever the two
slci3rs diverge too much.
2017-12-14 09:40:45 +01:00
Enrico Turri
0fe855cd6d Time estimate shown in GUI as formatted string / Write to file made by class GCode's private methods 2017-12-14 09:18:28 +01:00
bubnikv
08b74f8caf Fix of the wipe tower priming towers. The priming towers were printed
at the homing height on the MK2MM printer, not at the 1st layer height.
2017-12-13 15:35:00 +01:00
bubnikv
38ecfa8467 Updated the build instructions on OSX due to breaking changes caused
by the perlbrew system.
2017-12-13 15:03:14 +01:00
bubnikv
d47dc5da3e Fixed update of "dirty" profile when the "compatible_printers"
option appears (filter is active) or disappears (no filter active,
compatible with any printer).
2017-12-13 14:44:27 +01:00
bubnikv
898c697f13 Update the maximum volumetric flow hint at the filament page
when the page gets activated, so that the print & printer profile changes
are reflected immediately.
2017-12-13 14:12:47 +01:00
bubnikv
21b4e62e6e Fixed handling of print and filament presets incompatible
with the newly selected print profile,
fixed loading of print and filament tab pages after the print or filament
preset has been changed to be compatible with a newly selected printer.
2017-12-13 14:00:14 +01:00
bubnikv
91e847cb76 Yet another fix for https://github.com/prusa3d/Slic3r/issues/607.
Use EPSILON to match two layers by their floating point Z height.
2017-12-13 10:32:25 +01:00
bubnikv
673e98bc83 When the legacy OpenGL 1.2 is enforced, suppress anti aliasing as well.
Let's hope it will be a valid workaround for the reoccuring
buggy Intel HD Graphics driver issue.
2017-12-12 20:47:36 +01:00
Enrico Turri
20234c94ee GCodeTimeEstimator - added retract_acceleration, minimum_travel_feedrate members and process of M201 gcode 2017-12-12 13:44:52 +01:00
bubnikv
74cb74f1fc Increased maximum allowed temperature to 1500 centigrades as someone
is seemingly uses Slic3r to print glass :-)
https://github.com/prusa3d/Slic3r/issues/629
2017-12-12 13:43:36 +01:00
bubnikv
743fc9dbd0 Workaround for buggy Intel HD Graphics OpenGL drivers:
Fall back to OpenGL 1.1 by a "use_legacy_opengl" preferences switch.
https://github.com/prusa3d/Slic3r/issues/233
https://github.com/prusa3d/Slic3r/issues/268
https://github.com/prusa3d/Slic3r/issues/619
2017-12-11 18:00:51 +01:00
bubnikv
61e6f23ed2 Fix of
"Multimaterial printer switches filament at the wrong time during a print"
https://github.com/prusa3d/Slic3r/issues/607

There was a single layer between the raft top and the object first layer
missing on the wipe tower, and after this missing layer all the tool
changes were shifted by one layer, meaning two color print had the colors
switched.
2017-12-11 17:19:55 +01:00
Enrico Turri
e199d0532c GCodeTimeEstimator - added process of G92 gcode 2017-12-11 15:15:21 +01:00
Enrico Turri
34a0a2cb5e GCodeTimeEstimator - added process of M82 and M83 gcodes 2017-12-11 14:03:29 +01:00
Enrico Turri
50a45949d1 merge with master 2017-12-11 12:01:30 +01:00
Enrico Turri
bea9628be0 time estimation shown in GUI after gcode export 2017-12-11 11:11:54 +01:00
bubnikv
1938828520 Slic3r version was not set by the placeholder parser.
https://github.com/prusa3d/Slic3r/issues/615
2017-12-11 09:31:29 +01:00
Enrico Turri
a0a503e4a8 integration of time estimator into gcode export - save time estimation into gcode file 2017-12-11 09:06:29 +01:00
bubnikv
ae5863f5e0 Fixed a typo in a path to Resources on OSX. 2017-12-10 23:27:22 +01:00
bubnikv
679aa2822c Moved the Slic3rPE/print,filament,printer folders to
Slic3rPE/presets/print,filament,printer
to separate the presets from further data stored into the Slic3rPE
directory.
2017-12-10 22:11:00 +01:00
bubnikv
ca4bd96d5d Modification of Slic3r to search the icons in resources/icons
after they have been moved from var
2017-12-10 21:14:03 +01:00
bubnikv
455f9befbc Moved the icons and images from Slic3r/var to Slic3r/resources/icons
to simplify installation of application static data
(icons, images and printer profiles) onto a target system.
2017-12-10 20:51:45 +01:00
bubnikv
98fdb46da9 Added a first config bundle for the Prusa MK2 & MK3 machines. 2017-12-10 13:21:06 +01:00
bubnikv
657f2734f1 Extended the Config Wizard to offer a selection of config bundles
bundled with Slic3r installation, and install it into user's Slic3r profile.
These bundled config bundles will be contained in the Slic3r source
tree under Slic3r/resources/profiles.

Breaking change! The Slic3r user directory has been renamed to Slic3rPE
for the Prusa Edition. Also it is likely, that the Slic3rPE directory
will be reorganized before the final 1.38 release to reserve space
for temporary profiles downloaded from the Internet.
2017-12-10 13:19:44 +01:00
bubnikv
9a80ff57b2 Improved robustness of handling preset files stored into a wrong location.
Fixes https://github.com/prusa3d/Slic3r/issues/616
2017-12-09 18:48:21 +01:00
bubnikv
8509e4b5f5 Fixes regression error introduced in Slic3r 1.38.2:
Slic3r 1.38.3 gcodes not building up bed temperature
https://github.com/prusa3d/Slic3r/issues/614
2017-12-09 16:39:49 +01:00
bubnikv
f0e154d54c Bumped up the build version. 2017-12-09 15:49:43 +01:00
Enrico Turri
092d271fa2 time estimator wip stage 2 2017-12-08 10:50:36 +01:00
Lukas Matena
87c67636df Extrusion flow calculation based on nozzle diameter etc 2017-12-07 11:59:14 +01:00
bubnikv
75dcdb84b1 Fix of a crash due to the way how the presets are sorted and searched
for in the PresetCollection: The 1st preset is always the "-- default --"
even if there are some presets starting with an ASCII character lower than '-'.
https://github.com/prusa3d/Slic3r/issues/603
2017-12-06 16:47:53 +01:00
Enrico Turri
bc3d184d7c time estimator wip 2017-12-06 14:12:10 +01:00
bubnikv
2eeca93a97 Feature Request: Add to Plater: Ctrl+O
implements https://github.com/prusa3d/Slic3r/issues/379
thanks @alexrj
2017-12-05 20:06:19 +01:00
qtux
b0f84c5cb2 Add used filament length to the "Sliced Info" box (#585) 2017-12-05 19:05:49 +01:00
bubnikv
7892dfd53c Fixed a regression bug in G-code export, where ferror was called on
released FILE structure.
2017-12-05 18:40:46 +01:00
bubnikv
0a2be9d7bf Fixed compilation on unices. 2017-12-05 17:52:12 +01:00
bubnikv
c34ec9b7d3 PlaceholderParser: Improved error reporting https://github.com/prusa3d/Slic3r/issues/600
Fixed '+' operator for strings.
2017-12-05 17:38:29 +01:00
bubnikv
8746f84fa2 Improved error reporting of the PlaceholderParser.
The PlaceholderParser is currently used by the GCode.cpp
and by Printer.cpp to generate a new name for the exported G-code or SVG file.
The PlaceholderParser::process() will throw a runtime_error with
a comprehensive error message.
The G-code export will include these error messages into the G-code text
with !!!!!! separators, and the GUI will inform the user, that the G-code
export failed.
2017-12-05 15:54:24 +01:00
Lukas Matena
c34fd10e23 Wipe tower rotation around center point 2017-12-05 11:25:38 +01:00
bubnikv
1244fd09eb More efficient utf8 parser for the PlaceholderParser. 2017-12-04 18:22:42 +01:00
bubnikv
fb1bebd982 PlaceholderParser: simplistic extension to parse UTF8 characters
in the G-code and string constants.
Solves https://github.com/prusa3d/Slic3r/issues/600
2017-12-04 17:42:35 +01:00
bubnikv
2b0b8e6e68 Removed the hard-coded priming line when
both single_extruder_multi_material and wipe_tower are enabled,
and the print prints with a single extruder only.

Newly the same situation will be handled through a conditional G-code
in the following format:

{if not has_wipe_tower}
; Do the priming
{endif}
2017-12-04 11:57:54 +01:00
bubnikv
8af329e660 Added Perl to C++ interfaces for creating the preset editor pages
from C++ and to add debugging menus from C++. These lightweigth
interfaces should help new team members to hack the UI without
a Perl knowledge.
2017-12-04 10:48:40 +01:00
bubnikv
16bd3fc624 Fixed an extruder ordering bug on the 1st layer wipe tower.
This is a regression after introducing the extruder priming areas
at the edge of the print bed.
2017-12-03 09:43:00 +01:00
bubnikv
73a539780a Bumped up a version number. 2017-12-01 18:56:32 +01:00
bubnikv
ca0626b168 Fixed regression bugs regarding print validation,
fixed crashes when loading a config.ini with "compatible_printers"
disabled export of "compatible_printers" into gcode and config.ini

Enabled compatibility of printing multiple objects with support / no support
with a wipe tower.
2017-12-01 18:55:57 +01:00
Lukas Matena
cb84a6cfce Wipe tower rotation - bug fix (now returning start_pos correctly) 2017-12-01 11:10:01 +01:00
bubnikv
354408c7e6 Load the wxWidgets PNG handler only once. 2017-11-30 20:25:59 +01:00
bubnikv
a0268a1906 Some other accelerator keys were not displayed on Linux and OSX correctly.
Suppress them on these systems.
2017-11-30 20:13:05 +01:00
bubnikv
752d72f58d Increased fill rate of the support 1st layer from 50% to 70%. 2017-11-30 19:04:07 +01:00
bubnikv
91e1dc639d Fix of the preceding cherry pick. 2017-11-30 19:00:26 +01:00
Joseph Lenox
488feb2335 Added --no-gui flag to force CLI usage (allows for CLI usage with AppImage build).
Forced --gui flag in AppImage build.
2017-11-30 18:42:31 +01:00
bubnikv
d161d4f78c There is a hack applied to add accelerator keys to the menu
without being registered. Unfortunately this hack works on wxWidgets
on Windows. On OSX or Linux, a warning is emited and no accelerator
key is shown on the menu.
This commit just removes the warnings, it does not add the menu accelerators.
https://github.com/prusa3d/Slic3r/issues/539
2017-11-30 18:26:15 +01:00
bubnikv
cecaf6eabc Slight optimization of the filament_start_gcode insertion:
It is not needed between the purging towers and the wipe tower brim.
2017-11-30 17:55:39 +01:00
bubnikv
a617e02ae6 New hot key for auto arrange: 'a'. 2017-11-30 17:45:03 +01:00
bubnikv
bff7065360 Fixed a bug in the support generator: There was half extrusion width
gap created between the support and the support sheath.
Now the support sheath will overlap with the support base by 10%
of the extrusion width by default.
2017-11-30 16:24:48 +01:00
Lukas Matena
55570119f7 Correction of previous commit 2017-11-30 16:11:20 +01:00
bubnikv
3996535e5d Changed handling of filament_gcode_start and filament_gcode_end custom
G-codes in case of single extruder multiple material setup:
At the start of the print, the filament_gcode_start is executed
for the active extruder only, and the filament_gcode_start /
filament_gcode_end are then executed at each tool change.

When the Prusa MM wipe tower is active, the tool changes are handled
a bit differently: M900 K0 is emited before the wipe tower extrusions start,
and the filament_gcode_start code is executed after the wipe tower extrusions
are done. This rule effectively disables the linear advance over the wipe tower.

Implements https://github.com/prusa3d/Slic3r/issues/568
2017-11-30 16:01:47 +01:00
bubnikv
8807d288d7 Fixed a regression issue when starting Slic3r with non-existent datadir. 2017-11-30 15:51:51 +01:00
Lukas Matena
a733df8f37 Wipe tower rotation - preview box 2017-11-30 14:43:47 +01:00
bubnikv
830da1f8e4 Fixed a regression bug of handling the obsolete config parameters,
causing crashes.
2017-11-30 13:43:02 +01:00
Lukas Matena
2921302fe9 GUI integration of rotation angle setting 2017-11-30 12:08:22 +01:00
bubnikv
3813402aa3 Merge branch 'master' into wipe_tower_improvements 2017-11-30 10:33:52 +01:00
bubnikv
6aff27f3ab Moved initialization of Slic3r XS datadir variable to GUI.pm
Solves https://github.com/prusa3d/Slic3r/issues/594
2017-11-30 10:22:39 +01:00
bubnikv
2f54bf5bca Fixed a random crash in the PlaceholderParser due to deallocating
an undefined pointer.
2017-11-29 20:38:19 +01:00
bubnikv
f754cb422b Bumped up the version number. 2017-11-29 19:34:24 +01:00
bubnikv
ae118519ab Fixed a 32bit build bug in the new PlaceholderParser macro processor. 2017-11-29 19:27:26 +01:00
Eyal
da8ffd477d Missing prerequisites in Build.PL (#593)
I was unable to compile without ExtUtils::XSpp and ExtUtils::Typemaps .

My platform is a fresh install of OctoPi on Raspberry Pi.

I'm not sure what the `0` in those lines does.
2017-11-29 16:57:21 +01:00
bubnikv
6729dc1c6d Fixed a failing PlaceholderParser test case. 2017-11-29 16:35:48 +01:00
bubnikv
08e81f2765 Bumped up the build version. 2017-11-29 10:52:54 +01:00
bubnikv
0ddbfccb08 Added some test cases for the conditional G-code math calculator.
https://github.com/prusa3d/Slic3r/issues/438
2017-11-28 19:56:32 +01:00
Lukas Matena
0e9e487930 First implementation of wipe tower rotation 2017-11-28 17:32:11 +01:00
bubnikv
9ca63f16bc New PlaceholderParser variable for sequential prints:
current_object_idx - zero based index of the object printed.
Implements feature request https://github.com/prusa3d/Slic3r/issues/578
2017-11-28 15:30:05 +01:00
bubnikv
672194b475 Ported the between_objects_gcode custom G-code blocks,
thanks @lordofhyphens, https://github.com/alexrj/Slic3r/pull/3275

Improved handling of custom G-code blocks: Slic3r will try to extract
the target extruder and bed temperatures from the custom G-code blocks.
2017-11-28 15:19:57 +01:00
bubnikv
f58b217369 Implemented loading of a Slic3r Config Bundle as a Slic3r Config file. 2017-11-28 11:57:33 +01:00
bubnikv
3c0cd3cbc8 Improve error handling of loading Slic3r profiles. 2017-11-28 10:08:01 +01:00
bubnikv
bb2b180ecc Fixed G-code export of custom G-code sections to not add a newline
if the custom G-code already ends with a newline.
2017-11-26 21:23:18 +01:00
bubnikv
b54a15faa2 Fix of the new PlaceholderParser: Maintain whitespaces and new lines. 2017-11-26 20:43:31 +01:00
bubnikv
571d654e67 Placeholder parser - added a comment with a reference to a C grammar. 2017-11-26 11:52:44 +01:00
bubnikv
5c3ba79c6f PlaceholderParser - added an unary not operator. 2017-11-26 11:16:28 +01:00
bubnikv
2312fa845e Fixed compilation on GCC, changed to handle keywords correctly. 2017-11-26 10:54:54 +01:00
bubnikv
708f416c84 PlaceholderParser extended with {if}/{elsif}{else} blocks and
+ - * / == != <> numeric expressions.
2017-11-26 09:59:14 +01:00
bubnikv
9205c8aab4 Sketch of the PlaceholderParser if/elsif/else macro. 2017-11-17 18:46:03 +01:00
bubnikv
47f193fe2d The PlaceholderParser has been rewritten to use
a real boost::spirit::qi parser, accessing the DynamicConfig repository
directly. This is a first step towards a full fledged expression
interpreter.
2017-11-17 11:15:46 +01:00
bubnikv
200f176951 Fixed compilation on Linux / GTK 2017-11-10 18:50:14 +01:00
bubnikv
4628308415 Oh those compiler differences. 2017-11-10 17:42:30 +01:00
bubnikv
bfce6dba9b Integrated the "compatible printers" idea by @alexrj with Vojtech's twist:
The incompatible presets are hidden in the tabs if show_incompatible_presets
is false. If show_incompatible_presets is true, there is a button to
show / hide the incompatible presets from the tab selector.
2017-11-10 17:27:05 +01:00
bubnikv
b23b9ea1d2 Implemented volumetric flow rate hints,
removed some C++11 conditioned compilation. Slic3r now requires C++11.
2017-11-09 15:10:20 +01:00
bubnikv
9a0100d6de Initial definition of PresetHints C++ class and Perl binding, ported the cooling logic hints to C++.
Removed Perl Flow::new_from_spacing bindings.
Some Fill C++11 beautification.
Fix of a support_material_1st_layer_flow, brim_flow and skirt_flow logic to use the extrusion_width if both first_layer_extrusion_width and support_material_extrusion_width are undefined.
Documented the extrusion width logic in the config tooltips, including the default values.
2017-11-09 10:48:06 +01:00
bubnikv
5fb54ed1f3 Code beautification: PrintConfig tooltips were split to multiple lines. 2017-11-09 10:06:25 +01:00
bubnikv
e4614f301c ConfigBase with option template to do the type conversion
of resolved ConfigOption.
2017-11-09 10:05:37 +01:00
bubnikv
71b58e24a9 Fixed a regression bug in the "first layer extrusion width" G-code comment.
https://github.com/prusa3d/Slic3r/issues/566
2017-11-06 15:43:56 +01:00
bubnikv
e6ecb77d9a Fixed loading of configs and configs from g-codes. 2017-11-03 19:14:33 +01:00
bubnikv
b11d9708ed Updated Controller after the presets C++ port. 2017-11-02 21:51:06 +01:00
bubnikv
dd9e1aff70 When loading Slic3r.ini of older Slic3rs, remove the .ini suffix
from the preset names.
This fixes https://github.com/prusa3d/Slic3r/issues/367
2017-11-02 17:31:24 +01:00
bubnikv
ee84e1773d Fixed an incorrect comment separator in generated g-code. 2017-11-02 16:50:08 +01:00
bubnikv
4ab4a9afe8 Fighting with boost::filesystem::directory_iterator 2017-11-02 16:40:25 +01:00
bubnikv
7551006102 Another fix or Unices of the previous commit. 2017-11-02 16:35:46 +01:00
bubnikv
df5628422c Fixed serial port enumeration on non-Win32 systems. 2017-11-02 16:29:03 +01:00
bubnikv
e8b6d92d4d Looks like the reworked C++ preferences start to work again. 2017-11-02 16:21:34 +01:00
bubnikv
95c284c764 Next step of Perl to C++ configuration layer conversion. 2017-11-01 19:30:05 +01:00
bubnikv
337f6c5808 Deleted the config-bundle-to-config.pl tool, it will be replaced
with direct loading of a config bundle as a config file the same way
it has been done for the config from a G-code.
2017-10-30 18:55:31 +01:00
bubnikv
d564fc95df Split Preset.cpp,hpp to Preset.cpp,hpp and PresetBundle.cpp,hpp 2017-10-30 18:41:50 +01:00
bubnikv
1fee3633a0 New C++ class AppConfig for maintaining the config.ini
New helper function for generating a unified "generated by slic3r" header.
2017-10-30 18:15:41 +01:00
bubnikv
835e5b71a8 Reduce UI flicker. 2017-10-28 00:18:02 +02:00
bubnikv
857b78ddca Fix of the previous commit: Slic3r::Config::new_from_defaults_keys
has to be provided with a reference to array of strings.
2017-10-27 22:49:59 +02:00
bubnikv
21633bc0ba throw std::invalid_argument instead of std::exception 2017-10-27 21:28:39 +02:00
bubnikv
2455aee97c Further reduction of Perl Config.pm methods. 2017-10-27 18:52:35 +02:00
bubnikv
3bc79e80d5 Fixed configuration & validate C++ ports. 2017-10-27 16:11:06 +02:00
bubnikv
5a99e694ce Another step towards the C++ presets. 2017-10-26 17:17:39 +02:00
bubnikv
ee645007f2 Another step towards C++ presets. 2017-10-25 12:53:31 +02:00
bubnikv
7308017ee8 Added the AGPL v3 license file 2017-10-21 16:09:25 +02:00
bubnikv
fe0bf6ebf3 Optimization of Perlglue ConfigBase__get 2017-10-18 14:26:38 +02:00
bubnikv
d9d6d996e9 Utility functions to pass wxWidgets pointers from Perl to C++ code.
C++ var_dir / set_var_dir() interface to access the UI resources
from the C++ code.
2017-10-17 20:00:15 +02:00
bubnikv
af51220f34 Fix of preceding commit. 2017-10-17 19:41:04 +02:00
bubnikv
b9d57483d8 perglue.cpp - use static_cast instead of dynamic_cast if possible,
use switch instead of plenty of ifs,
export clone<DynamicPrintConfig> to Perl XS.
2017-10-17 19:19:41 +02:00
bubnikv
746afbd790 Yet another compilation fix? 2017-10-17 18:49:07 +02:00
bubnikv
9a7d1bb566 Another compilation fix. 2017-10-17 18:41:54 +02:00
bubnikv
de2c6a2a3d exception what() method shall be noexcept. 2017-10-17 17:53:16 +02:00
bubnikv
67ce4d862b One more fix of the preceding commit. 2017-10-17 17:48:04 +02:00
bubnikv
38aca5047f Fix of the preceding commit for gcc & clang:
Add a class name suffix to the s_cache static members
of the StaticPrintConfig derived classes.
2017-10-17 17:37:03 +02:00
bubnikv
3731820c48 Optimization of the configuration layer:
The values of StaticPrintConfig derived objects were searched by a name
walking through a huge chained if.
Now they are being mapped with a std::map.
Also initialization of StaticPrintConfig classes from their ConfigOptionDef
defaults is done by maintaining a single global definition of each
StaticPrintConfig derived class, and a new instance is initialized
from this static copy.

Also the ConfigOption instances are casted using static_cast
wherever possible, and their types are verified by a virtual type() method.
This approach avoids insiginificant performance penalty of a dynamic_cast.

Also the compare and clone methods were added to ConfigOption,
and the cloning & compare work on binary values, not by serialization.
2017-10-17 16:01:18 +02:00
bubnikv
a91d7cb2f7 Redefined the ==, != operators of Point and BoundingBox classes
to become members of their respective classes to avoid type clashes
through implicit casting operators of ConfigOption classes.
2017-10-17 14:36:30 +02:00
bubnikv
a191fbbec8 Fix of a 3D print path preview for the wipe tower: Calculate
the bounding boxes accurately.
2017-10-04 13:50:04 +02:00
bubnikv
5a844c91f1 When executing G-code post-processing scripts written in perl on windows,
run the perl interpreter, which was used to run the Slic3r.
https://github.com/prusa3d/Slic3r/issues/514
2017-10-03 17:05:47 +02:00
bubnikv
a830a3c161 Fixes the scene disappearing when there are no Prusa MM priming towers. 2017-10-03 14:15:00 +02:00
bubnikv
e719e48a84 Fixed a bug in the temperature handling of the Prusa Multi Material
priming towers.
2017-10-03 13:43:34 +02:00
bubnikv
eb0117b1c1 Fix of https://github.com/prusa3d/Slic3r/issues/492
When a layer contained the support interface only, it was errorneously
printed with the support base material.
2017-10-03 13:22:37 +02:00
bubnikv
9898024ce9 admesh: changed header_num_facets to uint32 2017-10-03 12:41:53 +02:00
bubnikv
1958673806 Fixed the cubic infill: The cubic infill was 30% flatter than it should
have been.
2017-10-03 11:29:13 +02:00
bubnikv
a52a04550e Big endian fix, thanks to @hyperair for hints and initial implementation. 2017-10-03 10:57:16 +02:00
bubnikv
84d4bf8fdb Load presets into the new C++ class. 2017-10-02 17:35:00 +02:00
bubnikv
b1e3b0cdf9 Further fixes of the previous commit. 2017-09-20 10:16:00 +02:00
bubnikv
8089631f10 Fix of the previous commit: Fix compilation on Linux. 2017-09-20 10:03:53 +02:00
bubnikv
473233019c Initial partial implementation of presets in C++. 2017-09-19 13:55:48 +02:00
bubnikv
b58756f38b A bit of refactoring and beautification. 2017-09-18 10:01:37 +02:00
bubnikv
e16f827223 Ported PrintConfigBase::_handle_legacy from Perl to C++,
merged from upstream Slic3r, thanks to @alexrj.
2017-09-18 09:56:48 +02:00
bubnikv
cd084a33c6 Fixed a regression bug, which was made during the porting of
discover_horizontal_shells() fron Perl to C++, where
the already calculated bridge direction was being lost.

Improved constness of the debug methods
    void export_region_slices_to_svg(const char *path) const;
    void export_region_fill_surfaces_to_svg(const char *path) const;
2017-09-14 13:15:32 +02:00
bubnikv
630b746cab Fix a lag when starting to move a platter object.
The fix is done by disabling the print out of a model statistics,
which runs the model fixing twice.
2017-09-14 09:06:14 +02:00
bubnikv
777dc8c48b Fixed a missing bbox.defined=true assignment. 2017-09-13 15:52:51 +02:00
bubnikv
e2a169b0e5 Changed the G-code protocol for cleaning up the priming towers
for the multi material prints.
2017-09-13 13:27:49 +02:00
bubnikv
83b5b9e660 Set a missing bbox.defined flag. 2017-09-13 10:28:02 +02:00
bubnikv
6b2b279889 Fix of "exponentional values generated as G1 F-1.95058e+006 causing problems"
https://github.com/prusa3d/Slic3r/issues/463
2017-09-12 18:20:06 +02:00
bubnikv
98408bbed0 Fixed a crash when slicing leads to no print.
Fixed a bug in TriangleMesh::bounding_box().
2017-09-12 16:48:44 +02:00
bubnikv
b08d6f1969 The last priming area is shortened and the excess wipe is moved
into the wipe tower if there is enough space inside the wipe tower.
2017-09-12 15:55:38 +02:00
bubnikv
6d4ec5c989 Further fix of https://github.com/alexrj/Slic3r/issues/4085
making it safe in case wxWidgets do not report supporting multisampling,
but the OpenGL context actually does and it leaves the multi-sampling enabled.
This then may in theory lead to incorrect picking by color.
2017-09-12 10:14:24 +02:00
bubnikv
888a904c9b Workaround of
"GL_MULTISAMPLE and GL_ARRAY_BUFFER_ARB messages on failed launch"
https://github.com/alexrj/Slic3r/issues/4085

Also fixes
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872273
2017-09-12 10:03:10 +02:00
bubnikv
100c8f60a5 Added GCode/PrintExtents.cpp,h
Added a check for a collision between the multi material priming
regions with the rest of the print.
2017-09-12 09:01:48 +02:00
bubnikv
748c1ab1de Merge branch 'master' of https://github.com/prusa3d/Slic3r 2017-09-11 09:58:54 +02:00
bubnikv
fd3b474a63 Merges https://github.com/prusa3d/Slic3r/pull/509 2017-09-11 09:58:41 +02:00
eyal0
d903af5373 Many warnings fixed (#510)
Thanks
2017-09-11 09:49:59 +02:00
bubnikv
836dd98113 CMake build system: Adding -fext-numeric-literals when compiling with gcc.
This should fix https://github.com/prusa3d/Slic3r/issues/500
2017-09-11 09:20:22 +02:00
bubnikv
93774087f1 Fixed typo from the previous commit. 2017-09-04 13:55:56 +02:00
bubnikv
2c5304a520 Implemented an initial priming line for a single-material print
on a Prusa Multi-Material printer.
2017-09-04 13:51:05 +02:00
bubnikv
29d9a1e810 Fixed a default locale on Windows for UTF normalization. 2017-09-04 10:34:51 +02:00
bubnikv
b35f5780dc Fixed compilation on OSX & LInux 2017-09-04 10:14:56 +02:00
bubnikv
b610866d77 Implemented priming of all the filaments of the Prusa Multi Material. 2017-09-01 17:30:18 +02:00
bubnikv
247070cd82 Fixed a regression bug of Slic3r::encode() / decode() 2017-08-30 14:57:13 +02:00
bubnikv
dcbc28fd49 Fixed ReleaseWithDebugInfo build. 2017-08-30 14:55:45 +02:00
bubnikv
38e35cefc7 Removed the Perl Build.PL for the XS module. This has been replaced
by the CMake based build system.
2017-08-30 10:03:32 +02:00
bubnikv
4bd694e205 CMake build process: Fixed build on OSX: renamed XS to XS.bundle 2017-08-29 16:37:46 +02:00
bubnikv
6688d6c590 CMake build system: Link perl library on windows only. 2017-08-29 12:41:59 +02:00
bubnikv
c0a9c67632 CMake build system: Fix on older linux? 2017-08-28 23:17:24 +02:00
bubnikv
ff4e8d94c0 CMake build process: Workaround for an old CMake on Linux. 2017-08-28 23:11:43 +02:00
bubnikv
d5c2c252a5 CMake build process: Fix of the Perl Alien::Wx querying script. 2017-08-28 22:23:21 +02:00
bubnikv
0cb491e135 CMake build process:
Added the "test" target to execute the perl prove unit / integration tests.
Added a post-build step to copy the XS.dll & Slic3r/XS.pm to local-lib.
2017-08-28 19:11:16 +02:00
bubnikv
cf2f29a5f1 reverted a regression bug in the Perl Wx module minium version
https://github.com/prusa3d/Slic3r/issues/468
2017-08-28 15:59:26 +02:00
bubnikv
48f826c2c5 Disabled a limit of the nozzle diameter 0.4mm for the Prusa Wipe Tower.
Allowed scaling of the extrusion amount over the Prusa Wipe Tower
for layer heights over 0.2mm.
2017-08-28 14:57:00 +02:00
bubnikv
61b89865ff Fixed a regression bug (bundling of multiple STLs into a single model). 2017-08-28 14:54:46 +02:00
Vojtech Bubnik
3469bb2ea6 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2017-08-18 14:18:42 -07:00
Vojtech Bubnik
81e2c6f2db CMake build system: Made the Release build default 2017-08-18 14:18:27 -07:00
Vojtech Bubnik
85ffbf1f57 Merged 2017-08-18 22:47:26 +02:00
Vojtech Bubnik
d0c43c99c3 CMake build system: Linux fixes 2017-08-18 22:45:24 +02:00
Vojtech Bubnik
9620596d59 CMake build system - fixes for OSX. Now a working XS.bundle is being generated. 2017-08-18 13:06:10 -07:00
bubnikv
ba1c0b0137 CMake build process - fixes of the previous check-ins to build
cleanly on Windows & Linux. There is still a work on OSX:
The XS module has to be linked without perl.lib and with
the following parameters to produce a bundle: -bundle -undefined dynamic_lookup
2017-08-18 21:09:53 +02:00
bubnikv
e2a685b8bb CMake build system: Fixes for OSX. 2017-08-18 16:59:36 +02:00
bubnikv
3dbc93c663 CMake: Aadd local-lib to PATH and PERL5LIB environment variables,
so the locally installed modules (mainly the Alien::wxPerl) will be reached.
2017-08-18 14:34:54 +02:00
bubnikv
cb1bc0aaf8 CMake build system, initial placeholder for slic3r C binary. 2017-08-18 13:32:35 +02:00
bubnikv
428b7d3f9d CMake: Added all header files to the particular libraries. 2017-08-18 12:41:01 +02:00
bubnikv
2a3d2fb8c1 CMake: Split the globs into separate libraries. 2017-08-18 11:39:24 +02:00
bubnikv
401059066e Switched to Perl local::lib for local compilation.
Taken from upstream Slic3r, thanks @alexrj.
2017-08-18 09:58:50 +02:00
Vojtech Bubnik
952ca18bf9 Modified to compile on Ubuntu 2017-08-17 19:43:14 +02:00
bubnikv
94483202ec CMake build system: Always use the system libexpat on Linux. 2017-08-17 18:33:15 +02:00
bubnikv
c0f099c2cf CMake conversion, further steps: Now it compiles on Visual Studio 2013. 2017-08-17 18:27:51 +02:00
bubnikv
bb36e78428 Further CMake integration, split the xs CMakeFiles.txt to
FindAlienWx.cmake and FindPerlEmbed.cmake for easier Perl integration.
2017-08-17 13:30:46 +02:00
bubnikv
5673205d2e Initial implementation of a CMake build system for the Slic3r XS module.
Based on https://github.com/CReimer/Slic3r/tree/makefile_pr
Big thanks to @CReimer for his huge effort.
2017-08-16 19:05:08 +02:00
bubnikv
507f2ff45e Comprimed the previous pull request. 2017-08-14 12:56:09 +02:00
redPrint7
fdc7036fe3 Update WipeTowerPrusaMM.cpp (#464)
Resolves compile error on Win XP / Win 7 with native toolchain MinGW32-w64 on perl 5.26 or Citrusperl 5.24.
2017-08-14 12:54:19 +02:00
bubnikv
a2b876e261 Fixing a crash on pressing +/- with no object active.
https://github.com/prusa3d/Slic3r/issues/467
2017-08-14 12:50:35 +02:00
bubnikv
3b54b68b59 Merged new methods for handling menus with icons,
merged "Use submenus for listing options in dropdown menu." #3905
thanks @alexrj
Adapted the "Use submenus" code to sort the menus in the same order
as they appear in the parameter tabs.
2017-08-04 16:28:01 +02:00
bubnikv
632bf56f29 merged save_window_pos / restore_window_pos from @alexrj Slic3r. 2017-08-04 15:54:12 +02:00
Alessandro Ranellucci
38e713c23c Remember object settings dialog size and position. #3943 2017-08-04 15:45:10 +02:00
bubnikv
8d5e5519f2 Fix of compilation on Windows 32bit: Include windows.h for the declaration
of MultiByteToWideChar.
2017-08-03 19:49:41 +02:00
bubnikv
ed46cfa19d Simplified the code base by requiring wxWidgets >= 3.0 2017-08-03 17:47:18 +02:00
bubnikv
1385018724 Unicode handling:
Removed the Perl dependencies on Encode, Encode::Locale and Unicode::Normalize.
Added dependency on boost::locale.
Added encode_path, decode_path, normalize_utf8 functions to Slic3r.xs

Slic3r.xs has been made mostly utf8 safe by using the boost::nowide library,
thanks to @alexrj for the idea.

Simplified the encode_path / decode_path stuff:
wxWidgets are unicode already, so there is no need to decode_path() from it.
Perl / win32 interfacing is non-unicode, so decode_path() is executed
on ARGV just at the beginning of the perl scripts.
2017-08-03 17:31:31 +02:00
bubnikv
31085fb1d7 Ported some ModelObject methods from Perl to C++.
Added some utility functions to TriangleMesh, thanks to @alexrj
Some porting to C++ based on work by @alexrj.
2017-08-02 16:05:18 +02:00
bubnikv
777023c7a8 Ported PrintObject::prepare_infill & combine_infill from Perl to C++. 2017-08-02 14:24:32 +02:00
bubnikv
933d5b261a Fix of a "Scale to Size" dialog, where a bed size is shown scaled. 2017-08-01 14:42:59 +02:00
bubnikv
71f99423c5 New feature: Bridging angle override through a bridge_angle config
variable. When set to zero, the usual automatic bridge detection applies.
The bridging angle override may be set at the Infill->Advanced settings,
or through a modifier mesh.
2017-07-31 16:23:52 +02:00
bubnikv
75c72bc59b Fix of "MM incorrect extruder temperature"
https://github.com/prusa3d/Slic3r/issues/443

Change of the PlaceholderParser:
All vector configuration values stored into the PlaceholderParser
are expected to be addressed by the extruder ID, therefore
if a vector configuration value is addressed without an index,
a current extruder ID is used.

Also a small fix of fan handling: The fan speed is set to zero
at the start of the G-code if the cooling for the initial extruder
is disabled.
2017-07-31 15:42:55 +02:00
bubnikv
7181f5d163 PrusaControl file format: Added multi-material support. 2017-07-28 15:48:49 +02:00
bubnikv
812a2c7cbd Further implementation of FillRectilinear3. 2017-07-28 15:47:59 +02:00
bubnikv
137aab9631 Fixed compilation on Linux 2017-07-27 13:21:48 +02:00
bubnikv
a6ea01a23f Moved some math macros (sqr, lerp, clamp) to libslic3r.h
Added UNUSED macro to libslic3r.h, used it to reduce some compile warnings.

Split the Int128 class from Clipper library to a separate file,
extended Int128 with intrinsic types wherever possible for performance,
added new geometric predicates.

Added a draft of new FillRectilinear3, which should reduce overfill near the perimeters in the future.
2017-07-27 10:39:43 +02:00
bubnikv
3b51f64411 Fixing https://github.com/prusa3d/Slic3r/issues/432
Slic3r GUI not starting, error when using --gui (on linux)

Implements https://github.com/prusa3d/Slic3r/issues/407
Shortcuts: Movement in 3D Space
Assignment of the camera shortcuts is clear from the menu accelerators.

Implements https://github.com/prusa3d/Slic3r/issues/406
Shortcuts: Rotate +/- 45 degrees
l/r keys rotate the object

Also changed the accelerators for adding / removing duplicates from
Ctrl++/- to plain +/-, from Ctrl-Del to plain Del,
and added an 's' key accelerator for uniform scaling.
2017-07-21 16:29:40 +02:00
bubnikv
969e3f4a80 Fixed "Fill angle of any number other than an Integer does not work"
https://github.com/prusa3d/Slic3r/issues/427
Also enabled floating point rotation angle for supports.
2017-07-20 13:38:10 +02:00
bubnikv
7103fa78ff Reverted back width of the tree control on the Tab panels.
Fixes https://github.com/prusa3d/Slic3r/issues/428
2017-07-20 13:09:02 +02:00
bubnikv
afd5d9eff3 Fixed issues with undefined filament color preview values. 2017-07-20 13:02:12 +02:00
bubnikv
6bb773d0dd Prusa MM Wipe Tower, Improvements of the 1st layer:
Thiner priming line along the wipe tower,
relatively thick infill at the 1st layer to improve adhesion.
2017-07-20 12:58:51 +02:00
bubnikv
aaefb76888 Fixed test cases after change of the "sane" extrusion widths.
Changed the default perimeter / infill overlap to 25%.
2017-07-20 11:03:54 +02:00
bubnikv
ac672d9dc5 Changed the default "sane" extrusion width parameters to
1x nozzle_dmr for support and top infill,
and 1.125x nozzle_dmr for the rest.
This corresponds roughly to the default values tuned for the Prusa MK2
for normal prints.
2017-07-19 16:06:29 +02:00
bubnikv
2f2c0ddc99 Refactored Fill / Flow for readability.
Added an "overlap" member variable to fill classes in the preparation
for futher move of the "infill / perimeter" overlap to the Fill class.
Moved the orientation predicates from Fill to Geometry.
2017-07-19 15:53:43 +02:00
bubnikv
9c1b1829cf PerimeterGenerator - a bit of refactoring for readability. 2017-07-19 15:42:49 +02:00
bubnikv
81823fe7df Reduced the content of Geometry.pm, removed unused Perl subroutines.
Reduced the use Slic3r::Geometry and use Slic3r::Geometry::Clipper
clauses to only reference used subroutines.
2017-07-19 10:45:39 +02:00
bubnikv
2c82a327dd Fix of "Wipe Tower ... only supported ... .4 nozzle" error when slicing
a non .4mm nozzle single extruder (Stock MK2S) print
https://github.com/prusa3d/Slic3r/issues/426

The constraint for the "Wipe Tower" checkbox has been raised, so
one will get this error message only if the printer settings has more
than one extruder configured, as the wipe tower does not get generated
for a single extruder print.
2017-07-17 09:07:18 +02:00
bubnikv
ed73f0b6ef Fix of "Modifier meshes don't work for speed modifications"
https://github.com/prusa3d/Slic3r/issues/298
2017-07-14 17:30:54 +02:00
bubnikv
40a882d01e Experimental feature, which may make the Clipper offsets run faster
due to avoiding the 128bit multiply operations:
A filtered predicate is tried to calculate SlopesEqual()
to minimize the invocation of 128bit multiply operations.
2017-07-13 15:52:19 +02:00
bubnikv
bd93d2f334 Fix of "Cooling fan problem Slic3r 1.35.5.16 "
https://github.com/prusa3d/Slic3r/issues/418
This is a regression of the cooling buffer changes done for multi-material
(supporting different cooling settings for different filaments)
2017-07-13 12:11:00 +02:00
bubnikv
c9325338a8 Fixed "upscaled objects cannot be cut above original height"
https://github.com/prusa3d/Slic3r/issues/419
2017-07-12 23:28:11 +02:00
bubnikv
3a813aaef6 Implemented "Suggestion for Preview View Change"
https://github.com/prusa3d/Slic3r/issues/415

Use left / right keys to switch between the low / high layer scroll bars
on the 3d preview screen.
2017-07-11 18:21:25 +02:00
bubnikv
6f28818f87 Fix of
"Unicode char like for example "ł" crush app when used in profile name"
https://github.com/prusa3d/Slic3r/issues/388

The Prusa3D binary builds are missing the UTF8 libraries.
To avoid having to bundle them, the case sensitive regexes testing
file suffixes were replaced with explicit enumeration of lower / upper
case letters. While crude, it avoids triggering the UTF8 library.
2017-07-11 17:15:34 +02:00
bubnikv
32213ce679 Implements loading of multi-part objects as a bunch of STLs
for a multi-material printer.
Also only a single pop-up dialog is open when loading multiple files.
2017-07-11 13:55:55 +02:00
bubnikv
a7153c67e6 Changed layout of the Tab page to accomodate a wider profile selection
combo box.
https://github.com/prusa3d/Slic3r/issues/194
https://github.com/prusa3d/Slic3r/issues/377
2017-07-11 12:02:44 +02:00
bubnikv
c159165780 A bit of clean-up in GCode.cpp 2017-07-11 11:42:55 +02:00
bubnikv
c52c31a855 A bit of clean-up in FillRectilinear2.cpp 2017-07-11 11:42:21 +02:00
bubnikv
c7d16699a4 When setting an override extruder in the Object Settings dialog,
don't apply this extruder to supports. This did not make sense
as the new "don't change tool (0)" extruder choice fits well for non-soluble
and the soluble supports should not be overriden as well.
2017-07-11 11:41:23 +02:00
bubnikv
41f50b246c Inlined Surface::any_internal_contains / any_bottom_contains 2017-07-10 13:15:36 +02:00
bubnikv
7c1350d007 Fixed "Too much support generated for buildplate only supports"
https://github.com/prusa3d/Slic3r/issues/359
2017-07-07 18:06:41 +02:00
bubnikv
774c69e3c6 Fix of "Problem with larger brim overlapping "
https://github.com/prusa3d/Slic3r/issues/373
2017-07-07 16:40:23 +02:00
bubnikv
434f538919 Fix of soluble interface / non-soluble support:
The non-soluble support with "don't care" extruder will preferably
be printed with a non-soluble extruder, if possible without a tool change.
2017-07-07 13:22:00 +02:00
bubnikv
abcd746774 Fix of
Overhang threshold not utilized after 1.34.1
https://github.com/prusa3d/Slic3r/issues/360

"Overhang threshold" and "Enforce support" don't work
https://github.com/prusa3d/Slic3r/issues/273
2017-07-07 10:45:39 +02:00
bubnikv
e78839d2fc Fixed a regression after porting GCode generator to C++
Not lifting extruder after printing complete individual objects
https://github.com/prusa3d/Slic3r/issues/400
2017-07-05 11:58:00 +02:00
bubnikv
0ad4e9d51f Refactored the cooling buffer: Removed ElapsedTime. 2017-06-30 20:01:32 +02:00
bubnikv
bf9027ff2d Fix of a cooling buffer over multiple extruders. 2017-06-30 19:07:14 +02:00
bubnikv
115deee252 FLT_MAX strikes again 2017-06-30 17:14:13 +02:00
bubnikv
1158ce41df Finalized implementation of a cooling buffer for multiple extruders
with different settings.
2017-06-30 17:05:58 +02:00
bubnikv
ab21a253e0 Hopefully finally fixed reordering of the multi-material parts. 2017-06-26 16:44:16 +02:00
bubnikv
8160db23cc Implementation of "XY size Compensation for first layer"
https://github.com/prusa3d/Slic3r/issues/190
2017-06-26 16:28:10 +02:00
bubnikv
32fa84c5a5 Fix of https://github.com/alexrj/Slic3r/issues/4043 , thanks to @lordofhyphens.
Further refactoring of the cooling logic to collect per extruder data.
2017-06-23 10:13:09 +02:00
bubnikv
39b9341359 Include the wipe tower print time into the cooling time.
Further refactoring of Extruder class.
2017-06-22 15:18:37 +02:00
bubnikv
0454cc95f9 Ported the cooling changes from @alexrj: Don't slow down the external
perimeters if not necessary, don't take the bridging time into account
when slowing down the print.

Removed Extruder & GCodeWriter Perl bindings.
Improved Extruder for constness.
Refactored GCode::m_elapsed_time to struct ElapsedTime.
2017-06-22 12:59:23 +02:00
bubnikv
c1146e298b Set the bed temperature based on the active extruder settings.
https://github.com/prusa3d/Slic3r/issues/157
2017-06-21 17:45:55 +02:00
bubnikv
f0325575c2 Slic3r has been modified to propagate the following filament specific
values to GCode generator, one per active extruder:

bed_temperature
bridge_fan_speed
cooling
disable_fan_first_layers
fan_always_on
fan_below_layer_time
first_layer_bed_temperature
max_fan_speed
min_fan_speed
min_print_speed
slowdown_below_layer_time

Now it remains to extend Slic3r to correctly apply these values.
2017-06-21 16:15:39 +02:00
bubnikv
0bd2bb1e8e Compilation issue on Linux & OSX
https://github.com/prusa3d/Slic3r/issues/368
2017-06-21 14:12:11 +02:00
bubnikv
b12e4689e8 Fix of changing the order of volumes of a multi-volume part:
The 3D preview scene was not updated properly.
2017-06-21 14:10:22 +02:00
bubnikv
7ca02bda0f Fix of a "split" function issue.
1) Load a multi-part stl
2) Rotate it by 90 degrees
3) Split it.

Before this fix, the split object jumped away from the print bed.

This sound similar to
https://github.com/prusa3d/Slic3r/issues/309
2017-06-19 14:26:19 +02:00
bubnikv
c33ed9144c Fixed the objects jumping 2017-06-19 11:47:43 +02:00
bubnikv
046d5a9cb7 The option --gui-mode has been removed with the following option:
82bde51c27

As it causes issues to the Repetier Host application
https://github.com/prusa3d/Slic3r/issues/363

this option has been added with this commit for compatibility reasons.
2017-06-19 11:47:16 +02:00
bubnikv
cb43f19a90 Fixed a variable layer height profile update issue.
https://github.com/prusa3d/Slic3r/issues/358
2017-06-15 20:15:53 +02:00
bubnikv
aa54c3402b Disable the "split" button when there is no volume selected. 2017-06-15 18:11:36 +02:00
bubnikv
b724d789fd New feature: Splitting an object into a multi-part volume. 2017-06-15 15:38:15 +02:00
bubnikv
a1f6403463 Fix of a wipe tower - wipe tower shrinking by the amount of material
wiped into the zig-zag pattern.
2017-06-15 10:53:37 +02:00
bubnikv
b8369ab19a gcc and clang did not like throwing std::exceptions with a cstring arugment 2017-06-14 20:33:20 +02:00
bubnikv
2ac981e422 Improved error handling when importing configuration from a G-code. 2017-06-14 20:18:46 +02:00
bubnikv
f7334f58d3 Finalized the config import from a G-code. 2017-06-14 18:53:11 +02:00
bubnikv
93dce7a2d3 Ported config load / stored to C++, thanks @alexrj
Implemented import of config values from the G-code.
2017-06-14 17:51:14 +02:00
bubnikv
c61e098066 Integrated the not yet accepted boost::nowide library, thanks @alexrj. 2017-06-14 16:24:49 +02:00
bubnikv
c431bf5982 Fixed missing default_region_config values exported into the g-code. 2017-06-14 15:16:43 +02:00
bubnikv
3e82eb7010 Extended the tooltpis for quick slice functions. 2017-06-14 12:52:50 +02:00
bubnikv
a73a1a3f09 Removed the DLP projector dialog as it is confusing to our customers
and we doubt anybody is using it.
2017-06-14 12:05:23 +02:00
bubnikv
82bde51c27 Removed the 'simple' mode. 2017-06-14 11:48:08 +02:00
bubnikv
8a2a9abbd4 Fix of "Raft and support dont work together"
https://github.com/prusa3d/Slic3r/issues/314
There was an issue with raft & soluble support.
Also there was a bug, where the support was not generated correctly
after a change of the support Z gap.
2017-06-13 19:29:15 +02:00
bubnikv
6cb7583756 Reverted the "set_and_wait_temperatures" configuration to match
the behavior of the @alexrj slic3r.
2017-06-13 13:46:04 +02:00
bubnikv
fdb5ed1fcb Fix for "Crash when deleting all objects"
https://github.com/prusa3d/Slic3r/issues/193
2017-06-13 13:42:38 +02:00
bubnikv
f7831240e1 Fixed compilation on OSX 2017-06-13 12:09:49 +02:00
bubnikv
a4992602ee Auto arrange: Do at least something if the objects do not fit the bed.
Thans @alexr
https://github.com/prusa3d/Slic3r/issues/336
2017-06-13 11:43:25 +02:00
bubnikv
5cae4cc614 Fix of https://github.com/prusa3d/Slic3r/issues/285
Refactored Model.cpp/hpp to C++x11 loops,
simplified the mesh / bbox handling.
2017-06-13 11:35:24 +02:00
bubnikv
21ddcb8487 Fix of a layer height test to allow / disable the wipe tower. 2017-06-12 14:33:33 +02:00
bubnikv
f408f08850 Disabled the new Slic3r version check until we have a server set up
for the Slic3r Prusa Edition.

Hopefully a fix of https://github.com/prusa3d/Slic3r/issues/258
by moving the 2D thumbnail generation to the main thread and
forcing the simple 2D convex hull for even the small objects.
2017-06-12 14:25:35 +02:00
bubnikv
02ab92ea65 Little improvements of the 3D manipulation usablility:
Limit zoom out to 3x the "scene fit" amount.
Disable wheel scrolling when the middle button is pressed.
2017-06-09 15:02:11 +02:00
bubnikv
881a5c531b Fix of the last commits:
1) FLT_MAX replaced with limits,
2) apply_config is called by the test case harness to update layer height profile.
2017-06-09 14:24:00 +02:00
bubnikv
958c6553e7 Hopefully a fix of
"Layer editing does not trigger reslicing with Background Processing enabled"
https://github.com/prusa3d/Slic3r/issues/293
2017-06-09 13:27:35 +02:00
bubnikv
6ce832e439 The OpenGL Z-bufer has low precision, therefore a bounding box test
had to be relaxed.
2017-06-08 20:50:24 +02:00
bubnikv
2bbcd49278 Fix of a crash in pressure equlizer filter.
https://github.com/prusa3d/Slic3r/issues/339
2017-06-08 20:28:21 +02:00
bubnikv
66f1ae003f A little simplification of the Perl side threading:
Only single level Perl worker threads are allowed.
2017-06-08 18:53:33 +02:00
bubnikv
e0a24f94c0 Removed Object.pm support_material_flow method. 2017-06-08 18:13:12 +02:00
bubnikv
dd41406a55 Fixed regression in invalidation of slicing steps. 2017-06-08 17:46:28 +02:00
bubnikv
89dcd3e8b1 Implemented raft support for the wipe tower
https://github.com/prusa3d/Slic3r/issues/324

Implemented a correct layer height preview for the wipe tower layers,
if the wipe tower layer height is not constant due to the application
of raft.
2017-06-08 16:58:29 +02:00
bubnikv
f9f0940297 Implemented rotation of the support structure. 2017-06-08 14:02:37 +02:00
bubnikv
27003dc0fd Possible fix of
https://github.com/prusa3d/Slic3r/issues/260
https://github.com/prusa3d/Slic3r/issues/272
by disabling opengl blending when picking.

Also the limiting region for object movement has been rounded smoothly.
2017-06-08 12:23:50 +02:00
bubnikv
a15e6127cf Relaxed the requirements on the layer height for the Wipe Tower to
the span of 0.15mm to 0.35mm.
2017-06-08 12:10:34 +02:00
bubnikv
fe409a76a6 Fixed panning issues when the camera is parallel to the bed plane. 2017-06-08 12:01:35 +02:00
bubnikv
8b5f7f0fb2 Limit the object movement to the vincinity of the print bed. 2017-06-08 11:02:29 +02:00
bubnikv
dabcff1c07 When testing for a key press, rather check for the modifier keys
(alt, ctrl) always. Also if a key event is not processed, pass it
for further processing.
2017-06-06 19:14:52 +02:00
bubnikv
53d08d1883 New BoundingBox3 class. 2017-06-06 19:12:46 +02:00
bubnikv
0816c995a7 Implements "Fewer" button should not remove last copy from build platform
https://github.com/prusa3d/Slic3r/issues/301
2017-06-06 15:38:27 +02:00
bubnikv
baf27ff021 Fix of View menu not working https://github.com/prusa3d/Slic3r/issues/307 2017-06-06 13:39:50 +02:00
bubnikv
35acd799cf Fixed a superflous "Dirty" multi-extruder printer profile after
the introduction of new extruder parameters
(deretract_speed extruder_colour retract_before_wipe).
https://github.com/prusa3d/Slic3r/issues/325
2017-06-06 12:52:15 +02:00
bubnikv
3e764ada0c For the wipe tower to work, verify that all objects are sliced
with the same layer heights.
Also enforce layer synchronization for soluble supports.
2017-06-06 11:40:35 +02:00
bubnikv
72f348658f Testing for the required parameter combinations before enabling the wipe tower.
The wipe tower needs to be made more general in the future to overcome
these limitations.
2017-06-06 10:36:14 +02:00
bubnikv
88c9ae6ca6 Fix of
https://github.com/prusa3d/Slic3r/issues/315
a crash if the max_layer_height is left to a default value of zero.
2017-06-05 12:02:26 +02:00
bubnikv
ad3be1a69e Implemented filament start / g-codes.
https://github.com/prusa3d/Slic3r/issues/265
https://github.com/prusa3d/Slic3r/issues/319
Based on the implementation by @lordofhyphens
19eea19d91
2017-06-05 11:30:57 +02:00
bubnikv
b5f38dd23f Fixed the "avoid crossing perimeters" bug introduced in Slic3r 1.34.1.24
https://github.com/prusa3d/Slic3r/issues/311
https://github.com/prusa3d/Slic3r/issues/317
https://github.com/prusa3d/Slic3r/issues/323
2017-06-02 13:33:19 +02:00
bubnikv
ef73bb404b Fixed compilation on gcc. 2017-06-01 16:43:21 +02:00
bubnikv
02592378e2 Improved "ensure vertical wall thickness" feature for multi material:
If the "interface_shells" feature is disabled, the "ensure vertical wall thickness"
feature will not add full infill over internal shells.

Fixed some issues with delayed loading of 3d scenes.
2017-06-01 16:31:29 +02:00
bubnikv
ee5ee5f432 Performance improvements in reloading the 3D scene.
Now the 3D scene loading is postponed until the page is visible.
2017-05-31 17:05:11 +02:00
bubnikv
556f40bf00 Clean-up of print step invalidation. 2017-05-31 17:02:23 +02:00
bubnikv
c8b934f8d3 Yet more refactoring of Print / PrintObject in regard to
C++11 loops, configuration and step invalidation.
2017-05-31 12:55:59 +02:00
bubnikv
0a692cc497 Regression fix of percent config values serialization. 2017-05-30 21:29:43 +02:00
bubnikv
102329c54d Further refactoring, C++11 conversion and code simplification. 2017-05-30 20:09:34 +02:00
bubnikv
e1ca1a82fb Fixed a regression bug from the last commit. Some more code simplification
and inlining.
2017-05-30 18:33:17 +02:00
bubnikv
efb1fd2066 Fixed order of loading the configs into Print / PrintObjects
and loading the 3d print path preview.
2017-05-30 17:24:50 +02:00
bubnikv
41a4df0a38 Print, PrintObject: Invalidation of steps, when chained, will now return
a correct invalidated / not invalidated flag.
Rewrote the step valid state from std::set to a fixed array for performance
reasons.
2017-05-30 17:17:26 +02:00
bubnikv
e32632b9d9 Config.cpp/h - inlined short functions, converted loops to C++11,
fixed some constness issues.
2017-05-30 17:04:36 +02:00
bubnikv
2178180a19 Wipe tower: Wipe less than usual amount of material if the wipe
is followed by the final sparse zig-zag tower section.
2017-05-30 10:51:38 +02:00
bubnikv
0120f3ed92 Fix of the final purge over the wipe tower. 2017-05-30 09:25:34 +02:00
bubnikv
adb36e47ff Added images for the up / down buttons (used to change order
of model volumes).
2017-05-26 15:44:45 +02:00
bubnikv
3d6c997012 fixed compilation on Windows 2017-05-25 22:54:42 +02:00
bubnikv
2f4ff6577a With single_extruder_multi_material enabled,
don't append a tool selection (Txx) to the extruder temperature
settings (M104 and M109).
2017-05-25 22:52:28 +02:00
bubnikv
e000b22578 Implemented wipe tower print path preview. 2017-05-25 22:27:53 +02:00
bubnikv
7d64c465c0 New config field extruder_color for preview of extruder assignment. 2017-05-24 15:20:20 +02:00
bubnikv
2713aa1772 When generating a g-code for a layer, collect layers of multiple objects
with not exactly the same print_z, but support a slight deviation.
2017-05-23 17:09:43 +02:00
bubnikv
ca590cb559 Refactored ToolOrdering to a class,
layers with print_z closer than EPSILON are merged and printed together.
2017-05-23 15:00:01 +02:00
bubnikv
aad9f61bad Wipe Tower: Fixed some ordering issue in the G-code writer. 2017-05-22 20:56:42 +02:00
bubnikv
c9c4105289 Fixed an excessive retract / derectract length
with the new retract_before_wipe value set to nonzero.
2017-05-22 18:16:35 +02:00
bubnikv
ff9d565ba7 Implemented UI for ordering volumes
https://github.com/prusa3d/Slic3r/issues/277
2017-05-20 22:02:04 +02:00
bubnikv
7884fa3d7c Implemented Multipart object list window resize #278 2017-05-20 19:44:55 +02:00
bubnikv
dfc4717308 Fixes for Multi Material ramming, increased separation of wipe lines. 2017-05-20 18:59:05 +02:00
bubnikv
a99b006b98 Implemented https://github.com/prusa3d/Slic3r/issues/199
by merging the work by @lordofhyphens done on https://github.com/alexrj/Slic3r/issues/3268
2017-05-20 15:29:25 +02:00
bubnikv
6fa280be0b Finished the wipe tower UI. 2017-05-19 21:48:32 +02:00
bubnikv
70db88dd90 Improved retract handling on bowden extruders:
Separated deretract speed from a retract speed,
allowed a partial retract before wipe.
2017-05-19 19:24:21 +02:00
bubnikv
8bd3dec331 Extrude brim of the wipe tower before any other objects. 2017-05-18 21:22:48 +02:00
bubnikv
11307eb350 typo in default ramming sequence. 2017-05-18 19:49:55 +02:00
bubnikv
c28e4cb0f7 Increased extruder driver current for ramming over the multi material
wipe tower.
2017-05-18 19:05:44 +02:00
bubnikv
81701b400c Prusa Multi Material: Improved path planning when jumping to the wipe tower. 2017-05-18 16:53:19 +02:00
bubnikv
e75d851bc4 Updated MANIFEST,
fixed some compiler warnings.
2017-05-17 20:06:33 +02:00
bubnikv
fdff937cb2 Fixed tool ordering for sequential prints. 2017-05-17 19:25:36 +02:00
bubnikv
34747b2015 Added ABS material to the Prusa Multi Material wipe tower. 2017-05-17 18:14:47 +02:00
bubnikv
66b619dfa4 Bugfix of tool ordering. 2017-05-17 17:21:55 +02:00
bubnikv
f27ec3f226 Prusa Multi Material wipe tower: Do an unretract before doing
the wipe tower things.
2017-05-17 16:59:56 +02:00
bubnikv
cb0a66b743 Initial implementation of a wipe tower preview UI. 2017-05-17 16:53:40 +02:00
bubnikv
7b6c9b3b3c Fixes of the Prusa Multi Material wipe tower. 2017-05-17 16:45:37 +02:00
bubnikv
4bc827d1da WipeTowerPrusaMM: Added some documentation, fixed minor issues. 2017-05-17 10:42:39 +02:00
bubnikv
7b152919a6 Changed handling of extruder temperatures
for single_extruder_multi_material printers.
Fixed some compilation errors on OSX.
Disabled re-slicing on change of new G-code only parameters.
2017-05-16 16:02:52 +02:00
bubnikv
21be680ac2 Fixes of G-code multi-tool ordering. 2017-05-16 15:30:03 +02:00
bubnikv
c22b6edeeb Initial integration of the Prusa MultiMatrial Wipe Tower. 2017-05-16 13:45:28 +02:00
bubnikv
74346efccb Fix of a multi-material g-code export. 2017-05-15 16:42:29 +02:00
bubnikv
60c65f6da7 Fixed crashes intruduced recently into G-code generator.
Added a template sort_remove_duplicates.
2017-05-15 11:32:59 +02:00
bubnikv
89e34ae1d6 Missing include for OSX. 2017-05-12 14:22:20 +02:00
Xoan Sampaiño
281a9c45eb Remove hardcoded font size for wxGTK
When in wxGTK (GNU/Linux), some widgets has a hardcoded point size font that not fit with normal GUI font and therefore this widgets doesn't inherit changes in system font size.

This commit only affect this platform, changing `!&Wx::wxMSW` to `&Wx::wxMAC`.
2017-05-12 11:31:54 +02:00
bubnikv
ff0412b417 Support material - Fixed some compilation warnings, added new debbuging
SVG file outputs.
2017-05-12 11:18:32 +02:00
bubnikv
3b5f40710c Support Generator: Fixed initial indices in search caches.
Changed the interface layer infill type to concentric for soluble supports.
2017-05-12 11:14:25 +02:00
bubnikv
46e8259b99 Fixing some missing layers with support material. 2017-05-12 11:09:24 +02:00
bubnikv
805179b9da Wipe tower refactored to remove renundancies,
added comments.
2017-05-12 10:44:56 +02:00
bubnikv
b92aa20cef Include <strings.h> on linux. 2017-05-10 16:15:14 +02:00
bubnikv
146039f402 Added Prusa MultiMaterial Wipe Tower. Now it is time to integrate it
into the G-code generator.
2017-05-10 15:54:59 +02:00
bubnikv
2f57ee60d1 Improved G-code generator for multi-material prints
to minimize tool switches.
2017-05-10 11:25:57 +02:00
bubnikv
18bb3c3244 Added Notes Tab to Printer Settings #210 2017-05-05 11:59:51 +02:00
bubnikv
60528c5c2a Performance improvements of the MotionPlanner
(rewrote the Dijkstra shortest path algorithm to use a binary priority
heap instead of a dumb O(n^2) algorithm, added some bounding box tests
to avoid expensive in-polygon tests if possible).
2017-05-05 09:59:56 +02:00
bubnikv
8a628c451c Fixed a newly introduced G-code issue on Windows
when exporting into a localized directory.
2017-05-04 09:24:34 +02:00
bubnikv
0adc6cc65e Provide own implementation of std::make_unique for older compilers. 2017-05-03 18:57:33 +02:00
bubnikv
867619fa40 missing include <memory> 2017-05-03 18:35:55 +02:00
bubnikv
e90279c513 Ported the G-code generator from Perl to C++.
Removed GCode.pm
Removed the Perl bindigns for AvoidCrossingPerimeters, OozePrevention, SpiralVase, Wipe
Changed the std::set of extruder IDs to vector of IDs.
Removed some MSVC compiler warnings, removed obnoxious compiler warnings when compiling the Perl bindings.
2017-05-03 18:28:22 +02:00
bubnikv
72ae3585e4 Removed a broken Arc Fitting feature.
Removed the questionable Pressure Advance feature. It is better to use the Pressure Advance implemented into a firmware.
Added a C++ implementation of GCodeReader and SpiralVase, thanks to @alexrj
Added a C++ implementation of GCodeTimeEstimator, thanks to @lordofhyphens
2017-04-26 14:24:31 +02:00
bubnikv
e918ea9c65 Fixes Variable Layer Height issue when max_layer_height at its default of zero
https://github.com/prusa3d/Slic3r/issues/267
2017-04-24 09:51:24 +02:00
bubnikv
69c0f55679 Fixes loading of multi-part ASCII STLs.
https://github.com/prusa3d/Slic3r/issues/255
2017-04-18 10:53:31 +02:00
bubnikv
8040ef8efb Fixing a bug in the layer editor for high diameter nozzles.
https://github.com/prusa3d/Slic3r/issues/247
2017-04-11 11:16:47 +02:00
bubnikv
23be6233c8 Finalized the experimental "synchronize support layers with object layers"
feature (the support_material_synchronize_layers settings).
The feature is now enabled for the soluble supports only
(with support_material_contact_distance > 0).

Fixes https://github.com/prusa3d/Slic3r/issues/197
2017-04-10 12:00:07 +02:00
bubnikv
688fe3e2b2 Fixed some rare support issues connected with the 1st print layer.
Fixed support issue, where the XY gap was ignored for the top contact layers
and a fixed 50% was used instead.
2017-04-07 17:44:51 +02:00
bubnikv
ed2ee2f6f3 Merged support_fills with support_interface_fills.
When extruding supports, the support is interleaved with interface
if possible (when extruded with the same extruder).
Otherwise the base is extruded first.
2017-04-07 17:37:30 +02:00
bubnikv
c40de7e424 Fix of https://github.com/prusa3d/Slic3r/issues/218
Cut function bug in accepting a numerical value
2017-04-05 15:55:02 +02:00
bubnikv
7ffb3590c4 Finalized the Prusa Control project file format import. 2017-04-05 14:45:43 +02:00
bubnikv
f9023c0603 Removed some unused code. 2017-04-05 13:50:59 +02:00
bubnikv
b66bfb41aa Validate the height values entered into the layer height table.
Clamp these values between the minimum of min_layer_height per nozzle
and the maximum of max_layer_height per nozzle.
Don't allow entering zero layer height to trim an object,
the cut dialog should be used instead.

Fixes https://github.com/prusa3d/Slic3r/issues/235
2017-04-05 13:27:00 +02:00
bubnikv
6f5700a3a6 Fix of
https://github.com/prusa3d/Slic3r/issues/66
https://github.com/prusa3d/Slic3r/issues/181

Implemented filtering of the support structures expanded into a grid,
where the support parts leaked through the object wall are removed
after the fact.
2017-04-05 09:56:59 +02:00
bubnikv
5126c5018a Provision for disabling TBB parallelization for debugging purposes. 2017-04-05 09:53:24 +02:00
bubnikv
74b95e9152 Adapted BoundingBox get_extents(const ExPolygons &expolygons)
to work even with empty polygons.
2017-04-05 09:52:06 +02:00
bubnikv
555560f63c Simplification, C++11 beautification. 2017-04-05 09:51:03 +02:00
bubnikv
ef2cfdb0d1 C++11 beautification of loops. 2017-04-05 08:59:03 +02:00
bubnikv
47543cf82a Operator< for Point 2017-04-05 08:57:59 +02:00
bubnikv
329f0b9cf4 Debugging output and asserts for TriangleMeshSlicer::slice(). 2017-04-05 08:57:37 +02:00
bubnikv
bd9ee88e2f Fix of https://github.com/prusa3d/Slic3r/issues/214
Dent in perimeters around a hole

Clipper Offset has been extended to remove tiny edges before the offset.
This is important as the tiny edges pose difficulty
for normal calculation, leading to various adverse effects like
kinks and dents in the offsetted contour.
2017-04-04 11:17:25 +02:00
bubnikv
70fcedb113 Fix of https://github.com/prusa3d/Slic3r/issues/232
Single layer of sparse support above dense support before model
2017-04-04 09:57:54 +02:00
bubnikv
9d9a6feb96 Disable ensure_vertical_shell_thickness for spiral vase mode. 2017-04-03 11:19:32 +02:00
bubnikv
1719952f49 Fixing "opening an obj file causes Slic3r to become stuck and use 100% on one core" #221
Extended the OBJ parser to triangulate quads. Higher order polygons are not supported though.
2017-04-03 10:05:22 +02:00
bubnikv
8ac1d37b10 Fixed crashes on OpenGL < 2 due to printing null pointers returned
by glGetString().
2017-03-31 15:29:34 +02:00
Joseph Lenox
7b5158f5f2 Permit firmware retraction when firmware is Repetier (repetier-firmware supports it). Fixes #3821 2017-03-30 16:47:06 +02:00
bubnikv
36416d77b8 Fixes of VBO rendering on Linux with wxWidgets & GTK 2017-03-30 10:25:52 +02:00
bubnikv
b60ae4745f Fixed missing #include<assert.h> 2017-03-29 19:57:11 +02:00
bubnikv
3e347c33dc Bundled Eigen library. 2017-03-29 18:19:57 +02:00
bubnikv
5dc899d64e Reset wipe moves on tool change and on travel. 2017-03-29 17:45:38 +02:00
bubnikv
4bbb1f4b63 Rewrote next_highest_power_of_2 as a template as OSX had issues with
the previous implementation.
2017-03-28 18:02:26 +02:00
bubnikv
2da3388aa5 Only print "Generating perimeters" once. 2017-03-28 17:27:05 +02:00
bubnikv
3ebf0ce7fd Improved memory allocation efficiency of the 3D path preview generator. 2017-03-28 17:09:57 +02:00
bubnikv
1fb302d480 Reverted due to a failing test t\multi.t 2017-03-28 14:29:27 +02:00
bubnikv
95b45da57c Fixed 3D view of the Cut dialog. 2017-03-28 14:18:13 +02:00
bubnikv
40b75f6cee Snapped the bottom interface layer print heights to the top interface
layer print heights to avoid too thin layer surfaces. The minimum layer
height at the nozzle page is maintained for the support layers.

Base layers are trimmed by the briding bottom surfaces.
2017-03-28 13:46:31 +02:00
bubnikv
9f7a5c7a6f Some beautification and C++11 adaptation. 2017-03-28 13:25:10 +02:00
bubnikv
640698d28b Fixing Zero extrusion print moves and overlapping regions in first layer
https://github.com/prusa3d/Slic3r/issues/184

No E distances generated when support is selected. bug?
https://github.com/prusa3d/Slic3r/issues/175
2017-03-27 14:34:07 +02:00
bubnikv
67126d6f48 Moved the NVIDIA and AMD hints to the slic3r.exe wrapper. 2017-03-27 09:06:24 +02:00
bubnikv
0dae43e4bc Bugfix: when the Voronoi diagram contained very large coordinates we need to check whether they are greater than our allowed range and consider the Voronoi edges infinite in those cases, in order to prevent overflows.
https://github.com/alexrj/Slic3r/issues/3776
9ad1360e44
2017-03-24 09:32:30 +01:00
bubnikv
6162670bbd Fixing Window selections wrong
https://github.com/prusa3d/Slic3r/issues/191
Thanks @uclaros
94f60db114
2017-03-23 18:02:35 +01:00
bubnikv
bc7ff623f8 Updated from upstream,
build instructions for Windows point to Prusa3D instructions.
2017-03-23 17:00:46 +01:00
bubnikv
53832aff24 Documented the boost libraries required by Slic3r Prusa Edition
https://github.com/prusa3d/Slic3r/issues/88
2017-03-23 16:28:23 +01:00
bubnikv
b7d3ed26c6 Link boost & intel Thread Building Blocks statically by default
on Windows and OSX, dynamically on Linux.
This could be overidden by an environment variable
SLIC3R_DYNAMIC=1
2017-03-23 15:06:22 +01:00
bubnikv
a7838cac07 Fixed the rotation and scaling inputs allowing decimal numbers with
both the dot and comma as a decimal separator.

Fixes 6649888d1c
2017-03-23 14:32:19 +01:00
bubnikv
cc9460b8fa Increased a threshold for print centering from EPSILON to 5um
to account for the decimation of the brim lines.
2017-03-23 13:21:44 +01:00
bubnikv
9e0a690d2e Simplified the skirt paths. 2017-03-23 12:35:00 +01:00
bubnikv
073d6d2d43 Fixed colors of the path preview. 2017-03-23 12:34:35 +01:00
bubnikv
1770d031b4 Fixed rotations, allow both dot and dash as decimal separators,
correctly report invalid numeric values for rotation.
2017-03-23 11:53:59 +01:00
bubnikv
1b3c651643 Fixed iusses in rendering print paths through VBOs for multiple objects. 2017-03-23 11:10:53 +01:00
bubnikv
3b5d1d0e25 Try to enforce the use of a high performance NVIDIA / ATI GPU
on dual graphic card laptops.
2017-03-23 10:28:08 +01:00
bubnikv
1fb3d00932 Fix of parsing ASCII STLs on Visual Studio 2013 with global optimization. 2017-03-22 17:57:27 +01:00
bubnikv
ed495663e8 Support generator parallelized. 2017-03-22 15:35:50 +01:00
bubnikv
04cd474708 Fixed some instance of simplify_polygons() invocation.
Geometry::deg2rad() made a template.
Some methods of Layer made inline.
Added a helper template remove_nulls().
2017-03-22 15:35:09 +01:00
bubnikv
6b99cbdc02 Had the vertex buffer objects disabled for debugging purposes by mistake. 2017-03-21 08:59:48 +01:00
bubnikv
d8f0c0bdff Fixed bug in variable layer height editing: Make the OpenGL context
current.
2017-03-20 15:55:22 +01:00
bubnikv
039cd0ac5b new GLShader.cpp,h 2017-03-20 14:48:17 +01:00
bubnikv
045de596e2 Use OpenGL 2.0 shaders for the layer height rendering.
Use OpenGL 2.0 shaders for the print path rendering for performance reasons.
2017-03-20 12:05:20 +01:00
bubnikv
56f845f3c1 Fixed the reports given by the build process if BOOST or TBB libraries
were not found.
https://github.com/prusa3d/Slic3r/issues/177
2017-03-17 22:49:43 +01:00
bubnikv
8e28bd36a2 Link XS with -framework OpenGL on OSX. 2017-03-16 14:26:16 +01:00
bubnikv
73de247a15 Enabled SLIC3R_GUI by default. This is required to enable the OpenGL 2.0
API through C++ GLEW.
2017-03-16 14:09:42 +01:00
bubnikv
7f7d2da5fe Use Vertex Buffer Objects for rendering of 3D volumes if possible. 2017-03-16 14:02:28 +01:00
bubnikv
c32c7fa1dc Fixed a typo. 2017-03-15 21:26:46 +01:00
bubnikv
93cab990c7 Fixed some memory allocation issues of the new C++ 3d path preview
(reserved memory has to be shrank around the collected data).

Initial implementation of the vertex buffer objects for the 3d path preview.
2017-03-15 20:45:03 +01:00
bubnikv
d18e10c7c9 Rewrote the OpenGL object rendering to indexed triangle / quad sets
for lower memory consumption.
Rewrote the print path 3D preview to generate these indexed triangle / quad
sets, possibly with at least as possible duplication of vertices,
with a crease angle of 45 degrees, leading to maximum 8% overshoots
at the corners.
2017-03-15 16:33:25 +01:00
bubnikv
e7a920fe16 Fixed some picking issues after porting GLVolumes to C++.
Initial interface for print paths visualization by VBOs.
2017-03-14 10:11:08 +01:00
bubnikv
79e6f23fdc code beautification, C++11 loops 2017-03-13 16:03:44 +01:00
bubnikv
c96d794604 BoundingBox, Print - methods inlined, added const accessors. 2017-03-13 16:03:11 +01:00
bubnikv
e6fddd364d Volume rewritten from Perl to C++,
generation of vertex arrays from paths rewritten from Perl to C++,
parallelized.
2017-03-13 16:02:17 +01:00
bubnikv
50976e1b5a Parallelized slices_to_fill_surfaces_clipped() 2017-03-08 23:02:27 +01:00
bubnikv
720459183e Parallelized detection of extra perimeters. 2017-03-08 22:38:08 +01:00
bubnikv
a956186c76 Parallelized TriangleMeshSlicer::make_expolygons 2017-03-08 21:55:38 +01:00
bubnikv
336f86c101 Fixed a newly introduced memory leak into the Clipper library,
made all Clipper interfaces non-virtual.
2017-03-08 20:27:03 +01:00
bubnikv
4426e47e2a Fixed a race condition in the parallelization
of the "ensure vertical wall thickness" feature.
2017-03-08 18:10:39 +01:00
bubnikv
20796b89c1 Improved debugging of slicing. 2017-03-08 15:58:40 +01:00
bubnikv
b5e45bccf9 Fixed a typo after porting _simplify_slices to C++. 2017-03-08 15:08:40 +01:00
bubnikv
798bca561b Parallelized the slow discover_vertical_shells() 2017-03-08 14:54:04 +01:00
bubnikv
f200781436 C++ compiler suppressed default constructor and assignment operator
for Surface after the move operators were implemented. Added
those operators manually.
2017-03-08 14:22:49 +01:00
bubnikv
52b76930aa Simplify_slices rewritten to C++, parallelized.
Added some move methods to Surface class.
2017-03-08 13:43:49 +01:00
bubnikv
4331f38912 Fixing of slicing errors ported to C++, parallelized. 2017-03-08 11:56:42 +01:00
bubnikv
73439b7acb Parallelized PrintObject::_slice(), make_slices() code. 2017-03-08 10:37:47 +01:00
bubnikv
1e6cf0cd98 TriangleMeshSlicer
replaced the vectors of vectors by vectors of indices to a continuous memory,
using binary search to get to an index.
2017-03-08 09:47:32 +01:00
bubnikv
edd7cabf68 Trace TriangleMeshSlicer at loglevel debug (nr. 4) 2017-03-07 22:50:32 +01:00
bubnikv
dfba2cb6b2 Parallelized PrintObject::detect_surfaces_type() 2017-03-07 21:46:45 +01:00
bubnikv
65c024f7cf Parallelize PrintObject::process_external_surfaces() 2017-03-07 17:43:43 +01:00
bubnikv
109013bed7 Yet another fix of the static linking on Windows. 2017-03-07 16:33:36 +01:00
bubnikv
32b0428303 Yet another fix of a static TBB linkage. 2017-03-07 14:50:32 +01:00
bubnikv
a4dea4b7fc Fix of intel TBB linking. 2017-03-07 14:31:08 +01:00
bubnikv
32ebb1e2c7 Fix of a static library extension of the INtel Thread Building Blocks on OSX/Linux. 2017-03-07 14:13:30 +01:00
bubnikv
cb1a6eae1e Added dependencies on the Intel Thread Building Blocks.
Changed the C++ parallelization code to Intel Thread Building Blocks.
2017-03-07 13:03:14 +01:00
bubnikv
8a42c0ad9f Implementation of scaling factor of objects into an AMF file.
https://github.com/prusa3d/Slic3r/issues/7
2017-03-06 17:35:38 +01:00
bubnikv
c23c0ee7d2 Fix of https://github.com/prusa3d/Slic3r/issues/172 ? 2017-03-06 15:03:31 +01:00
bubnikv
06f82d1db5 No need for Math::Libm 2017-03-06 13:09:23 +01:00
bubnikv
d20a9d73d4 Fix for OSX: clang requires the member operator< and == to be const. 2017-03-05 16:34:16 +01:00
bubnikv
a9a20003c0 Clipper memory optimization: Own memory manager for OutPt objects.
Allocate OutPt by chunks of 32, reuse the released OutPt objects.
2017-03-03 23:06:51 +01:00
bubnikv
f24427cd76 Another Clipper optimization. When adding a set of paths
to Clipper, allocate the edges in a single continuous vector.
2017-03-03 21:40:40 +01:00
bubnikv
fa4df36963 Fix: Orientation() has been declared inline, therefore not exported. 2017-03-03 20:39:04 +01:00
bubnikv
5580fd64b3 Clipper library:
Added some comments,
some methods were made inline, tiny methods moved to the header as inline,
dynamic allocation replaced with std:: containers,
changed some loops to the condensed C++11 syntax.
2017-03-03 20:38:53 +01:00
bubnikv
fddd7c620f Some optimization of memory allocation, some reduction / inlining of short functions. 2017-03-03 20:38:40 +01:00
bubnikv
1909c75c21 TriangleMeshSlic3r used unordered_map, which was terribly horribly shamelessly
slow on mingw. Rewrote using std::vector<>, which is blazing fast.
2017-03-03 17:36:07 +01:00
bubnikv
a219ae3d27 Set boost tracing level on DLL initialization to errors only. 2017-03-03 14:38:25 +01:00
bubnikv
4de33effdc Tracing of TriangleMesh repair. 2017-03-03 13:31:51 +01:00
bubnikv
930e6752d9 Reverted unification of positive and negative zeros when loaded
from an STL file.
2017-03-03 12:54:00 +01:00
bubnikv
4d00aa1800 More tracing of the slicing process. 2017-03-03 12:53:05 +01:00
bubnikv
062a6628e5 Revert "Some optimization of memory allocation, some reduction / inlining of short functions."
This reverts commit bc19e97d45.
2017-03-02 20:44:53 +01:00
bubnikv
473624fcd7 Revert "Clipper library:"
This reverts commit 90a415ae10.
2017-03-02 20:44:43 +01:00
bubnikv
cd7134e6f6 Revert "Fix: Orientation() has been declared inline, therefore not exported."
This reverts commit c2ee73d211.
2017-03-02 20:44:28 +01:00
bubnikv
c2ee73d211 Fix: Orientation() has been declared inline, therefore not exported. 2017-03-02 17:34:53 +01:00
bubnikv
90a415ae10 Clipper library:
Added some comments,
some methods were made inline, tiny methods moved to the header as inline,
dynamic allocation replaced with std:: containers,
changed some loops to the condensed C++11 syntax.
2017-03-02 17:11:46 +01:00
bubnikv
4287362aa6 Extended tracing of the slicing process. 2017-03-02 16:52:24 +01:00
bubnikv
d430767fa7 Define a surface type count constant to be able to address a vector
with a surface type.
2017-03-02 16:42:26 +01:00
bubnikv
83a80a9b7d Optimization of LayerRegion::slices_to_fill_surfaces_clipped()
Added some run time tracing through boost::log.
2017-03-02 16:41:16 +01:00
bubnikv
73f603d90e Fix of #117: A large fractal pyramid takes ages to slice
The Clipper library has difficulties processing overlapping polygons.
Namely, the function Clipper::JoinCommonEdges() has potentially a terrible time complexity if the output
of the operation is of the PolyTree type.
This function implmenets a following workaround:
1) Peform the Clipper operation with the output to Paths. This method handles overlaps in a reasonable time.
2) Run Clipper Union once again to extract the PolyTree from the result of 1).
2017-03-02 16:39:43 +01:00
bubnikv
258252cbf3 Shiny Profiler: Disable exponential dumping of the timing data. 2017-03-02 16:35:15 +01:00
bubnikv
349cf841d6 Need to include '-lboost_filesystem' in build #166 2017-03-02 16:33:50 +01:00
bubnikv
07fa15806f Utility function SVG::export_expolygons() to paint a set of possibly
overlapping ExPolygons with attributes.
2017-03-02 16:32:43 +01:00
bubnikv
dff5bda202 The Shiny profiler is not thread safe. Disable parallelization if
SLIC3R_PROFILE is enabled.
2017-03-02 16:31:29 +01:00
bubnikv
bc19e97d45 Some optimization of memory allocation, some reduction / inlining of short functions. 2017-03-01 14:27:08 +01:00
bubnikv
f8a2087fc6 Fixed a bug after merge.
https://github.com/prusa3d/Slic3r/issues/163
2017-03-01 13:16:33 +01:00
bubnikv
46fc4a0a8e Correctly rename g-code file once it is generated. 2017-02-28 10:44:44 +01:00
Alessandro Ranellucci
80f345d7c1 Remove unnecessary method call 2017-02-28 10:41:36 +01:00
Alessandro Ranellucci
6a90fceaaf Ported expanded_output_filepath() to C++/XS 2017-02-28 10:38:32 +01:00
bubnikv
66493ce821 Some documentation on missing functionalities. 2017-02-28 10:29:52 +01:00
Alessandro Ranellucci
6f11969257 Restore [input_filename] in custom G-code as well 2017-02-28 10:28:29 +01:00
AndylgTom
4528f35bc0 Update Config.xsp (#50)
For fix to display Unicode in category
2017-02-28 10:06:03 +01:00
bubnikv
4010dd71f6 Support Prusa Control project files (.PRUS) by the GUI. 2017-02-27 16:09:22 +01:00
bubnikv
8a8b49ea02 Removed CoolingBuffer.pm as it has been superseeded by the C++ code. 2017-02-27 01:51:08 +01:00
bubnikv
c9465cf7fa Fixed typos in AMF export. 2017-02-27 01:39:20 +01:00
bubnikv
ee619701d8 Got rid of the Perl Format::STL, Format::AMF, Format::OBJ for good. 2017-02-27 01:03:00 +01:00
bubnikv
f0f550783f Good bye, Perl Expat binding! 2017-02-27 00:38:30 +01:00
bubnikv
9ea570ea4e Fix of a warning in expat parser, which turns to an error
on some Perl/XS installations (strawberry Perl 64bit)
2017-02-26 23:35:44 +01:00
bubnikv
616788a600 Disabling the support tests until the test suite is modified
for the new supports.
2017-02-26 23:16:26 +01:00
bubnikv
2f67a16c6f Fixing compilation issues. 2017-02-26 23:13:31 +01:00
bubnikv
2c932b1bf4 Fixed a bug in AMF serialization. 2017-02-26 22:59:25 +01:00
Joseph Lenox
1f1b6c8036 Fixed a missing include. 2017-02-26 22:40:10 +01:00
bubnikv
1b89c08bfc TriangleMesh.cpp/h:
New methods: has_multiple_patches(), number_of_patches()
Improved constness of file access methods.
Reduced some memory allocations costs.
Fixed some crashes of the cut() method on invalid meshes, Slic3r crashes on the unstable triangulation now.
Documented.
2017-02-26 22:17:39 +01:00
bubnikv
5b98f1a068 Some utility methods to help loading models from the disk.
Not quite sucessfull try to fix the crahes on mesh cut.
2017-02-26 22:03:03 +01:00
bubnikv
efb02f71f0 AdMesh:
unify positive and negative zeros in stl_check_facets_exact() and stl_check_facets_nearby()
New function stl_transform() by a 3x4 matrix.
Some constness improvements.
2017-02-26 21:59:09 +01:00
bubnikv
b7aeeb968b Using the C++ file loaders. 2017-02-26 21:54:42 +01:00
bubnikv
121b3c31d2 Removed the old Perl Supports. 2017-02-26 21:49:40 +01:00
bubnikv
25dfe7278c Initial rewrite of the file accessors from Perl to C++.
This is especially important for the extremely slow AMF parser.
Also there is a new file handler for the Prusa Control 'PRUS' format.
2017-02-26 21:46:33 +01:00
bubnikv
91af2ddd1e Include expat parser into the Slic3r source code tree.
Having the expat parser inside the Slic3r source base makes life easier
on non-Linux systems and it also allows us to configure the Expat
parser for maximum performance by disabling all unneeded features.
2017-02-26 21:42:52 +01:00
bubnikv
82aed45816 Hopefully fixes the aligned seam:
https://github.com/prusa3d/Slic3r/issues/74

The way it works now is following:
Slic3r will add some negative penalty to all perimeter points near the last seam.
Once the perimeter point with minimum penalty is found, its penalty is compared
to a point closest to the last seam. If the penalty of the point
closest to the last seam is nearly as good as the minimum penalty,
the point closest to the last seam is picked instead. This heuristics
will hide the seams into corners if possible, but if not possible, it will
strive to align the seams precisely.
2017-02-22 16:35:07 +01:00
bubnikv
523b7f3ebc Fix of a typo specific to a debugging build. 2017-02-22 16:13:10 +01:00
bubnikv
f7acb20e23 Changed defaults for the perimeter/infill overlap (15-55%)
and for the infill pattern (honeycomb->stars)
2017-02-22 16:06:35 +01:00
bubnikv
a4dd6c7ce5 Added missing get_volume() method to the PrintObject Perl interface. 2017-02-22 16:05:14 +01:00
Alessandro Ranellucci
4a84643894 Fixed regression causing slowdown_below_layer_time to be ignored. #3515 #3443 2017-02-22 15:29:14 +01:00
bubnikv
9f660738b3 Fixes an issue: Slic3r outputs Weight: %.1fg, Cost: %.1f on command line,
instead of filling in the numbers.

https://github.com/prusa3d/Slic3r/issues/144
2017-02-22 12:01:31 +01:00
Alessandro Ranellucci
8174c05df4 Command for reloading an object from file. #1466 2017-02-21 17:58:48 +01:00
bubnikv
d02ee5cf80 By @lordofhyphens:
only re-zoom if we have a valid bounding box, avoid a divide by 0 error.
2017-02-21 17:43:28 +01:00
Alessandro Ranellucci
6649888d1c Support decimal scaling factors and rotation angles. #1617 2017-02-21 16:43:47 +01:00
Alessandro Ranellucci
fefba5ff1d Bugfix: --rotate did not support decimal values and interpreted them as radians. #3460 2017-02-21 16:42:51 +01:00
Alessandro Ranellucci
a8edff1e84 Always retract in bottom layers. #3053 #3618 2017-02-21 16:37:31 +01:00
Joseph Lenox
873161ea7c Only enable movers if modifier mesh. 2017-02-21 16:30:13 +01:00
Joseph Lenox
e2b56c4462 Repair the generic mesh so it can be exported. 2017-02-21 16:29:57 +01:00
Joseph Lenox
4f428fae40 Added UI options to make a slab, defaulting to the model object's bounding box * 1.5 2017-02-21 16:29:42 +01:00
Joseph Lenox
6aecae3121 UI: fixed naming sphere is not a cylinder. 2017-02-21 16:29:32 +01:00
Joseph Lenox
2971235299 UI code to generate a generic sphere. 2017-02-21 16:29:21 +01:00
Joseph Lenox
c575a1f1d6 Added make_sphere, generates a mesh with specified step angle and raidus rho. 2017-02-21 16:29:09 +01:00
Alessandro Ranellucci
ceb72da632 Implement clone() for Fill classes 2017-02-21 16:22:54 +01:00
Joseph Lenox
716dc2e650 Made cube and cylinder static functions of the package, not some specific TriangleMesh object. 2017-02-21 16:11:52 +01:00
Joseph Lenox
26b6e4c619 Disable sliders if a volume is not selected. 2017-02-21 16:11:41 +01:00
Joseph Lenox
2eea139731 UI now changes its options based on the object type selected. 2017-02-21 16:11:22 +01:00
Joseph Lenox
3ee32ef153 Menu now works to select cylinders (reusing the gui options) 2017-02-21 16:11:09 +01:00
Joseph Lenox
f44df28a96 Fixed mesh generation to generate cylinders. 2017-02-21 16:10:54 +01:00
Joseph Lenox
b91b98b21e Added prototype make_cylinder() 2017-02-21 16:10:38 +01:00
Joseph Lenox
3bb237deee Added new constructor to TriangleMesh that accepts vectors of Points and make_cube function to make a new simple cube mesh. 2017-02-21 16:10:14 +01:00
Joseph Lenox
ff33fbbb9a Use LambdaObjectDialog in GUI.pm to avoid crash on Windows. 2017-02-21 16:09:51 +01:00
Joseph Lenox
107c89d37b Removed commented code. 2017-02-21 16:04:45 +01:00
Joseph Lenox
a0548898f3 Added a cancel button, and rewrote initial option code to reuse OptionGroup. 2017-02-21 16:04:02 +01:00
Joseph Lenox
3109a9bc1f Update main plater view after moving mesh 2017-02-21 16:03:46 +01:00
Joseph Lenox
33f489bba9 Anonymous object supports. Initial implementation provides for a box of arbitrary size. 2017-02-21 16:03:19 +01:00
Joseph Lenox
e93cc13698 Permit sliding modifer meshes around in the Settings dialog. 2017-02-21 16:02:56 +01:00
Alessandro Ranellucci
a65c9ba083 Ported CoolingBuffer to C++/XS 2017-02-21 14:02:47 +01:00
Alessandro Ranellucci
c517b0d8f1 Bugfix: object disappeared from 2D plater when reloaded from disk. #3634 2017-02-21 13:57:40 +01:00
Ralph Giles
061a79bfbd Readme improvements (#3679)
* Use svg badge for travis build status.

This avoids bluriness with high-density displays. We're already
using svg for the appveyor status.

* Update README to use https urls.

Both xkcd and freenode are available securely now.
2017-02-21 13:12:21 +01:00
Sebastianv650
b8ece2af06 Pressure advance overrides print speeds patch (#3287)
* Fix PressureRegulation.pm

Check if a pressure advance is needed even if speed is unchanged, but a discharge happened before. Restore print speed after advance / discharge. Solves #3282
2017-02-21 13:09:12 +01:00
Joseph Lenox
27a1a6609f Fixed input to bed shape dialog to catch everything that resolves to 0. Fixes #3681 (#3683) 2017-02-21 13:07:15 +01:00
Joseph Lenox
b022e51d94 Don't reset speed on flush moves (avoid use of uninitialized variable). 2017-02-21 13:02:16 +01:00
bubnikv
8aae5bdb28 The variable layer editing shader was made OpenGL 2.0 compatible.
Fixed a bug in the scaling of colors for the variable layer editing.
2017-02-21 09:39:28 +01:00
bubnikv
006173342c Fixes: Infill patterns triangles/stars seem to be mixed-up
https://github.com/prusa3d/Slic3r/issues/143
2017-02-20 22:36:34 +01:00
bubnikv
171148d3a6 Changed the platte of the variable layer height visualization,
green shall indicate a thin layer.
2017-02-20 22:22:23 +01:00
bubnikv
8cfdc28f2b Implemented a level of detail on the variable layer height editing tool. 2017-02-20 21:54:53 +01:00
bubnikv
440a5eb2a0 Fixes an ugly infinite loop issue.
https://github.com/prusa3d/Slic3r/issues/142
2017-02-19 21:45:38 +01:00
bubnikv
6e19921f98 Fix a warning on Linux / OSX. 2017-02-19 19:44:05 +01:00
bubnikv
a8eb217e4a System Info dialog made nicer.
Fixed a bug in reporting a software renderer on Windows.
2017-02-19 19:08:58 +01:00
bubnikv
898deb48c4 Error reporting on initialization of the Layer Editing OpenGL shaders.
The shaders are initialized when the layer editing button is pressed
for the first time. If the initialization fails, a message box
is shown and the layer editing will stay disabled.
2017-02-19 18:01:03 +01:00
bubnikv
70229be9bc Added SystemInfo dialog,
a new SLIC3R_BUILD define to be replaced by the build script,
a menu item to open the "New Issue" github page.
2017-02-19 16:04:57 +01:00
bubnikv
89702a5b4e Fixing an update of the "Export G-code, Send to printer" and similar buttons.
It is a bug, which was lingering around for a long time, only now
the buggy function is called at a time point, where it really hurts.
https://github.com/prusa3d/Slic3r/issues/137
2017-02-17 15:11:59 +01:00
bubnikv
31f213d6ca Hopefully fixes "Export G-Code" Disabled After First Export"
https://github.com/prusa3d/Slic3r/issues/137
2017-02-17 15:00:01 +01:00
bubnikv
17ea15eb6f Build script clean-up:
Removed a requirement on an old Perl::OpenGL library.
Removed a mention of the Perl::PlanePath library, which is no more used by Slic3r.
2017-02-15 19:31:20 +01:00
bubnikv
3bfa6416d8 Fixed https://github.com/prusa3d/Slic3r/issues/126
by re-shuffling the simplification of a path to be extruded.
A non-simplified path was being used for a wipe move before,
causing an extremely detailed path to be exported into a G-code.
2017-02-15 17:51:46 +01:00
bubnikv
2ddabe5fa8 Show the print statistics only if it has valid information to show.
The old behavior was confusing, leading to questions like the following:
https://github.com/prusa3d/Slic3r/issues/130
2017-02-15 16:02:54 +01:00
bubnikv
4d739c41a0 Improvements of the layer height spline editing close to the top
of the object.
2017-02-15 14:39:08 +01:00
bubnikv
d2d7c5bead Fixed trimming of support volumes by objects for the soluble supports
and for the raft contact layer over soluble supports.
https://github.com/prusa3d/Slic3r/issues/120
2017-02-15 13:34:17 +01:00
bubnikv
35490216a7 Fixes the order of a skirt, raft, support & object on the 1st layer. 2017-02-15 12:31:14 +01:00
bubnikv
d67de182a0 fix of C++11 gcc incompatiblity 2017-02-15 11:16:39 +01:00
bubnikv
3d11d1aebf make_skirt ported to C++ 2017-02-15 11:05:52 +01:00
bubnikv
90028e47e9 Added the append templates for std::vector 2017-02-15 11:03:19 +01:00
bubnikv
f5e4026aee Fixed some of the raft issues introduced in the new C++ supports. 2017-02-14 19:49:30 +01:00
bubnikv
420e387055 new feature: Clip multi-part objects one by the other.
This works the same way as if the XY compensation was set to a tiny value
before, but without the overhead of an offset.
2017-02-14 12:36:04 +01:00
bubnikv
ce8973b33a Fixed a bug in renaming a G-code at the end of a G-code export
from .tmp suffix to a non .tmp file on localized Windows.
2017-02-13 15:45:31 +01:00
bubnikv
fd54956d70 Hopefuly a fix of https://github.com/prusa3d/Slic3r/issues/116
Enabling / disabling of the layer editing button on OSX & linux did not work.
2017-02-13 12:40:12 +01:00
bubnikv
e2f8ea2809 When renaming the exported G-code (removing the .tmp suffix),
some other application (thank you, Windows Explorer) may keep the file locked.
Try to wait a bit and then rename the file again.
2017-02-13 12:36:46 +01:00
bubnikv
8d6acd2aec Fix of "no support generated" https://github.com/prusa3d/Slic3r/issues/114
when a first layer height was set in percents.
2017-02-12 00:51:53 +01:00
bubnikv
61f9414b09 Fixed a bug in manipulation of multi-component bodies. 2017-02-10 11:24:54 +01:00
bubnikv
152026fa08 Disable variable layer height editing on the UI when a printer
profile is switched to one with the layer height editing disabled.
2017-02-10 10:21:50 +01:00
bubnikv
43757df016 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2017-02-10 09:41:16 +01:00
Joseph Lenox
eb9f1808c0 Test to ensure that the repetier firmware returns the correct acceleration M code and that the values are set properly. 2017-02-10 09:39:33 +01:00
Joseph Lenox
abda054720 Cherry-picked Repetier acceleration fixes, thanks to @lordofhyphens
e0d8101627
885f27b8ae

Added a printer settings to enable / disable variable layer height editing.
2017-02-10 09:39:19 +01:00
Klim
98edb4f854 fix for issue #57 (#63) 2017-02-09 21:59:57 +01:00
bubnikv
db30cee6a9 Fixed the 'iso' camera orientation. 2017-02-09 21:40:07 +01:00
bubnikv
6c4b4f4d12 Compilation fix on gcc,
fix of a maximum layer height limit for variable layer height editing.
2017-02-09 17:09:19 +01:00
bubnikv
adb218e605 Changed layer leight limits label on the UI. 2017-02-09 16:21:48 +01:00
bubnikv
b30501b411 Limit the maximum support layer height by the maximum layer height
value defined at the printer's nozzle.
Internal filtering of empty support layers to avoid generating
unnecessary Z moves.
2017-02-09 16:19:14 +01:00
bubnikv
0aa66b9608 Added var/variable_layer_height_reset.png - a reset button image
for the variable layer height bar.
2017-02-09 14:57:11 +01:00
bubnikv
88e34ff5de Store / retrieve layer height profile from the AMF file.
Reset the layer height profile when changing a print profile to an incompatible one.
Reset button on the layer height bar.
Fixed an update issue on zooming by a scroll wheel.
Fixed an issue when loading an AMF file: Object names are now retained.
2017-02-09 14:56:13 +01:00
Joseph Lenox
61c0ae4e94 Changed filament density to use g/cm^3. Extended tooltip to indicate calculation methods. 2017-02-08 11:40:52 +01:00
Joseph Lenox
90d3535520 Added second information box that populates after exporting gcode for sliced statistics. 2017-02-08 11:40:36 +01:00
Joseph Lenox
203a965b3d added total cost/weight to Extruder statistics, mocked up addendum to status bar change. 2017-02-08 11:40:01 +01:00
Joseph Lenox
3846d9e734 Add weight/cost output to gcode. On the way to #647 2017-02-08 11:39:45 +01:00
Alessandro Ranellucci
bbd63616b1 Write to a temporary file before renaming with the final name. #1844 2017-02-08 11:27:15 +01:00
bubnikv
6b1a72aac9 Fix of Post processing scripst not working:
https://github.com/alexrj/Slic3r/issues/3698

This is really a patch as it does not let the user to use the semicolon
inside a script invocation line.
2017-02-08 10:35:21 +01:00
bubnikv
e7718b385f Added a "variable layer height" icon, active on OSX initially. 2017-02-07 19:01:58 +01:00
bubnikv
957803e60c Added min_layer_height, max_layer_height per nozzle settings
for controlling the support layer height & variable layer height.
Added an experimental "rear" seam option.
2017-02-07 18:46:02 +01:00
bubnikv
64c752ff9d Extended the Slic3r::GUI::Tab::XXX::_update mechanism to deliver
a set of updated config keys.
2017-02-07 18:41:09 +01:00
bubnikv
e386a2bf72 Documentation of the UI config update functions,
documented missing AMF support for the variable layer thickness.
2017-02-07 18:28:53 +01:00
bubnikv
43ac693900 Added a tooltip overlay for the variable layer height edit tool.
Short methods of PrintState made inline.
Added layer height profile to a Model class.
2017-02-07 18:17:12 +01:00
bubnikv
aceb87d188 Change of defaults. Background processing disabled by default,
default mode set to expert.
2017-02-07 13:21:09 +01:00
bubnikv
8474f77db4 Enabled the variable layer height in the builds by default. 2017-02-03 15:53:31 +01:00
bubnikv
7e6390c4b6 Avoid placement of seams on bridging perimeters, if random seam is enabled.
https://github.com/alexrj/Slic3r/issues/3526#issuecomment-263125049
2017-02-02 18:49:33 +01:00
bubnikv
4256af22ff Created a total_lengt() free function for Polygons and Polylines.
Modified the "extra perimeters when needed" function to use the new free functions,
extended the tooltip of the "extra perimeters when needed" feature.
2017-02-02 16:03:32 +01:00
bubnikv
c25ae35737 Fix of https://github.com/prusa3d/Slic3r/issues/75
Fixed by @alexr 8f0d8f2096
See also https://github.com/alexrj/Slic3r/issues/3613 https://github.com/alexrj/Slic3r/pull/3614
2017-02-02 15:09:22 +01:00
bubnikv
c2ddf537c6 Fixed a newly introduced bug in the multi material UI dialog. 2017-01-31 11:38:07 +01:00
bubnikv
817d827f7a GCodeWriter - made tiny methods inline. 2017-01-30 19:57:20 +01:00
bubnikv
4ab972b87a When the support extruders are set to 0, support is printed with the current material without a tool change.
A fix of support path generator.
2017-01-30 19:56:46 +01:00
bubnikv
4e90ae9a28 FillRectilinear2:
Fix of a degenerate case, where there is a vertical segment on this vertical line and the contour
follows from left to right or vice versa, leading to low,low or high,high intersections.
2017-01-29 00:20:09 +01:00
bubnikv
0ca230a197 Supports - trimming base support layers with the bottom surfaces. 2017-01-26 12:02:10 +01:00
bubnikv
22124e5f61 Multiple bug fixes in the new support generator to guarantee gap
between object and support.
2017-01-25 18:33:05 +01:00
bubnikv
a74aaca681 Disable support interface loops by default. 2017-01-25 18:29:10 +01:00
bubnikv
1699864b8a utility class ClosestPointInRadiusLookup 2017-01-25 18:26:06 +01:00
bubnikv
c5843988c0 ExtrusionEntity - add only valid polylines 2017-01-25 18:25:14 +01:00
bubnikv
40eaf144f0 new function remove_degenerate(Polylines ...) 2017-01-25 18:23:57 +01:00
bubnikv
c46b6ca27e ExtrusionMultiPath perl binding - polyline() method. 2017-01-25 18:22:29 +01:00
bubnikv
081c1d681c Fixed preview of ExtrusionMultiPath instances. 2017-01-20 20:20:41 +01:00
bubnikv
c0b3de6248 Hopefully fixes https://github.com/prusa3d/Slic3r/issues/90
Latest master segfaults with perl 5.24.1 #90
The fix achives similar goal to https://github.com/alexrj/Slic3r/pull/3575
but it is simpler.
2017-01-20 16:56:37 +01:00
bubnikv
3985f50c5b Added new file: ExtrusionMultiPath.xsp
Fixed a missing copy constructor of ExtrusionPath.
2017-01-20 15:41:50 +01:00
bubnikv
ff25c0ccc2 Improvements of the new support generator:
Variable path thickness for all support layers to avoid over-extrusion.
Supports only in grid cells below the top contacts.
Provision for filtering excessively long perimeter pieces of the support infill lines.
2017-01-20 15:21:05 +01:00
bubnikv
08351b5e48 Fix of ExtrusionMultiPath binding to Perl & G-code generator. 2017-01-20 15:17:32 +01:00
bubnikv
29b986fa76 Improvement of the move semantics on various objects:
The source object will be empty after the move operation.
2017-01-20 14:39:44 +01:00
bubnikv
d5f9db76b3 Fix of an inconsistent bottom contact layer thickness
in case two and more bottom contact layers overlap after their extension.

New method modulate_extrusion_by_overlapping_layers() reduces thickness
of an extrusion path where it overlaps in Z with some other paths.

The same trick has yet to be applied to the layers overlapping in Z with
top contact surfaces.
2017-01-19 13:47:06 +01:00
bubnikv
0b90ebd74e Move semantics on MultiPoint, Polygon, Polyline.
Append methods on Polyline.
squared length function on point->DistanceTo
2017-01-19 13:43:29 +01:00
bubnikv
50cdf8e6d1 Move semantics for ExtrusionEntityCollection 2017-01-19 13:37:15 +01:00
bubnikv
e016c4e423 New extrusion class: ExtrusionMultiPath
This is similar to an ExtrusionLoop, but it is open.
It may contain multiple chained paths with differing parameters.
This allows one to have a hierarchy of paths, where the ExtrusionEntityCollection
will be chained by the G-code generator, but ExtrusionMultiPath will not.
2017-01-19 13:35:55 +01:00
bubnikv
e6b441eea4 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2017-01-16 10:57:06 +01:00
bubnikv
4eed07bbab Fix of the 1st support layer. 2017-01-16 10:56:40 +01:00
bubnikv
a747a87e83 Merge pull request #94 from eyal0/fix_rpi_less_than
Change char to int because char might be unsigned
2017-01-12 10:59:22 +01:00
Eyal Soha
02515350f7 Merge branch 'fix_rpi_less_than' of github.com:eyal0/Slic3r into fix_rpi_less_than 2017-01-12 11:30:57 +02:00
Eyal Soha
b851e04c17 Change char to int
char might be signed or unsigned but int is definitely signed.  This fixes prusa3d/Slic3r#93 .
2017-01-12 11:30:14 +02:00
Eyal Soha
cbebff495b Merge tag 'version_1.33.2' into fix_rpi_less_than
version 1.33.2 - alpha
2017-01-12 10:59:33 +02:00
Eyal Soha
0db4be56a5 use int instead of char 2017-01-12 10:05:59 +02:00
bubnikv
41fbec9063 Only synchronize intermediate layers if explicitely asked for. 2017-01-11 18:05:03 +01:00
bubnikv
f0cf7adf84 Bugfix of a new support - first layer thickness of the support. 2017-01-11 17:22:28 +01:00
bubnikv
c2ba5901e4 Copy / move assign operators for ExPolygon. 2017-01-11 14:38:24 +01:00
bubnikv
c632d08550 Only compile debug output functions for SupportGenerator if SLIC3R_DEBUG is enabled. 2017-01-11 14:37:53 +01:00
bubnikv
87964eb57a Move semantics for the ExPolygon constructor. 2017-01-11 13:44:11 +01:00
bubnikv
bd3daeed5a Slightly more efficient PrintObject Layer destruction. 2017-01-11 13:43:33 +01:00
bubnikv
fa1506c833 Bugfix of duplicate support print paths. 2017-01-11 13:42:41 +01:00
bubnikv
d9ea3df85f Another step to make the new C++ supports working.
Added support_material_xy_spacing configuration.
2017-01-05 09:14:59 +01:00
bubnikv
1ba03af2da Made the config value support_material_xy_spacing relative
to the external perimeter width.
2017-01-05 09:12:24 +01:00
bubnikv
bbdaa44acb Const version of a PrintObject::get_region(). Made get_region() inline. 2017-01-05 09:11:36 +01:00
bubnikv
b42c5d6dfa Extended the SVG exporting class with export_expolygons()
calculating the contour bounds internally.
2017-01-05 09:10:16 +01:00
bubnikv
aad3d4107f Improved debugging of the EdgeGrid distance field function. 2017-01-05 09:09:26 +01:00
slicer-builder
bb22f1dc8a prototyping tweakable XY supports;
option should be present now in advanced support menu.
Can't figure out what's going on atm; support should be moving but isn't
2017-01-03 11:46:52 +01:00
Joseph Lenox
f63c21f0f3 Added a feature to increase gap between object in XY and generated supports.
Advanced feature, may not generate supports that are printable.
2017-01-03 11:43:18 +01:00
Joseph Lenox
4b2bc29b14 set support spacing option if support is off 2017-01-03 11:40:45 +01:00
bubnikv
07dd06c53c Merge remote-tracking branch 'origin/supports-synchronize-layers' 2017-01-03 10:51:23 +01:00
bubnikv
7a2572a0fb Improved debugging of "ensure vertical wall thickness" feature. 2017-01-03 10:51:19 +01:00
bubnikv
17db5bff8d Fix of
Number of solid top/bottom layers ignored,
Ensure Vertical Shell Thickness interferes with solid top layer count
https://github.com/prusa3d/Slic3r/issues/79
https://github.com/prusa3d/Slic3r/issues/60
2017-01-02 16:51:43 +01:00
bubnikv
479f716625 Improvements in the manual layer width editor. 2016-12-21 16:00:41 +01:00
bubnikv
955bc957ba New supports now do rafts at least to the extent the test cases run through.
New supports enabled, old supports will go away soon.
2016-12-20 12:19:13 +01:00
bubnikv
5614e997a4 Merge pull request #43 from ctgreybeard/dev
xs/Build.pl fails to find boost libraries
2016-12-15 12:55:19 +01:00
bubnikv
6400cec7ae Merge branch 'master' into dev 2016-12-15 12:54:34 +01:00
bubnikv
c1f4d06be2 define -DBOOST_LOG_DYN_LINK for boost::log 2016-12-15 09:46:41 +01:00
bubnikv
56e87e3bdb Set BOOST_LOG_DYN_LINK symbol when linking with dynamic boost libraries. 2016-12-14 16:51:27 +01:00
bubnikv
a870b69733 Fixed static linking against boost. 2016-12-14 15:43:26 +01:00
bubnikv
ff0a8956ee Fixed previous checkin. 2016-12-14 15:42:38 +01:00
bubnikv
c79e1cc89b Fixed UI bug on OSX, experimental features made switchable through
environment.
2016-12-14 15:36:18 +01:00
bubnikv
79ff013ea7 Fixed crashes on shader destruction on OSX. 2016-12-14 15:09:12 +01:00
bubnikv
ae2e37b4bd Added diagnostics of @LIBS, @INCS to the Build.PL
Extended MANIFEST with new files.
2016-12-13 22:46:28 +01:00
bubnikv
2cd96cabcd Another take to get rid of the templates from the ClipperUtil.hpp
to compile cleanly on OSX.
2016-12-13 22:13:02 +01:00
bubnikv
852b542913 Had troubles with the template instantiation on OSX, so I reverted
them to overloaded functions. This is certainly easier to read and
work with anyway.
2016-12-13 21:30:56 +01:00
bubnikv
ddea33d93a Fixed compilation of ClipperUtils on GCC, which is more strict
than VS2013 compiler.
2016-12-13 19:52:28 +01:00
bubnikv
e64dcf5e59 VS2013 could compile this, let's hope GCC will as well. 2016-12-13 19:39:20 +01:00
bubnikv
6582182e0c Adapted to the new ClipperUtils.hpp interface by @alexrj 2016-12-13 19:22:23 +01:00
bubnikv
b2a5a1d22f Added a move constructor / assignment operator to the old Clipper library
PolyTree class.
2016-12-13 18:59:18 +01:00
bubnikv
e22d007ab7 Fixed typo, missing class name. 2016-12-12 23:46:50 +01:00
bubnikv
06540f73f7 Try to fix compilation problems due to Perl crazy macros. 2016-12-12 19:13:33 +01:00
bubnikv
ce7717e450 Fix compilation on Linux. 2016-12-12 18:59:35 +01:00
bubnikv
e5b77e08de Perl crazy macros strike again, they collide with boost threads. 2016-12-12 18:55:04 +01:00
bubnikv
46b44fc141 User interface of the variable layer thickness. Certainly not finished yet,
but sufficient for evaluation of the prints.
2016-12-12 18:02:24 +01:00
bubnikv
2d030f3a3c Most of the slicing code rewritten to C++. 2016-12-12 17:56:37 +01:00
bubnikv
1ea958158a Support for user definable variable layer thickness, the C++ backend. 2016-12-12 17:53:38 +01:00
bubnikv
2ab86a4895 ConfigOptionVector::get_at(idx)
Avoid using exceptons for normal work flow. Assert if the vector is empty.
2016-12-12 15:56:42 +01:00
bubnikv
d775c6c14c Added methods set/add to SurfaceCollection. 2016-12-12 15:54:37 +01:00
bubnikv
333a0b1c0e Shortcuts for zero mesh transformations. 2016-12-12 15:52:04 +01:00
bubnikv
933a0db9ed Minor fix of bridging flow, see @alexrj 3a3b24ec7c803c58919a5401e5804261999875b4 2016-12-12 15:33:14 +01:00
bubnikv
126126cc78 Fixes after the merge of changes by @alexrj. 2016-12-08 19:02:16 +01:00
bubnikv
5d18657ac5 Don't be lazy, use fully qualified Slic3r::Polygon/ExPolygon/Point/Line names 2016-12-08 15:16:09 +01:00
Alessandro Ranellucci
24e0b568b5 Fix compilation, cherry picked from @alexrj fde6e2e61deabd097a3bf565d4948077147b25ab 2016-12-08 15:01:36 +01:00
Alessandro Ranellucci
a26330a292 Try to fix compilation problem with Boost 1.54. #3595 2016-12-08 14:56:13 +01:00
Alessandro Ranellucci
9c0c05631c Ignore failure to call SetAutoPop when not available. #3596 @alexrj 2e82fb01a65deb4e0872de9219f47e58b7000ebf 2016-12-08 14:55:48 +01:00
Joseph Lenox
a8930f12cd Fix perl redefining multiple functions also defined/used by boostlib through the include chain. (#3593)
Resolved ordering dependency (thanks win32 perl!)
2016-12-08 14:53:52 +01:00
Alessandro Ranellucci
5dc8a0808e Maybe the Travis CI server has more than 16 cores? 2016-12-08 14:52:42 +01:00
Alessandro Ranellucci
d8082b9db4 Try to fix compilation error about the new threads default 2016-12-08 14:52:15 +01:00
Alessandro Ranellucci
9e8dae817d Fixes and improvements to the view selection menu, cherry picked from @alexrj a7693c4719c0e0e0129aea7461706d2ed53a52cc 2016-12-08 14:51:35 +01:00
Alessandro Ranellucci
d628764da6 Minor fixes to parallelize code, cherry picked from @alexrj 5242b3e03ab2b195ba9c7c53fba705a8ed1c7abd 2016-12-08 14:44:03 +01:00
Alessandro Ranellucci
73ddd3b438 Refactored parallelization code, cherry picked from @alexrj 36789774471a0bf9a66bb33cc3ab6984f8ede8c6 2016-12-08 14:40:47 +01:00
Alessandro Ranellucci
9fbd135f14 Automatically detect the number of cores and use that as a default for threads number 2016-12-08 14:28:36 +01:00
Alessandro Ranellucci
70a9de085b Parallelize TriangleMeshSlicer::slice(), cherry picked from @alexrj 83ad123d951c6ee663d2f3b02e095c203ca794e7 2016-12-08 14:28:09 +01:00
Alessandro Ranellucci
e9290252d6 Fixed regression in the _make_perimeters port 2016-12-08 14:25:05 +01:00
Alessandro Ranellucci
86c8207d31 Ported make_perimeters() and infill() to C++/XS, use pure C++ threads, cherry picked from @alexrj 66591bcc556c01572ec7519b1f8cb4ee2d430685 2016-12-08 14:24:40 +01:00
bubnikv
3e8cafa857 Fix of ASCII STL parser. Accept a model even with invalid normals. 2016-12-05 11:39:17 +01:00
bubnikv
330ffed87e Adjusted copyright header of the Perl GLShader module. 2016-12-02 11:19:27 +01:00
bubnikv
7e1af658b6 Initial experiments with vertex / fragment shaders,
prototype to visualize layer thickness.
2016-12-02 11:14:24 +01:00
bubnikv
bd618569e1 Print the supports before the object layer at the same height. 2016-11-30 18:54:19 +01:00
bubnikv
26a8017e99 Made the support interface contact loops configurable. 2016-11-30 17:33:55 +01:00
bubnikv
38cb2842ac support_material_synchronize_layers implementation 2016-11-30 16:06:12 +01:00
bubnikv
556204fddc support_material_synchronize_layers configuration value
for synchronization of object layers with print layers.
2016-11-30 16:04:15 +01:00
bubnikv
946b36bb4d Supports using the EdgeGrid simplify_contour 2016-11-29 19:30:59 +01:00
bubnikv
1d44e92a6e Point dot operator and PointHash object for std unique_xxx functions. 2016-11-29 19:29:24 +01:00
bubnikv
5c23ee504c EdgeGrid::contours_simplified for supports 2016-11-29 19:28:33 +01:00
bubnikv
ca5ad58ad2 logging of slicing process 2016-11-29 19:27:23 +01:00
bubnikv
85aa802d4b Fix of the last clipperutil safety_offset modification. Handle safety
offset of holes separately, don't forget to reverse them before / after.
2016-11-29 19:26:26 +01:00
bubnikv
792856a505 Bounding Box - new method align_to_grid 2016-11-29 19:25:10 +01:00
Bill Waggoner
50fe691604 Squashed commit of the following:
commit 7fc66514bf3fbcc2c2709a4eb94856fa9b3ba523
Author: Bill Waggoner <ctgreybeard@gmail.com>
Date:   Mon Nov 28 14:09:09 2016 -0500

    Build.pl fails to find boost libraries

commit 3fa66c4970eb2235aa57041a5a318ddcb1910219
Author: Bill Waggoner <ctgreybeard@gmail.com>
Date:   Mon Nov 28 14:00:07 2016 -0500

    Build.pl fails to find boost correctly

Signed-off-by: Bill Waggoner <ctgreybeard@gmail.com>
2016-11-28 14:28:50 -05:00
bubnikv
bde2ee6a7e Step forward in the C++ supports. 2016-11-28 17:36:50 +01:00
bubnikv
8b0784f26c Added a free "cross product" function to Pointf (thinking the Pointf is
really a vector in this case).

Made the == operator inline.
2016-11-28 17:34:52 +01:00
bubnikv
695c92fb00 CLIPPER_OFFSET_SCALE was made a power of two, the scaling functions
inside ClipperUtils are now using bit shifts instead of multiplication
by doubles, which makes the scaling precise.

Removed the scale parameter from all offset functions.

Modified the safety offset to calculate offset per polygon instead
of over all polygons at once. The old way was not safe and very slow,
sometimes this meant a kiss of death for supports for example.
2016-11-28 17:33:17 +01:00
bubnikv
e93253e270 Extended tracing of Support generator 2016-11-24 15:38:19 +01:00
bubnikv
a5b04d5cf3 Support calculation optimized. 2016-11-24 15:05:05 +01:00
bubnikv
e02755632e new Utils.hpp 2016-11-24 14:05:06 +01:00
bubnikv
0d20a81354 Log support through boost::log 2016-11-24 13:44:51 +01:00
bubnikv
e67e37c772 Supports: Disabled debugging,fix of bottom surface over print. 2016-11-24 11:29:31 +01:00
bubnikv
14df0717ca Fix of new suports. 2016-11-24 10:43:47 +01:00
bubnikv
d8be4de6cf One step further to the C++ Supports. 2016-11-23 15:51:47 +01:00
bubnikv
1a1eaa0810 increased version number. 2016-11-20 23:06:56 +01:00
bubnikv
a069c41b20 On Windows, load the icon either from the exe, or fron the ico file. 2016-11-20 14:22:26 +01:00
bubnikv
39679f9518 Missed this one at the last check-in. 2016-11-20 12:59:29 +01:00
bubnikv
ef69474636 Optimized Layer::merge_slices()
Don't merge classified pieces of layerm->slices, but use the non-split
islands of a layer. For a single region print, these shall be equal.

Added Slic3r-console.ico windows icon for the console Slic3r.
This is a copy of the big icon, with the big images stripped off.
2016-11-20 12:38:59 +01:00
bubnikv
79f5a16536 Reverted the perimeter generator to not save the perimeter areas.
These could be calculated from the fill areas if needed.
On the other side, the non-classified (non-split) fill areas are stored
now for use in the "ensure vertical wall thickness" feature,
also the non-split fill areas are re-used when recalculating the infills.
This is safer than trying to stitch the fill region together from the
classified fragments.

Modified the "ensure vertical wall thickness" feature to use the non-split
fill areas instead of perimeter areas for the calculation
of non-supported regions. This is cheaper as the fill areas contain
roughly half the edges.
2016-11-17 23:22:59 +01:00
bubnikv
2085a482c7 admesh: Fixed a problem in loading an STL when compiled with
Visual Studio 2013. Added multiple compile time checks for data
sizes and alignment. The library STL import is not big endian safe, so
added a test for endianity, modified STL export to a faster little endian only.
2016-11-17 16:57:58 +01:00
bubnikv
9772584d78 Tame the Shiny profiler. Make it switchable with define SLIC3R_PROFILE. 2016-11-16 23:11:51 +01:00
bubnikv
3d47c52b47 In "ensure vertical wall thickness", the union_ is called each time
a new layer is added to the shell. This is faster than calling union_
over all collected polygons. Also security offset has been disabled.
2016-11-16 22:16:20 +01:00
bubnikv
6a3bdf43dc ClipperUtils extended with intrusive profiling macros.
offset2() was exteded with a shortcut, if both offset directions
are of the same direction.
2016-11-16 22:12:58 +01:00
bubnikv
bcda69c1e5 Extended the Build.PL to understand an environment variable
SLIC3R_PROFILE to set the C++ symbol of the same name to enable
Shiny profiler.
2016-11-16 22:10:04 +01:00
bubnikv
c3af189045 Reduced some compiler warnings. 2016-11-16 22:09:00 +01:00
bubnikv
901ec0ad37 Disable includes inside Shiny sources when SLIC3R_PROFILE symbol is not defined. 2016-11-16 22:04:38 +01:00
bubnikv
bfbe85b5c2 Some optimization of the "ensure vertical wall thickness" feature. 2016-11-16 18:04:47 +01:00
bubnikv
e857833a91 Undef seed macro because of crazy perl macro substitutions. 2016-11-16 13:19:48 +01:00
bubnikv
a36cc6491c Fixed compilation of XS modules by undefinig the "seed" macro
redefined crazily by Perl.
2016-11-16 13:14:42 +01:00
bubnikv
1589ffb224 Fix for compilation on Strawberry Perl with C++11 enabled. 2016-11-16 13:06:51 +01:00
bubnikv
68e9ec0d41 Set the C++ version to C++11 for all compilers but Visual Studio C++. 2016-11-16 13:00:36 +01:00
bubnikv
4c407c8a59 Optimization of Model bounding box routines (avoids copying the mesh),
optimization of the admesh rotate function (also made numerically more robust).
2016-11-16 11:53:29 +01:00
bubnikv
52de3940fe Improvements of admesh robustness when loading and fixing STLs.
https://github.com/prusa3d/Slic3r/issues/33
2016-11-16 10:33:23 +01:00
bubnikv
d1d6e907c5 Positive and negative zeros are possible in the floats, which are considered equal by the FP unit.
When using a memcmp on raw floats, those numbers report to be different.
Unify all +0 and -0 to +0 to make the floats equal under memcmp.
2016-11-16 09:31:18 +01:00
bubnikv
50f06a0fe8 Increased the gimbal lock threshold to 170 degrees from 150 degrees.
This makes it possible to look at the bottom of an object.
2016-11-16 09:24:27 +01:00
bubnikv
e6d802a5ff Fixed a 64bit compatiblity in admesh, fixed a typo in TriangleMesh::swap() 2016-11-15 17:22:00 +01:00
bubnikv
7f1704b2ac Disabled live preview by default as it is not stable and/or the calculation takes too long for interactive usage. 2016-11-13 23:35:56 +01:00
bubnikv
9abe07852e Fixed https://github.com/prusa3d/Slic3r/issues/32 2016-11-12 23:20:49 +01:00
bubnikv
7ebc3b0884 Merge branch 'master' of https://github.com/prusa3d/Slic3r 2016-11-12 19:05:12 +01:00
bubnikv
b116fe287c Fixes https://github.com/prusa3d/Slic3r/issues/32#issuecomment-260135542
Reverts an inadverent bug introduced in 4460b5ce50
2016-11-12 19:04:40 +01:00
bubnikv
c1af9bda0a Merge pull request #30 from hroncok/patch-1
Update the version
2016-11-11 15:51:58 +00:00
Miro Hrončok
ec3aeb1e47 Update the version
If this version is not updated, Slic3r shows the old version
in the title bar and status bar and that can be confusing to the user.
2016-11-11 16:46:05 +01:00
bubnikv
1070f0c0af New feature: Propose to enable "detect bridging perimeters"
when the supports are first enabled. Don't check keep asking,
if the user does not want the bridging perimeters to be enabled.
2016-11-11 15:05:39 +01:00
bubnikv
f4ee87ba24 Fixed https://github.com/prusa3d/Slic3r/issues/27 2016-11-11 12:00:40 +01:00
bubnikv
c2d5b32ee2 Changed the logic of the "ensure vertical wall thickness" feature
slightly by inflating the projected top/bottom/bottom bridge surfaces
before they are added into a surface. This ensures, that the possible
projected infill areas merge with the perimeter supporting areas,
but the perimeter supporting areas will not be inflated on their own,
if there is no touching projection of a top/bottom/bottom bridge
surface.
2016-11-11 11:13:36 +01:00
bubnikv
4460b5ce50 re-wrote PrintObject::detect_surfaces_type() to C++,
Fixed some cracks in the fill surfaces created by rounding all surfaces inside detect_surface_type().

Fixed https://github.com/prusa3d/Slic3r/issues/12
Bridging-Angle not optimal

Extended the "Ensure veritcal wall thickness" mode (merged with the original discover_horizontal_shells function), but this a work in progress. Already Slic3r with "ensure vertical wall thickness" produces less spurious infills inside solids.
2016-11-10 19:23:01 +01:00
bubnikv
317e9131e8 New sparse infill: "stars" - David's star shaped infill.
This is very similar to a "triangles" infill, but maximum two lines
intersect at a single point.

added utility function get_extents_vector()
2016-11-09 15:39:12 +01:00
bubnikv
eb0ab38618 Fixes https://github.com/prusa3d/Slic3r/issues/26
Strange behavior of Extra perimeters and ensure wall thickness
Old behavior is re-enabled when ensure vertical wall thickness is off.
2016-11-09 10:24:45 +01:00
bubnikv
e15b5f4587 Fix of https://github.com/prusa3d/Slic3r/issues/16
Crashes while switching in preview through layers with arrow keys

Also added a check box to visualize a single layer only
in the 3D path view. The check box may be toggled with a 'S' key.

Added shift+U / shift+D buttons in the 3D path view to show a single
layer only.
2016-11-08 17:13:16 +01:00
bubnikv
e92501e51e Use a less aggressive positive offset for top/bottom/bridge surfaces,
when enlarging them for better anchoring.
2016-11-08 15:35:08 +01:00
bubnikv
b8590180d8 Fix of https://github.com/prusa3d/Slic3r/issues/20
Slicing preview incorrect in terms of visible solid layers
2016-11-08 15:33:13 +01:00
bubnikv
443e900e07 Fixed compilation on Strawberry 2016-11-08 11:23:08 +01:00
bubnikv
5aacc6b015 Extended exit report when catching an exception under a broken
Strawberry Perl.
2016-11-08 11:15:09 +01:00
bubnikv
2e53c06159 Finished the SLIC3R_HAS_BROKEN_CROAK magic. 2016-11-08 10:59:43 +01:00
bubnikv
eb61373b69 Compilation with an environment variable SLIC3R_HAS_BROKEN_CROAK set
will force the perl confess / croak called from a C++ code to
print an error message and exit. There is a bug in some Strawberry
Perl instalations leading to an interpreter hang up and an exit
with a reasonable message is better than that.
2016-11-08 10:49:32 +01:00
bubnikv
22ca927f12 Reworked the bridge detector to allow searching a single bridging
direction over multiple regions. This allows a single bridge to be
drawn over holes, which are too close to each other to allow
for separate bridges.
Fixes Bridging-Angle not optimal
https://github.com/prusa3d/Slic3r/issues/12

Re-allowed adaptive infill line width for solid infills. The adaptive
infill line width works in some circumstances, see Issue #15,
but the original implementation often changed the line width too
aggressively. The current implementation limits the line width change
to 20%.
Fixes Gaps between infill and perimeter leads to errors in laydown on following layer
https://github.com/prusa3d/Slic3r/issues/15
2016-11-08 09:59:25 +01:00
bubnikv
5a81731577 Implemented utility functions to operate over lines, polylines, polygons,
surfaces.
2016-11-07 22:49:11 +01:00
bubnikv
aac968162b Unit test to verify whether Slic3r would hang when croaking from
a C++ exception handler. This is an unfortunate error in some
Strawberry Perl distributions.
2016-11-06 17:42:36 +01:00
bubnikv
e9e55e7ac3 Fix missing cubic infill line, thanks @KoKuToru for pointing out the problem
and proposing a fix.
https://github.com/prusa3d/Slic3r/pull/18

Fixed a slight bug, where the infill did not take the complete area.
2016-11-06 16:03:13 +01:00
bubnikv
bfb336df0c Refactored Print::validate() method to not throw an exception, but
to return a string with an error message instead. This was necessary
to avoid a hang-up on some Strawberry Perl distributions, when
a perl "croak" function is called after a C++ exception is caught.
2016-11-05 02:23:46 +01:00
bubnikv
dfa3f8d597 Perl OpenGL 0.7 package causes crashes on many platforms.
Constrain compilation to Perl OpenGL version lower than 0.7.
897ca52654
2016-11-04 23:23:01 +01:00
bubnikv
89cf29080b Fix of https://github.com/prusa3d/Slic3r/issues/14
A to_polygons(SurfacePtrs &&) method does not make sense as
the ownership of the Surfaces stored in the pointer array is not known.
Thanks to @flannelhead for precisely pinpointing this issue.
2016-11-04 17:20:32 +01:00
bubnikv
96a1c74d45 Let's hope to fix compilation on gcc. 2016-11-04 17:09:01 +01:00
bubnikv
a10e9c6573 Fix of https://github.com/prusa3d/Slic3r/issues/13
The BoundingBox::defined flag was not set in constructor,
if initialized from min/max corners.
2016-11-04 16:49:08 +01:00
bubnikv
6217622865 Hopefully a fix of https://github.com/prusa3d/Slic3r/issues/11
Replaced eval { die } construct with a bool return value indicating
success or failure of an automatic arrangement of parts on the print bed.

Don't know exactly what is happening here, but throwing a "die" inside
a XS function and then catching it inside an eval {} block is suspcious.
2016-11-04 15:03:51 +01:00
bubnikv
3fc57ba8d8 Fixed compilation of the XS module with SLIC3R_GUI compilation flag
enabled, leading to a linkage of GL and GLU libraries.
https://github.com/prusa3d/Slic3r/issues/8
2016-11-04 01:06:26 +01:00
bubnikv
61d82b02b5 Improves https://github.com/prusa3d/Slic3r/issues/3
Limits the length of an infill connecting segment of a solid infill
to 3x the solid infill spacing.
2016-11-04 00:55:43 +01:00
bubnikv
483a658144 Method ExtrusionEntity::polygons_covered() and derived were split
into polygons_covered_by_width() and polygons_covered_by_spacing().

Bugfix of ExtrusionLoop::split_at(const Point &point),
where the split ExtrusionPaths were not initialised correctly.
2016-11-04 00:10:35 +01:00
bubnikv
f278fa454e Merge pull request #10 from flannelhead/cpp11-fix
Fix compilation with C++11 and above
2016-11-03 19:10:45 +00:00
bubnikv
7b6b609df1 ExtrusionEntity and derived classes: Documented, short methods made
inline for efficiency and readability, grow() renamed to polygons_covered().
2016-11-03 10:24:32 +01:00
bubnikv
12b7818caa Only call wxWidgets method wxApp::SetAppDisplayName for wxWidgets 3.0
and newer.
2016-11-03 09:15:30 +01:00
Sakari Kapanen
fad91b86bd unique_ptr instead of auto_ptr for C++11 and above 2016-11-03 08:18:27 +02:00
Sakari Kapanen
60ea0561ec Copy and move variants of chained_path functions 2016-11-02 22:31:03 +02:00
Sakari Kapanen
381c88ce0c Fix typos preventing compilation with CPPVER >= 11 2016-11-02 22:29:59 +02:00
bubnikv
d530bdba67 Test of a 100% coverage by the FillRectilinear2 has been disabled before,
now also the expected number of tests executed has been adjusted accordingly.
2016-11-02 17:15:05 +01:00
bubnikv
28ccb51f9b Fixed a crash when accessing a non-existing config value from C++ infill.
Disabled a test case of 100% infill coverage. This needs to be
yet improved.
2016-11-02 16:55:56 +01:00
bubnikv
a6cf6afb49 Missing #include <memory> 2016-11-02 11:13:13 +01:00
bubnikv
95ede7c4b8 Rewrote Fill2.pm to C++, deleted Perl infills for good.
Removed dependency on Perl Math::PlanePath module.
Fixed compilation with Visual Studio and SLIC3R_DEBUG: Visual Studio older than 2015 does not support the prinf type specifier %zu. Use %Iu instead.
C++11 move semantics enabled.
2016-11-02 10:47:00 +01:00
bubnikv
3a31d37d35 Fix of https://github.com/prusa3d/Slic3r/issues/5 :
missing #include <assert.h> in FillBase.hpp

Also disabled the automatic width adjustment in all the infills
by default for now.
2016-11-02 09:00:26 +01:00
bubnikv
36f51ff2bf Fixed a return value in the Config multi-string parser. 2016-11-01 14:52:44 +01:00
bubnikv
0264381f79 Missing include for memcpy for Linux. 2016-11-01 13:53:28 +01:00
bubnikv
3d3654707b Added "Notes" page to the filament configuration.
Added "filament_max_volumetric_speed", a cap on the maximum volumetric
extrusion role, filament specific. This is very useful when mixing
rigid filament with a soft filament.

Extended the import / export of multi-string values into configuration
values, including the test cases. Multi-line strings will be enclosed
into quotes, quotes escaped using a C-style escape sequences. Single
word strings could still be stored without quotes.
2016-11-01 13:41:24 +01:00
bubnikv
4e66ed81d2 Fixed the fill density for rectilinear, triangular and cubic infills.
Initial implementation of the "infill link maximum distance" feature.
Parts of the perimeter connecting two infill lines will be dropped,
if longer than a given threshold.
2016-10-27 17:03:57 +02:00
bubnikv
34fab1566f "Background slice now" function, initial implementation by @lordofhyphens
https://github.com/alexrj/Slic3r/pull/3501
2016-10-25 13:24:42 +02:00
bubnikv
34248c2fbf On Windows use the Slic3r.ico instead of the PNG file
for the application icon.
2016-10-24 18:05:26 +02:00
bubnikv
51c8d73b11 Fixed a division by zero in 3D scene, if there is nothing to show.
Improved Prusa3D icon.
2016-10-24 17:32:22 +02:00
bubnikv
741a85187c Suppress the '- default -' selection of Print/Filament/Printer settings
if there is any valid option available. This feature has been asked for
by the Prusa3D customers as the '- default -' option has nothing to do
with the actual printer and when selected accidentally, it could even
lead to a printer damage.
2016-10-24 16:07:36 +02:00
bubnikv
4524ecf66b by alexrj: Always convert strings to UTF-8 before passing them to XS 2016-10-24 14:08:22 +02:00
bubnikv
250ff451ba by alexrj: Fixes in GCodeSender to reset the connection after it breaks.
by alexrj: Fix in mouse handling of 2DBed.
by alexrj: ClipperUtils for ExPolygon vs. ExPolygon
2016-10-24 14:07:38 +02:00
bubnikv
cc8b7390ee Make sure the shells for the "ensure verticall wall thickness" feature
are thick enough to be actually filled by the rectilinear fill.
Otherwise gaps would be left in the sparse infill, causing missing
bond to the perimeters.
2016-10-22 22:25:00 +02:00
bubnikv
b28d31d0fe Fixes gaps created around the 3D honeycomb infill. The bug has been
introduced during the C++ porting of the original Perl code.
2016-10-22 21:31:39 +02:00
bubnikv
67c98eca5f Cleaned up the PNG headers of the icon files:
libpng warning: iCCP: Not recognizing known sRGB profile that has been edited
2016-10-22 17:31:41 +02:00
bubnikv
3574d68465 Changed the icons to indicate this is not the alexrj build. 2016-10-22 17:15:42 +02:00
bubnikv
20cd34a3a5 Cubic infill. 2016-10-21 18:56:55 +02:00
bubnikv
1fb57e439e Defined the +-* operators on Pointf.
Removed the deprecated VibrationLimit feature.
Added triangle infill.
The Prusa3D fork of Slic3r has been marked as "Slic3r Prusa Edition"
with menus pointing to the prusa3d/slic3r github release page
and Prusa3D drivers downloads page.
2016-10-21 16:53:42 +02:00
bubnikv
15d3e94a66 Unified the creation of paths of debugging output files
pointing to a predefined output directory.
2016-10-21 10:18:01 +02:00
bubnikv
59f3fed9f2 gcc bailed out on <cstdint> 2016-10-20 18:38:44 +02:00
bubnikv
978fca6f7c Fixed a compilation problem on OSX.
Fixed an inverted assert condition.
2016-10-20 18:34:33 +02:00
bubnikv
9e4edcd8ec Enabled the C++ fillers for all infills, not just the supports.
Made sure the C++ fillers are instantiated at the worker threads,
where there are being released.
Extended the FillRectilinear2 to calculate the contour / line intersection
with exact arithmetics, improved robustness and added error handling
and error reporting, if the contours to be filled are not correct.
2016-10-20 17:44:46 +02:00
bubnikv
f788f50b5a Disabled asserts in the release build (-DNDEBUG).
Added a safe variant of offset(const Slic3r::ExPolygon...), which offsets each loop separately.
New functions "remove_sticks" to remove zero area parts of polygons.
New functions "remove_small" and "remove_degenerate" for polygon clean up.
Extended the C++ supports, those are not finalized yet though.
2016-10-20 13:04:23 +02:00
bubnikv
53907a9cfe Fix of a crash when setting a viewport over an empty platter.
Exported bounding box 'empty' method to perl.
2016-10-18 16:44:05 +02:00
bubnikv
26349b30c5 Fixed a bug in EdgeGrid for horizontal or vertical lines ending at the grid lines. 2016-10-17 18:06:38 +02:00
bubnikv
c0956dbd34 Disable debugging output from the Filler2.pm 2016-10-17 17:16:02 +02:00
bubnikv
7fd06ef311 Removed #include <malloc.h> from the Shiny profiler as there is no
malloc.h on OSX.
2016-10-17 12:13:30 +02:00
bubnikv
6f4a04c2d7 Fix of compilation on Linux. Disable hopefully finally the Shiny profiler. 2016-10-17 10:33:23 +02:00
bubnikv
52dc18e350 Hopefully fixed compilation of the Shiny profiler on Linux,
where the Shiny profiler shall be disabled.
2016-10-17 09:55:42 +02:00
bubnikv
19312d0a1a Yet another fixes to make SupportMaterial.cpp compile on gcc. 2016-10-17 09:34:48 +02:00
bubnikv
30c1be40da Fixes of SupportMaterial.cpp 2016-10-17 09:27:20 +02:00
bubnikv
e8f73134e6 Fixed a typo, which broke compilation on GCC. 2016-10-16 23:13:43 +02:00
bubnikv
75ee1baf1d Another tiny change to support non C++11 compiler. 2016-10-16 23:05:47 +02:00
bubnikv
a7c53c7f5f Disable C++11 hash feature in C++ Supports to compile on Strawberry. 2016-10-16 22:56:21 +02:00
bubnikv
47cc9687a0 Added a new switch: ensure_vertical_shell_thickness
This enables a zig-zag infill similar to Cura or Simplify3D
on overhangs.
2016-10-16 22:11:19 +02:00
bubnikv
7d7f093120 C++ supports sketched, but not finalized yet. Slic3r is still using
the old Perl supports, but this time with the C++ fillers.
2016-10-16 16:30:56 +02:00
bubnikv
8f40d9b34e Initial implementation of C++ supports,
some documentation of the existing code.
2016-10-13 16:00:22 +02:00
bubnikv
c16eca0065 Improvements of the C++ RectInfill2 code for supports:
Make the contours more continuous.

Some documentation, asserts and such.
2016-10-06 21:41:52 +02:00
bubnikv
ee4b9ab82f Select standard camera views (left / right / top / bottom / front / rear / default)
by menu.
2016-10-05 14:13:07 +02:00
bubnikv
5268574ade Made the sheath around the base support configurable. Without the sheath
it is easier to remove the support, but the support is more fragile.
2016-10-04 14:38:13 +02:00
bubnikv
5bb37ad2c4 A new feature "support_material_buildplate_only" implemented.
Also a bug has been fixed for zero interface layers. Before
slic3r would put infinite number of interface layers over top surfaces,
if the number of interface layers was set to zero.
2016-10-04 13:54:10 +02:00
bubnikv
ae2bae137a Added a low layer slider into the 3D preview window.
This is to limit the preview to a span of layers.
2016-10-03 17:01:29 +02:00
bubnikv
b7af7276c9 Instantiate the new C++ filler. It will be used for the supports first. 2016-10-03 16:59:00 +02:00
bubnikv
d2635ab799 Finished merging of bridging regions. 2016-09-30 16:11:19 +02:00
bubnikv
3a81e6bee4 Bugfix of bottom bridges. If close regions shall be closed by bridges,
these regions are grown to anchor the bridge lines to the bottom surface.
The grown regions may overlap. In that case the regions are now merged
before the bridging direction is calculated for the merged region.
2016-09-30 15:23:18 +02:00
bubnikv
b5e24d3527 Fix of a test case of PerimeterGenerator. 2016-09-28 11:17:59 +02:00
bubnikv
403329db49 Misc bugfixes. 2016-09-26 13:58:47 +02:00
bubnikv
790b640521 Visualization of fill surfaces. 2016-09-26 13:56:24 +02:00
bubnikv
e0d1aa8a1a Collect the perimeter surfaces when generating perimeters.
The perimeter surfaces are later used for performing infill
below overhangs and to maintan configured vertical wall thickness
at sloping surfaces.
2016-09-26 13:44:23 +02:00
bubnikv
8f04f5d5f6 Don't adjust width of infill. It produces dangerously wide fills.
If the infill flow adjustment is enabled, report cases,
where the infill flow grows over the limits.
Make the internal bridging infill 50% sparse.
2016-09-26 13:38:37 +02:00
bubnikv
6950ce3bcf Report when the threading is disabled and when the debugging output
is enabled.

Two new environment variables are respected:
SLIC3R_SINGLETHREADED and SLIC3R_DEBUGOUT.
2016-09-26 12:57:15 +02:00
bubnikv
c514e731da Documented the bridge detector. 2016-09-26 12:53:41 +02:00
bubnikv
feb269c97c G code generator will include marks for the G-code analyzer, so
the path preview will be colored with a fine granularity.
2016-09-26 12:52:40 +02:00
bubnikv
8564ac391c Test case for Bugfix: use Lift-z option for 2. extruder #3385
thanks to
https://github.com/platsch
2016-09-26 12:50:05 +02:00
bubnikv
088b0dab90 Bugfix: use Lift-z option for 2. extruder #3385
Thanks to https://github.com/platsch
https://github.com/alexrj/Slic3r/pull/3392
2016-09-26 12:49:29 +02:00
bubnikv
edc70e27d9 New routines for debugging visualization of surfaces & infills. 2016-09-26 12:45:23 +02:00
bubnikv
4046552dd1 Documented MultiPoint. 2016-09-26 12:44:45 +02:00
bubnikv
758458e5a0 PressureEqualizer - fixed compiler warnings, documented. 2016-09-26 12:44:03 +02:00
bubnikv
4a13efd081 Surface / Surface Collection - optimization routines for filtering,
routines for visualization.
2016-09-26 12:42:44 +02:00
bubnikv
a506030082 Draft of a 3D toolpaths preview. 2016-09-26 12:38:29 +02:00
bubnikv
03b1312f2d G-code analyser, first draft. The G-code analyser will be used
for advanced visualization of the printing paths, including
the extrusion types.
2016-09-26 12:37:54 +02:00
bubnikv
565146d9d1 Fix of a spiral vase with realtive extruder distances enabled.
The clone function is used by the SpiralVase.pm only, so the change
is safe.
2016-09-23 12:59:20 +02:00
bubnikv
6e97b9bb73 Optimization of the layer offsets in 3D visualization. 2016-09-15 12:26:53 +02:00
bubnikv
459a42aab6 Fixed a bug in conditional compilation of the Shiny profiler. 2016-09-15 00:57:40 +02:00
bubnikv
a53bd3dfe9 Generate multiple vertex lists rather than requesting a single huge
memory block.
2016-09-15 00:06:42 +02:00
bubnikv
2a5095a1ea OpenGL support through GLEW. Only active if compiled with SLIC3R_GUI=1. 2016-09-14 16:31:26 +02:00
bubnikv
266e1c4be1 Initial commit of the GLEW library for calling OpenGL from the C++ code. 2016-09-14 14:07:41 +02:00
bubnikv
b1575b4dcb Integration of the Shiny lightweight intrusive profiler. 2016-09-14 11:43:38 +02:00
bubnikv
4c67230436 Documented the purpose of various perl modules. 2016-09-14 11:22:41 +02:00
bubnikv
55218c8c4d Documented.
Fixed rough Z buffer quantization issues with ortographic camera.
Initial implementation of a perspective camera.
2016-09-14 09:38:59 +02:00
bubnikv
17d9c8c9dd fixes for gcc: Missing include float.h 2016-09-13 15:59:23 +02:00
bubnikv
7d56827e26 updated for older gcc 2016-09-13 15:29:31 +02:00
bubnikv
f73ca007e6 Fixed compilation on old gcc. 2016-09-13 15:15:44 +02:00
bubnikv
15c1edd552 Configurable volumetric extrusion rate slope. 2016-09-13 15:02:28 +02:00
bubnikv
620c6c7378 Ported from the playground branch. Various documentation and optimization. 2016-09-13 13:30:00 +02:00
bubnikv
a5b7f14dfa Updates in the C++ infill code. 2016-09-13 11:26:38 +02:00
bubnikv
b2a6f43923 Documented perl modules. 2016-09-13 11:24:55 +02:00
bubnikv
6dfe4c0b96 Debugging code: Storing the test STLs inlined in the Perl code into a file. 2016-09-13 09:48:29 +02:00
bubnikv
068f71847e Some inlining optimizations. 2016-09-13 09:46:41 +02:00
bubnikv
c443f49da3 Fix in splitting the loop at a new point. 2016-09-13 09:44:30 +02:00
bubnikv
f518e0675c Initial commit of the new Pressure Equalizer, the EdgeGrid
signed distance field structure.
The EdgeGrid is used to avoid placing the seams on overhangs.
2016-09-12 16:25:15 +02:00
bubnikv
73cbb4b5dc some optimizations of Point rotation 2016-09-12 13:52:31 +02:00
bubnikv
9a83d4e8d5 Reverted some now unnecessary changes. Reverted the infill to the original perl implementation. 2016-09-12 13:26:17 +02:00
bubnikv
9fcc8fe9ae Meged with release_candidate_1_3 2016-09-12 11:29:39 +02:00
bubnikv
ca98e2655a New command line option: --dont-arrange
Don't arrange the objects on the build plate. The model coordinates
define the absolute positions on the build plate.
The option --print-center will be ignored.

Also there is a fix in the command line invocation of --duplicate-grid
so it will run, but still there is something broken there and the results
are not correct.
2016-09-05 11:32:58 +02:00
bubnikv
ab357c75a5 Updated xs/Build.PL to support Visual Studio compiler suite.
Updated xs/Build.PL to understand BOOST_LIBRARY_PATH and
BOOST_INCLUDE_PATH environment variables. This way one may easily
switch between various boost builds.

Some minor tweeks were done to make Slic3r compile with
Visual Studio 2013.
2016-08-21 21:46:17 +02:00
bubnikv
bd23fe9c44 Fixed a crash in a constructor of FullPrintConfig due to an incorrect use
of virtual inheritance. Note that an invocation of ConfigBase::optptr()
is routed to FullPrintConfig::optptr() for all classes of the FullPrintConfig
hierarchy. FullPrintConfig::optptr() in turn invokes optptr()
of PrintObjectConfig, PrintRegionConfig, PrintConfig and HostConfig.
Due to the use of virtual inheritance, this all happens, when
PrintObjectConfig gets constructed as part of FullPrintConfig, but
at that time PrintRegionConfig, PrintConfig and HostConfig are not
constructed yet. Accessing them at that time leads to crashes,
when compiled with Visual Studio 2013 compiler. For some reason
the code generated by gcc does not crash, but I believe the behavior
is undefined and it is better to be fixed anyway.

The patch solves the problem by calling set_defaults() by the topmost
object, which not only fixes the crashes, but also avoids repeated
initialization.
2016-08-21 19:09:31 +02:00
bubnikv
3e8575c931 Documented the build process 2016-06-27 15:28:13 +02:00
bubnikv
1c1542dd94 Revert "Documented the build process"
This reverts commit 5e7aee217e.
2016-06-27 15:22:58 +02:00
bubnikv
5e7aee217e Documented the build process 2016-06-27 15:15:06 +02:00
Vojtech Bubnik
7649a1df41 Merge branch 'master' of https://github.com/alexrj/Slic3r into release_candidate_1_3 2016-06-03 17:45:05 +02:00
bubnikv
e0b9865386 Fix of a crash when the Print Bed dialog is reopened after the bed shape
was defined with an STL.
Fix of rendering on Windows, refresh on resize.
2016-06-03 17:21:47 +02:00
bubnikv
ef0d22be30 2D platter rendering fixed on Windows, and the background color fixed
on Linux/GTK.
2016-06-03 15:23:03 +02:00
bubnikv
62b440ff6c Fixes a performance issues on Windows, where the cut is being
refreshed many times for a single move of the Z plane.

Fixes a problem on Windows, where the new wxWidgets always returned
Cancel, even if the window was closed with the "Cut" button.

Improved performance if the live preview is disabled or not needed,
because both top and bottom parts shall be displayed.
2016-06-03 10:35:39 +02:00
bubnikv
5573faec6b Moved the Bonjour discovery to Tab.pm,
when no Bonjour devices found, a simple message box is shown.
Otherwise the Bonjour selection dialog with an empty list crashes on windows.
2016-06-03 09:36:23 +02:00
Joseph Lenox
2230652218 Added simple JSCAD modifier helper
Simple cube oriented around the center with a parametric interface. Just copy/paste into openjscad.org and hit shift+enter.
2016-06-02 19:18:29 -05:00
Joseph Lenox
2e1a3eaf16 Merge pull request #3353 from alexrj/feature-3308
Post process script for fan kickstart
2016-06-02 11:44:48 -05:00
Joseph Lenox
5e17746427 Post process script for fan kickstart
Addresses #3308
2016-06-02 11:43:34 -05:00
Joseph Lenox
7b334bf2e5 Merge pull request #3351 from VanessaE/patch-1
Mention anti-ooze sacrificial skirt feature.
2016-06-01 16:48:48 -05:00
Vanessa Ezekowitz
39dfee79c7 Mention anti-ooze sacrificial skirt feature. 2016-06-01 17:47:54 -04:00
bubnikv
bb9c3dd9ce Fix of git #3293: More efficient GCode export
This fixes two problems of repeatedly copying data from the C++ layer
to perl, by factoring the copying out of an inner loop.
2016-06-01 20:58:05 +02:00
Joseph Lenox
08a2775dbd Update solid_layers.scad
Oops, left a hardcoded 0.3 in. Fixed.
2016-05-31 19:14:20 -05:00
Alessandro Ranellucci
2a8c139ca4 Add XYZ homing button to printer manual control 2016-05-31 15:02:56 +02:00
Alessandro Ranellucci
30f6e4b16f Bugfix: homing was not correctly saved 2016-05-31 15:02:55 +02:00
Joseph Lenox
00ab6af046 Merge pull request #3346 from lordofhyphens/feature-1129_899
Added a short OpenSCAD utility
2016-05-29 11:01:38 -05:00
Joseph Lenox
ea9b10c764 Added a short OpenSCAD description to aid in the creation of simple modifier meshes that describe a change every N layers 2016-05-29 10:56:21 -05:00
bubnikv
ab9e3b718c Support multi sampled anti-aliasing with wxWidgets 3.0.3. 2016-05-27 23:38:45 +02:00
Alessandro Ranellucci
9e8022f6f6 More refactoring to medial axis and gap fill, more robust 2016-05-20 17:03:57 +02:00
Joseph Lenox
b068616366 Merge pull request #3120 from Vicious-one/patch-1
Fix for #3069
2016-05-18 23:01:19 -05:00
Joseph Lenox
f2e8c6f3bd Merge pull request #3262 from hyperair/fix-autospeed-F0-moves
Don't use equality comparisons for floats
2016-05-18 22:07:34 -05:00
Joseph Lenox
3d34bed0e3 Merge pull request #3326 from hyperair/fix-cooldown-verbose
Fix cooling not working if !gcode_comments
2016-05-18 21:42:29 -05:00
Joseph Lenox
6122056517 Merge pull request #3330 from prusa3d/release_candidate_1_3
allow to hide the "controller" tab
2016-05-18 21:31:27 -05:00
bubnikv
d8be976356 The "controller" tab and the settings of the USB/serial connection was
made configurable. Now one may hide the "controller" tab and the USB/serial
connection configuration from the preferences. This is useful for someone,
who never connects his printer to the computer by a cable.
2016-05-16 23:57:53 +02:00
Chow Loong Jin
209b919fe6 Fix cooling not working if !gcode_comments
The cooling markers were being passed into GCodeWriter::set_speed() as a
comment which were being ignored if gcode_comments was false.

Fixes: #3325
2016-05-12 23:35:39 +08:00
Vojtech Bubnik
d022493297 Merge remote-tracking branch 'upstream/master' 2016-05-03 22:05:31 +02:00
bubnikv
79c5e0a52d Optimize remove_duplicate_points. 2016-04-15 18:01:08 +02:00
bubnikv
42d9db04f2 Don't crash, if the number of lines to display is zero. 2016-04-15 17:58:29 +02:00
bubnikv
83166a7ff3 Close SVG file when the object gets deallocated. 2016-04-15 17:57:38 +02:00
bubnikv
3a0172888a Adapted to the new infills. 2016-04-15 17:54:47 +02:00
bubnikv
ab5e01d114 Adapted to the new infills.
New infills process a not yet shrunk expolygon.
2016-04-15 17:51:11 +02:00
bubnikv
f3bda8a57a Disable optimizations and debug check even in debug mode. 2016-04-14 11:17:44 +02:00
bubnikv
23a5edbd11 Breaking into the debugger from the menu. This may be useful in Windows. 2016-04-13 20:51:03 +02:00
bubnikv
d6b53d18b8 Optimized and improved rectilinear fill. 2016-04-13 20:46:45 +02:00
bubnikv
f767ce816b Optimized and improved rectilinear fill. 2016-04-13 20:45:44 +02:00
Joseph Lenox
510ca9f9e2 Merge pull request #3303 from hyperair/fix-cooldown
Changes to properly detect extrusion moves for "layer cooldown" slowdowns and properly calculate time required to complete moves.
2016-04-12 12:50:43 -05:00
Chow Loong Jin
3d73fbf5fd Use float for elapsed_time
When accumulating elapsed_time from many moves that take less than 1
second, elapsed_time does not get incremented because (unsigned int)0.9
= 0.
2016-04-13 01:13:42 +08:00
Chow Loong Jin
4c622c504f Account for travel moves in elapsed_time 2016-04-13 01:13:39 +08:00
Alessandro Ranellucci
a54edf8fbc Support static linking of the Boost libs 2016-04-11 22:14:12 +02:00
bubnikv
3b81bf0e33 Remove some debugging info. 2016-04-11 17:48:27 +02:00
bubnikv
3ba625da22 Revert incorrect checkins. 2016-04-11 17:34:15 +02:00
bubnikv
ed83ff37f8 Simulation of extrusion in a plane, useful for finding out under / over-extruions. 2016-04-11 17:10:13 +02:00
bubnikv
9716ee8eca Interface to a filler, ported from Perl to C++. 2016-04-11 17:09:15 +02:00
bubnikv
be3e4caf1d Fills were reimplemented in C++.
While reimplementing the FillPlanePath code, the octagon infill was fixed to extrude the right amount of material.
2016-04-11 17:08:30 +02:00
bubnikv
7da68c91a5 Vojtech likes to use Sublime on Windows to get the wheels rolling. 2016-04-11 17:05:58 +02:00
Alessandro Ranellucci
f66585c250 Fixed compilation on OS X 2016-04-11 12:04:54 +02:00
bubnikv
d392858ee3 The chaining and leftmost_point methods were rewritten as static methods, so they may be called on Polylines without having to convert to PolylineCollection first. 2016-04-10 19:32:39 +02:00
bubnikv
6c5c9eddba Fixed a typo when SLIC3R_DEBUG is active. 2016-04-10 19:13:08 +02:00
bubnikv
bcfbe02c8d New method to rotate only polygons, not translate.
New free function to_polygons. Whithout this function one needs to construct the ExPolygonCollection, which means a deep copy.
2016-04-10 19:12:32 +02:00
bubnikv
023310882f Added a macro SLIC3R_CPPVER to indicate the C++ language version supported by the compiler. 2016-04-10 19:07:34 +02:00
bubnikv
7d54e28e30 Added optimized methods for point and polyline rotation.
Existing methods for rotation were optimized by calculating the sin/cos values once only.
Added an operator- for points.
2016-04-10 19:06:46 +02:00
bubnikv
c8ff517389 New constructors for the bounding box with min/max points were added.
empty(bbox) function template was added.
2016-04-10 19:02:00 +02:00
bubnikv
33ddb13e5d Use CLIPPER_OFFSET_SCALE instead of a numeric value. 2016-04-10 18:58:12 +02:00
Chow Loong Jin
a94402a8a2 Update tests for new GCode style and markers 2016-04-10 16:40:18 +08:00
Chow Loong Jin
2e2e4e68d3 Fix layer time slowdown
The recent GCode writer changes which put the speed changes on a line of
their own have caused the layer time slowdown to be ignored by the regex
in CoolingBuffer.pm.

Fixes: #3134
2016-04-10 16:10:18 +08:00
Alessandro Ranellucci
82b07a02fa One more year 2016-04-09 19:11:50 +02:00
Alessandro Ranellucci
f006e66549 Refactored calls to Wx::Bitmap->new 2016-04-09 19:10:57 +02:00
bubnikv
4156b51c18 Debugging visualization of the gap fills into a SVG format, if SLIC3R_DEBUG is set. 2016-03-27 10:53:59 +02:00
Alessandro Ranellucci
9576973b57 Tune gap fill and thin walls to less extreme values 2016-03-26 18:37:37 +01:00
Alessandro Ranellucci
36d5272f05 Filter gap fill using length relative to the actual width. #2781 2016-03-26 18:10:17 +01:00
Alessandro Ranellucci
fd4f5e40ca Actually add CONNTRIBUTING.md, not included in f5a5eb3736 2016-03-26 12:22:34 +01:00
Alessandro Ranellucci
660b56acb5 Fixed type error 2016-03-26 12:21:54 +01:00
Alessandro Ranellucci
f5a5eb3736 Moved CONTRIBUTING.md to .github/ 2016-03-26 10:57:35 +01:00
Alessandro Ranellucci
7041bb5bd9 Rewritten the medial axis algorithm, now more robust (don't just prune MAT from endpoints, but validate all single edges) 2016-03-26 01:45:08 +01:00
Joseph Lenox
e4147a6bed Merge pull request #3284 from lordofhyphens/gh2
Update ISSUE_TEMPLATE.md to hopefully make issues less free-form.
2016-03-20 13:46:18 -05:00
Joseph Lenox
bfa12e5a66 Update ISSUE_TEMPLATE.md 2016-03-20 13:44:09 -05:00
Alessandro Ranellucci
b744947711 Missing #include 2016-03-20 01:50:27 +01:00
Alessandro Ranellucci
412a862677 Fixed dragging in 3D plater having some glitches with multipart objects 2016-03-19 22:31:07 +01:00
Alessandro Ranellucci
dd879c3ef2 When loading an AMF file having multiple objects that look like multiple parts of a single object, prompt user and ask how to consider it. #2970
Conflicts:

	lib/Slic3r/Model.pm
2016-03-19 22:24:20 +01:00
Alessandro Ranellucci
dfb1ec99ac Variable-width thin walls. Yay! 2016-03-19 19:40:11 +01:00
Alessandro Ranellucci
6dc42ee902 Variable-width gap fill. Yay! #2960 2016-03-19 19:20:04 +01:00
Alessandro Ranellucci
5ff7511a14 Fixed regression in bridging caused by error in porting. Includes regression test. #3175 2016-03-18 22:40:29 +01:00
Alessandro Ranellucci
e2aae39f15 Bugfix: crash when input to bed shape options was '-'. #3254 2016-03-18 01:15:52 +01:00
Alessandro Ranellucci
c12ccd8357 Merge pull request #3272 from markwal/fixboost106000check
Fix issue with undefined BOOST_VERSION
2016-03-14 10:08:40 +01:00
Mark Walker
92e1f1011a Fix issue with undefined BOOST_VERSION
if BOOST_VERSION < 106000 always succeeds because BOOST_VERSION is
undefined.  In order to avoid the code for new boost, we need
<boost/version.hpp>
2016-03-13 23:51:35 -07:00
Alessandro Ranellucci
1a09ae81db Merge pull request #3166 from hippich/pk-fix-about-screen
Fix Slic3r crash when opening About dialog
2016-03-14 00:17:13 +01:00
Alessandro Ranellucci
7aafa54bf0 Raise allowed temperatures to 500°C. #3114 2016-03-14 00:08:08 +01:00
Alessandro Ranellucci
f4a9fa6569 Support incompatible change in Boost 1.60. #3117 2016-03-14 00:06:56 +01:00
Alessandro Ranellucci
38d9acbbfb Bugfix: memory corruption in BridgeDetector (thanks @JakeQZ for the patch). #3267 2016-03-13 21:13:51 +01:00
Alessandro Ranellucci
0964700e6d Merge pull request #3209 from hyperair/fix-3046
Don't toggle support_material_enforce_layers field
2016-03-13 18:30:22 +01:00
Alessandro Ranellucci
d5ff69b1aa Make GCodeSender more robust (keep more than one sent line) and fix a memory access problem in the asio write buffer 2016-03-13 18:27:02 +01:00
Alessandro Ranellucci
ff0a947364 Merge pull request #3190 from farhaven/master
Implement serial port baudrate selection for OpenBSD
2016-03-13 15:37:13 +01:00
Alessandro Ranellucci
6e5938c833 Fixed return value for deserialize() implementations. #3250 2016-03-13 15:26:52 +01:00
Alessandro Ranellucci
b9127e163b Merge pull request #3269 from 2bright/master
fix a segment fault by admesh
2016-03-13 12:48:54 +01:00
Alessandro Ranellucci
4fad87e438 Fixed float comparison in combine_infill 2016-03-13 12:24:03 +01:00
wenjie
3acb0514e1 fix a segment fault by admesh 2016-03-12 16:01:16 +08:00
Chow Loong Jin
5f8eea9adf Don't use equality comparisons for floats
This fixes an issue where F0 moves arise from 0-width (or 0 layer
height?) support material segments when using autospeed.

Fixes: #3261
2016-03-08 08:28:30 +08:00
Alessandro Ranellucci
a32937cef2 Refactoring: new Layer::make_fill() method 2016-02-20 20:51:07 +01:00
Alessandro Ranellucci
9eabbded2b Fixed regression in the C++ port of PerimeterGenerator causing gaps to be filled twice 2016-02-20 19:27:00 +01:00
Alessandro Ranellucci
e72a89ec23 New icon for Infill (credits: Carlo Mariella) 2016-02-20 16:18:48 +01:00
Chow Loong Jin
a9c5874db3 Don't toggle support_material_enforce_layers field
support_material_enforce_layers works independently of the support_material ||
raft options, so we should not disable the field when support material
generation is disabled.

Fixes: #3046
2016-01-17 17:12:47 +08:00
Gregor Best
5a13c4384f Implement serial port baudrate selection for OpenBSD
Signed-off-by: Gregor Best <gbe@unobtanium.de>
2016-01-03 17:35:59 +01:00
Pavel Karoukin
571b406bd6 @farhaven: There's one more wxCLOSE in lib/Slic3r/GUI/Projector.pm, that one should probably be changed as well. 2015-12-27 11:26:11 -06:00
Alessandro Ranellucci
83c91a3538 Dump serial messages to file in order to debug communication issues 2015-12-26 11:50:20 +01:00
Alessandro Ranellucci
f5326c393a Revert "Implement resizable left column in preset editor. #3151"
This reverts commit 4b30d67e54.
2015-12-25 17:52:10 +01:00
Alessandro Ranellucci
7c8b71012c Force the 'nearest' strategy for starting skirt loops 2015-12-21 15:02:39 +01:00
Alessandro Ranellucci
1a286fc906 Fixes and improvements to MotionPlanner, much smarter now 2015-12-21 14:46:35 +01:00
Alessandro Ranellucci
f7e97f7e9b Refactor cutting logic, don't slice in 3DScene 2015-12-19 23:15:37 +01:00
Alessandro Ranellucci
025a508de2 Ignore cut result if user didn't click the cut button 2015-12-19 20:41:47 +01:00
Alessandro Ranellucci
6e231a8cae Editable text control for specifying the cut Z in cut dialog 2015-12-19 20:38:50 +01:00
Alessandro Ranellucci
70e8db8a0a Minor code cleanup here and there 2015-12-19 20:27:04 +01:00
Pavel Karoukin
4f32a1cf9d Fix Slic3r crash when opening About dialog 2015-12-19 10:47:15 -06:00
Alessandro Ranellucci
795107dfa2 Bugfix: external details were simplified too much when using default settings at low layer height, because the internal flow was erroneously taken into account. #2807 2015-12-19 16:46:56 +01:00
Alessandro Ranellucci
bab3404b2d Very minor code improvements 2015-12-19 16:36:07 +01:00
Alessandro Ranellucci
2df750a9c9 Fixed ported code of PerimeterGenerator 2015-12-19 16:35:51 +01:00
Alessandro Ranellucci
790dbfe9a8 Fix false positive in lift unit test 2015-12-19 15:00:56 +01:00
Alessandro Ranellucci
667a121ddb Fixed error in porting causing wrong moves with avoid_crossing_perimeters 2015-12-19 14:49:29 +01:00
Alessandro Ranellucci
9dc0514844 Use bridge flow and speed for solid_infill_every_layers 2015-12-19 12:48:48 +01:00
Alessandro Ranellucci
a2ea191d84 Fix regression in lift, includes regression test 2015-12-19 12:44:22 +01:00
Alessandro Ranellucci
fd7795da59 One more fix for compilation with older compilers 2015-12-19 10:20:05 +01:00
Alessandro Ranellucci
4b30d67e54 Implement resizable left column in preset editor. #3151 2015-12-18 20:00:22 +01:00
Alessandro Ranellucci
8138fbf349 New --retract-lift-above and --retract-lift-below options. #763 #3057 2015-12-18 18:36:39 +01:00
Alessandro Ranellucci
562efc1677 Typo 2015-12-18 13:49:22 +01:00
Alessandro Ranellucci
b8f0391934 Fix compilation with GCC 2015-12-18 13:40:57 +01:00
Alessandro Ranellucci
44825d91af Some changes to DLP projector 2015-12-18 00:56:56 +01:00
Alessandro Ranellucci
d0ad57b64d Don't show any dialog if 0 configs were imported 2015-12-17 18:48:50 +01:00
Alessandro Ranellucci
3ec3aaf960 Removed debugging statements 2015-12-16 13:11:41 +01:00
Alessandro Ranellucci
e381100812 More efficient syntax for the PrintConfigDef constructor 2015-12-16 13:09:25 +01:00
Alessandro Ranellucci
934bd43e35 More refactoring on Config XS bindings 2015-12-16 12:58:06 +01:00
Alessandro Ranellucci
3c862836f2 Refactored the Config XS bindings 2015-12-16 12:33:19 +01:00
Alessandro Ranellucci
c73378744f Prevent flickering 2015-12-15 17:10:10 +01:00
Alessandro Ranellucci
21364b7cd1 Fix one regression in arrange 2015-12-14 00:15:26 +01:00
Alessandro Ranellucci
7ecfe195f7 Live preview in the cut dialog 2015-12-14 00:15:26 +01:00
Alessandro Ranellucci
c0248dea8c Bugfix: missing include assert.h #3155 2015-12-11 21:36:51 +01:00
Alessandro Ranellucci
37d0558873 Move the position_screen method to the Screen class 2015-12-11 01:18:02 +01:00
Alessandro Ranellucci
9bd10b3b5e Updates to GUI projector: fix buttons not updating when print finished; ring a bell at that time; disable screensaver not just when printing but until the DLP projector window gets closed 2015-12-11 01:13:47 +01:00
Alessandro Ranellucci
e2f2761a00 One more fix for compilation 2015-12-08 11:07:45 +01:00
Alessandro Ranellucci
9f90b2a1bf Fix compilation 2015-12-08 11:01:12 +01:00
Alessandro Ranellucci
5cfa36f36e Fix typo #3152 2015-12-08 10:53:57 +01:00
Alessandro Ranellucci
4913e90e10 Remove any Perl related code from libslic3r 2015-12-08 00:39:54 +01:00
Alessandro Ranellucci
3fac8cd77e Large refactoring of the Config classes 2015-12-07 19:39:49 +01:00
Alessandro Ranellucci
32a333f16a Import config bundle automatically if found in application directory 2015-12-07 12:17:06 +01:00
Alessandro Ranellucci
7e1fac8f76 Separate libslic3r code from slic3r application code 2015-12-06 12:54:01 +01:00
Alessandro Ranellucci
7eb3a70649 Bump version number 2015-12-06 11:18:27 +01:00
Alessandro Ranellucci
954e2c9bf0 Fix comment stripping in sender 2015-12-06 11:17:58 +01:00
Alessandro Ranellucci
27dcd60c77 Fix compilation on Windows 2015-12-06 11:17:50 +01:00
Alessandro Ranellucci
c16cdb9d85 Preserve the current layer when refreshing the 3D preview 2015-12-05 23:22:50 +01:00
Alessandro Ranellucci
a8091e41a0 Fix a minor glitch with scrollbars in OverrideSettingsPanel 2015-12-05 23:14:13 +01:00
Alessandro Ranellucci
50b52367a2 New "Scale to size" command(s). #2711 2015-12-05 19:37:57 +01:00
Alessandro Ranellucci
abff77cf04 Add color icons to menu items about axes. #3121 2015-12-05 19:01:17 +01:00
Alessandro Ranellucci
65d0f92cfe Fixed Travis CI conf 2015-12-05 15:14:37 +01:00
Alessandro Ranellucci
4b59490330 Upgrade Travis CI conf 2015-12-05 15:07:37 +01:00
Alessandro Ranellucci
d0db8914f7 Fix a compilation error on Win32 2015-12-05 11:48:24 +01:00
Alessandro Ranellucci
e2b203ba8d Disable screensaver while projecting (untested on Windows) 2015-12-04 21:25:45 +01:00
Alessandro Ranellucci
366b364996 Improvements to DLP projector: disable all options while printing; apply config changes to the printer preset so that user can save them; show total and remaining print time 2015-12-04 18:52:53 +01:00
Alessandro Ranellucci
7523550066 Try to fix compilation on older Perls 2015-12-02 19:57:03 +01:00
Alessandro Ranellucci
1bebe6097b Make test happy 2015-12-02 19:39:16 +01:00
Alessandro Ranellucci
4f8a18bbad Ported Layer::maker_perimeters() to XS 2015-12-02 19:32:57 +01:00
Alessandro Ranellucci
3a9cf91f83 Ported a couple more methods to XS 2015-12-02 18:29:33 +01:00
Alessandro Ranellucci
ed75219215 Ported mode Model methods to XS 2015-12-02 18:06:18 +01:00
Alessandro Ranellucci
dfce3a3138 Ported _arrange() and arrange_object() to XS 2015-12-01 21:51:16 +01:00
Alessandro Ranellucci
5655f786f4 Change order in DLP projection 2015-12-01 20:54:06 +01:00
Alessandro Ranellucci
5844b956be Bugfix: prevent crash when setting a Choice field to a non-indexed value 2015-12-01 20:53:29 +01:00
Alessandro Ranellucci
48f1fab49f Bugfix: an error in porting caused bad perimeter ordering. Includes regression test and more unit tests for PerimeterGenerator 2015-12-01 20:40:00 +01:00
Alessandro Ranellucci
fbc67d9078 Merge branch 'sender-dlp' 2015-11-28 20:30:22 +01:00
Alessandro Ranellucci
017ed05911 Removed debugging comment 2015-11-22 10:13:58 +01:00
Alessandro Ranellucci
ad4940a1d6 New option for inverting the Y axis in projection 2015-11-20 10:30:56 +01:00
Alessandro Ranellucci
f9d1ca8373 Project grid 2015-11-20 10:04:17 +01:00
Alessandro Ranellucci
bd00e7c584 Fix projection of slices with holes because wxDC is not honoring the fill rule 2015-11-20 09:57:51 +01:00
Alessandro Ranellucci
78d2240d71 Limit slider to number of layers 2015-11-20 09:41:13 +01:00
Alessandro Ranellucci
4a65671f64 Prevent absolute movement if user hasn't homed both X and Y 2015-11-20 09:36:17 +01:00
Alessandro Ranellucci
cc57432be4 Let user configure travel speed in manual control dialog 2015-11-20 09:32:48 +01:00
Alessandro Ranellucci
0af289ed78 Added manual projection control 2015-11-20 09:18:41 +01:00
Alessandro Ranellucci
2efc759a74 Add manual control to DLP projector too 2015-11-19 17:31:47 +01:00
Alessandro Ranellucci
128b2623cc More small fixes for compilation on Linux 2015-11-19 17:03:34 +01:00
Alessandro Ranellucci
6fde339164 One more fix for Travis CI 2015-11-19 17:03:33 +01:00
Alessandro Ranellucci
39924ee89c More small fixes for compilation on Linux 2015-11-19 17:02:01 +01:00
Alessandro Ranellucci
c63a5f26ca One more fix for Travis CI 2015-11-19 17:00:25 +01:00
Alessandro Ranellucci
c149420d23 Further improvements for compilation (Ubuntu)
Conflicts:

	.travis.yml
2015-11-19 15:31:33 +01:00
Alessandro Ranellucci
1378562e63 Further improvements for compilation (Ubuntu) 2015-11-19 15:30:27 +01:00
Alessandro Ranellucci
e48a0fe022 Added libboost-* packages for Travis CI build 2015-11-19 15:05:29 +01:00
Alessandro Ranellucci
624c5e78db Changed default settings for DLP projector and changed time options from integer to decimal 2015-11-19 15:04:50 +01:00
Alessandro Ranellucci
73b6400129 Merge branch 'master' into sender-dlp 2015-11-19 13:19:04 +01:00
Alessandro Ranellucci
dbcc41e432 Merge branch 'sender' 2015-11-19 13:18:42 +01:00
Alessandro Ranellucci
21a5d6e137 Several fixes to GCodeSender, including compilation on older OS X and DTR reset 2015-11-19 13:17:52 +01:00
Alessandro Ranellucci
870cb3ccc4 Merge branch 'sender' into sender-dlp 2015-11-16 12:50:41 +01:00
Alessandro Ranellucci
e50bbc0245 Don't crash when no serial ports are available on Windows 2015-11-16 12:50:16 +01:00
Alessandro Ranellucci
c1f95ac173 Slice objects even if background processing is disabled 2015-11-15 23:16:14 +01:00
Alessandro Ranellucci
5ba2f72324 More customizable options for DLP projector 2015-11-15 22:42:56 +01:00
Alessandro Ranellucci
be0ba4d5a2 Re-enable serial connection for DLP projector 2015-11-15 21:08:47 +01:00
Alessandro Ranellucci
6bfa2cfaec Projector for DLP 2015-11-15 21:08:14 +01:00
Alessandro Ranellucci
80620a5e94 Some fixes and improvements to controller 2015-11-08 11:17:55 +01:00
Alessandro Ranellucci
3c43fb8081 Fix rendering on Windows 2015-11-08 10:20:47 +01:00
Alessandro Ranellucci
9febb10bd7 Smoother manual control movements 2015-11-08 10:20:47 +01:00
Alessandro Ranellucci
321b1a90a2 Two fixes for --debug 2015-11-08 09:13:26 +01:00
Alessandro Ranellucci
37ecc61d06 Two fixes for --debug 2015-11-08 09:12:59 +01:00
Alessandro Ranellucci
25a358cd20 Prevent double connection check 2015-11-06 16:34:54 +01:00
Alessandro Ranellucci
3cbc35143b More fixes for serial port detection on Windows 2015-11-06 16:33:54 +01:00
Alessandro Ranellucci
5d69e732d8 Fix serial port detection on Windows 2015-11-06 16:25:51 +01:00
Alessandro Ranellucci
9a8724cdd0 More compilation changes for Win32 2015-11-06 11:51:24 +01:00
Alessandro Ranellucci
ca48501f91 Remove Boost from distribution and fix some more things for Windows compilation 2015-11-06 11:34:37 +01:00
Alessandro Ranellucci
e7d2be842d Improve Boost path detection 2015-11-06 11:03:45 +01:00
Alessandro Ranellucci
97bf69ba7f Fix compilation on Windows 2015-11-06 10:43:11 +01:00
Alessandro Ranellucci
9f9b5afedb Merge branch 'master' into sender 2015-11-05 11:04:01 +01:00
Alessandro Ranellucci
2e9a0f5590 Added more search paths for Boost on Win32 2015-11-05 11:02:12 +01:00
Alessandro Ranellucci
61f0a9e4da Replace the flip word with mirror. #3060 2015-11-04 23:11:30 +01:00
Alessandro Ranellucci
f8d2c69713 Fixed compilation warnings and a potential bug in MotionPlanner, as reported in #3054 2015-11-04 20:50:32 +01:00
ntfshard
7c7982d9f3 Fix signed-unsigned compare 2015-11-04 20:49:20 +01:00
ntfshard
c90ecac48e Addtional check for TPPLPoly::operator= 2015-11-04 20:49:20 +01:00
ntfshard
d62f33b0b4 Removed unused variables 2015-11-04 20:49:20 +01:00
ntfshard
32f5538e0d Fix for -Wmaybe-uninitialized warninig 2015-11-04 20:49:20 +01:00
ntfshard
40e49613b1 Config: pass value as a reference 2015-11-04 20:49:20 +01:00
ntfshard
ef0050662c Function arguments passed by reference 2015-11-04 20:49:20 +01:00
ntfshard
e1d663c0ce Function arguments passed by reference 2015-11-04 20:49:20 +01:00
ntfshard
dbcd1e2df6 Fix: memory leak in ExPolygon::triangulate_p2t 2015-11-04 20:49:20 +01:00
ntfshard
c6ef26a457 std::list::empty faster than std::list::size (for C++03) 2015-11-04 20:49:19 +01:00
ntfshard
dd5c5eb931 Fix: Initializer list, right initialisation order 2015-11-04 20:49:19 +01:00
ntfshard
eb7464ace6 Style fix: const for some functions 2015-11-04 20:49:19 +01:00
ntfshard
f2c4a66e45 Refactoring: prefix inc/dec operators for iterators 2015-11-04 20:49:19 +01:00
Alessandro Ranellucci
06913cc8b8 Merge pull request #3111 from mdebski/temp_comments
Fix incorrect comments to bed temperature setting gcode
2015-11-04 20:17:58 +01:00
Alessandro Ranellucci
bce3d98d9d Bugfix: error when setting per-region percent perimeter_extrusion_width. #2983
Conflicts:

	lib/Slic3r/Layer.pm
2015-11-04 20:10:52 +01:00
Alessandro Ranellucci
7a2a1b5446 Merge pull request #3039 from llluis/patch-1
Bugfix #3038
2015-11-04 19:47:02 +01:00
Alessandro Ranellucci
b8e95f40a6 Prompt user when setting wipe + use_firmware_retraction. #3056 2015-11-04 19:43:50 +01:00
Alessandro Ranellucci
b67b903902 Include the option category for first_layer_extrusion_width. #3061 2015-11-04 19:33:49 +01:00
Alessandro Ranellucci
810d7ee1c0 Fixed one more memory leak 2015-11-04 19:29:59 +01:00
Alessandro Ranellucci
198dc7d3bd When background processing fails because of an error, display it in an explicit dialog 2015-11-04 19:28:25 +01:00
Alessandro Ranellucci
a25757a66d Fixed regression causing empty prints to hang. #3107 2015-11-04 19:20:34 +01:00
Alessandro Ranellucci
69a71db25b Bugfix: wrong default in extruder_offset tooltip. #3051 2015-11-04 19:13:56 +01:00
Alessandro Ranellucci
c34430c6c4 Fix G-code checksum 2015-11-04 14:00:37 +01:00
Maciej Dębski
369b99c712 Fix incorrect comments to temperature-setting gcode 2015-11-04 13:55:08 +01:00
Alessandro Ranellucci
1d10e463a3 Bugfix: wrong error handling in GCodeSender 2015-11-03 23:08:16 +01:00
Alessandro Ranellucci
8f7e820a01 Display a warning when no USB/serial printers were configured 2015-11-03 23:00:59 +01:00
Alessandro Ranellucci
e8ae2d6ec2 Try to fix broken wx scrolling 2015-11-03 22:46:31 +01:00
Alessandro Ranellucci
d8a94c3936 Smarter logic for displaying printer panels 2015-11-03 21:55:17 +01:00
Alessandro Ranellucci
16c38315f7 Fixed manual control buttons 2015-11-02 20:42:40 +01:00
Alessandro Ranellucci
9ee6829ebc Implemented connection timeout in C++ 2015-11-02 20:36:36 +01:00
Alessandro Ranellucci
4295d65115 Manual control 2015-11-02 20:16:37 +01:00
Alessandro Ranellucci
cb8f8a24b0 Keep print job order 2015-11-02 16:54:02 +01:00
Alessandro Ranellucci
01a2a07ecd More memory leaks fixed
Conflicts:

	lib/Slic3r/GUI/Plater.pm
2015-11-02 01:45:46 +01:00
Alessandro Ranellucci
9438289fc1 Removed debugging statement 2015-11-02 01:44:44 +01:00
Alessandro Ranellucci
4e3784a2a9 More memory leaks fixed 2015-11-02 01:44:19 +01:00
Alessandro Ranellucci
3685f5031d Fixed memory leak 2015-11-02 01:36:49 +01:00
Alessandro Ranellucci
05812a0a60 Fixed memory leak 2015-11-02 01:36:35 +01:00
Alessandro Ranellucci
b309c61de3 Test button for serial connection 2015-11-02 01:35:28 +01:00
Alessandro Ranellucci
fc1a7471cf Several improvements to the print job queue 2015-11-02 01:18:05 +01:00
Alessandro Ranellucci
9b21ac877a Merge branch 'master' into sender
Conflicts:
	Build.PL
	lib/Slic3r.pm
	xs/MANIFEST
	xs/src/libslic3r/PrintConfig.hpp
2015-11-01 19:12:13 +01:00
Alessandro Ranellucci
2811af349a Added a new grid infill pattern 2015-11-01 19:03:11 +01:00
Alessandro Ranellucci
889a54e946 Bump version number 2015-10-26 23:25:26 +01:00
Alessandro Ranellucci
9fcec10737 Finished porting LayerRegion to C++ 2015-10-26 23:24:46 +01:00
Vicious-one
8e0d458d1d Fix for #3069 2015-09-30 16:22:49 +03:00
Luís Andrade
b31edc0be3 Update GCode.cpp
Bugfix #3038
2015-08-10 18:03:45 -04:00
Alessandro Ranellucci
5b8ed7367a Fixed potential hang in PerimeterGenerator.cpp 2015-08-06 10:07:13 +02:00
Alessandro Ranellucci
6ac79e3ed6 Ported make_perimeters() to C++ 2015-07-23 16:27:21 +02:00
Alessandro Ranellucci
15d2522f3d Merge branch 'xs-perimetergenerator' 2015-07-23 15:53:19 +02:00
Alessandro Ranellucci
b4515cf695 Finished porting PerimeterGenerator to C++ 2015-07-23 15:53:02 +02:00
Alessandro Ranellucci
9ac4fc9034 Fix compilation on Windows due to lack of setenvt(). #2973 2015-07-10 16:01:45 +02:00
Alessandro Ranellucci
0e18b094d1 More work for porting PerimeterGenerator to XS 2015-07-07 01:17:31 +02:00
Alessandro Ranellucci
c65c9d876e Bugfix: zooming in empty layers preview (because of disabled background processing) crashed 2015-07-04 15:26:11 +02:00
Alessandro Ranellucci
e84ead5291 Bugfix: changing range-based layer heigths didn't trigger background processing. #2958 2015-07-04 15:26:04 +02:00
Alessandro Ranellucci
440af2c81c Bugfix: bridge anchors were shortened under rare circumstances 2015-07-03 23:38:41 +02:00
Alessandro Ranellucci
b8aecbd56c Initial work for porting PerimeterGenerator to XS 2015-07-03 22:58:29 +02:00
Alessandro Ranellucci
3e739b87da Finished porting Slic3r::GCode to XS (speed boost!) 2015-07-02 20:24:16 +02:00
Alessandro Ranellucci
0ad4296aaf Ported GCode::set_extruders() and GCode::change_layer() to XS 2015-07-02 19:33:08 +02:00
Alessandro Ranellucci
9a17efc480 Use GCodeWriter for path segments (refactoring) 2015-07-02 19:14:55 +02:00
Alessandro Ranellucci
fbd640fdc5 Ported GCode::extrude_path() to XS (speed boost!) 2015-07-02 18:57:40 +02:00
Alessandro Ranellucci
b025efe729 Ported GCode::travel_to() to XS 2015-07-02 15:12:04 +02:00
Alessandro Ranellucci
a6f4c8e567 Ported GCode::set_extruder() and OozePrevention 2015-07-02 15:02:20 +02:00
Alessandro Ranellucci
72355a9500 Use macro in PrintConfig.hpp 2015-07-02 14:35:21 +02:00
Alessandro Ranellucci
ff5747bb60 Macro for readability 2015-07-02 14:31:21 +02:00
Alessandro Ranellucci
b14290b9f6 Make tests happy 2015-07-02 14:29:20 +02:00
Alessandro Ranellucci
5571144c0e Ported Slic3r::GCode::needs_retraction() to XS 2015-07-01 23:14:40 +02:00
Alessandro Ranellucci
b4019bb438 Ported more Slic3r::GCode methods to XS 2015-07-01 23:00:52 +02:00
Alessandro Ranellucci
801f629fdc Ported Slic3r::GCode storage to XS 2015-07-01 21:47:17 +02:00
Alessandro Ranellucci
ab858f320d Updated test 2015-07-01 21:02:36 +02:00
Alessandro Ranellucci
280f3f38d7 Ported Slic3r::GCode::OozePrevention storage to XS 2015-07-01 21:01:42 +02:00
Alessandro Ranellucci
b43dd92766 Ported Slic3r::GCode::Wipe storage to XS 2015-07-01 20:57:16 +02:00
Alessandro Ranellucci
76b2e88551 Removed setenv() test as we can't test environment variables in Perl since they are now set in XS 2015-07-01 20:15:52 +02:00
Alessandro Ranellucci
bf9cd1b8e6 Ported Slic3r::GCode::AvoidCrossingPerimeters to XS 2015-07-01 20:14:05 +02:00
Alessandro Ranellucci
580d28d071 Finished porting PlaceholderParser to XS 2015-07-01 19:35:22 +02:00
Alessandro Ranellucci
249088b4f8 Ported Config::setenv() to XS 2015-07-01 18:18:25 +02:00
Alessandro Ranellucci
f361d8ad43 Ported PlaceholderParser::apply_env_variables() to XS 2015-07-01 17:56:38 +02:00
Alessandro Ranellucci
724e668a94 Revert "Add perl 5.22 to Travis CI"
This reverts commit 3b7cb6722c.
2015-06-20 16:33:12 +02:00
Alessandro Ranellucci
3b7cb6722c Add perl 5.22 to Travis CI 2015-06-20 16:10:59 +02:00
Alessandro Ranellucci
be1f35c516 Disable testing of modules that have known broken tests 2015-06-20 15:56:54 +02:00
Alessandro Ranellucci
4a39665804 Bugfix: binary ASCII files were not written with the correct fopen() mode. #2928 2015-06-20 14:16:23 +02:00
Alessandro Ranellucci
3cd6c78044 Releasing 1.2.9 2015-06-17 10:38:28 +02:00
Alessandro Ranellucci
455a1062ef Fix minor rendering glitch in 2D toolpaths preview 2015-06-17 00:34:05 +02:00
Alessandro Ranellucci
be635c69e7 Fixed regression casusing some rare STL files not to parsed correctly because of lack of the solid name. #2914 2015-06-15 17:17:36 +02:00
Alessandro Ranellucci
6dc3caa8b2 Typo 2015-06-15 17:08:12 +02:00
Alessandro Ranellucci
539cde8d7a Raise the thickness threshold used for generating thin walls. TODO: don't enforce this at the segment level but consider the average thickness of an entire polyline and compare it to the total length. #2910 2015-06-15 17:00:10 +02:00
Alessandro Ranellucci
bc69d6da81 Minor adjustment of infill_overlap math 2015-06-14 11:28:33 +02:00
Alessandro Ranellucci
38a9e32a28 Limit bridge over sparse infill to areas that can absorb such extrudate. #2899 2015-06-13 19:48:46 +02:00
Alessandro Ranellucci
7a34078f5f Bump version number 2015-06-13 11:42:37 +02:00
Alessandro Ranellucci
552430db67 More fixes for Unicode path handling (thanks @josefprusa for Czech test VM) 2015-06-13 11:41:55 +02:00
Alessandro Ranellucci
4a91ea817a Releasing 1.2.8 2015-06-09 17:18:43 +02:00
Alessandro Ranellucci
e715974688 Better validation for speeds (prevent 0mm/s travel speed). #2893 2015-06-09 17:15:01 +02:00
Alessandro Ranellucci
1e23b82e24 Bugfix: small gaps were left between infill and perimeters when solid infill extrusion width was much thinner than internal infill extrusion width. #2895 2015-06-09 16:04:26 +02:00
Alessandro Ranellucci
911bed827c Fixed regression in STL parser. #2886 2015-06-09 14:54:52 +02:00
Alessandro Ranellucci
eff0620ddf Prompt user when overwriting a file during G-code export as well. #2882 2015-06-03 13:19:43 +02:00
Alessandro Ranellucci
52d3a047a0 One more raft issue causing extra layers. #2723 2015-06-03 09:39:10 +02:00
Alessandro Ranellucci
c5f72a633a Bugfix: Repeat Last Quick Slice was affected by the plater exports. #2016 2015-06-02 22:27:11 +02:00
Alessandro Ranellucci
1dc5f5531e If --save is called without any other config option, export full default settings. #2110 2015-06-02 22:05:53 +02:00
Alessandro Ranellucci
6018dafc46 Removed debugging statement 2015-06-02 20:03:57 +02:00
Alessandro Ranellucci
5ce4d8cfb0 Bugfix: extra thin layers added to raft. #2723 2015-06-02 19:58:36 +02:00
Alessandro Ranellucci
ee66392e11 Fix numerical issues causing incomplete raft under certain circumstances. Includes a minor refactoring of raft layer logic. #2723 2015-06-02 19:44:29 +02:00
Alessandro Ranellucci
854be6a186 Handle OctoPrint upload of files having Unicode characters in filename or path. #2827 2015-06-02 17:10:06 +02:00
Alessandro Ranellucci
56b993bb89 More fixes for Unicode filenames support on Windows and OS X 2015-06-02 16:10:15 +02:00
Alessandro Ranellucci
7b65a35519 Always limit volumetric speed with Max Volumetric Speed (not just when using autospeed). #2810 2015-06-02 11:54:38 +02:00
Alessandro Ranellucci
c37b5c2e87 Remove debugging statement 2015-06-02 11:49:43 +02:00
Alessandro Ranellucci
8613e174e7 Fix error in autospeed. #2810 2015-06-02 11:48:56 +02:00
Alessandro Ranellucci
e90f5fde4e Enlarge your about window 2015-06-02 11:20:45 +02:00
Alessandro Ranellucci
ca72fd4266 Fix ComboCtrl on Windows 2015-06-02 11:19:11 +02:00
Alessandro Ranellucci
03c754ab14 Add close button and support Esc key and close on click inside the window to the About dialog since the title bar is not displayed on Windows and some Linux distros. #2688 2015-06-02 10:49:24 +02:00
Alessandro Ranellucci
b4cc92b9fa Fix filament colors not being initialized in additional comboboxes 2015-06-01 23:58:34 +02:00
Alessandro Ranellucci
0a9f1c466a Minor improvements to filament choosers in the plater 2015-06-01 23:52:15 +02:00
Alessandro Ranellucci
c2c321c90b Restore the (modified) label in preset comboctrl 2015-06-01 23:34:04 +02:00
Alessandro Ranellucci
1fcfdf4718 Added a couple full_label values 2015-06-01 23:22:44 +02:00
Alessandro Ranellucci
6c53b14ee4 Minor improvement to extruder count field 2015-06-01 23:19:26 +02:00
Alessandro Ranellucci
4402dfa6f3 Fix crash in GUI caused by recursive event calls. #2613 2015-06-01 23:11:27 +02:00
Alessandro Ranellucci
6095427926 Fix admesh's STL parser in order to make it more tolerant for broken STL files having multiple 'solid' definitions. Still not the ideal STL parser, but handles the cases that were reported so far. #2471 #2842 2015-06-01 19:49:52 +02:00
Alessandro Ranellucci
f14c0e2183 Bugfix: concave starting points were not correctly detected for slice holes. Includes regression test. #2857 2015-06-01 17:55:51 +02:00
Alessandro Ranellucci
97c701cdac Fix concurrency issue in Wx when changing the number of extruders. #2863 2015-06-01 14:57:43 +02:00
Alessandro Ranellucci
d549393a84 Comment about GetSelection() being context-aware. #2873 2015-06-01 14:32:31 +02:00
Alessandro Ranellucci
5b82f09308 Merge pull request #2873 from darenschwenke/master
Fixes #2858
2015-06-01 14:31:07 +02:00
Alessandro Ranellucci
fbea32a81c Prevent writing empty materials to AMF files. Also add a note about material-id = 0 being reserved by AMF spec. #2871 2015-06-01 11:51:00 +02:00
Daren Schwenke
23119e3673 Fixes #2858 2015-06-01 02:48:11 -04:00
Alessandro Ranellucci
e26022a2f2 Comment about Ctrl+, 2015-05-31 22:35:52 +02:00
Alessandro Ranellucci
17eb50da6d Use Ctrl+, for Preferences (standard on OS X, don't know about others). #2860 2015-05-31 22:33:46 +02:00
Alessandro Ranellucci
29b0e807d4 New [current_extruder] variable in custom G-code. #2866 2015-05-31 22:14:48 +02:00
Alessandro Ranellucci
1875825f45 Minor fix to previous commit 2015-05-31 22:09:58 +02:00
Alessandro Ranellucci
7f70da97b4 New experimental autospeed feature. #2810 2015-05-31 22:04:32 +02:00
Alessandro Ranellucci
6e280ab8cb Prompt user when using 100% infill with a pattern that does not support it 2015-05-28 18:56:35 +02:00
Alessandro Ranellucci
2f4fa41ce4 Fixed regression introduced with recent fixes to UTF-8 preset names handling on Windows that prevented their load on OS X (TODO: test on Linux) 2015-05-28 18:44:19 +02:00
Alessandro Ranellucci
e58c32bee8 Ask for confirmation before stopping prints 2015-05-28 18:33:15 +02:00
Alessandro Ranellucci
13b7316807 Merge branch 'master' into sender
Conflicts:
	Build.PL
	lib/Slic3r/GUI/MainFrame.pm
2015-05-28 18:05:36 +02:00
Alessandro Ranellucci
0d08c1819b Bugfix: plater views were not refreshed after config wizard in simple mode 2015-05-27 00:50:18 +02:00
Alessandro Ranellucci
310212ed30 Enable menu icons on older Windows and Linux Wx 2015-05-26 11:27:07 +02:00
Alessandro Ranellucci
aa8b6afe8b Assign color to filaments 2015-05-26 02:01:43 +02:00
Alessandro Ranellucci
ad0a15debe Menu item icons :o) 2015-05-25 22:37:04 +02:00
Alessandro Ranellucci
b7b017c3fa Fit objects to print bed when they are too large and warn user. #2853 2015-05-25 19:51:47 +02:00
Alessandro Ranellucci
57e6a7becd Fix --help output: --retract-layer-change is disabled by default. #2846 2015-05-25 00:35:57 +02:00
Alessandro Ranellucci
7c31134a66 Fixed one little regression in gap detection causing some very very narrow gaps to be skipped when external perimeter extrusion width was much smaller than perimeter extrusion width. Also, push a bit more material in gap fill. #2560 2015-05-25 00:03:38 +02:00
Alessandro Ranellucci
a547645e86 Bump version number 2015-05-24 23:29:59 +02:00
Alessandro Ranellucci
42ae8347df Zoom around mouse location in 2D toolpaths preview 2015-05-24 23:29:53 +02:00
Alessandro Ranellucci
249a48d68d Releasing 1.2.7 2015-05-24 17:39:27 +02:00
Alessandro Ranellucci
8cbb12aeb6 Workaround for wxCocoa bug causing wxSpinCtrl values to be reset when losing focus after changing them from the text field. #2612 2015-05-24 17:24:10 +02:00
Alessandro Ranellucci
f010354201 Bugfix: skirt was not exported to G-code when raft_layers > 0. #2843 2015-05-24 16:28:04 +02:00
Alessandro Ranellucci
e0678d3a38 Bugfix: skirt was floating in 3D preview when raft layers were enabled. #2843 2015-05-24 15:47:07 +02:00
Alessandro Ranellucci
a587e11780 Regression test for overlapping gap fill. #2474 2015-05-22 14:26:01 +02:00
Alessandro Ranellucci
7cc745969c Bugfix: some gaps were filled twice. #2836 2015-05-22 11:21:49 +02:00
Alessandro Ranellucci
31e0fc7f17 Fixes and improvements to thin wall detection. #2829 2015-05-22 01:46:01 +02:00
Alessandro Ranellucci
70ec433e67 Faster (but less precise) implementation of simplify_by_visibility(), since it was the bottleneck of avoid_crossing_perimeters. #2777 2015-05-18 19:28:59 +02:00
Alessandro Ranellucci
c64308a5e7 Render brim and skirt in 3D toolpaths preview. #2649 2015-05-18 00:49:16 +02:00
Alessandro Ranellucci
36ba2eb5d6 Improved zoom/pan for toolpaths preview 2015-05-17 21:29:57 +02:00
Alessandro Ranellucci
80b169aa75 Pan & zoom for toolpaths preview 2015-05-16 00:33:22 +02:00
Alessandro Ranellucci
97211f35e7 More robust medial axis pruning. #2800 2015-05-13 20:50:30 +02:00
Alessandro Ranellucci
1dc63071ed Try to fix crash upon quick slice. #2801 2015-05-06 00:39:16 +02:00
Alessandro Ranellucci
d998d97754 Bugfix: crash on Windows when deleting the first object part. #2774 2015-05-05 01:12:16 +02:00
Alessandro Ranellucci
63af442e3e Bugfix: [layer_num] was out of order because of support material layers having their order numbers. Now we use a unique continuous series. Includes regression test. #2634 2015-05-03 21:41:30 +02:00
Alessandro Ranellucci
73e32dfe5d Use unique continuous numbering for layer numbers in case of support material layers. #2634 2015-05-03 20:18:34 +02:00
Alessandro Ranellucci
0d01348acc Use radians everywhere, including ModelInstance::rotation 2015-05-03 18:40:00 +02:00
Alessandro Ranellucci
79ce094e3a Bugfix: splitting a rotated object resulted in wrong positions. #2772 2015-05-03 18:28:39 +02:00
Alessandro Ranellucci
7d81aee62f Added the [scale] placeholder. #2791 2015-05-02 21:59:15 +02:00
Alessandro Ranellucci
00acd32120 Fix failing test. #2806 2015-05-02 21:46:08 +02:00
Alessandro Ranellucci
bf541a1fed Refactoring in PlaceholderParser 2015-05-02 21:43:22 +02:00
Alessandro Ranellucci
a16dda0885 Bugfix: changes to the resolution config option didn't trigger reslicing. #2795 2015-04-29 19:22:44 +02:00
Alessandro Ranellucci
d6d7880507 Ported Slic3r::Geometry::arrange() to C++/XS 2015-04-29 19:19:07 +02:00
Alessandro Ranellucci
5eb3bc52ef Ported ModelObject::rotate() and ModelObject::flip() to XS, as well as axes constants 2015-04-16 21:22:04 +02:00
Alessandro Ranellucci
be2f46ca68 Ported Layer::merge_slices() to XS 2015-04-16 20:44:55 +02:00
Alessandro Ranellucci
1f8ef2a63c Fixed regression introduced by the recent PerimeterGenerator refactoring causing spiral vase not to be correctly skipped on multi-loop layers. Includes regression test. #2761 2015-04-12 20:16:27 +02:00
Alessandro Ranellucci
901716adc8 Bugfix: the object parts editor is opened in invalid status until user clicks on a tree list item. #2762 2015-03-30 20:27:18 +02:00
Alessandro Ranellucci
ce676a7ca7 Bugfix: the Export G-code button was not re-enabled after cancelling an export job. #2754 2015-03-28 18:53:07 +01:00
Alessandro Ranellucci
2c13be1fa9 Bugfix: NumericChoice field was misbehaving. (thanks @markwal) #2752 2015-03-27 19:04:30 +01:00
Alessandro Ranellucci
21da24e372 Typo 2015-03-27 17:59:40 +01:00
Alessandro Ranellucci
2d7bfbb805 Bugfix: dirty filament options were ignored when using multiple extruders. Patch by @markwal. #2740 2015-03-23 21:48:31 +01:00
Alessandro Ranellucci
92b980b10e Bugfix: superfluous and harmful travel moves between objects when using sequential printing with Avoid crossing perimeters. #2691 2015-03-23 21:38:57 +01:00
Alessandro Ranellucci
13b63d06ed Use thick raft layers as we do for support material layers. #2723 2015-03-09 20:00:55 +01:00
Alessandro Ranellucci
8654537e55 Use support material layer height for raft layer instead of object layer height. #2723 2015-03-09 19:36:23 +01:00
Alessandro Ranellucci
d8ee9dd5f5 Limit first object layer height correctly when using a larger support material extruder. #2722 2015-03-09 19:27:57 +01:00
Alessandro Ranellucci
3fd182a8f5 Fix object Z alignment after cut + rotate lower part. #2724 2015-03-09 18:37:58 +01:00
Alessandro Ranellucci
6cab5668e3 Restore correct ordering of concentric infill loops, preventing them from being reordered during G-code generation 2015-03-09 18:28:07 +01:00
Alessandro Ranellucci
25cddfe446 Bugfix: layers view was not resized when inactive. #2608 2015-03-09 15:30:19 +01:00
Alessandro Ranellucci
0d6376f3e6 Call decode_path() on wxWidgets-supplied datadir. #2710 2015-03-09 15:25:42 +01:00
Alessandro Ranellucci
6185f45815 Hopefully fix all problems with non-ASCII paths on Windows 2015-03-09 15:17:50 +01:00
Alessandro Ranellucci
66824fd17e Set STDOUT to UTF-8 2015-03-08 00:54:38 +01:00
Alessandro Ranellucci
d2172b4383 Merge branch 'master' into sender 2015-03-06 22:15:43 +01:00
Alessandro Ranellucci
095391d702 When using raft, validate first layer height against support material extruder only instead of taking other extruders into account, thus potentially allowing larger nozzles to be used for it. #2701 2015-03-06 21:35:00 +01:00
Alessandro Ranellucci
9332c21791 Bugfix: double wipe was not prevented, causing potential collision between objects in sequential printing. #2691 2015-03-06 10:36:04 +01:00
Alessandro Ranellucci
c2009af1c6 Remove ;_WIPE marks in G-code which were left between objects in sequential printing 2015-03-06 10:25:31 +01:00
Alessandro Ranellucci
722e94513c Refactoring: removed the non-idempotent init_extruders() step. Also, infill_extruder was not limited to the available number of extruders when slicing from the plater, and support material extruder was considered also when support material was disabled 2015-03-06 09:56:58 +01:00
Alessandro Ranellucci
a3b843b24e Bugfix: temperature was not set correctly when using sequential printing. Includes regression test. #2702 2015-03-02 23:56:38 +01:00
Alessandro Ranellucci
9d435c8f4d Bugfix: we can't check for executability of post-processing scripts on Windows. #2616 2015-03-02 21:49:05 +01:00
Alessandro Ranellucci
70c032868a Prevent OpenGL scene from Z clipping 2015-03-01 19:58:05 +01:00
Alessandro Ranellucci
1ab8efba7f Fixed regression causing random failures in bridge direction detection. #2636 2015-02-27 21:55:02 +01:00
Alessandro Ranellucci
bb3feedc31 Bugfix: too many skirt layers were printed when using tall skirts and support material. #2695 2015-02-27 19:59:43 +01:00
Alessandro Ranellucci
70ace8c76f Bugfix: use proper spacing for first support layer instead of trying to align it to upper layers. #2662 2015-02-27 18:43:15 +01:00
Alessandro Ranellucci
45c91b2ae9 Don't trigger extra perimeters when less than 30% of the upper loops would benefit from it. #2664. Also fixes #2610 2015-02-24 00:34:43 +01:00
Alessandro Ranellucci
7a695a4a2f Change the behaviour of infill/perimeter overlap to handle some edge cases. #2632 2015-02-23 23:44:34 +01:00
Alessandro Ranellucci
e88cf466fe A couple notes about infill_only_where_needed 2015-02-23 00:55:00 +01:00
Alessandro Ranellucci
2655f3f816 Better and more robust implementation of infill_only_where_needed 2015-02-23 00:44:51 +01:00
Alessandro Ranellucci
69ea88473d Workaround for the Clipper issue causing extra points in grid segments 2015-02-22 17:09:08 +01:00
Alessandro Ranellucci
f8fa73fa4a Removed debugging stuff 2015-02-22 17:04:08 +01:00
Alessandro Ranellucci
2eca094170 Added failing test case for Clipper regression causing extra points in polyline intersection, thus crash with circular bed shape 2015-02-22 17:03:23 +01:00
Alessandro Ranellucci
edbc11477c Update to Clipper 6.2.9. Fixes #2639 2015-02-22 15:13:52 +01:00
Alessandro Ranellucci
5021c9605b Revert "Merge pull request #2681 from robstarling/u/robstar/circular-bedshape-drawing-fix2"
This reverts commit 13885a36ec, reversing
changes made to 7198607420.
2015-02-22 15:01:33 +01:00
Alessandro Ranellucci
13885a36ec Merge pull request #2681 from robstarling/u/robstar/circular-bedshape-drawing-fix2
Bugfix: correctly draw circular beds in the 2D plater
2015-02-22 14:52:53 +01:00
Alessandro Ranellucci
7198607420 Merge pull request #2667 from hyperair/issue-2662
Fix support material first layer extrusion width
2015-02-22 14:48:57 +01:00
Alessandro Ranellucci
6413d5dcba Merge pull request #2630 from lordofhyphens/fix-admesh-warning
Fix a warning about unused return value when using freopen in admesh.
2015-02-22 14:48:17 +01:00
Rob Starling
6719afadec Bugfix: correctly draw circular beds in the 2D plater
Wx::DrawLine wasn't happy with a polyline, so we pass the sequence of points to Wx::DrawLines
2015-02-21 14:08:52 -08:00
Chow Loong Jin
073681a50a Get first_layer_extrusion_width from PrintConfig instead of PrintObjectConfig
This fixes an issue where the support material doesn't honour a custom first
layer extrusion width.

Fixes: #2662
2015-02-17 13:59:46 +08:00
Alessandro Ranellucci
d44bf38906 Sync viewport of 3D views. #2628 2015-02-16 00:37:36 +01:00
Alessandro Ranellucci
09c8563e71 Bugfix: background processing were not restarted after the previous one failed because of a validation error. #2633 2015-02-16 00:05:39 +01:00
Alessandro Ranellucci
a07c48bb30 Fixed regression causing [input_filename] and [input_filename_base] not being available in custom G-code anymore. Includes regression test. #1507 2015-02-15 23:47:35 +01:00
Alessandro Ranellucci
c0f453f83e Simpler and more robust implementation of extra perimeters. #2395 2015-02-15 21:58:14 +01:00
Alessandro Ranellucci
5574e376d6 More aggressive gap fill #2560 2015-02-15 18:25:24 +01:00
Alessandro Ranellucci
ba6ae12635 Change end_program() to postamble() 2015-02-15 17:09:17 +01:00
Alessandro Ranellucci
1180a6d83f Merge pull request #2508 from strahlex/machinekit-gcode
added support Machinekit flavour GCode
2015-02-15 17:00:08 +01:00
Alessandro Ranellucci
8851dc7f23 Added failing test case for upstream Clipper issue 126 (our #2639) 2015-02-15 16:47:55 +01:00
Alessandro Ranellucci
32b8eb489c Updated Clipper to 6.2.8. This fixes several minor issues, including infill paths not being trimmed correctly. #2448 2015-02-15 16:10:04 +01:00
Alessandro Ranellucci
43f4806142 Load files into the GUI when supplying them as command line arguments along with the --gui switch. #2644 2015-02-14 12:54:06 +01:00
Alessandro Ranellucci
6eb1fa36ed Bugfix: bridge speed was still used for first object layer above raft when support_material_contact_distance == 0. Includes regression tests. #2656 2015-02-14 12:47:33 +01:00
Alessandro Ranellucci
dd17682fac Merge pull request #2658 from kentfredric/typemaps
Remove redundant dep on ExtUtils::Typemap
2015-02-13 19:16:49 +01:00
Kent Fredric
df5c2a6f11 Remove redundant dep on ExtUtils::Typemap
Typemap (Singluar) version 1.00 is essentially identical to Typemaps (Plural)
 Typemap is literally a dumb subclass of TypeMaps, and so this
 dependency simply gives an extra installation requirement that does
 nothing.
2015-02-14 06:44:22 +13:00
Alexander Rössler
cef1494852 Switched to P parameter instead of S for Machinekit flavour MCode commands 2015-02-10 14:22:23 +01:00
Alessandro Ranellucci
13d1393ae4 Fixed buttons size on Linux. #2642 2015-02-09 11:04:28 +01:00
Alessandro Ranellucci
64144d007c Typo in 4083b33807 2015-02-09 11:02:11 +01:00
Alessandro Ranellucci
4083b33807 Bugfix: crash on version check on Linux. #2641 2015-02-09 11:00:44 +01:00
Alessandro Ranellucci
a68fed3938 Bump version number 2015-02-09 10:53:55 +01:00
Alexander Rössler
cc83e9f06d using end_program() function in GCode output 2015-02-07 12:37:00 +01:00
Alexander Rössler
f2fa8cb63f added end_program() function to GCodeWriter 2015-02-07 12:36:29 +01:00
Alexander Rössler
d6feec808c enabling firmware retraction for Machinekit in GUI 2015-02-07 12:35:35 +01:00
Alexander Rössler
32eff40422 added retract and unretract command for Machinekit flavour 2015-02-06 19:16:57 +01:00
Alexander Rössler
d35226b889 added support Machinekit flavour GCode 2015-02-06 18:48:46 +01:00
Joseph Lenox
102785d154 Fix a warning about unused return value when using freopen in admesh. Added another NULL check for safety. 2015-02-05 00:58:27 -06:00
Alessandro Ranellucci
0d822f0ec2 Removing Perl 5.12 from Travis CI, adding 5.20 2015-02-01 22:01:24 +01:00
Alessandro Ranellucci
73eb11b395 Releasing 1.2.6 2015-02-01 15:47:29 +01:00
Alessandro Ranellucci
3ae6f2630e Merge branch 'master' into sender
Conflicts:
	Build.PL
2015-02-01 14:07:32 +01:00
Alessandro Ranellucci
bb3bf28e59 Ported prepare_fill_surfaces() to XS/C++ 2015-02-01 12:43:58 +01:00
Alessandro Ranellucci
97b5d76d50 Enforce cleaner honeycomb paths 2015-02-01 12:27:20 +01:00
Alessandro Ranellucci
8b6b192dac Throw an error for first_layer_height == 0. #2605 2015-02-01 12:18:18 +01:00
Alessandro Ranellucci
07cd25d0ec New option for customization of infill/perimeters overlap. #2459 2015-02-01 12:08:25 +01:00
Alessandro Ranellucci
fbcf5319ea Fixed regression in seam_position = aligned. #2604 2015-01-31 21:45:27 +01:00
Alessandro Ranellucci
98417f77f0 Some improvements to the Simple Mode 2015-01-31 12:46:24 +01:00
Alessandro Ranellucci
2e88b088e6 Make tests happy with new defaults 2015-01-31 12:10:50 +01:00
Alessandro Ranellucci
84eb37e218 Typo in previous commit 2015-01-31 11:57:18 +01:00
Alessandro Ranellucci
62e418d0fc Modernize some defaults 2015-01-31 11:38:17 +01:00
Alessandro Ranellucci
059b00a829 New --before-layer-change option and new layer_z placeholder. #2602 2015-01-30 20:08:00 +01:00
Alessandro Ranellucci
2d3fdf920b Fixed SVG export not placing object inside the SVG viewport anymore. #2601 2015-01-30 19:34:46 +01:00
Alessandro Ranellucci
8605969dc5 Don't output slic3r:z attribute in SVG for raft layers 2015-01-30 18:45:30 +01:00
Alessandro Ranellucci
e2b1b52679 Added a new Slic3r::Geometry::simplify_polygons() function 2015-01-30 18:33:20 +01:00
Alessandro Ranellucci
d4ba0f17bb Remove artifacts in original slices so that they're not amplified while generating perimeters. #2561 #2416 2015-01-30 18:32:25 +01:00
Alessandro Ranellucci
e61deb3673 Check display area before moving window to the last saved position. #2600 2015-01-30 13:21:07 +01:00
Alessandro Ranellucci
fe4f79ba90 Fixed regression causing random loss of infill because of corrupt thin polygons returned by Clipper. #2539 2015-01-30 10:12:31 +01:00
Alessandro Ranellucci
9ad5d9bb3d Fixed minor issue in 3D preview causing single-line toolpaths to miss the cap on one endpoint 2015-01-28 23:35:48 +01:00
Alessandro Ranellucci
7652abdf8d Merge pull request #2595 from xdissent/deserialize-points
Use std::getline to deserialize point list coords, fixes #2318
2015-01-28 21:02:05 +01:00
Alessandro Ranellucci
1d204af6f4 Fixed regression causing rectilinear infill to be misaligned across layers. #2566 2015-01-28 19:49:56 +01:00
Alessandro Ranellucci
3dedae3928 Enable/disable config fields according to CLI options 2015-01-28 19:14:15 +01:00
Greg Thornton
b0b9c17c23 Use std::getline to deserialize point list coords, fixes #2318 2015-01-28 09:08:50 -06:00
Alessandro Ranellucci
d5a2714db2 Merge pull request #2551 from cyplo/sudo-readme-changes
I suggest using "perl Build.PL --sudo" instead of "sudo perl Build.PL" in the README file.
2015-01-28 13:37:03 +01:00
Alessandro Ranellucci
b1f1893481 Bugfix: tangent horizontal mesh surfaces were not included in slices under rare circumstances, generating almost invalid polygons that confused Clipper and caused skipped layers. Includes regression test 2015-01-28 13:00:38 +01:00
Alessandro Ranellucci
8a5a0b6726 Minor optimization in TriangleMesh code 2015-01-25 17:30:55 +01:00
Alessandro Ranellucci
9abcd5816c Little test for mixing objects and toolpaths 2015-01-25 15:36:20 +01:00
Alessandro Ranellucci
c264969962 Bugfix: crash when rendering lines with zero length in 3D preview. #2569 2015-01-25 15:21:45 +01:00
Alessandro Ranellucci
a10a554e2a Remember last selected settings page in Printer Settings too, like in Print Settings and Filament Settings. #2568 2015-01-25 11:43:34 +01:00
Alessandro Ranellucci
0a1f5992ad Add Bed Shape to Simple Mode as well. #2574 2015-01-25 11:10:06 +01:00
Alessandro Ranellucci
43f57ba2cb Optimization: don't reload 3D toolpaths each time the preview tab is selected 2015-01-25 10:59:39 +01:00
Alessandro Ranellucci
38d8b1d268 Update bed shape in 3D preview as well 2015-01-25 00:29:51 +01:00
Alessandro Ranellucci
a5c0ffe963 Faster loading of 3D preview and much less memory used 2015-01-24 23:35:29 +01:00
Cyryl Plotnicki-Chudyk
1bc83e658b use 'perl Build.PL --sudo' instead of 'sudo perl Build.PL' 2015-01-20 16:48:15 +01:00
Alessandro Ranellucci
8cfd2e33d8 Wrong line included in previous commit 2015-01-19 18:54:35 +01:00
Alessandro Ranellucci
8791f5a493 Cleanup of some method signatures and of XS return types 2015-01-19 18:53:04 +01:00
Alessandro Ranellucci
c9cdae1a96 Wrong file included in previous commit 2015-01-19 15:32:39 +01:00
Alessandro Ranellucci
229039d3b8 Fixed test and implementation of ooze prevention standby points (wrong test caused wrong implementation). #2103 2015-01-19 15:31:12 +01:00
Alessandro Ranellucci
7b980c1dc9 New option for vertical distance between object and support material, with special handling of the 0 case that disabled bridge flow/speed in order to allow for soluble material. #2491 #2272 #2069 #1942 #2435 #1703 2015-01-19 09:52:24 +01:00
Alessandro Ranellucci
fc5437f6d3 Require disabled support material for Spiral Vase 2015-01-18 22:21:50 +01:00
Alessandro Ranellucci
ba4325411b Bugfix: the downwards move in sequential printing was performed in the wrong spot. #2524 2015-01-18 22:08:43 +01:00
Alessandro Ranellucci
3d500ca317 Skip geometry from unfinished steps in 3D rendering 2015-01-18 21:31:09 +01:00
Alessandro Ranellucci
b782351fd3 Enable arrows in 3D preview and rename preview tabs 2015-01-18 20:55:44 +01:00
Alessandro Ranellucci
428f831886 Scroll 3D preview layers with a slider 2015-01-18 20:48:54 +01:00
Alessandro Ranellucci
f2818ddbe0 Live 3D toolpaths preview. 2015-01-18 19:36:47 +01:00
Alessandro Ranellucci
3648bbd6d4 Require an up-to-date Win32::API version because older ones are not thread-safe and cause random segfaults. #2517 2015-01-18 16:52:55 +01:00
Alessandro Ranellucci
90afbc8bd9 Bugfix: don't crash when skirts > 0 but skirt_height = 0. Includes regression test. #2537 2015-01-18 13:01:00 +01:00
Alessandro Ranellucci
9f0283f808 Minor issue when dealing with files with empty layers at bottom. #2553 2015-01-18 12:35:05 +01:00
Alessandro Ranellucci
f11196525b Handle empty STL files gracefully instead of crashing. #2557 2015-01-18 12:12:10 +01:00
Alessandro Ranellucci
4696b46475 Clarified tooltip for First Layer Extrusion Width. #2543 2015-01-18 11:42:19 +01:00
Alessandro Ranellucci
b646b5c98a Revert "Updated Clipper to 6.2.7"
This reverts commit e6c022a61c.
2015-01-18 01:31:10 +01:00
Alessandro Ranellucci
e9d08ce51f Updated MANIFEST 2015-01-18 01:14:14 +01:00
Alessandro Ranellucci
e6c022a61c Updated Clipper to 6.2.7 2015-01-18 01:07:23 +01:00
Alessandro Ranellucci
357f10732a Added test case for a Clipper bug 2015-01-18 01:07:23 +01:00
Alessandro Ranellucci
2bbb6c570b Ported toolpaths rendering to C++ 2015-01-18 01:07:22 +01:00
Alessandro Ranellucci
bfbcbd55d8 Render infill and support material as well 2015-01-18 01:07:22 +01:00
Alessandro Ranellucci
cf4119e169 Populate ExtrusionPath::height correctly in case of bridge 2015-01-18 01:07:22 +01:00
Alessandro Ranellucci
d781371d66 Join extrusions properly in 3D preview 2015-01-18 01:07:22 +01:00
Alessandro Ranellucci
ce1d368037 Use 3D as the default view 2015-01-17 10:53:01 +01:00
Alessandro Ranellucci
35da87a90a Check whether the configured post-processing scripts are executable and show an error when they aren't 2015-01-17 10:50:34 +01:00
Alessandro Ranellucci
89f0c60fc8 Adapt t/multi.t to new behavior of auto_assign_extruders() 2015-01-17 10:36:42 +01:00
Alessandro Ranellucci
b77d35f6f1 Don't autoassign extruders to material config. #2522 2015-01-16 16:35:35 +01:00
Alessandro Ranellucci
e749f6040f New +Line::intersection_infinite() method 2015-01-16 16:25:39 +01:00
Alessandro Ranellucci
aa69ae11a8 Prune very short thin walls 2015-01-15 22:37:55 +01:00
Alessandro Ranellucci
a616d64971 Bump version number 2015-01-15 22:35:14 +01:00
Alessandro Ranellucci
e0a3d2577c Initial work for 3D rendering of toolpaths 2015-01-15 20:06:30 +01:00
Alessandro Ranellucci
18e815d032 More efficient 3D preview of slices 2015-01-15 18:49:07 +01:00
Alessandro Ranellucci
306bc02e29 Fix --help, wrong default were displayed for a couple options. #2541 2015-01-15 17:49:22 +01:00
Alessandro Ranellucci
24e8307e68 Faster algorithm for sorting perimeter loops 2015-01-15 17:42:39 +01:00
Alessandro Ranellucci
56853319d1 Restore correct Z alignment after cut 2015-01-14 23:26:28 +01:00
Alessandro Ranellucci
2a7f1a8c19 Only show a single instance in settings and cut dialogs 2015-01-14 23:24:01 +01:00
Alessandro Ranellucci
ebf17d14f0 Open the Object Settings dialog when double clicking an item in the list instead of the cut dialog 2015-01-14 23:21:54 +01:00
Alessandro Ranellucci
b518d5d32f New command for setting the number of copies of the selected object. #2540 2015-01-14 23:19:13 +01:00
Alessandro Ranellucci
bf02062a67 Bugfix: random but frequent crashes after recent perimeter code refactoring 2015-01-14 22:55:11 +01:00
Alessandro Ranellucci
d1243397fa Make tests happy 2015-01-14 00:14:56 +01:00
Alessandro Ranellucci
9a7e5327ab Support --solid-fill-pattern for legacy. #2527 2015-01-13 23:22:27 +01:00
Alessandro Ranellucci
aa5bafb8be Support preset names with Unicode characters. #2527 2015-01-13 23:22:27 +01:00
Alessandro Ranellucci
9c08dfb50c Merge pull request #2531 from lordofhyphens/issue_2526
Fix for issue #2526, changed to GET.
2015-01-13 20:59:14 +01:00
Alessandro Ranellucci
88b62a9923 Merge pull request #2532 from lordofhyphens/issue2530_partial_fix
A partial fix for issue #2530
2015-01-13 20:58:53 +01:00
Alessandro Ranellucci
5b074540e6 Merge pull request #2536 from adius/master
Fix typo in documentation
2015-01-13 20:58:00 +01:00
Alessandro Ranellucci
04aa240265 Only apply perimeter/infill overlap to the endpoints of rectilinear infill (and do that in a more proper way) 2015-01-13 20:55:20 +01:00
Alessandro Ranellucci
3ee0fc5b1c Ability to select object parts by clicking in the 3D view in the object editor 2015-01-13 20:55:19 +01:00
Alessandro Ranellucci
d46d5c955b One more refactoring in 3DScene (select group/drag group) 2015-01-13 20:55:19 +01:00
Alessandro Ranellucci
9c8f8f8ded Refactoring: make Slic3r::GUI::3DScene::Base model-independent 2015-01-13 20:55:19 +01:00
adius
4b38cffc60 Fix typo in documentation 2015-01-13 00:19:01 +01:00
Joseph Lenox
4f2e172561 A partial fix for issue #2530, which will makes the bonjour dialog put the port number in the string. 2015-01-12 12:10:56 -06:00
Joseph Lenox
90811f6736 Fix for issue #2526, changed to GET. 2015-01-12 11:56:54 -06:00
Alessandro Ranellucci
28d7b0dba6 Write fatal errors to console as well 2015-01-09 14:50:42 +01:00
Alessandro Ranellucci
40ce69ce5c Make Test::Harness optional 2015-01-09 14:02:49 +01:00
Alessandro Ranellucci
bb9ceba343 Releasing 1.2.5 2015-01-09 13:44:28 +01:00
Alessandro Ranellucci
02d717b7a3 Don't put any M200 automatically when volumetric mode is selected. Explain how to do it manually in the tooltip. #1746 2015-01-09 12:02:04 +01:00
Alessandro Ranellucci
fb08588007 Renamed PreviewCanvas to 3DScene 2015-01-09 01:30:04 +01:00
Alessandro Ranellucci
0a62d658d9 Removed ObjectPreviewDialog not used anymore 2015-01-09 01:27:35 +01:00
Alessandro Ranellucci
4c7d9dfef5 Memory optimization in PreviewCanvas: don't keep additional meshes in memory when not needed 2015-01-09 01:18:47 +01:00
Alessandro Ranellucci
64c9e3af4b Bugfix: objects were floating in STL export after rotation and flip. #2512 2015-01-09 00:47:40 +01:00
Alessandro Ranellucci
766b301f78 Typo 2015-01-08 22:51:21 +01:00
Alessandro Ranellucci
9ec7b43ca1 Merge branch 'master' into sender
Conflicts:
	lib/Slic3r/GUI/Tab.pm
2015-01-08 22:47:43 +01:00
Alessandro Ranellucci
9f4f711017 Disable the OctoPrint test button when LWP::UserAgent is not available 2015-01-08 21:37:00 +01:00
Alessandro Ranellucci
24daa50bfd Button for testing OctoPrint connectivity. #2509 2015-01-08 21:34:51 +01:00
Alessandro Ranellucci
79cb350f2d Fixed segfault in new MotionPlanner code when environments were empty (small islands). #2511 2015-01-08 21:24:51 +01:00
Alessandro Ranellucci
2f255620c6 Fix toolpath preview after recent change of semantics of LayerRegion::perimeters 2015-01-08 15:41:17 +01:00
Alessandro Ranellucci
8b11adb883 Enlarge the About dialog. #2476 2015-01-08 15:34:42 +01:00
Alessandro Ranellucci
fc47892474 Bump version number 2015-01-08 15:31:59 +01:00
Alessandro Ranellucci
c908d4d96e Restore correct depth test for the Z axis. #2510 2015-01-08 15:31:13 +01:00
Alessandro Ranellucci
406d045ced The inwards move after an external loop was still randomly generated outwards in some cases. Perimeters are now generated with a distinct iterator for each slice. Nested islands are also correctly supported too. Various regression tests included. #2253 2015-01-08 15:22:13 +01:00
Alessandro Ranellucci
af92e3d49e Bugfix: validation for sequential printing was not entirely correct. #2480 2015-01-07 21:57:22 +01:00
Alessandro Ranellucci
9b9ed91e6e Nicer rendering for 3D slices 2015-01-07 20:45:50 +01:00
Alessandro Ranellucci
d5cab6221d Better lighting in the 3D view 2015-01-07 20:11:03 +01:00
Alessandro Ranellucci
a4235f5f44 Better axes rendering 2015-01-07 19:49:54 +01:00
Alessandro Ranellucci
06aaf83cfe Restored correct transparency of the cutting plane 2015-01-07 19:46:37 +01:00
Alessandro Ranellucci
b085710a4b Further refactoring to PerimeterGenerator: remove the $traverse closure 2015-01-07 16:16:00 +01:00
Alessandro Ranellucci
82ec03fc23 Refactored perimeter generation code into a new separate class for easier unit testing 2015-01-07 16:04:53 +01:00
Alessandro Ranellucci
6962b8dddd Glitches when panning with middle mouse button. #2454 2015-01-07 11:58:22 +01:00
Alessandro Ranellucci
4688ae2fb6 Bugfix: rotation in 3D view was randomly stopping. #2482 2015-01-07 11:13:56 +01:00
Alessandro Ranellucci
1b766f12ca Minor fix after recent changes in MotionPlanner 2015-01-06 23:30:28 +01:00
Alessandro Ranellucci
21a660c56c Fix compilation 2015-01-06 21:29:32 +01:00
Alessandro Ranellucci
0de1c235a9 Reversed mouse wheel zooming in 3D once more. #2478 2015-01-06 21:08:33 +01:00
Alessandro Ranellucci
49817aac34 Removed test that doesn't apply anymore because the logic of only_retract_when_crossing_perimeters is much more complex now 2015-01-06 21:04:00 +01:00
Alessandro Ranellucci
d4ae734659 Minor improvement to IntersectionLine (now subclasses Line) 2015-01-06 20:58:07 +01:00
Alessandro Ranellucci
39172d5a08 Fixed typo causing test to fail 2015-01-06 20:54:32 +01:00
Alessandro Ranellucci
8f4cbefd0d Lots of improvements to MotionPlanner/avoid_crossing_perimeters. Smoother paths and several edge cases now handled better 2015-01-06 20:52:36 +01:00
Alessandro Ranellucci
5e100abe25 Added several drawing methods to Slic3r::SVG 2015-01-06 20:51:48 +01:00
Alessandro Ranellucci
713fcb5e8e New methods in Slic3r::SVG C++ class 2015-01-06 16:26:15 +01:00
Alessandro Ranellucci
f0de57cbe4 Minor cleanup of the init_external_mp() call 2015-01-06 15:04:09 +01:00
Alessandro Ranellucci
2562070232 Refactored the travel/retract/avoid_crossing_perimeters logic. Several edge cases are now handled correctly. #2498 2015-01-06 14:52:03 +01:00
Alessandro Ranellucci
7e82159620 Fixed one more case where only_retract_when_crossing_perimeters didn't apply. #2498 2015-01-06 11:29:34 +01:00
Alessandro Ranellucci
0f7933c4f9 Bugfix: pressure regulation accumulated too much retraction and didn't discharge at the end of print. Includes regression test. #2470 2015-01-06 00:35:39 +01:00
Alessandro Ranellucci
9fd0637990 Bugfix: artifacts were introduced when perimeters were recalculated through incremental slicing. #2494 2015-01-05 21:00:50 +01:00
Alessandro Ranellucci
3332282767 Unit test for pressure advance. #2470 2015-01-05 20:07:47 +01:00
Alessandro Ranellucci
47e4e8bb66 Option to use volumetric E values. #1746 2015-01-05 19:39:10 +01:00
Alessandro Ranellucci
6776d6bc00 Bugfix: a bug in Polyline::split_at() caused random loss of perimeter segments. #2495 2015-01-05 15:51:57 +01:00
Alessandro Ranellucci
9507fb91f0 Serial ports detection on Win32 2015-01-04 23:53:59 +01:00
Alessandro Ranellucci
9af43bee52 Handle log, temperatures. Move controller to main tabpanel. More things 2015-01-04 23:18:23 +01:00
Alessandro Ranellucci
3ab4d4b094 Merge branch 'master' into sender 2015-01-04 19:36:28 +01:00
Alessandro Ranellucci
a6f3e6bfdb Mark Vibration Limit as deprecated. #2483 2015-01-04 19:32:59 +01:00
Alessandro Ranellucci
92e896c4d1 Prettify infill pattern labels 2015-01-04 19:32:05 +01:00
Alessandro Ranellucci
6c7c089fc4 Disable the "Export G-code" and "Send to print" buttons when other actions are pending 2015-01-04 19:29:34 +01:00
Alessandro Ranellucci
0775960b9f Minor reordering of options 2015-01-04 19:20:13 +01:00
Alessandro Ranellucci
cbc0e270b7 Nicer configuration fields for USB/Serial connection 2015-01-04 19:14:54 +01:00
Alessandro Ranellucci
16939b80e6 Implemented priority queue 2015-01-04 18:17:15 +01:00
Alessandro Ranellucci
af1b705563 Increase HTTP timeout for Octoprint upload. #2481 2015-01-04 15:30:31 +01:00
Alessandro Ranellucci
6438bfc3cb Draw bed contours with grid linewidth 2015-01-04 13:36:14 +01:00
Alessandro Ranellucci
84c30c1cf5 Nicer bed appearance 2015-01-04 13:32:00 +01:00
Alessandro Ranellucci
694268d6c7 Fix incomplete grid in 3D preview 2015-01-04 13:17:20 +01:00
Alessandro Ranellucci
510b472b51 Gradient background for 3D view 2015-01-04 13:11:05 +01:00
Alessandro Ranellucci
504cbd89db Fix bug in admesh code that causes random binary STL files not to be read correctly on Windows. #2461 2015-01-04 11:46:58 +01:00
Alessandro Ranellucci
b4a6d0acee Handle connection failures with a timeout 2015-01-03 23:33:52 +01:00
Alessandro Ranellucci
2c0d216c1a More work on print controller 2015-01-03 23:25:55 +01:00
Alessandro Ranellucci
3b09377a43 Export single object as STL from its contextual menu. #2479 2015-01-03 15:48:53 +01:00
Alessandro Ranellucci
d46d9079a3 Fixed test after recent change of distance_to_line() semantics 2015-01-03 15:41:54 +01:00
Alessandro Ranellucci
73d45dd851 Minor cleanup of Layer::Region::_fill_gaps() 2015-01-03 15:11:33 +01:00
Alessandro Ranellucci
d8be67c28b Bugfix: Douglas-Peucker used perpendicular distance instead of shortest distance, thus clipping more than it should. #2474 2015-01-03 15:03:53 +01:00
Alessandro Ranellucci
69da8b0999 Use borderless buttons for save/delete in presets management (better look on wxOSX with 3.0.0) 2015-01-01 17:14:57 +01:00
Alessandro Ranellucci
93687c1491 Disable Growl notifications if register() fails - this prevents a deadlock on growler->notify() 2015-01-01 12:37:38 +01:00
Alessandro Ranellucci
c06ce3b58c Initial work for a controller GUI 2014-12-31 19:10:46 +01:00
Alessandro Ranellucci
29d64107de Merge branch 'master' into sender 2014-12-31 16:25:26 +01:00
Alessandro Ranellucci
1eac452d71 Send file basename when uploading to OctoPrint 2014-12-30 22:07:47 +01:00
Alessandro Ranellucci
fffdbe0abb Releasing 1.2.4 2014-12-30 14:51:59 +01:00
Alessandro Ranellucci
7fa27c958a Bugfix: when dragging an object, only one part was moving. #2467 2014-12-30 14:21:10 +01:00
Alessandro Ranellucci
77d2a8aa8c Fix Preferences window size. #2463 2014-12-30 13:24:00 +01:00
Alessandro Ranellucci
c4832c5342 Bugfix: early object destruction caused a segfault when splitting. Also fixed a memory leak and restore background processing when split only detected one part. #2466 #2398 2014-12-30 13:16:28 +01:00
Alessandro Ranellucci
494efe65b2 Bugfix: auto-center didn't update the PrintObject copies properly, causing misalignment. #2464 2014-12-29 22:29:24 +01:00
Alessandro Ranellucci
4b7cec28b9 Fix to Octoprint upload. #2465 2014-12-29 20:34:33 +01:00
Alessandro Ranellucci
9d5f55af77 Minor optimization in G-code export 2014-12-29 17:40:56 +01:00
Alessandro Ranellucci
1c0437bc7b One more fix to 3D honeycomb not covering the entire area after last commit 2014-12-29 15:52:48 +01:00
Alessandro Ranellucci
67d7658c59 Bugfix: random misalignment of the 3D Honeycomb pattern 2014-12-29 14:42:41 +01:00
Alessandro Ranellucci
d38503bf44 Bugfix: downwards interface detection might cause a crash 2014-12-29 14:29:21 +01:00
Alessandro Ranellucci
200130bc10 Bump version number 2014-12-29 12:49:49 +01:00
Alessandro Ranellucci
6896e53078 Octoprint -> OctoPrint 2014-12-29 12:49:32 +01:00
Alessandro Ranellucci
13b4237fec Releasing 1.2.3 2014-12-29 11:45:41 +01:00
Alessandro Ranellucci
242dc17680 Minor improvements to Octoprint integration 2014-12-29 11:45:09 +01:00
Alessandro Ranellucci
de2fd9721c Fixed ooze prevention test as well 2014-12-29 01:37:34 +01:00
Alessandro Ranellucci
0b77fe743c Workaround for upstream bug in OpenGL test that prevents installation 2014-12-29 01:10:34 +01:00
Alessandro Ranellucci
e8dc981774 Fixes to Ooze Prevention 2014-12-29 00:51:27 +01:00
Alessandro Ranellucci
c43049e13b Prevent rare crashes using Ooze Prevention 2014-12-28 22:09:28 +01:00
Alessandro Ranellucci
b468e68c59 Bonjour autodiscovery of the Octoprint instances in local network. #1826 2014-12-28 18:49:52 +01:00
Alessandro Ranellucci
5d4d79191a Fixed regression causing bridges not to be printed with rectilinear pattern when --external-fill-pattern was set. #2460 2014-12-28 17:29:21 +01:00
Alessandro Ranellucci
959eb60ad0 Scoping error caused the Unsaved Changes dialog not to be shown when closing the main window 2014-12-28 16:19:55 +01:00
Alessandro Ranellucci
c1e44eb591 Fixed extra comment that prevented the Export STL button from working after the recent changes in plater layout. #2458 2014-12-28 14:59:28 +01:00
Alessandro Ranellucci
fbb3462f5b Bump version number 2014-12-28 14:58:58 +01:00
Alessandro Ranellucci
efe7d5f857 Integration with Octoprint. #1826 2014-12-28 01:30:05 +01:00
Alessandro Ranellucci
eba19aaba4 Fixed Object part editor because it wasn't updated with the new PreviewCanvas API. #2455 2014-12-28 00:16:15 +01:00
Alessandro Ranellucci
b126f92f41 Finished GCodeSender 2014-12-27 22:58:01 +01:00
Alessandro Ranellucci
8b438dc0de Merge branch 'master' into sender 2014-12-27 18:10:03 +01:00
Alessandro Ranellucci
9803e2fabf Releasing 1.2.2 2014-12-27 14:38:55 +01:00
Alessandro Ranellucci
53e8699765 Prepend option category in the unsaved changes dialog 2014-12-27 14:38:06 +01:00
Alessandro Ranellucci
bbb47e087a Restore functionality of Test::SectionCut 2014-12-27 13:04:28 +01:00
Alessandro Ranellucci
b5b0df2426 Adapt SectionCut to the new APIs 2014-12-26 18:57:21 +01:00
Alessandro Ranellucci
005f138ce7 Merge branch 'master' into sender 2014-12-26 01:30:48 +01:00
Alessandro Ranellucci
5dc635b0b1 Pan with middle mouse button too. #2444 2014-12-25 20:08:47 +01:00
Alessandro Ranellucci
6ac82f1a20 Fix cutting of objects rotated around X or Y 2014-12-25 20:04:59 +01:00
Alessandro Ranellucci
5d9ff677c0 Workaround wxMSW not catching mouse wheel events if panel has no focus. #2424 2014-12-25 19:51:53 +01:00
Alessandro Ranellucci
ce395dfba8 💄 2014-12-25 19:42:24 +01:00
Alessandro Ranellucci
4c3fa999f5 Only draw the slices in toolpath preview for the current selected layer 2014-12-25 19:35:51 +01:00
Alessandro Ranellucci
617fbaa9bd Restore expansion of filament choosers 2014-12-25 19:14:18 +01:00
Alessandro Ranellucci
dbbc6e7e55 Update plater preset selectors when dismissing unsaved changes 2014-12-25 18:52:27 +01:00
Alessandro Ranellucci
6c2a28166a Rearrange plater's layout slightly in order to have larger preset selectors 2014-12-25 18:50:02 +01:00
Alessandro Ranellucci
cc36aff66a Fix MainFrame after recent changes in preset handling 2014-12-25 18:18:41 +01:00
Alessandro Ranellucci
70601eeb51 Tell what options were changed when prompting user for saving a modified preset. Also, check whether the preset was actually modified by performing a proper idempotent diff. #2165 2014-12-25 17:35:31 +01:00
Alessandro Ranellucci
5a0f4eac8d One more retraction optimization 2014-12-25 11:37:54 +01:00
Alessandro Ranellucci
70f454c693 Fixed regression in inwards move 2014-12-25 11:06:42 +01:00
Alessandro Ranellucci
ffff597bfe Bugfix: the Bed Shape dialog didn't retain rectangle origin correctly. #2427 2014-12-25 02:36:10 +01:00
Alessandro Ranellucci
5639132dae Bugfix: the region_volumes vector was not always extended after creating new regions, causing bad memory access in apply_config(). #2446 2014-12-24 18:35:59 +01:00
Alessandro Ranellucci
33f7b08c80 Fix t/support.t after changing contact distance on top surfaces 2014-12-24 12:11:30 +01:00
Alessandro Ranellucci
19548fe301 Don't perform wiping if we have just changed layer and no extrusions were performed before the first retraction. Includes regression test. #2214 2014-12-24 12:02:42 +01:00
Alessandro Ranellucci
9dd228df01 Enable the GLU tesselator on MSW if we have a recent OpenGL module 2014-12-24 11:49:27 +01:00
Alessandro Ranellucci
4848cb7606 Ported PrintObject::bridge_over_infill() to XS 2014-12-24 10:20:55 +01:00
Alessandro Ranellucci
ea40c4d1b0 Fixed rendering of multiple interlaced layers in toolpaths preview 2014-12-24 01:34:35 +01:00
Alessandro Ranellucci
5d3cd792eb Make infill_only_where_needed idempotent. #2198 2014-12-24 01:29:36 +01:00
Alessandro Ranellucci
350d634433 Enable extruder_offset configuration for first extruder. #2224 2014-12-24 00:34:17 +01:00
Alessandro Ranellucci
9cb6dc768f Limit the Perl version warning to 5.16, as 5.18 seems to work fine 2014-12-24 00:19:20 +01:00
Alessandro Ranellucci
91bc4d8157 Bugfix: a typo caused wrong loop splitting, thus wrong ordering of perimeters having bridging parts. Includes regression test. #2258 2014-12-24 00:11:29 +01:00
Alessandro Ranellucci
c63d5da5c2 Move dump_perl() to Slic3r::Polyline 2014-12-24 00:11:13 +01:00
Alessandro Ranellucci
d47e12f05c Bugfix: a wrong optimization caused some top-level perimeters not to be sorted using the nearest-neighbor search. #2322 2014-12-24 00:10:31 +01:00
Alessandro Ranellucci
af446dc7d4 Apply contact distance to first support layer above object's top surfaces too. #1939 2014-12-23 22:18:43 +01:00
Alessandro Ranellucci
25bc8e6f29 Smarter automatic disabling of GUI fields + reordering of Print Settings pages + minor adjustments to tooltips 2014-12-23 20:47:11 +01:00
Alessandro Ranellucci
092b1724ba Fixed t/vibrationlimit.t 2014-12-23 11:23:12 +01:00
Alessandro Ranellucci
473802ce8c Use support material interface extruder for layers above object's top surfaces too. #1939 2014-12-23 01:04:25 +01:00
Alessandro Ranellucci
a1a88baa68 Revert printf to debugf 2014-12-23 01:04:20 +01:00
Alessandro Ranellucci
6a939eb250 Fight deadlocks 2014-12-22 19:47:39 +01:00
Alessandro Ranellucci
bb907fb405 Don't trigger the on_move callback upon simple object selection with no dragging action 2014-12-22 19:34:19 +01:00
Alessandro Ranellucci
faed500520 Refresh slider when reloading print in toolpath preview canvas 2014-12-22 18:56:16 +01:00
Alessandro Ranellucci
0ded18207b Adapt t/fill.t to the new infill internal API 2014-12-22 17:29:23 +01:00
Alessandro Ranellucci
e49cf2c55f Refactored Line infill implementation 2014-12-22 17:25:52 +01:00
Alessandro Ranellucci
64061267c8 Align infill across layers regardless of first-layer-specific extrusion width. Includes a good internal API refactoring and a fix to 3D honeycomb flow 2014-12-22 16:47:35 +01:00
Alessandro Ranellucci
93507bfd49 Bugfix: only_retract_when_crossing_perimeters was not correctly applied on bottom layer when no bottom solid layers were printed 2014-12-22 11:46:16 +01:00
Alessandro Ranellucci
540c2b8705 Minor additions for debugging 2014-12-22 11:37:28 +01:00
Alessandro Ranellucci
45cc204f74 Center hilbertcurve, archimedeanchords, octagramspiral around object's center and align them across layers 2014-12-22 11:16:01 +01:00
Alessandro Ranellucci
1b582ea66a Remove the "(slow)" mark on infill patterns that used to be slow in the past 2014-12-22 10:48:05 +01:00
Alessandro Ranellucci
bdce1ded7e Disable cross-hatching for hilbertcurve, archimedeanchords, octagramspiral 2014-12-22 10:47:09 +01:00
Alessandro Ranellucci
5cd3ef7b8a Bugfix: PlanePath infills sometimes did not cover the whole area. #863 #1162 2014-12-22 00:18:45 +01:00
Alessandro Ranellucci
74f25ef52f Consolidated all PlanePath classes in a single file 2014-12-21 23:43:53 +01:00
Alessandro Ranellucci
1485659726 Minor rewording. #2411 2014-12-21 23:40:05 +01:00
Alessandro Ranellucci
583b009d1b Honor print bed center in Quick Slice. #2440 2014-12-21 23:29:31 +01:00
Alessandro Ranellucci
4fc955a0fd Fixed concave_points() and convex_points() after recent change of ccw_angle() 2014-12-21 23:10:38 +01:00
Alessandro Ranellucci
7253dc699a Some more work on wireframe 2014-12-21 22:52:18 +01:00
Alessandro Ranellucci
c21a254480 Incomplete work for wireframe 2014-12-21 22:52:18 +01:00
Alessandro Ranellucci
5b51832b62 Wireframe.pl wireframe 2014-12-21 22:52:18 +01:00
Alessandro Ranellucci
9ac60dca1a Fixed vibration limit. 2014-12-21 12:39:19 +01:00
Alessandro Ranellucci
795c85d30e Apply a true double-ended nearest-neightbor search to thin fills in order to minimize travel moves between them. #2213 2014-12-20 22:40:43 +01:00
Alessandro Ranellucci
79ac29b435 Increase inset overlap tolerance 2014-12-20 22:40:34 +01:00
Alessandro Ranellucci
632e3d3067 Added an explicit warning when user has old threads.pm version. #2348 2014-12-17 14:53:36 +01:00
Alessandro Ranellucci
38ecce0ce9 Disable the GLU tesselator on MSW 2014-12-17 14:41:58 +01:00
Alessandro Ranellucci
34a49086e5 Added code for potential antialiasing 2014-12-17 14:28:25 +01:00
Alessandro Ranellucci
a0dda36df0 Minor fix to BridgeDetector 2014-12-17 01:21:12 +01:00
Alessandro Ranellucci
21ea100d0e Fixed tests 2014-12-17 01:15:47 +01:00
Alessandro Ranellucci
9264db7ecd Removed useless thing added in e79aa2e81c 2014-12-17 00:52:01 +01:00
Alessandro Ranellucci
c00061678b Use perimeter extruder for brim. #618 2014-12-17 00:45:05 +01:00
Alessandro Ranellucci
e79aa2e81c New --solid-infill-extruder option. Includes a refactoring of the strategy used to order layer extrusions according to their extruder and island; toolchanges and travel moves should be more optimized now. #618 2014-12-17 00:34:00 +01:00
Alessandro Ranellucci
d9cffeca4a Bugfix: adjust skirt flow according to each layer's height. #2307 2014-12-16 18:55:16 +01:00
Alessandro Ranellucci
99deffef62 Bugfix: use the external motion planner when extruding skirt and brim. #2412 2014-12-16 18:13:38 +01:00
Alessandro Ranellucci
a200498eef Minor fix to view-toolpaths.pl 2014-12-16 18:13:31 +01:00
Alessandro Ranellucci
fcfb3b98bc 3D object positioning 2014-12-16 01:12:56 +01:00
Alessandro Ranellucci
a82f95e903 Some initial work for 3D slice rendering 2014-12-15 15:19:42 +01:00
Alessandro Ranellucci
a34cd24fa1 Overlay object slices in toolpaths preview 2014-12-15 12:42:11 +01:00
Alessandro Ranellucci
9cd0a63331 Refactoring of PreviewCanvas 2014-12-15 01:28:11 +01:00
Alessandro Ranellucci
74b3be3c06 Refactoring in 3D interactive code. Highlight all copies of an object when hovering 2014-12-14 00:54:35 +01:00
Alessandro Ranellucci
2f2ae75529 Some incomplete work for moving objects in 3D plater 2014-12-13 22:18:43 +01:00
Alessandro Ranellucci
ac2b6de62b Minor addition to OpenGL code to prevent darker models 2014-12-13 20:56:22 +01:00
Alessandro Ranellucci
16945dad70 💄 2014-12-13 20:47:59 +01:00
Alessandro Ranellucci
d1f58cbed5 Objects can be selected in 3D preview now. Double click and right click work as well 2014-12-13 20:41:03 +01:00
Alessandro Ranellucci
b0aa1260e2 Bugfix: wxComboBox left blank after menu item selection on MSW due to an undocumented wxWidgets issue. #2361 2014-12-13 15:40:42 +01:00
Alessandro Ranellucci
e9166a8fe6 Use a semaphore to synchronize threads instead of blocking with join(). Lock threads array in order to ensure all of them are signalled. #2394 2014-12-13 15:01:53 +01:00
Alessandro Ranellucci
84760b8d59 Require a recent threads.pm version because of upstream bug 85140 potentially causing deadlocks when stopping running threads. #2394
https://rt.cpan.org/Ticket/Display.html?id=85140
2014-12-13 00:01:24 +01:00
Alessandro Ranellucci
ac495e974a Update test 2014-12-12 23:02:28 +01:00
Alessandro Ranellucci
133466a6b5 Minor improvements to the Skirt Loops tooltip 2014-12-12 22:50:43 +01:00
Alessandro Ranellucci
360dee862b Keep model objects aligned to Z = 0 in plater 2014-12-12 22:43:56 +01:00
Alessandro Ranellucci
050f9ff61a Removed two useless methods in Print 2014-12-12 22:43:56 +01:00
Alessandro Ranellucci
b28fb2ef17 Bugfix: objects were not aligned to Z = 0 before exporting STL from plater. #2393 2014-12-12 22:43:56 +01:00
Alessandro Ranellucci
93d9ee9205 Consider extrusion width in Print::total_bounding_box() 2014-12-12 22:43:56 +01:00
Alessandro Ranellucci
e8ab9ac13a Ported Print::bounding_box(), Print::total_bounding_box(), Print::skirt_flow(), Print:skirt_first_layer_height() to XS 2014-12-12 22:43:56 +01:00
Alessandro Ranellucci
baf070a36d Bugfix: workaround for MSW wxWidgets not drawing the slider 2014-12-12 12:34:40 +01:00
Alessandro Ranellucci
829bd7378e Remove the Rotate... button from Windows as well, like for other operating systems 2014-12-10 17:34:59 +01:00
Alessandro Ranellucci
c8596c5c58 Limit "Only retract when crossing perimeters" so that retraction is triggered also when crossing the boundaries of a single region. #2298 2014-12-09 01:08:58 +01:00
Alessandro Ranellucci
80c38b0113 Remember window size and position. #1253 #2251 2014-12-08 22:05:26 +01:00
Alessandro Ranellucci
d350241da3 Make combine_infill() completely idempotent. Includes unit testing 2014-12-08 21:23:42 +01:00
Alessandro Ranellucci
9a9ba02d85 Bugfix: infill was not correctly generated when infill_every_layers was used along with raft_layers. Includes regression test. #2396 2014-12-08 20:14:04 +01:00
Alessandro Ranellucci
f7026c41c5 Show button icons with wxWidgets 3.x.x too. #2372 2014-12-08 18:23:37 +01:00
Alessandro Ranellucci
2d243a39ff Bugfix: crash when deleting objects from plater with toolpaths preview open. #2389 2014-12-07 20:23:00 +01:00
Alessandro Ranellucci
807d042d11 Typo. #2401 2014-12-07 19:56:35 +01:00
Alessandro Ranellucci
6ce651eb4a Fixed wrong implementation of concave_points() and convex_points() in C++. #2384 2014-12-07 19:53:22 +01:00
Alessandro Ranellucci
95f7bcb9fe Removed Toolpaths Preview menu item. #2385 2014-12-01 21:06:21 +01:00
Alessandro Ranellucci
c9e896c669 Display validation errors in status bar when background processing couldn't generate toolpaths 2014-12-01 00:15:45 +01:00
Alessandro Ranellucci
04bcb410a9 Minor GUI improvements to toolpaths preview 2014-12-01 00:10:32 +01:00
Alessandro Ranellucci
98c67007d5 Finished bb103122065cddf8f8ea63f5e4fce954142c4d4c 2014-12-01 00:00:12 +01:00
Alessandro Ranellucci
eb23990d6d Ported PrintObject::total_layer_count() to XS 2014-12-01 00:00:12 +01:00
Alessandro Ranellucci
c7f5753a28 Ported PrintObject::bounding_box() to XS 2014-12-01 00:00:12 +01:00
Alessandro Ranellucci
1fda9e3d50 Ported concave_points() and convex_points() to XS 2014-12-01 00:00:12 +01:00
Alessandro Ranellucci
076d82d8d6 Fixed regression causing the plater Split command not to remove objects from the model. #2380 2014-12-01 00:00:11 +01:00
Alessandro Ranellucci
e4dd5cf82f Bugfix: object steps were not invalidated when First layer extrusion width was changed. #2379 2014-12-01 00:00:11 +01:00
Alessandro Ranellucci
0d3c4a160f Typo in Reader.pm #2033 2014-12-01 00:00:11 +01:00
Alessandro Ranellucci
80adf9e5d0 Open the settings dialog instead of the cut dialog when user double clicks on objects in plater 2014-12-01 00:00:11 +01:00
Alessandro Ranellucci
e8f242ee3f Move toolpaths preview to the plater dialog 2014-12-01 00:00:11 +01:00
Alessandro Ranellucci
98cb9f0e18 Refactoring: moved G-code export logic into new Slic3r::Print::GCode class. Removed Slic3r::GCode::Layer class. Fixes the order of post-processing filters so that cooling buffer is applied before any other filter whose logic is affected by speeds 2014-12-01 00:00:11 +01:00
Alessandro Ranellucci
7a7d00c8d6 Rename solid_fill_pattern to external_fill_pattern and clarify tooltip 2014-11-27 00:38:05 +01:00
Alessandro Ranellucci
23848492ce Fixed regression causing crash when using avoid_crossing_perimeters with multiple object, caused by recent refactorings. Added regression test 2014-11-26 22:46:51 +01:00
Alessandro Ranellucci
11dd67ab34 Initial work for G-code sender and more intensive usage of Boost 2014-11-26 22:30:25 +01:00
Alessandro Ranellucci
43cbad8867 Minor fix to pressure management: support the case where speed is set before printing commands with a dedicated G1 Fx line 2014-11-24 18:32:18 +01:00
Alessandro Ranellucci
ff9b53260d New experimental feature for pressure management. Credits to @llluis for the original implementation. #1203 #1677 #2018 2014-11-24 18:22:39 +01:00
Alessandro Ranellucci
5a382f0200 Bugfix: Slic3r::GCode::Reader did not parse correctly when use_relative_e_distances was enabled. #2033 2014-11-24 16:30:57 +01:00
Alessandro Ranellucci
945567d1f3 Merge pull request #2278 from hroncok/admesh98
Updated to admesh 0.98.1
2014-11-24 15:36:26 +01:00
Alessandro Ranellucci
55888ace75 Minor cleanup in GCode.pm 2014-11-23 20:16:51 +01:00
Alessandro Ranellucci
634bc09e2c Refactoring: renamed all contains_*() methods to contains() in C++ 2014-11-23 20:14:13 +01:00
Alessandro Ranellucci
5deadc8f12 Refactoring: removed _islands members in Slic3r::GCode 2014-11-23 20:03:16 +01:00
Alessandro Ranellucci
4925b056c2 Fix error in a1193d28bc. #2365
God bless regression tests.
2014-11-23 19:37:59 +01:00
Alessandro Ranellucci
60a76b8cfa Fixed regression causing retraction to be skipped when Retract Length was 0 but Use Firmware Retraction was enabled. Includes regression test. #2359 2014-11-23 19:32:06 +01:00
Alessandro Ranellucci
a1193d28bc Fixed regression causing small perimeter speed not to be applied anymore. #2365 2014-11-23 19:15:28 +01:00
Alessandro Ranellucci
2c64c3dd5b Bugfix: spiral vase was not working when extrusion axis was not E. #2350 2014-11-23 18:59:18 +01:00
Alessandro Ranellucci
c1e26a70f8 Refactoring: move ooze prevention, wipe and avoid crossing perimeters into nested classes for better isolation 2014-11-23 15:13:40 +01:00
Alessandro Ranellucci
3605289bbc --spiral-vase now automatically overrides --perimeters, --top-solid-layers and --fill-density instead of throwing incompatibility error. #2360 2014-11-22 23:10:18 +01:00
Alessandro Ranellucci
399fc519e6 Leave the Spiral Vase checkbox always enabled but prompt user when incompatible options are set. This should be more user-friendly than blindly disabling the Spiral Vase checkbox. #2360 2014-11-22 22:52:12 +01:00
Alessandro Ranellucci
6010297465 All std::string variables are now supposed to be UTF-8 encoded. We now embed the std::string typemaps in order to do this. #2282 2014-11-22 22:20:28 +01:00
Alessandro Ranellucci
989ec5cf4d Fixes to UTF-8 handling in file paths 2014-11-22 21:55:45 +01:00
Alessandro Ranellucci
049859e5b1 Fixed minor regression in plater 2D canvas 2014-11-22 19:42:35 +01:00
Alessandro Ranellucci
bf0eb1af0c Refactored ClipperUtils API for a more consistent arguments convention 2014-11-15 23:44:03 +01:00
Alessandro Ranellucci
28466750e6 Ported some minor methods to XS 2014-11-15 23:06:15 +01:00
Alessandro Ranellucci
379cde30e2 Ported Slic3r::BridgeDetector to XS 2014-11-15 22:41:22 +01:00
Alessandro Ranellucci
36825e0134 Removing empty file 2014-11-13 00:39:06 +01:00
Alessandro Ranellucci
3a12cc5dbf Removing empty file 2014-11-13 00:38:43 +01:00
Alessandro Ranellucci
33fe53fd7c Ported three PrintObject methods to XS 2014-11-13 00:34:56 +01:00
Alessandro Ranellucci
f8986d0ef5 Restore correct behavior for autoarrange after recent commits 2014-11-13 00:23:31 +01:00
Alessandro Ranellucci
875035c09e Minor improvement to plater: select/drag uppermost object when user clicks on overlapping objects 2014-11-13 00:16:41 +01:00
Alessandro Ranellucci
a5df9fb795 Ported ModelObject::split() to XS 2014-11-12 23:50:09 +01:00
Alessandro Ranellucci
334086d605 Bugfix: skirt and brim were not recalculated when objects where just moved in plater 2014-11-12 23:28:42 +01:00
Alessandro Ranellucci
a5787cfb04 Merge branch 'xs-reload-object'
Conflicts:
	lib/Slic3r/Print.pm
2014-11-12 22:51:48 +01:00
Alessandro Ranellucci
9a4e8f39af Refactoring: move split logic in a single place (ModelObject class) 2014-11-12 22:36:03 +01:00
Alessandro Ranellucci
e5cce32302 Merge pull request #2353 from harriv/patch-2
Removed extra ; from Print.cpp
2014-11-12 10:40:46 +01:00
harriv
33cdee1ad6 Removed extra ; from Print.cpp 2014-11-11 22:17:02 +02:00
Alessandro Ranellucci
8b6a8e6307 Ported PlaceholderParser::update_timestamp() to XS
Note that Slic3r version number is now located in libslic3r.h
2014-11-09 20:41:43 +01:00
Alessandro Ranellucci
6135a9fb8b Bugfix: a move below z_offset was performed when retract_lift was enabled and lift amount was less than z_offset. Includes regression test. #2349 2014-11-09 19:24:17 +01:00
Alessandro Ranellucci
ee3fb7caa2 Ported GCodeWriter to XS (faster G-code export!) 2014-11-09 19:02:45 +01:00
Alessandro Ranellucci
b69caff93c Ported LayerRegion::make_slices() to XS 2014-11-09 16:24:07 +01:00
Alessandro Ranellucci
948793e570 Prettier validation errors 2014-11-09 15:31:40 +01:00
Alessandro Ranellucci
bad0bd8520 Ported Print::validate() to XS 2014-11-09 15:27:34 +01:00
Alessandro Ranellucci
3e4c572164 Ported some methods including add_model_object() and apply_config() to XS 2014-11-09 12:25:59 +01:00
Alessandro Ranellucci
6b4015f9ac Bump version number 2014-11-09 09:31:40 +01:00
Alessandro Ranellucci
eab09866cb Releasing 1.2.1 2014-11-08 18:01:53 +01:00
Alessandro Ranellucci
b8ef6c6c26 Bugfix: choice fields were not populated correctly in object and part settings 2014-11-08 15:42:23 +01:00
Alessandro Ranellucci
c97cac5bc9 Fixed glitch in commit 9c93e52c8f causing tests failures 2014-11-08 15:02:58 +01:00
Alessandro Ranellucci
0a351fe47d Fix rendering issue of slider controls on Linux 2014-11-08 14:47:05 +01:00
Alessandro Ranellucci
c1d2c4e457 Bugfix: Z depth issues in 3D preview on Linux. #2197 2014-11-08 14:37:37 +01:00
Alessandro Ranellucci
9c93e52c8f Workaround Clipper changing point coordinates while performing simplify_polygons(), thus causing a crash in Slic3r. #2306 2014-11-08 12:56:14 +01:00
Alessandro Ranellucci
a78be203aa Upgrade Clipper to 6.2.1 2014-11-08 12:05:27 +01:00
Alessandro Ranellucci
67f1cdf76f Bugfix: seam_position = random didn't work with a single perimeter. #2179 2014-11-07 23:53:18 +01:00
Alessandro Ranellucci
c3d401fb41 Limit automatic extrusion width for support material interface as well 2014-11-07 23:35:33 +01:00
Alessandro Ranellucci
09fd5b4af4 Bugfix: adjust flow by using each support layer's height instead of a bogus one. #2269 2014-11-07 23:18:35 +01:00
Alessandro Ranellucci
16fce2facb Fixed minor regression in recent commit 2014-11-07 22:58:48 +01:00
Alessandro Ranellucci
d645dabcff Ported reload_object() to XS 2014-11-07 20:25:05 +01:00
Alessandro Ranellucci
12ba7201c0 Fixed regression causing per-volume settings to be ignored upon background recalculation. #2277 2014-11-07 20:14:02 +01:00
Alessandro Ranellucci
59f0c64e1c Fixed regression test for #2301 2014-11-07 17:27:16 +01:00
Alessandro Ranellucci
66b5f45f45 Merge branch 'issue2301-bridge-speed' 2014-11-07 17:18:17 +01:00
Alessandro Ranellucci
b6bd527bdc Apply bridge flow and speed to first layer as well, when we have raft layers. This behavior is more consistent when all the other bottom surfaces lying on the void (thus on support material). #2301 2014-11-07 17:17:20 +01:00
Alessandro Ranellucci
f07c4ecadb Typo. #2339 2014-11-07 14:25:07 +01:00
Alessandro Ranellucci
bf3f45604a Solid infill below area option was not invalidating the correct steps 2014-11-07 00:53:15 +01:00
Alessandro Ranellucci
fb2d84b5d3 Bugfix: double G10 and G11 commands were issued. #2320 2014-11-07 00:26:39 +01:00
Alessandro Ranellucci
8ad200a352 Minor cleanup of t/gcode.t 2014-11-06 21:13:30 +01:00
Alessandro Ranellucci
9372abb51e Fixed regression in min_skirt_length. Includes regression test. #2337 2014-11-06 21:11:59 +01:00
Alessandro Ranellucci
06385221a3 Make .ini parser more tolerant to whitespace 2014-11-06 21:08:55 +01:00
Alessandro Ranellucci
30b0869595 Bugfix: crash when slicing one layer objects with sailfish G-code flavor. Includes regression test. #2335 2014-11-06 21:06:09 +01:00
Alessandro Ranellucci
11bd1e68e2 Fixed some regressions in retracts and wipe. Includes regression test 2014-11-05 01:16:26 +01:00
Alessandro Ranellucci
a4eef93950 Fixed minor regression 2014-11-04 21:07:18 +01:00
Alessandro Ranellucci
d452a16ba8 Install Class::Accessor with Build.PL --gui. #2315 2014-10-28 23:39:11 +01:00
Alessandro Ranellucci
01133fd0be Fix tests after recent output change for ConfigOptionPoint values 2014-10-28 23:37:20 +01:00
Alessandro Ranellucci
268de5c8e5 More refactoring to GCode.pm: make writer() public and fix usage of Slic3r::GCode without a Slic3r::Layer object 2014-10-28 21:47:09 +01:00
Alessandro Ranellucci
a38ec14cb1 Some minor refactoring and cleaning to the travel_to() method and new init_external_mp() method 2014-10-27 10:34:51 +01:00
Alessandro Ranellucci
ed17c22889 Minor cleanup of imported symbols 2014-10-25 11:15:12 +02:00
Alessandro Ranellucci
366e10d6ec Added comment 2014-10-25 11:10:44 +02:00
Alessandro Ranellucci
e29569a2cd Minor cleanup and refactoring in Slic3r::GCode 2014-10-25 11:00:08 +02:00
Alessandro Ranellucci
36c1a9d20c Renamed shift_x and shift_y into origin 2014-10-25 10:56:21 +02:00
Alessandro Ranellucci
7f57f007cd Refactoring: moved Slic3r::GCode::Base to Slic3r::GCode::Writer 2014-10-25 10:42:07 +02:00
Alessandro Ranellucci
c2e710d092 Removed --g0 2014-10-21 21:41:11 +02:00
Alessandro Ranellucci
71ec90a1dd Finish porting the Extruder class to libslic3r 2014-10-21 20:36:52 +02:00
Alessandro Ranellucci
f82e92f498 Merge branch 'gcode-refactoring' 2014-10-21 20:20:28 +02:00
Alessandro Ranellucci
d34fd844a4 Remove wireframe.pl from the gcode-refactoring branch so that we can merge it into master 2014-10-21 20:19:53 +02:00
Alessandro Ranellucci
167df0ab87 Refactoring: moved most of the low-level G-code to the Slic3r::GCode::Base class. Cleanup of the retraction and wipe logic. 2014-10-21 20:16:45 +02:00
Alessandro Ranellucci
33edda0a69 Moved Slic3r::GCode::Base to its own file 2014-10-18 17:59:52 +02:00
Alessandro Ranellucci
106817d13a Adapt wireframe.pl to the new GCode interface 2014-10-18 17:58:41 +02:00
Alessandro Ranellucci
f8967418b9 Refactoring: moved the ooze prevention logic into a separate class with hooks 2014-10-18 17:58:14 +02:00
Alessandro Ranellucci
e521475b7e Refactoring: moved some low-level G-code generation methods to the new Slic3r::GCode::Base class 2014-10-18 17:41:21 +02:00
Alessandro Ranellucci
4b013d7a48 Added failing test for bridge speed not being used for first object layer above support material. #2301 2014-10-18 14:08:40 +02:00
Alessandro Ranellucci
e5aed3a63e Bump version number 2014-10-18 00:47:01 +02:00
Alessandro Ranellucci
6b8f03ff1c Bugfix: crash in some circumstances when avoid_crossing_perimeters is enabled. #2266 2014-10-15 00:59:26 +02:00
Alessandro Ranellucci
39b41fda12 Bugfix: because of a typo, bridge acceleration wasn't applied anymore. #2296 2014-10-15 00:23:58 +02:00
Alessandro Ranellucci
d0a81dca28 Some initial work for implementing wireframe 2014-10-15 00:23:04 +02:00
Alessandro Ranellucci
0d2dcbc85b Typo in command line help (wrong default for default_acceleration). #2283 2014-09-24 22:25:23 +02:00
Alessandro Ranellucci
6573ae002a Bugfix: fix crash in some circumstances caused by Avoid crossing perimeters. #2271 2014-09-23 20:19:47 +02:00
Alessandro Ranellucci
24d67c42c6 Bugfix: configuration wizard was broken. #2210 2014-09-23 20:00:51 +02:00
Miro Hrončok
b9f4880b23 Updated to admesh 0.98.1 2014-09-23 14:34:37 +02:00
3036 changed files with 518576 additions and 334161 deletions

22
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,22 @@
### Version
_Version of Slic3r used goes here_
_Use `About->About Slic3r` for release versions_
_For -dev versions, use `git describe --tag` or get the hash value for the version you downloaded or `git rev-parse HEAD`_
### Operating system type + version
_What OS are you using, and state any version #s_
### Behavior
* _Describe the problem_
* _Steps needed to reproduce the problem_
* _If this is a command-line slicing issue, include the options used_
* _Expected Results_
* _Actual Results_
* _Screenshots from __*Slic3r*__ preview are preferred_
_Is this a new feature request?_
#### STL/Config (.ZIP) where problem occurs
_Upload a zipped copy of an STL and your config (`File -> Export Config`)_

3
.gitignore vendored
View File

@@ -8,3 +8,6 @@ xs/buildtmp
*.o
MANIFEST.bak
xs/MANIFEST.bak
xs/assertlib*
.init_bundle.ini
local-lib

View File

@@ -1,12 +0,0 @@
language: perl
install: true
script: perl ./Build.PL
perl:
- "5.12"
- "5.14"
- "5.18"
branches:
only:
- master
- stable

View File

@@ -7,42 +7,47 @@ use Config;
use File::Spec;
my %prereqs = qw(
Encode::Locale 0
Devel::CheckLib 0
ExtUtils::MakeMaker 6.80
ExtUtils::ParseXS 3.22
ExtUtils::XSpp 0
ExtUtils::Typemaps 0
ExtUtils::Typemaps::Basic 0
File::Basename 0
File::Spec 0
Getopt::Long 0
Math::PlanePath 53
Module::Build::WithXSpp 0.14
Moo 1.003001
POSIX 0
Scalar::Util 0
Test::Harness 0
Test::More 0
Thread::Semaphore 0
IO::Scalar 0
threads 1.96
Time::HiRes 0
);
my %recommends = qw(
Class::XSAccessor 0
XML::SAX::ExpatXS 0
Test::Harness 0
);
my $sudo = grep { $_ eq '--sudo' } @ARGV;
my $gui = grep { $_ eq '--gui' } @ARGV;
my $xs_only = grep { $_ eq '--xs' } @ARGV;
my $nolocal = grep { $_ eq '--nolocal' } @ARGV;
if ($gui) {
%prereqs = qw(
Class::Accessor 0
Wx 0.9918
Socket 2.016
);
%recommends = qw(
Growl::GNTP 0.15
Wx::GLCanvas 0
OpenGL 0
);
} elsif ($xs_only) {
%prereqs = %recommends = ();
if ($^O eq 'MSWin32') {
$recommends{"Win32::TieRegistry"} = 0;
# we need an up-to-date Win32::API because older aren't thread-safe (GH #2517)
$prereqs{'Win32::API'} = 0.79;
}
}
my @missing_prereqs = ();
@@ -95,27 +100,29 @@ EOF
my @cpanm_args = ();
push @cpanm_args, "--sudo" if $sudo;
# install local::lib without --local-lib otherwise it's not usable afterwards
if (!eval "use local::lib qw(local-lib); 1") {
my $res = system $cpanm, @cpanm_args, 'local::lib';
warn "Warning: local::lib is required. You might need to run the `cpanm --sudo local::lib` command in order to install it.\n"
if $res != 0;
}
push @cpanm_args, ('--local-lib', 'local-lib') if ! $nolocal;
# make sure our cpanm is updated (old ones don't support the ~ syntax)
system $cpanm, @cpanm_args, 'App::cpanminus';
# install the Windows-compatible Math::Libm
if ($^O eq 'MSWin32' && !eval "use Math::Libm; 1") {
system $cpanm, @cpanm_args, 'https://github.com/alexrj/Math-Libm/tarball/master';
}
my %modules = (%prereqs, %recommends);
foreach my $module (sort keys %modules) {
my $version = $modules{$module};
my @cmd = ($cpanm, @cpanm_args, "$module~$version");
if ($module eq 'XML::SAX::ExpatXS' && $^O eq 'MSWin32') {
my $mingw = 'C:\dev\CitrusPerl\mingw64';
$mingw = 'C:\dev\CitrusPerl\mingw32' if !-d $mingw;
if (!-d $mingw) {
print "Could not find the MinGW directory at $mingw; skipping XML::SAX::ExpatXS (only needed for faster parsing of AMF files)\n";
} else {
push @cmd, sprintf('--configure-args="EXPATLIBPATH=%s\lib EXPATINCPATH=%s\include"', $mingw, $mingw);
}
}
my @cmd = ($cpanm, @cpanm_args);
# temporary workaround for upstream bug in test
push @cmd, '--notest'
if $module =~ /^(?:OpenGL|Test::Harness)$/;
push @cmd, "$module~$version";
my $res = system @cmd;
if ($res != 0) {
if (exists $prereqs{$module}) {
@@ -125,36 +132,19 @@ EOF
}
}
}
if (!$gui) {
# clean xs directory before reinstalling, to make sure Build is called
# with current perl binary
if (-e './xs/Build') {
if ($^O eq 'MSWin32') {
system '.\xs\Build', 'distclean';
} else {
system './xs/Build', 'distclean';
}
}
my $res = system $cpanm, @cpanm_args, '--reinstall', '--verbose', './xs';
if ($res != 0) {
die "The XS/C++ code failed to compile, aborting\n";
}
}
}
if (@missing_prereqs) {
printf "The following prerequisites failed to install: %s\n", join(', ', @missing_prereqs);
exit 1;
} elsif (!$gui) {
eval "use App::Prove; 1" or die "Failed to load App::Prove";
my $res = App::Prove->new->run ? 0 : 1;
if ($res == 0) {
print "If you also want to use the GUI you can now run `perl Build.PL --gui` to install the required modules.\n";
} else {
print "Some tests failed. Please report the failure to the author!\n";
}
exit $res;
print "\n";
if ($gui) {
print "Perl dependencies for the Slic3r GUI were installed.\n";
} else {
print "Perl dependencies for Slic3r were installed.\n";
print "If you also want to use the GUI you can now run `perl Build.PL --gui` to install the required modules.\n";
}
print "\n";
print "In the next step, you need to build the Slic3r C++ library.\n";
print "1) Create a build directory and change to it\n";
print "2) run cmake .. -DCMAKE_BUILD_TYPE=Release\n";
print "3) run make\n";
print "4) to execute the automatic tests, run ctest --verbose\n";
__END__

91
CMakeLists.txt Normal file
View File

@@ -0,0 +1,91 @@
# Boost 1.63 requires CMake 3.7 or newer
cmake_minimum_required(VERSION 2.8)
project(Slic3r)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Release)" FORCE)
endif()
if(DEFINED ENV{SLIC3R_STATIC})
set(SLIC3R_STATIC_INITIAL $ENV{SLIC3R_STATIC})
else()
if (MSVC OR MINGW OR APPLE)
set(SLIC3R_STATIC_INITIAL 1)
else()
set(SLIC3R_STATIC_INITIAL 0)
endif()
endif()
option(SLIC3R_STATIC "Compile Slic3r with static libraries (Boost, TBB, glew)" ${SLIC3R_STATIC_INITIAL})
option(SLIC3R_GUI "Compile Slic3r with GUI components (OpenGL, wxWidgets)" 1)
option(SLIC3R_PRUSACONTROL "Compile Slic3r with the PrusaControl prject file format (requires wxWidgets base library)" 1)
option(SLIC3R_PROFILE "Compile Slic3r with an invasive Shiny profiler" 0)
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
if (MSVC AND SLIC3R_MSVC_COMPILE_PARALLEL)
add_compile_options(/MP)
endif ()
# Find the Perl interpreter, add local-lib to PATH and PERL5LIB environment variables,
# so the locally installed modules (mainly the Alien::wxPerl) will be reached.
if (WIN32)
set(ENV_PATH_SEPARATOR ";")
else()
set(ENV_PATH_SEPARATOR ":")
endif()
set(ENV{PATH} "${PROJECT_SOURCE_DIR}/local-lib/bin${ENV_PATH_SEPARATOR}$ENV{PATH}")
set(ENV{PERL5LIB} "${PROJECT_SOURCE_DIR}/local-lib/lib/perl${ENV_PATH_SEPARATOR}$ENV{PERL5LIB}")
message("PATH: $ENV{PATH}")
message("PERL5LIB: $ENV{PERL5LIB}")
find_package(Perl REQUIRED)
# CMAKE_PREFIX_PATH is used to point CMake to the remaining dependencies (Boost, TBB, ...)
# We pick it from environment if it is not defined in another way
if(NOT DEFINED CMAKE_PREFIX_PATH)
if(DEFINED ENV{CMAKE_PREFIX_PATH})
set(CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")
endif()
endif()
# WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory.
# We pick it from environment if it is not defined in another way
if(WIN32)
if(NOT DEFINED WIN10SDK_PATH)
if(DEFINED ENV{WIN10SDK_PATH})
set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}")
endif()
endif()
if(DEFINED WIN10SDK_PATH AND NOT EXISTS "${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h")
message("WIN10SDK_PATH is invalid: ${WIN10SDK_PATH}")
message("${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h was not found")
message("STL fixing by the Netfabb service will not be compiled")
unset(WIN10SDK_PATH)
endif()
endif()
add_subdirectory(xs)
get_filename_component(PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
if (MSVC)
# By default the startup project in MSVC is the 'ALL_BUILD' cmake-created project,
# but we want 'slic3r' as the startup one because debugging run command is associated with it.
# (Unfortunatelly it cannot be associated with ALL_BUILD using CMake.)
# Note: For some reason this needs to be set in the top-level CMakeLists.txt
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT XS)
set(PERL_PROVE "${PERL_BIN_PATH}/prove.bat")
else ()
set(PERL_PROVE "${PERL_BIN_PATH}/prove")
endif ()
enable_testing ()
add_test (NAME xs COMMAND "${PERL_EXECUTABLE}" ${PERL_PROVE} -I ${PROJECT_SOURCE_DIR}/local-lib/lib/perl5 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/xs)
add_test (NAME integration COMMAND "${PERL_EXECUTABLE}" ${PERL_PROVE} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
install(PROGRAMS slic3r.pl DESTINATION bin RENAME slic3r-prusa3d)
file(GLOB MyVar var/*.png)
install(FILES ${MyVar} DESTINATION share/slic3r-prusa3d)
install(FILES lib/Slic3r.pm DESTINATION lib/slic3r-prusa3d)
install(DIRECTORY lib/Slic3r DESTINATION lib/slic3r-prusa3d)

661
LICENSE Normal file
View File

@@ -0,0 +1,661 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

View File

@@ -2,13 +2,16 @@ _Q: Oh cool, a new RepRap slicer?_
A: Yes.
Slic3r [![Build Status](https://travis-ci.org/alexrj/Slic3r.png?branch=master)](https://travis-ci.org/alexrj/Slic3r)
Slic3r
======
Prebuilt Windows, OSX and Linux binaries are available through the [git releases page](https://github.com/prusa3d/Slic3r/releases).
<img width=256 src=https://cloud.githubusercontent.com/assets/31754/22719818/09998c92-ed6d-11e6-9fa0-09de638f3a36.png />
Slic3r takes 3D models (STL, OBJ, AMF) and converts them into G-code instructions for
3D printers. It's compatible with any modern printer based on the RepRap toolchain,
including all those based on the Marlin, Sprinter and Repetier firmware. It also works
with Mach3 and LinuxCNC controllers.
with Mach3, LinuxCNC and Machinekit controllers.
See the [project homepage](http://slic3r.org/) at slic3r.org and the
[manual](http://manual.slic3r.org/) for more information.
@@ -17,7 +20,7 @@ See the [project homepage](http://slic3r.org/) at slic3r.org and the
The core geometric algorithms and data structures are written in C++,
and Perl is used for high-level flow abstraction, GUI and testing.
If you're wondering why Perl, see http://xkcd.com/224/
If you're wondering why Perl, see https://xkcd.com/224/
The C++ API is public and its use in other projects is encouraged.
The goal is to make Slic3r fully modular so that any part of its logic
@@ -30,7 +33,7 @@ Key features are:
* **multi-platform** (Linux/Mac/Win) and packaged as standalone-app with no dependencies required
* complete **command-line interface** to use it with no GUI
* multi-material **(multiple extruders)** object printing
* multiple G-code flavors supported (RepRap, Makerbot, Mach3 etc.)
* multiple G-code flavors supported (RepRap, Makerbot, Mach3, Machinekit etc.)
* ability to plate **multiple objects having distinct print settings**
* **multithread** processing
* **STL auto-repair** (tolerance for broken models)
@@ -52,25 +55,26 @@ Other major features are:
### How to install?
You can just download a precompiled package from [slic3r.org](http://slic3r.org/);
You can download a precompiled package from [slic3r.org](http://slic3r.org/);
it will run without the need for any dependency.
If you want to compile the source yourself just do the following (checkout
[slic3r.org](http://slic3r.org/download) for more details):
```
$ git clone https://github.com/alexrj/Slic3r.git
$ cd Slic3r
$ sudo perl Build.PL
$ sudo perl Build.PL --gui
$ ./slic3r.pl
```
If you want to compile the source yourself follow the instructions on one of these wiki pages:
* [Linux](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-GNU-Linux)
* [Windows](https://github.com/prusa3d/Slic3r/wiki/How-to-compile-Slic3r-Prusa-Edition-on-MS-Windows)
* [Mac OSX](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-OS-X)
### Can I help?
Sure! Drop me a line at aar@cpan.org. You can also
find me in #reprap and in #slic3r on FreeNode with the nickname _Sound_.
Before sending patches and pull requests contact me to discuss your proposed
Sure! You can do the following to find things that are available to help with:
* [Pull Request Milestone](https://github.com/alexrj/Slic3r/milestone/31)
* Please comment in the related github issue that you are working on it so that other people know.
* Items in the [TODO](https://github.com/alexrj/Slic3r/wiki/TODO) wiki page.
* Please comment in the related github issue that you are working on it so that other people know.
* Drop me a line at aar@cpan.org.
* You can also find me (rarely) in #reprap and in #slic3r on [FreeNode](https://webchat.freenode.net) with the nickname _Sound_. Another contributor, _LoH_, is also in both channels.
* Add an [issue](https://github.com/alexrj/Slic3r/issues) to the github tracker if it isn't already present.
Before sending patches and pull requests contact me (preferably through opening a github issue or commenting on an existing, related, issue) to discuss your proposed
changes: this way we'll ensure nobody wastes their time and no conflicts arise
in development.
@@ -109,8 +113,11 @@ The author of the Silk icon set is Mark James.
-j, --threads <num> Number of threads to use (1+, default: 2)
GUI options:
--gui Forces the GUI launch instead of command line slicing (if you
supply a model file, it will be loaded into the plater)
--no-plater Disable the plater tab
--gui-mode Overrides the configured mode (simple/expert)
--no-gui Forces the command line slicing instead of gui.
This takes precedence over --gui if both are present.
--autosave <file> Automatically export current configuration to the specified file
Output options:
@@ -130,17 +137,12 @@ The author of the Silk icon set is Mark James.
(default: 100,100)
--z-offset Additional height in mm to add to vertical coordinates
(+/-, default: 0)
--gcode-flavor The type of G-code to generate (reprap/teacup/makerware/sailfish/mach3/no-extrusion,
--gcode-flavor The type of G-code to generate (reprap/teacup/repetier/makerware/sailfish/mach3/machinekit/smoothie/no-extrusion,
default: reprap)
--use-relative-e-distances Enable this to get relative E values (default: no)
--use-firmware-retraction Enable firmware-controlled retraction using G10/G11 (default: no)
--gcode-arcs Use G2/G3 commands for native arcs (experimental, not supported
by all firmwares)
--g0 Use G0 commands for retraction (experimental, not supported by all
firmwares)
--use-volumetric-e Express E in cubic millimeters and prepend M200 (default: no)
--gcode-comments Make G-code verbose by adding comments (default: no)
--vibration-limit Limit the frequency of moves on X and Y axes (Hz, set zero to disable;
default: 0)
Filament options:
--filament-diameter Diameter in mm of your raw filament (default: 3)
@@ -194,7 +196,7 @@ The author of the Silk icon set is Mark James.
to disable; default: 0)
--default-acceleration
Acceleration will be reset to this value after the specific settings above
have been applied. (mm/s^2, set zero to disable; default: 130)
have been applied. (mm/s^2, set zero to disable; default: 0)
Accuracy options:
--layer-height Layer height in mm (default: 0.3)
@@ -218,7 +220,8 @@ The author of the Silk icon set is Mark James.
--end-gcode Load final G-code from the supplied file. This will overwrite
the default commands (turn off temperature [M104 S0],
home X axis [G28 X], disable motors [M84]).
--layer-gcode Load layer-change G-code from the supplied file (default: nothing).
--before-layer-gcode Load before-layer-change G-code from the supplied file (default: nothing).
--layer-gcode Load after-layer-change G-code from the supplied file (default: nothing).
--toolchange-gcode Load tool-change G-code from the supplied file (default: nothing).
--seam-position Position of loop starting points (random/nearest/aligned, default: aligned).
--external-perimeters-first Reverse perimeter order. (default: no)
@@ -252,6 +255,9 @@ The author of the Silk icon set is Mark James.
Spacing between pattern lines (mm, default: 2.5)
--support-material-angle
Support material angle in degrees (range: 0-90, default: 0)
--support-material-contact-distance
Vertical distance between object and support material
(0+, default: 0.2)
--support-material-interface-layers
Number of perpendicular layers between support material and object (0+, default: 3)
--support-material-interface-spacing
@@ -272,14 +278,16 @@ The author of the Silk icon set is Mark James.
--retract-before-travel
Only retract before travel moves of this length in mm (default: 2)
--retract-lift Lift Z by the given distance in mm when retracting (default: 0)
--retract-lift-above Only lift Z when above the specified height (default: 0)
--retract-lift-below Only lift Z when below the specified height (default: 0)
--retract-layer-change
Enforce a retraction before each Z move (default: yes)
Enforce a retraction before each Z move (default: no)
--wipe Wipe the nozzle while doing a retraction (default: no)
Retraction options for multi-extruder setups:
--retract-length-toolchange
Length of retraction in mm when disabling tool (default: 1)
--retract-restart-extra-toolchnage
Length of retraction in mm when disabling tool (default: 10)
--retract-restart-extra-toolchange
Additional amount of filament in mm to push after
switching tool (default: 0)
@@ -313,6 +321,9 @@ The author of the Silk icon set is Mark James.
--duplicate Number of items with auto-arrange (1+, default: 1)
--duplicate-grid Number of items with grid arrangement (default: 1,1)
--duplicate-distance Distance in mm between copies (default: 6)
--dont-arrange Don't arrange the objects on the build plate. The model coordinates
define the absolute positions on the build plate.
The option --print-center will be ignored.
--xy-size-compensation
Grow/shrink objects by the configured absolute distance (mm, default: 0)
@@ -345,16 +356,18 @@ The author of the Silk icon set is Mark James.
Set a different extrusion width for top infill
--support-material-extrusion-width
Set a different extrusion width for support material
--infill-overlap Overlap between infill and perimeters (default: 15%)
--bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: 1)
Multiple extruder options:
--extruder-offset Offset of each extruder, if firmware doesn't handle the displacement
(can be specified multiple times, default: 0x0)
--perimeter-extruder
Extruder to use for perimeters (1+, default: 1)
Extruder to use for perimeters and brim (1+, default: 1)
--infill-extruder Extruder to use for infill (1+, default: 1)
--solid-infill-extruder Extruder to use for solid infill (1+, default: 1)
--support-material-extruder
Extruder to use for support material (1+, default: 1)
Extruder to use for support material, raft and skirt (1+, default: 1)
--support-material-interface-extruder
Extruder to use for support material interface (1+, default: 1)
--ooze-prevention Drop temperature and park extruders outside a full skirt for automatic wiping
@@ -372,4 +385,4 @@ If you want to change a preset file, just do
If you want to slice a file overriding an option contained in your preset file:
slic3r.pl --load config.ini --layer-height 0.25 file.stl
slic3r.pl --load config.ini --layer-height 0.25 file.stl

View File

@@ -0,0 +1,106 @@
# Find the wxWidgets module based on the information provided by the Perl Alien::wxWidgets module.
# Check for the Perl & PerlLib modules
include(LibFindMacros)
libfind_package(AlienWx Perl)
libfind_package(AlienWx PerlLibs)
if (AlienWx_DEBUG)
message(STATUS " AlienWx_FIND_COMPONENTS=${AlienWx_FIND_COMPONENTS}")
endif()
# Execute an Alien::Wx module to find the relevant information regarding
# the wxWidgets used by the Perl interpreter.
# Perl specific stuff
set(AlienWx_TEMP_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/AlienWx_TEMP_INCLUDE.txt)
execute_process(
COMMAND ${PERL_EXECUTABLE} -e "
# Import Perl modules.
use strict;
use warnings;
use Text::ParseWords;
BEGIN {
# CMake sets the environment variables CC and CXX to the detected C compiler.
# There is an issue with the Perl ExtUtils::CBuilder, which does not handle whitespaces
# in the paths correctly on Windows, so we rather drop the CMake auto-detected paths.
delete \$ENV{CC};
delete \$ENV{CXX};
}
use Alien::wxWidgets;
use ExtUtils::CppGuess;
# Test for a Visual Studio compiler
my \$cpp_guess = ExtUtils::CppGuess->new;
my \$mswin = \$^O eq 'MSWin32';
my \$msvc = \$cpp_guess->is_msvc;
# List of wxWidgets components to be used.
my @components = split /;/, '${AlienWx_FIND_COMPONENTS}';
# Query the available data from Alien::wxWidgets.
my \$version = Alien::wxWidgets->version;
my \$config = Alien::wxWidgets->config;
my \$compiler = Alien::wxWidgets->compiler;
my \$linker = Alien::wxWidgets->linker;
my \$include_path = ' ' . Alien::wxWidgets->include_path;
my \$defines = ' ' . Alien::wxWidgets->defines;
my \$cflags = Alien::wxWidgets->c_flags;
my \$linkflags = Alien::wxWidgets->link_flags;
my \$libraries = ' ' . Alien::wxWidgets->libraries(@components);
#my @libraries = Alien::wxWidgets->link_libraries(@components);
#my @implib = Alien::wxWidgets->import_libraries(@components);
#my @shrlib = Alien::wxWidgets->shared_libraries(@components);
#my @keys = Alien::wxWidgets->library_keys; # 'gl', 'adv', ...
#my \$library_path = Alien::wxWidgets->shared_library_path;
#my \$key = Alien::wxWidgets->key;
#my \$prefix = Alien::wxWidgets->prefix;
my \$filename = '${AlienWx_TEMP_INCLUDE}';
open(my $fh, '>', \$filename) or die \"Could not open file '\$filename' \$!\";
# Convert a space separated lists to CMake semicolon separated lists,
# escape the backslashes,
# export the resulting list to a temp file.
sub cmake_set_var {
my (\$varname, \$content) = @_;
# Remove line separators.
\$content =~ s/\\r|\\n//g;
# Escape the path separators.
\$content =~ s/\\\\/\\\\\\\\\\\\\\\\/g;
my @words = shellwords(\$content);
print \$fh \"set(AlienWx_\$varname \\\"\" . join(';', @words) . \"\\\")\\n\";
}
cmake_set_var('VERSION', \$version);
\$include_path =~ s/ -I/ /g;
cmake_set_var('INCLUDE_DIRS', \$include_path);
\$libraries =~ s/ -L/ -LIBPATH:/g if \$msvc;
cmake_set_var('LIBRARIES', \$libraries);
#cmake_set_var('LIBRARY_DIRS', );
#\$defines =~ s/ -D/ /g;
cmake_set_var('DEFINITIONS', \$defines);
#cmake_set_var('DEFINITIONS_DEBUG', );
cmake_set_var('CXX_FLAGS', \$cflags);
close \$fh;
")
include(${AlienWx_TEMP_INCLUDE})
file(REMOVE ${AlienWx_TEMP_INCLUDE})
unset(AlienWx_TEMP_INCLUDE)
if (AlienWx_DEBUG)
message(STATUS " AlienWx_VERSION = ${AlienWx_VERSION}")
message(STATUS " AlienWx_INCLUDE_DIRS = ${AlienWx_INCLUDE_DIRS}")
message(STATUS " AlienWx_LIBRARIES = ${AlienWx_LIBRARIES}")
message(STATUS " AlienWx_LIBRARY_DIRS = ${AlienWx_LIBRARY_DIRS}")
message(STATUS " AlienWx_DEFINITIONS = ${AlienWx_DEFINITIONS}")
message(STATUS " AlienWx_DEFINITIONS_DEBUG = ${AlienWx_DEFINITIONS_DEBUG}")
message(STATUS " AlienWx_CXX_FLAGS = ${AlienWx_CXX_FLAGS}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(AlienWx
REQUIRED_VARS AlienWx_INCLUDE_DIRS AlienWx_LIBRARIES
# HANDLE_COMPONENTS
VERSION_VAR AlienWx_VERSION)

View File

@@ -0,0 +1,59 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindCURL
# --------
#
# Find curl
#
# Find the native CURL headers and libraries.
#
# ::
#
# CURL_INCLUDE_DIRS - where to find curl/curl.h, etc.
# CURL_LIBRARIES - List of libraries when using curl.
# CURL_FOUND - True if curl found.
# CURL_VERSION_STRING - the version of curl found (since CMake 2.8.8)
# Look for the header file.
find_path(CURL_INCLUDE_DIR NAMES curl/curl.h)
mark_as_advanced(CURL_INCLUDE_DIR)
# Look for the library (sorted from most current/relevant entry to least).
find_library(CURL_LIBRARY NAMES
curl
# Windows MSVC Makefile:
libcurl_a
# Windows MSVC prebuilts:
curllib
libcurl_imp
curllib_static
# Windows older "Win32 - MSVC" prebuilts (libcurl.lib, e.g. libcurl-7.15.5-win32-msvc.zip):
libcurl
)
mark_as_advanced(CURL_LIBRARY)
if(CURL_INCLUDE_DIR)
foreach(_curl_version_header curlver.h curl.h)
if(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}")
file(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"")
string(REGEX REPLACE "^#define[\t ]+LIBCURL_VERSION[\t ]+\"([^\"]*)\".*" "\\1" CURL_VERSION_STRING "${curl_version_str}")
unset(curl_version_str)
break()
endif()
endforeach()
endif()
find_package_handle_standard_args(CURL
REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
VERSION_VAR CURL_VERSION_STRING)
if(CURL_FOUND)
set(CURL_LIBRARIES ${CURL_LIBRARY})
set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
message(STATUS " Curl libraries: = ${CURL_LIBRARIES}")
message(STATUS " Curl include dirs: = ${CURL_INCLUDE_DIRS}")
endif()

View File

@@ -0,0 +1,86 @@
# - Try to find Eigen3 lib
#
# This module supports requiring a minimum version, e.g. you can do
# find_package(Eigen3 3.1.2)
# to require version 3.1.2 or newer of Eigen3.
#
# Once done this will define
#
# EIGEN3_FOUND - system has eigen lib with correct version
# EIGEN3_INCLUDE_DIR - the eigen include directory
# EIGEN3_VERSION - eigen version
# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>
# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
# Redistribution and use is allowed according to the terms of the 2-clause BSD license.
if(NOT Eigen3_FIND_VERSION)
if(NOT Eigen3_FIND_VERSION_MAJOR)
set(Eigen3_FIND_VERSION_MAJOR 2)
endif(NOT Eigen3_FIND_VERSION_MAJOR)
if(NOT Eigen3_FIND_VERSION_MINOR)
set(Eigen3_FIND_VERSION_MINOR 91)
endif(NOT Eigen3_FIND_VERSION_MINOR)
if(NOT Eigen3_FIND_VERSION_PATCH)
set(Eigen3_FIND_VERSION_PATCH 0)
endif(NOT Eigen3_FIND_VERSION_PATCH)
set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
endif(NOT Eigen3_FIND_VERSION)
macro(_eigen3_check_version)
file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
set(EIGEN3_VERSION_OK FALSE)
else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
set(EIGEN3_VERSION_OK TRUE)
endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
if(NOT EIGEN3_VERSION_OK)
message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
"but at least version ${Eigen3_FIND_VERSION} is required")
endif(NOT EIGEN3_VERSION_OK)
endmacro(_eigen3_check_version)
if (EIGEN3_INCLUDE_DIR)
# in cache already
_eigen3_check_version()
set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
else (EIGEN3_INCLUDE_DIR)
# specific additional paths for some OS
if (WIN32)
set(EIGEN_ADDITIONAL_SEARCH_PATHS ${EIGEN_ADDITIONAL_SEARCH_PATHS} "C:/Program Files/Eigen/include" "C:/Program Files (x86)/Eigen/include")
endif(WIN32)
find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
PATHS
${CMAKE_INSTALL_PREFIX}/include
${EIGEN_ADDITIONAL_SEARCH_PATHS}
${KDE4_INCLUDE_DIR}
PATH_SUFFIXES eigen3 eigen
)
if(EIGEN3_INCLUDE_DIR)
_eigen3_check_version()
endif(EIGEN3_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
mark_as_advanced(EIGEN3_INCLUDE_DIR)
endif(EIGEN3_INCLUDE_DIR)

View File

@@ -0,0 +1,88 @@
# Find the dependencies for linking with the Perl runtime library.
# Check for the Perl & PerlLib modules
include(LibFindMacros)
libfind_package(PerlEmbed Perl)
libfind_package(PerlEmbed PerlLibs)
# Execute an Alien::Wx module to find the relevant information regarding
# the wxWidgets used by the Perl interpreter.
# Perl specific stuff
set(PerlEmbed_TEMP_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/PerlEmbed_TEMP_INCLUDE.txt)
execute_process(
COMMAND ${PERL_EXECUTABLE} -MExtUtils::Embed -e "
# Import Perl modules.
use strict;
use warnings;
use Config;
use Text::ParseWords;
use ExtUtils::CppGuess;
# Test for a Visual Studio compiler
my \$cpp_guess = ExtUtils::CppGuess->new;
my \$mswin = \$^O eq 'MSWin32';
my \$msvc = \$cpp_guess->is_msvc;
# Query the available data from Alien::wxWidgets.
my \$ccflags;
my \$ldflags;
{ local *STDOUT; open STDOUT, '>', \\\$ccflags; ccflags; }
{ local *STDOUT; open STDOUT, '>', \\\$ldflags; ldopts; }
\$ccflags = ' ' . \$ccflags;
\$ldflags = ' ' . \$ldflags;
my \$filename = '${PerlEmbed_TEMP_INCLUDE}';
open(my $fh, '>', \$filename) or die \"Could not open file '\$filename' \$!\";
# Convert a space separated lists to CMake semicolon separated lists,
# escape the backslashes,
# export the resulting list to a temp file.
sub cmake_set_var {
my (\$varname, \$content) = @_;
# Remove line separators.
\$content =~ s/\\r|\\n//g;
# Escape the path separators.
\$content =~ s/\\\\/\\\\\\\\\\\\\\\\/g;
my @words = shellwords(\$content);
print \$fh \"set(PerlEmbed_\$varname \\\"\" . join(';', @words) . \"\\\")\\n\";
}
cmake_set_var('ARCHNAME', \$Config{archname});
cmake_set_var('CCFLAGS', \$ccflags);
\$ldflags =~ s/ -L/ -LIBPATH:/g if \$msvc;
cmake_set_var('LD', \$Config{ld});
cmake_set_var('LDFLAGS', \$ldflags);
cmake_set_var('CCCDLFLAGS', \$Config{cccdlflags});
cmake_set_var('LDDLFLAGS', \$Config{lddlflags});
cmake_set_var('DLEXT', \$Config{dlext});
close \$fh;
")
include(${PerlEmbed_TEMP_INCLUDE})
file(REMOVE ${PerlEmbed_TEMP_INCLUDE})
unset(PerlEmbed_TEMP_INCLUDE)
if (PerlEmbed_DEBUG)
# First show the configuration extracted by FindPerl & FindPerlLibs:
message(STATUS " PERL_INCLUDE_PATH = ${PERL_INCLUDE_PATH}")
message(STATUS " PERL_LIBRARY = ${PERL_LIBRARY}")
message(STATUS " PERL_EXECUTABLE = ${PERL_EXECUTABLE}")
message(STATUS " PERL_SITESEARCH = ${PERL_SITESEARCH}")
message(STATUS " PERL_SITELIB = ${PERL_SITELIB}")
message(STATUS " PERL_VENDORARCH = ${PERL_VENDORARCH}")
message(STATUS " PERL_VENDORLIB = ${PERL_VENDORLIB}")
message(STATUS " PERL_ARCHLIB = ${PERL_ARCHLIB}")
message(STATUS " PERL_PRIVLIB = ${PERL_PRIVLIB}")
message(STATUS " PERL_EXTRA_C_FLAGS = ${PERL_EXTRA_C_FLAGS}")
# Second show the configuration extracted by this module (FindPerlEmbed):
message(STATUS " PerlEmbed_ARCHNAME = ${PerlEmbed_ARCHNAME}")
message(STATUS " PerlEmbed_CCFLAGS = ${PerlEmbed_CCFLAGS}")
message(STATUS " PerlEmbed_CCCDLFLAGS = ${PerlEmbed_CCCDLFLAGS}")
message(STATUS " LD = ${PerlEmbed_LD}")
message(STATUS " PerlEmbed_LDFLAGS = ${PerlEmbed_LDFLAGS}")
message(STATUS " PerlEmbed_LDDLFLAGS = ${PerlEmbed_LDDLFLAGS}")
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PerlEmbed
REQUIRED_VARS PerlEmbed_CCFLAGS PerlEmbed_LDFLAGS
VERSION_VAR PERL_VERSION)

322
cmake/modules/FindTBB.cmake Normal file
View File

@@ -0,0 +1,322 @@
# The MIT License (MIT)
#
# Copyright (c) 2015 Justus Calvin
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# FindTBB
# -------
#
# Find TBB include directories and libraries.
#
# Usage:
#
# find_package(TBB [major[.minor]] [EXACT]
# [QUIET] [REQUIRED]
# [[COMPONENTS] [components...]]
# [OPTIONAL_COMPONENTS components...])
#
# where the allowed components are tbbmalloc and tbb_preview. Users may modify
# the behavior of this module with the following variables:
#
# * TBB_ROOT_DIR - The base directory the of TBB installation.
# * TBB_INCLUDE_DIR - The directory that contains the TBB headers files.
# * TBB_LIBRARY - The directory that contains the TBB library files.
# * TBB_<library>_LIBRARY - The path of the TBB the corresponding TBB library.
# These libraries, if specified, override the
# corresponding library search results, where <library>
# may be tbb, tbb_debug, tbbmalloc, tbbmalloc_debug,
# tbb_preview, or tbb_preview_debug.
# * TBB_USE_DEBUG_BUILD - The debug version of tbb libraries, if present, will
# be used instead of the release version.
# * TBB_STATIC - Static linking of libraries with a _static suffix.
# For example, on Windows a tbb_static.lib will be searched for
# instead of tbb.lib.
#
# Users may modify the behavior of this module with the following environment
# variables:
#
# * TBB_INSTALL_DIR
# * TBBROOT
# * LIBRARY_PATH
#
# This module will set the following variables:
#
# * TBB_FOUND - Set to false, or undefined, if we havent found, or
# dont want to use TBB.
# * TBB_<component>_FOUND - If False, optional <component> part of TBB sytem is
# not available.
# * TBB_VERSION - The full version string
# * TBB_VERSION_MAJOR - The major version
# * TBB_VERSION_MINOR - The minor version
# * TBB_INTERFACE_VERSION - The interface version number defined in
# tbb/tbb_stddef.h.
# * TBB_<library>_LIBRARY_RELEASE - The path of the TBB release version of
# <library>, where <library> may be tbb, tbb_debug,
# tbbmalloc, tbbmalloc_debug, tbb_preview, or
# tbb_preview_debug.
# * TBB_<library>_LIBRARY_DEGUG - The path of the TBB release version of
# <library>, where <library> may be tbb, tbb_debug,
# tbbmalloc, tbbmalloc_debug, tbb_preview, or
# tbb_preview_debug.
#
# The following varibles should be used to build and link with TBB:
#
# * TBB_INCLUDE_DIRS - The include directory for TBB.
# * TBB_LIBRARIES - The libraries to link against to use TBB.
# * TBB_LIBRARIES_RELEASE - The release libraries to link against to use TBB.
# * TBB_LIBRARIES_DEBUG - The debug libraries to link against to use TBB.
# * TBB_DEFINITIONS - Definitions to use when compiling code that uses
# TBB.
# * TBB_DEFINITIONS_RELEASE - Definitions to use when compiling release code that
# uses TBB.
# * TBB_DEFINITIONS_DEBUG - Definitions to use when compiling debug code that
# uses TBB.
#
# This module will also create the "tbb" target that may be used when building
# executables and libraries.
include(FindPackageHandleStandardArgs)
if(NOT TBB_FOUND)
##################################
# Check the build type
##################################
if(NOT DEFINED TBB_USE_DEBUG_BUILD)
if(CMAKE_BUILD_TYPE MATCHES "(Debug|DEBUG|debug)")
set(TBB_BUILD_TYPE DEBUG)
else()
set(TBB_BUILD_TYPE RELEASE)
endif()
elseif(TBB_USE_DEBUG_BUILD)
set(TBB_BUILD_TYPE DEBUG)
else()
set(TBB_BUILD_TYPE RELEASE)
endif()
##################################
# Set the TBB search directories
##################################
# Define search paths based on user input and environment variables
set(TBB_SEARCH_DIR ${TBB_ROOT_DIR} $ENV{TBB_INSTALL_DIR} $ENV{TBBROOT})
# Define the search directories based on the current platform
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(TBB_DEFAULT_SEARCH_DIR "C:/Program Files/Intel/TBB"
"C:/Program Files (x86)/Intel/TBB")
# Set the target architecture
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(TBB_ARCHITECTURE "intel64")
else()
set(TBB_ARCHITECTURE "ia32")
endif()
# Set the TBB search library path search suffix based on the version of VC
if(WINDOWS_STORE)
set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11_ui")
elseif(MSVC14)
set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc14")
elseif(MSVC12)
set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc12")
elseif(MSVC11)
set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11")
elseif(MSVC10)
set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc10")
endif()
# Add the library path search suffix for the VC independent version of TBB
list(APPEND TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc_mt")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# OS X
set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb")
# TODO: Check to see which C++ library is being used by the compiler.
if(NOT ${CMAKE_SYSTEM_VERSION} VERSION_LESS 13.0)
# The default C++ library on OS X 10.9 and later is libc++
set(TBB_LIB_PATH_SUFFIX "lib/libc++" "lib")
else()
set(TBB_LIB_PATH_SUFFIX "lib")
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Linux
set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb")
# TODO: Check compiler version to see the suffix should be <arch>/gcc4.1 or
# <arch>/gcc4.1. For now, assume that the compiler is more recent than
# gcc 4.4.x or later.
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(TBB_LIB_PATH_SUFFIX "lib/intel64/gcc4.4")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
set(TBB_LIB_PATH_SUFFIX "lib/ia32/gcc4.4")
endif()
endif()
##################################
# Find the TBB include dir
##################################
find_path(TBB_INCLUDE_DIRS tbb/tbb.h
HINTS ${TBB_INCLUDE_DIR} ${TBB_SEARCH_DIR}
PATHS ${TBB_DEFAULT_SEARCH_DIR}
PATH_SUFFIXES include)
##################################
# Set version strings
##################################
if(TBB_INCLUDE_DIRS)
file(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _tbb_version_file)
string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"
TBB_VERSION_MAJOR "${_tbb_version_file}")
string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1"
TBB_VERSION_MINOR "${_tbb_version_file}")
string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1"
TBB_INTERFACE_VERSION "${_tbb_version_file}")
set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}")
endif()
##################################
# Find TBB components
##################################
if(TBB_VERSION VERSION_LESS 4.3)
set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc tbb)
else()
set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc_proxy tbbmalloc tbb)
endif()
if(TBB_STATIC)
set(TBB_STATIC_SUFFIX "_static")
endif()
# Find each component
foreach(_comp ${TBB_SEARCH_COMPOMPONENTS})
if(";${TBB_FIND_COMPONENTS};tbb;" MATCHES ";${_comp};")
# Search for the libraries
find_library(TBB_${_comp}_LIBRARY_RELEASE ${_comp}${TBB_STATIC_SUFFIX}
HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR}
PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH
PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX})
find_library(TBB_${_comp}_LIBRARY_DEBUG ${_comp}${TBB_STATIC_SUFFIX}_debug
HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR}
PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH
PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX})
if(TBB_${_comp}_LIBRARY_DEBUG)
list(APPEND TBB_LIBRARIES_DEBUG "${TBB_${_comp}_LIBRARY_DEBUG}")
endif()
if(TBB_${_comp}_LIBRARY_RELEASE)
list(APPEND TBB_LIBRARIES_RELEASE "${TBB_${_comp}_LIBRARY_RELEASE}")
endif()
if(TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE} AND NOT TBB_${_comp}_LIBRARY)
set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE}}")
endif()
if(TBB_${_comp}_LIBRARY AND EXISTS "${TBB_${_comp}_LIBRARY}")
set(TBB_${_comp}_FOUND TRUE)
else()
set(TBB_${_comp}_FOUND FALSE)
endif()
# Mark internal variables as advanced
mark_as_advanced(TBB_${_comp}_LIBRARY_RELEASE)
mark_as_advanced(TBB_${_comp}_LIBRARY_DEBUG)
mark_as_advanced(TBB_${_comp}_LIBRARY)
endif()
endforeach()
unset(TBB_STATIC_SUFFIX)
##################################
# Set compile flags and libraries
##################################
set(TBB_DEFINITIONS_RELEASE "")
set(TBB_DEFINITIONS_DEBUG "-DTBB_USE_DEBUG=1")
if(TBB_LIBRARIES_${TBB_BUILD_TYPE})
set(TBB_DEFINITIONS "${TBB_DEFINITIONS_${TBB_BUILD_TYPE}}")
set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}")
elseif(TBB_LIBRARIES_RELEASE)
set(TBB_DEFINITIONS "${TBB_DEFINITIONS_RELEASE}")
set(TBB_LIBRARIES "${TBB_LIBRARIES_RELEASE}")
elseif(TBB_LIBRARIES_DEBUG)
set(TBB_DEFINITIONS "${TBB_DEFINITIONS_DEBUG}")
set(TBB_LIBRARIES "${TBB_LIBRARIES_DEBUG}")
endif()
find_package_handle_standard_args(TBB
REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES
HANDLE_COMPONENTS
VERSION_VAR TBB_VERSION)
##################################
# Create targets
##################################
if(NOT CMAKE_VERSION VERSION_LESS 3.0 AND TBB_FOUND)
add_library(tbb SHARED IMPORTED)
set_target_properties(tbb PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS}
IMPORTED_LOCATION ${TBB_LIBRARIES})
if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG)
set_target_properties(tbb PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:TBB_USE_DEBUG=1>"
IMPORTED_LOCATION_DEBUG ${TBB_LIBRARIES_DEBUG}
IMPORTED_LOCATION_RELWITHDEBINFO ${TBB_LIBRARIES_DEBUG}
IMPORTED_LOCATION_RELEASE ${TBB_LIBRARIES_RELEASE}
IMPORTED_LOCATION_MINSIZEREL ${TBB_LIBRARIES_RELEASE}
)
elseif(TBB_LIBRARIES_RELEASE)
set_target_properties(tbb PROPERTIES IMPORTED_LOCATION ${TBB_LIBRARIES_RELEASE})
else()
set_target_properties(tbb PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS_DEBUG}"
IMPORTED_LOCATION ${TBB_LIBRARIES_DEBUG}
)
endif()
endif()
mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARIES)
unset(TBB_ARCHITECTURE)
unset(TBB_BUILD_TYPE)
unset(TBB_LIB_PATH_SUFFIX)
unset(TBB_DEFAULT_SEARCH_DIR)
if(TBB_DEBUG)
message(STATUS " TBB_INCLUDE_DIRS = ${TBB_INCLUDE_DIRS}")
message(STATUS " TBB_DEFINITIONS = ${TBB_DEFINITIONS}")
message(STATUS " TBB_LIBRARIES = ${TBB_LIBRARIES}")
message(STATUS " TBB_DEFINITIONS_DEBUG = ${TBB_DEFINITIONS_DEBUG}")
message(STATUS " TBB_LIBRARIES_DEBUG = ${TBB_LIBRARIES_DEBUG}")
message(STATUS " TBB_DEFINITIONS_RELEASE = ${TBB_DEFINITIONS_RELEASE}")
message(STATUS " TBB_LIBRARIES_RELEASE = ${TBB_LIBRARIES_RELEASE}")
endif()
endif()

View File

@@ -0,0 +1,265 @@
# Version 2.2
# Public Domain, originally written by Lasse Kärkkäinen <tronic>
# Maintained at https://github.com/Tronic/cmake-modules
# Please send your improvements as pull requests on Github.
# Find another package and make it a dependency of the current package.
# This also automatically forwards the "REQUIRED" argument.
# Usage: libfind_package(<prefix> <another package> [extra args to find_package])
macro (libfind_package PREFIX PKG)
set(${PREFIX}_args ${PKG} ${ARGN})
if (${PREFIX}_FIND_REQUIRED)
set(${PREFIX}_args ${${PREFIX}_args} REQUIRED)
endif()
find_package(${${PREFIX}_args})
set(${PREFIX}_DEPENDENCIES ${${PREFIX}_DEPENDENCIES};${PKG})
unset(${PREFIX}_args)
endmacro()
# A simple wrapper to make pkg-config searches a bit easier.
# Works the same as CMake's internal pkg_check_modules but is always quiet.
macro (libfind_pkg_check_modules)
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_check_modules(${ARGN} QUIET)
endif()
endmacro()
# Avoid useless copy&pasta by doing what most simple libraries do anyway:
# pkg-config, find headers, find library.
# Usage: libfind_pkg_detect(<prefix> <pkg-config args> FIND_PATH <name> [other args] FIND_LIBRARY <name> [other args])
# E.g. libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2)
function (libfind_pkg_detect PREFIX)
# Parse arguments
set(argname pkgargs)
foreach (i ${ARGN})
if ("${i}" STREQUAL "FIND_PATH")
set(argname pathargs)
elseif ("${i}" STREQUAL "FIND_LIBRARY")
set(argname libraryargs)
else()
set(${argname} ${${argname}} ${i})
endif()
endforeach()
if (NOT pkgargs)
message(FATAL_ERROR "libfind_pkg_detect requires at least a pkg_config package name to be passed.")
endif()
# Find library
libfind_pkg_check_modules(${PREFIX}_PKGCONF ${pkgargs})
if (pathargs)
find_path(${PREFIX}_INCLUDE_DIR NAMES ${pathargs} HINTS ${${PREFIX}_PKGCONF_INCLUDE_DIRS})
endif()
if (libraryargs)
find_library(${PREFIX}_LIBRARY NAMES ${libraryargs} HINTS ${${PREFIX}_PKGCONF_LIBRARY_DIRS})
endif()
endfunction()
# Extracts a version #define from a version.h file, output stored to <PREFIX>_VERSION.
# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR)
# Fourth argument "QUIET" may be used for silently testing different define names.
# This function does nothing if the version variable is already defined.
function (libfind_version_header PREFIX VERSION_H DEFINE_NAME)
# Skip processing if we already have a version or if the include dir was not found
if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR)
return()
endif()
set(quiet ${${PREFIX}_FIND_QUIETLY})
# Process optional arguments
foreach(arg ${ARGN})
if (arg STREQUAL "QUIET")
set(quiet TRUE)
else()
message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.")
endif()
endforeach()
# Read the header and parse for version number
set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
if (NOT EXISTS ${filename})
if (NOT quiet)
message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
endif()
return()
endif()
file(READ "${filename}" header)
string(REGEX REPLACE ".*#[ \t]*define[ \t]*${DEFINE_NAME}[ \t]*\"([^\n]*)\".*" "\\1" match "${header}")
# No regex match?
if (match STREQUAL header)
if (NOT quiet)
message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"<version>\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
endif()
return()
endif()
# Export the version string
set(${PREFIX}_VERSION "${match}" PARENT_SCOPE)
endfunction()
# Do the final processing once the paths have been detected.
# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
# all the variables, each of which contain one include directory.
# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
# Also handles errors in case library detection was required, etc.
function (libfind_process PREFIX)
# Skip processing if already processed during this configuration run
if (${PREFIX}_FOUND)
return()
endif()
set(found TRUE) # Start with the assumption that the package was found
# Did we find any files? Did we miss includes? These are for formatting better error messages.
set(some_files FALSE)
set(missing_headers FALSE)
# Shorthands for some variables that we need often
set(quiet ${${PREFIX}_FIND_QUIETLY})
set(required ${${PREFIX}_FIND_REQUIRED})
set(exactver ${${PREFIX}_FIND_VERSION_EXACT})
set(findver "${${PREFIX}_FIND_VERSION}")
set(version "${${PREFIX}_VERSION}")
# Lists of config option names (all, includes, libs)
unset(configopts)
set(includeopts ${${PREFIX}_PROCESS_INCLUDES})
set(libraryopts ${${PREFIX}_PROCESS_LIBS})
# Process deps to add to
foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES})
if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS)
# The package seems to export option lists that we can use, woohoo!
list(APPEND includeopts ${${i}_INCLUDE_OPTS})
list(APPEND libraryopts ${${i}_LIBRARY_OPTS})
else()
# If plural forms don't exist or they equal singular forms
if ((NOT DEFINED ${i}_INCLUDE_DIRS AND NOT DEFINED ${i}_LIBRARIES) OR
({i}_INCLUDE_DIR STREQUAL ${i}_INCLUDE_DIRS AND ${i}_LIBRARY STREQUAL ${i}_LIBRARIES))
# Singular forms can be used
if (DEFINED ${i}_INCLUDE_DIR)
list(APPEND includeopts ${i}_INCLUDE_DIR)
endif()
if (DEFINED ${i}_LIBRARY)
list(APPEND libraryopts ${i}_LIBRARY)
endif()
else()
# Oh no, we don't know the option names
message(FATAL_ERROR "We couldn't determine config variable names for ${i} includes and libs. Aieeh!")
endif()
endif()
endforeach()
if (includeopts)
list(REMOVE_DUPLICATES includeopts)
endif()
if (libraryopts)
list(REMOVE_DUPLICATES libraryopts)
endif()
string(REGEX REPLACE ".*[ ;]([^ ;]*(_INCLUDE_DIRS|_LIBRARIES))" "\\1" tmp "${includeopts} ${libraryopts}")
if (NOT tmp STREQUAL "${includeopts} ${libraryopts}")
message(AUTHOR_WARNING "Plural form ${tmp} found in config options of ${PREFIX}. This works as before but is now deprecated. Please only use singular forms INCLUDE_DIR and LIBRARY, and update your find scripts for LibFindMacros > 2.0 automatic dependency system (most often you can simply remove the PROCESS variables entirely).")
endif()
# Include/library names separated by spaces (notice: not CMake lists)
unset(includes)
unset(libs)
# Process all includes and set found false if any are missing
foreach (i ${includeopts})
list(APPEND configopts ${i})
if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
list(APPEND includes "${${i}}")
else()
set(found FALSE)
set(missing_headers TRUE)
endif()
endforeach()
# Process all libraries and set found false if any are missing
foreach (i ${libraryopts})
list(APPEND configopts ${i})
if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
list(APPEND libs "${${i}}")
else()
set (found FALSE)
endif()
endforeach()
# Version checks
if (found AND findver)
if (NOT version)
message(WARNING "The find module for ${PREFIX} does not provide version information, so we'll just assume that it is OK. Please fix the module or remove package version requirements to get rid of this warning.")
elseif (version VERSION_LESS findver OR (exactver AND NOT version VERSION_EQUAL findver))
set(found FALSE)
set(version_unsuitable TRUE)
endif()
endif()
# If all-OK, hide all config options, export variables, print status and exit
if (found)
foreach (i ${configopts})
mark_as_advanced(${i})
endforeach()
if (NOT quiet)
message(STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
if (LIBFIND_DEBUG)
message(STATUS " ${PREFIX}_DEPENDENCIES=${${PREFIX}_DEPENDENCIES}")
message(STATUS " ${PREFIX}_INCLUDE_OPTS=${includeopts}")
message(STATUS " ${PREFIX}_INCLUDE_DIRS=${includes}")
message(STATUS " ${PREFIX}_LIBRARY_OPTS=${libraryopts}")
message(STATUS " ${PREFIX}_LIBRARIES=${libs}")
endif()
set (${PREFIX}_INCLUDE_OPTS ${includeopts} PARENT_SCOPE)
set (${PREFIX}_LIBRARY_OPTS ${libraryopts} PARENT_SCOPE)
set (${PREFIX}_INCLUDE_DIRS ${includes} PARENT_SCOPE)
set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE)
set (${PREFIX}_FOUND TRUE PARENT_SCOPE)
endif()
return()
endif()
# Format messages for debug info and the type of error
set(vars "Relevant CMake configuration variables:\n")
foreach (i ${configopts})
mark_as_advanced(CLEAR ${i})
set(val ${${i}})
if ("${val}" STREQUAL "${i}-NOTFOUND")
set (val "<not found>")
elseif (val AND NOT EXISTS ${val})
set (val "${val} (does not exist)")
else()
set(some_files TRUE)
endif()
set(vars "${vars} ${i}=${val}\n")
endforeach()
set(vars "${vars}You may use CMake GUI, cmake -D or ccmake to modify the values. Delete CMakeCache.txt to discard all values and force full re-detection if necessary.\n")
if (version_unsuitable)
set(msg "${PREFIX} ${${PREFIX}_VERSION} was found but")
if (exactver)
set(msg "${msg} only version ${findver} is acceptable.")
else()
set(msg "${msg} version ${findver} is the minimum requirement.")
endif()
else()
if (missing_headers)
set(msg "We could not find development headers for ${PREFIX}. Do you have the necessary dev package installed?")
elseif (some_files)
set(msg "We only found some files of ${PREFIX}, not all of them. Perhaps your installation is incomplete or maybe we just didn't look in the right place?")
if(findver)
set(msg "${msg} This could also be caused by incompatible version (if it helps, at least ${PREFIX} ${findver} should work).")
endif()
else()
set(msg "We were unable to find package ${PREFIX}.")
endif()
endif()
# Fatal error out if REQUIRED
if (required)
set(msg "REQUIRED PACKAGE NOT FOUND\n${msg} This package is REQUIRED and you need to install it or adjust CMake configuration in order to continue building ${CMAKE_PROJECT_NAME}.")
message(FATAL_ERROR "${msg}\n${vars}")
endif()
# Otherwise just print a nasty warning
if (NOT quiet)
message(WARNING "WARNING: MISSING PACKAGE\n${msg} This package is NOT REQUIRED and you may ignore this warning but by doing so you may miss some functionality of ${CMAKE_PROJECT_NAME}. \n${vars}")
endif()
endfunction()

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is autogenerated by CMake
Note: In the .in template file, the $ {}-style variables are interpreted by CMake while the $()-style variables belong to MSVC
-->
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<ExecutablePath>$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(FxCopDir);$(PATH);${PROPS_PERL_BIN_PATH}\;</ExecutablePath>
</PropertyGroup>
<ItemDefinitionGroup />
<ItemGroup />
<PropertyGroup>
<LocalDebuggerCommand>${PROPS_PERL_EXECUTABLE}</LocalDebuggerCommand>
<LocalDebuggerCommandArguments>slic3r.pl</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerWorkingDirectory>${PROPS_CMAKE_SOURCE_DIR}</LocalDebuggerWorkingDirectory>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,2 @@
# Building Slic3r PE on Linux/UNIX

View File

@@ -0,0 +1,93 @@
# Building Slic3r PE on Microsoft Windows
The currently supported way of building Slic3r PE on Windows is with CMake and MS Visual Studio 2013
using our Perl binary distribution (compiled from official Perl sources).
You can use the free [Visual Studio 2013 Community Edition](https://www.visualstudio.com/vs/older-downloads/).
CMake installer can be downloaded from [the official website](https://cmake.org/download/).
Other setups (such as mingw + Strawberry Perl) _may_ work, but we cannot guarantee this will work
and cannot provide guidance.
### Geting the dependencies
First, download and upnack our Perl + wxWidgets binary distribution:
- 32 bit, release mode: [wperl32-5.24.0-2018-03-02.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=wperl32-5.24.0-2018-03-02.7z)
- 64 bit, release mode: [wperl64-5.24.0-2018-03-02.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=wperl64-5.24.0-2018-03-02.7z)
- 64 bit, release mode + debug symbols: [wperl64d-5.24.0-2018-03-02.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=wperl64d-5.24.0-2018-03-02.7z)
It is recommended to unpack this package into `C:\`.
Apart from wxWidgets and Perl, you will also need additional dependencies:
- Boost
- Intel TBB
- libcurl
We have prepared a binary package of the listed libraries:
- 32 bit: [slic3r-destdir-32.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=2%2Fslic3r-destdir-32.7z)
- 64 bit: [slic3r-destdir-64.7z](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=2%2Fslic3r-destdir-64.7z)
It is recommended you unpack this package into `C:\local\` as the environment
setup script expects it there.
Alternatively you can also compile the additional dependencies yourself.
There is a [powershell script](./deps-build/windows/slic3r-makedeps.ps1) which automates this process.
### Building Slic3r PE
Once the dependencies are set up in their respective locations,
go to the `wperl*` directory extracted earlier and launch the `cmdline.lnk` file
which opens a command line prompt with appropriate environment variables set up.
In this command line, `cd` into the directory with Slic3r sources
and use these commands to build the Slic3r from the command line:
perl Build.PL
perl Build.PL --gui
mkdir build
cd build
cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
nmake
cd ..
perl slic3r.pl
The above commands use `nmake` Makefiles.
You may also build Slic3r PE with other build tools:
### Building with Visual Studio
To build and debug Slic3r PE with Visual Studio (64 bits), replace the `cmake` command with:
cmake .. -G "Visual Studio 12 Win64" -DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo
For the 32-bit variant, use:
cmake .. -G "Visual Studio 12" -DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo
After `cmake` has finished, go to the build directory and open the `Slic3r.sln` solution file.
This should open Visual Studio and load the Slic3r solution containing all the projects.
Make sure you use Visual Studio 2013 to open the solution.
You can then use the usual Visual Studio controls to build Slic3r (Hit `F5` to build and run with debugger).
If you want to run or debug Slic3r from within Visual Studio, make sure the `XS` project is activated.
It should be set as the Startup project by CMake by default, but you might want to check anyway.
There are multiple projects in the Slic3r solution, but only the `XS` project is configured with the right
commands to run and debug Slic3r.
The above cmake commands generate Visual Studio project files with the `RelWithDebInfo` configuration only.
If you also want to use the `Release` configuration, you can generate Visual Studio projects with:
-DCMAKE_CONFIGURATION_TYPES=Release;RelWithDebInfo
(The `Debug` configuration is not supported as of now.)
### Building with ninja
To use [Ninja](https://ninja-build.org/), replace the `cmake` and `nmake` commands with:
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release
ninja

316
doc/How_to_build_Slic3r.txt Normal file
View File

@@ -0,0 +1,316 @@
How to build Slic3r on Mac OS X 10.9 Maveric
---------------------------------------------
Vojtech Bubnik, 2017-12-12
1) Install Mac OS X 10.7 Lion 64 bit with X Code
------------------------------------------------
One has to build the OSX Slic3r on a real Mac, either directly on the system, or on a virtualized OSX. On Mac, two commercial solutions are available to legally virtualize MacOS on MacOS:
http://www.parallels.com/eu/products/desktop/
http://www.vmware.com/products/workstation/
Installation of a X Code on an OS X 10.7 Lion needs a bit of work. The latest X Code supported by the Lion on a Virtual Box is 4.21. The trouble is, the certificates of the X Code 4.21 installation package expired. One way to work around the certificate is to flatten the installation package by unpacking and repacking it:
pkgutil --expand Foobar.pkg foobar
pkgutil --flatten foobar barfoo.pkg
The flattened package is available here:
\\rs.prusa\Development\Slic3r-Prusa\installxcode_421_lion_fixed.pkg
This installer does not install the X Code directly. Instead, it installs another installer with a set of 47 pkg files. These files have their certificates expired as well. You will find the packages on your MacOS here:
/Applications/Install Xcode.app/Contents/Resources/Packages/
It is best to flatten them in a loop:
cd /Applications/Install\ Xcode.app/Contents/Resources/Packages/
for f in *.pkg; do
pkgutil --expand $f /tmp/$f
rm -f $f
pkgutil --flatten /tmp/$f $f
done
After that, you may finish the installation of Xcode by running
/Applications/Install\ Xcode.app
1b) Installing the Xcode on a newer system
-------------------------------------------
You will need to register as an Apple developer on
https://developer.apple.com/
log in and download and install Xcode
https://developer.apple.com/downloads/
You will likely need to download and install Xcode Command Line Tools, though the Xcode 4.1 came with the command line tools installed.
2) Prepare the development environment
--------------------------------------
Install the brew package manager:
http://brew.sh/
The brew package manager requires the git command line tool. Normally the git tool is installed as part of the Xcode command line tools.
Copy and execute a command line from the top of http://brew.sh/ . It is possible, that the invocation of git fails because of some parameters the old git does not recognize. If so, invoke the git call manually.
Compile the boost library using brew. Following line compiles a 64bit boost with both static and shared libraries.
brew install boost --universal
Install dylibbundler tool. The dylibbundler tool serves to collect dependent dynamic libraries and fix their linkage. Execute
brew install dylibbundler
Install cmake
brew install cmake
3) Install perl
---------------
We don't want to distribute perl pre-installed on the Mac OS box. First, the system perl installation is not correct on some Mac OS versions, second it is not rellocatable. To compile a 64bit rellocatable perl, we use the perlbrew distribution. The perlbrew distribution installs into a user home directory and it allows switching between multiple versions of perl.
http://perlbrew.pl/
First install perlbrew
curl -L http://install.perlbrew.pl | bash
Then compile the newest perl with the rellocatable @INC path and with multithreading enabled, execute following line:
perlbrew install --threads -Duserelocatableinc --switch perl-5.26.1
The --switch parameter switches the active perl to the currently compiled one.
Available perl versions could be listed by calling
perlbrew available
Switch to the newly compiled perl
perl5/perlbrew/bin/perlbrew switch perl-5.26.1
Install cpanm
perlbrew install-cpanm
Initialize CPAN, install PAR and PAR::Packer modules
execute cpan command, from the cpan prompt, run
install App::cpanminus
install ExtUtils::CppGuess
install ExtUtils::Typemaps
install ExtUtils::Typemaps::Basic
install PAR
install PAR::Packer
install Module::Build
install Module::Pluggable
install Module::Runtime
install Moo
install Test::Pod
install Test::Pod::Coverage
quit
4) Download and install Slic3r
------------------------------
git clone git://github.com/alexrj/Slic3r
cd Slic3r
perl Build.PL
Now Slic3r shall be compiled. You may try to execute
perl slic3r.pl
to get a help screen, or
perl slic3r.pl some_model.stl
to have the model sliced.
5) Download and compile the GUI libraries needed to execute Slic3r in GUI mode
------------------------------------------------------------------------------
Building the Perl Alien-Wx containing a wxWidgets library:
We use wxWidgets-3.0.3.
patch wxWidgets-3.0.3//src/osx/cocoa/textctrl.mm , see https://github.com/prusa3d/Slic3r/issues/600
perl -I. Build.PL --wxWidgets-extraflags="--with-osx_cocoa --with-macosx-version-min=10.9 --with-macosx-sdk=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk --with-libjpeg=builtin --with-libpng=builtin --with-regex=builtin --with-libtiff=builtin --with-zlib=builtin --with-expat=builtin --with-opengl"
perl -I. Build
perl -I. Build test
perl -I. Build
Building the Perl Wx package:
cpan install Wx
Building the Perl OpenGL package:
OpenGL needs to be patched to support MSAA, see the Windows patch.
For the current Slic3r 1.2.30 code base, set the environment variable SLIC3R_STATIC to link a static version of the boost library:
export SLIC3R_STATIC=1
then execute
perl Build.PL --gui
and keep your fingers crossed. The Build.PL script downloads and compiles the WxWidgets 3.0 through a Alien::Wx PERL package. The WxWidget shared libraries will land into
~/perl5/perlbrew/perls/perl-5.22.1/lib/site_perl/5.22.1/darwin-thread-multi-2level/Alien/wxWidgets/
On Maverics, we experienced following issue compiling WxPerl:
http://wiki.bolay.net/doku.php?id=acdsn:acdsn-a:mac
Now you could run the GUI version of slic3r by calling
perl slic3r.pl --gui
If some dependency is missing, the MacOS system will let you know.
6) Packing the Slic3r
---------------------
Perl is an operating system on its own. Many modules are shared among multiple applications and it is difficult to extract a stand-alone application from a perl installation manually. Fortunately, tools are available, which automate the process to some extent. One of the tools is the PAR::Packer. The PAR::Packer tool (pp executable) is able to create a standalone executable for a perl script. The standalone executable contains a PAR archive (a zip file) bundled with a perl interpreter. When executed, the bundled executable will decompress most of the PAR archive into a temp folder. Because of that, we will use the PAR::Packer to resolve and collect the dependencies, but we will create an installer manually.
The PAR::Packer could analyze the dependencies by a statical analysis, or at a runtime. The statical analysis does not resolve the dynamically loaded modules. On the other side, the statical analysis is pessimistic, therefore it often collects unneeded packages. The dynamic analysis may miss some package, if not all branches of a code are executed. We will try to solely depend on the dynamic analysis to keep the installation size minimal. We may need to develop a protocol or an automatic UI tool to exercise as much as possible from the Slic3r GUI to pack the GUI version reliably. Once a reliable list of dependencies is collected, we may not need the PAR::Packer anymore.
To create a PAR archive of a command line slic3r, execute
pp -e -p -x slic3r.pl --xargs cube.stl -o slic3r.par
and let the slic3r slice a cube.stl to load the dynamic modules.
To create a PAR archive of a GUI slic3r, execute
pp -e -p -x slic3r.pl --xargs --gui -o slic3r.par
and exercise the slic3r gui to load all modules.
Rename the slic3r.par file to slic3r.zip and decompress. Most of the code needed to execute Slic3r is there, only the perl executable is missing for the command line slic3r, and the WxWidgets shared libraries and the liblzma shared library are missing for the GUI version.
7) Collecting the dependent shared libraries, making the link paths relative
----------------------------------------------------------------------------
We have linked Slic3r against a static boost library, therefore the command line slic3r is not dependent on any non-system shared library. The situation is different for the GUI slic3r, which links dynamically against WxWidgets and liblzma.
The trick developed by Apple to allow rellocable shared libraries is to addres a shared library relatively to the path of the executable by encoding a special token @executable_path at the start of the path. Unfortunately the libraries requried by Slic3r are compiled with absolute paths.
Once the slic3r.par archive is unpacked, one may list the native shared libraries by
find ./ -name '*.bundle'
and one may list the dependencies by running
otool -L somefile.bundle
Most of the dependencies point to system directores and these dependences are always fulfilled. Dependencies pointing to the WxWidget libraries need to be fixed. These have a form
~/perlbrew/perls/perl-5.22.1/lib/site_perl/5.22.1/darwin-thread-multi-2level/Alien/wxWidgets/osx_cocoa_3_0_2_uni/lib/libwx_*.dylib
and we need to replace them with
@executable_path/../Frameworks/libwx_*.dylib
Another dependency, which needs our attention is
/usr/local/Cellar/xz/5.2.2/lib/liblzma.5.dylib
Fortunately, a tool dylibbundler was developed to address this problem.
First install dylibbundler by calling
brew dylibbundler
For some installations, the dylibbundler tool sufficiently fixes all dependencies. Unfortunately, the WxWidgets installation is inconsistent in the versioning, therefore a certain clean-up is required. Namely, the WxWidgets libraries are compiled with the full build number in their file name. For example, the base library is built as libwx_baseu-3.0.0.2.0.dylib and a symlink is created libwx_baseu-3.0.dylib pointing to the full name. Then some of the Wx libraries link against the full name and some against the symlink, leading the dylibbundler to pack both. We solved the problem by whipping up a following script:
\\rs.prusa\Development\Slic3r-Prusa\How_to_build_on_MacOSX_Lion\fix_dependencies.sh
call
slic3r_dependencies.sh --fix
to collect the shared libraries into Content/Frameworks and to fix their linkage.
call
slic3r_dependencies.sh --show
to list dependent libraries in a sorted order. All the non-system dependencies shall start with @executable_path after the fix.
8) Packing Slic3r into a dmg image using a bunch of scripts
-----------------------------------------------------------
Instead of relying on the PAR::Packer to collect the dependencies, we have used PAR::Packer to extract the dependencies, we manually cleaned them up and created an installer script.
\\rs.prusa\Development\Slic3r-Prusa\How_to_build_on_MacOSX_Lion\Slic3r-Build-MacOS
First compile Slic3r, then call build_dmg.sh with a path to the Slic3r source tree as a parameter.
The script will collect all dependencies into Slic3r.app and it will create Slic3r.dmg.
If SLIC3R_GUI variable is defined, a GUI variant of Slic3r will be packed.
How to build on Windows
-----------------------
The prefered perl distribution on MS Windows is the Strawberry Perl 5.22.1.3 (32bit)
http://strawberryperl.com/
Let it install into c:\strawberry
You may make a copy of the distribution. We recommend to make following copies:
For a release command line only build: c:\strawberry-minimal
For a release GUI build: c:\strawberry-minimal-gui
For a development build with debugging information: c:\strawberry-debug
and to make one of them active by making a directory junction:
mklink /d c:\Strawberry c:\Strawberry-debug
Building boost:
Slic3r seems to have a trouble with the latest boost 1.60.0 on Windows. Please use 1.59.
Decompress it to
c:\dev\
otherwise it will not be found by the Build.PL on Windows. You may consider to hack xs\Build.PL with your prefered boost path.
run
bootstrap.bat mingw
b2 toolset=gcc
Install git command line
https://git-scm.com/
Download Slic3r source code
git clone git://github.com/alexrj/Slic3r.git
Run compilation
cd Slic3r
perl Build.PL
perl Build.PL --gui
With a bit of luck, you will end up with a working Slic3r including GUI.
Packing on Windows
------------------
Life is easy on Windows. PAR::Packer will help again to collect the dependencies. The basic procedure is the same as for MacOS:
To create a PAR archive of a command line slic3r, execute
pp -e -p -x slic3r.pl --xargs cube.stl -o slic3r.par
and let the slic3r slice a cube.stl to load the dynamic modules.
To create a PAR archive of a GUI slic3r, execute
pp -e -p -x slic3r.pl --xargs --gui -o slic3r.par
and exercise the slic3r gui to load all modules.
The standalone installation is then created from the PAR archive by renaming it into a zip and adding following binaries from c:\strawberry to the root of the extracted zip:
perl5.22.1.exe
perl522.dll
libgcc_s_sjlj-1.dll
libstdc++-6.dll
libwinpthread-1.dll
The GUI build requires following DLLs in addition:
libglut-0_.dll
wxbase30u_gcc_custom.dll
wxmsw30u_adv_gcc_custom.dll
wxmsw30u_core_gcc_custom.dll
wxmsw30u_gl_gcc_custom.dll
wxmsw30u_html_gcc_custom.dll
and the var directory with the icons needs to be copied to the destination directory.
To run the slic3r, move the script\slic3r.pl one level up and create a following tiny windows batch in the root of the unpacked zip:
@perl5.22.1.exe slic3r.pl %*
A windows shortcut may be created for the GUI version. Instead of the perl.exe, it is better to use the wperl.exe to start the GUI Slic3r, because it does not open a text console.
The strawberry perl is already rellocatable, which means that the perl interpreter will find the perl modules in the lib directory,
and Windows look up the missing DLLs in the directory of the executable, therefore no further rellocation effort is necessary.
Packing on Windows, a single EXE solution
-----------------------------------------
One may try to create a PAR executable for command line slic3r:
pp -M Encode::Locale -M Moo -M Thread::Semaphore -M Slic3r::XS -M Unicode::Normalize -o slic3r.exe slic3r.pl
One may as well create a PAR executable for Windows GUI:
pp -M Encode::Locale -M Moo -M Thread::Semaphore -M OpenGL -M Slic3r::XS -M Unicode::Normalize -M Wx -M Class::Accessor -M Wx::DND -M Wx::Grid -M Wx::Print -M Wx::Html -M Wx::GLCanvas -M Math::Trig -M threads -M threads::shared -M Thread::Queue -l C:\strawberry\perl\site\lib\auto\Wx\Wx.xs.dll -o -l C:\strawberry\perl\site\lib\Alien\wxWidgets\msw_3_0_2_uni_gcc_3_4\lib\wxbase30u_gcc_custom.dll -l C:\strawberry\perl\site\lib\Alien\wxWidgets\msw_3_0_2_uni_gcc_3_4\lib\wxmsw30u_core_gcc_custom.dll -l C:\strawberry\perl\site\lib\Alien\wxWidgets\msw_3_0_2_uni_gcc_3_4\lib\wxmsw30u_gl_gcc_custom.dll -l C:\strawberry\perl\site\lib\Alien\wxWidgets\msw_3_0_2_uni_gcc_3_4\lib\wxmsw30u_adv_gcc_custom.dll -l C:\strawberry\perl\site\lib\Alien\wxWidgets\msw_3_0_2_uni_gcc_3_4\lib\wxmsw30u_html_gcc_custom.dll -o slic3r.exe slic3r.pl
Remember, that these executables will unpack into a temporary directory. The directory may be declared by setting an environment variable PAR_GLOBAL_TEMP. Otherwise the temporaries are unpacked into
C:\Users\xxx\AppData\Local\Temp\par-xxxxxx
Debugging the perl, debugging on Windows
----------------------------------------
It is possible to debug perl using the integrated debugger. The EPIC plugin for Eclipse works very well with an older eclipse-SDK-3.6.2. There is a catch though: The Perl debugger does not work correctly with multiple threads running under the Perl interpreter. If that happens, the EPIC plugin gets confused and the debugger stops working. The same happens with the Komodo IDE.
Debugging the C++ code works fine using the latest Eclipse for C++ and the gdb of MinGW. The gdb packed with the Strawberry distribution does not contain the Python support, so pretty printing of the stl containers only works if another gdb build is used. The one of the QT installation works well.
It is yet a bit more complicated. The Strawberry MINGW is compiled for a different C++ exception passing model (SJLJ) than the other MINGWs, so one cannot simply combine MINGWs on Windows. For an unknown reason the nice debugger of the QT Creator hangs when debugging the C++ compiled by the Strawberry MINGW. Mabe it is because of the different exception passing models.
And to disable optimization of the C/C++ code, one has to manually modify Config_heavy.pl in the Perl central installation. The SLIC3R_DEBUG environment variable did not override all the -O2 and -O3 flags that the perl build adds the gcc execution line.
----------------------------------------------------------------------
Building boost.
One may save compilation time by compiling just what Slic3r needs.
./bootstrap.sh --with-libraries=system,filesystem,thread,log,locale,regex
The -fPIC flag is required on Linux to make the static libraries rellocatable,
so they could be embedded into a shared library.
It is important to disable boost.locale.icu=off when compiling the static boost library.
./bjam -a link=static variant=release threading=multi boost.locale.icu=off --with-locale cxxflags=-fPIC cflags=-fPIC
To install on Linux to /usr/local/..., run the line above with the additional install keyword and with sudo.

76
doc/Localization_guide.md Normal file
View File

@@ -0,0 +1,76 @@
# Localization and translation guide
The purpose of this guide is to describe how to contribute to the Slic3rPE translations. We use GNUgettext for extracting string resources from the project and PoEdit for editing translations.
Those are possible to download here:
- https://sourceforge.net/directory/os:windows/?q=gnu+gettext GNUgettext package contains a set of tools to extract strings from the source code and to create the translation Catalog.
- https://poedit.net PoEdit provides good interface for the translators.
After GNUgettext is installed it is recommended to add the path to gettext/bin to PATH variable.
Full manual for GNUgettext you can see here: http://www.gnu.org/software/gettext/manual/gettext.html
### Scenario 1. How do I add a translation or fix the existing translation
1. Get PO-file from corresponding folder here:
https://github.com/prusa3d/Slic3r/tree/master/resources/localization
2. Open this file in PoEdit as "Edit a translation"
3. Apply your corrections to translation
4. Push changed Slic3rPE.po and Slic3rPE.mo (will create automatically after saving of Slic3r.po in PoEdit) back to to the enter folder.
### Scenario 2. How do I add a new language support
1. Get file Slic3rPE.pot here :
https://github.com/prusa3d/Slic3r/tree/master/resources/localization
2. Open it in PoEdit for "Create new translation"
3. Select Translation Language (for example French).
4. As a result you will have fr.po - the file contaning translation to French.
Notice. When the transtation is complete you need to:
- Rename the file to Slic3rPE.po
- Click "Save file" button. Slic3rPE.mo will be created immediatly
- Both Slic3rPE.po and Slic3rPE.mo have to be saved here:
https://github.com/prusa3d/Slic3r/tree/master/resources/localization/fr
( name of folder "fr" means "French" - the translation language).
### Scenario 3. How do I add a new text resource when implementing a feature to Slic3rPE
Each string resource in Slic3rPE available for translation needs to be explicitly marked using L() macro like this:
```C++
auto msg = L("This message to be localized")
```
To get translated text use one of needed macro/function (`_(s)`, `_CHB(s)` or `L_str(s)` ).
If you add new file resourse, add it to list of files contaned macro `L()`
### Scenario 4. How do I use GNUgettext to localize my own application taking Slic3rPE as an example
1. For conviniance create list of files with this macro `L(s)`. We have
https://github.com/prusa3d/Slic3r/tree/master/resources/localization/list.txt.
2. Create template file(*.POT) with GNUgettext command:
```
xgettext --keyword=L --from-code=UTF-8 --debug -o Slic3rPE.pot -f list.txt
```
Use flag `--from-code=UTF-8` to specify that the source strings are in UTF-8 encoding
Use flag `--debug` to correctly extract formated strings(used %d, %s etc.)
3. Create PO- and MO-files for your project as described above.
4. To merge old PO-file with strings from creaded new POT-file use command:
```
msgmerge -N -o new.po old.po new.pot
```
Use option `-N` to not using fuzzy matching when an exact match is not found.
5. To concatenate old PO-file with strings from new PO-file use command:
```
msgcat -o new.po old.po
```
6. Create an English translation catalog with command:
```
msgen -o new.po old.po
```
Notice, in this Catalog it will be totally same strings for initial text and translated.
When you have Catalog to translation open POT or PO file in PoEdit and start to translation.
It's very important to keep attention to every gaps and punctuation. Especially with
formated strings. (used %d, %s etc.)

View File

@@ -0,0 +1,135 @@
#
# This makefile downloads, configures and builds Slic3r PE dependencies for Unix.
# (That is, all dependencies except perl + wxWidgets.)
# The libraries are installed in DESTDIR, which you can customize like so:
#
# DESTDIR=foo/bar make
#
# The default DESTDIR is ~/slic3r-destdir
# If the DESTDIR doesn't exits, the makefile tries to create it
#
# To pass the DESTDIR path along to cmake, set the use CMAKE_PREFIX_PATH variable
# and set it to $DESTDIR/usr/local
#
# You can also customize the NPROC variable in the same way to configure the number
# of cores the build process uses. By default this is set to what the `nproc` command says.
#
DESTDIR ?= $(HOME)/slic3r-destdir
NPROC ?= $(shell nproc)
BOOST = boost_1_66_0
TBB_SHA = a0dc9bf76d0120f917b641ed095360448cabc85b
TBB = tbb-$(TBB_SHA)
OPENSSL = openssl-OpenSSL_1_1_0g
CURL = curl-7.58.0
.PHONY: all destdir boost libcurl libopenssl libtbb
all: destdir boost libtbb libcurl
@echo
@echo "All done!"
@echo
destdir:
mkdir -p $(DESTDIR)
boost: $(BOOST).tar.gz
tar -zxvf $(BOOST).tar.gz
cd $(BOOST) && ./bootstrap.sh --with-libraries=system,filesystem,thread,log,locale,regex --prefix=$(DESTDIR)/usr/local
cd $(BOOST) && ./b2 \
-j $(NPROC) \
link=static \
variant=release \
threading=multi \
boost.locale.icu=off \
cxxflags=-fPIC cflags=-fPIC \
install
$(BOOST).tar.gz:
curl -L -o $@ https://dl.bintray.com/boostorg/release/1.66.0/source/$@
libtbb: $(TBB).tar.gz
tar -zxvf $(TBB).tar.gz
mkdir -p $(TBB)/mybuild
cd $(TBB)/mybuild && cmake .. -DTBB_BUILD_SHARED=OFF -DTBB_BUILD_TESTS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON
$(MAKE) -C $(TBB)/mybuild -j$(NPROC)
$(MAKE) -C $(TBB)/mybuild install DESTDIR=$(DESTDIR)
$(TBB).tar.gz:
curl -L -o $@ https://github.com/wjakob/tbb/archive/$(TBB_SHA).tar.gz
# Note: libcurl build system seems to be a bit wonky about finding openssl (cf. #2378).
# It seems that currently the only working option is to set a prefix in the openssl build
# and use the `--with-ssl=...` option in libcurl.
# Additionally, pkg-config needs to be installed and openssl libs need to NOT be installed on the build system.
libopenssl: $(OPENSSL).tar.gz
tar -zxvf $(OPENSSL).tar.gz
cd $(OPENSSL) && ./config --prefix=$(DESTDIR)/usr/local no-shared no-ssl3-method no-dynamic-engine '-Wa,--noexecstack'
$(MAKE) -C $(OPENSSL) depend
$(MAKE) -C $(OPENSSL) -j$(NPROC)
$(MAKE) -C $(OPENSSL) install_sw
$(OPENSSL).tar.gz:
curl -L -o $@ 'https://github.com/openssl/openssl/archive/OpenSSL_1_1_0g.tar.gz'
libcurl: libopenssl $(CURL).tar.gz
tar -zxvf $(CURL).tar.gz
cd $(CURL) && ./configure \
--enable-static \
--disable-shared \
--with-ssl=$(DESTDIR)/usr/local \
--with-pic \
--enable-ipv6 \
--enable-versioned-symbols \
--enable-threaded-resolver \
--with-random=/dev/urandom \
--with-ca-bundle=/etc/ssl/certs/ca-certificates.crt \
--disable-ldap \
--disable-ldaps \
--disable-manual \
--disable-rtsp \
--disable-dict \
--disable-telnet \
--disable-pop3 \
--disable-imap \
--disable-smb \
--disable-smtp \
--disable-gopher \
--disable-crypto-auth \
--without-gssapi \
--without-libpsl \
--without-libidn2 \
--without-gnutls \
--without-polarssl \
--without-mbedtls \
--without-cyassl \
--without-nss \
--without-axtls \
--without-brotli \
--without-libmetalink \
--without-libssh \
--without-libssh2 \
--without-librtmp \
--without-nghttp2 \
--without-zsh-functions-dir
$(MAKE) -C $(CURL) -j$(NPROC)
$(MAKE) -C $(CURL) install DESTDIR=$(DESTDIR)
$(CURL).tar.gz:
curl -L -o $@ https://curl.haxx.se/download/$@
clean:
rm -rf $(BOOST) $(BOOST).tar.gz $(TBB) $(TBB).tar.gz $(OPENSSL) $(OPENSSL).tar.gz $(CURL) $(CURL).tar.gz

View File

@@ -0,0 +1,141 @@
#!powershell
#
# This script downloads, configures and builds Slic3r PE dependencies for Unix.
# (That is, all dependencies except perl + wxWidgets.)
#
# To use this script, launch the Visual Studio command line,
# `cd` into the directory containing this script and use this command:
#
# powershell .\slic3r-makedeps.ps1
#
# The dependencies will be downloaded and unpacked into the current dir.
# This script WILL NOT try to guess the build architecture (64 vs 32 bits),
# it will by default build the 64-bit variant. To build the 32-bit variant, use:
#
# powershell .\slic3r-makedeps.ps1 -b32
#
# Built libraries are installed into $destdir,
# which by default is C:\local\slic3r-destdir-$bits
# You can customize the $destdir using:
#
# powershell .\slic3r-makedeps.ps1 -destdir C:\foo\bar
#
# To pass the $destdir path along to cmake, set the use CMAKE_PREFIX_PATH variable
# and set it to $destdir\usr\local
#
# Script requirements: PowerShell 3.0, .NET 4.5
#
param(
[switch]$b32 = $false,
[string]$destdir = ""
)
if ($destdir -eq "") {
$destdir = "C:\local\slic3r-destdir-" + ('32', '64')[!$b32]
}
$BOOST = 'boost_1_63_0'
$CURL = 'curl-7.58.0'
$TBB_SHA = 'a0dc9bf76d0120f917b641ed095360448cabc85b'
$TBB = "tbb-$TBB_SHA"
try
{
# Set up various settings and utilities:
[Environment]::CurrentDirectory = Get-Location
$NPROC = (Get-WmiObject -class Win32_processor).NumberOfLogicalProcessors
Add-Type -A System.IO.Compression.FileSystem
# This fxies SSL/TLS errors, credit goes to Ansible; see their `win_get_url.ps1` file
$security_protcols = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::SystemDefault
if ([Net.SecurityProtocolType].GetMember('Tls11').Count -gt 0) {
$security_protcols = $security_protcols -bor [Net.SecurityProtocolType]::Tls11
}
if ([Net.SecurityProtocolType].GetMember('Tls12').Count -gt 0) {
$security_protcols = $security_protcols -bor [Net.SecurityProtocolType]::Tls12
}
[Net.ServicePointManager]::SecurityProtocol = $security_protcols
$webclient = New-Object System.Net.WebClient
# Ensure DESTDIR exists:
mkdir $destdir -ea 0
mkdir "$destdir\usr\local" -ea 0
# Download sources:
echo 'Downloading sources ...'
if (!(Test-Path "$BOOST.zip")) { $webclient.DownloadFile("https://dl.bintray.com/boostorg/release/1.63.0/source/$BOOST.zip", "$BOOST.zip") }
if (!(Test-Path "$TBB.zip")) { $webclient.DownloadFile("https://github.com/wjakob/tbb/archive/$TBB_SHA.zip", "$TBB.zip") }
if (!(Test-Path "$CURL.zip")) { $webclient.DownloadFile("https://curl.haxx.se/download/$CURL.zip", ".\$CURL.zip") }
# Unpack sources:
echo 'Unpacking ...'
if (!(Test-Path $BOOST)) { [IO.Compression.ZipFile]::ExtractToDirectory("$BOOST.zip", '.') }
if (!(Test-Path $TBB)) { [IO.Compression.ZipFile]::ExtractToDirectory("$TBB.zip", '.') }
if (!(Test-Path $CURL)) { [IO.Compression.ZipFile]::ExtractToDirectory("$CURL.zip", '.') }
# Build libraries:
echo 'Building ...'
# Build boost
pushd "$BOOST"
.\bootstrap
$adr_mode = ('32', '64')[!$b32]
.\b2 `
-j "$NPROC" `
--with-system `
--with-filesystem `
--with-thread `
--with-log `
--with-locale `
--with-regex `
"--prefix=$destdir/usr/local" `
"address-model=$adr_mode" `
toolset=msvc-12.0 `
link=static `
variant=release `
threading=multi `
boost.locale.icu=off `
install
popd
# Build TBB
pushd "$TBB"
mkdir 'mybuild' -ea 0
cd 'mybuild'
$generator = ('Visual Studio 12', 'Visual Studio 12 Win64')[!$b32]
cmake .. `
-G "$generator" `
-DCMAKE_CONFIGURATION_TYPES=Release `
-DTBB_BUILD_SHARED=OFF `
-DTBB_BUILD_TESTS=OFF "-DCMAKE_INSTALL_PREFIX:PATH=$destdir\usr\local"
msbuild /P:Configuration=Release INSTALL.vcxproj
popd
# Build libcurl:
pushd "$CURL\winbuild"
$machine = ("x86", "x64")[!$b32]
nmake /f Makefile.vc mode=static VC=12 GEN_PDB=yes DEBUG=no "MACHINE=$machine"
Copy-Item -R -Force ..\builds\libcurl-*-winssl\include\* "$destdir\usr\local\include\"
Copy-Item -R -Force ..\builds\libcurl-*-winssl\lib\* "$destdir\usr\local\lib\"
popd
echo ""
echo "All done!"
echo ""
}
catch [Exception]
{
# This prints errors in a verbose manner
echo $_.Exception|format-list -force
}

52
doc/updating/Updatig.md Normal file
View File

@@ -0,0 +1,52 @@
# Slic3r PE 1.40 configuration update
Slic3r PE 1.40.0 comes with a major re-work of the way configuration presets work.
There are three new features:
+ A two-tier system of presets being divided into _System_ and _User_ groups
+ Configuration snapshots
+ Configuration updating from the internet
## System and User presets
- _System preset_: These are the presets that come with Slic3r PE installation. They come from a vendor configuration bundle (not individual files like before). They are **read-only** a user cannot modify them, but may instead create a derived User preset based on a System preset
- _User preset_: These are regular presets stored in files just like before. Additionally, they may be derived (inherited) from one of the System presets
A derived User preset keeps track of wich settings are inherited from the parent System preset and which are modified by the user. When a system preset is updated (either via installation of a new Slic3r or automatically from the internet), in a User preset the settings that are modified by the user will stay that way, while the ones that are inherited reflect the updated System preset.
This system ensures that we don't overwrite user's settings when there is an update to the built in presets.
Slic3r GUI now displays accurately which settings are inherited and which are modified.
A setting derived from a System preset is represented by green label and a locked lock icon:
![a system setting](setting_sys.png)
A settings modified in a User preset has an open lock icon:
![a user setting](setting_user.png)
Clickign the open lock icon restored the system setting.
Additionaly, any setting that is modified but not yet saved onto disk is represented by orange label and a back-arrow:
![a modified setting](setting_mod.png)
Clicking the back-arrow restores the value that was previously saved in this Preset.
## Configuration snapshots
Configuration snapshots can now be taken via the _Configuration_ menu.
A snapshot contains complete configuration from the point when the snapshot was taken.
Users may move back and forth between snapshots at will using a dialog:
![snapshots dialog](snapshots_dialog.png)
# Updating from the internet
Slic3r PE 1.40.0 checks for updates of the built-in System presets and downloads them.
The first-time configuration assistant will ask you if you want to enable this feature - it is **not** mandatory.
Updates are checked for and downloaded in the background. If there's is an update, Slic3r will prompt about it
next time it is launched, never during normal program operation. An update may be either accepted or refused.
Before any update is applied a configuration snapshot (as described above) is taken.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@@ -1,3 +1,6 @@
# This package loads all the non-GUI Slic3r perl packages.
# In addition, it implements utility functions for file handling and threading.
package Slic3r;
# Copyright holder: Alessandro Ranellucci
@@ -5,62 +8,54 @@ package Slic3r;
use strict;
use warnings;
use Config;
require v5.10;
our $VERSION = "1.2.0";
our $VERSION = VERSION();
our $BUILD = BUILD();
our $FORK_NAME = FORK_NAME();
our $debug = 0;
sub debugf {
printf @_ if $debug;
}
our $loglevel = 0;
# load threads before Moo as required by it
our $have_threads;
BEGIN {
# Test, whether the perl was compiled with ithreads support and ithreads actually work.
use Config;
$have_threads = $Config{useithreads} && eval "use threads; use threads::shared; use Thread::Queue; 1";
### temporarily disable threads if using the broken Moo version
use Moo;
$have_threads = 0 if $Moo::VERSION == 1.003000;
my $have_threads = $Config{useithreads} && eval "use threads; use threads::shared; use Thread::Queue; 1";
die "Slic3r Prusa Edition requires working Perl threads.\n" if ! $have_threads;
die "threads.pm >= 1.96 is required, please update\n" if $threads::VERSION < 1.96;
die "Perl threading is broken with this Moo version: " . $Moo::VERSION . "\n" if $Moo::VERSION == 1.003000;
$debug = 1 if (defined($ENV{'SLIC3R_DEBUGOUT'}) && $ENV{'SLIC3R_DEBUGOUT'} == 1);
print "Debugging output enabled\n" if $debug;
}
warn "Running Slic3r under Perl >= 5.16 is not supported nor recommended\n"
if $^V >= v5.16;
warn "Running Slic3r under Perl 5.16 is neither supported nor recommended\n"
if $^V == v5.16;
use FindBin;
our $var = "$FindBin::Bin/var";
use Encode;
use Encode::Locale;
# Let the XS module know where the GUI resources reside.
set_resources_dir(decode_path($FindBin::Bin) . (($^O eq 'darwin') ? '/../Resources' : '/resources'));
set_var_dir(resources_dir() . "/icons");
set_local_dir(resources_dir() . "/localization/");
use Moo 1.003001;
use Slic3r::XS; # import all symbols (constants etc.) before they get parsed
use Slic3r::Config;
use Slic3r::ExPolygon;
use Slic3r::Extruder;
use Slic3r::ExtrusionLoop;
use Slic3r::ExtrusionPath;
use Slic3r::ExtrusionPath::Collection;
use Slic3r::Fill;
use Slic3r::Flow;
use Slic3r::Format::AMF;
use Slic3r::Format::OBJ;
use Slic3r::Format::STL;
use Slic3r::GCode;
use Slic3r::GCode::ArcFitting;
use Slic3r::GCode::CoolingBuffer;
use Slic3r::GCode::Layer;
use Slic3r::GCode::MotionPlanner;
use Slic3r::GCode::PlaceholderParser;
use Slic3r::GCode::Reader;
use Slic3r::GCode::SpiralVase;
use Slic3r::GCode::VibrationLimit;
use Slic3r::Geometry qw(PI);
use Slic3r::Geometry::Clipper;
use Slic3r::Layer;
use Slic3r::Layer::BridgeDetector;
use Slic3r::Layer::Region;
use Slic3r::Line;
use Slic3r::Model;
use Slic3r::Point;
@@ -69,38 +64,40 @@ use Slic3r::Polyline;
use Slic3r::Print;
use Slic3r::Print::Object;
use Slic3r::Print::Simple;
use Slic3r::Print::SupportMaterial;
use Slic3r::Surface;
our $build = eval "use Slic3r::Build; 1";
use Thread::Semaphore;
# Scaling between the float and integer coordinates.
# Floats are in mm.
use constant SCALING_FACTOR => 0.000001;
use constant RESOLUTION => 0.0125;
use constant SCALED_RESOLUTION => RESOLUTION / SCALING_FACTOR;
use constant SMALL_PERIMETER_LENGTH => (6.5 / SCALING_FACTOR) * 2 * PI;
use constant LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER => 0.15;
use constant INFILL_OVERLAP_OVER_SPACING => 0.45;
use constant EXTERNAL_INFILL_MARGIN => 3;
use constant INSET_OVERLAP_TOLERANCE => 0.2;
# keep track of threads we created
my @threads : shared = ();
my $sema = Thread::Semaphore->new;
# Keep track of threads we created. Perl worker threads shall not create further threads.
my @threads = ();
my $pause_sema = Thread::Semaphore->new;
my $paused = 0;
# Set the logging level at the Slic3r XS module.
$Slic3r::loglevel = (defined($ENV{'SLIC3R_LOGLEVEL'}) && $ENV{'SLIC3R_LOGLEVEL'} =~ /^[1-9]/) ? $ENV{'SLIC3R_LOGLEVEL'} : 0;
set_logging_level($Slic3r::loglevel);
# Let the palceholder parser evaluate one expression to initialize its local static macro_processor
# class instance in a thread safe manner.
Slic3r::GCode::PlaceholderParser->new->evaluate_boolean_expression('1==1');
sub spawn_thread {
my ($cb) = @_;
@_ = ();
my $thread = threads->create(sub {
Slic3r::debugf "Starting thread %d...\n", threads->tid;
local $SIG{'KILL'} = sub {
Slic3r::debugf "Exiting thread...\n";
Slic3r::debugf "Exiting thread %d...\n", threads->tid;
Slic3r::thread_cleanup();
threads->exit();
};
local $SIG{'STOP'} = sub {
$sema->down;
$sema->up;
$pause_sema->down;
$pause_sema->up;
};
$cb->();
});
@@ -108,45 +105,6 @@ sub spawn_thread {
return $thread;
}
sub parallelize {
my %params = @_;
if (!$params{disable} && $Slic3r::have_threads && $params{threads} > 1) {
my @items = (ref $params{items} eq 'CODE') ? $params{items}->() : @{$params{items}};
my $q = Thread::Queue->new;
$q->enqueue(@items, (map undef, 1..$params{threads}));
my $thread_cb = sub {
# execute thread callback
$params{thread_cb}->($q);
# cleanup before terminating thread
Slic3r::thread_cleanup();
# This explicit exit avoids an untrappable
# "Attempt to free unreferenced scalar" error
# triggered on Ubuntu 12.04 32-bit when we're running
# from the Wx plater and
# we're reusing the same plater object more than once.
# The downside to using this exit is that we can't return
# any value to the main thread but we're not doing that
# anymore anyway.
# collect_cb is completely useless now
# and should be removed from the codebase.
threads->exit;
};
$params{collect_cb} ||= sub {};
@_ = ();
my @my_threads = map spawn_thread($thread_cb), 1..$params{threads};
foreach my $th (@my_threads) {
$params{collect_cb}->($th->join);
}
} else {
$params{no_threads_cb}->();
}
}
# call this at the very end of each thread (except the main one)
# so that it does not try to free existing objects.
# at that stage, existing objects are only those that we
@@ -159,27 +117,34 @@ sub parallelize {
# object in a thread, make sure the main thread still holds a
# reference so that it won't be destroyed in thread.
sub thread_cleanup {
return if !$Slic3r::have_threads;
# prevent destruction of shared objects
no warnings 'redefine';
*Slic3r::BridgeDetector::DESTROY = sub {};
*Slic3r::Config::DESTROY = sub {};
*Slic3r::Config::Full::DESTROY = sub {};
*Slic3r::Config::GCode::DESTROY = sub {};
*Slic3r::Config::Print::DESTROY = sub {};
*Slic3r::Config::PrintObject::DESTROY = sub {};
*Slic3r::Config::PrintRegion::DESTROY = sub {};
*Slic3r::Config::Static::DESTROY = sub {};
*Slic3r::ExPolygon::DESTROY = sub {};
*Slic3r::ExPolygon::Collection::DESTROY = sub {};
*Slic3r::Extruder::DESTROY = sub {};
*Slic3r::ExtrusionLoop::DESTROY = sub {};
*Slic3r::ExtrusionMultiPath::DESTROY = sub {};
*Slic3r::ExtrusionPath::DESTROY = sub {};
*Slic3r::ExtrusionPath::Collection::DESTROY = sub {};
*Slic3r::ExtrusionSimulator::DESTROY = sub {};
*Slic3r::Flow::DESTROY = sub {};
*Slic3r::GCode::DESTROY = sub {};
*Slic3r::GCode::PlaceholderParser::DESTROY = sub {};
*Slic3r::GCode::PreviewData::DESTROY = sub {};
*Slic3r::GCode::Sender::DESTROY = sub {};
*Slic3r::Geometry::BoundingBox::DESTROY = sub {};
*Slic3r::Geometry::BoundingBoxf::DESTROY = sub {};
*Slic3r::Geometry::BoundingBoxf3::DESTROY = sub {};
*Slic3r::Layer::PerimeterGenerator::DESTROY = sub {};
*Slic3r::Line::DESTROY = sub {};
*Slic3r::Linef3::DESTROY = sub {};
*Slic3r::Model::DESTROY = sub {};
*Slic3r::Model::Object::DESTROY = sub {};
*Slic3r::Point::DESTROY = sub {};
@@ -189,57 +154,135 @@ sub thread_cleanup {
*Slic3r::Polyline::DESTROY = sub {};
*Slic3r::Polyline::Collection::DESTROY = sub {};
*Slic3r::Print::DESTROY = sub {};
*Slic3r::Print::Object::DESTROY = sub {};
*Slic3r::Print::Region::DESTROY = sub {};
*Slic3r::Surface::DESTROY = sub {};
*Slic3r::Surface::Collection::DESTROY = sub {};
*Slic3r::Print::SupportMaterial2::DESTROY = sub {};
*Slic3r::TriangleMesh::DESTROY = sub {};
*Slic3r::GUI::AppConfig::DESTROY = sub {};
*Slic3r::GUI::GCodePreviewData::DESTROY = sub {};
*Slic3r::GUI::PresetBundle::DESTROY = sub {};
*Slic3r::GUI::Tab::DESTROY = sub {};
*Slic3r::GUI::PresetHints::DESTROY = sub {};
*Slic3r::GUI::TabIface::DESTROY = sub {};
*Slic3r::OctoPrint::DESTROY = sub {};
*Slic3r::PresetUpdater::DESTROY = sub {};
return undef; # this prevents a "Scalars leaked" warning
}
sub get_running_threads {
sub _get_running_threads {
return grep defined($_), map threads->object($_), @threads;
}
sub kill_all_threads {
# detach any running thread created in the current one
my @killed = ();
foreach my $thread (get_running_threads()) {
# Send SIGKILL to all the running threads to let them die.
foreach my $thread (_get_running_threads) {
Slic3r::debugf "Thread %d killing %d...\n", threads->tid, $thread->tid;
$thread->kill('KILL');
push @killed, $thread;
}
# unlock semaphore before we block on wait
# otherwise we'd get a deadlock if threads were paused
resume_threads();
$_->join for @killed; # block until threads are killed
resume_all_threads();
# in any thread we wait for our children
foreach my $thread (_get_running_threads) {
Slic3r::debugf " Thread %d waiting for %d...\n", threads->tid, $thread->tid;
$thread->join; # block until threads are killed
Slic3r::debugf " Thread %d finished waiting for %d...\n", threads->tid, $thread->tid;
}
@threads = ();
}
sub pause_threads {
sub pause_all_threads {
return if $paused;
$paused = 1;
$sema->down;
$_->kill('STOP') for get_running_threads();
$pause_sema->down;
$_->kill('STOP') for _get_running_threads;
}
sub resume_threads {
sub resume_all_threads {
return unless $paused;
$paused = 0;
$sema->up;
}
sub encode_path {
my ($filename) = @_;
return encode('locale_fs', $filename);
$pause_sema->up;
}
# Open a file by converting $filename to local file system locales.
sub open {
my ($fh, $mode, $filename) = @_;
return CORE::open $$fh, $mode, encode_path($filename);
}
sub tags {
my ($format) = @_;
$format //= '';
my %tags;
# End of line
$tags{eol} = ($format eq 'html') ? '<br>' : "\n";
# Heading
$tags{h2start} = ($format eq 'html') ? '<b>' : '';
$tags{h2end} = ($format eq 'html') ? '</b>' : '';
# Bold font
$tags{bstart} = ($format eq 'html') ? '<b>' : '';
$tags{bend} = ($format eq 'html') ? '</b>' : '';
# Verbatim
$tags{vstart} = ($format eq 'html') ? '<pre>' : '';
$tags{vend} = ($format eq 'html') ? '</pre>' : '';
return %tags;
}
sub slic3r_info
{
my (%params) = @_;
my %tag = Slic3r::tags($params{format});
my $out = '';
$out .= "$tag{bstart}$Slic3r::FORK_NAME$tag{bend}$tag{eol}";
$out .= "$tag{bstart}Version: $tag{bend}$Slic3r::VERSION$tag{eol}";
$out .= "$tag{bstart}Build: $tag{bend}$Slic3r::BUILD$tag{eol}";
return $out;
}
sub copyright_info
{
my (%params) = @_;
my %tag = Slic3r::tags($params{format});
my $out =
'Copyright &copy; 2016 Vojtech Bubnik, Prusa Research. <br />' .
'Copyright &copy; 2011-2016 Alessandro Ranellucci. <br />' .
'<a href="http://slic3r.org/">Slic3r</a> is licensed under the ' .
'<a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License, version 3</a>.' .
'<br /><br /><br />' .
'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Y. Sapir, Mike Sheldrake and numerous others. ' .
'Manual by Gary Hodgson. Inspired by the RepRap community. <br />' .
'Slic3r logo designed by Corey Daniels, <a href="http://www.famfamfam.com/lab/icons/silk/">Silk Icon Set</a> designed by Mark James. ';
return $out;
}
sub system_info
{
my (%params) = @_;
my %tag = Slic3r::tags($params{format});
my $out = '';
$out .= "$tag{bstart}Operating System: $tag{bend}$Config{osname}$tag{eol}";
$out .= "$tag{bstart}System Architecture: $tag{bend}$Config{archname}$tag{eol}";
if ($^O eq 'MSWin32') {
$out .= "$tag{bstart}Windows Version: $tag{bend}" . `ver` . $tag{eol};
} else {
# Hopefully some kind of unix / linux.
$out .= "$tag{bstart}System Version: $tag{bend}" . `uname -a` . $tag{eol};
}
$out .= $tag{vstart} . Config::myconfig . $tag{vend};
$out .= " $tag{bstart}\@INC:$tag{bend}$tag{eol}$tag{vstart}";
foreach my $i (@INC) {
$out .= " $i\n";
}
$out .= "$tag{vend}";
return $out;
}
# this package declaration prevents an ugly fatal warning to be emitted when
# spawning a new thread
package GLUquadricObjPtr;
package Wx::Printout;
1;

View File

@@ -1,3 +1,6 @@
# Extends C++ class Slic3r::DynamicPrintConfig
# This perl class does not keep any perl class variables,
# all the storage is handled by the underlying C++ code.
package Slic3r::Config;
use strict;
use warnings;
@@ -5,45 +8,31 @@ use utf8;
use List::Util qw(first max);
# cemetery of old config settings
our @Ignore = qw(duplicate_x duplicate_y multiply_x multiply_y support_material_tool acceleration
adjust_overhang_flow standby_temperature scale rotate duplicate duplicate_grid
rotate scale duplicate_grid start_perimeters_at_concave_points start_perimeters_at_non_overhang
randomize_start seal_position bed_size print_center);
# C++ Slic3r::PrintConfigDef exported as a Perl hash of hashes.
# The C++ counterpart is a constant singleton.
our $Options = print_config_def();
# overwrite the hard-coded readonly value (this information is not available in XS)
$Options->{threads}{readonly} = !$Slic3r::have_threads;
# generate accessors
# Generate accessors.
{
no strict 'refs';
for my $opt_key (keys %$Options) {
*{$opt_key} = sub { $_[0]->get($opt_key) };
*{$opt_key} = sub {
#print "Slic3r::Config::accessor $opt_key\n";
$_[0]->get($opt_key)
};
}
}
sub new_from_defaults {
my $class = shift;
my (@opt_keys) = @_;
my $self = $class->new;
my $defaults = Slic3r::Config::Full->new;
if (@opt_keys) {
$self->set($_, $defaults->get($_)) for @opt_keys;
} else {
$self->apply_static($defaults);
}
return $self;
}
# From command line parameters, used by slic3r.pl
sub new_from_cli {
my $class = shift;
my %args = @_;
# Delete hash keys with undefined value.
delete $args{$_} for grep !defined $args{$_}, keys %args;
# Replace the start_gcode, end_gcode ... hash values
# with the content of the files they reference.
for (qw(start end layer toolchange)) {
my $opt_key = "${_}_gcode";
if ($args{$opt_key}) {
@@ -56,7 +45,7 @@ sub new_from_cli {
}
}
}
my $self = $class->new;
foreach my $opt_key (keys %args) {
my $opt_def = $Options->{$opt_key};
@@ -75,373 +64,13 @@ sub new_from_cli {
return $self;
}
sub merge {
my $class = shift;
my $config = $class->new;
$config->apply($_) for @_;
return $config;
}
sub load {
my $class = shift;
my ($file) = @_;
my $ini = __PACKAGE__->read_ini($file);
return $class->load_ini_hash($ini->{_});
}
sub load_ini_hash {
my $class = shift;
my ($ini_hash) = @_;
my $config = $class->new;
foreach my $opt_key (keys %$ini_hash) {
($opt_key, my $value) = _handle_legacy($opt_key, $ini_hash->{$opt_key});
next if !defined $opt_key;
$config->set_deserialize($opt_key, $value);
}
return $config;
}
sub clone {
my $self = shift;
my $new = (ref $self)->new;
$new->apply($self);
return $new;
}
sub get_value {
my $self = shift;
my ($opt_key) = @_;
return $Options->{$opt_key}{ratio_over}
? $self->get_abs_value($opt_key)
: $self->get($opt_key);
}
sub _handle_legacy {
my ($opt_key, $value) = @_;
# handle legacy options
if ($opt_key =~ /^(extrusion_width|bottom_layer_speed|first_layer_height)_ratio$/) {
$opt_key = $1;
$opt_key =~ s/^bottom_layer_speed$/first_layer_speed/;
$value = $value =~ /^\d+(?:\.\d+)?$/ && $value != 0 ? ($value*100) . "%" : 0;
}
if ($opt_key eq 'threads' && !$Slic3r::have_threads) {
$value = 1;
}
if ($opt_key eq 'gcode_flavor' && $value eq 'makerbot') {
$value = 'makerware';
}
if ($opt_key eq 'fill_density' && defined($value) && $value !~ /%/ && $value <= 1) {
# fill_density was turned into a percent value
$value *= 100;
$value = "$value"; # force update of the PV value, workaround for bug https://rt.cpan.org/Ticket/Display.html?id=94110
}
if ($opt_key eq 'randomize_start' && $value) {
$opt_key = 'seam_position';
$value = 'random';
}
if ($opt_key eq 'bed_size' && $value) {
$opt_key = 'bed_shape';
my ($x, $y) = split /,/, $value;
$value = "0x0,${x}x0,${x}x${y},0x${y}";
}
return () if first { $_ eq $opt_key } @Ignore;
# For historical reasons, the world's full of configs having these very low values;
# to avoid unexpected behavior we need to ignore them. Banning these two hard-coded
# values is a dirty hack and will need to be removed sometime in the future, but it
# will avoid lots of complaints for now.
if ($opt_key eq 'perimeter_acceleration' && $value == '25') {
$value = 0;
}
if ($opt_key eq 'infill_acceleration' && $value == '50') {
$value = 0;
}
if (!exists $Options->{$opt_key}) {
my @keys = grep { $Options->{$_}{aliases} && grep $_ eq $opt_key, @{$Options->{$_}{aliases}} } keys %$Options;
if (!@keys) {
warn "Unknown option $opt_key\n";
return ();
}
$opt_key = $keys[0];
}
return ($opt_key, $value);
}
sub set_ifndef {
my $self = shift;
my ($opt_key, $value, $deserialize) = @_;
if (!$self->has($opt_key)) {
if ($deserialize) {
$self->set_deserialize($opt_key, $value);
} else {
$self->set($opt_key, $value);
}
}
}
sub as_ini {
my ($self) = @_;
my $ini = { _ => {} };
foreach my $opt_key (sort @{$self->get_keys}) {
next if $Options->{$opt_key}{shortcut};
$ini->{_}{$opt_key} = $self->serialize($opt_key);
}
return $ini;
}
sub save {
my $self = shift;
my ($file) = @_;
__PACKAGE__->write_ini($file, $self->as_ini);
}
sub setenv {
my $self = shift;
foreach my $opt_key (@{$self->get_keys}) {
$ENV{"SLIC3R_" . uc $opt_key} = $self->serialize($opt_key);
}
}
sub equals {
my ($self, $other) = @_;
return @{ $self->diff($other) } == 0;
}
# this will *ignore* options not present in both configs
sub diff {
my ($self, $other) = @_;
my @diff = ();
foreach my $opt_key (sort @{$self->get_keys}) {
push @diff, $opt_key
if $other->has($opt_key) && $other->serialize($opt_key) ne $self->serialize($opt_key);
}
return [@diff];
}
# this method is idempotent by design and only applies to ::DynamicConfig or ::Full
# objects because it performs cross checks
sub validate {
my $self = shift;
# -j, --threads
die "Invalid value for --threads\n"
if $self->threads < 1;
# --layer-height
die "Invalid value for --layer-height\n"
if $self->layer_height <= 0;
die "--layer-height must be a multiple of print resolution\n"
if $self->layer_height / &Slic3r::SCALING_FACTOR % 1 != 0;
# --first-layer-height
die "Invalid value for --first-layer-height\n"
if $self->first_layer_height !~ /^(?:\d*(?:\.\d+)?)%?$/;
# --filament-diameter
die "Invalid value for --filament-diameter\n"
if grep $_ < 1, @{$self->filament_diameter};
# --nozzle-diameter
die "Invalid value for --nozzle-diameter\n"
if grep $_ < 0, @{$self->nozzle_diameter};
# --perimeters
die "Invalid value for --perimeters\n"
if $self->perimeters < 0;
# --solid-layers
die "Invalid value for --solid-layers\n" if defined $self->solid_layers && $self->solid_layers < 0;
die "Invalid value for --top-solid-layers\n" if $self->top_solid_layers < 0;
die "Invalid value for --bottom-solid-layers\n" if $self->bottom_solid_layers < 0;
# --gcode-flavor
die "Invalid value for --gcode-flavor\n"
if !first { $_ eq $self->gcode_flavor } @{$Options->{gcode_flavor}{values}};
die "--use-firmware-retraction is only supported by Marlin firmware\n"
if $self->use_firmware_retraction && $self->gcode_flavor ne 'reprap';
die "--use-firmware-retraction is not compatible with --wipe\n"
if $self->use_firmware_retraction && first {$_} @{$self->wipe};
# --fill-pattern
die "Invalid value for --fill-pattern\n"
if !first { $_ eq $self->fill_pattern } @{$Options->{fill_pattern}{values}};
# --solid-fill-pattern
die "Invalid value for --solid-fill-pattern\n"
if !first { $_ eq $self->solid_fill_pattern } @{$Options->{solid_fill_pattern}{values}};
# --fill-density
die "The selected fill pattern is not supposed to work at 100% density\n"
if $self->fill_density == 100
&& !first { $_ eq $self->fill_pattern } @{$Options->{solid_fill_pattern}{values}};
# --infill-every-layers
die "Invalid value for --infill-every-layers\n"
if $self->infill_every_layers !~ /^\d+$/ || $self->infill_every_layers < 1;
# --skirt-height
die "Invalid value for --skirt-height\n"
if $self->skirt_height < -1; # -1 means as tall as the object
# --bridge-flow-ratio
die "Invalid value for --bridge-flow-ratio\n"
if $self->bridge_flow_ratio <= 0;
# extruder clearance
die "Invalid value for --extruder-clearance-radius\n"
if $self->extruder_clearance_radius <= 0;
die "Invalid value for --extruder-clearance-height\n"
if $self->extruder_clearance_height <= 0;
# --extrusion-multiplier
die "Invalid value for --extrusion-multiplier\n"
if defined first { $_ <= 0 } @{$self->extrusion_multiplier};
# --default-acceleration
die "Invalid zero value for --default-acceleration when using other acceleration settings\n"
if ($self->perimeter_acceleration || $self->infill_acceleration || $self->bridge_acceleration || $self->first_layer_acceleration)
&& !$self->default_acceleration;
# --spiral-vase
if ($self->spiral_vase) {
# Note that we might want to have more than one perimeter on the bottom
# solid layers.
die "Can't make more than one perimeter when spiral vase mode is enabled\n"
if $self->perimeters > 1;
die "Can't make less than one perimeter when spiral vase mode is enabled\n"
if $self->perimeters < 1;
die "Spiral vase mode can only print hollow objects, so you need to set Fill density to 0\n"
if $self->fill_density > 0;
die "Spiral vase mode is not compatible with top solid layers\n"
if $self->top_solid_layers > 0;
die "Spiral vase mode is not compatible with support material\n"
if $self->support_material || $self->support_material_enforce_layers > 0;
}
# extrusion widths
{
my $max_nozzle_diameter = max(@{ $self->nozzle_diameter });
die "Invalid extrusion width (too large)\n"
if defined first { $_ > 10 * $max_nozzle_diameter }
map $self->get_abs_value_over("${_}_extrusion_width", $self->layer_height),
qw(perimeter infill solid_infill top_infill support_material first_layer);
}
# general validation, quick and dirty
foreach my $opt_key (@{$self->get_keys}) {
my $opt = $Options->{$opt_key};
next unless defined $self->$opt_key;
next unless defined $opt->{cli} && $opt->{cli} =~ /=(.+)$/;
my $type = $1;
my @values = ();
if ($type =~ s/\@$//) {
die "Invalid value for $opt_key\n" if ref($self->$opt_key) ne 'ARRAY';
@values = @{ $self->$opt_key };
} else {
@values = ($self->$opt_key);
}
foreach my $value (@values) {
if ($type eq 'i' || $type eq 'f' || $opt->{type} eq 'percent') {
$value =~ s/%$// if $opt->{type} eq 'percent';
die "Invalid value for $opt_key\n"
if ($type eq 'i' && $value !~ /^-?\d+$/)
|| (($type eq 'f' || $opt->{type} eq 'percent') && $value !~ /^-?(?:\d+|\d*\.\d+)$/)
|| (defined $opt->{min} && $value < $opt->{min})
|| (defined $opt->{max} && $value > $opt->{max});
} elsif ($type eq 's' && $opt->{type} eq 'select') {
die "Invalid value for $opt_key\n"
unless first { $_ eq $value } @{ $opt->{values} };
}
}
}
return 1;
}
# min object distance is max(duplicate_distance, clearance_radius)
sub min_object_distance {
my $self = shift;
return ($self->complete_objects && $self->extruder_clearance_radius > $self->duplicate_distance)
? $self->extruder_clearance_radius
: $self->duplicate_distance;
}
# CLASS METHODS:
sub write_ini {
my $class = shift;
my ($file, $ini) = @_;
Slic3r::open(\my $fh, '>', $file);
binmode $fh, ':utf8';
my $localtime = localtime;
printf $fh "# generated by Slic3r $Slic3r::VERSION on %s\n", "$localtime";
# make sure the _ category is the first one written
foreach my $category (sort { ($a eq '_') ? -1 : ($a cmp $b) } keys %$ini) {
printf $fh "\n[%s]\n", $category if $category ne '_';
foreach my $key (sort keys %{$ini->{$category}}) {
printf $fh "%s = %s\n", $key, $ini->{$category}{$key};
}
}
close $fh;
}
sub read_ini {
my $class = shift;
my ($file) = @_;
local $/ = "\n";
Slic3r::open(\my $fh, '<', $file);
binmode $fh, ':utf8';
my $ini = { _ => {} };
my $category = '_';
while (<$fh>) {
s/\R+$//;
next if /^\s+/;
next if /^$/;
next if /^\s*#/;
if (/^\[(.+?)\]$/) {
$category = $1;
next;
}
/^(\w+) = (.*)/ or die "Unreadable configuration file (invalid data at line $.)\n";
$ini->{$category}{$1} = $2;
}
close $fh;
return $ini;
}
package Slic3r::Config::Print;
package Slic3r::Config::Static;
use parent 'Slic3r::Config';
package Slic3r::Config::PrintObject;
use parent 'Slic3r::Config';
package Slic3r::Config::PrintRegion;
use parent 'Slic3r::Config';
package Slic3r::Config::Full;
use parent 'Slic3r::Config';
sub Slic3r::Config::GCode::new { Slic3r::Config::Static::new_GCodeConfig }
sub Slic3r::Config::Print::new { Slic3r::Config::Static::new_PrintConfig }
sub Slic3r::Config::PrintObject::new { Slic3r::Config::Static::new_PrintObjectConfig }
sub Slic3r::Config::PrintRegion::new { Slic3r::Config::Static::new_PrintRegionConfig }
sub Slic3r::Config::Full::new { Slic3r::Config::Static::new_FullPrintConfig }
1;

View File

@@ -5,7 +5,6 @@ use warnings;
# an ExPolygon is a polygon with holes
use List::Util qw(first);
use Slic3r::Geometry qw(X Y A B point_in_polygon epsilon scaled_epsilon);
use Slic3r::Geometry::Clipper qw(union_ex diff_pl);
sub wkt {
@@ -43,7 +42,6 @@ sub bounding_box {
}
package Slic3r::ExPolygon::Collection;
use Slic3r::Geometry qw(X1 Y1);
sub size {
my $self = shift;

View File

@@ -1,52 +0,0 @@
package Slic3r::Extruder;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(EXTRUDER_ROLE_PERIMETER EXTRUDER_ROLE_INFILL EXTRUDER_ROLE_SUPPORT_MATERIAL
EXTRUDER_ROLE_SUPPORT_MATERIAL_INTERFACE);
our %EXPORT_TAGS = (roles => \@EXPORT_OK);
use Slic3r::Geometry qw(PI scale);
# has 'e_per_mm3' => (is => 'lazy');
# has 'retract_speed_mm_min' => (is => 'lazy');
use constant EXTRUDER_ROLE_PERIMETER => 1;
use constant EXTRUDER_ROLE_INFILL => 2;
use constant EXTRUDER_ROLE_SUPPORT_MATERIAL => 3;
use constant EXTRUDER_ROLE_SUPPORT_MATERIAL_INTERFACE => 4;
sub e_per_mm3 {
my $self = shift;
return $self->extrusion_multiplier * (4 / (($self->filament_diameter ** 2) * PI));
}
sub retract_speed_mm_min {
my $self = shift;
return $self->retract_speed * 60;
}
sub scaled_wipe_distance {
my ($self, $travel_speed) = @_;
# how far do we move in XY at travel_speed for the time needed to consume
# retract_length at retract_speed?
# reduce feedrate a bit; travel speed is often too high to move on existing material
# too fast = ripping of existing material; too slow = short wipe path, thus more blob
return scale($self->retract_length / $self->retract_speed * $travel_speed * 0.8);
}
sub extruded_volume {
my ($self, $E) = @_;
return $E * ($self->filament_diameter**2) * PI/4;
}
sub e_per_mm {
my ($self, $mm3_per_mm) = @_;
return $mm3_per_mm * $self->e_per_mm3;
}
1;

View File

@@ -4,8 +4,8 @@ use warnings;
use parent qw(Exporter);
our @EXPORT_OK = qw(EXTRL_ROLE_DEFAULT EXTRL_ROLE_EXTERNAL_PERIMETER
EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER);
our @EXPORT_OK = qw(EXTRL_ROLE_DEFAULT
EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER EXTRL_ROLE_SKIRT);
our %EXPORT_TAGS = (roles => \@EXPORT_OK);

View File

@@ -6,7 +6,8 @@ use parent qw(Exporter);
our @EXPORT_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_EXTERNAL_PERIMETER EXTR_ROLE_OVERHANG_PERIMETER
EXTR_ROLE_FILL EXTR_ROLE_SOLIDFILL EXTR_ROLE_TOPSOLIDFILL EXTR_ROLE_GAPFILL EXTR_ROLE_BRIDGE
EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_SUPPORTMATERIAL_INTERFACE);
EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_SUPPORTMATERIAL_INTERFACE
EXTR_ROLE_NONE);
our %EXPORT_TAGS = (roles => \@EXPORT_OK);
1;

View File

@@ -1,5 +0,0 @@
package Slic3r::ExtrusionPath::Collection;
use strict;
use warnings;
1;

View File

@@ -1,262 +0,0 @@
package Slic3r::Fill;
use Moo;
use Slic3r::ExtrusionPath ':roles';
use Slic3r::Fill::3DHoneycomb;
use Slic3r::Fill::ArchimedeanChords;
use Slic3r::Fill::Base;
use Slic3r::Fill::Concentric;
use Slic3r::Fill::Flowsnake;
use Slic3r::Fill::HilbertCurve;
use Slic3r::Fill::Honeycomb;
use Slic3r::Fill::Line;
use Slic3r::Fill::OctagramSpiral;
use Slic3r::Fill::PlanePath;
use Slic3r::Fill::Rectilinear;
use Slic3r::Flow ':roles';
use Slic3r::Geometry qw(X Y PI scale chained_path deg2rad);
use Slic3r::Geometry::Clipper qw(union union_ex diff diff_ex intersection_ex offset offset2);
use Slic3r::Surface ':types';
has 'bounding_box' => (is => 'ro', required => 0);
has 'fillers' => (is => 'rw', default => sub { {} });
our %FillTypes = (
archimedeanchords => 'Slic3r::Fill::ArchimedeanChords',
rectilinear => 'Slic3r::Fill::Rectilinear',
flowsnake => 'Slic3r::Fill::Flowsnake',
octagramspiral => 'Slic3r::Fill::OctagramSpiral',
hilbertcurve => 'Slic3r::Fill::HilbertCurve',
line => 'Slic3r::Fill::Line',
concentric => 'Slic3r::Fill::Concentric',
honeycomb => 'Slic3r::Fill::Honeycomb',
'3dhoneycomb' => 'Slic3r::Fill::3DHoneycomb',
);
sub filler {
my $self = shift;
my ($filler) = @_;
if (!ref $self) {
return $FillTypes{$filler}->new;
}
$self->fillers->{$filler} ||= $FillTypes{$filler}->new(
bounding_box => $self->bounding_box,
);
return $self->fillers->{$filler};
}
sub make_fill {
my $self = shift;
my ($layerm) = @_;
Slic3r::debugf "Filling layer %d:\n", $layerm->id;
my $fill_density = $layerm->config->fill_density;
my $infill_flow = $layerm->flow(FLOW_ROLE_INFILL);
my $solid_infill_flow = $layerm->flow(FLOW_ROLE_SOLID_INFILL);
my @surfaces = ();
# merge adjacent surfaces
# in case of bridge surfaces, the ones with defined angle will be attached to the ones
# without any angle (shouldn't this logic be moved to process_external_surfaces()?)
{
my @surfaces_with_bridge_angle = grep { $_->bridge_angle >= 0 } @{$layerm->fill_surfaces};
# group surfaces by distinct properties
my @groups = @{$layerm->fill_surfaces->group};
# merge compatible groups (we can generate continuous infill for them)
{
# cache flow widths and patterns used for all solid groups
# (we'll use them for comparing compatible groups)
my @is_solid = my @fw = my @pattern = ();
for (my $i = 0; $i <= $#groups; $i++) {
# we can only merge solid non-bridge surfaces, so discard
# non-solid surfaces
if ($groups[$i][0]->is_solid && (!$groups[$i][0]->is_bridge || $layerm->id == 0)) {
$is_solid[$i] = 1;
$fw[$i] = ($groups[$i][0]->surface_type == S_TYPE_TOP)
? $layerm->flow(FLOW_ROLE_TOP_SOLID_INFILL)->width
: $solid_infill_flow->width;
$pattern[$i] = $groups[$i][0]->is_external
? $layerm->config->solid_fill_pattern
: 'rectilinear';
} else {
$is_solid[$i] = 0;
$fw[$i] = 0;
$pattern[$i] = 'none';
}
}
# loop through solid groups
for (my $i = 0; $i <= $#groups; $i++) {
next if !$is_solid[$i];
# find compatible groups and append them to this one
for (my $j = $i+1; $j <= $#groups; $j++) {
next if !$is_solid[$j];
if ($fw[$i] == $fw[$j] && $pattern[$i] eq $pattern[$j]) {
# groups are compatible, merge them
push @{$groups[$i]}, @{$groups[$j]};
splice @groups, $j, 1;
splice @is_solid, $j, 1;
splice @fw, $j, 1;
splice @pattern, $j, 1;
}
}
}
}
# give priority to bridges
@groups = sort { ($a->[0]->bridge_angle >= 0) ? -1 : 0 } @groups;
foreach my $group (@groups) {
my $union_p = union([ map $_->p, @$group ], 1);
# subtract surfaces having a defined bridge_angle from any other
if (@surfaces_with_bridge_angle && $group->[0]->bridge_angle < 0) {
$union_p = diff(
$union_p,
[ map $_->p, @surfaces_with_bridge_angle ],
1,
);
}
# subtract any other surface already processed
my $union = diff_ex(
$union_p,
[ map $_->p, @surfaces ],
1,
);
push @surfaces, map $group->[0]->clone(expolygon => $_), @$union;
}
}
# we need to detect any narrow surfaces that might collapse
# when adding spacing below
# such narrow surfaces are often generated in sloping walls
# by bridge_over_infill() and combine_infill() as a result of the
# subtraction of the combinable area from the layer infill area,
# which leaves small areas near the perimeters
# we are going to grow such regions by overlapping them with the void (if any)
# TODO: detect and investigate whether there could be narrow regions without
# any void neighbors
my $distance_between_surfaces = $infill_flow->scaled_spacing * &Slic3r::INFILL_OVERLAP_OVER_SPACING;
{
my $collapsed = diff(
[ map @{$_->expolygon}, @surfaces ],
offset2([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2, +$distance_between_surfaces/2),
1,
);
push @surfaces, map Slic3r::Surface->new(
expolygon => $_,
surface_type => S_TYPE_INTERNALSOLID,
), @{intersection_ex(
offset($collapsed, $distance_between_surfaces),
[
(map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces),
(@$collapsed),
],
1,
)};
}
# add spacing between surfaces
@surfaces = map @{$_->offset(-$distance_between_surfaces / 2)}, @surfaces;
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output("fill_" . $layerm->print_z . ".svg",
expolygons => [ map $_->expolygon, grep !$_->is_solid, @surfaces ],
red_expolygons => [ map $_->expolygon, grep $_->is_solid, @surfaces ],
);
}
my @fills = ();
my @fills_ordering_points = ();
SURFACE: foreach my $surface (@surfaces) {
next if $surface->surface_type == S_TYPE_INTERNALVOID;
my $filler = $layerm->config->fill_pattern;
my $density = $fill_density;
my $role = ($surface->surface_type == S_TYPE_TOP) ? FLOW_ROLE_TOP_SOLID_INFILL
: $surface->is_solid ? FLOW_ROLE_SOLID_INFILL
: FLOW_ROLE_INFILL;
my $is_bridge = $layerm->id > 0 && $surface->is_bridge;
my $is_solid = $surface->is_solid;
# force 100% density and rectilinear fill for external surfaces
if ($surface->surface_type != S_TYPE_INTERNAL) {
$density = 100;
$filler = $layerm->config->solid_fill_pattern;
if ($is_bridge) {
$filler = 'rectilinear';
} elsif ($surface->surface_type == S_TYPE_INTERNALSOLID) {
$filler = 'rectilinear';
}
} else {
next SURFACE unless $density > 0;
}
my $h = $surface->thickness == -1 ? $layerm->height : $surface->thickness;
my $flow = $layerm->region->flow(
$role,
$h,
$is_bridge,
$layerm->id == 0,
-1,
$layerm->object,
);
my $f = $self->filler($filler);
$f->layer_id($layerm->id);
$f->z($layerm->print_z);
$f->angle(deg2rad($layerm->config->fill_angle));
my ($params, @polylines) = $f->fill_surface(
$surface,
density => $density/100,
flow => $flow,
layer_height => $h,
);
next unless @polylines;
my $mm3_per_mm = $flow->mm3_per_mm;
# save into layer
push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new;
$collection->no_sort($params->{no_sort});
$collection->append(
map Slic3r::ExtrusionPath->new(
polyline => $_,
role => ($is_bridge
? EXTR_ROLE_BRIDGE
: $is_solid
? (($surface->surface_type == S_TYPE_TOP) ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL)
: EXTR_ROLE_FILL),
mm3_per_mm => $mm3_per_mm,
width => $flow->width,
height => ($is_bridge ? $flow->width : $h),
), @polylines,
);
push @fills_ordering_points, $polylines[0]->first_point;
}
# add thin fill regions
foreach my $thin_fill (@{$layerm->thin_fills}) {
push @fills, Slic3r::ExtrusionPath::Collection->new($thin_fill);
push @fills_ordering_points, $thin_fill->first_point;
}
# organize infill paths using a nearest-neighbor search
@fills = @fills[ @{chained_path(\@fills_ordering_points)} ];
return @fills;
}
1;

View File

@@ -1,233 +0,0 @@
package Slic3r::Fill::3DHoneycomb;
use Moo;
extends 'Slic3r::Fill::Base';
use POSIX qw(ceil fmod);
use Slic3r::Geometry qw(scale scaled_epsilon);
use Slic3r::Geometry::Clipper qw(intersection_pl);
sub fill_surface {
my ($self, $surface, %params) = @_;
# use bridge flow since most of this pattern hangs in air
my $flow = Slic3r::Flow->new(
width => $params{flow}->width,
height => $params{flow}->height,
nozzle_diameter => $params{flow}->nozzle_diameter,
bridge => 1,
);
my $expolygon = $surface->expolygon;
my $bb = $expolygon->bounding_box;
my $size = $bb->size;
my $distance = $flow->scaled_spacing / $params{density};
# align bounding box to a multiple of our honeycomb grid
{
my $min = $bb->min_point;
$min->translate(
-($bb->x_min % $distance),
-($bb->y_min % $distance),
);
$bb->merge_point($min);
}
# generate pattern
my @polylines = map Slic3r::Polyline->new(@$_),
makeGrid(
scale($self->z),
$distance,
ceil($size->x / $distance),
ceil($size->y / $distance), #//
(($self->layer_id / $surface->thickness_layers) % 2) + 1,
);
# move pattern in place
$_->translate($bb->x_min, $bb->y_min) for @polylines;
# clip pattern to boundaries
@polylines = @{intersection_pl(\@polylines, \@$expolygon)};
# connect lines
unless ($params{dont_connect} || !@polylines) { # prevent calling leftmost_point() on empty collections
my ($expolygon_off) = @{$expolygon->offset_ex(scaled_epsilon)};
my $collection = Slic3r::Polyline::Collection->new(@polylines);
@polylines = ();
foreach my $polyline (@{$collection->chained_path_from($collection->leftmost_point, 0)}) {
# try to append this polyline to previous one if any
if (@polylines) {
my $line = Slic3r::Line->new($polylines[-1]->last_point, $polyline->first_point);
if ($line->length <= 1.5*$distance && $expolygon_off->contains_line($line)) {
$polylines[-1]->append_polyline($polyline);
next;
}
}
# make a clone before $collection goes out of scope
push @polylines, $polyline->clone;
}
}
# TODO: return ExtrusionLoop objects to get better chained paths
return { flow => $flow}, @polylines;
}
=head1 DESCRIPTION
Creates a contiguous sequence of points at a specified height that make
up a horizontal slice of the edges of a space filling truncated
octahedron tesselation. The octahedrons are oriented so that the
square faces are in the horizontal plane with edges parallel to the X
and Y axes.
Credits: David Eccles (gringer).
=head2 makeGrid(z, gridSize, gridWidth, gridHeight, curveType)
Generate a set of curves (array of array of 2d points) that describe a
horizontal slice of a truncated regular octahedron with a specified
grid square size.
=cut
sub makeGrid {
my ($z, $gridSize, $gridWidth, $gridHeight, $curveType) = @_;
my $scaleFactor = $gridSize;
my $normalisedZ = $z / $scaleFactor;
my @points = makeNormalisedGrid($normalisedZ, $gridWidth, $gridHeight, $curveType);
foreach my $lineRef (@points) {
foreach my $pointRef (@$lineRef) {
$pointRef->[0] *= $scaleFactor;
$pointRef->[1] *= $scaleFactor;
}
}
return @points;
}
=head1 FUNCTIONS
=cut
=head2 colinearPoints(offset, gridLength)
Generate an array of points that are in the same direction as the
basic printing line (i.e. Y points for columns, X points for rows)
Note: a negative offset only causes a change in the perpendicular
direction
=cut
sub colinearPoints {
my ($offset, $baseLocation, $gridLength) = @_;
my @points = ();
push @points, $baseLocation - abs($offset/2);
for (my $i = 0; $i < $gridLength; $i++) {
push @points, $baseLocation + $i + abs($offset/2);
push @points, $baseLocation + ($i+1) - abs($offset/2);
}
push @points, $baseLocation + $gridLength + abs($offset/2);
return @points;
}
=head2 colinearPoints(offset, baseLocation, gridLength)
Generate an array of points for the dimension that is perpendicular to
the basic printing line (i.e. X points for columns, Y points for rows)
=cut
sub perpendPoints {
my ($offset, $baseLocation, $gridLength) = @_;
my @points = ();
my $side = 2*(($baseLocation) % 2) - 1;
push @points, $baseLocation - $offset/2 * $side;
for (my $i = 0; $i < $gridLength; $i++) {
$side = 2*(($i+$baseLocation) % 2) - 1;
push @points, $baseLocation + $offset/2 * $side;
push @points, $baseLocation + $offset/2 * $side;
}
push @points, $baseLocation - $offset/2 * $side;
return @points;
}
=head2 trim(pointArrayRef, minX, minY, maxX, maxY)
Trims an array of points to specified rectangular limits. Point
components that are outside these limits are set to the limits.
=cut
sub trim {
my ($pointArrayRef, $minX, $minY, $maxX, $maxY) = @_;
foreach (@$pointArrayRef) {
$_->[0] = ($_->[0] < $minX) ? $minX : (($_->[0] > $maxX) ? $maxX : $_->[0]);
$_->[1] = ($_->[1] < $minY) ? $minY : (($_->[1] > $maxY) ? $maxY : $_->[1]);
}
}
=head2 makeNormalisedGrid(z, gridWidth, gridHeight, curveType)
Generate a set of curves (array of array of 2d points) that describe a
horizontal slice of a truncated regular octahedron with edge length 1.
curveType specifies which lines to print, 1 for vertical lines
(columns), 2 for horizontal lines (rows), and 3 for both.
=cut
sub makeNormalisedGrid {
my ($z, $gridWidth, $gridHeight, $curveType) = @_;
## offset required to create a regular octagram
my $octagramGap = 0.5;
# sawtooth wave function for range f($z) = [-$octagramGap .. $octagramGap]
my $a = sqrt(2); # period
my $wave = abs(fmod($z, $a) - $a/2)/$a*4 - 1;
my $offset = $wave * $octagramGap;
my @points = ();
if (($curveType & 1) != 0) {
for (my $x = 0; $x <= $gridWidth; $x++) {
my @xPoints = perpendPoints($offset, $x, $gridHeight);
my @yPoints = colinearPoints($offset, 0, $gridHeight);
# This is essentially @newPoints = zip(@xPoints, @yPoints)
my @newPoints = map [ $xPoints[$_], $yPoints[$_] ], 0..$#xPoints;
# trim points to grid edges
#trim(\@newPoints, 0, 0, $gridWidth, $gridHeight);
if ($x % 2 == 0){
push @points, [ @newPoints ];
} else {
push @points, [ reverse @newPoints ];
}
}
}
if (($curveType & 2) != 0) {
for (my $y = 0; $y <= $gridHeight; $y++) {
my @xPoints = colinearPoints($offset, 0, $gridWidth);
my @yPoints = perpendPoints($offset, $y, $gridWidth);
my @newPoints = map [ $xPoints[$_], $yPoints[$_] ], 0..$#xPoints;
# trim points to grid edges
#trim(\@newPoints, 0, 0, $gridWidth, $gridHeight);
if ($y % 2 == 0) {
push @points, [ @newPoints ];
} else {
push @points, [ reverse @newPoints ];
}
}
}
return @points;
}
1;

View File

@@ -1,7 +0,0 @@
package Slic3r::Fill::ArchimedeanChords;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::ArchimedeanChords;
1;

View File

@@ -1,86 +0,0 @@
package Slic3r::Fill::Base;
use Moo;
has 'layer_id' => (is => 'rw');
has 'z' => (is => 'rw'); # in unscaled coordinates
has 'angle' => (is => 'rw'); # in radians, ccw, 0 = East
has 'bounding_box' => (is => 'ro', required => 0); # Slic3r::Geometry::BoundingBox object
sub adjust_solid_spacing {
my $self = shift;
my %params = @_;
my $number_of_lines = int($params{width} / $params{distance}) + 1;
return $params{distance} if $number_of_lines <= 1;
my $extra_space = $params{width} % $params{distance};
return $params{distance} + $extra_space / ($number_of_lines - 1);
}
package Slic3r::Fill::WithDirection;
use Moo::Role;
use Slic3r::Geometry qw(PI rad2deg);
sub angles () { [0, PI/2] }
sub infill_direction {
my $self = shift;
my ($surface) = @_;
if (!defined $self->angle) {
warn "Using undefined infill angle";
$self->angle(0);
}
# set infill angle
my (@rotate);
$rotate[0] = $self->angle;
$rotate[1] = $self->bounding_box
? $self->bounding_box->center
: $surface->expolygon->bounding_box->center;
my $shift = $rotate[1]->clone;
if (defined $self->layer_id) {
# alternate fill direction
my $layer_num = $self->layer_id / $surface->thickness_layers;
my $angle = $self->angles->[$layer_num % @{$self->angles}];
$rotate[0] = $self->angle + $angle if $angle;
}
# use bridge angle
if ($surface->bridge_angle >= 0) {
Slic3r::debugf "Filling bridge with angle %d\n", rad2deg($surface->bridge_angle);
$rotate[0] = $surface->bridge_angle;
}
$rotate[0] += PI/2;
$shift->rotate(@rotate);
return [\@rotate, $shift];
}
# this method accepts any object that implements rotate() and translate()
sub rotate_points {
my $self = shift;
my ($expolygon, $rotate_vector) = @_;
# rotate points
my ($rotate, $shift) = @$rotate_vector;
$rotate = [ -$rotate->[0], $rotate->[1] ];
$expolygon->rotate(@$rotate);
$expolygon->translate(@$shift);
}
sub rotate_points_back {
my $self = shift;
my ($paths, $rotate_vector) = @_;
my ($rotate, $shift) = @$rotate_vector;
$shift = [ map -$_, @$shift ];
$_->translate(@$shift) for @$paths;
$_->rotate(@$rotate) for @$paths;
}
1;

View File

@@ -1,65 +0,0 @@
package Slic3r::Fill::Concentric;
use Moo;
extends 'Slic3r::Fill::Base';
use Slic3r::Geometry qw(scale unscale X);
use Slic3r::Geometry::Clipper qw(offset offset2 union_pt_chained);
sub fill_surface {
my $self = shift;
my ($surface, %params) = @_;
# no rotation is supported for this infill pattern
my $expolygon = $surface->expolygon;
my $bounding_box = $expolygon->bounding_box;
my $flow = $params{flow};
my $min_spacing = $flow->scaled_spacing;
my $distance = $min_spacing / $params{density};
my $flow_spacing = $flow->spacing;
if ($params{density} == 1 && !$params{dont_adjust}) {
$distance = $self->adjust_solid_spacing(
width => $bounding_box->size->[X],
distance => $distance,
);
$flow = Slic3r::Flow->new_from_spacing(
spacing => unscale($distance),
nozzle_diameter => $flow->nozzle_diameter,
layer_height => ($params{layer_height} or die "No layer_height supplied to fill_surface()"),
bridge => $flow->bridge,
);
}
# compensate the overlap which is good for rectilinear but harmful for concentric
# where the perimeter/infill spacing should be equal to any other loop spacing
my @loops = my @last = @{offset(\@$expolygon, -&Slic3r::INFILL_OVERLAP_OVER_SPACING * $min_spacing / 2)};
while (@last) {
push @loops, @last = @{offset2(\@last, -($distance + 0.5*$min_spacing), +0.5*$min_spacing)};
}
# generate paths from the outermost to the innermost, to avoid
# adhesion problems of the first central tiny loops
@loops = map Slic3r::Polygon->new(@$_),
reverse @{union_pt_chained(\@loops)};
# order paths using a nearest neighbor search
my @paths = ();
my $last_pos = Slic3r::Point->new(0,0);
foreach my $loop (@loops) {
push @paths, $loop->split_at_index($last_pos->nearest_point_index(\@$loop));
$last_pos = $paths[-1]->last_point;
}
# clip the paths to prevent the extruder from getting exactly on the first point of the loop
my $clip_length = scale($flow->nozzle_diameter) * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER;
$_->clip_end($clip_length) for @paths;
@paths = grep $_->is_valid, @paths; # remove empty paths (too short, thus eaten by clipping)
# TODO: return ExtrusionLoop objects to get better chained paths
return { flow => $flow, no_sort => 1 }, @paths;
}
1;

View File

@@ -1,18 +0,0 @@
package Slic3r::Fill::Flowsnake;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::Flowsnake;
use Slic3r::Geometry qw(X);
# Sorry, this fill is currently broken.
sub process_polyline {
my $self = shift;
my ($polyline, $bounding_box) = @_;
$_->[X] += $bounding_box->center->[X] for @$polyline;
}
1;

View File

@@ -1,7 +0,0 @@
package Slic3r::Fill::HilbertCurve;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::HilbertCurve;
1;

View File

@@ -1,129 +0,0 @@
package Slic3r::Fill::Honeycomb;
use Moo;
extends 'Slic3r::Fill::Base';
with qw(Slic3r::Fill::WithDirection);
has 'cache' => (is => 'rw', default => sub {{}});
use Slic3r::Geometry qw(PI X Y MIN MAX scale scaled_epsilon);
use Slic3r::Geometry::Clipper qw(intersection intersection_pl);
sub angles () { [0, PI/3, PI/3*2] }
sub fill_surface {
my $self = shift;
my ($surface, %params) = @_;
my $rotate_vector = $self->infill_direction($surface);
# cache hexagons math
my $cache_id = sprintf "d%s_s%s", $params{density}, $params{flow}->spacing;
my $m;
if (!($m = $self->cache->{$cache_id})) {
$m = $self->cache->{$cache_id} = {};
my $min_spacing = $params{flow}->scaled_spacing;
$m->{distance} = $min_spacing / $params{density};
$m->{hex_side} = $m->{distance} / (sqrt(3)/2);
$m->{hex_width} = $m->{distance} * 2; # $m->{hex_width} == $m->{hex_side} * sqrt(3);
my $hex_height = $m->{hex_side} * 2;
$m->{pattern_height} = $hex_height + $m->{hex_side};
$m->{y_short} = $m->{distance} * sqrt(3)/3;
$m->{x_offset} = $min_spacing / 2;
$m->{y_offset} = $m->{x_offset} * sqrt(3)/3;
$m->{hex_center} = Slic3r::Point->new($m->{hex_width}/2, $m->{hex_side});
}
my @polygons = ();
{
# adjust actual bounding box to the nearest multiple of our hex pattern
# and align it so that it matches across layers
my $bounding_box = $surface->expolygon->bounding_box;
{
# rotate bounding box according to infill direction
my $bb_polygon = $bounding_box->polygon;
$bb_polygon->rotate($rotate_vector->[0][0], $m->{hex_center});
$bounding_box = $bb_polygon->bounding_box;
# extend bounding box so that our pattern will be aligned with other layers
# $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
$bounding_box->merge_point(Slic3r::Point->new(
$bounding_box->x_min - ($bounding_box->x_min % $m->{hex_width}),
$bounding_box->y_min - ($bounding_box->y_min % $m->{pattern_height}),
));
}
my $x = $bounding_box->x_min;
while ($x <= $bounding_box->x_max) {
my $p = [];
my @x = ($x + $m->{x_offset}, $x + $m->{distance} - $m->{x_offset});
for (1..2) {
@$p = reverse @$p; # turn first half upside down
my @p = ();
for (my $y = $bounding_box->y_min; $y <= $bounding_box->y_max; $y += $m->{y_short} + $m->{hex_side} + $m->{y_short} + $m->{hex_side}) {
push @$p,
[ $x[1], $y + $m->{y_offset} ],
[ $x[0], $y + $m->{y_short} - $m->{y_offset} ],
[ $x[0], $y + $m->{y_short} + $m->{hex_side} + $m->{y_offset} ],
[ $x[1], $y + $m->{y_short} + $m->{hex_side} + $m->{y_short} - $m->{y_offset} ],
[ $x[1], $y + $m->{y_short} + $m->{hex_side} + $m->{y_short} + $m->{hex_side} + $m->{y_offset} ];
}
@x = map $_ + $m->{distance}, reverse @x; # draw symmetrical pattern
$x += $m->{distance};
}
push @polygons, Slic3r::Polygon->new(@$p);
}
$_->rotate(-$rotate_vector->[0][0], $m->{hex_center}) for @polygons;
}
my @paths;
if ($params{complete}) {
# we were requested to complete each loop;
# in this case we don't try to make more continuous paths
@paths = map $_->split_at_first_point,
@{intersection([ $surface->p ], \@polygons)};
} else {
# consider polygons as polylines without re-appending the initial point:
# this cuts the last segment on purpose, so that the jump to the next
# path is more straight
@paths = @{intersection_pl(
[ map Slic3r::Polyline->new(@$_), @polygons ],
[ @{$surface->expolygon} ],
)};
# connect paths
if (@paths) { # prevent calling leftmost_point() on empty collections
my $collection = Slic3r::Polyline::Collection->new(@paths);
@paths = ();
foreach my $path (@{$collection->chained_path_from($collection->leftmost_point, 0)}) {
if (@paths) {
# distance between first point of this path and last point of last path
my $distance = $paths[-1]->last_point->distance_to($path->first_point);
if ($distance <= $m->{hex_width}) {
$paths[-1]->append_polyline($path);
next;
}
}
# make a clone before $collection goes out of scope
push @paths, $path->clone;
}
}
# clip paths again to prevent connection segments from crossing the expolygon boundaries
@paths = @{intersection_pl(
\@paths,
[ map @$_, @{$surface->expolygon->offset_ex(scaled_epsilon)} ],
)};
}
return { flow => $params{flow} }, @paths;
}
1;

View File

@@ -1,8 +0,0 @@
package Slic3r::Fill::Line;
use Moo;
extends 'Slic3r::Fill::Rectilinear';
# Sorry for breaking OOP, but Line is implemented inside Rectilinear.
1;

View File

@@ -1,9 +0,0 @@
package Slic3r::Fill::OctagramSpiral;
use Moo;
extends 'Slic3r::Fill::PlanePath';
use Math::PlanePath::OctagramSpiral;
sub multiplier () { sqrt(2) }
1;

View File

@@ -1,62 +0,0 @@
package Slic3r::Fill::PlanePath;
use Moo;
extends 'Slic3r::Fill::Base';
with qw(Slic3r::Fill::WithDirection);
use Slic3r::Geometry qw(scale X1 Y1 X2 Y2);
use Slic3r::Geometry::Clipper qw(intersection_pl);
sub multiplier () { 1 }
sub get_n {
my $self = shift;
my ($path, $bounding_box) = @_;
my ($n_lo, $n_hi) = $path->rect_to_n_range(@$bounding_box);
return ($n_lo .. $n_hi);
}
sub process_polyline {}
sub fill_surface {
my $self = shift;
my ($surface, %params) = @_;
# rotate polygons
my $expolygon = $surface->expolygon->clone;
my $rotate_vector = $self->infill_direction($surface);
$self->rotate_points($expolygon, $rotate_vector);
my $flow = $params{flow};
my $distance_between_lines = $flow->scaled_spacing / $params{density} * $self->multiplier;
my $bounding_box = $expolygon->bounding_box;
(ref $self) =~ /::([^:]+)$/;
my $path = "Math::PlanePath::$1"->new;
my @n = $self->get_n($path, [ map +($_ / $distance_between_lines), @{$bounding_box->min_point}, @{$bounding_box->max_point} ]);
my $polyline = Slic3r::Polyline->new(
map [ map {$_*$distance_between_lines} $path->n_to_xy($_) ], @n,
);
return {} if @$polyline <= 1;
$self->process_polyline($polyline, $bounding_box);
my @paths = @{intersection_pl([$polyline], \@$expolygon)};
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output("fill.svg",
polygons => $expolygon,
polylines => [map $_->p, @paths],
);
}
# paths must be rotated back
$self->rotate_points_back(\@paths, $rotate_vector);
return { flow => $flow }, @paths;
}
1;

View File

@@ -1,111 +0,0 @@
package Slic3r::Fill::Rectilinear;
use Moo;
extends 'Slic3r::Fill::Base';
with qw(Slic3r::Fill::WithDirection);
has 'cache' => (is => 'rw', default => sub {{}});
use Slic3r::Geometry qw(A B X Y MIN scale unscale scaled_epsilon);
use Slic3r::Geometry::Clipper qw(intersection_pl offset);
sub fill_surface {
my $self = shift;
my ($surface, %params) = @_;
# rotate polygons so that we can work with vertical lines here
my $expolygon = $surface->expolygon->clone;
my $rotate_vector = $self->infill_direction($surface);
$self->rotate_points($expolygon, $rotate_vector);
my $flow = $params{flow} or die "No flow supplied to fill_surface()";
my $min_spacing = $flow->scaled_spacing;
my $line_spacing = $min_spacing / $params{density};
my $line_oscillation = $line_spacing - $min_spacing;
my $is_line_pattern = $self->isa('Slic3r::Fill::Line');
my $bounding_box = $expolygon->bounding_box;
# define flow spacing according to requested density
if ($params{density} == 1 && !$params{dont_adjust}) {
$line_spacing = $self->adjust_solid_spacing(
width => $bounding_box->size->[X],
distance => $line_spacing,
);
$flow = Slic3r::Flow->new_from_spacing(
spacing => unscale($line_spacing),
nozzle_diameter => $flow->nozzle_diameter,
layer_height => ($params{layer_height} or die "No layer_height supplied to fill_surface()"),
bridge => $flow->bridge,
);
} else {
# extend bounding box so that our pattern will be aligned with other layers
$bounding_box->merge_point(Slic3r::Point->new(
$bounding_box->x_min - ($bounding_box->x_min % $line_spacing),
$bounding_box->y_min - ($bounding_box->y_min % $line_spacing),
));
}
# generate the basic pattern
my $i = 0;
my $x = $bounding_box->x_min;
my $x_max = $bounding_box->x_max + scaled_epsilon;
my @vertical_lines = ();
while ($x <= $x_max) {
my $vertical_line = [ [$x, $bounding_box->y_max], [$x, $bounding_box->y_min] ];
if ($is_line_pattern && $i % 2) {
$vertical_line->[A][X] += $line_oscillation;
$vertical_line->[B][X] -= $line_oscillation;
}
push @vertical_lines, Slic3r::Polyline->new(@$vertical_line);
$i++;
$x += $line_spacing;
}
# clip paths against a slightly larger expolygon, so that the first and last paths
# are kept even if the expolygon has vertical sides
# the minimum offset for preventing edge lines from being clipped is scaled_epsilon;
# however we use a larger offset to support expolygons with slightly skewed sides and
# not perfectly straight
my @polylines = @{intersection_pl(\@vertical_lines, $expolygon->offset(scale 0.02))};
# connect lines
unless ($params{dont_connect} || !@polylines) { # prevent calling leftmost_point() on empty collections
my ($expolygon_off) = @{$expolygon->offset_ex($min_spacing/2)};
my $collection = Slic3r::Polyline::Collection->new(@polylines);
@polylines = ();
my $tolerance = 10 * scaled_epsilon;
my $diagonal_distance = $line_spacing * 2;
my $can_connect = $is_line_pattern
? sub {
($_[X] >= ($line_spacing - $line_oscillation) - $tolerance) && ($_[X] <= ($line_spacing + $line_oscillation) + $tolerance)
&& $_[Y] <= $diagonal_distance
}
: sub { $_[X] <= $diagonal_distance && $_[Y] <= $diagonal_distance };
foreach my $polyline (@{$collection->chained_path_from($collection->leftmost_point, 0)}) {
if (@polylines) {
my $first_point = $polyline->first_point;
my $last_point = $polylines[-1]->last_point;
my @distance = map abs($first_point->$_ - $last_point->$_), qw(x y);
# TODO: we should also check that both points are on a fill_boundary to avoid
# connecting paths on the boundaries of internal regions
if ($can_connect->(@distance) && $expolygon_off->contains_line(Slic3r::Line->new($last_point, $first_point))) {
$polylines[-1]->append_polyline($polyline);
next;
}
}
# make a clone before $collection goes out of scope
push @polylines, $polyline->clone;
}
}
# paths must be rotated back
$self->rotate_points_back(\@polylines, $rotate_vector);
return { flow => $flow }, @polylines;
}
1;

View File

@@ -1,128 +0,0 @@
package Slic3r::Format::AMF;
use Moo;
use Slic3r::Geometry qw(X Y Z);
sub read_file {
my $self = shift;
my ($file) = @_;
eval qq{
require Slic3r::Format::AMF::Parser;
use XML::SAX::ParserFactory;
1;
} or die "AMF parsing requires XML::SAX\n";
Slic3r::open(\my $fh, '<', $file) or die "Failed to open $file\n";
my $model = Slic3r::Model->new;
XML::SAX::ParserFactory
->parser(Handler => Slic3r::Format::AMF::Parser->new(_model => $model))
->parse_file($fh);
close $fh;
return $model;
}
sub write_file {
my $self = shift;
my ($file, $model, %params) = @_;
my %vertices_offset = ();
Slic3r::open(\my $fh, '>', $file);
binmode $fh, ':utf8';
printf $fh qq{<?xml version="1.0" encoding="UTF-8"?>\n};
printf $fh qq{<amf unit="millimeter">\n};
printf $fh qq{ <metadata type="cad">Slic3r %s</metadata>\n}, $Slic3r::VERSION;
for my $material_id (sort @{ $model->material_names }) {
my $material = $model->get_material($material_id);
printf $fh qq{ <material id="%s">\n}, $material_id;
for (keys %{$material->attributes}) {
printf $fh qq{ <metadata type=\"%s\">%s</metadata>\n}, $_, $material->attributes->{$_};
}
my $config = $material->config;
foreach my $opt_key (@{$config->get_keys}) {
printf $fh qq{ <metadata type=\"slic3r.%s\">%s</metadata>\n}, $opt_key, $config->serialize($opt_key);
}
printf $fh qq{ </material>\n};
}
my $instances = '';
for my $object_id (0 .. $#{ $model->objects }) {
my $object = $model->objects->[$object_id];
printf $fh qq{ <object id="%d">\n}, $object_id;
my $config = $object->config;
foreach my $opt_key (@{$config->get_keys}) {
printf $fh qq{ <metadata type=\"slic3r.%s\">%s</metadata>\n}, $opt_key, $config->serialize($opt_key);
}
if ($object->name) {
printf $fh qq{ <metadata type=\"name\">%s</metadata>\n}, $object->name;
}
printf $fh qq{ <mesh>\n};
printf $fh qq{ <vertices>\n};
my @vertices_offset = ();
{
my $vertices_offset = 0;
foreach my $volume (@{ $object->volumes }) {
push @vertices_offset, $vertices_offset;
my $vertices = $volume->mesh->vertices;
foreach my $vertex (@$vertices) {
printf $fh qq{ <vertex>\n};
printf $fh qq{ <coordinates>\n};
printf $fh qq{ <x>%s</x>\n}, $vertex->[X];
printf $fh qq{ <y>%s</y>\n}, $vertex->[Y];
printf $fh qq{ <z>%s</z>\n}, $vertex->[Z];
printf $fh qq{ </coordinates>\n};
printf $fh qq{ </vertex>\n};
}
$vertices_offset += scalar(@$vertices);
}
}
printf $fh qq{ </vertices>\n};
foreach my $volume (@{ $object->volumes }) {
my $vertices_offset = shift @vertices_offset;
printf $fh qq{ <volume%s>\n},
($volume->material_id eq '') ? '' : (sprintf ' materialid="%s"', $volume->material_id);
my $config = $volume->config;
foreach my $opt_key (@{$config->get_keys}) {
printf $fh qq{ <metadata type=\"slic3r.%s\">%s</metadata>\n}, $opt_key, $config->serialize($opt_key);
}
if ($volume->name) {
printf $fh qq{ <metadata type=\"name\">%s</metadata>\n}, $volume->name;
}
if ($volume->modifier) {
printf $fh qq{ <metadata type=\"slic3r.modifier\">1</metadata>\n};
}
foreach my $facet (@{$volume->mesh->facets}) {
printf $fh qq{ <triangle>\n};
printf $fh qq{ <v%d>%d</v%d>\n}, $_, $facet->[$_-1] + $vertices_offset, $_ for 1..3;
printf $fh qq{ </triangle>\n};
}
printf $fh qq{ </volume>\n};
}
printf $fh qq{ </mesh>\n};
printf $fh qq{ </object>\n};
if ($object->instances) {
foreach my $instance (@{$object->instances}) {
$instances .= sprintf qq{ <instance objectid="%d">\n}, $object_id;
$instances .= sprintf qq{ <deltax>%s</deltax>\n}, $instance->offset->[X];
$instances .= sprintf qq{ <deltay>%s</deltay>\n}, $instance->offset->[Y];
$instances .= sprintf qq{ <rz>%s</rz>\n}, $instance->rotation;
$instances .= sprintf qq{ </instance>\n};
}
}
}
if ($instances) {
printf $fh qq{ <constellation id="1">\n};
printf $fh $instances;
printf $fh qq{ </constellation>\n};
}
printf $fh qq{</amf>\n};
close $fh;
}
1;

View File

@@ -1,161 +0,0 @@
package Slic3r::Format::AMF::Parser;
use strict;
use warnings;
use base 'XML::SAX::Base';
my %xyz_index = (x => 0, y => 1, z => 2); #=
sub new {
my $self = shift->SUPER::new(@_);
$self->{_tree} = [];
$self->{_objects_map} = {}; # this hash maps AMF object IDs to object indexes in $model->objects
$self->{_instances} = {}; # apply these lazily to make sure all objects have been parsed
$self;
}
sub start_element {
my $self = shift;
my $data = shift;
if ($data->{LocalName} eq 'object') {
$self->{_object} = $self->{_model}->add_object;
$self->{_object_vertices} = [];
$self->{_objects_map}{ $self->_get_attribute($data, 'id') } = $#{ $self->{_model}->objects };
} elsif ($data->{LocalName} eq 'vertex') {
$self->{_vertex} = ["", "", ""];
} elsif ($self->{_vertex} && $data->{LocalName} =~ /^[xyz]$/ && $self->{_tree}[-1] eq 'coordinates') {
$self->{_coordinate} = $data->{LocalName};
} elsif ($data->{LocalName} eq 'volume') {
$self->{_volume} = $self->{_object}->add_volume(
material_id => $self->_get_attribute($data, 'materialid') // undef,
mesh => Slic3r::TriangleMesh->new,
);
$self->{_volume_facets} = [];
} elsif ($data->{LocalName} eq 'triangle') {
$self->{_triangle} = ["", "", ""];
} elsif ($self->{_triangle} && $data->{LocalName} =~ /^v([123])$/ && $self->{_tree}[-1] eq 'triangle') {
$self->{_vertex_idx} = $1-1;
} elsif ($data->{LocalName} eq 'material') {
my $material_id = $self->_get_attribute($data, 'id') // '_';
$self->{_material} = $self->{_model}->set_material($material_id);
} elsif ($data->{LocalName} eq 'metadata') {
$self->{_metadata_type} = $self->_get_attribute($data, 'type');
$self->{_metadata_value} = '';
} elsif ($data->{LocalName} eq 'constellation') {
$self->{_constellation} = 1; # we merge all constellations as we don't support more than one
} elsif ($data->{LocalName} eq 'instance' && $self->{_constellation}) {
my $object_id = $self->_get_attribute($data, 'objectid');
$self->{_instances}{$object_id} ||= [];
push @{ $self->{_instances}{$object_id} }, $self->{_instance} = {};
} elsif ($data->{LocalName} =~ /^(?:deltax|deltay|rz)$/ && $self->{_instance}) {
$self->{_instance_property} = $data->{LocalName};
}
push @{$self->{_tree}}, $data->{LocalName};
}
sub characters {
my $self = shift;
my $data = shift;
if ($self->{_vertex} && $self->{_coordinate}) {
$self->{_vertex}[ $xyz_index{$self->{_coordinate}} ] .= $data->{Data};
} elsif ($self->{_triangle} && defined $self->{_vertex_idx}) {
$self->{_triangle}[ $self->{_vertex_idx} ] .= $data->{Data};
} elsif ($self->{_metadata_type}) {
$self->{_metadata_value} .= $data->{Data};
} elsif ($self->{_instance_property}) {
$self->{_instance}{ $self->{_instance_property} } .= $data->{Data};
}
}
sub end_element {
my $self = shift;
my $data = shift;
pop @{$self->{_tree}};
if ($data->{LocalName} eq 'object') {
$self->{_object} = undef;
$self->{_object_vertices} = undef;
} elsif ($data->{LocalName} eq 'vertex') {
push @{$self->{_object_vertices}}, $self->{_vertex};
$self->{_vertex} = undef;
} elsif ($self->{_coordinate} && $data->{LocalName} =~ /^[xyz]$/) {
$self->{_coordinate} = undef;
} elsif ($data->{LocalName} eq 'volume') {
$self->{_volume}->mesh->ReadFromPerl($self->{_object_vertices}, $self->{_volume_facets});
$self->{_volume}->mesh->repair;
$self->{_volume} = undef;
$self->{_volume_facets} = undef;
} elsif ($data->{LocalName} eq 'triangle') {
push @{$self->{_volume_facets}}, $self->{_triangle};
$self->{_triangle} = undef;
} elsif (defined $self->{_vertex_idx} && $data->{LocalName} =~ /^v[123]$/) {
$self->{_vertex_idx} = undef;
} elsif ($data->{LocalName} eq 'material') {
$self->{_material} = undef;
} elsif ($data->{LocalName} eq 'metadata') {
my $value = $self->{_metadata_value};
if ($self->{_metadata_type} =~ /^slic3r\.(.+)/) {
my $opt_key = $1;
if (exists $Slic3r::Config::Options->{$opt_key}) {
my $config;
if ($self->{_material}) {
$config = $self->{_material}->config;
} elsif ($self->{_volume}) {
$config = $self->{_volume}->config;
} elsif ($self->{_object}) {
$config = $self->{_object}->config;
}
$config->set_deserialize($opt_key, $value) if defined $config;
} elsif ($opt_key eq 'modifier' && $self->{_volume}) {
$self->{_volume}->set_modifier($value);
}
} elsif ($self->{_metadata_type} eq 'name' && $self->{_volume}) {
$self->{_volume}->set_name($value);
} elsif ($self->{_metadata_type} eq 'name' && $self->{_object}) {
$self->{_object}->set_name($value);
} elsif ($self->{_material}) {
$self->{_material}->set_attribute($self->{_metadata_type}, $value);
}
$self->{_metadata_type} = undef;
$self->{_metadata_value} = undef;
} elsif ($data->{LocalName} eq 'constellation') {
$self->{_constellation} = undef;
} elsif ($data->{LocalName} eq 'instance') {
$self->{_instance} = undef;
} elsif ($data->{LocalName} =~ /^(?:deltax|deltay|rz)$/ && $self->{_instance}) {
$self->{_instance_property} = undef;
}
}
sub end_document {
my $self = shift;
foreach my $object_id (keys %{ $self->{_instances} }) {
my $new_object_id = $self->{_objects_map}{$object_id};
if (!defined $new_object_id) {
warn "Undefined object $object_id referenced in constellation\n";
next;
}
foreach my $instance (@{ $self->{_instances}{$object_id} }) {
$self->{_model}->objects->[$new_object_id]->add_instance(
rotation => $instance->{rz} || 0,
offset => Slic3r::Pointf->new($instance->{deltax} || 0, $instance->{deltay} || 0),
);
}
}
}
sub _get_attribute {
my $self = shift;
my ($data, $name) = @_;
return +(map $_->{Value}, grep $_->{Name} eq $name, values %{$data->{Attributes}})[0];
}
1;

View File

@@ -1,34 +0,0 @@
package Slic3r::Format::OBJ;
use Moo;
use File::Basename qw(basename);
sub read_file {
my $self = shift;
my ($file) = @_;
Slic3r::open(\my $fh, '<', $file) or die "Failed to open $file\n";
my $vertices = [];
my $facets = [];
while (<$fh>) {
if (/^v ([^ ]+)\s+([^ ]+)\s+([^ ]+)/) {
push @$vertices, [$1, $2, $3];
} elsif (/^f (\d+).*? (\d+).*? (\d+).*?/) {
push @$facets, [ $1-1, $2-1, $3-1 ];
}
}
close $fh;
my $mesh = Slic3r::TriangleMesh->new;
$mesh->ReadFromPerl($vertices, $facets);
$mesh->repair;
my $model = Slic3r::Model->new;
my $basename = basename($file);
my $object = $model->add_object(input_file => $file, name => $basename);
my $volume = $object->add_volume(mesh => $mesh, name => $basename);
return $model;
}
1;

View File

@@ -1,38 +0,0 @@
package Slic3r::Format::STL;
use Moo;
use File::Basename qw(basename);
sub read_file {
my $self = shift;
my ($file) = @_;
my $path = Slic3r::encode_path($file);
die "Failed to open $file\n" if !-e $path;
my $mesh = Slic3r::TriangleMesh->new;
$mesh->ReadSTLFile($path);
$mesh->repair;
my $model = Slic3r::Model->new;
my $basename = basename($file);
my $object = $model->add_object(input_file => $file, name => $basename);
my $volume = $object->add_volume(mesh => $mesh, name => $basename);
return $model;
}
sub write_file {
my $self = shift;
my ($file, $mesh, %params) = @_;
$mesh = $mesh->mesh if $mesh->isa('Slic3r::Model');
my $path = Slic3r::encode_path($file);
$params{binary}
? $mesh->write_binary($path)
: $mesh->write_ascii($path);
}
1;

View File

@@ -1,713 +0,0 @@
package Slic3r::GCode;
use Moo;
use List::Util qw(min max first);
use Slic3r::ExtrusionLoop ':roles';
use Slic3r::ExtrusionPath ':roles';
use Slic3r::Flow ':roles';
use Slic3r::Geometry qw(epsilon scale unscale scaled_epsilon points_coincide PI X Y B);
use Slic3r::Geometry::Clipper qw(union_ex offset_ex);
use Slic3r::Surface ':types';
has 'config' => (is => 'ro', default => sub { Slic3r::Config::Full->new });
has 'placeholder_parser' => (is => 'rw', default => sub { Slic3r::GCode::PlaceholderParser->new });
has 'standby_points' => (is => 'rw');
has 'enable_loop_clipping' => (is => 'rw', default => sub {1});
has 'enable_wipe' => (is => 'rw', default => sub {0}); # at least one extruder has wipe enabled
has 'layer_count' => (is => 'ro', required => 1 );
has '_layer_index' => (is => 'rw', default => sub {-1}); # just a counter
has 'layer' => (is => 'rw');
has '_layer_islands' => (is => 'rw');
has '_upper_layer_islands' => (is => 'rw');
has '_seam_position' => (is => 'ro', default => sub { {} }); # $object => pos
has 'shift_x' => (is => 'rw', default => sub {0} );
has 'shift_y' => (is => 'rw', default => sub {0} );
has 'z' => (is => 'rw');
has 'extruders' => (is => 'ro', default => sub {{}});
has 'multiple_extruders' => (is => 'rw', default => sub {0});
has 'extruder' => (is => 'rw');
has 'external_mp' => (is => 'rw');
has 'layer_mp' => (is => 'rw');
has 'new_object' => (is => 'rw', default => sub {0});
has 'straight_once' => (is => 'rw', default => sub {1});
has 'elapsed_time' => (is => 'rw', default => sub {0} ); # seconds
has 'lifted' => (is => 'rw', default => sub {0} );
has 'last_pos' => (is => 'rw', default => sub { Slic3r::Point->new(0,0) } );
has 'last_fan_speed' => (is => 'rw', default => sub {0});
has 'last_acceleration' => (is => 'rw', default => sub {0});
has 'wipe_path' => (is => 'rw');
sub set_extruders {
my ($self, $extruder_ids, $print_config) = @_;
foreach my $i (@$extruder_ids) {
$self->extruders->{$i} = my $e = Slic3r::Extruder->new($i, $print_config);
$self->enable_wipe(1) if $e->wipe;
}
# we enable support for multiple extruder if any extruder greater than 0 is used
# (even if prints only uses that one) since we need to output Tx commands
# first extruder has index 0
$self->multiple_extruders(max(@$extruder_ids) > 0);
}
sub set_shift {
my ($self, @shift) = @_;
# if shift increases (goes towards right), last_pos decreases because it goes towards left
my @translate = (
scale ($self->shift_x - $shift[X]),
scale ($self->shift_y - $shift[Y]),
);
$self->last_pos->translate(@translate);
$self->wipe_path->translate(@translate) if $self->wipe_path;
$self->shift_x($shift[X]);
$self->shift_y($shift[Y]);
}
sub change_layer {
my ($self, $layer) = @_;
$self->layer($layer);
$self->_layer_index($self->_layer_index + 1);
# avoid computing islands and overhangs if they're not needed
$self->_layer_islands($layer->islands);
$self->_upper_layer_islands($layer->upper_layer ? $layer->upper_layer->islands : []);
if ($self->config->avoid_crossing_perimeters) {
$self->layer_mp(Slic3r::MotionPlanner->new(
union_ex([ map @$_, @{$layer->slices} ], 1),
));
}
my $gcode = "";
if ($self->config->gcode_flavor =~ /^(?:makerware|sailfish)$/) {
# TODO: cap this to 99% and add an explicit M73 P100 in the end G-code
$gcode .= sprintf "M73 P%s%s\n",
int(99 * ($self->_layer_index / ($self->layer_count - 1))),
($self->config->gcode_comments ? ' ; update progress' : '');
}
$gcode .= $self->move_z($layer->print_z);
return $gcode;
}
# this method accepts Z in unscaled coordinates
sub move_z {
my ($self, $z, $comment) = @_;
my $gcode = "";
$z += $self->config->z_offset;
my $current_z = $self->z;
my $nominal_z = defined $current_z ? ($current_z - $self->lifted) : undef;
if (!defined $current_z || $z > $current_z || $z < $nominal_z) {
# we're moving above the current actual Z (so above the lift height of the current
# layer if any) or below the current nominal layer
# in both cases, we're going to the nominal Z of the next layer
$self->lifted(0);
if ($self->extruder->retract_layer_change) {
# this retraction may alter $self->z
$gcode .= $self->retract(move_z => $z);
$current_z = $self->z; # update current z in case retract() changed it
$nominal_z = defined $current_z ? ($current_z - $self->lifted) : undef;
}
$gcode .= $self->G0(undef, $z, 0, $self->config->travel_speed*60, $comment || ('move to next layer (' . $self->layer->id . ')'))
if !defined $current_z || abs($z - $nominal_z) > epsilon;
} elsif ($z < $current_z) {
# we're moving above the current nominal layer height and below the current actual one.
# we're basically advancing to next layer, whose nominal Z is still lower than the previous
# layer Z with lift.
$self->lifted($current_z - $z);
}
return $gcode;
}
sub extrude {
my $self = shift;
$_[0]->isa('Slic3r::ExtrusionLoop')
? $self->extrude_loop(@_)
: $self->extrude_path(@_);
}
sub extrude_loop {
my ($self, $loop, $description, $speed) = @_;
# make a copy; don't modify the orientation of the original loop object otherwise
# next copies (if any) would not detect the correct orientation
$loop = $loop->clone;
# extrude all loops ccw
my $was_clockwise = $loop->make_counter_clockwise;
# find the point of the loop that is closest to the current extruder position
# or randomize if requested
my $last_pos = $self->last_pos;
if ($self->config->spiral_vase) {
$loop->split_at($last_pos);
} elsif ($self->config->seam_position eq 'nearest' || $self->config->seam_position eq 'aligned') {
# simplify polygon in order to skip false positives in concave/convex detection
my $polygon = $loop->polygon;
my @simplified = @{$polygon->simplify(scale $self->extruder->nozzle_diameter/2)};
# concave vertices have priority
my @candidates = map @{$_->concave_points(PI*4/3)}, @simplified;
# if no concave points were found, look for convex vertices
@candidates = map @{$_->convex_points(PI*2/3)}, @simplified if !@candidates;
# retrieve the last start position for this object
my $obj_ptr;
if (defined $self->layer) {
$obj_ptr = $self->layer->object->ptr;
if (defined $self->_seam_position->{$self->layer->object}) {
$last_pos = $self->_seam_position->{$obj_ptr};
}
}
my $point;
if ($self->config->seam_position eq 'nearest') {
@candidates = @$polygon if !@candidates;
$point = $last_pos->nearest_point(\@candidates);
$loop->split_at_vertex($point);
} elsif (@candidates) {
my @non_overhang = grep !$loop->has_overhang_point($_), @candidates;
@candidates = @non_overhang if @non_overhang;
$point = $last_pos->nearest_point(\@candidates);
$loop->split_at_vertex($point);
} else {
$point = $last_pos->projection_onto_polygon($polygon);
$loop->split_at($point);
}
$self->_seam_position->{$obj_ptr} = $point;
} elsif ($self->config->seam_position eq 'random') {
if ($loop->role == EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER) {
my $polygon = $loop->polygon;
my $centroid = $polygon->centroid;
$last_pos = Slic3r::Point->new($polygon->bounding_box->x_max, $centroid->y); #))
$last_pos->rotate(rand(2*PI), $centroid);
}
$loop->split_at($last_pos);
}
# clip the path to avoid the extruder to get exactly on the first point of the loop;
# if polyline was shorter than the clipping distance we'd get a null polyline, so
# we discard it in that case
my $clip_length = $self->enable_loop_clipping
? scale($self->extruder->nozzle_diameter) * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER
: 0;
# get paths
my @paths = @{$loop->clip_end($clip_length)};
return '' if !@paths;
# apply the small perimeter speed
if ($paths[0]->is_perimeter && $loop->length <= &Slic3r::SMALL_PERIMETER_LENGTH) {
$speed //= $self->config->get_abs_value('small_perimeter_speed');
}
$speed //= -1;
# extrude along the path
my $gcode = join '', map $self->_extrude_path($_, $description, $speed), @paths;
# reset acceleration
$gcode .= $self->set_acceleration($self->config->default_acceleration);
$self->wipe_path($paths[-1]->polyline->clone) if $self->enable_wipe; # TODO: don't limit wipe to last path
# make a little move inwards before leaving loop
if ($paths[-1]->role == EXTR_ROLE_EXTERNAL_PERIMETER && defined $self->layer && $self->config->perimeters > 1) {
my $last_path_polyline = $paths[-1]->polyline;
# detect angle between last and first segment
# the side depends on the original winding order of the polygon (left for contours, right for holes)
my @points = $was_clockwise ? (-2, 1) : (1, -2);
my $angle = Slic3r::Geometry::angle3points(@$last_path_polyline[0, @points]) / 3;
$angle *= -1 if $was_clockwise;
# create the destination point along the first segment and rotate it
# we make sure we don't exceed the segment length because we don't know
# the rotation of the second segment so we might cross the object boundary
my $first_segment = Slic3r::Line->new(@$last_path_polyline[0,1]);
my $distance = min(scale($self->extruder->nozzle_diameter), $first_segment->length);
my $point = $first_segment->point_at($distance);
$point->rotate($angle, $last_path_polyline->first_point);
# generate the travel move
$gcode .= $self->travel_to($point, $paths[-1]->role, "move inwards before travel");
}
return $gcode;
}
sub extrude_path {
my ($self, $path, $description, $speed) = @_;
my $gcode = $self->_extrude_path($path, $description, $speed);
# reset acceleration
$gcode .= $self->set_acceleration($self->config->default_acceleration);
return $gcode;
}
sub _extrude_path {
my ($self, $path, $description, $speed) = @_;
$path->simplify(&Slic3r::SCALED_RESOLUTION);
# go to first point of extrusion path
my $gcode = "";
{
my $first_point = $path->first_point;
$gcode .= $self->travel_to($first_point, $path->role, "move to first $description point")
if !defined $self->last_pos || !$self->last_pos->coincides_with($first_point);
}
# compensate retraction
$gcode .= $self->unretract;
# adjust acceleration
{
my $acceleration;
if ($self->config->first_layer_acceleration && $self->layer->id == 0) {
$acceleration = $self->config->first_layer_acceleration;
} elsif ($self->config->perimeter_acceleration && $path->is_perimeter) {
$acceleration = $self->config->perimeter_acceleration;
} elsif ($self->config->infill_acceleration && $path->is_fill) {
$acceleration = $self->config->infill_acceleration;
} elsif ($self->config->infill_acceleration && $path->is_bridge) {
$acceleration = $self->config->bridge_acceleration;
} else {
$acceleration = $self->config->default_acceleration;
}
$gcode .= $self->set_acceleration($acceleration);
}
# calculate extrusion length per distance unit
my $e = $self->extruder->e_per_mm3 * $path->mm3_per_mm;
$e = 0 if !$self->config->get_extrusion_axis;
# set speed
my $F;
if ($path->role == EXTR_ROLE_PERIMETER) {
$F = $self->config->get_abs_value('perimeter_speed');
} elsif ($path->role == EXTR_ROLE_EXTERNAL_PERIMETER) {
$F = $self->config->get_abs_value('external_perimeter_speed');
} elsif ($path->role == EXTR_ROLE_OVERHANG_PERIMETER || $path->role == EXTR_ROLE_BRIDGE) {
$F = $self->config->get_abs_value('bridge_speed');
} elsif ($path->role == EXTR_ROLE_FILL) {
$F = $self->config->get_abs_value('infill_speed');
} elsif ($path->role == EXTR_ROLE_SOLIDFILL) {
$F = $self->config->get_abs_value('solid_infill_speed');
} elsif ($path->role == EXTR_ROLE_TOPSOLIDFILL) {
$F = $self->config->get_abs_value('top_solid_infill_speed');
} elsif ($path->role == EXTR_ROLE_GAPFILL) {
$F = $self->config->get_abs_value('gap_fill_speed');
} else {
$F = $speed // -1;
die "Invalid speed" if $F < 0; # $speed == -1
}
$F *= 60; # convert mm/sec to mm/min
if ($self->layer->id == 0) {
$F = $self->config->get_abs_value_over('first_layer_speed', $F/60) * 60;
}
# extrude arc or line
$gcode .= ";_BRIDGE_FAN_START\n" if $path->is_bridge;
my $path_length = unscale $path->length;
{
$gcode .= $path->gcode($self->extruder, $e, $F,
$self->shift_x - $self->extruder->extruder_offset->x,
$self->shift_y - $self->extruder->extruder_offset->y, #,,
$self->config->get_extrusion_axis,
$self->config->gcode_comments ? " ; $description" : "");
if ($self->enable_wipe) {
$self->wipe_path($path->polyline->clone);
$self->wipe_path->reverse;
}
}
$gcode .= ";_BRIDGE_FAN_END\n" if $path->is_bridge;
$self->last_pos($path->last_point);
if ($self->config->cooling) {
my $path_time = $path_length / $F * 60;
$self->elapsed_time($self->elapsed_time + $path_time);
}
return $gcode;
}
sub travel_to {
my ($self, $point, $role, $comment) = @_;
my $gcode = "";
my $travel = Slic3r::Line->new($self->last_pos, $point);
# move travel back to original layer coordinates for the island check.
# note that we're only considering the current object's islands, while we should
# build a more complete configuration space
$travel->translate(-$self->shift_x, -$self->shift_y);
# skip retraction if the travel move is contained in an island in the current layer
# *and* in an island in the upper layer (so that the ooze will not be visible)
if ($travel->length < scale $self->extruder->retract_before_travel
|| ($self->config->only_retract_when_crossing_perimeters
&& $self->config->fill_density > 0
&& (first { $_->contains_line($travel) } @{$self->_upper_layer_islands})
&& (first { $_->contains_line($travel) } @{$self->_layer_islands}))
|| (defined $role && $role == EXTR_ROLE_SUPPORTMATERIAL && (first { $_->contains_line($travel) } @{$self->layer->support_islands}))
) {
$self->straight_once(0);
$gcode .= $self->G0($point, undef, 0, $self->config->travel_speed*60, $comment || "");
} elsif (!$self->config->avoid_crossing_perimeters || $self->straight_once) {
$self->straight_once(0);
$gcode .= $self->retract;
$gcode .= $self->G0($point, undef, 0, $self->config->travel_speed*60, $comment || "");
} else {
if ($self->new_object) {
$self->new_object(0);
# represent $point in G-code coordinates
$point = $point->clone;
my @shift = ($self->shift_x, $self->shift_y);
$point->translate(map scale $_, @shift);
# calculate path (external_mp uses G-code coordinates so we temporary need a null shift)
$self->set_shift(0,0);
$gcode .= $self->_plan($self->external_mp, $point, $comment);
$self->set_shift(@shift);
} else {
$gcode .= $self->_plan($self->layer_mp, $point, $comment);
}
}
return $gcode;
}
sub _plan {
my ($self, $mp, $point, $comment) = @_;
my $gcode = "";
my @travel = @{$mp->shortest_path($self->last_pos, $point)->lines};
# if the path is not contained in a single island we need to retract
my $need_retract = !$self->config->only_retract_when_crossing_perimeters;
if (!$need_retract) {
$need_retract = 1;
foreach my $island (@{$self->_upper_layer_islands}) {
# discard the island if at any line is not enclosed in it
next if first { !$island->contains_line($_) } @travel;
# okay, this island encloses the full travel path
$need_retract = 0;
last;
}
}
# do the retract (the travel_to argument is broken)
$gcode .= $self->retract if $need_retract;
# append the actual path and return
# use G1 because we rely on paths being straight (G0 may make round paths)
$gcode .= join '', map $self->G1($_->b, undef, 0, $self->config->travel_speed*60, $comment || ""), @travel;
return $gcode;
}
sub retract {
my ($self, %params) = @_;
# get the retraction length and abort if none
my ($length, $restart_extra, $comment) = $params{toolchange}
? ($self->extruder->retract_length_toolchange, $self->extruder->retract_restart_extra_toolchange, "retract for tool change")
: ($self->extruder->retract_length, $self->extruder->retract_restart_extra, "retract");
# if we already retracted, reduce the required amount of retraction
$length -= $self->extruder->retracted;
return "" unless $length > 0;
my $gcode = "";
# wipe
my $wipe_path;
if ($self->extruder->wipe && $self->wipe_path) {
my @points = @{$self->wipe_path};
$wipe_path = Slic3r::Polyline->new($self->last_pos, @{$self->wipe_path}[1..$#{$self->wipe_path}]);
$wipe_path->clip_end($wipe_path->length - $self->extruder->scaled_wipe_distance($self->config->travel_speed));
}
# prepare moves
my $retract = [undef, undef, -$length, $self->extruder->retract_speed_mm_min, $comment];
my $lift = ($self->config->retract_lift->[0] == 0 || defined $params{move_z}) && !$self->lifted
? undef
: [undef, $self->z + $self->config->retract_lift->[0], 0, $self->config->travel_speed*60, 'lift plate during travel'];
# check that we have a positive wipe length
if ($wipe_path) {
# subdivide the retraction
my $retracted = 0;
foreach my $line (@{$wipe_path->lines}) {
my $segment_length = $line->length;
# reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one
# due to rounding
my $e = $retract->[2] * ($segment_length / $self->extruder->scaled_wipe_distance($self->config->travel_speed)) * 0.95;
$retracted += $e;
$gcode .= $self->G1($line->b, undef, $e, $self->config->travel_speed*60*0.8, $retract->[3] . ";_WIPE");
}
if ($retracted > $retract->[2]) {
# if we retracted less than we had to, retract the remainder
# TODO: add regression test
$gcode .= $self->G1(undef, undef, $retract->[2] - $retracted, $self->extruder->retract_speed_mm_min, $comment);
}
$gcode .= $self->reset_e;
} elsif ($self->config->use_firmware_retraction) {
$gcode .= "G10 ; retract\n";
} else {
$gcode .= $self->G1(@$retract);
# reset extrusion distance during retracts
# this makes sure we leave sufficient precision in the firmware
$gcode .= $self->reset_e;
}
if (!$self->lifted) {
if (defined $params{move_z} && $self->config->retract_lift->[0] > 0) {
my $travel = [undef, $params{move_z} + $self->config->retract_lift->[0], 0, $self->config->travel_speed*60, 'move to next layer (' . $self->layer->id . ') and lift'];
$gcode .= $self->G0(@$travel);
$self->lifted($self->config->retract_lift->[0]);
} elsif ($lift) {
$gcode .= $self->G1(@$lift);
}
}
$self->extruder->set_retracted($self->extruder->retracted + $length);
$self->extruder->set_restart_extra($restart_extra);
$self->lifted($self->config->retract_lift->[0]) if $lift;
$gcode .= "M103 ; extruder off\n" if $self->config->gcode_flavor eq 'makerware';
return $gcode;
}
sub unretract {
my ($self) = @_;
my $gcode = "";
$gcode .= "M101 ; extruder on\n" if $self->config->gcode_flavor eq 'makerware';
if ($self->lifted) {
$gcode .= $self->G0(undef, $self->z - $self->lifted, 0, $self->config->travel_speed*60, 'restore layer Z');
$self->lifted(0);
}
my $to_unretract = $self->extruder->retracted + $self->extruder->restart_extra;
if ($to_unretract) {
if ($self->config->use_firmware_retraction) {
$gcode .= "G11 ; unretract\n";
$gcode .= $self->reset_e;
} elsif ($self->config->get_extrusion_axis) {
# use G1 instead of G0 because G0 will blend the restart with the previous travel move
$gcode .= sprintf "G1 %s%.5f F%.3f",
$self->config->get_extrusion_axis,
$self->extruder->extrude($to_unretract),
$self->extruder->retract_speed_mm_min;
$gcode .= " ; compensate retraction" if $self->config->gcode_comments;
$gcode .= "\n";
}
$self->extruder->set_retracted(0);
$self->extruder->set_restart_extra(0);
}
return $gcode;
}
sub reset_e {
my ($self) = @_;
return "" if $self->config->gcode_flavor =~ /^(?:mach3|makerware|sailfish)$/;
$self->extruder->set_E(0) if $self->extruder;
return sprintf "G92 %s0%s\n", $self->config->get_extrusion_axis, ($self->config->gcode_comments ? ' ; reset extrusion distance' : '')
if $self->config->get_extrusion_axis && !$self->config->use_relative_e_distances;
}
sub set_acceleration {
my ($self, $acceleration) = @_;
return "" if !$acceleration || $acceleration == $self->last_acceleration;
$self->last_acceleration($acceleration);
return sprintf "M204 S%s%s\n",
$acceleration, ($self->config->gcode_comments ? ' ; adjust acceleration' : '');
}
sub G0 {
my $self = shift;
return $self->G1(@_) if !($self->config->g0 || $self->config->gcode_flavor eq 'mach3');
return $self->_G0_G1("G0", @_);
}
sub G1 {
my $self = shift;
return $self->_G0_G1("G1", @_);
}
sub _G0_G1 {
my ($self, $gcode, $point, $z, $e, $F, $comment) = @_;
if ($point) {
$gcode .= sprintf " X%.3f Y%.3f",
($point->x * &Slic3r::SCALING_FACTOR) + $self->shift_x - $self->extruder->extruder_offset->x,
($point->y * &Slic3r::SCALING_FACTOR) + $self->shift_y - $self->extruder->extruder_offset->y; #**
$self->last_pos($point->clone);
}
if (defined $z && (!defined $self->z || $z != $self->z)) {
$self->z($z);
$gcode .= sprintf " Z%.3f", $z;
}
return $self->_Gx($gcode, $e, $F, $comment);
}
sub _Gx {
my ($self, $gcode, $e, $F, $comment) = @_;
$gcode .= sprintf " F%.3f", $F;
# output extrusion distance
if ($e && $self->config->get_extrusion_axis) {
$gcode .= sprintf " %s%.5f", $self->config->get_extrusion_axis, $self->extruder->extrude($e);
}
$gcode .= " ; $comment" if $comment && $self->config->gcode_comments;
return "$gcode\n";
}
sub set_extruder {
my ($self, $extruder_id) = @_;
# return nothing if this extruder was already selected
return "" if (defined $self->extruder) && ($self->extruder->id == $extruder_id);
# if we are running a single-extruder setup, just set the extruder and return nothing
if (!$self->multiple_extruders) {
$self->extruder($self->extruders->{$extruder_id});
return "";
}
# trigger retraction on the current extruder (if any)
my $gcode = "";
$gcode .= $self->retract(toolchange => 1) if defined $self->extruder;
# append custom toolchange G-code
if (defined $self->extruder && $self->config->toolchange_gcode) {
$gcode .= sprintf "%s\n", $self->placeholder_parser->process($self->config->toolchange_gcode, {
previous_extruder => $self->extruder->id,
next_extruder => $extruder_id,
});
}
# set the current extruder to the standby temperature
if ($self->standby_points && defined $self->extruder) {
# move to the nearest standby point
{
my $last_pos = $self->last_pos->clone;
$last_pos->translate(scale +$self->shift_x, scale +$self->shift_y);
my $standby_point = $last_pos->nearest_point($self->standby_points);
$standby_point->translate(scale -$self->shift_x, scale -$self->shift_y);
$gcode .= $self->travel_to($standby_point);
}
if ($self->config->standby_temperature_delta != 0) {
my $temp = defined $self->layer && $self->layer->id == 0
? $self->extruder->first_layer_temperature
: $self->extruder->temperature;
# we assume that heating is always slower than cooling, so no need to block
$gcode .= $self->set_temperature($temp + $self->config->standby_temperature_delta, 0);
}
}
# set the new extruder
$self->extruder($self->extruders->{$extruder_id});
$gcode .= sprintf "%s%d%s\n",
($self->config->gcode_flavor eq 'makerware'
? 'M135 T'
: $self->config->gcode_flavor eq 'sailfish'
? 'M108 T'
: 'T'),
$extruder_id,
($self->config->gcode_comments ? ' ; change extruder' : '');
$gcode .= $self->reset_e;
# set the new extruder to the operating temperature
if ($self->config->ooze_prevention && $self->config->standby_temperature_delta != 0) {
my $temp = defined $self->layer && $self->layer->id == 0
? $self->extruder->first_layer_temperature
: $self->extruder->temperature;
$gcode .= $self->set_temperature($temp, 1);
}
return $gcode;
}
sub set_fan {
my ($self, $speed, $dont_save) = @_;
if ($self->last_fan_speed != $speed || $dont_save) {
$self->last_fan_speed($speed) if !$dont_save;
if ($speed == 0) {
my $code = $self->config->gcode_flavor eq 'teacup'
? 'M106 S0'
: $self->config->gcode_flavor =~ /^(?:makerware|sailfish)$/
? 'M127'
: 'M107';
return sprintf "$code%s\n", ($self->config->gcode_comments ? ' ; disable fan' : '');
} else {
if ($self->config->gcode_flavor =~ /^(?:makerware|sailfish)$/) {
return sprintf "M126%s\n", ($self->config->gcode_comments ? ' ; enable fan' : '');
} else {
return sprintf "M106 %s%d%s\n", ($self->config->gcode_flavor eq 'mach3' ? 'P' : 'S'),
(255 * $speed / 100), ($self->config->gcode_comments ? ' ; enable fan' : '');
}
}
}
return "";
}
sub set_temperature {
my ($self, $temperature, $wait, $tool) = @_;
return "" if $wait && $self->config->gcode_flavor =~ /^(?:makerware|sailfish)$/;
my ($code, $comment) = ($wait && $self->config->gcode_flavor ne 'teacup')
? ('M109', 'wait for temperature to be reached')
: ('M104', 'set temperature');
my $gcode = sprintf "$code %s%d %s; $comment\n",
($self->config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature,
(defined $tool && ($self->multiple_extruders || $self->config->gcode_flavor =~ /^(?:makerware|sailfish)$/)) ? "T$tool " : "";
$gcode .= "M116 ; wait for temperature to be reached\n"
if $self->config->gcode_flavor eq 'teacup' && $wait;
return $gcode;
}
sub set_bed_temperature {
my ($self, $temperature, $wait) = @_;
my ($code, $comment) = ($wait && $self->config->gcode_flavor ne 'teacup')
? (($self->config->gcode_flavor =~ /^(?:makerware|sailfish)$/ ? 'M109' : 'M190'), 'wait for bed temperature to be reached')
: ('M140', 'set bed temperature');
my $gcode = sprintf "$code %s%d ; $comment\n",
($self->config->gcode_flavor eq 'mach3' ? 'P' : 'S'), $temperature;
$gcode .= "M116 ; wait for bed temperature to be reached\n"
if $self->config->gcode_flavor eq 'teacup' && $wait;
return $gcode;
}
1;

View File

@@ -1,242 +0,0 @@
package Slic3r::GCode::ArcFitting;
use Moo;
use Slic3r::Geometry qw(X Y PI scale unscale epsilon scaled_epsilon deg2rad angle3points);
extends 'Slic3r::GCode::Reader';
has 'config' => (is => 'ro', required => 0);
has 'min_segments' => (is => 'rw', default => sub { 2 });
has 'min_total_angle' => (is => 'rw', default => sub { deg2rad(30) });
has 'max_relative_angle' => (is => 'rw', default => sub { deg2rad(15) });
has 'len_epsilon' => (is => 'rw', default => sub { scale 0.2 });
has 'angle_epsilon' => (is => 'rw', default => sub { abs(deg2rad(10)) });
has '_extrusion_axis' => (is => 'lazy');
has '_path' => (is => 'rw');
has '_cur_F' => (is => 'rw');
has '_cur_E' => (is => 'rw');
has '_cur_E0' => (is => 'rw');
has '_comment' => (is => 'rw');
sub _build__extrusion_axis {
my ($self) = @_;
return $self->config ? $self->config->get_extrusion_axis : 'E';
}
sub process {
my $self = shift;
my ($gcode) = @_;
die "Arc fitting is not available (incomplete feature)\n";
die "Arc fitting doesn't support extrusion axis not being E\n" if $self->_extrusion_axis ne 'E';
my $new_gcode = "";
$self->parse($gcode, sub {
my ($reader, $cmd, $args, $info) = @_;
if ($info->{extruding} && $info->{dist_XY} > 0) {
# this is an extrusion segment
# get segment
my $line = Slic3r::Line->new(
Slic3r::Point->new_scale($self->X, $self->Y),
Slic3r::Point->new_scale($args->{X}, $args->{Y}),
);
# get segment speed
my $F = $args->{F} // $reader->F;
# get extrusion per unscaled distance unit
my $e = $info->{dist_E} / unscale($line->length);
if ($self->_path && $F == $self->_cur_F && abs($e - $self->_cur_E) < epsilon) {
# if speed and extrusion per unit are the same as the previous segments,
# append this segment to path
$self->_path->append($line->b);
} elsif ($self->_path) {
# segment can't be appended to previous path, so we flush the previous one
# and start over
$new_gcode .= $self->path_to_gcode;
$self->_path(undef);
}
if (!$self->_path) {
# if this is the first segment of a path, start it from scratch
$self->_path(Slic3r::Polyline->new(@$line));
$self->_cur_F($F);
$self->_cur_E($e);
$self->_cur_E0($self->E);
$self->_comment($info->{comment});
}
} else {
# if we have a path, we flush it and go on
$new_gcode .= $self->path_to_gcode if $self->_path;
$new_gcode .= $info->{raw} . "\n";
$self->_path(undef);
}
});
$new_gcode .= $self->path_to_gcode if $self->_path;
return $new_gcode;
}
sub path_to_gcode {
my ($self) = @_;
my @chunks = $self->detect_arcs($self->_path);
my $gcode = "";
my $E = $self->_cur_E0;
foreach my $chunk (@chunks) {
if ($chunk->isa('Slic3r::Polyline')) {
my @lines = @{$chunk->lines};
$gcode .= sprintf "G1 F%s\n", $self->_cur_F;
foreach my $line (@lines) {
$E += $self->_cur_E * unscale($line->length);
$gcode .= sprintf "G1 X%.3f Y%.3f %s%.5f",
(map unscale($_), @{$line->b}),
$self->_extrusion_axis, $E;
$gcode .= sprintf " ; %s", $self->_comment if $self->_comment;
$gcode .= "\n";
}
} elsif ($chunk->isa('Slic3r::GCode::ArcFitting::Arc')) {
$gcode .= !$chunk->is_ccw ? "G2" : "G3";
$gcode .= sprintf " X%.3f Y%.3f", map unscale($_), @{$chunk->end}; # destination point
# XY distance of the center from the start position
$gcode .= sprintf " I%.3f", unscale($chunk->center->[X] - $chunk->start->[X]);
$gcode .= sprintf " J%.3f", unscale($chunk->center->[Y] - $chunk->start->[Y]);
$E += $self->_cur_E * unscale($chunk->length);
$gcode .= sprintf " %s%.5f", $self->_extrusion_axis, $E;
$gcode .= sprintf " F%s\n", $self->_cur_F;
}
}
return $gcode;
}
sub detect_arcs {
my ($self, $path) = @_;
my @chunks = ();
my @arc_points = ();
my $polyline = undef;
my $arc_start = undef;
my @points = @$path;
for (my $i = 1; $i <= $#points; ++$i) {
my $end = undef;
# we need at least three points to check whether they form an arc
if ($i < $#points) {
my $len = $points[$i-1]->distance_to($points[$i]);
my $rel_angle = PI - angle3points(@points[$i, $i-1, $i+1]);
if (abs($rel_angle) <= $self->max_relative_angle) {
for (my $j = $i+1; $j <= $#points; ++$j) {
# check whether @points[($i-1)..$j] form an arc
last if abs($points[$j-1]->distance_to($points[$j]) - $len) > $self->len_epsilon;
last if abs(PI - angle3points(@points[$j-1, $j-2, $j]) - $rel_angle) > $self->angle_epsilon;
$end = $j;
}
}
}
if (defined $end && ($end - $i + 1) >= $self->min_segments) {
my $arc = polyline_to_arc(Slic3r::Polyline->new(@points[($i-1)..$end]));
if (1||$arc->angle >= $self->min_total_angle) {
push @chunks, $arc;
# continue scanning after arc points
$i = $end;
next;
}
}
# if last chunk was a polyline, append to it
if (@chunks && $chunks[-1]->isa('Slic3r::Polyline')) {
$chunks[-1]->append($points[$i]);
} else {
push @chunks, Slic3r::Polyline->new(@points[($i-1)..$i]);
}
}
return @chunks;
}
sub polyline_to_arc {
my ($polyline) = @_;
my @points = @$polyline;
my $is_ccw = $points[2]->ccw(@points[0,1]) > 0;
# to find the center, we intersect the perpendicular lines
# passing by first and last vertex;
# a better method would be to draw all the perpendicular lines
# and find the centroid of the enclosed polygon, or to
# intersect multiple lines and find the centroid of the convex hull
# around the intersections
my $arc_center;
{
my $first_ray = Slic3r::Line->new(@points[0,1]);
$first_ray->rotate(PI/2 * ($is_ccw ? 1 : -1), $points[0]);
my $last_ray = Slic3r::Line->new(@points[-2,-1]);
$last_ray->rotate(PI/2 * ($is_ccw ? -1 : 1), $points[-1]);
# require non-parallel rays in order to compute an accurate center
return if abs($first_ray->atan2_ - $last_ray->atan2_) < deg2rad(30);
$arc_center = $first_ray->intersection($last_ray, 0) or return;
}
# angle measured in ccw orientation
my $abs_angle = Slic3r::Geometry::angle3points($arc_center, @points[0,-1]);
my $rel_angle = $is_ccw
? $abs_angle
: (2*PI - $abs_angle);
my $arc = Slic3r::GCode::ArcFitting::Arc->new(
start => $points[0]->clone,
end => $points[-1]->clone,
center => $arc_center,
is_ccw => $is_ccw || 0,
angle => $rel_angle,
);
if (0) {
printf "points = %d, path length = %f, arc angle = %f, arc length = %f\n",
scalar(@points),
unscale(Slic3r::Polyline->new(@points)->length),
Slic3r::Geometry::rad2deg($rel_angle),
unscale($arc->length);
}
return $arc;
}
package Slic3r::GCode::ArcFitting::Arc;
use Moo;
has 'start' => (is => 'ro', required => 1);
has 'end' => (is => 'ro', required => 1);
has 'center' => (is => 'ro', required => 1);
has 'is_ccw' => (is => 'ro', required => 1);
has 'angle' => (is => 'ro', required => 1);
sub radius {
my ($self) = @_;
return $self->start->distance_to($self->center);
}
sub length {
my ($self) = @_;
return $self->radius * $self->angle;
}
1;

View File

@@ -1,80 +0,0 @@
package Slic3r::GCode::CoolingBuffer;
use Moo;
has 'config' => (is => 'ro', required => 1); # Slic3r::Config::Print
has 'gcodegen' => (is => 'ro', required => 1);
has 'gcode' => (is => 'rw', default => sub {""});
has 'elapsed_time' => (is => 'rw', default => sub {0});
has 'layer_id' => (is => 'rw');
has 'last_z' => (is => 'rw', default => sub { {} }); # obj_id => z (basically a 'last seen' table)
has 'min_print_speed' => (is => 'lazy');
sub _build_min_print_speed {
my $self = shift;
return 60 * $self->config->min_print_speed;
}
sub append {
my $self = shift;
my ($gcode, $obj_id, $layer_id, $print_z) = @_;
my $return = "";
if (exists $self->last_z->{$obj_id} && $self->last_z->{$obj_id} != $print_z) {
$return = $self->flush;
}
$self->layer_id($layer_id);
$self->last_z->{$obj_id} = $print_z;
$self->gcode($self->gcode . $gcode);
$self->elapsed_time($self->elapsed_time + $self->gcodegen->elapsed_time);
$self->gcodegen->elapsed_time(0);
return $return;
}
sub flush {
my $self = shift;
my $gcode = $self->gcode;
my $elapsed = $self->elapsed_time;
$self->gcode("");
$self->elapsed_time(0);
$self->last_z({}); # reset the whole table otherwise we would compute overlapping times
my $fan_speed = $self->config->fan_always_on ? $self->config->min_fan_speed : 0;
my $speed_factor = 1;
if ($self->config->cooling) {
Slic3r::debugf "Layer %d estimated printing time: %d seconds\n", $self->layer_id, $elapsed;
if ($elapsed < $self->config->slowdown_below_layer_time) {
$fan_speed = $self->config->max_fan_speed;
$speed_factor = $elapsed / $self->config->slowdown_below_layer_time;
} elsif ($elapsed < $self->config->fan_below_layer_time) {
$fan_speed = $self->config->max_fan_speed - ($self->config->max_fan_speed - $self->config->min_fan_speed)
* ($elapsed - $self->config->slowdown_below_layer_time)
/ ($self->config->fan_below_layer_time - $self->config->slowdown_below_layer_time); #/
}
Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100;
if ($speed_factor < 1) {
$gcode =~ s/^(?=.*? [XY])(?=.*? E)(?!;_WIPE)(?<!;_BRIDGE_FAN_START\n)(G1 .*?F)(\d+(?:\.\d+)?)/
my $new_speed = $2 * $speed_factor;
$1 . sprintf("%.3f", $new_speed < $self->min_print_speed ? $self->min_print_speed : $new_speed)
/gexm;
}
}
$fan_speed = 0 if $self->layer_id < $self->config->disable_fan_first_layers;
$gcode = $self->gcodegen->set_fan($fan_speed) . $gcode;
# bridge fan speed
if (!$self->config->cooling || $self->config->bridge_fan_speed == 0 || $self->layer_id < $self->config->disable_fan_first_layers) {
$gcode =~ s/^;_BRIDGE_FAN_(?:START|END)\n//gm;
} else {
$gcode =~ s/^;_BRIDGE_FAN_START\n/ $self->gcodegen->set_fan($self->config->bridge_fan_speed, 1) /gmex;
$gcode =~ s/^;_BRIDGE_FAN_END\n/ $self->gcodegen->set_fan($fan_speed, 1) /gmex;
}
$gcode =~ s/;_WIPE//g;
return $gcode;
}
1;

View File

@@ -1,238 +0,0 @@
package Slic3r::GCode::Layer;
use Moo;
use List::Util qw(first);
use Slic3r::Geometry qw(X Y unscale);
has 'print' => (is => 'ro', required => 1);
has 'gcodegen' => (is => 'ro', required => 1, handles => [qw(extruders)]);
has 'shift' => (is => 'ro', default => sub { [0,0] });
has 'spiralvase' => (is => 'lazy');
has 'vibration_limit' => (is => 'lazy');
has 'arc_fitting' => (is => 'lazy');
has 'skirt_done' => (is => 'rw', default => sub { {} }); # print_z => 1
has 'brim_done' => (is => 'rw');
has 'second_layer_things_done' => (is => 'rw');
has '_last_obj_copy' => (is => 'rw');
sub _build_spiralvase {
my $self = shift;
return $self->print->config->spiral_vase
? Slic3r::GCode::SpiralVase->new(config => $self->print->config)
: undef;
}
sub _build_vibration_limit {
my $self = shift;
return $self->print->config->vibration_limit
? Slic3r::GCode::VibrationLimit->new(config => $self->print->config)
: undef;
}
sub _build_arc_fitting {
my $self = shift;
return $self->print->config->gcode_arcs
? Slic3r::GCode::ArcFitting->new(config => $self->print->config)
: undef;
}
sub process_layer {
my $self = shift;
my ($layer, $object_copies) = @_;
my $gcode = "";
my $object = $layer->object;
$self->gcodegen->config->apply_object_config($object->config);
# check whether we're going to apply spiralvase logic
if (defined $self->spiralvase) {
$self->spiralvase->enable(
($layer->id > 0 || $self->print->config->brim_width == 0)
&& ($layer->id >= $self->print->config->skirt_height && $self->print->config->skirt_height != -1)
&& !defined(first { $_->config->bottom_solid_layers > $layer->id } @{$layer->regions})
&& !defined(first { @{$_->perimeters} > 1 } @{$layer->regions})
&& !defined(first { @{$_->fills} > 0 } @{$layer->regions})
);
}
# if we're going to apply spiralvase to this layer, disable loop clipping
$self->gcodegen->enable_loop_clipping(!defined $self->spiralvase || !$self->spiralvase->enable);
if (!$self->second_layer_things_done && $layer->id == 1) {
for my $extruder_id (sort keys %{$self->extruders}) {
my $extruder = $self->extruders->{$extruder_id};
$gcode .= $self->gcodegen->set_temperature($extruder->temperature, 0, $extruder->id)
if $extruder->temperature && $extruder->temperature != $extruder->first_layer_temperature;
}
$gcode .= $self->gcodegen->set_bed_temperature($self->print->config->bed_temperature)
if $self->print->config->bed_temperature && $self->print->config->bed_temperature != $self->print->config->first_layer_bed_temperature;
$self->second_layer_things_done(1);
}
# set new layer - this will change Z and force a retraction if retract_layer_change is enabled
$gcode .= $self->gcodegen->change_layer($layer);
$gcode .= $self->gcodegen->placeholder_parser->process($self->print->config->layer_gcode, {
layer_num => $self->gcodegen->layer->id,
}) . "\n" if $self->print->config->layer_gcode;
# extrude skirt
if (((values %{$self->skirt_done}) < $self->print->config->skirt_height || $self->print->config->skirt_height == -1)
&& !$self->skirt_done->{$layer->print_z}) {
$self->gcodegen->set_shift(@{$self->shift});
my @extruder_ids = sort keys %{$self->extruders};
$gcode .= $self->gcodegen->set_extruder($extruder_ids[0]);
# skip skirt if we have a large brim
if ($layer->id < $self->print->config->skirt_height || $self->print->config->skirt_height == -1) {
# distribute skirt loops across all extruders
my @skirt_loops = @{$self->print->skirt};
for my $i (0 .. $#skirt_loops) {
# when printing layers > 0 ignore 'min_skirt_length' and
# just use the 'skirts' setting; also just use the current extruder
last if ($layer->id > 0) && ($i >= $self->print->config->skirts);
my $extruder_id = $extruder_ids[($i/@extruder_ids) % @extruder_ids];
$gcode .= $self->gcodegen->set_extruder($extruder_id)
if $layer->id == 0;
$gcode .= $self->gcodegen->extrude_loop($skirt_loops[$i], 'skirt', $object->config->support_material_speed);
}
}
$self->skirt_done->{$layer->print_z} = 1;
$self->gcodegen->straight_once(1);
}
# extrude brim
if (!$self->brim_done) {
$gcode .= $self->gcodegen->set_extruder($self->print->objects->[0]->config->support_material_extruder-1);
$self->gcodegen->set_shift(@{$self->shift});
$gcode .= $self->gcodegen->extrude_loop($_, 'brim', $object->config->support_material_speed)
for @{$self->print->brim};
$self->brim_done(1);
$self->gcodegen->straight_once(1);
}
for my $copy (@$object_copies) {
$self->gcodegen->new_object(1) if ($self->_last_obj_copy // '') ne "$copy";
$self->_last_obj_copy("$copy");
$self->gcodegen->set_shift(map $self->shift->[$_] + unscale $copy->[$_], X,Y);
# extrude support material before other things because it might use a lower Z
# and also because we avoid travelling on other things when printing it
if ($layer->isa('Slic3r::Layer::Support')) {
if ($layer->support_interface_fills->count > 0) {
$gcode .= $self->gcodegen->set_extruder($object->config->support_material_interface_extruder-1);
$gcode .= $self->gcodegen->extrude_path($_, 'support material interface', $object->config->get_abs_value('support_material_interface_speed'))
for @{$layer->support_interface_fills->chained_path_from($self->gcodegen->last_pos, 0)};
}
if ($layer->support_fills->count > 0) {
$gcode .= $self->gcodegen->set_extruder($object->config->support_material_extruder-1);
$gcode .= $self->gcodegen->extrude_path($_, 'support material', $object->config->get_abs_value('support_material_speed'))
for @{$layer->support_fills->chained_path_from($self->gcodegen->last_pos, 0)};
}
}
# tweak region ordering to save toolchanges
my @region_ids = 0 .. ($self->print->region_count-1);
if ($self->gcodegen->multiple_extruders) {
my $last_extruder = $self->gcodegen->extruder;
my $best_region_id = first { $self->print->regions->[$_]->config->perimeter_extruder-1 eq $last_extruder } @region_ids;
@region_ids = ($best_region_id, grep $_ != $best_region_id, @region_ids) if $best_region_id;
}
foreach my $region_id (@region_ids) {
my $layerm = $layer->regions->[$region_id] or next;
my $region = $self->print->regions->[$region_id];
$self->gcodegen->config->apply_region_config($region->config);
# group extrusions by island
my @perimeters_by_island = map [], 0..$#{$layer->slices}; # slice idx => @perimeters
my @infill_by_island = map [], 0..$#{$layer->slices}; # slice idx => @fills
# NOTE: we assume $layer->slices was already ordered with chained_path()!
PERIMETER: foreach my $perimeter (@{$layerm->perimeters}) {
for my $i (0 .. $#{$layer->slices}-1) {
if ($layer->slices->[$i]->contour->contains_point($perimeter->first_point)) {
push @{ $perimeters_by_island[$i] }, $perimeter;
next PERIMETER;
}
}
push @{ $perimeters_by_island[-1] }, $perimeter; # optimization
}
FILL: foreach my $fill (@{$layerm->fills}) {
for my $i (0 .. $#{$layer->slices}-1) {
if ($layer->slices->[$i]->contour->contains_point($fill->first_point)) {
push @{ $infill_by_island[$i] }, $fill;
next FILL;
}
}
push @{ $infill_by_island[-1] }, $fill; # optimization
}
for my $i (0 .. $#{$layer->slices}) {
# give priority to infill if we were already using its extruder and it wouldn't
# be good for perimeters
if ($self->print->config->infill_first
|| ($self->gcodegen->multiple_extruders && $region->config->infill_extruder-1 == $self->gcodegen->extruder->id && $region->config->infill_extruder != $region->config->perimeter_extruder)) {
$gcode .= $self->_extrude_infill($infill_by_island[$i], $region);
$gcode .= $self->_extrude_perimeters($perimeters_by_island[$i], $region);
} else {
$gcode .= $self->_extrude_perimeters($perimeters_by_island[$i], $region);
$gcode .= $self->_extrude_infill($infill_by_island[$i], $region);
}
}
}
}
# apply spiral vase post-processing if this layer contains suitable geometry
# (we must feed all the G-code into the post-processor, including the first
# bottom non-spiral layers otherwise it will mess with positions)
$gcode = $self->spiralvase->process_layer($gcode)
if defined $self->spiralvase;
# apply vibration limit if enabled
$gcode = $self->vibration_limit->process($gcode)
if $self->print->config->vibration_limit != 0;
# apply arc fitting if enabled
$gcode = $self->arc_fitting->process($gcode)
if $self->print->config->gcode_arcs;
return $gcode;
}
sub _extrude_perimeters {
my $self = shift;
my ($island_perimeters, $region) = @_;
return "" if !@$island_perimeters;
my $gcode = "";
$gcode .= $self->gcodegen->set_extruder($region->config->perimeter_extruder-1);
$gcode .= $self->gcodegen->extrude($_, 'perimeter') for @$island_perimeters;
return $gcode;
}
sub _extrude_infill {
my $self = shift;
my ($island_fills, $region) = @_;
return "" if !@$island_fills;
my $gcode = "";
$gcode .= $self->gcodegen->set_extruder($region->config->infill_extruder-1);
for my $fill (@$island_fills) {
if ($fill->isa('Slic3r::ExtrusionPath::Collection')) {
$gcode .= $self->gcodegen->extrude($_, 'fill')
for @{$fill->chained_path_from($self->gcodegen->last_pos, 0)};
} else {
$gcode .= $self->gcodegen->extrude($fill, 'fill') ;
}
}
return $gcode;
}
1;

View File

@@ -1,317 +0,0 @@
package Slic3r::GCode::MotionPlanner;
use Moo;
has 'islands' => (is => 'ro', required => 1); # arrayref of ExPolygons
has 'internal' => (is => 'ro', default => sub { 1 });
has '_space' => (is => 'ro', default => sub { Slic3r::GCode::MotionPlanner::ConfigurationSpace->new });
has '_inner' => (is => 'ro', default => sub { [] }); # arrayref of ExPolygons
use List::Util qw(first max);
use Slic3r::Geometry qw(A B scale epsilon);
use Slic3r::Geometry::Clipper qw(offset offset_ex diff_ex intersection_pl);
# clearance (in mm) from the perimeters
has '_inner_margin' => (is => 'ro', default => sub { scale 1 });
has '_outer_margin' => (is => 'ro', default => sub { scale 2 });
# this factor weigths the crossing of a perimeter
# vs. the alternative path. a value of 5 means that
# a perimeter will be crossed if the alternative path
# is >= 5x the length of the straight line we could
# follow if we decided to cross the perimeter.
# a nearly-infinite value for this will only permit
# perimeter crossing when there's no alternative path.
use constant CROSSING_PENALTY => 20;
use constant POINT_DISTANCE => 10; # unscaled
# setup our configuration space
sub BUILD {
my $self = shift;
my $point_distance = scale POINT_DISTANCE;
my $nodes = $self->_space->nodes;
my $edges = $self->_space->edges;
# process individual islands
for my $i (0 .. $#{$self->islands}) {
my $expolygon = $self->islands->[$i];
# find external margin
my $outer = offset([ @$expolygon ], +$self->_outer_margin);
my @outer_points = map @{$_->equally_spaced_points($point_distance)}, @$outer;
# add outer points to graph
my $o_outer = $self->_space->add_nodes(@outer_points);
# find pairs of visible outer points and add them to the graph
for my $i (0 .. $#outer_points) {
for my $j (($i+1) .. $#outer_points) {
my ($a, $b) = ($outer_points[$i], $outer_points[$j]);
my $line = Slic3r::Polyline->new($a, $b);
# outer points are visible when their line has empty intersection with islands
my $intersection = intersection_pl(
[ $line ],
[ map @$_, @{$self->islands} ],
);
if (!@$intersection) {
$self->_space->add_edge($i+$o_outer, $j+$o_outer, $line->length);
}
}
}
if ($self->internal) {
# find internal margin
my $inner = offset_ex([ @$expolygon ], -$self->_inner_margin);
push @{ $self->_inner }, @$inner;
my @inner_points = map @{$_->equally_spaced_points($point_distance)}, map @$_, @$inner;
# add points to graph and get their offset
my $o_inner = $self->_space->add_nodes(@inner_points);
# find pairs of visible inner points and add them to the graph
for my $i (0 .. $#inner_points) {
for my $j (($i+1) .. $#inner_points) {
my ($a, $b) = ($inner_points[$i], $inner_points[$j]);
my $line = Slic3r::Line->new($a, $b);
# turn $inner into an ExPolygonCollection and use $inner->contains_line()
if (first { $_->contains_line($line) } @$inner) {
$self->_space->add_edge($i+$o_inner, $j+$o_inner, $line->length);
}
}
}
# generate the stripe around slice contours
my $contour = diff_ex(
$outer,
[ map @$_, @$inner ],
);
# find pairs of visible points in this area and add them to the graph
for my $i (0 .. $#inner_points) {
for my $j (0 .. $#outer_points) {
my ($a, $b) = ($inner_points[$i], $outer_points[$j]);
my $line = Slic3r::Line->new($a, $b);
# turn $contour into an ExPolygonCollection and use $contour->contains_line()
if (first { $_->contains_line($line) } @$contour) {
$self->_space->add_edge($i+$o_inner, $j+$o_outer, $line->length * CROSSING_PENALTY);
}
}
}
}
}
# since Perl has no infinity symbol and we don't want to overcomplicate
# the Dijkstra algorithm with string constants or -1 values
$self->_space->_infinity(10 * (max(map values %$_, values %{$self->_space->edges}) // 0));
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output("space.svg",
no_arrows => 1,
expolygons => $self->islands,
lines => $self->_space->get_lines,
points => $self->_space->nodes,
);
printf "%d islands\n", scalar @{$self->islands};
eval "use Devel::Size";
print "MEMORY USAGE:\n";
printf " %-19s = %.1fMb\n", $_, Devel::Size::total_size($self->$_)/1024/1024
for qw(_space islands);
printf " %-19s = %.1fMb\n", $_, Devel::Size::total_size($self->_space->$_)/1024/1024
for qw(nodes edges);
printf " %-19s = %.1fMb\n", 'self', Devel::Size::total_size($self)/1024/1024;
exit if $self->internal;
}
}
sub shortest_path {
my $self = shift;
my ($from, $to) = @_;
return Slic3r::Polyline->new($from, $to)
if !@{$self->_space->nodes};
# create a temporary configuration space
my $space = $self->_space->clone;
# add from/to points to the temporary configuration space
my $node_from = $self->_add_point_to_space($from, $space);
my $node_to = $self->_add_point_to_space($to, $space);
# compute shortest path
my $path = $space->shortest_path($node_from, $node_to);
if (!$path->is_valid) {
Slic3r::debugf "Failed to compute shortest path.\n";
return Slic3r::Polyline->new($from, $to);
}
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output("path.svg",
no_arrows => 1,
expolygons => $self->islands,
lines => $space->get_lines,
red_points => [$from, $to],
red_polylines => [$path],
);
exit;
}
return $path;
}
# returns the index of the new node
sub _add_point_to_space {
my ($self, $point, $space) = @_;
my $n = $space->add_nodes($point);
# check whether we are inside an island or outside
my $inside = defined first { $self->islands->[$_]->contains_point($point) } 0..$#{$self->islands};
# find candidates by checking visibility from $from to them
foreach my $idx (0..$#{$space->nodes}) {
my $line = Slic3r::Line->new($point, $space->nodes->[$idx]);
# if $point is inside an island, it is visible from $idx when island contains their line
# if $point is outside an island, it is visible from $idx when their line does not cross any island
if (
($inside && defined first { $_->contains_line($line) } @{$self->_inner})
|| (!$inside && !@{intersection_pl(
[ $line->as_polyline ],
[ map @$_, @{$self->islands} ],
)})
) {
# $n ($point) and $idx are visible
$space->add_edge($n, $idx, $line->length);
}
}
# if we found no visibility, retry with larger margins
if (!exists $space->edges->{$n} && $inside) {
foreach my $idx (0..$#{$space->nodes}) {
my $line = Slic3r::Line->new($point, $space->nodes->[$idx]);
if (defined first { $_->contains_line($line) } @{$self->islands}) {
# $n ($point) and $idx are visible
$space->add_edge($n, $idx, $line->length);
}
}
}
warn "Temporary node is not visible from any other node"
if !exists $space->edges->{$n};
return $n;
}
package Slic3r::GCode::MotionPlanner::ConfigurationSpace;
use Moo;
has 'nodes' => (is => 'rw', default => sub { [] }); # [ Point, ... ]
has 'edges' => (is => 'rw', default => sub { {} }); # node_idx => { node_idx => distance, ... }
has '_infinity' => (is => 'rw');
sub clone {
my $self = shift;
return (ref $self)->new(
nodes => [ map $_->clone, @{$self->nodes} ],
edges => { map { $_ => { %{$self->edges->{$_}} } } keys %{$self->edges} },
_infinity => $self->_infinity,
);
}
sub nodes_count {
my $self = shift;
return scalar(@{ $self->nodes });
}
sub add_nodes {
my ($self, @nodes) = @_;
my $offset = $self->nodes_count;
push @{ $self->nodes }, @nodes;
return $offset;
}
sub add_edge {
my ($self, $a, $b, $dist) = @_;
$self->edges->{$a}{$b} = $self->edges->{$b}{$a} = $dist;
}
sub shortest_path {
my ($self, $node_from, $node_to) = @_;
my $edges = $self->edges;
my (%dist, %visited, %prev);
$dist{$_} = $self->_infinity for keys %$edges;
$dist{$node_from} = 0;
my @queue = ($node_from);
while (@queue) {
my $u = -1;
{
# find node in @queue with smallest distance in %dist and has not been visited
my $d = -1;
foreach my $n (@queue) {
next if $visited{$n};
if ($u == -1 || $dist{$n} < $d) {
$u = $n;
$d = $dist{$n};
}
}
}
last if $u == $node_to;
# remove $u from @queue
@queue = grep $_ != $u, @queue;
$visited{$u} = 1;
# loop through neighbors of $u
foreach my $v (keys %{ $edges->{$u} }) {
my $alt = $dist{$u} + $edges->{$u}{$v};
if ($alt < $dist{$v}) {
$dist{$v} = $alt;
$prev{$v} = $u;
if (!$visited{$v}) {
push @queue, $v;
}
}
}
}
my @points = ();
{
my $u = $node_to;
while (exists $prev{$u}) {
unshift @points, $self->nodes->[$u];
$u = $prev{$u};
}
unshift @points, $self->nodes->[$node_from];
}
return Slic3r::Polyline->new(@points);
}
# for debugging purposes
sub get_lines {
my $self = shift;
my @lines = ();
my %lines = ();
for my $i (keys %{$self->edges}) {
for my $j (keys %{$self->edges->{$i}}) {
my $line_id = join '_', sort $i, $j;
next if $lines{$line_id};
$lines{$line_id} = 1;
push @lines, Slic3r::Line->new(map $self->nodes->[$_], $i, $j);
}
}
return [@lines];
}
1;

View File

@@ -1,62 +0,0 @@
package Slic3r::GCode::PlaceholderParser;
use strict;
use warnings;
sub new {
# TODO: move this code to C++ constructor, remove this method
my ($class) = @_;
my $self = $class->_new;
$self->apply_env_variables;
$self->update_timestamp;
return $self;
}
sub apply_env_variables {
my ($self) = @_;
$self->_single_set($_, $ENV{$_}) for grep /^SLIC3R_/, keys %ENV;
}
sub update_timestamp {
my ($self) = @_;
my @lt = localtime; $lt[5] += 1900; $lt[4] += 1;
$self->_single_set('timestamp', sprintf '%04d%02d%02d-%02d%02d%02d', @lt[5,4,3,2,1,0]);
$self->_single_set('year', "$lt[5]");
$self->_single_set('month', "$lt[4]");
$self->_single_set('day', "$lt[3]");
$self->_single_set('hour', "$lt[2]");
$self->_single_set('minute', "$lt[1]");
$self->_single_set('second', "$lt[0]");
$self->_single_set('version', $Slic3r::VERSION);
}
# TODO: or this could be an alias
sub set {
my ($self, $key, $val) = @_;
$self->_single_set($key, $val);
}
sub process {
my ($self, $string, $extra) = @_;
# extra variables have priority over the stored ones
if ($extra) {
my $regex = join '|', keys %$extra;
$string =~ s/\[($regex)\]/$extra->{$1}/eg;
}
{
my $regex = join '|', @{$self->_single_keys};
$string =~ s/\[($regex)\]/$self->_single_get("$1")/eg;
}
{
my $regex = join '|', @{$self->_multiple_keys};
$string =~ s/\[($regex)\]/$self->_multiple_get("$1")/egx;
# unhandled indices are populated using the first value
$string =~ s/\[($regex)_\d+\]/$self->_multiple_get("$1")/egx;
}
return $string;
}
1;

View File

@@ -1,19 +1,31 @@
# Helper module to parse and interpret a G-code file,
# invoking a callback for each move extracted from the G-code.
# Currently used by the automatic tests only.
package Slic3r::GCode::Reader;
use Moo;
has 'config' => (is => 'ro', default => sub { Slic3r::Config::GCode->new });
has 'X' => (is => 'rw', default => sub {0});
has 'Y' => (is => 'rw', default => sub {0});
has 'Z' => (is => 'rw', default => sub {0});
has 'E' => (is => 'rw', default => sub {0});
has 'F' => (is => 'rw', default => sub {0});
has '_extrusion_axis' => (is => 'rw', default => sub {"E"});
our $Verbose = 0;
my @AXES = qw(X Y Z E);
sub apply_print_config {
my ($self, $print_config) = @_;
$self->config->apply_static($print_config);
$self->_extrusion_axis($self->config->get_extrusion_axis);
}
sub clone {
my $self = shift;
return (ref $self)->new(
map { $_ => $self->$_ } (@AXES, 'F'),
map { $_ => $self->$_ } (@AXES, 'F', '_extrusion_axis', 'config'),
);
}
@@ -32,10 +44,16 @@ sub parse {
$command //= '';
my %args = map { /([A-Z])(.*)/; ($1 => $2) } @args;
# convert extrusion axis
if (exists $args{ $self->_extrusion_axis }) {
$args{E} = $args{ $self->_extrusion_axis };
}
# check motion
if ($command =~ /^G[01]$/) {
foreach my $axis (@AXES) {
if (exists $args{$axis}) {
$self->$axis(0) if $axis eq 'E' && $self->config->use_relative_e_distances;
$info{"dist_$axis"} = $args{$axis} - $self->$axis;
$info{"new_$axis"} = $args{$axis};
} else {
@@ -43,7 +61,7 @@ sub parse {
$info{"new_$axis"} = $self->$axis;
}
}
$info{dist_XY} = Slic3r::Geometry::unscale(Slic3r::Line->new_scale([0,0], [@info{qw(dist_X dist_Y)}])->length);
$info{dist_XY} = sqrt(($info{dist_X}**2) + ($info{dist_Y}**2));
if (exists $args{E}) {
if ($info{dist_E} > 0) {
$info{extruding} = 1;

View File

@@ -1,81 +0,0 @@
package Slic3r::GCode::SpiralVase;
use Moo;
has 'config' => (is => 'ro', required => 1);
has 'enable' => (is => 'rw', default => sub { 0 });
has 'reader' => (is => 'ro', default => sub { Slic3r::GCode::Reader->new });
use Slic3r::Geometry qw(unscale);
sub process_layer {
my $self = shift;
my ($gcode) = @_;
# This post-processor relies on several assumptions:
# - all layers are processed through it, including those that are not supposed
# to be transformed, in order to update the reader with the XY positions
# - each call to this method includes a full layer, with a single Z move
# at the beginning
# - each layer is composed by suitable geometry (i.e. a single complete loop)
# - loops were not clipped before calling this method
# if we're not going to modify G-code, just feed it to the reader
# in order to update positions
if (!$self->enable) {
$self->reader->parse($gcode, sub {});
return $gcode;
}
# get total XY length for this layer by summing all extrusion moves
my $total_layer_length = 0;
my $layer_height = 0;
my $z = undef;
$self->reader->clone->parse($gcode, sub {
my ($reader, $cmd, $args, $info) = @_;
if ($cmd eq 'G1') {
if ($info->{extruding}) {
$total_layer_length += $info->{dist_XY};
} elsif (exists $args->{Z}) {
$layer_height += $info->{dist_Z};
$z //= $args->{Z};
}
}
});
#use XXX; XXX [ $gcode, $layer_height, $z, $total_layer_length ];
# remove layer height from initial Z
$z -= $layer_height;
my $new_gcode = "";
$self->reader->parse($gcode, sub {
my ($reader, $cmd, $args, $info) = @_;
if ($cmd eq 'G1' && exists $args->{Z}) {
# if this is the initial Z move of the layer, replace it with a
# (redundant) move to the last Z of previous layer
my $line = $info->{raw};
$line =~ s/ Z[.0-9]+/ Z$z/;
$new_gcode .= "$line\n";
} elsif ($cmd eq 'G1' && !exists($args->{Z}) && $info->{dist_XY}) {
# horizontal move
my $line = $info->{raw};
if ($info->{extruding}) {
$z += $info->{dist_XY} * $layer_height / $total_layer_length;
$line =~ s/^G1 /sprintf 'G1 Z%.3f ', $z/e;
$new_gcode .= "$line\n";
}
# skip travel moves: the move to first perimeter point will
# cause a visible seam when loops are not aligned in XY; by skipping
# it we blend the first loop move in the XY plane (although the smoothness
# of such blend depend on how long the first segment is; maybe we should
# enforce some minimum length?)
} else {
$new_gcode .= "$info->{raw}\n";
}
});
return $new_gcode;
}
1;

View File

@@ -1,64 +0,0 @@
package Slic3r::GCode::VibrationLimit;
use Moo;
extends 'Slic3r::GCode::Reader';
has 'config' => (is => 'ro', required => 1);
has '_min_time' => (is => 'lazy');
has '_last_dir' => (is => 'ro', default => sub { [0,0] });
has '_dir_time' => (is => 'ro', default => sub { [0,0] });
# inspired by http://hydraraptor.blogspot.it/2010/12/frequency-limit.html
use List::Util qw(max);
use Slic3r::Geometry qw(X Y);
sub _build__min_time {
my ($self) = @_;
return 1 / ($self->config->vibration_limit * 60); # in minutes
}
sub process {
my $self = shift;
my ($gcode) = @_;
my $new_gcode = "";
$self->parse($gcode, sub {
my ($reader, $cmd, $args, $info) = @_;
if ($cmd eq 'G1' && $info->{dist_XY} > 0) {
my $point = Slic3r::Point->new($args->{X} // $reader->X, $args->{Y} // $reader->Y);
my @dir = (
($point->x <=> $reader->X),
($point->y <=> $reader->Y), #$
);
my $time = $info->{dist_XY} / ($args->{F} // $reader->F); # in minutes
if ($time > 0) {
my @pause = ();
foreach my $axis (X,Y) {
if ($dir[$axis] != 0 && $self->_last_dir->[$axis] != $dir[$axis]) {
if ($self->_last_dir->[$axis] != 0) {
# this axis is changing direction: check whether we need to pause
if ($self->_dir_time->[$axis] < $self->_min_time) {
push @pause, ($self->_min_time - $self->_dir_time->[$axis]);
}
}
$self->_last_dir->[$axis] = $dir[$axis];
$self->_dir_time->[$axis] = 0;
}
$self->_dir_time->[$axis] += $time;
}
if (@pause) {
$new_gcode .= sprintf "G4 P%d\n", max(@pause) * 60 * 1000;
}
}
}
$new_gcode .= $info->{raw} . "\n";
});
return $new_gcode;
}
1;

View File

@@ -5,142 +5,234 @@ use utf8;
use File::Basename qw(basename);
use FindBin;
use Slic3r::GUI::AboutDialog;
use Slic3r::GUI::BedShapeDialog;
use Slic3r::GUI::ConfigWizard;
use List::Util qw(first);
use Slic3r::GUI::2DBed;
use Slic3r::GUI::Controller;
use Slic3r::GUI::Controller::ManualControlDialog;
use Slic3r::GUI::Controller::PrinterPanel;
use Slic3r::GUI::MainFrame;
use Slic3r::GUI::Notifier;
use Slic3r::GUI::Plater;
use Slic3r::GUI::Plater::2D;
use Slic3r::GUI::Plater::2DToolpaths;
use Slic3r::GUI::Plater::3D;
use Slic3r::GUI::Plater::3DPreview;
use Slic3r::GUI::Plater::ObjectPartsPanel;
use Slic3r::GUI::Plater::ObjectCutDialog;
use Slic3r::GUI::Plater::ObjectPreviewDialog;
use Slic3r::GUI::Plater::ObjectSettingsDialog;
use Slic3r::GUI::Plater::LambdaObjectDialog;
use Slic3r::GUI::Plater::OverrideSettingsPanel;
use Slic3r::GUI::Preferences;
use Slic3r::GUI::ProgressStatusBar;
use Slic3r::GUI::OptionsGroup;
use Slic3r::GUI::OptionsGroup::Field;
use Slic3r::GUI::SimpleTab;
use Slic3r::GUI::Tab;
use Slic3r::GUI::SystemInfo;
our $have_OpenGL = eval "use Slic3r::GUI::PreviewCanvas; 1";
use Wx::Locale gettext => 'L';
use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow
:filedialog);
use Wx::Event qw(EVT_IDLE);
our $have_OpenGL = eval "use Slic3r::GUI::3DScene; 1";
use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow :filedialog :font);
use Wx::Event qw(EVT_IDLE EVT_COMMAND EVT_MENU);
use base 'Wx::App';
use constant FILE_WILDCARDS => {
known => 'Known files (*.stl, *.obj, *.amf, *.xml)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML',
known => 'Known files (*.stl, *.obj, *.amf, *.xml, *.3mf, *.prusa)|*.stl;*.STL;*.obj;*.OBJ;*.zip.amf;*.amf;*.AMF;*.xml;*.XML;*.3mf;*.3MF;*.prusa;*.PRUSA',
stl => 'STL files (*.stl)|*.stl;*.STL',
obj => 'OBJ files (*.obj)|*.obj;*.OBJ',
amf => 'AMF files (*.amf)|*.amf;*.AMF;*.xml;*.XML',
amf => 'AMF files (*.amf)|*.zip.amf;*.amf;*.AMF;*.xml;*.XML',
threemf => '3MF files (*.3mf)|*.3mf;*.3MF',
prusa => 'Prusa Control files (*.prusa)|*.prusa;*.PRUSA',
ini => 'INI files *.ini|*.ini;*.INI',
gcode => 'G-code files (*.gcode, *.gco, *.g, *.ngc)|*.gcode;*.GCODE;*.gco;*.GCO;*.g;*.G;*.ngc;*.NGC',
svg => 'SVG files *.svg|*.svg;*.SVG',
};
use constant MODEL_WILDCARD => join '|', @{&FILE_WILDCARDS}{qw(known stl obj amf)};
use constant MODEL_WILDCARD => join '|', @{&FILE_WILDCARDS}{qw(known stl obj amf threemf prusa)};
# Datadir provided on the command line.
our $datadir;
# If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden.
our $no_plater;
our $mode;
our $autosave;
our @cb;
our $Settings = {
_ => {
mode => 'simple',
version_check => 1,
autocenter => 1,
background_processing => 1,
},
};
our $have_button_icons = &Wx::wxVERSION_STRING =~ / 2\.9\.[1-9]/;
our $small_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$small_font->SetPointSize(11) if !&Wx::wxMSW;
$small_font->SetPointSize(11) if &Wx::wxMAC;
our $small_bold_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$small_bold_font->SetPointSize(11) if &Wx::wxMAC;
$small_bold_font->SetWeight(wxFONTWEIGHT_BOLD);
our $medium_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$medium_font->SetPointSize(12);
our $grey = Wx::Colour->new(200,200,200);
# Events to be sent from a C++ menu implementation:
# 1) To inform about a change of the application language.
our $LANGUAGE_CHANGE_EVENT = Wx::NewEventType;
# 2) To inform about a change of Preferences.
our $PREFERENCES_EVENT = Wx::NewEventType;
# To inform AppConfig about Slic3r version available online
our $VERSION_ONLINE_EVENT = Wx::NewEventType;
sub OnInit {
my ($self) = @_;
$self->SetAppName('Slic3r');
$self->SetAppName('Slic3rPE');
$self->SetAppDisplayName('Slic3r Prusa Edition');
Slic3r::debugf "wxWidgets version %s, Wx version %s\n", &Wx::wxVERSION_STRING, $Wx::VERSION;
$self->{notifier} = Slic3r::GUI::Notifier->new;
# locate or create data directory
$datadir ||= Wx::StandardPaths::Get->GetUserDataDir;
$datadir = Slic3r::encode_path($datadir);
Slic3r::debugf "Data directory: %s\n", $datadir;
# just checking for existence of $datadir is not enough: it may be an empty directory
# Set the Slic3r data directory at the Slic3r XS module.
# Unix: ~/.Slic3r
# Windows: "C:\Users\username\AppData\Roaming\Slic3r" or "C:\Documents and Settings\username\Application Data\Slic3r"
# Mac: "~/Library/Application Support/Slic3r"
Slic3r::set_data_dir($datadir || Wx::StandardPaths::Get->GetUserDataDir);
Slic3r::GUI::set_wxapp($self);
$self->{app_config} = Slic3r::GUI::AppConfig->new;
Slic3r::GUI::set_app_config($self->{app_config});
$self->{preset_bundle} = Slic3r::GUI::PresetBundle->new;
Slic3r::GUI::set_preset_bundle($self->{preset_bundle});
# just checking for existence of Slic3r::data_dir is not enough: it may be an empty directory
# supplied as argument to --datadir; in that case we should still run the wizard
my $run_wizard = (-d $datadir && -e "$datadir/slic3r.ini") ? 0 : 1;
for ($datadir, "$datadir/print", "$datadir/filament", "$datadir/printer") {
mkdir or $self->fatal_error("Slic3r was unable to create its data directory at $_ (errno: $!).")
unless -d $_;
eval { $self->{preset_bundle}->setup_directories() };
if ($@) {
warn $@ . "\n";
fatal_error(undef, $@);
}
my $app_conf_exists = $self->{app_config}->exists;
# load settings
my $last_version;
if (-f "$datadir/slic3r.ini") {
my $ini = eval { Slic3r::Config->read_ini("$datadir/slic3r.ini") };
$Settings = $ini if $ini;
$last_version = $Settings->{_}{version};
$Settings->{_}{mode} ||= 'expert';
$Settings->{_}{autocenter} //= 1;
$Settings->{_}{background_processing} //= 1;
$self->{app_config}->load if $app_conf_exists;
$self->{app_config}->set('version', $Slic3r::VERSION);
$self->{app_config}->save;
$self->{preset_updater} = Slic3r::PresetUpdater->new($VERSION_ONLINE_EVENT);
Slic3r::GUI::set_preset_updater($self->{preset_updater});
Slic3r::GUI::load_language();
# Suppress the '- default -' presets.
$self->{preset_bundle}->set_default_suppressed($self->{app_config}->get('no_defaults') ? 1 : 0);
eval { $self->{preset_bundle}->load_presets($self->{app_config}); };
if ($@) {
warn $@ . "\n";
show_error(undef, $@);
}
$Settings->{_}{version} = $Slic3r::VERSION;
$self->save_settings;
# application frame
Wx::Image::AddHandler(Wx::PNGHandler->new);
print STDERR "Creating main frame...\n";
Wx::Image::FindHandlerType(wxBITMAP_TYPE_PNG) || Wx::Image::AddHandler(Wx::PNGHandler->new);
$self->{mainframe} = my $frame = Slic3r::GUI::MainFrame->new(
mode => $mode // $Settings->{_}{mode},
no_plater => $no_plater,
# If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden.
no_controller => $self->{app_config}->get('no_controller'),
no_plater => $no_plater,
lang_ch_event => $LANGUAGE_CHANGE_EVENT,
preferences_event => $PREFERENCES_EVENT,
);
$self->SetTopWindow($frame);
if (!$run_wizard && (!defined $last_version || $last_version ne $Slic3r::VERSION)) {
# user was running another Slic3r version on this computer
if (!defined $last_version || $last_version =~ /^0\./) {
show_info($self->{mainframe}, "Hello! Support material was improved since the "
. "last version of Slic3r you used. It is strongly recommended to revert "
. "your support material settings to the factory defaults and start from "
. "those. Enjoy and provide feedback!", "Support Material");
}
if (!defined $last_version || $last_version =~ /^(?:0|1\.[01])\./) {
show_info($self->{mainframe}, "Hello! In this version a new Bed Shape option was "
. "added. If the bed coordinates in the plater preview screen look wrong, go "
. "to Print Settings and click the \"Set\" button next to \"Bed Shape\".", "Bed Shape");
}
}
$self->{mainframe}->config_wizard if $run_wizard;
$self->check_version
if $self->have_version_check
&& ($Settings->{_}{version_check} // 1)
&& (!$Settings->{_}{last_version_check} || (time - $Settings->{_}{last_version_check}) >= 86400);
EVT_IDLE($frame, sub {
# This makes CallAfter() work
EVT_IDLE($self->{mainframe}, sub {
while (my $cb = shift @cb) {
$cb->();
}
$self->{app_config}->save if $self->{app_config}->dirty;
});
# On OS X the UI tends to freeze in weird ways if modal dialogs (config wizard, update notifications, ...)
# are shown before or in the same event callback with the main frame creation.
# Therefore we schedule them for later using CallAfter.
$self->CallAfter(sub {
eval {
if (! $self->{preset_updater}->config_update()) {
exit 0;
}
};
if ($@) {
warn $@ . "\n";
fatal_error(undef, $@);
}
});
$self->CallAfter(sub {
if (! Slic3r::GUI::config_wizard_startup($app_conf_exists)) {
# Only notify if there was not wizard so as not to bother too much ...
$self->{preset_updater}->slic3r_update_notify();
}
$self->{preset_updater}->sync($self->{preset_bundle});
});
# The following event is emited by the C++ menu implementation of application language change.
EVT_COMMAND($self, -1, $LANGUAGE_CHANGE_EVENT, sub{
print STDERR "LANGUAGE_CHANGE_EVENT\n";
$self->recreate_GUI;
});
# The following event is emited by the C++ menu implementation of preferences change.
EVT_COMMAND($self, -1, $PREFERENCES_EVENT, sub{
$self->update_ui_from_settings;
});
# The following event is emited by PresetUpdater (C++)
EVT_COMMAND($self, -1, $VERSION_ONLINE_EVENT, sub {
my ($self, $event) = @_;
my $version = $event->GetString;
$self->{app_config}->set('version_online', $version);
$self->{app_config}->save;
});
return 1;
}
sub about {
sub recreate_GUI{
print STDERR "recreate_GUI\n";
my ($self) = @_;
my $about = Slic3r::GUI::AboutDialog->new(undef);
my $topwindow = $self->GetTopWindow();
$self->{mainframe} = my $frame = Slic3r::GUI::MainFrame->new(
# If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden.
no_controller => $self->{app_config}->get('no_controller'),
no_plater => $no_plater,
lang_ch_event => $LANGUAGE_CHANGE_EVENT,
preferences_event => $PREFERENCES_EVENT,
);
if($topwindow)
{
$self->SetTopWindow($frame);
$topwindow->Destroy;
}
EVT_IDLE($self->{mainframe}, sub {
while (my $cb = shift @cb) {
$cb->();
}
$self->{app_config}->save if $self->{app_config}->dirty;
});
# On OSX the UI was not initialized correctly if the wizard was called
# before the UI was up and running.
$self->CallAfter(sub {
# Run the config wizard, don't offer the "reset user profile" checkbox.
Slic3r::GUI::config_wizard_startup(1);
});
}
sub system_info {
my ($self) = @_;
my $slic3r_info = Slic3r::slic3r_info(format => 'html');
my $copyright_info = Slic3r::copyright_info(format => 'html');
my $system_info = Slic3r::system_info(format => 'html');
my $opengl_info;
my $opengl_info_txt = '';
if (defined($self->{mainframe}) && defined($self->{mainframe}->{plater}) &&
defined($self->{mainframe}->{plater}->{canvas3D})) {
$opengl_info = Slic3r::GUI::_3DScene::get_gl_info(1, 1);
$opengl_info_txt = Slic3r::GUI::_3DScene::get_gl_info(0, 1);
}
my $about = Slic3r::GUI::SystemInfo->new(
parent => undef,
slic3r_info => $slic3r_info,
# copyright_info => $copyright_info,
system_info => $system_info,
opengl_info => $opengl_info,
text_info => Slic3r::slic3r_info . Slic3r::system_info . $opengl_info_txt,
);
$about->ShowModal;
$about->Destroy;
}
@@ -160,22 +252,19 @@ sub catch_error {
# static method accepting a wxWindow object as first parameter
sub show_error {
my $self = shift;
my ($message) = @_;
Wx::MessageDialog->new($self, $message, 'Error', wxOK | wxICON_ERROR)->ShowModal;
my ($parent, $message) = @_;
Slic3r::GUI::show_error_id($parent ? $parent->GetId() : 0, $message);
}
# static method accepting a wxWindow object as first parameter
sub show_info {
my $self = shift;
my ($message, $title) = @_;
Wx::MessageDialog->new($self, $message, $title || 'Notice', wxOK | wxICON_INFORMATION)->ShowModal;
my ($parent, $message, $title) = @_;
Wx::MessageDialog->new($parent, $message, $title || 'Notice', wxOK | wxICON_INFORMATION)->ShowModal;
}
# static method accepting a wxWindow object as first parameter
sub fatal_error {
my $self = shift;
$self->show_error(@_);
show_error(@_);
exit 1;
}
@@ -200,79 +289,24 @@ sub notify {
$frame->RequestUserAttention(&Wx::wxMAC ? wxUSER_ATTENTION_ERROR : wxUSER_ATTENTION_INFO)
unless ($frame->IsActive);
$self->{notifier}->notify($message);
# There used to be notifier using a Growl application for OSX, but Growl is dead.
# The notifier also supported the Linux X D-bus notifications, but that support was broken.
#TODO use wxNotificationMessage?
}
sub save_settings {
# Called after the Preferences dialog is closed and the program settings are saved.
# Update the UI based on the current preferences.
sub update_ui_from_settings {
my ($self) = @_;
Slic3r::Config->write_ini("$datadir/slic3r.ini", $Settings);
}
sub presets {
my ($self, $section) = @_;
my %presets = ();
opendir my $dh, "$Slic3r::GUI::datadir/$section" or die "Failed to read directory $Slic3r::GUI::datadir/$section (errno: $!)\n";
foreach my $file (grep /\.ini$/i, readdir $dh) {
my $name = basename($file);
$name =~ s/\.ini$//;
$presets{$name} = "$Slic3r::GUI::datadir/$section/$file";
}
closedir $dh;
return %presets;
}
sub have_version_check {
my ($self) = @_;
# return an explicit 0
return ($Slic3r::have_threads && $Slic3r::build && eval "use LWP::UserAgent; 1") || 0;
}
sub check_version {
my ($self, %p) = @_;
Slic3r::debugf "Checking for updates...\n";
@_ = ();
threads->create(sub {
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
my $response = $ua->get('http://slic3r.org/updatecheck');
if ($response->is_success) {
if ($response->decoded_content =~ /^obsolete ?= ?([a-z0-9.-]+,)*\Q$Slic3r::VERSION\E(?:,|$)/) {
my $res = Wx::MessageDialog->new(undef, "A new version is available. Do you want to open the Slic3r website now?",
'Update', wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxICON_INFORMATION | wxICON_ERROR)->ShowModal;
Wx::LaunchDefaultBrowser('http://slic3r.org/') if $res == wxID_YES;
} else {
Slic3r::GUI::show_info(undef, "You're using the latest version. No updates are available.") if $p{manual};
}
$Settings->{_}{last_version_check} = time();
$self->save_settings;
} else {
Slic3r::GUI::show_error(undef, "Failed to check for updates. Try later.") if $p{manual};
}
Slic3r::thread_cleanup();
})->detach;
}
sub output_path {
my ($self, $dir) = @_;
return ($Settings->{_}{last_output_path} && $Settings->{_}{remember_output_path})
? $Settings->{_}{last_output_path}
: $dir;
$self->{mainframe}->update_ui_from_settings;
}
sub open_model {
my ($self, $window) = @_;
my $dir = $Slic3r::GUI::Settings->{recent}{skein_directory}
|| $Slic3r::GUI::Settings->{recent}{config_directory}
|| '';
my $dialog = Wx::FileDialog->new($window // $self->GetTopWindow, 'Choose one or more files (STL/OBJ/AMF):', $dir, "",
my $dlg_title = L('Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):');
my $dialog = Wx::FileDialog->new($window // $self->GetTopWindow, $dlg_title,
$self->{app_config}->get_last_dir, "",
MODEL_WILDCARD, wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST);
if ($dialog->ShowModal != wxID_OK) {
$dialog->Destroy;
@@ -280,7 +314,6 @@ sub open_model {
}
my @input_files = $dialog->GetPaths;
$dialog->Destroy;
return @input_files;
}
@@ -289,4 +322,61 @@ sub CallAfter {
push @cb, $cb;
}
sub append_menu_item {
my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_;
$id //= &Wx::NewId();
my $item = Wx::MenuItem->new($menu, $id, $string, $description // '', $kind // 0);
$self->set_menu_item_icon($item, $icon);
$menu->Append($item);
EVT_MENU($self, $id, $cb);
return $item;
}
sub append_submenu {
my ($self, $menu, $string, $description, $submenu, $id, $icon) = @_;
$id //= &Wx::NewId();
my $item = Wx::MenuItem->new($menu, $id, $string, $description // '');
$self->set_menu_item_icon($item, $icon);
$item->SetSubMenu($submenu);
$menu->Append($item);
return $item;
}
sub set_menu_item_icon {
my ($self, $menuItem, $icon) = @_;
# SetBitmap was not available on OS X before Wx 0.9927
if ($icon && $menuItem->can('SetBitmap')) {
$menuItem->SetBitmap(Wx::Bitmap->new(Slic3r::var($icon), wxBITMAP_TYPE_PNG));
}
}
sub save_window_pos {
my ($self, $window, $name) = @_;
$self->{app_config}->set("${name}_pos", join ',', $window->GetScreenPositionXY);
$self->{app_config}->set("${name}_size", join ',', $window->GetSizeWH);
$self->{app_config}->set("${name}_maximized", $window->IsMaximized);
$self->{app_config}->save;
}
sub restore_window_pos {
my ($self, $window, $name) = @_;
if ($self->{app_config}->has("${name}_pos")) {
my $size = [ split ',', $self->{app_config}->get("${name}_size"), 2 ];
$window->SetSize($size);
my $display = Wx::Display->new->GetClientArea();
my $pos = [ split ',', $self->{app_config}->get("${name}_pos"), 2 ];
if (($pos->[0] + $size->[0]/2) < $display->GetRight && ($pos->[1] + $size->[1]/2) < $display->GetBottom) {
$window->Move($pos);
}
$window->Maximize(1) if $self->{app_config}->get("${name}_maximized");
}
}
1;

216
lib/Slic3r/GUI/2DBed.pm Normal file
View File

@@ -0,0 +1,216 @@
# Bed shape dialog
package Slic3r::GUI::2DBed;
use strict;
use warnings;
use List::Util qw(min max);
use Slic3r::Geometry qw(X Y unscale deg2rad);
use Slic3r::Geometry::Clipper qw(intersection_pl);
use Wx qw(:misc :pen :brush :font :systemsettings wxTAB_TRAVERSAL wxSOLID);
use Wx::Event qw(EVT_PAINT EVT_ERASE_BACKGROUND EVT_MOUSE_EVENTS EVT_SIZE);
use base qw(Wx::Panel Class::Accessor);
__PACKAGE__->mk_accessors(qw(bed_shape interactive pos _scale_factor _shift on_move _painted));
sub new {
my ($class, $parent, $bed_shape) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, [250,-1], wxTAB_TRAVERSAL);
$self->{user_drawn_background} = $^O ne 'darwin';
$self->bed_shape($bed_shape // []);
EVT_PAINT($self, \&_repaint);
EVT_ERASE_BACKGROUND($self, sub {}) if $self->{user_drawn_background};
EVT_MOUSE_EVENTS($self, \&_mouse_event);
EVT_SIZE($self, sub { $self->Refresh; });
return $self;
}
sub _repaint {
my ($self, $event) = @_;
my $dc = Wx::AutoBufferedPaintDC->new($self);
my ($cw, $ch) = $self->GetSizeWH;
return if $cw == 0; # when canvas is not rendered yet, size is 0,0
if ($self->{user_drawn_background}) {
# On all systems the AutoBufferedPaintDC() achieves double buffering.
# On MacOS the background is erased, on Windows the background is not erased
# and on Linux/GTK the background is erased to gray color.
# Fill DC with the background on Windows & Linux/GTK.
my $color = Wx::SystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT);
$dc->SetPen(Wx::Pen->new($color, 1, wxSOLID));
$dc->SetBrush(Wx::Brush->new($color, wxSOLID));
my $rect = $self->GetUpdateRegion()->GetBox();
$dc->DrawRectangle($rect->GetLeft(), $rect->GetTop(), $rect->GetWidth(), $rect->GetHeight());
}
# turn $cw and $ch from sizes to max coordinates
$cw--;
$ch--;
my $cbb = Slic3r::Geometry::BoundingBoxf->new_from_points([
Slic3r::Pointf->new(0, 0),
Slic3r::Pointf->new($cw, $ch),
]);
# leave space for origin point
$cbb->set_x_min($cbb->x_min + 4);
$cbb->set_x_max($cbb->x_max - 4);
$cbb->set_y_max($cbb->y_max - 4);
# leave space for origin label
$cbb->set_y_max($cbb->y_max - 13);
# read new size
($cw, $ch) = @{$cbb->size};
my $ccenter = $cbb->center;
# get bounding box of bed shape in G-code coordinates
my $bed_shape = $self->bed_shape;
my $bed_polygon = Slic3r::Polygon->new_scale(@$bed_shape);
my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($bed_shape);
$bb->merge_point(Slic3r::Pointf->new(0,0)); # origin needs to be in the visible area
my ($bw, $bh) = @{$bb->size};
my $bcenter = $bb->center;
# calculate the scaling factor for fitting bed shape in canvas area
my $sfactor = min($cw/$bw, $ch/$bh);
my $shift = Slic3r::Pointf->new(
$ccenter->x - $bcenter->x * $sfactor,
$ccenter->y - $bcenter->y * $sfactor, #-
);
$self->_scale_factor($sfactor);
$self->_shift(Slic3r::Pointf->new(
$shift->x + $cbb->x_min,
$shift->y - ($cbb->y_max-$self->GetSize->GetHeight), #++
));
# draw bed fill
{
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,0,0), 1, wxSOLID));
$dc->SetBrush(Wx::Brush->new(Wx::Colour->new(255,255,255), wxSOLID));
$dc->DrawPolygon([ map $self->to_pixels($_), @$bed_shape ], 0, 0);
}
# draw grid
{
my $step = 10; # 1cm grid
my @polylines = ();
for (my $x = $bb->x_min - ($bb->x_min % $step) + $step; $x < $bb->x_max; $x += $step) {
push @polylines, Slic3r::Polyline->new_scale([$x, $bb->y_min], [$x, $bb->y_max]);
}
for (my $y = $bb->y_min - ($bb->y_min % $step) + $step; $y < $bb->y_max; $y += $step) {
push @polylines, Slic3r::Polyline->new_scale([$bb->x_min, $y], [$bb->x_max, $y]);
}
@polylines = @{intersection_pl(\@polylines, [$bed_polygon])};
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(230,230,230), 1, wxSOLID));
$dc->DrawLine(map @{$self->to_pixels([map unscale($_), @$_])}, @$_[0,-1]) for @polylines;
}
# draw bed contour
{
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,0,0), 1, wxSOLID));
$dc->SetBrush(Wx::Brush->new(Wx::Colour->new(255,255,255), wxTRANSPARENT));
$dc->DrawPolygon([ map $self->to_pixels($_), @$bed_shape ], 0, 0);
}
my $origin_px = $self->to_pixels(Slic3r::Pointf->new(0,0));
# draw axes
{
my $axes_len = 50;
my $arrow_len = 6;
my $arrow_angle = deg2rad(45);
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(255,0,0), 2, wxSOLID)); # red
my $x_end = Slic3r::Pointf->new($origin_px->[X] + $axes_len, $origin_px->[Y]);
$dc->DrawLine(@$origin_px, @$x_end);
foreach my $angle (-$arrow_angle, +$arrow_angle) {
my $end = $x_end->clone;
$end->translate(-$arrow_len, 0);
$end->rotate($angle, $x_end);
$dc->DrawLine(@$x_end, @$end);
}
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,255,0), 2, wxSOLID)); # green
my $y_end = Slic3r::Pointf->new($origin_px->[X], $origin_px->[Y] - $axes_len);
$dc->DrawLine(@$origin_px, @$y_end);
foreach my $angle (-$arrow_angle, +$arrow_angle) {
my $end = $y_end->clone;
$end->translate(0, +$arrow_len);
$end->rotate($angle, $y_end);
$dc->DrawLine(@$y_end, @$end);
}
}
# draw origin
{
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,0,0), 1, wxSOLID));
$dc->SetBrush(Wx::Brush->new(Wx::Colour->new(0,0,0), wxSOLID));
$dc->DrawCircle(@$origin_px, 3);
$dc->SetTextForeground(Wx::Colour->new(0,0,0));
$dc->SetFont(Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL));
$dc->DrawText("(0,0)", $origin_px->[X] + 1, $origin_px->[Y] + 2);
}
# draw current position
if (defined $self->pos) {
my $pos_px = $self->to_pixels($self->pos);
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(200,0,0), 2, wxSOLID));
$dc->SetBrush(Wx::Brush->new(Wx::Colour->new(200,0,0), wxTRANSPARENT));
$dc->DrawCircle(@$pos_px, 5);
$dc->DrawLine($pos_px->[X]-15, $pos_px->[Y], $pos_px->[X]+15, $pos_px->[Y]);
$dc->DrawLine($pos_px->[X], $pos_px->[Y]-15, $pos_px->[X], $pos_px->[Y]+15);
}
$self->_painted(1);
}
sub _mouse_event {
my ($self, $event) = @_;
return if !$self->interactive;
return if !$self->_painted;
my $pos = $event->GetPosition;
my $point = $self->to_units([ $pos->x, $pos->y ]); #]]
if ($event->LeftDown || $event->Dragging) {
$self->on_move->($point) if $self->on_move;
$self->Refresh;
}
}
# convert G-code coordinates into pixels
sub to_pixels {
my ($self, $point) = @_;
my $p = Slic3r::Pointf->new(@$point);
$p->scale($self->_scale_factor);
$p->translate(@{$self->_shift});
return [$p->x, $self->GetSize->GetHeight - $p->y]; #]]
}
# convert pixels into G-code coordinates
sub to_units {
my ($self, $point) = @_;
my $p = Slic3r::Pointf->new(
$point->[X],
$self->GetSize->GetHeight - $point->[Y],
);
$p->translate(@{$self->_shift->negative});
$p->scale(1/$self->_scale_factor);
return $p;
}
sub set_pos {
my ($self, $pos) = @_;
$self->pos($pos);
$self->Refresh;
}
1;

2231
lib/Slic3r/GUI/3DScene.pm Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,110 +0,0 @@
package Slic3r::GUI::AboutDialog;
use strict;
use warnings;
use utf8;
use Wx qw(:font :html :misc :sizer :systemsettings);
use Wx::Event qw(EVT_HTML_LINK_CLICKED);
use Wx::Print;
use Wx::Html;
use base 'Wx::Dialog';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, -1, 'About Slic3r', wxDefaultPosition, [600, 270]);
$self->SetBackgroundColour(Wx::wxWHITE);
my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
$self->SetSizer($hsizer);
# logo
my $logo = Slic3r::GUI::AboutDialog::Logo->new($self, -1, wxDefaultPosition, wxDefaultSize);
$logo->SetBackgroundColour(Wx::wxWHITE);
$hsizer->Add($logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 30);
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
$hsizer->Add($vsizer, 1, wxEXPAND, 0);
# title
my $title = Wx::StaticText->new($self, -1, 'Slic3r', wxDefaultPosition, wxDefaultSize);
my $title_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$title_font->SetWeight(wxFONTWEIGHT_BOLD);
$title_font->SetFamily(wxFONTFAMILY_ROMAN);
$title_font->SetPointSize(24);
$title->SetFont($title_font);
$vsizer->Add($title, 0, wxALIGN_LEFT | wxTOP, 30);
# version
my $version = Wx::StaticText->new($self, -1, "Version $Slic3r::VERSION", wxDefaultPosition, wxDefaultSize);
my $version_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$version_font->SetPointSize(&Wx::wxMSW ? 9 : 11);
$version->SetFont($version_font);
$vsizer->Add($version, 0, wxALIGN_LEFT | wxBOTTOM, 10);
# text
my $text =
'<html>' .
'<body bgcolor="#ffffff" link="#808080">' .
'<font color="#808080">' .
'Copyright &copy; 2011-2014 Alessandro Ranellucci. <br />' .
'<a href="http://slic3r.org/">Slic3r</a> is licensed under the ' .
'<a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License, version 3</a>.' .
'<br /><br /><br />' .
'Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Y. Sapir, Mike Sheldrake and numerous others. ' .
'Manual by Gary Hodgson. Inspired by the RepRap community. <br />' .
'Slic3r logo designed by Corey Daniels, <a href="http://www.famfamfam.com/lab/icons/silk/">Silk Icon Set</a> designed by Mark James. ' .
'</font>' .
'</body>' .
'</html>';
my $html = Wx::HtmlWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER);
my $font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
my $size = &Wx::wxMSW ? 8 : 10;
$html->SetFonts($font->GetFaceName, $font->GetFaceName, [$size, $size, $size, $size, $size, $size, $size]);
$html->SetBorders(2);
$html->SetPage($text);
$vsizer->Add($html, 1, wxEXPAND | wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 20);
EVT_HTML_LINK_CLICKED($self, $html, \&link_clicked);
return $self;
}
sub link_clicked {
my ($self, $event) = @_;
Wx::LaunchDefaultBrowser($event->GetLinkInfo->GetHref);
$event->Skip(0);
}
package Slic3r::GUI::AboutDialog::Logo;
use Wx qw(:bitmap :dc);
use Wx::Event qw(EVT_PAINT);
use base 'Wx::Panel';
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
$self->{logo} = Wx::Bitmap->new("$Slic3r::var/Slic3r_192px.png", wxBITMAP_TYPE_PNG);
$self->SetMinSize(Wx::Size->new($self->{logo}->GetWidth, $self->{logo}->GetHeight));
EVT_PAINT($self, \&repaint);
return $self;
}
sub repaint {
my ($self, $event) = @_;
my $dc = Wx::PaintDC->new($self);
$dc->SetBackgroundMode(wxTRANSPARENT);
my $size = $self->GetSize;
my $logo_w = $self->{logo}->GetWidth;
my $logo_h = $self->{logo}->GetHeight;
$dc->DrawBitmap($self->{logo}, ($size->GetWidth - $logo_w) / 2, ($size->GetHeight - $logo_h) / 2, 1);
$event->Skip;
}
1;

View File

@@ -1,412 +0,0 @@
package Slic3r::GUI::BedShapeDialog;
use strict;
use warnings;
use utf8;
use List::Util qw(min max);
use Slic3r::Geometry qw(PI X Y unscale);
use Wx qw(:dialog :id :misc :sizer :choicebook wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_CLOSE);
use base 'Wx::Dialog';
sub new {
my $class = shift;
my ($parent, $default) = @_;
my $self = $class->SUPER::new($parent, -1, "Bed Shape", wxDefaultPosition, [350,700], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
$self->{panel} = my $panel = Slic3r::GUI::BedShapePanel->new($self, $default);
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
$main_sizer->Add($panel, 1, wxEXPAND);
$main_sizer->Add($self->CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND);
$self->SetSizer($main_sizer);
$self->SetMinSize($self->GetSize);
$main_sizer->SetSizeHints($self);
# needed to actually free memory
EVT_CLOSE($self, sub {
$self->EndModal(wxID_OK);
$self->Destroy;
});
return $self;
}
sub GetValue {
my ($self) = @_;
return $self->{panel}->GetValue;
}
package Slic3r::GUI::BedShapePanel;
use List::Util qw(min max sum first);
use Slic3r::Geometry qw(PI X Y scale unscale scaled_epsilon deg2rad);
use Slic3r::Geometry::Clipper qw(intersection_pl);
use Wx qw(:font :id :misc :sizer :choicebook :filedialog :pen :brush wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_CLOSE EVT_CHOICEBOOK_PAGE_CHANGED EVT_BUTTON EVT_PAINT);
use base 'Wx::Panel';
use constant SHAPE_RECTANGULAR => 0;
use constant SHAPE_CIRCULAR => 1;
use constant SHAPE_CUSTOM => 2;
sub new {
my $class = shift;
my ($parent, $default) = @_;
my $self = $class->SUPER::new($parent, -1);
$self->on_change(undef);
my $box = Wx::StaticBox->new($self, -1, "Shape");
my $sbsizer = Wx::StaticBoxSizer->new($box, wxVERTICAL);
# shape options
$self->{shape_options_book} = Wx::Choicebook->new($self, -1, wxDefaultPosition, [300,-1], wxCHB_TOP);
$sbsizer->Add($self->{shape_options_book});
$self->{optgroups} = [];
{
my $optgroup = $self->_init_shape_options_page('Rectangular');
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'rect_size',
type => 'point',
label => 'Size',
tooltip => 'Size in X and Y of the rectangular plate.',
default => [200,200],
));
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'rect_origin',
type => 'point',
label => 'Origin',
tooltip => 'Distance of the 0,0 G-code coordinate from the front left corner of the rectangle.',
default => [0,0],
));
$optgroup->on_change->($_) for qw(rect_size rect_origin); # set defaults
}
{
my $optgroup = $self->_init_shape_options_page('Circular');
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'diameter',
type => 'f',
label => 'Diameter',
tooltip => 'Diameter of the print bed. It is assumed that origin (0,0) is located in the center.',
sidetext => 'mm',
default => 200,
));
$optgroup->on_change->($_) for qw(diameter); # set defaults
}
{
my $optgroup = $self->_init_shape_options_page('Custom');
$optgroup->append_line(Slic3r::GUI::OptionsGroup::Line->new(
full_width => 1,
widget => sub {
my ($parent) = @_;
my $btn = Wx::Button->new($parent, -1, "Load shape from STL...", wxDefaultPosition, wxDefaultSize);
EVT_BUTTON($self, $btn, sub { $self->_load_stl });
return $btn;
}
));
}
EVT_CHOICEBOOK_PAGE_CHANGED($self, -1, sub {
$self->_update_shape;
});
# right pane with preview canvas
my $canvas = $self->{canvas} = Wx::Panel->new($self, -1, wxDefaultPosition, [250,-1], wxTAB_TRAVERSAL);
EVT_PAINT($canvas, sub {
$self->_repaint_canvas;
});
# main sizer
my $top_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$top_sizer->Add($sbsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
$top_sizer->Add($canvas, 1, wxEXPAND | wxALL, 10) if $canvas;
$self->SetSizerAndFit($top_sizer);
$self->_set_shape($default);
$self->_update_preview;
return $self;
}
sub on_change {
my ($self, $cb) = @_;
$self->{on_change} = $cb // sub {};
}
sub _set_shape {
my ($self, $points) = @_;
$self->{bed_shape} = $points;
# is this a rectangle?
if (@$points == 4) {
my $polygon = Slic3r::Polygon->new_scale(@$points);
my $lines = $polygon->lines;
if ($lines->[0]->parallel_to_line($lines->[2]) && $lines->[1]->parallel_to_line($lines->[3])) {
# okay, it's a rectangle
# find origin
# the || 0 hack prevents "-0" which might confuse the user
my $x_min = min(map $_->[X], @$points) || 0;
my $x_max = max(map $_->[X], @$points) || 0;
my $y_min = min(map $_->[Y], @$points) || 0;
my $y_max = max(map $_->[Y], @$points) || 0;
my $origin = [-$x_min, -$y_min];
$self->{shape_options_book}->SetSelection(SHAPE_RECTANGULAR);
my $optgroup = $self->{optgroups}[SHAPE_RECTANGULAR];
$optgroup->set_value('rect_size', [ $x_max-$x_min, $y_max-$y_min ]);
$optgroup->set_value('rect_origin', $origin);
return;
}
}
# is this a circle?
{
my $polygon = Slic3r::Polygon->new_scale(@$points);
my $center = $polygon->bounding_box->center;
my @vertex_distances = map $center->distance_to($_), @$polygon;
my $avg_dist = sum(@vertex_distances)/@vertex_distances;
if (!defined first { abs($_ - $avg_dist) > scaled_epsilon } @vertex_distances) {
# all vertices are equidistant to center
$self->{shape_options_book}->SetSelection(SHAPE_CIRCULAR);
my $optgroup = $self->{optgroups}[SHAPE_CIRCULAR];
$optgroup->set_value('diameter', sprintf("%.0f", unscale($avg_dist*2)));
return;
}
}
$self->{shape_options_book}->SetSelection(SHAPE_CUSTOM);
}
sub _update_shape {
my ($self) = @_;
my $page_idx = $self->{shape_options_book}->GetSelection;
if ($page_idx == SHAPE_RECTANGULAR) {
return if grep !defined($self->{"_$_"}), qw(rect_size rect_origin); # not loaded yet
my ($x, $y) = @{$self->{_rect_size}};
return if !$x || !$y; # empty strings
my ($x0, $y0) = (0,0);
my ($x1, $y1) = ($x,$y);
{
my ($dx, $dy) = @{$self->{_rect_origin}};
return if $dx eq '' || $dy eq ''; # empty strings
$x0 -= $dx;
$x1 -= $dx;
$y0 -= $dy;
$y1 -= $dy;
}
$self->{bed_shape} = [
[$x0,$y0],
[$x1,$y0],
[$x1,$y1],
[$x0,$y1],
];
} elsif ($page_idx == SHAPE_CIRCULAR) {
return if grep !defined($self->{"_$_"}), qw(diameter); # not loaded yet
return if !$self->{_diameter};
my $r = $self->{_diameter}/2;
my $twopi = 2*PI;
my $edges = 60;
my $polygon = Slic3r::Polygon->new_scale(
map [ $r * cos $_, $r * sin $_ ],
map { $twopi/$edges*$_ } 1..$edges
);
$self->{bed_shape} = [
map [ unscale($_->x), unscale($_->y) ], @$polygon #))
];
}
$self->{on_change}->();
$self->_update_preview;
}
sub _update_preview {
my ($self) = @_;
$self->{canvas}->Refresh if $self->{canvas};
}
sub _repaint_canvas {
my ($self) = @_;
my $canvas = $self->{canvas};
my $dc = Wx::PaintDC->new($canvas);
my ($cw, $ch) = $canvas->GetSizeWH;
return if $cw == 0; # when canvas is not rendered yet, size is 0,0
# turn $cw and $ch from sizes to max coordinates
$cw--;
$ch--;
my $cbb = Slic3r::Geometry::BoundingBoxf->new_from_points([
Slic3r::Pointf->new(0, 0),
Slic3r::Pointf->new($cw, $ch),
]);
# leave space for origin point
$cbb->set_x_min($cbb->x_min + 2);
$cbb->set_y_max($cbb->y_max - 2);
# leave space for origin label
$cbb->set_y_max($cbb->y_max - 10);
# read new size
($cw, $ch) = @{$cbb->size};
my $ccenter = $cbb->center;
# get bounding box of bed shape in G-code coordinates
my $bed_shape = $self->{bed_shape};
my $bed_polygon = Slic3r::Polygon->new_scale(@$bed_shape);
my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($bed_shape);
$bb->merge_point(Slic3r::Pointf->new(0,0)); # origin needs to be in the visible area
my ($bw, $bh) = @{$bb->size};
my $bcenter = $bb->center;
# calculate the scaling factor for fitting bed shape in canvas area
my $sfactor = min($cw/$bw, $ch/$bh);
my $shift = [
$ccenter->x - $bcenter->x * $sfactor,
$ccenter->y - $bcenter->y * $sfactor, #-
];
# prepare function to convert G-code coordinates into pixels
my $to_pixel = sub {
my ($point) = @_;
my $p = Slic3r::Pointf->new(@$point);
$p->scale($sfactor);
$p->translate(@$shift);
return [ $p->x + $cbb->x_min, $ch-$p->y + $cbb->y_min ]; #++
};
# draw bed fill
{
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,0,0), 1, wxSOLID));
$dc->SetBrush(Wx::Brush->new(Wx::Colour->new(255,255,255), wxSOLID));
$dc->DrawPolygon([ map $to_pixel->($_), @$bed_shape ], 0, 0);
}
# draw grid
{
my $step = 10; # 1cm grid
my @polylines = ();
for (my $x = $bb->x_min - ($bb->x_min % $step) + $step; $x < $bb->x_max; $x += $step) {
push @polylines, Slic3r::Polyline->new_scale([$x, $bb->y_min], [$x, $bb->y_max]);
}
for (my $y = $bb->y_min - ($bb->y_min % $step) + $step; $y < $bb->y_max; $y += $step) {
push @polylines, Slic3r::Polyline->new_scale([$bb->x_min, $y], [$bb->x_max, $y]);
}
@polylines = @{intersection_pl(\@polylines, [$bed_polygon])};
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(230,230,230), 1, wxSOLID));
$dc->DrawLine(map @{$to_pixel->([map unscale($_), @$_])}, @$_) for @polylines;
}
# draw bed contour
{
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,0,0), 1, wxSOLID));
$dc->SetBrush(Wx::Brush->new(Wx::Colour->new(255,255,255), wxTRANSPARENT));
$dc->DrawPolygon([ map $to_pixel->($_), @$bed_shape ], 0, 0);
}
my $origin_px = $to_pixel->(Slic3r::Pointf->new(0,0));
# draw axes
{
my $axes_len = 50;
my $arrow_len = 6;
my $arrow_angle = deg2rad(45);
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(255,0,0), 2, wxSOLID)); # red
my $x_end = Slic3r::Pointf->new($origin_px->[X] + $axes_len, $origin_px->[Y]);
$dc->DrawLine(@$origin_px, @$x_end);
foreach my $angle (-$arrow_angle, +$arrow_angle) {
my $end = $x_end->clone;
$end->translate(-$arrow_len, 0);
$end->rotate($angle, $x_end);
$dc->DrawLine(@$x_end, @$end);
}
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,255,0), 2, wxSOLID)); # green
my $y_end = Slic3r::Pointf->new($origin_px->[X], $origin_px->[Y] - $axes_len);
$dc->DrawLine(@$origin_px, @$y_end);
foreach my $angle (-$arrow_angle, +$arrow_angle) {
my $end = $y_end->clone;
$end->translate(0, +$arrow_len);
$end->rotate($angle, $y_end);
$dc->DrawLine(@$y_end, @$end);
}
}
# draw origin
{
$dc->SetPen(Wx::Pen->new(Wx::Colour->new(0,0,0), 1, wxSOLID));
$dc->SetBrush(Wx::Brush->new(Wx::Colour->new(0,0,0), wxSOLID));
$dc->DrawCircle(@$origin_px, 3);
$dc->SetTextForeground(Wx::Colour->new(0,0,0));
$dc->SetFont(Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL));
$dc->DrawText("(0,0)", $origin_px->[X] + 1, $origin_px->[Y] + 2);
}
}
sub _init_shape_options_page {
my ($self, $title) = @_;
my $panel = Wx::Panel->new($self->{shape_options_book});
my $optgroup;
push @{$self->{optgroups}}, $optgroup = Slic3r::GUI::OptionsGroup->new(
parent => $panel,
title => 'Settings',
label_width => 100,
on_change => sub {
my ($opt_id) = @_;
$self->{"_$opt_id"} = $optgroup->get_value($opt_id);
$self->_update_shape;
},
);
$panel->SetSizerAndFit($optgroup->sizer);
$self->{shape_options_book}->AddPage($panel, $title);
return $optgroup;
}
sub _load_stl {
my ($self) = @_;
my $dialog = Wx::FileDialog->new($self, 'Choose a file to import bed shape from (STL/OBJ/AMF):', "", "", &Slic3r::GUI::MODEL_WILDCARD, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if ($dialog->ShowModal != wxID_OK) {
$dialog->Destroy;
return;
}
my $input_file = $dialog->GetPaths;
$dialog->Destroy;
my $model = Slic3r::Model->read_from_file($input_file);
my $mesh = $model->raw_mesh;
my $expolygons = $mesh->horizontal_projection;
if (@$expolygons == 0) {
Slic3r::GUI::show_error($self, "The selected file contains no geometry.");
return;
}
if (@$expolygons > 1) {
Slic3r::GUI::show_error($self, "The selected file contains several disjoint areas. This is not supported.");
return;
}
my $polygon = $expolygons->[0]->contour;
$self->{bed_shape} = [ map [ unscale($_->x), unscale($_->y) ], @$polygon ]; #))
}
sub GetValue {
my ($self) = @_;
return $self->{bed_shape};
}
1;

View File

@@ -1,385 +0,0 @@
package Slic3r::GUI::ConfigWizard;
use strict;
use warnings;
use utf8;
use Wx;
use base 'Wx::Wizard';
use Slic3r::Geometry qw(unscale);
# adhere to various human interface guidelines
our $wizard = 'Wizard';
$wizard = 'Assistant' if &Wx::wxMAC || &Wx::wxGTK;
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, -1, "Configuration $wizard");
# initialize an empty repository
$self->{config} = Slic3r::Config->new;
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Welcome->new($self));
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Firmware->new($self));
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Bed->new($self));
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Nozzle->new($self));
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Filament->new($self));
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Temperature->new($self));
$self->add_page(Slic3r::GUI::ConfigWizard::Page::BedTemperature->new($self));
$self->add_page(Slic3r::GUI::ConfigWizard::Page::Finished->new($self));
$_->build_index for @{$self->{pages}};
return $self;
}
sub add_page {
my $self = shift;
my ($page) = @_;
my $n = push @{$self->{pages}}, $page;
# add first page to the page area sizer
$self->GetPageAreaSizer->Add($page) if $n == 1;
# link pages
$self->{pages}[$n-2]->set_next_page($page) if $n >= 2;
$page->set_previous_page($self->{pages}[$n-2]) if $n >= 2;
}
sub run {
my $self = shift;
if (Wx::Wizard::RunWizard($self, $self->{pages}[0])) {
# it would be cleaner to have these defined inside each page class,
# in some event getting called before leaving the page
{
# set first_layer_height + layer_height based on nozzle_diameter
my $nozzle = $self->{config}->nozzle_diameter;
$self->{config}->set('first_layer_height', $nozzle->[0]);
$self->{config}->set('layer_height', $nozzle->[0] - 0.1);
# set first_layer_temperature to temperature + 5
$self->{config}->set('first_layer_temperature', [$self->{config}->temperature->[0] + 5]);
# set first_layer_bed_temperature to temperature + 5
$self->{config}->set('first_layer_bed_temperature',
($self->{config}->bed_temperature > 0) ? ($self->{config}->bed_temperature + 5) : 0);
}
$self->Destroy;
return $self->{config};
} else {
$self->Destroy;
return undef;
}
}
package Slic3r::GUI::ConfigWizard::Index;
use Wx qw(:bitmap :dc :font :misc :sizer :systemsettings :window);
use Wx::Event qw(EVT_ERASE_BACKGROUND EVT_PAINT);
use base 'Wx::Panel';
sub new {
my $class = shift;
my ($parent, $title) = @_;
my $self = $class->SUPER::new($parent);
push @{$self->{titles}}, $title;
$self->{own_index} = 0;
$self->{bullets}->{before} = Wx::Bitmap->new("$Slic3r::var/bullet_black.png", wxBITMAP_TYPE_PNG);
$self->{bullets}->{own} = Wx::Bitmap->new("$Slic3r::var/bullet_blue.png", wxBITMAP_TYPE_PNG);
$self->{bullets}->{after} = Wx::Bitmap->new("$Slic3r::var/bullet_white.png", wxBITMAP_TYPE_PNG);
$self->{background} = Wx::Bitmap->new("$Slic3r::var/Slic3r_192px_transparent.png", wxBITMAP_TYPE_PNG);
$self->SetMinSize(Wx::Size->new($self->{background}->GetWidth, $self->{background}->GetHeight));
EVT_PAINT($self, \&repaint);
return $self;
}
sub repaint {
my ($self, $event) = @_;
my $size = $self->GetClientSize;
my $gap = 5;
my $dc = Wx::PaintDC->new($self);
$dc->SetBackgroundMode(wxTRANSPARENT);
$dc->SetFont($self->GetFont);
$dc->SetTextForeground($self->GetForegroundColour);
my $background_h = $self->{background}->GetHeight;
my $background_w = $self->{background}->GetWidth;
$dc->DrawBitmap($self->{background}, ($size->GetWidth - $background_w) / 2, ($size->GetHeight - $background_h) / 2, 1);
my $label_h = $self->{bullets}->{own}->GetHeight;
$label_h = $dc->GetCharHeight if $dc->GetCharHeight > $label_h;
my $label_w = $size->GetWidth;
my $i = 0;
foreach (@{$self->{titles}}) {
my $bullet = $self->{bullets}->{own};
$bullet = $self->{bullets}->{before} if $i < $self->{own_index};
$bullet = $self->{bullets}->{after} if $i > $self->{own_index};
$dc->SetTextForeground(Wx::Colour->new(128, 128, 128)) if $i > $self->{own_index};
$dc->DrawLabel($_, $bullet, Wx::Rect->new(0, $i * ($label_h + $gap), $label_w, $label_h));
$i++;
}
$event->Skip;
}
sub prepend_title {
my $self = shift;
my ($title) = @_;
unshift @{$self->{titles}}, $title;
$self->{own_index}++;
$self->Refresh;
}
sub append_title {
my $self = shift;
my ($title) = @_;
push @{$self->{titles}}, $title;
$self->Refresh;
}
package Slic3r::GUI::ConfigWizard::Page;
use Wx qw(:font :misc :sizer :staticline :systemsettings);
use base 'Wx::WizardPage';
sub new {
my $class = shift;
my ($parent, $title, $short_title) = @_;
my $self = $class->SUPER::new($parent);
my $sizer = Wx::FlexGridSizer->new(0, 2, 10, 10);
$sizer->AddGrowableCol(1, 1);
$sizer->AddGrowableRow(1, 1);
$sizer->AddStretchSpacer(0);
$self->SetSizer($sizer);
# title
my $text = Wx::StaticText->new($self, -1, $title, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
my $bold_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
$bold_font->SetWeight(wxFONTWEIGHT_BOLD);
$bold_font->SetPointSize(14);
$text->SetFont($bold_font);
$sizer->Add($text, 0, wxALIGN_LEFT, 0);
# index
$self->{short_title} = $short_title ? $short_title : $title;
$self->{index} = Slic3r::GUI::ConfigWizard::Index->new($self, $self->{short_title});
$sizer->Add($self->{index}, 1, wxEXPAND | wxTOP | wxRIGHT, 10);
# contents
$self->{width} = 430;
$self->{vsizer} = Wx::BoxSizer->new(wxVERTICAL);
$sizer->Add($self->{vsizer}, 1);
return $self;
}
sub append_text {
my $self = shift;
my ($text) = @_;
my $para = Wx::StaticText->new($self, -1, $text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
$para->Wrap($self->{width});
$para->SetMinSize([$self->{width}, -1]);
$self->{vsizer}->Add($para, 0, wxALIGN_LEFT | wxTOP | wxBOTTOM, 10);
}
sub append_option {
my $self = shift;
my ($full_key) = @_;
# populate repository with the factory default
my $opt_key = $full_key;
$opt_key =~ s/#.+//;
$self->config->apply(Slic3r::Config->new_from_defaults($opt_key));
# draw the control
my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new(
parent => $self,
title => '',
config => $self->config,
options => [$full_key],
full_labels => 1,
);
$self->{vsizer}->Add($optgroup->sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
}
sub append_panel {
my ($self, $panel) = @_;
$self->{vsizer}->Add($panel, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
}
sub set_previous_page {
my $self = shift;
my ($previous_page) = @_;
$self->{previous_page} = $previous_page;
}
sub GetPrev {
my $self = shift;
return $self->{previous_page};
}
sub set_next_page {
my $self = shift;
my ($next_page) = @_;
$self->{next_page} = $next_page;
}
sub GetNext {
my $self = shift;
return $self->{next_page};
}
sub get_short_title {
my $self = shift;
return $self->{short_title};
}
sub build_index {
my $self = shift;
my $page = $self;
$self->{index}->prepend_title($page->get_short_title) while ($page = $page->GetPrev);
$page = $self;
$self->{index}->append_title($page->get_short_title) while ($page = $page->GetNext);
}
sub config {
my ($self) = @_;
return $self->GetParent->{config};
}
package Slic3r::GUI::ConfigWizard::Page::Welcome;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, "Welcome to the Slic3r Configuration $wizard", 'Welcome');
$self->append_text('Hello, welcome to Slic3r! This '.lc($wizard).' helps you with the initial configuration; just a few settings and you will be ready to print.');
$self->append_text('To import an existing configuration instead, cancel this '.lc($wizard).' and use the Open Config menu item found in the File menu.');
$self->append_text('To continue, click Next.');
return $self;
}
package Slic3r::GUI::ConfigWizard::Page::Firmware;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, 'Firmware Type');
$self->append_text('Choose the type of firmware used by your printer, then click Next.');
$self->append_option('gcode_flavor');
return $self;
}
package Slic3r::GUI::ConfigWizard::Page::Bed;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, 'Bed Size');
$self->append_text('Set the shape of your printer\'s bed, then click Next.');
$self->config->apply(Slic3r::Config->new_from_defaults('bed_shape'));
$self->{bed_shape_panel} = my $panel = Slic3r::GUI::BedShapePanel->new($self, $self->config->bed_shape);
$self->{bed_shape_panel}->on_change(sub {
$self->config->set('bed_shape', $self->{bed_shape_panel}->GetValue);
});
$self->append_panel($self->{bed_shape_panel});
return $self;
}
package Slic3r::GUI::ConfigWizard::Page::Nozzle;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, 'Nozzle Diameter');
$self->append_text('Enter the diameter of your printer\'s hot end nozzle, then click Next.');
$self->append_option('nozzle_diameter#0');
return $self;
}
package Slic3r::GUI::ConfigWizard::Page::Filament;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, 'Filament Diameter');
$self->append_text('Enter the diameter of your filament, then click Next.');
$self->append_text('Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average.');
$self->append_option('filament_diameter#0');
return $self;
}
package Slic3r::GUI::ConfigWizard::Page::Temperature;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, 'Extrusion Temperature');
$self->append_text('Enter the temperature needed for extruding your filament, then click Next.');
$self->append_text('A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS.');
$self->append_option('temperature#0');
return $self;
}
package Slic3r::GUI::ConfigWizard::Page::BedTemperature;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, 'Bed Temperature');
$self->append_text('Enter the bed temperature needed for getting your filament to stick to your heated bed, then click Next.');
$self->append_text('A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.');
$self->append_option('bed_temperature');
return $self;
}
package Slic3r::GUI::ConfigWizard::Page::Finished;
use base 'Slic3r::GUI::ConfigWizard::Page';
sub new {
my $class = shift;
my ($parent) = @_;
my $self = $class->SUPER::new($parent, 'Congratulations!', 'Finish');
$self->append_text("You have successfully completed the Slic3r Configuration $wizard. " .
'Slic3r is now configured for your printer and filament.');
$self->append_text('To close this '.lc($wizard).' and apply the newly created configuration, click Finish.');
return $self;
}
1;

View File

@@ -0,0 +1,190 @@
# The "Controller" tab to control the printer using serial / USB.
# This feature is rarely used. Much more often, the firmware reads the G-codes from a SD card.
# May there be multiple subtabs per each printer connected?
package Slic3r::GUI::Controller;
use strict;
use warnings;
use utf8;
use Wx qw(wxTheApp :frame :id :misc :sizer :bitmap :button :icon :dialog wxBORDER_NONE);
use Wx::Event qw(EVT_CLOSE EVT_LEFT_DOWN EVT_MENU);
use base qw(Wx::ScrolledWindow Class::Accessor);
use List::Util qw(first);
__PACKAGE__->mk_accessors(qw(_selected_printer_preset));
our @ConfigOptions = qw(bed_shape serial_port serial_speed);
sub new {
my ($class, $parent) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, [600,350]);
$self->SetScrollbars(0, 1, 0, 1);
$self->{sizer} = my $sizer = Wx::BoxSizer->new(wxVERTICAL);
# warning to show when there are no printers configured
{
$self->{text_no_printers} = Wx::StaticText->new($self, -1,
"No printers were configured for USB/serial control.",
wxDefaultPosition, wxDefaultSize);
$self->{sizer}->Add($self->{text_no_printers}, 0, wxTOP | wxLEFT, 30);
}
# button for adding new printer panels
{
my $btn = $self->{btn_add} = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new(Slic3r::var("add.png"), wxBITMAP_TYPE_PNG),
wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
$btn->SetToolTipString("Add printer…")
if $btn->can('SetToolTipString');
EVT_LEFT_DOWN($btn, sub {
my $menu = Wx::Menu->new;
my @panels = $self->print_panels;
# remove printers that already exist
# update configs of currently loaded print panels
foreach my $preset (@{wxTheApp->{preset_bundle}->printer}) {
my $preset_name = $preset->name;
next if ! $preset->config->serial_port ||
defined first { defined $_ && $_->printer_name eq $preset_name } @panels;
my $myconfig = $preset->config->clone_only(\@ConfigOptions);
my $id = &Wx::NewId();
$menu->Append($id, $preset_name);
EVT_MENU($menu, $id, sub {
$self->add_printer($preset_name, $myconfig);
});
}
$self->PopupMenu($menu, $btn->GetPosition);
$menu->Destroy;
});
$self->{sizer}->Add($btn, 0, wxTOP | wxLEFT, 10);
}
$self->SetSizer($sizer);
$self->SetMinSize($self->GetSize);
#$sizer->SetSizeHints($self);
EVT_CLOSE($self, sub {
my (undef, $event) = @_;
if ($event->CanVeto) {
foreach my $panel ($self->print_panels) {
if ($panel->printing) {
my $confirm = Wx::MessageDialog->new(
$self, "Printer '" . $panel->printer_name . "' is printing.\n\nDo you want to stop printing?",
'Unfinished Print', wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION,
);
if ($confirm->ShowModal == wxID_NO) {
$event->Veto;
return;
}
}
}
}
foreach my $panel ($self->print_panels) {
$panel->disconnect;
}
$event->Skip;
});
$self->Layout;
return $self;
}
sub OnActivate {
my ($self) = @_;
# get all available presets
my %presets = map { $_->name => $_->config->clone_only(\@ConfigOptions) }
grep { $_->config->serial_port } @{wxTheApp->{preset_bundle}->printer};
# decide which ones we want to keep
my %active = ();
# keep the ones that are currently connected or have jobs in queue
$active{$_} = 1 for map $_->printer_name,
grep { $_->is_connected || @{$_->jobs} > 0 }
$self->print_panels;
if (%presets) {
# if there are no active panels, use sensible defaults
if (!%active && keys %presets <= 2) {
# if only one or two presets exist, load them
$active{$_} = 1 for keys %presets;
}
if (!%active) {
# enable printers whose port is available
my %ports = map { $_ => 1 } Slic3r::GUI::scan_serial_ports;
$active{$_} = 1
for grep exists $ports{$presets{$_}->serial_port}, keys %presets;
}
if (!%active && $self->_selected_printer_preset) {
# enable currently selected printer if it is configured
$active{$self->_selected_printer_preset} = 1
if $presets{$self->_selected_printer_preset};
}
}
# apply changes
for my $panel ($self->print_panels) {
next if $active{$panel->printer_name};
$self->{sizer}->DetachWindow($panel);
$panel->Destroy;
}
$self->add_printer($_, $presets{$_}) for sort keys %active;
# show/hide the warning about no printers
$self->{text_no_printers}->Show(!%presets);
# show/hide the Add button
$self->{btn_add}->Show(keys %presets != keys %active);
$self->Layout;
# we need this in order to trigger the OnSize event of wxScrolledWindow which
# recalculates the virtual size
Wx::GetTopLevelParent($self)->SendSizeEvent;
}
sub add_printer {
my ($self, $printer_name, $config) = @_;
# check that printer doesn't exist already
foreach my $panel ($self->print_panels) {
if ($panel->printer_name eq $printer_name) {
return $panel;
}
}
my $printer_panel = Slic3r::GUI::Controller::PrinterPanel->new($self, $printer_name, $config);
$self->{sizer}->Prepend($printer_panel, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 10);
$self->Layout;
return $printer_panel;
}
sub print_panels {
my ($self) = @_;
return grep $_->isa('Slic3r::GUI::Controller::PrinterPanel'),
map $_->GetWindow, $self->{sizer}->GetChildren;
}
# Called by Slic3r::GUI::Tab::Printer::_on_presets_changed
# when the presets are loaded or the user selects another preset.
sub update_presets {
my ($self, $presets) = @_;
# update configs of currently loaded print panels
my @presets = @$presets;
foreach my $panel ($self->print_panels) {
my $preset = $presets->find_preset($panel->printer_name, 0);
$panel->config($preset->config->clone_only(\@ConfigOptions))
if defined $preset;
}
$self->_selected_printer_preset($presets->get_selected_preset->name);
}
1;

View File

@@ -0,0 +1,190 @@
# A printer "Controller" -> "ManualControlDialog" subtab, opened per 3D printer connected?
package Slic3r::GUI::Controller::ManualControlDialog;
use strict;
use warnings;
use utf8;
use Wx qw(:dialog :id :misc :sizer :choicebook :button :bitmap
wxBORDER_NONE wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_CLOSE EVT_BUTTON);
use base qw(Wx::Dialog Class::Accessor);
__PACKAGE__->mk_accessors(qw(sender config2 x_homed y_homed));
sub new {
my ($class, $parent, $config, $sender) = @_;
my $self = $class->SUPER::new($parent, -1, "Manual Control", wxDefaultPosition,
[500,380], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
$self->sender($sender);
$self->config2({
xy_travel_speed => 130,
z_travel_speed => 10,
});
my $bed_sizer = Wx::FlexGridSizer->new(2, 3, 1, 1);
$bed_sizer->AddGrowableCol(1, 1);
$bed_sizer->AddGrowableRow(0, 1);
my $move_button = sub {
my ($sizer, $label, $icon, $bold, $pos, $handler) = @_;
my $btn = Wx::Button->new($self, -1, $label, wxDefaultPosition, wxDefaultSize,
wxBU_LEFT | wxBU_EXACTFIT);
$btn->SetFont($bold ? $Slic3r::GUI::small_bold_font : $Slic3r::GUI::small_font);
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("$icon.png"), wxBITMAP_TYPE_PNG));
$btn->SetBitmapPosition($pos);
EVT_BUTTON($self, $btn, $handler);
$sizer->Add($btn, 1, wxEXPAND | wxALL, 0);
};
# Y buttons
{
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
for my $d (qw(+10 +1 +0.1)) {
$move_button->($sizer, $d, 'arrow_up', 0, wxLEFT, sub { $self->rel_move('Y', $d) });
}
$move_button->($sizer, 'Y', 'house', 1, wxLEFT, sub { $self->home('Y') });
for my $d (qw(-0.1 -1 -10)) {
$move_button->($sizer, $d, 'arrow_down', 0, wxLEFT, sub { $self->rel_move('Y', $d) });
};
$bed_sizer->Add($sizer, 1, wxEXPAND, 0);
}
# Bed canvas
{
my $bed_shape = $config->bed_shape;
$self->{canvas} = my $canvas = Slic3r::GUI::2DBed->new($self, $bed_shape);
$canvas->interactive(1);
$canvas->on_move(sub {
my ($pos) = @_;
if (!($self->x_homed && $self->y_homed)) {
Slic3r::GUI::show_error($self, "Please home both X and Y before moving.");
return ;
}
# delete any pending commands to get a smoother movement
$self->sender->purge_queue(1);
$self->abs_xy_move($pos);
});
$bed_sizer->Add($canvas, 0, wxEXPAND | wxRIGHT, 3);
}
# Z buttons
{
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
for my $d (qw(+10 +1 +0.1)) {
$move_button->($sizer, $d, 'arrow_up', 0, wxLEFT, sub { $self->rel_move('Z', $d) });
}
$move_button->($sizer, 'Z', 'house', 1, wxLEFT, sub { $self->home('Z') });
for my $d (qw(-0.1 -1 -10)) {
$move_button->($sizer, $d, 'arrow_down', 0, wxLEFT, sub { $self->rel_move('Z', $d) });
};
$bed_sizer->Add($sizer, 1, wxEXPAND, 0);
}
# XYZ home button
$move_button->($bed_sizer, 'XYZ', 'house', 1, wxTOP, sub { $self->home(undef) });
# X buttons
{
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
for my $d (qw(-10 -1 -0.1)) {
$move_button->($sizer, $d, 'arrow_left', 0, wxTOP, sub { $self->rel_move('X', $d) });
}
$move_button->($sizer, 'X', 'house', 1, wxTOP, sub { $self->home('X') });
for my $d (qw(+0.1 +1 +10)) {
$move_button->($sizer, $d, 'arrow_right', 0, wxTOP, sub { $self->rel_move('X', $d) });
}
$bed_sizer->Add($sizer, 1, wxEXPAND, 0);
}
my $optgroup = Slic3r::GUI::OptionsGroup->new(
parent => $self,
title => 'Settings',
on_change => sub {
my ($opt_id, $value) = @_;
$self->config2->{$opt_id} = $value;
},
);
{
my $line = Slic3r::GUI::OptionsGroup::Line->new(
label => 'Speed (mm/s)',
);
$line->append_option(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'xy_travel_speed',
type => 'f',
label => 'X/Y',
tooltip => '',
default => $self->config2->{xy_travel_speed},
));
$line->append_option(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'z_travel_speed',
type => 'f',
label => 'Z',
tooltip => '',
default => $self->config2->{z_travel_speed},
));
$optgroup->append_line($line);
}
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
$main_sizer->Add($bed_sizer, 1, wxEXPAND | wxALL, 10);
$main_sizer->Add($optgroup->sizer, 0, wxEXPAND | wxALL, 10);
#$main_sizer->Add($self->CreateButtonSizer(wxCLOSE), 0, wxEXPAND);
#EVT_BUTTON($self, wxID_CLOSE, sub { $self->Close });
$self->SetSizer($main_sizer);
$self->SetMinSize($self->GetSize);
#$main_sizer->SetSizeHints($self);
$self->Layout;
# needed to actually free memory
EVT_CLOSE($self, sub {
$self->EndModal(wxID_OK);
$self->Destroy;
});
return $self;
}
sub abs_xy_move {
my ($self, $pos) = @_;
$self->sender->send("G90", 1); # set absolute positioning
$self->sender->send(sprintf("G1 X%.1f Y%.1f F%d", @$pos, $self->config2->{xy_travel_speed}*60), 1);
$self->{canvas}->set_pos($pos);
}
sub rel_move {
my ($self, $axis, $distance) = @_;
my $speed = ($axis eq 'Z') ? $self->config2->{z_travel_speed} : $self->config2->{xy_travel_speed};
$self->sender->send("G91", 1); # set relative positioning
$self->sender->send(sprintf("G1 %s%.1f F%d", $axis, $distance, $speed*60), 1);
$self->sender->send("G90", 1); # set absolute positioning
if (my $pos = $self->{canvas}->pos) {
if ($axis eq 'X') {
$pos->translate($distance, 0);
} elsif ($axis eq 'Y') {
$pos->translate(0, $distance);
}
$self->{canvas}->set_pos($pos);
}
}
sub home {
my ($self, $axis) = @_;
$axis //= '';
$self->sender->send(sprintf("G28 %s", $axis), 1);
$self->{canvas}->set_pos(undef);
$self->x_homed(1) if $axis eq 'X';
$self->y_homed(1) if $axis eq 'Y';
}
1;

View File

@@ -0,0 +1,707 @@
package Slic3r::GUI::Controller::PrinterPanel;
use strict;
use warnings;
use utf8;
use Wx qw(wxTheApp :panel :id :misc :sizer :button :bitmap :window :gauge :timer
:textctrl :font :systemsettings);
use Wx::Event qw(EVT_BUTTON EVT_MOUSEWHEEL EVT_TIMER EVT_SCROLLWIN);
use base qw(Wx::Panel Class::Accessor);
__PACKAGE__->mk_accessors(qw(printer_name config sender jobs
printing status_timer temp_timer));
use constant CONNECTION_TIMEOUT => 3; # seconds
use constant STATUS_TIMER_INTERVAL => 1000; # milliseconds
use constant TEMP_TIMER_INTERVAL => 5000; # milliseconds
sub new {
my ($class, $parent, $printer_name, $config) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, [500, 250]);
$self->printer_name($printer_name || 'Printer');
$self->config($config);
$self->jobs([]);
# set up the timer that polls for updates
{
my $timer_id = &Wx::NewId();
$self->status_timer(Wx::Timer->new($self, $timer_id));
EVT_TIMER($self, $timer_id, sub {
my ($self, $event) = @_;
if ($self->printing) {
my $queue_size = $self->sender->queue_size;
$self->{gauge}->SetValue($self->{gauge}->GetRange - $queue_size);
if ($queue_size == 0) {
$self->print_completed;
}
}
$self->{log_textctrl}->AppendText("$_\n") for @{$self->sender->purge_log};
{
my $temp = $self->sender->getT;
if ($temp eq '') {
$self->{temp_panel}->Hide;
} else {
if (!$self->{temp_panel}->IsShown) {
$self->{temp_panel}->Show;
$self->Layout;
}
$self->{temp_text}->SetLabel($temp . "°C");
$temp = $self->sender->getB;
if ($temp eq '') {
$self->{bed_temp_text}->SetLabel('n.a.');
} else {
$self->{bed_temp_text}->SetLabel($temp . "°C");
}
}
}
});
}
# set up the timer that sends temperature requests
# (responses are handled by status_timer)
{
my $timer_id = &Wx::NewId();
$self->temp_timer(Wx::Timer->new($self, $timer_id));
EVT_TIMER($self, $timer_id, sub {
my ($self, $event) = @_;
$self->sender->send("M105", 1); # send it through priority queue
});
}
my $box = Wx::StaticBox->new($self, -1, "");
my $sizer = Wx::StaticBoxSizer->new($box, wxHORIZONTAL);
my $left_sizer = Wx::BoxSizer->new(wxVERTICAL);
# printer name
{
my $text = Wx::StaticText->new($box, -1, $self->printer_name, wxDefaultPosition, [220,-1]);
my $font = $text->GetFont;
$font->SetPointSize(20);
$text->SetFont($font);
$left_sizer->Add($text, 0, wxEXPAND, 0);
}
# connection info
{
my $conn_sizer = Wx::FlexGridSizer->new(2, 2, 1, 0);
$conn_sizer->SetFlexibleDirection(wxHORIZONTAL);
$conn_sizer->AddGrowableCol(1, 1);
$left_sizer->Add($conn_sizer, 0, wxEXPAND | wxTOP, 5);
{
my $text = Wx::StaticText->new($box, -1, "Port:", wxDefaultPosition, wxDefaultSize);
$text->SetFont($Slic3r::GUI::small_font);
$conn_sizer->Add($text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
}
my $serial_port_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
{
$self->{serial_port_combobox} = Wx::ComboBox->new($box, -1, $config->serial_port, wxDefaultPosition, wxDefaultSize, []);
$self->{serial_port_combobox}->SetFont($Slic3r::GUI::small_font);
$self->update_serial_ports;
$serial_port_sizer->Add($self->{serial_port_combobox}, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 1);
}
{
$self->{btn_rescan_serial} = my $btn = Wx::BitmapButton->new($box, -1, Wx::Bitmap->new(Slic3r::var("arrow_rotate_clockwise.png"), wxBITMAP_TYPE_PNG),
wxDefaultPosition, wxDefaultSize, &Wx::wxBORDER_NONE);
$btn->SetToolTipString("Rescan serial ports")
if $btn->can('SetToolTipString');
$serial_port_sizer->Add($btn, 0, wxALIGN_CENTER_VERTICAL, 0);
EVT_BUTTON($self, $btn, sub { $self->update_serial_ports });
}
$conn_sizer->Add($serial_port_sizer, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
{
my $text = Wx::StaticText->new($box, -1, "Speed:", wxDefaultPosition, wxDefaultSize);
$text->SetFont($Slic3r::GUI::small_font);
$conn_sizer->Add($text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
}
my $serial_speed_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
{
$self->{serial_speed_combobox} = Wx::ComboBox->new($box, -1, $config->serial_speed, wxDefaultPosition, wxDefaultSize,
["115200", "250000"]);
$self->{serial_speed_combobox}->SetFont($Slic3r::GUI::small_font);
$serial_speed_sizer->Add($self->{serial_speed_combobox}, 0, wxALIGN_CENTER_VERTICAL, 0);
}
{
$self->{btn_disconnect} = my $btn = Wx::Button->new($box, -1, "Disconnect", wxDefaultPosition, wxDefaultSize);
$btn->SetFont($Slic3r::GUI::small_font);
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("delete.png"), wxBITMAP_TYPE_PNG));
$serial_speed_sizer->Add($btn, 0, wxLEFT, 5);
EVT_BUTTON($self, $btn, \&disconnect);
}
$conn_sizer->Add($serial_speed_sizer, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
}
# buttons
{
$self->{btn_connect} = my $btn = Wx::Button->new($box, -1, "Connect to printer", wxDefaultPosition, [-1, 40]);
my $font = $btn->GetFont;
$font->SetPointSize($font->GetPointSize + 2);
$btn->SetFont($font);
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("arrow_up.png"), wxBITMAP_TYPE_PNG));
$left_sizer->Add($btn, 0, wxTOP, 15);
EVT_BUTTON($self, $btn, \&connect);
}
# print progress bar
{
my $gauge = $self->{gauge} = Wx::Gauge->new($self, wxGA_HORIZONTAL, 100, wxDefaultPosition, wxDefaultSize);
$left_sizer->Add($self->{gauge}, 0, wxEXPAND | wxTOP, 15);
$gauge->Hide;
}
# status
$self->{status_text} = Wx::StaticText->new($box, -1, "", wxDefaultPosition, [200,-1]);
$left_sizer->Add($self->{status_text}, 1, wxEXPAND | wxTOP, 15);
# manual control
{
$self->{btn_manual_control} = my $btn = Wx::Button->new($box, -1, "Manual control", wxDefaultPosition, wxDefaultSize);
$btn->SetFont($Slic3r::GUI::small_font);
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("cog.png"), wxBITMAP_TYPE_PNG));
$btn->Hide;
$left_sizer->Add($btn, 0, wxTOP, 15);
EVT_BUTTON($self, $btn, sub {
my $dlg = Slic3r::GUI::Controller::ManualControlDialog->new
($self, $self->config, $self->sender);
$dlg->ShowModal;
});
}
# temperature
{
my $temp_panel = $self->{temp_panel} = Wx::Panel->new($box, -1);
my $temp_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
my $temp_font = Wx::Font->new($Slic3r::GUI::small_font);
$temp_font->SetWeight(wxFONTWEIGHT_BOLD);
{
my $text = Wx::StaticText->new($temp_panel, -1, "Temperature:", wxDefaultPosition, wxDefaultSize);
$text->SetFont($Slic3r::GUI::small_font);
$temp_sizer->Add($text, 0, wxALIGN_CENTER_VERTICAL);
$self->{temp_text} = Wx::StaticText->new($temp_panel, -1, "", wxDefaultPosition, wxDefaultSize);
$self->{temp_text}->SetFont($temp_font);
$self->{temp_text}->SetForegroundColour(Wx::wxRED);
$temp_sizer->Add($self->{temp_text}, 1, wxALIGN_CENTER_VERTICAL);
}
{
my $text = Wx::StaticText->new($temp_panel, -1, "Bed:", wxDefaultPosition, wxDefaultSize);
$text->SetFont($Slic3r::GUI::small_font);
$temp_sizer->Add($text, 0, wxALIGN_CENTER_VERTICAL);
$self->{bed_temp_text} = Wx::StaticText->new($temp_panel, -1, "", wxDefaultPosition, wxDefaultSize);
$self->{bed_temp_text}->SetFont($temp_font);
$self->{bed_temp_text}->SetForegroundColour(Wx::wxRED);
$temp_sizer->Add($self->{bed_temp_text}, 1, wxALIGN_CENTER_VERTICAL);
}
$temp_panel->SetSizer($temp_sizer);
$temp_panel->Hide;
$left_sizer->Add($temp_panel, 0, wxEXPAND | wxTOP | wxBOTTOM, 4);
}
# print jobs panel
$self->{print_jobs_sizer} = my $print_jobs_sizer = Wx::BoxSizer->new(wxVERTICAL);
{
my $text = Wx::StaticText->new($box, -1, "Queue:", wxDefaultPosition, wxDefaultSize);
$text->SetFont($Slic3r::GUI::small_font);
$print_jobs_sizer->Add($text, 0, wxEXPAND, 0);
$self->{jobs_panel} = Wx::ScrolledWindow->new($box, -1, wxDefaultPosition, wxDefaultSize,
wxVSCROLL | wxBORDER_NONE);
$self->{jobs_panel}->SetScrollbars(0, 1, 0, 1);
$self->{jobs_panel_sizer} = Wx::BoxSizer->new(wxVERTICAL);
$self->{jobs_panel}->SetSizer($self->{jobs_panel_sizer});
$print_jobs_sizer->Add($self->{jobs_panel}, 1, wxEXPAND, 0);
# TODO: fix this. We're trying to pass the scroll event to the parent but it
# doesn't work.
EVT_SCROLLWIN($self->{jobs_panel}, sub {
my ($panel, $event) = @_;
my $controller = $self->GetParent;
my $new_event = Wx::ScrollWinEvent->new(
$event->GetEventType,
$event->GetPosition,
$event->GetOrientation,
);
$controller->ProcessEvent($new_event);
}) if 0;
}
my $log_sizer = Wx::BoxSizer->new(wxVERTICAL);
{
my $text = Wx::StaticText->new($box, -1, "Log:", wxDefaultPosition, wxDefaultSize);
$text->SetFont($Slic3r::GUI::small_font);
$log_sizer->Add($text, 0, wxEXPAND, 0);
my $log = $self->{log_textctrl} = Wx::TextCtrl->new($box, -1, "", wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxBORDER_NONE);
$log->SetBackgroundColour($box->GetBackgroundColour);
$log->SetFont($Slic3r::GUI::small_font);
$log->SetEditable(0);
$log_sizer->Add($self->{log_textctrl}, 1, wxEXPAND, 0);
}
$sizer->Add($left_sizer, 0, wxEXPAND | wxALL, 0);
$sizer->Add($print_jobs_sizer, 2, wxEXPAND | wxALL, 0);
$sizer->Add($log_sizer, 1, wxEXPAND | wxLEFT, 15);
$self->SetSizer($sizer);
$self->SetMinSize($self->GetSize);
$self->_update_connection_controls;
return $self;
}
sub is_connected {
my ($self) = @_;
return $self->sender && $self->sender->is_connected;
}
sub _update_connection_controls {
my ($self) = @_;
$self->{btn_connect}->Show;
$self->{btn_disconnect}->Hide;
$self->{serial_port_combobox}->Enable;
$self->{serial_speed_combobox}->Enable;
$self->{btn_rescan_serial}->Enable;
$self->{btn_manual_control}->Hide;
$self->{btn_manual_control}->Disable;
if ($self->is_connected) {
$self->{btn_connect}->Hide;
$self->{btn_manual_control}->Show;
if (!$self->printing || $self->printing->paused) {
$self->{btn_disconnect}->Show;
$self->{btn_manual_control}->Enable;
}
$self->{serial_port_combobox}->Disable;
$self->{serial_speed_combobox}->Disable;
$self->{btn_rescan_serial}->Disable;
}
$self->Layout;
}
sub set_status {
my ($self, $status) = @_;
$self->{status_text}->SetLabel($status);
$self->{status_text}->Wrap($self->{status_text}->GetSize->GetWidth);
$self->{status_text}->Refresh;
$self->Layout;
}
sub connect {
my ($self) = @_;
return if $self->is_connected;
$self->set_status("Connecting...");
$self->sender(Slic3r::GCode::Sender->new);
my $res = $self->sender->connect(
$self->{serial_port_combobox}->GetValue,
$self->{serial_speed_combobox}->GetValue,
);
if (!$res) {
$self->set_status("Connection failed. Check serial port and speed.");
} else {
if ($self->sender->wait_connected) {
$self->set_status("Printer is online. You can now start printing from the queue on the right.");
$self->status_timer->Start(STATUS_TIMER_INTERVAL, wxTIMER_CONTINUOUS);
$self->temp_timer->Start(TEMP_TIMER_INTERVAL, wxTIMER_CONTINUOUS);
# request temperature now, without waiting for the timer
$self->sender->send("M105", 1);
} else {
$self->set_status("Connection failed. Check serial port and speed.");
}
}
$self->_update_connection_controls;
$self->reload_jobs;
}
sub disconnect {
my ($self) = @_;
$self->status_timer->Stop;
$self->temp_timer->Stop;
return if !$self->is_connected;
$self->printing->printing(0) if $self->printing;
$self->printing(undef);
$self->{gauge}->Hide;
$self->{temp_panel}->Hide;
$self->sender->disconnect;
$self->set_status("");
$self->_update_connection_controls;
$self->reload_jobs;
}
sub update_serial_ports {
my ($self) = @_;
my $cb = $self->{serial_port_combobox};
my $current = $cb->GetValue;
$cb->Clear;
$cb->Append($_) for Slic3r::GUI::scan_serial_ports;
$cb->SetValue($current);
}
sub load_print_job {
my ($self, $gcode_file, $filament_stats) = @_;
push @{$self->jobs}, my $job = Slic3r::GUI::Controller::PrinterPanel::PrintJob->new(
id => time() . $gcode_file . rand(1000),
gcode_file => $gcode_file,
filament_stats => $filament_stats,
);
$self->reload_jobs;
return $job;
}
sub delete_job {
my ($self, $job) = @_;
$self->jobs([ grep $_->id ne $job->id, @{$self->jobs} ]);
$self->reload_jobs;
}
sub print_job {
my ($self, $job) = @_;
$self->printing($job);
$job->printing(1);
$self->reload_jobs;
open my $fh, '<', $job->gcode_file;
my $line_count = 0;
while (my $row = <$fh>) {
$self->sender->send($row);
$line_count++;
}
close $fh;
$self->_update_connection_controls;
$self->{gauge}->SetRange($line_count);
$self->{gauge}->SetValue(0);
$self->{gauge}->Enable;
$self->{gauge}->Show;
$self->Layout;
$self->set_status('Printing...');
$self->{log_textctrl}->AppendText(sprintf "=====\n");
$self->{log_textctrl}->AppendText(sprintf "Printing %s\n", $job->name);
$self->{log_textctrl}->AppendText(sprintf "Print started at %s\n", $self->_timestamp);
}
sub print_completed {
my ($self) = @_;
my $job = $self->printing;
$self->printing(undef);
$job->printing(0);
$job->printed(1);
$self->_update_connection_controls;
$self->{gauge}->Hide;
$self->Layout;
$self->set_status('Print completed.');
$self->{log_textctrl}->AppendText(sprintf "Print completed at %s\n", $self->_timestamp);
$self->reload_jobs;
}
sub reload_jobs {
my ($self) = @_;
# reorder jobs
@{$self->jobs} = sort { ($a->printed <=> $b->printed) || ($a->timestamp <=> $b->timestamp) }
@{$self->jobs};
# remove all panels
foreach my $child ($self->{jobs_panel_sizer}->GetChildren) {
my $window = $child->GetWindow;
$self->{jobs_panel_sizer}->Detach($window);
# now $child does not exist anymore
$window->Destroy;
}
# re-add all panels
foreach my $job (@{$self->jobs}) {
my $panel = Slic3r::GUI::Controller::PrinterPanel::PrintJobPanel->new($self->{jobs_panel}, $job);
$self->{jobs_panel_sizer}->Add($panel, 0, wxEXPAND | wxBOTTOM, 5);
$panel->on_delete_job(sub {
my ($job) = @_;
$self->delete_job($job);
});
$panel->on_print_job(sub {
my ($job) = @_;
$self->print_job($job);
});
$panel->on_pause_print(sub {
my ($job) = @_;
$self->sender->pause_queue;
$job->paused(1);
$self->reload_jobs;
$self->_update_connection_controls;
$self->{gauge}->Disable;
$self->set_status('Print is paused. Click on Resume to continue.');
});
$panel->on_abort_print(sub {
my ($job) = @_;
$self->sender->purge_queue;
$self->printing(undef);
$job->printing(0);
$job->paused(0);
$self->reload_jobs;
$self->_update_connection_controls;
$self->{gauge}->Disable;
$self->{gauge}->Hide;
$self->set_status('Print was aborted.');
$self->{log_textctrl}->AppendText(sprintf "Print aborted at %s\n", $self->_timestamp);
});
$panel->on_resume_print(sub {
my ($job) = @_;
$self->sender->resume_queue;
$job->paused(0);
$self->reload_jobs;
$self->_update_connection_controls;
$self->{gauge}->Enable;
$self->set_status('Printing...');
});
$panel->enable_print if $self->is_connected && !$self->printing;
EVT_MOUSEWHEEL($panel, sub {
my (undef, $event) = @_;
Wx::PostEvent($self->{jobs_panel}, $event);
$event->Skip;
});
}
$self->{jobs_panel}->Layout;
$self->{print_jobs_sizer}->Layout;
}
sub _timestamp {
my ($self) = @_;
my @time = localtime(time);
return sprintf '%02d:%02d:%02d', @time[2,1,0];
}
package Slic3r::GUI::Controller::PrinterPanel::PrintJob;
use Moo;
use File::Basename qw(basename);
has 'id' => (is => 'ro', required => 1);
has 'timestamp' => (is => 'ro', default => sub { time });
has 'gcode_file' => (is => 'ro', required => 1);
has 'filament_stats' => (is => 'rw');
has 'printing' => (is => 'rw', default => sub { 0 });
has 'paused' => (is => 'rw', default => sub { 0 });
has 'printed' => (is => 'rw', default => sub { 0 });
sub name {
my ($self) = @_;
return basename($self->gcode_file);
}
package Slic3r::GUI::Controller::PrinterPanel::PrintJobPanel;
use strict;
use warnings;
use utf8;
use Wx qw(wxTheApp :panel :id :misc :sizer :button :bitmap :font :dialog :icon :timer
:colour :brush :pen);
use Wx::Event qw(EVT_BUTTON EVT_TIMER EVT_ERASE_BACKGROUND);
use base qw(Wx::Panel Class::Accessor);
__PACKAGE__->mk_accessors(qw(job on_delete_job on_print_job on_pause_print on_resume_print
on_abort_print blink_timer));
sub new {
my ($class, $parent, $job) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize);
$self->job($job);
$self->SetBackgroundColour(wxWHITE);
{
my $white_brush = Wx::Brush->new(wxWHITE, wxSOLID);
my $pen = Wx::Pen->new(Wx::Colour->new(200,200,200), 1, wxSOLID);
EVT_ERASE_BACKGROUND($self, sub {
my ($self, $event) = @_;
my $dc = $event->GetDC;
my $size = $self->GetSize;
$dc->SetBrush($white_brush);
$dc->SetPen($pen);
$dc->DrawRoundedRectangle(0, 0, $size->GetWidth,$size->GetHeight, 6);
});
}
my $left_sizer = Wx::BoxSizer->new(wxVERTICAL);
{
$self->{job_name_textctrl} = my $text = Wx::StaticText->new($self, -1, $job->name, wxDefaultPosition, wxDefaultSize);
my $font = $text->GetFont;
$font->SetWeight(wxFONTWEIGHT_BOLD);
$text->SetFont($font);
if ($job->printed) {
$text->SetForegroundColour($Slic3r::GUI::grey);
}
$left_sizer->Add($text, 0, wxEXPAND, 0);
}
{
my $filament_stats = join "\n",
map "$_ (" . sprintf("%.2f", $job->filament_stats->{$_}/1000) . "m)",
sort keys %{$job->filament_stats};
my $text = Wx::StaticText->new($self, -1, $filament_stats, wxDefaultPosition, wxDefaultSize);
$text->SetFont($Slic3r::GUI::small_font);
if ($job->printed && !$job->printing) {
$text->SetForegroundColour($Slic3r::GUI::grey);
}
$left_sizer->Add($text, 0, wxEXPAND | wxTOP, 6);
}
my $buttons_sizer = Wx::BoxSizer->new(wxVERTICAL);
my $button_style = Wx::wxBORDER_NONE | wxBU_EXACTFIT;
{
my $btn = $self->{btn_delete} = Wx::Button->new($self, -1, 'Delete',
wxDefaultPosition, wxDefaultSize, $button_style);
$btn->SetToolTipString("Delete this job from print queue")
if $btn->can('SetToolTipString');
$btn->SetFont($Slic3r::GUI::small_font);
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("delete.png"), wxBITMAP_TYPE_PNG));
if ($job->printing) {
$btn->Hide;
}
$buttons_sizer->Add($btn, 0, wxBOTTOM, 2);
EVT_BUTTON($self, $btn, sub {
my $res = Wx::MessageDialog->new($self, "Are you sure you want to delete this print job?", 'Delete Job', wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION)->ShowModal;
return unless $res == wxID_YES;
wxTheApp->CallAfter(sub {
$self->on_delete_job->($job);
});
});
}
{
my $label = $job->printed ? 'Print Again' : 'Print This';
my $btn = $self->{btn_print} = Wx::Button->new($self, -1, $label, wxDefaultPosition, wxDefaultSize,
$button_style);
$btn->SetFont($Slic3r::GUI::small_bold_font);
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("control_play.png"), wxBITMAP_TYPE_PNG));
$btn->SetBitmapCurrent(Wx::Bitmap->new(Slic3r::var("control_play_blue.png"), wxBITMAP_TYPE_PNG));
#$btn->SetBitmapPosition(wxRIGHT);
$btn->Hide;
$buttons_sizer->Add($btn, 0, wxBOTTOM, 2);
EVT_BUTTON($self, $btn, sub {
wxTheApp->CallAfter(sub {
$self->on_print_job->($job);
});
});
}
{
my $btn = $self->{btn_pause} = Wx::Button->new($self, -1, "Pause", wxDefaultPosition, wxDefaultSize,
$button_style);
$btn->SetFont($Slic3r::GUI::small_font);
if (!$job->printing || $job->paused) {
$btn->Hide;
}
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("control_pause.png"), wxBITMAP_TYPE_PNG));
$btn->SetBitmapCurrent(Wx::Bitmap->new(Slic3r::var("control_pause_blue.png"), wxBITMAP_TYPE_PNG));
$buttons_sizer->Add($btn, 0, wxBOTTOM, 2);
EVT_BUTTON($self, $btn, sub {
wxTheApp->CallAfter(sub {
$self->on_pause_print->($job);
});
});
}
{
my $btn = $self->{btn_resume} = Wx::Button->new($self, -1, "Resume", wxDefaultPosition, wxDefaultSize,
$button_style);
$btn->SetFont($Slic3r::GUI::small_font);
if (!$job->printing || !$job->paused) {
$btn->Hide;
}
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("control_play.png"), wxBITMAP_TYPE_PNG));
$btn->SetBitmapCurrent(Wx::Bitmap->new(Slic3r::var("control_play_blue.png"), wxBITMAP_TYPE_PNG));
$buttons_sizer->Add($btn, 0, wxBOTTOM, 2);
EVT_BUTTON($self, $btn, sub {
wxTheApp->CallAfter(sub {
$self->on_resume_print->($job);
});
});
}
{
my $btn = $self->{btn_abort} = Wx::Button->new($self, -1, "Abort", wxDefaultPosition, wxDefaultSize,
$button_style);
$btn->SetFont($Slic3r::GUI::small_font);
if (!$job->printing) {
$btn->Hide;
}
$btn->SetBitmap(Wx::Bitmap->new(Slic3r::var("control_stop.png"), wxBITMAP_TYPE_PNG));
$btn->SetBitmapCurrent(Wx::Bitmap->new(Slic3r::var("control_stop_blue.png"), wxBITMAP_TYPE_PNG));
$buttons_sizer->Add($btn, 0, wxBOTTOM, 2);
EVT_BUTTON($self, $btn, sub {
wxTheApp->CallAfter(sub {
$self->on_abort_print->($job);
});
});
}
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$sizer->Add($left_sizer, 1, wxEXPAND | wxALL, 6);
$sizer->Add($buttons_sizer, 0, wxEXPAND | wxALL, 6);
$self->SetSizer($sizer);
# set-up the timer that changes the job name color while printing
if ($self->job->printing && !$self->job->paused) {
my $timer_id = &Wx::NewId();
$self->blink_timer(Wx::Timer->new($self, $timer_id));
my $blink = 0; # closure
my $colour = Wx::Colour->new(0, 190, 0);
EVT_TIMER($self, $timer_id, sub {
my ($self, $event) = @_;
$self->{job_name_textctrl}->SetForegroundColour($blink ? Wx::wxBLACK : $colour);
$blink = !$blink;
});
$self->blink_timer->Start(1000, wxTIMER_CONTINUOUS);
}
return $self;
}
sub enable_print {
my ($self) = @_;
if (!$self->job->printing) {
$self->{btn_print}->Show;
}
$self->Layout;
}
sub Destroy {
my ($self) = @_;
# There's a gap between the time Perl destroys the wxPanel object and
# the blink_timer member, so the wxTimer might still fire an event which
# isn't handled properly, causing a crash. So we ensure that blink_timer
# is stopped before we destroy the wxPanel.
$self->blink_timer->Stop if $self->blink_timer;
return $self->SUPER::Destroy;
}
1;

File diff suppressed because it is too large Load Diff

View File

@@ -1,41 +0,0 @@
package Slic3r::GUI::Notifier;
use Moo;
has 'growler' => (is => 'rw');
my $icon = "$Slic3r::var/Slic3r.png";
sub BUILD {
my ($self) = @_;
if (eval 'use Growl::GNTP; 1') {
# register with growl
eval {
$self->growler(Growl::GNTP->new(AppName => 'Slic3r', AppIcon => $icon));
$self->growler->register([{Name => 'SKEIN_DONE', DisplayName => 'Slicing Done'}]);
};
}
}
sub notify {
my ($self, $message) = @_;
my $title = 'Slicing Done!';
eval {
$self->growler->notify(Event => 'SKEIN_DONE', Title => $title, Message => $message)
if $self->growler;
};
# Net::DBus is broken in multithreaded environment
if (0 && eval 'use Net::DBus; 1') {
eval {
my $session = Net::DBus->session;
my $serv = $session->get_service('org.freedesktop.Notifications');
my $notifier = $serv->get_object('/org/freedesktop/Notifications',
'org.freedesktop.Notifications');
$notifier->Notify('Slic3r', 0, $icon, $title, $message, [], {}, -1);
undef $Net::DBus::bus_session;
};
}
}
1;

View File

@@ -1,3 +1,5 @@
# A dialog group object. Used by the Tab, Preferences dialog, ManualControlDialog etc.
package Slic3r::GUI::OptionsGroup;
use Moo;
@@ -83,7 +85,7 @@ sub append_line {
# if we have a single option with no sidetext just add it directly to the grid sizer
my @options = @{$line->get_options};
$self->_options->{$_->opt_id} = $_ for @options;
if (@options == 1 && !$options[0]->sidetext) {
if (@options == 1 && !$options[0]->sidetext && !$options[0]->side_widget && !@{$line->get_extra_widgets}) {
my $option = $options[0];
my $field = $self->_build_field($option);
$grid_sizer->Add($field, 0, ($option->full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0);
@@ -95,7 +97,9 @@ sub append_line {
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$grid_sizer->Add($sizer, 0, 0, 0);
foreach my $option (@options) {
foreach my $i (0..$#options) {
my $option = $options[$i];
# add label if any
if ($option->label) {
my $field_label = Wx::StaticText->new($self->parent, -1, $option->label . ":", wxDefaultPosition, wxDefaultSize);
@@ -111,12 +115,26 @@ sub append_line {
if ($option->sidetext) {
my $sidetext = Wx::StaticText->new($self->parent, -1, $option->sidetext, wxDefaultPosition, wxDefaultSize);
$sidetext->SetFont($self->sidetext_font);
$sizer->Add($sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL , 4);
$sizer->Add($sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
}
# add side widget if any
if ($option->side_widget) {
$sizer->Add($option->side_widget->($self->parent), 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1);
}
if ($option != $#options) {
$sizer->AddSpacer(4);
}
}
# add extra sizers if any
foreach my $extra_widget (@{$line->get_extra_widgets}) {
$sizer->Add($extra_widget->($self->parent), 0, wxLEFT | wxALIGN_CENTER_VERTICAL , 4);
}
}
sub append_single_option_line {
sub create_single_option_line {
my ($self, $option) = @_;
my $line = Slic3r::GUI::OptionsGroup::Line->new(
@@ -125,18 +143,24 @@ sub append_single_option_line {
);
$option->label("");
$line->append_option($option);
$self->append_line($line);
return $line;
}
sub append_single_option_line {
my ($self, $option) = @_;
return $self->append_line($self->create_single_option_line($option));
}
sub _build_field {
my $self = shift;
my ($opt) = @_;
my $opt_id = $opt->opt_id;
my $on_change = sub {
#! This function will be called from Field.
my ($opt_id, $value) = @_;
#! Call OptionGroup._on_change(...)
$self->_on_change($opt_id, $value)
unless $self->_disabled;
};
@@ -158,12 +182,17 @@ sub _build_field {
parent => $self->parent,
option => $opt,
);
} elsif ($type eq 'color') {
$field = Slic3r::GUI::OptionsGroup::Field::ColourPicker->new(
parent => $self->parent,
option => $opt,
);
} elsif ($type =~ /^(f|s|s@|percent)$/) {
$field = Slic3r::GUI::OptionsGroup::Field::TextCtrl->new(
parent => $self->parent,
option => $opt,
);
} elsif ($type eq 'select') {
} elsif ($type eq 'select' || $type eq 'select_open') {
$field = Slic3r::GUI::OptionsGroup::Field::Choice->new(
parent => $self->parent,
option => $opt,
@@ -186,6 +215,8 @@ sub _build_field {
}
return undef if !$field;
#! setting up a function that will be triggered when the field changes
#! think of it as $field->on_change = ($on_change)
$field->on_change($on_change);
$field->on_kill_focus($on_kill_focus);
$self->_fields->{$opt_id} = $field;
@@ -222,8 +253,20 @@ sub set_value {
}
sub _on_change {
my ($self, $opt_id) = @_;
$self->on_change->($opt_id);
my ($self, $opt_id, $value) = @_;
$self->on_change->($opt_id, $value);
}
sub enable {
my ($self) = @_;
$_->enable for values %{$self->_fields};
}
sub disable {
my ($self) = @_;
$_->disable for values %{$self->_fields};
}
sub _on_kill_focus {
@@ -241,6 +284,8 @@ has 'label_tooltip' => (is => 'rw', default => sub { "" });
has 'sizer' => (is => 'rw');
has 'widget' => (is => 'rw');
has '_options' => (is => 'ro', default => sub { [] });
# Extra UI components after the label and the edit widget of the option.
has '_extra_widgets' => (is => 'ro', default => sub { [] });
# this method accepts a Slic3r::GUI::OptionsGroup::Option object
sub append_option {
@@ -248,12 +293,24 @@ sub append_option {
push @{$self->_options}, $option;
}
sub append_widget {
my ($self, $widget) = @_;
push @{$self->_extra_widgets}, $widget;
}
sub get_options {
my ($self) = @_;
return [ @{$self->_options} ];
}
sub get_extra_widgets {
my ($self) = @_;
return [ @{$self->_extra_widgets} ];
}
# Configuration of an option.
# This very much reflects the content of the C++ ConfigOptionDef class.
package Slic3r::GUI::OptionsGroup::Option;
use Moo;
@@ -274,6 +331,7 @@ has 'max' => (is => 'rw', default => sub { undef });
has 'labels' => (is => 'rw', default => sub { [] });
has 'values' => (is => 'rw', default => sub { [] });
has 'readonly' => (is => 'rw', default => sub { 0 });
has 'side_widget' => (is => 'rw', default => sub { undef });
package Slic3r::GUI::ConfigOptionsGroup;
@@ -298,6 +356,8 @@ sub get_option {
my $opt_id = ($opt_index == -1 ? $opt_key : "${opt_key}#${opt_index}");
$self->_opt_map->{$opt_id} = [ $opt_key, $opt_index ];
# Slic3r::Config::Options is a C++ Slic3r::PrintConfigDef exported as a Perl hash of hashes.
# The C++ counterpart is a constant singleton.
my $optdef = $Slic3r::Config::Options->{$opt_key}; # we should access this from $self->config
my $default_value = $self->_get_config_value($opt_key, $opt_index, $optdef->{gui_flags} =~ /\bserialized\b/);
@@ -309,7 +369,8 @@ sub get_option {
gui_flags => $optdef->{gui_flags},
label => ($self->full_labels && defined $optdef->{full_label}) ? $optdef->{full_label} : $optdef->{label},
sidetext => $optdef->{sidetext},
tooltip => $optdef->{tooltip} . " (default: " . $default_value . ")",
# calling serialize() ensures we get a stringified value
tooltip => $optdef->{tooltip} . " (default: " . $self->config->serialize($opt_key) . ")",
multiline => $optdef->{multiline},
width => $optdef->{width},
min => $optdef->{min},
@@ -320,7 +381,7 @@ sub get_option {
);
}
sub append_single_option_line {
sub create_single_option_line {
my ($self, $opt_key, $opt_index) = @_;
my $option;
@@ -329,9 +390,15 @@ sub append_single_option_line {
} else {
$option = $self->get_option($opt_key, $opt_index);
}
return $self->SUPER::append_single_option_line($option);
return $self->SUPER::create_single_option_line($option);
}
sub append_single_option_line {
my ($self, $option, $opt_index) = @_;
return $self->append_line($self->create_single_option_line($option, $opt_index));
}
# Initialize UI components with the config values.
sub reload_config {
my ($self) = @_;
@@ -355,8 +422,11 @@ sub _get_config_value {
my ($self, $opt_key, $opt_index, $deserialize) = @_;
if ($deserialize) {
# Want to edit a vector value (currently only multi-strings) in a single edit box.
# Aggregate the strings the old way.
# Currently used for the post_process config value only.
die "Can't deserialize option indexed value" if $opt_index != -1;
return $self->config->serialize($opt_key);
return join(';', @{$self->config->get($opt_key)});
} else {
return $opt_index == -1
? $self->config->get($opt_key)
@@ -365,7 +435,7 @@ sub _get_config_value {
}
sub _on_change {
my ($self, $opt_id) = @_;
my ($self, $opt_id, $value) = @_;
if (exists $self->_opt_map->{$opt_id}) {
my ($opt_key, $opt_index) = @{ $self->_opt_map->{$opt_id} };
@@ -375,7 +445,10 @@ sub _on_change {
my $field_value = $self->get_value($opt_id);
if ($option->gui_flags =~ /\bserialized\b/) {
die "Can't set serialized option indexed value" if $opt_index != -1;
$self->config->set_deserialize($opt_key, $field_value);
# Split a string to multiple strings by a semi-colon. This is the old way of storing multi-string values.
# Currently used for the post_process config value only.
my @values = split /;/, $field_value;
$self->config->set($opt_key, \@values);
} else {
if ($opt_index == -1) {
$self->config->set($opt_key, $field_value);
@@ -387,7 +460,7 @@ sub _on_change {
}
}
$self->SUPER::_on_change($opt_id);
$self->SUPER::_on_change($opt_id, $value);
}
sub _on_kill_focus {
@@ -399,6 +472,8 @@ sub _on_kill_focus {
$self->reload_config;
}
# Static text shown among the options.
# Currently used for the filament cooling legend only.
package Slic3r::GUI::OptionsGroup::StaticText;
use Wx qw(:misc :systemsettings);
use base 'Wx::StaticText';

View File

@@ -1,13 +1,17 @@
# An input field class prototype.
package Slic3r::GUI::OptionsGroup::Field;
use Moo;
# This is a base class for option fields.
has 'parent' => (is => 'ro', required => 1);
has 'option' => (is => 'ro', required => 1); # Slic3r::GUI::OptionsGroup::Option
# Slic3r::GUI::OptionsGroup::Option
has 'option' => (is => 'ro', required => 1);
# On change callback
has 'on_change' => (is => 'rw', default => sub { sub {} });
has 'on_kill_focus' => (is => 'rw', default => sub { sub {} });
has 'wxSsizer' => (is => 'rw'); # alternatively, wxSizer object
# If set, the callback $self->on_change is not called.
# This is used to avoid recursive invocation of the field change/update by wxWidgets.
has 'disable_change_event' => (is => 'rw', default => sub { 0 });
# This method should not fire the on_change event
@@ -36,7 +40,7 @@ sub toggle {
sub _on_change {
my ($self, $opt_id) = @_;
$self->on_change->($opt_id)
$self->on_change->($opt_id, $self->get_value)
unless $self->disable_change_event;
}
@@ -120,6 +124,10 @@ sub BUILD {
});
}
sub get_value {
my ($self) = @_;
return $self->wxWindow->GetValue ? 1 : 0;
}
package Slic3r::GUI::OptionsGroup::Field::SpinCtrl;
use Moo;
@@ -128,6 +136,8 @@ extends 'Slic3r::GUI::OptionsGroup::Field::wxWindow';
use Wx qw(:misc);
use Wx::Event qw(EVT_SPINCTRL EVT_TEXT EVT_KILL_FOCUS);
has 'tmp_value' => (is => 'rw');
sub BUILD {
my ($self) = @_;
@@ -136,16 +146,34 @@ sub BUILD {
$self->wxWindow($field);
EVT_SPINCTRL($self->parent, $field, sub {
$self->tmp_value(undef);
$self->_on_change($self->option->opt_id);
});
EVT_TEXT($self->parent, $field, sub {
my ($s, $event) = @_;
# On OSX/Cocoa, wxSpinCtrl::GetValue() doesn't return the new value
# when it was changed from the text control, so the on_change callback
# gets the old one, and on_kill_focus resets the control to the old value.
# As a workaround, we get the new value from $event->GetString and store
# here temporarily so that we can return it from $self->get_value
$self->tmp_value($event->GetString) if $event->GetString =~ /^\d+$/;
$self->_on_change($self->option->opt_id);
# We don't reset tmp_value here because _on_change might put callbacks
# in the CallAfter queue, and we want the tmp value to be available from
# them as well.
});
EVT_KILL_FOCUS($field, sub {
$self->tmp_value(undef);
$self->_on_kill_focus($self->option->opt_id, @_);
});
}
sub get_value {
my ($self) = @_;
return $self->tmp_value // $self->wxWindow->GetValue;
}
package Slic3r::GUI::OptionsGroup::Field::TextCtrl;
use Moo;
@@ -194,44 +222,86 @@ extends 'Slic3r::GUI::OptionsGroup::Field::wxWindow';
use List::Util qw(first);
use Wx qw(:misc :combobox);
use Wx::Event qw(EVT_COMBOBOX);
use Wx::Event qw(EVT_COMBOBOX EVT_TEXT);
sub BUILD {
my ($self) = @_;
my $style = 0;
$style |= wxCB_READONLY if defined $self->option->gui_type && $self->option->gui_type ne 'select_open';
my $field = Wx::ComboBox->new($self->parent, -1, "", wxDefaultPosition, $self->_default_size,
$self->option->labels || $self->option->values, wxCB_READONLY);
$self->option->labels || $self->option->values || [], $style);
$self->wxWindow($field);
$self->set_value($self->option->default);
EVT_COMBOBOX($self->parent, $field, sub {
$self->_on_change($self->option->opt_id);
});
EVT_TEXT($self->parent, $field, sub {
$self->_on_change($self->option->opt_id);
});
}
sub set_value {
my ($self, $value) = @_;
my $idx = first { $self->option->values->[$_] eq $value } 0..$#{$self->option->values};
$self->disable_change_event(1);
my $idx;
if ($self->option->values) {
$idx = first { $self->option->values->[$_] eq $value } 0..$#{$self->option->values};
# if value is not among indexes values we use SetValue()
}
if (defined $idx) {
$self->wxWindow->SetSelection($idx);
} else {
$self->wxWindow->SetValue($value);
}
$self->disable_change_event(0);
}
sub set_values {
my ($self, $values) = @_;
$self->disable_change_event(1);
$self->wxWindow->SetSelection($idx);
# it looks that Clear() also clears the text field in recent wxWidgets versions,
# but we want to preserve it
my $ww = $self->wxWindow;
my $value = $ww->GetValue;
$ww->Clear;
$ww->Append($_) for @$values;
$ww->SetValue($value);
$self->disable_change_event(0);
}
sub get_value {
my ($self) = @_;
return $self->option->values->[$self->wxWindow->GetSelection];
if ($self->option->values) {
my $idx = $self->wxWindow->GetSelection;
if ($idx != &Wx::wxNOT_FOUND) {
return $self->option->values->[$idx];
}
}
return $self->wxWindow->GetValue;
}
package Slic3r::GUI::OptionsGroup::Field::NumericChoice;
use Moo;
extends 'Slic3r::GUI::OptionsGroup::Field::wxWindow';
use List::Util qw(first);
use Wx qw(:misc :combobox);
use Wx qw(wxTheApp :misc :combobox);
use Wx::Event qw(EVT_COMBOBOX EVT_TEXT);
# if option has no 'values', indices are values
# if option has no 'labels', values are labels
sub BUILD {
my ($self) = @_;
@@ -245,18 +315,28 @@ sub BUILD {
my $disable_change_event = $self->disable_change_event;
$self->disable_change_event(1);
my $value = $field->GetSelection;
my $idx = $field->GetSelection; # get index of selected value
my $label;
if ($self->option->values) {
$label = $value = $self->option->values->[$value];
} elsif ($value <= $#{$self->option->labels}) {
$label = $self->option->labels->[$value];
if ($self->option->labels && $idx <= $#{$self->option->labels}) {
$label = $self->option->labels->[$idx];
} elsif ($self->option->values && $idx <= $#{$self->option->values}) {
$label = $self->option->values->[$idx];
} else {
$label = $value;
$label = $idx;
}
$field->SetValue($label);
# The MSW implementation of wxComboBox will leave the field blank if we call
# SetValue() in the EVT_COMBOBOX event handler, so we postpone the call.
wxTheApp->CallAfter(sub {
my $dce = $self->disable_change_event;
$self->disable_change_event(1);
# ChangeValue() is not exported in wxPerl
$field->SetValue($label);
$self->disable_change_event($dce);
});
$self->disable_change_event($disable_change_event);
$self->_on_change($self->option->opt_id);
@@ -283,8 +363,8 @@ sub set_value {
$self->disable_change_event(0);
return;
}
}
if ($self->option->labels && $value <= $#{$self->option->labels}) {
} elsif ($self->option->labels && $value <= $#{$self->option->labels}) {
# if we have no values, we expect value to be an index
$field->SetValue($self->option->labels->[$value]);
$self->disable_change_event(0);
return;
@@ -299,17 +379,62 @@ sub get_value {
my ($self) = @_;
my $label = $self->wxWindow->GetValue;
my $value_idx = first { $self->option->labels->[$_] eq $label } 0..$#{$self->option->labels};
if (defined $value_idx) {
if ($self->option->values) {
return $self->option->values->[$value_idx];
if ($self->option->labels) {
my $value_idx = first { $self->option->labels->[$_] eq $label } 0..$#{$self->option->labels};
if (defined $value_idx) {
if ($self->option->values) {
return $self->option->values->[$value_idx];
}
return $value_idx;
}
return $value_idx;
}
return $label;
}
package Slic3r::GUI::OptionsGroup::Field::ColourPicker;
use Moo;
extends 'Slic3r::GUI::OptionsGroup::Field::wxWindow';
use Wx qw(:misc :colour);
use Wx::Event qw(EVT_COLOURPICKER_CHANGED);
sub BUILD {
my ($self) = @_;
my $field = Wx::ColourPickerCtrl->new($self->parent, -1,
$self->_string_to_colour($self->option->default), wxDefaultPosition,
$self->_default_size);
$self->wxWindow($field);
EVT_COLOURPICKER_CHANGED($self->parent, $field, sub {
$self->_on_change($self->option->opt_id);
});
}
sub set_value {
my ($self, $value) = @_;
$self->disable_change_event(1);
$self->wxWindow->SetColour($self->_string_to_colour($value));
$self->disable_change_event(0);
}
sub get_value {
my ($self) = @_;
return $self->wxWindow->GetColour->GetAsString(wxC2S_HTML_SYNTAX);
}
sub _string_to_colour {
my ($self, $string) = @_;
$string =~ s/^#//;
# If the color is in an invalid format, set it to white.
$string = 'FFFFFF' if ($string !~ m/^[[:xdigit:]]{6}/);
return Wx::Colour->new(unpack 'C*', pack 'H*', $string);
}
package Slic3r::GUI::OptionsGroup::Field::wxSizer;
use Moo;
extends 'Slic3r::GUI::OptionsGroup::Field';
@@ -335,6 +460,7 @@ sub BUILD {
$self->wxSizer($sizer);
my $field_size = Wx::Size->new(40, -1);
$self->x_textctrl(Wx::TextCtrl->new($self->parent, -1, $self->option->default->[X], wxDefaultPosition, $field_size));
$self->y_textctrl(Wx::TextCtrl->new($self->parent, -1, $self->option->default->[Y], wxDefaultPosition, $field_size));
@@ -397,11 +523,10 @@ extends 'Slic3r::GUI::OptionsGroup::Field::wxSizer';
has 'scale' => (is => 'rw', default => sub { 10 });
has 'slider' => (is => 'rw');
has 'statictext' => (is => 'rw');
has 'textctrl' => (is => 'rw');
use Slic3r::Geometry qw(X Y);
use Wx qw(:misc :sizer);
use Wx::Event qw(EVT_SLIDER);
use Wx::Event qw(EVT_SLIDER EVT_TEXT EVT_KILL_FOCUS);
sub BUILD {
my ($self) = @_;
@@ -419,14 +544,30 @@ sub BUILD {
);
$self->slider($slider);
my $statictext = Wx::StaticText->new($self->parent, -1, $slider->GetValue/$self->scale);
$self->statictext($statictext);
my $textctrl = Wx::TextCtrl->new($self->parent, -1, $slider->GetValue/$self->scale,
wxDefaultPosition, [50,-1]);
$self->textctrl($textctrl);
$sizer->Add($_, 0, wxALIGN_CENTER_VERTICAL, 0) for $slider, $statictext;
$sizer->Add($slider, 1, wxALIGN_CENTER_VERTICAL, 0);
$sizer->Add($textctrl, 0, wxALIGN_CENTER_VERTICAL, 0);
EVT_SLIDER($self->parent, $slider, sub {
$self->_update_statictext;
$self->_on_change($self->option->opt_id);
if (! $self->disable_change_event) {
$self->textctrl->SetLabel($self->get_value);
$self->_on_change($self->option->opt_id);
}
});
EVT_TEXT($self->parent, $textctrl, sub {
my $value = $textctrl->GetValue;
if ($value =~ /^-?\d+(\.\d*)?$/) {
$self->disable_change_event(1);
$self->slider->SetValue($value*$self->scale);
$self->disable_change_event(0);
$self->_on_change($self->option->opt_id);
}
});
EVT_KILL_FOCUS($textctrl, sub {
$self->_on_kill_focus($self->option->opt_id, @_);
});
}
@@ -434,8 +575,8 @@ sub set_value {
my ($self, $value) = @_;
$self->disable_change_event(1);
$self->slider->SetValue($value);
$self->_update_statictext;
$self->slider->SetValue($value*$self->scale);
$self->textctrl->SetLabel($self->get_value);
$self->disable_change_event(0);
}
@@ -444,9 +585,20 @@ sub get_value {
return $self->slider->GetValue/$self->scale;
}
sub _update_statictext {
sub enable {
my ($self) = @_;
$self->statictext->SetLabel($self->get_value);
$self->slider->Enable;
$self->textctrl->Enable;
$self->textctrl->SetEditable(1);
}
sub disable {
my ($self) = @_;
$self->slider->Disable;
$self->textctrl->Disable;
$self->textctrl->SetEditable(0);
}
1;

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,6 @@
# 2D preview on the platter.
# 3D objects are visualized by their convex hulls.
package Slic3r::GUI::Plater::2D;
use strict;
use warnings;
@@ -6,28 +9,27 @@ use utf8;
use List::Util qw(min max first);
use Slic3r::Geometry qw(X Y scale unscale convex_hull);
use Slic3r::Geometry::Clipper qw(offset JT_ROUND intersection_pl);
use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT EVT_SIZE);
use Wx qw(wxTheApp :misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_MOUSE_EVENTS EVT_PAINT EVT_ERASE_BACKGROUND EVT_SIZE);
use base 'Wx::Panel';
use constant CANVAS_TEXT => join('-', +(localtime)[3,4]) eq '13-8'
? 'What do you want to print today? ™' # Sept. 13, 2006. The first part ever printed by a RepRap to make another RepRap.
: 'Drag your objects here';
use Wx::Locale gettext => 'L';
sub new {
my $class = shift;
my ($parent, $size, $objects, $model, $config) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, $size, wxTAB_TRAVERSAL);
# This has only effect on MacOS. On Windows and Linux/GTK, the background is painted by $self->repaint().
$self->SetBackgroundColour(Wx::wxWHITE);
$self->{objects} = $objects;
$self->{model} = $model;
$self->{config} = $config;
$self->{on_select_object} = sub {};
$self->{on_double_click} = sub {};
$self->{on_right_click} = sub {};
$self->{on_instance_moved} = sub {};
$self->{on_instances_moved} = sub {};
$self->{objects_brush} = Wx::Brush->new(Wx::Colour->new(210,210,210), wxSOLID);
$self->{selected_brush} = Wx::Brush->new(Wx::Colour->new(255,128,128), wxSOLID);
@@ -37,8 +39,11 @@ sub new {
$self->{print_center_pen} = Wx::Pen->new(Wx::Colour->new(200,200,200), 1, wxSOLID);
$self->{clearance_pen} = Wx::Pen->new(Wx::Colour->new(0,0,200), 1, wxSOLID);
$self->{skirt_pen} = Wx::Pen->new(Wx::Colour->new(150,150,150), 1, wxSOLID);
$self->{user_drawn_background} = $^O ne 'darwin';
EVT_PAINT($self, \&repaint);
EVT_ERASE_BACKGROUND($self, sub {}) if $self->{user_drawn_background};
EVT_MOUSE_EVENTS($self, \&mouse_event);
EVT_SIZE($self, sub {
$self->update_bed_size;
@@ -63,18 +68,30 @@ sub on_right_click {
$self->{on_right_click} = $cb;
}
sub on_instance_moved {
sub on_instances_moved {
my ($self, $cb) = @_;
$self->{on_instance_moved} = $cb;
$self->{on_instances_moved} = $cb;
}
sub repaint {
my ($self, $event) = @_;
my $dc = Wx::PaintDC->new($self);
my $dc = Wx::AutoBufferedPaintDC->new($self);
my $size = $self->GetSize;
my @size = ($size->GetWidth, $size->GetHeight);
if ($self->{user_drawn_background}) {
# On all systems the AutoBufferedPaintDC() achieves double buffering.
# On MacOS the background is erased, on Windows the background is not erased
# and on Linux/GTK the background is erased to gray color.
# Fill DC with the background on Windows & Linux/GTK.
my $brush_background = Wx::Brush->new(Wx::wxWHITE, wxSOLID);
$dc->SetPen(wxWHITE_PEN);
$dc->SetBrush($brush_background);
my $rect = $self->GetUpdateRegion()->GetBox();
$dc->DrawRectangle($rect->GetLeft(), $rect->GetTop(), $rect->GetWidth(), $rect->GetHeight());
}
# draw grid
$dc->SetPen($self->{grid_pen});
$dc->DrawLine(map @$_, @$_) for @{$self->{grid}};
@@ -87,7 +104,7 @@ sub repaint {
}
# draw print center
if (@{$self->{objects}} && $Slic3r::GUI::Settings->{_}{autocenter}) {
if (@{$self->{objects}} && wxTheApp->{app_config}->get("autocenter")) {
my $center = $self->unscaled_point_to_pixel($self->{print_center});
$dc->SetPen($self->{print_center_pen});
$dc->DrawLine($center->[X], 0, $center->[X], $size[Y]);
@@ -109,7 +126,11 @@ sub repaint {
if (!@{$self->{objects}}) {
$dc->SetTextForeground(Wx::Colour->new(150,50,50));
$dc->SetFont(Wx::Font->new(14, wxDEFAULT, wxNORMAL, wxNORMAL));
$dc->DrawLabel(CANVAS_TEXT, Wx::Rect->new(0, 0, $self->GetSize->GetWidth, $self->GetSize->GetHeight), wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
$dc->DrawLabel(
join('-', +(localtime)[3,4]) eq '13-8'
? L('What do you want to print today? ™') # Sept. 13, 2006. The first part ever printed by a RepRap to make another RepRap.
: L('Drag your objects here'),
Wx::Rect->new(0, 0, $self->GetSize->GetWidth, $self->GetSize->GetHeight), wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL);
}
# draw thumbnails
@@ -154,7 +175,7 @@ sub repaint {
# if sequential printing is enabled and we have more than one object, draw clearance area
if ($self->{config}->complete_objects && (map @{$_->instances}, @{$self->{model}->objects}) > 1) {
my ($clearance) = @{offset([$thumbnail->convex_hull], (scale($self->{config}->extruder_clearance_radius) / 2), 1, JT_ROUND, scale(0.1))};
my ($clearance) = @{offset([$thumbnail->convex_hull], (scale($self->{config}->extruder_clearance_radius) / 2), JT_ROUND, scale(0.1))};
$dc->SetPen($self->{clearance_pen});
$dc->SetBrush($self->{transparent_brush});
$dc->DrawPolygon($self->scaled_points_to_pixel($clearance, 1), 0, 0);
@@ -166,7 +187,7 @@ sub repaint {
if (@{$self->{objects}} && $self->{config}->skirts) {
my @points = map @{$_->contour}, map @$_, map @{$_->instance_thumbnails}, @{$self->{objects}};
if (@points >= 3) {
my ($convex_hull) = @{offset([convex_hull(\@points)], scale max($self->{config}->brim_width + $self->{config}->skirt_distance), 1, JT_ROUND, scale(0.1))};
my ($convex_hull) = @{offset([convex_hull(\@points)], scale max($self->{config}->brim_width + $self->{config}->skirt_distance), JT_ROUND, scale(0.1))};
$dc->SetPen($self->{skirt_pen});
$dc->SetBrush($self->{transparent_brush});
$dc->DrawPolygon($self->scaled_points_to_pixel($convex_hull, 1), 0, 0);
@@ -178,14 +199,15 @@ sub repaint {
sub mouse_event {
my ($self, $event) = @_;
my $pos = $event->GetPosition;
my $point = $self->point_to_model_units([ $pos->x, $pos->y ]); #]]
if ($event->ButtonDown) {
$self->{on_select_object}->(undef);
OBJECTS: for my $obj_idx (0 .. $#{$self->{objects}}) {
# traverse objects and instances in reverse order, so that if they're overlapping
# we get the one that gets drawn last, thus on top (as user expects that to move)
OBJECTS: for my $obj_idx (reverse 0 .. $#{$self->{objects}}) {
my $object = $self->{objects}->[$obj_idx];
for my $instance_idx (0 .. $#{ $object->instance_thumbnails }) {
for my $instance_idx (reverse 0 .. $#{ $object->instance_thumbnails }) {
my $thumbnail = $object->instance_thumbnails->[$instance_idx];
if (defined first { $_->contour->contains_point($point) } @$thumbnail) {
$self->{on_select_object}->($obj_idx);
@@ -200,7 +222,7 @@ sub mouse_event {
];
$self->{drag_object} = [ $obj_idx, $instance_idx ];
} elsif ($event->RightDown) {
$self->{on_right_click}->($pos);
$self->{on_right_click}->($pos->x, $pos->y);
}
last OBJECTS;
@@ -208,13 +230,13 @@ sub mouse_event {
}
}
$self->Refresh;
} elsif ($event->ButtonUp(&Wx::wxMOUSE_BTN_LEFT)) {
$self->{on_instance_moved}->();
$self->Refresh;
} elsif ($event->LeftUp) {
$self->{on_instances_moved}->()
if $self->{drag_object};
$self->{drag_start_pos} = undef;
$self->{drag_object} = undef;
$self->SetCursor(wxSTANDARD_CURSOR);
} elsif ($event->ButtonDClick) {
} elsif ($event->LeftDClick) {
$self->{on_double_click}->();
} elsif ($event->Dragging) {
return if !$self->{drag_start_pos}; # concurrency problems
@@ -225,7 +247,6 @@ sub mouse_event {
unscale($point->[X] - $self->{drag_start_pos}[X]),
unscale($point->[Y] - $self->{drag_start_pos}[Y]),
));
$model_object->update_bounding_box;
$self->Refresh;
} elsif ($event->Moving) {
my $cursor = wxSTANDARD_CURSOR;
@@ -237,7 +258,7 @@ sub mouse_event {
}
sub update_bed_size {
my $self = shift;
my ($self) = @_;
# when the canvas is not rendered yet, its GetSize() method returns 0,0
my $canvas_size = $self->GetSize;
@@ -274,7 +295,7 @@ sub update_bed_size {
push @polylines, Slic3r::Polyline->new([$bb->x_min, $y], [$bb->x_max, $y]);
}
@polylines = @{intersection_pl(\@polylines, [$polygon])};
$self->{grid} = [ map $self->scaled_points_to_pixel(\@$_, 1), @polylines ];
$self->{grid} = [ map $self->scaled_points_to_pixel([ @$_[0,-1] ], 1), @polylines ];
}
}
@@ -319,4 +340,32 @@ sub point_to_model_units {
);
}
sub reload_scene {
my ($self, $force) = @_;
if (! $self->IsShown && ! $force) {
$self->{reload_delayed} = 1;
return;
}
$self->{reload_delayed} = 0;
foreach my $obj_idx (0..$#{$self->{model}->objects}) {
my $plater_object = $self->{objects}[$obj_idx];
next if $plater_object->thumbnail;
# The thumbnail is not valid, update it with a convex hull of an object.
$plater_object->thumbnail(Slic3r::ExPolygon::Collection->new);
$plater_object->make_thumbnail($self->{model}, $obj_idx);
$plater_object->transform_thumbnail($self->{model}, $obj_idx);
}
$self->Refresh;
}
# Called by the Platter wxNotebook when this page is activated.
sub OnActivate {
my ($self) = @_;
$self->reload_scene(1) if ($self->{reload_delayed});
}
1;

View File

@@ -1,23 +1,25 @@
# 2D preview of the tool paths of a single layer, using a thin line.
# OpenGL is used to render the paths.
# Vojtech also added a 2D simulation of under/over extrusion in a single layer.
package Slic3r::GUI::Plater::2DToolpaths;
use strict;
use warnings;
use utf8;
use List::Util qw();
use Slic3r::Geometry qw();
use Wx qw(:misc :sizer :slider :statictext);
use Slic3r::Print::State ':steps';
use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE wxWANTS_CHARS);
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN);
use base 'Wx::Panel';
use base qw(Wx::Panel Class::Accessor);
__PACKAGE__->mk_accessors(qw(print enabled));
sub new {
my $class = shift;
my ($parent, $print) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition);
# init print
$self->{print} = $print;
$self->reload_print;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS);
$self->SetBackgroundColour(wxWHITE);
# init GUI elements
my $canvas = $self->{canvas} = Slic3r::GUI::Plater::2DToolpaths::Canvas->new($self, $print);
@@ -25,7 +27,9 @@ sub new {
$self, -1,
0, # default
0, # min
scalar(@{$self->{layers_z}})-1, # max
# we set max to a bogus non-zero value because the MSW implementation of wxSlider
# will skip drawing the slider if max <= min:
1, # max
wxDefaultPosition,
wxDefaultSize,
wxVERTICAL | wxSL_INVERSE,
@@ -43,26 +47,39 @@ sub new {
$sizer->Add($vsizer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5);
EVT_SLIDER($self, $slider, sub {
$self->set_z($self->{layers_z}[$slider->GetValue]);
$self->set_z($self->{layers_z}[$slider->GetValue])
if $self->enabled;
});
EVT_KEY_DOWN($canvas, sub {
my ($s, $event) = @_;
my $key = $event->GetKeyCode;
if ($key == 85 || $key == 315) {
$slider->SetValue($slider->GetValue + 1);
$self->set_z($self->{layers_z}[$slider->GetValue]);
} elsif ($key == 68 || $key == 317) {
$slider->SetValue($slider->GetValue - 1);
$self->set_z($self->{layers_z}[$slider->GetValue]);
if ($event->HasModifiers) {
$event->Skip;
} else {
my $key = $event->GetKeyCode;
if ($key == ord('D') || $key == WXK_LEFT) {
# Keys: 'D' or WXK_LEFT
$slider->SetValue($slider->GetValue - 1);
$self->set_z($self->{layers_z}[$slider->GetValue]);
} elsif ($key == ord('U') || $key == WXK_RIGHT) {
# Keys: 'U' or WXK_RIGHT
$slider->SetValue($slider->GetValue + 1);
$self->set_z($self->{layers_z}[$slider->GetValue]);
} elsif ($key >= ord('1') && $key <= ord('3')) {
# Keys: '1' to '3'
$canvas->set_simulation_mode($key - ord('1'));
} else {
$event->Skip;
}
}
});
$self->SetSizer($sizer);
$self->SetMinSize($self->GetSize);
$sizer->SetSizeHints($self);
$self->set_z($self->{layers_z}[0]);
# init print
$self->{print} = $print;
$self->reload_print;
return $self;
}
@@ -70,18 +87,42 @@ sub new {
sub reload_print {
my ($self) = @_;
# we require that there's at least one object and the posSlice step
# is performed on all of them (this ensures that _shifted_copies was
# populated and we know the number of layers)
if (!$self->print->object_step_done(STEP_SLICE)) {
$self->enabled(0);
$self->{slider}->Hide;
$self->{canvas}->Refresh; # clears canvas
return;
}
$self->{canvas}->bb($self->print->total_bounding_box);
$self->{canvas}->_dirty(1);
my %z = (); # z => 1
foreach my $object (@{$self->{print}->objects}) {
foreach my $layer (@{$object->layers}, @{$object->support_layers}) {
$z{$layer->print_z} = 1;
}
}
$self->enabled(1);
$self->{layers_z} = [ sort { $a <=> $b } keys %z ];
$self->{slider}->SetRange(0, scalar(@{$self->{layers_z}})-1);
if ((my $z_idx = $self->{slider}->GetValue) <= $#{$self->{layers_z}}) {
$self->set_z($self->{layers_z}[$z_idx]);
} else {
$self->{slider}->SetValue(0);
$self->set_z($self->{layers_z}[0]) if @{$self->{layers_z}};
}
$self->{slider}->Show;
$self->Layout;
}
sub set_z {
my ($self, $z) = @_;
return if !$self->enabled;
$self->{z_label}->SetLabel(sprintf '%.2f', $z);
$self->{canvas}->set_z($z);
}
@@ -89,14 +130,27 @@ sub set_z {
package Slic3r::GUI::Plater::2DToolpaths::Canvas;
use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS);
use OpenGL qw(:glconstants :glfunctions :glufunctions);
use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS);
use OpenGL qw(:glconstants :glfunctions :glufunctions :gluconstants);
use base qw(Wx::GLCanvas Class::Accessor);
use Wx::GLCanvas qw(:all);
use List::Util qw(min first);
use Slic3r::Geometry qw(scale unscale epsilon);
use List::Util qw(min max first);
use Slic3r::Geometry qw(scale epsilon X Y);
use Slic3r::Print::State ':steps';
__PACKAGE__->mk_accessors(qw(print z layers color init dirty bb));
__PACKAGE__->mk_accessors(qw(
print z layers color init
bb
_camera_bb
_dirty
_zoom
_camera_target
_drag_start_xy
_texture_name
_texture_size
_extrusion_simulator
_simulation_mode
));
# make OpenGL::Array thread-safe
{
@@ -107,25 +161,132 @@ __PACKAGE__->mk_accessors(qw(print z layers color init dirty bb));
sub new {
my ($class, $parent, $print) = @_;
my $self = $class->SUPER::new($parent);
my $self = (Wx::wxVERSION >= 3.000003) ?
# The wxWidgets 3.0.3-beta have a bug, they crash with NULL attribute list.
$class->SUPER::new($parent, -1, Wx::wxDefaultPosition, Wx::wxDefaultSize, 0, "",
[WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 24, 0]) :
$class->SUPER::new($parent);
# Immediatelly force creation of the OpenGL context to consume the static variable s_wglContextAttribs.
$self->GetContext();
$self->print($print);
$self->bb($self->print->total_bounding_box);
$self->_zoom(1);
# 2D point in model space
$self->_camera_target(Slic3r::Pointf->new(0,0));
# Texture for the extrusion simulator. The texture will be allocated / reallocated on Resize.
$self->_texture_name(0);
$self->_texture_size(Slic3r::Point->new(0,0));
$self->_extrusion_simulator(Slic3r::ExtrusionSimulator->new());
$self->_simulation_mode(0);
EVT_PAINT($self, sub {
my $dc = Wx::PaintDC->new($self);
$self->Render($dc);
});
EVT_SIZE($self, sub { $self->dirty(1) });
EVT_SIZE($self, sub { $self->_dirty(1) });
EVT_IDLE($self, sub {
return unless $self->dirty;
return unless $self->_dirty;
return if !$self->IsShownOnScreen;
$self->Resize( $self->GetSizeWH );
$self->Resize;
$self->Refresh;
});
EVT_MOUSEWHEEL($self, sub {
my ($self, $e) = @_;
return if !$self->GetParent->enabled;
my $old_zoom = $self->_zoom;
# Calculate the zoom delta and apply it to the current zoom factor
my $zoom = $e->GetWheelRotation() / $e->GetWheelDelta();
$zoom = max(min($zoom, 4), -4);
$zoom /= 10;
$self->_zoom($self->_zoom / (1-$zoom));
$self->_zoom(1) if $self->_zoom > 1; # prevent from zooming out too much
{
# In order to zoom around the mouse point we need to translate
# the camera target. This math is almost there but not perfect yet...
my $camera_bb_size = $self->_camera_bb->size;
my $size = Slic3r::Pointf->new($self->GetSizeWH);
my $pos = Slic3r::Pointf->new($e->GetPositionXY);
# calculate the zooming center in pixel coordinates relative to the viewport center
my $vec = Slic3r::Pointf->new($pos->x - $size->x/2, $pos->y - $size->y/2); #-
# calculate where this point will end up after applying the new zoom
my $vec2 = $vec->clone;
$vec2->scale($old_zoom / $self->_zoom);
# move the camera target by the difference of the two positions
$self->_camera_target->translate(
-($vec->x - $vec2->x) * $camera_bb_size->x / $size->x,
($vec->y - $vec2->y) * $camera_bb_size->y / $size->y, #//
);
}
$self->_dirty(1);
$self->Refresh;
});
EVT_MOUSE_EVENTS($self, \&mouse_event);
return $self;
}
sub Destroy {
my ($self) = @_;
# Deallocate the OpenGL resources.
my $context = $self->GetContext;
if ($context and $self->texture_id) {
$self->SetCurrent($context);
glDeleteTextures(1, ($self->texture_id));
$self->SetCurrent(0);
$self->texture_id(0);
$self->texture_size(new Slic3r::Point(0, 0));
}
return $self->SUPER::Destroy;
}
sub mouse_event {
my ($self, $e) = @_;
return if !$self->GetParent->enabled;
my $pos = Slic3r::Pointf->new($e->GetPositionXY);
if ($e->Entering && &Wx::wxMSW) {
# wxMSW needs focus in order to catch mouse wheel events
$self->SetFocus;
} elsif ($e->Dragging) {
if ($e->LeftIsDown || $e->MiddleIsDown || $e->RightIsDown) {
# if dragging, translate view
if (defined $self->_drag_start_xy) {
my $move = $self->_drag_start_xy->vector_to($pos); # in pixels
# get viewport and camera size in order to convert pixel to model units
my ($x, $y) = $self->GetSizeWH;
my $camera_bb_size = $self->_camera_bb->size;
# compute translation in model units
$self->_camera_target->translate(
-$move->x * $camera_bb_size->x / $x,
$move->y * $camera_bb_size->y / $y, # /**
);
$self->_dirty(1);
$self->Refresh;
}
$self->_drag_start_xy($pos);
}
} elsif ($e->LeftUp || $e->MiddleUp || $e->RightUp) {
$self->_drag_start_xy(undef);
} else {
$e->Skip();
}
}
sub set_z {
my ($self, $z) = @_;
@@ -150,9 +311,18 @@ sub set_z {
}
}
# reverse layers so that we draw the lowermost (i.e. current) on top
$self->z($z);
$self->layers([ @layers ]);
$self->dirty(1);
$self->layers([ reverse @layers ]);
$self->Refresh;
}
sub set_simulation_mode
{
my ($self, $mode) = @_;
$self->_simulation_mode($mode);
$self->_dirty(1);
$self->Refresh;
}
sub Render {
@@ -164,28 +334,115 @@ sub Render {
$self->SetCurrent($context);
$self->InitGL;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
my $bb = $self->bb;
my ($x1, $y1, $x2, $y2) = ($bb->x_min, $bb->y_min, $bb->x_max, $bb->y_max);
my ($x, $y) = $self->GetSizeWH;
if (($x2 - $x1)/($y2 - $y1) > $x/$y) {
# adjust Y
my $new_y = $y * ($x2 - $x1) / $x;
$y1 = ($y2 + $y1)/2 - $new_y/2;
$y2 = $y1 + $new_y;
} else {
my $new_x = $x * ($y2 - $y1) / $y;
$x1 = ($x2 + $x1)/2 - $new_x/2;
$x2 = $x1 + $new_x;
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
if (!$self->GetParent->enabled || !$self->layers) {
$self->SwapBuffers;
return;
}
glOrtho($x1, $x2, $y1, $y2, 0, 1);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if ($self->_simulation_mode and $self->_texture_name and $self->_texture_size->x() > 0 and $self->_texture_size->y() > 0) {
$self->_simulate_extrusion();
my ($x, $y) = $self->GetSizeWH;
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, $self->_texture_name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D_c(GL_TEXTURE_2D,
0, # level (0 normal, heighr is form mip-mapping)
GL_RGBA, # internal format
$self->_texture_size->x(), $self->_texture_size->y(),
0, # border
GL_RGBA, # format RGBA color data
GL_UNSIGNED_BYTE, # unsigned byte data
$self->_extrusion_simulator->image_ptr()); # ptr to texture data
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, 1, 0, 1, 0, 1);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glTexCoord2f($x/$self->_texture_size->x(), 0);
glVertex2f(1, 0);
glTexCoord2f($x/$self->_texture_size->x(), $y/$self->_texture_size->y());
glVertex2f(1, 1);
glTexCoord2f(0, $y/$self->_texture_size->y());
glVertex2f(0, 1);
glEnd();
glPopMatrix();
glBindTexture(GL_TEXTURE_2D, 0);
}
# anti-alias
if (0) {
glEnable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE);
}
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
# Tesselator triangulates polygons with holes on the fly for the rendering purposes only.
my $tess;
if ($self->_simulation_mode() == 0 and !(&Wx::wxMSW && $OpenGL::VERSION < 0.6704)) {
# We can't use the GLU tesselator on MSW with older OpenGL versions
# because of an upstream bug:
# http://sourceforge.net/p/pogl/bugs/16/
$tess = gluNewTess();
gluTessCallback($tess, GLU_TESS_BEGIN, 'DEFAULT');
gluTessCallback($tess, GLU_TESS_END, 'DEFAULT');
gluTessCallback($tess, GLU_TESS_VERTEX, 'DEFAULT');
gluTessCallback($tess, GLU_TESS_COMBINE, 'DEFAULT');
gluTessCallback($tess, GLU_TESS_ERROR, 'DEFAULT');
gluTessCallback($tess, GLU_TESS_EDGE_FLAG, 'DEFAULT');
}
foreach my $layer (@{$self->layers}) {
my $object = $layer->object;
# only draw the slice for the current layer
next unless abs($layer->print_z - $self->z) < epsilon;
# draw slice contour
glLineWidth(1);
foreach my $copy (@{ $object->_shifted_copies }) {
glPushMatrix();
glTranslatef(@$copy, 0);
foreach my $slice (@{$layer->slices}) {
glColor3f(0.95, 0.95, 0.95);
if ($tess) {
gluTessBeginPolygon($tess);
foreach my $polygon (@$slice) {
gluTessBeginContour($tess);
gluTessVertex_p($tess, @$_, 0) for @$polygon;
gluTessEndContour($tess);
}
gluTessEndPolygon($tess);
}
glColor3f(0.9, 0.9, 0.9);
foreach my $polygon (@$slice) {
foreach my $line (@{$polygon->lines}) {
glBegin(GL_LINES);
glVertex2f(@{$line->a});
glVertex2f(@{$line->b});
glEnd();
}
}
}
glPopMatrix();
}
}
my $skirt_drawn = 0;
my $brim_drawn = 0;
@@ -194,40 +451,47 @@ sub Render {
my $print_z = $layer->print_z;
# draw brim
if ($layer->id == 0 && !$brim_drawn) {
if ($self->print->step_done(STEP_BRIM) && $layer->id == 0 && !$brim_drawn) {
$self->color([0, 0, 0]);
$self->_draw(undef, $print_z, $_) for @{$self->print->brim};
$brim_drawn = 1;
}
if (($self->print->config->skirt_height == -1 || $self->print->config->skirt_height >= $layer->id) && !$skirt_drawn) {
if ($self->print->step_done(STEP_SKIRT)
&& ($self->print->has_infinite_skirt() || $self->print->config->skirt_height > $layer->id)
&& !$skirt_drawn) {
$self->color([0, 0, 0]);
$self->_draw(undef, $print_z, $_) for @{$self->print->skirt};
$skirt_drawn = 1;
}
foreach my $layerm (@{$layer->regions}) {
$self->color([0.7, 0, 0]);
$self->_draw($object, $print_z, $_) for @{$layerm->perimeters};
if ($object->step_done(STEP_PERIMETERS)) {
$self->color([0.7, 0, 0]);
$self->_draw($object, $print_z, $_) for map @$_, @{$layerm->perimeters};
}
$self->color([0, 0, 0.7]);
$self->_draw($object, $print_z, $_) for map @$_, @{$layerm->fills};
if ($object->step_done(STEP_INFILL)) {
$self->color([0, 0, 0.7]);
$self->_draw($object, $print_z, $_) for map @$_, @{$layerm->fills};
}
}
if ($layer->isa('Slic3r::Layer::Support')) {
$self->color([0, 0, 0]);
$self->_draw($object, $print_z, $_) for @{$layer->support_fills};
$self->_draw($object, $print_z, $_) for @{$layer->support_interface_fills};
if ($object->step_done(STEP_SUPPORTMATERIAL)) {
if ($layer->isa('Slic3r::Layer::Support')) {
$self->color([0, 0, 0]);
$self->_draw($object, $print_z, $_) for @{$layer->support_fills};
}
}
}
glFlush();
gluDeleteTess($tess) if $tess;
$self->SwapBuffers;
}
sub _draw {
my ($self, $object, $print_z, $path) = @_;
my @paths = $path->isa('Slic3r::ExtrusionLoop')
my @paths = ($path->isa('Slic3r::ExtrusionLoop') || $path->isa('Slic3r::ExtrusionMultiPath'))
? @$path
: ($path);
@@ -249,13 +513,15 @@ sub _draw_path {
if (defined $object) {
foreach my $copy (@{ $object->_shifted_copies }) {
glPushMatrix();
glTranslatef(@$copy, 0);
foreach my $line (@{$path->polyline->lines}) {
$line->translate(@$copy);
glBegin(GL_LINES);
glVertex2f(@{$line->a});
glVertex2f(@{$line->b});
glEnd();
}
glPopMatrix();
}
} else {
foreach my $line (@{$path->polyline->lines}) {
@@ -263,8 +529,42 @@ sub _draw_path {
glVertex2f(@{$line->a});
glVertex2f(@{$line->b});
glEnd();
}
}
}
sub _simulate_extrusion {
my ($self) = @_;
$self->_extrusion_simulator->reset_accumulator();
foreach my $layer (@{$self->layers}) {
if (abs($layer->print_z - $self->z) < epsilon) {
my $object = $layer->object;
my @shifts = (defined $object) ? @{$object->_shifted_copies} : (Slic3r::Point->new(0, 0));
foreach my $layerm (@{$layer->regions}) {
my @extrusions = ();
if ($object->step_done(STEP_PERIMETERS)) {
push @extrusions, @$_ for @{$layerm->perimeters};
}
if ($object->step_done(STEP_INFILL)) {
push @extrusions, @$_ for @{$layerm->fills};
}
foreach my $extrusion_entity (@extrusions) {
my @paths = ($extrusion_entity->isa('Slic3r::ExtrusionLoop') || $extrusion_entity->isa('Slic3r::ExtrusionMultiPath'))
? @$extrusion_entity
: ($extrusion_entity);
foreach my $path (@paths) {
print "width: ", $path->width,
" height: ", $path->height,
" mm3_per_mm: ", $path->mm3_per_mm,
" height2: ", $path->mm3_per_mm / $path->height,
"\n";
$self->_extrusion_simulator->extrude_to_accumulator($path, $_, $self->_simulation_mode()) for @shifts;
}
}
}
}
}
$self->_extrusion_simulator->evaluate_accumulator($self->_simulation_mode());
}
sub InitGL {
@@ -272,39 +572,126 @@ sub InitGL {
return if $self->init;
return unless $self->GetContext;
my $texture_id = 0;
($texture_id) = glGenTextures_p(1);
$self->_texture_name($texture_id);
$self->init(1);
}
sub GetContext {
my ($self) = @_;
if (Wx::wxVERSION >= 2.009) {
return $self->{context} ||= Wx::GLContext->new($self);
} else {
return $self->SUPER::GetContext;
}
return $self->{context} ||= Wx::GLContext->new($self);
}
sub SetCurrent {
my ($self, $context) = @_;
if (Wx::wxVERSION >= 2.009) {
return $self->SUPER::SetCurrent($context);
} else {
return $self->SUPER::SetCurrent;
}
return $self->SUPER::SetCurrent($context);
}
sub Resize {
my ($self, $x, $y) = @_;
my ($self) = @_;
return unless $self->GetContext;
$self->dirty(0);
return unless $self->bb;
$self->_dirty(0);
$self->SetCurrent($self->GetContext);
my ($x, $y) = $self->GetSizeWH;
if ($self->_texture_size->x() < $x or $self->_texture_size->y() < $y) {
# Allocate a large enough OpenGL texture with power of 2 dimensions.
$self->_texture_size->set_x(1) if ($self->_texture_size->x() == 0);
$self->_texture_size->set_y(1) if ($self->_texture_size->y() == 0);
$self->_texture_size->set_x($self->_texture_size->x() * 2) while ($self->_texture_size->x() < $x);
$self->_texture_size->set_y($self->_texture_size->y() * 2) while ($self->_texture_size->y() < $y);
#print "screen size ", $x, "x", $y;
#print "texture size ", $self->_texture_size->x(), "x", $self->_texture_size->y();
# Initialize an empty texture.
glBindTexture(GL_TEXTURE_2D, $self->_texture_name);
if (1) {
glTexImage2D_c(GL_TEXTURE_2D,
0, # level (0 normal, heighr is form mip-mapping)
GL_RGBA, # internal format
$self->_texture_size->x(), $self->_texture_size->y(),
0, # border
GL_RGBA, # format RGBA color data
GL_UNSIGNED_BYTE, # unsigned byte data
0); # ptr to texture data
}
glBindTexture(GL_TEXTURE_2D, 0);
$self->_extrusion_simulator->set_image_size($self->_texture_size);
}
$self->_extrusion_simulator->set_viewport(Slic3r::Geometry::BoundingBox->new_from_points(
[Slic3r::Point->new(0, 0), Slic3r::Point->new($x, $y)]));
glViewport(0, 0, $x, $y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
my $bb = $self->bb->clone;
# center bounding box around origin before scaling it
my $bb_center = $bb->center;
$bb->translate(@{$bb_center->negative});
# scale bounding box according to zoom factor
$bb->scale($self->_zoom);
# reposition bounding box around original center
$bb->translate(@{$bb_center});
# translate camera
$bb->translate(@{$self->_camera_target});
# keep camera_bb within total bb
# (i.e. prevent user from panning outside the bounding box)
{
my @translate = (0,0);
if ($bb->x_min < $self->bb->x_min) {
$translate[X] += $self->bb->x_min - $bb->x_min;
}
if ($bb->y_min < $self->bb->y_min) {
$translate[Y] += $self->bb->y_min - $bb->y_min;
}
if ($bb->x_max > $self->bb->x_max) {
$translate[X] -= $bb->x_max - $self->bb->x_max;
}
if ($bb->y_max > $self->bb->y_max) {
$translate[Y] -= $bb->y_max - $self->bb->y_max;
}
$self->_camera_target->translate(@translate);
$bb->translate(@translate);
}
# save camera
$self->_camera_bb($bb);
my ($x1, $y1, $x2, $y2) = ($bb->x_min, $bb->y_min, $bb->x_max, $bb->y_max);
if (($x2 - $x1)/($y2 - $y1) > $x/$y) {
# adjust Y
my $new_y = $y * ($x2 - $x1) / $x;
$y1 = ($y2 + $y1)/2 - $new_y/2;
$y2 = $y1 + $new_y;
} else {
my $new_x = $x * ($y2 - $y1) / $y;
$x1 = ($x2 + $x1)/2 - $new_x/2;
$x2 = $x1 + $new_x;
}
glOrtho($x1, $x2, $y1, $y2, 0, 1);
# Set the adjusted bounding box at the extrusion simulator.
#print "Scene bbox ", $bb->x_min, ",", $bb->y_min, " ", $bb->x_max, ",", $bb->y_max, "\n";
#print "Setting simulator bbox ", $x1, ",", $y1, " ", $x2, ",", $y2, "\n";
$self->_extrusion_simulator->set_bounding_box(
Slic3r::Geometry::BoundingBox->new_from_points(
[Slic3r::Point->new($x1, $y1), Slic3r::Point->new($x2, $y2)]));
glMatrixMode(GL_MODELVIEW);
}
# Thick line drawing is not used anywhere. Probably not tested?
sub line {
my (
$x1, $y1, $x2, $y2, # coordinates of the line

View File

@@ -4,43 +4,280 @@ use warnings;
use utf8;
use List::Util qw();
use Slic3r::Geometry qw();
use Slic3r::Geometry::Clipper qw();
use Wx qw(:misc :pen :brush :sizer :font :cursor wxTAB_TRAVERSAL);
use Wx::Event qw();
use base 'Slic3r::GUI::PreviewCanvas';
use Wx qw(:misc :pen :brush :sizer :font :cursor :keycode wxTAB_TRAVERSAL);
#==============================================================================================================================
#use Wx::Event qw(EVT_KEY_DOWN EVT_CHAR);
#==============================================================================================================================
use base qw(Slic3r::GUI::3DScene Class::Accessor);
#==============================================================================================================================
#use Wx::Locale gettext => 'L';
#
#__PACKAGE__->mk_accessors(qw(
# on_arrange on_rotate_object_left on_rotate_object_right on_scale_object_uniformly
# on_remove_object on_increase_objects on_decrease_objects on_enable_action_buttons));
#==============================================================================================================================
sub new {
my $class = shift;
my ($parent, $objects, $model, $config) = @_;
my ($parent, $objects, $model, $print, $config) = @_;
my $self = $class->SUPER::new($parent);
$self->{objects} = $objects;
$self->{model} = $model;
$self->{config} = $config;
$self->{on_select_object} = sub {};
$self->{on_double_click} = sub {};
$self->{on_right_click} = sub {};
$self->{on_instance_moved} = sub {};
#==============================================================================================================================
Slic3r::GUI::_3DScene::enable_picking($self, 1);
Slic3r::GUI::_3DScene::enable_moving($self, 1);
Slic3r::GUI::_3DScene::set_select_by($self, 'object');
Slic3r::GUI::_3DScene::set_drag_by($self, 'instance');
Slic3r::GUI::_3DScene::set_model($self, $model);
Slic3r::GUI::_3DScene::set_print($self, $print);
Slic3r::GUI::_3DScene::set_config($self, $config);
# $self->enable_picking(1);
# $self->enable_moving(1);
# $self->select_by('object');
# $self->drag_by('instance');
#
# $self->{objects} = $objects;
# $self->{model} = $model;
# $self->{print} = $print;
# $self->{config} = $config;
# $self->{on_select_object} = sub {};
# $self->{on_instances_moved} = sub {};
# $self->{on_wipe_tower_moved} = sub {};
#
# $self->{objects_volumes_idxs} = [];
#
# $self->on_select(sub {
# my ($volume_idx) = @_;
# $self->{on_select_object}->(($volume_idx == -1) ? undef : $self->volumes->[$volume_idx]->object_idx)
# if ($self->{on_select_object});
# });
#
# $self->on_move(sub {
# my @volume_idxs = @_;
# my %done = (); # prevent moving instances twice
# my $object_moved;
# my $wipe_tower_moved;
# foreach my $volume_idx (@volume_idxs) {
# my $volume = $self->volumes->[$volume_idx];
# my $obj_idx = $volume->object_idx;
# my $instance_idx = $volume->instance_idx;
# next if $done{"${obj_idx}_${instance_idx}"};
# $done{"${obj_idx}_${instance_idx}"} = 1;
# if ($obj_idx < 1000) {
# # Move a regular object.
# my $model_object = $self->{model}->get_object($obj_idx);
# $model_object
# ->instances->[$instance_idx]
# ->offset
# ->translate($volume->origin->x, $volume->origin->y); #))
# $model_object->invalidate_bounding_box;
# $object_moved = 1;
# } elsif ($obj_idx == 1000) {
# # Move a wipe tower proxy.
# $wipe_tower_moved = $volume->origin;
# }
# }
#
# $self->{on_instances_moved}->()
# if $object_moved && $self->{on_instances_moved};
# $self->{on_wipe_tower_moved}->($wipe_tower_moved)
# if $wipe_tower_moved && $self->{on_wipe_tower_moved};
# });
#
# EVT_KEY_DOWN($self, sub {
# my ($s, $event) = @_;
# if ($event->HasModifiers) {
# $event->Skip;
# } else {
# my $key = $event->GetKeyCode;
# if ($key == WXK_DELETE) {
# $self->on_remove_object->() if $self->on_remove_object;
# } else {
# $event->Skip;
# }
# }
# });
#
# EVT_CHAR($self, sub {
# my ($s, $event) = @_;
# if ($event->HasModifiers) {
# $event->Skip;
# } else {
# my $key = $event->GetKeyCode;
# if ($key == ord('a')) {
# $self->on_arrange->() if $self->on_arrange;
# } elsif ($key == ord('l')) {
# $self->on_rotate_object_left->() if $self->on_rotate_object_left;
# } elsif ($key == ord('r')) {
# $self->on_rotate_object_right->() if $self->on_rotate_object_right;
# } elsif ($key == ord('s')) {
# $self->on_scale_object_uniformly->() if $self->on_scale_object_uniformly;
# } elsif ($key == ord('+')) {
# $self->on_increase_objects->() if $self->on_increase_objects;
# } elsif ($key == ord('-')) {
# $self->on_decrease_objects->() if $self->on_decrease_objects;
# } else {
# $event->Skip;
# }
# }
# });
#==============================================================================================================================
return $self;
}
sub update {
my ($self) = @_;
$self->reset_objects;
return if $self->{model}->objects_count == 0;
$self->set_bounding_box($self->{model}->bounding_box);
$self->set_bed_shape($self->{config}->bed_shape);
foreach my $model_object (@{$self->{model}->objects}) {
$self->load_object($model_object, 1);
}
}
#==============================================================================================================================
#sub set_on_select_object {
# my ($self, $cb) = @_;
# $self->{on_select_object} = $cb;
#}
#
#sub set_on_double_click {
# my ($self, $cb) = @_;
# $self->on_double_click($cb);
#}
#
#sub set_on_right_click {
# my ($self, $cb) = @_;
# $self->on_right_click($cb);
#}
#
#sub set_on_arrange {
# my ($self, $cb) = @_;
# $self->on_arrange($cb);
#}
#
#sub set_on_rotate_object_left {
# my ($self, $cb) = @_;
# $self->on_rotate_object_left($cb);
#}
#
#sub set_on_rotate_object_right {
# my ($self, $cb) = @_;
# $self->on_rotate_object_right($cb);
#}
#
#sub set_on_scale_object_uniformly {
# my ($self, $cb) = @_;
# $self->on_scale_object_uniformly($cb);
#}
#
#sub set_on_increase_objects {
# my ($self, $cb) = @_;
# $self->on_increase_objects($cb);
#}
#
#sub set_on_decrease_objects {
# my ($self, $cb) = @_;
# $self->on_decrease_objects($cb);
#}
#
#sub set_on_remove_object {
# my ($self, $cb) = @_;
# $self->on_remove_object($cb);
#}
#
#sub set_on_instances_moved {
# my ($self, $cb) = @_;
# $self->{on_instances_moved} = $cb;
#}
#
#sub set_on_wipe_tower_moved {
# my ($self, $cb) = @_;
# $self->{on_wipe_tower_moved} = $cb;
#}
#
#sub set_on_model_update {
# my ($self, $cb) = @_;
# $self->on_model_update($cb);
#}
#
#sub set_on_enable_action_buttons {
# my ($self, $cb) = @_;
# $self->on_enable_action_buttons($cb);
#}
#
#sub update_volumes_selection {
# my ($self) = @_;
#
# foreach my $obj_idx (0..$#{$self->{model}->objects}) {
# if ($self->{objects}[$obj_idx]->selected) {
# my $volume_idxs = $self->{objects_volumes_idxs}->[$obj_idx];
# $self->select_volume($_) for @{$volume_idxs};
# }
# }
#}
#
#sub reload_scene {
# my ($self, $force) = @_;
#
# $self->reset_objects;
# $self->update_bed_size;
#
# if (! $self->IsShown && ! $force) {
# $self->{reload_delayed} = 1;
# return;
# }
#
# $self->{reload_delayed} = 0;
#
# $self->{objects_volumes_idxs} = [];
# foreach my $obj_idx (0..$#{$self->{model}->objects}) {
# my @volume_idxs = $self->load_object($self->{model}, $self->{print}, $obj_idx);
# push(@{$self->{objects_volumes_idxs}}, \@volume_idxs);
# }
#
# $self->update_volumes_selection;
#
# if (defined $self->{config}->nozzle_diameter) {
# # Should the wipe tower be visualized?
# my $extruders_count = scalar @{ $self->{config}->nozzle_diameter };
# # Height of a print.
# my $height = $self->{model}->bounding_box->z_max;
# # Show at least a slab.
# $height = 10 if $height < 10;
# if ($extruders_count > 1 && $self->{config}->single_extruder_multi_material && $self->{config}->wipe_tower &&
# ! $self->{config}->complete_objects) {
# $self->volumes->load_wipe_tower_preview(1000,
# $self->{config}->wipe_tower_x, $self->{config}->wipe_tower_y, $self->{config}->wipe_tower_width,
# #$self->{config}->wipe_tower_per_color_wipe# 15 * ($extruders_count - 1), # this is just a hack when the config parameter became obsolete
# 15 * ($extruders_count - 1),
# $self->{model}->bounding_box->z_max, $self->{config}->wipe_tower_rotation_angle, $self->UseVBOs);
# }
# }
#
# $self->update_volumes_colors_by_extruder($self->{config});
#
# # checks for geometry outside the print volume to render it accordingly
# if (scalar @{$self->volumes} > 0)
# {
# my $contained = $self->volumes->check_outside_state($self->{config});
# if (!$contained) {
# $self->set_warning_enabled(1);
# Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume"));
# $self->on_enable_action_buttons->(0) if ($self->on_enable_action_buttons);
# } else {
# $self->set_warning_enabled(0);
# $self->volumes->reset_outside_state();
# Slic3r::GUI::_3DScene::reset_warning_texture();
# $self->on_enable_action_buttons->(scalar @{$self->{model}->objects} > 0) if ($self->on_enable_action_buttons);
# }
# } else {
# $self->set_warning_enabled(0);
# Slic3r::GUI::_3DScene::reset_warning_texture();
# }
#}
#
#sub update_bed_size {
# my ($self) = @_;
# $self->set_bed_shape($self->{config}->bed_shape);
#}
#
## Called by the Platter wxNotebook when this page is activated.
#sub OnActivate {
# my ($self) = @_;
# $self->reload_scene(1) if ($self->{reload_delayed});
#}
#==============================================================================================================================
1;

View File

@@ -0,0 +1,542 @@
package Slic3r::GUI::Plater::3DPreview;
use strict;
use warnings;
use utf8;
use Slic3r::Print::State ':steps';
use Wx qw(:misc :sizer :slider :statictext :keycode wxWHITE wxCB_READONLY);
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN EVT_CHECKBOX EVT_CHOICE EVT_CHECKLISTBOX);
use base qw(Wx::Panel Class::Accessor);
use Wx::Locale gettext => 'L';
__PACKAGE__->mk_accessors(qw(print gcode_preview_data enabled _loaded canvas slider_low slider_high single_layer));
sub new {
my $class = shift;
my ($parent, $print, $gcode_preview_data, $config) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition);
$self->{config} = $config;
$self->{number_extruders} = 1;
# Show by feature type by default.
$self->{preferred_color_mode} = 'feature';
# init GUI elements
my $canvas = Slic3r::GUI::3DScene->new($self);
Slic3r::GUI::_3DScene::enable_shader($canvas, 1);
$self->canvas($canvas);
my $slider_low = Wx::Slider->new(
$self, -1,
0, # default
0, # min
# we set max to a bogus non-zero value because the MSW implementation of wxSlider
# will skip drawing the slider if max <= min:
1, # max
wxDefaultPosition,
wxDefaultSize,
wxVERTICAL | wxSL_INVERSE,
);
$self->slider_low($slider_low);
my $slider_high = Wx::Slider->new(
$self, -1,
0, # default
0, # min
# we set max to a bogus non-zero value because the MSW implementation of wxSlider
# will skip drawing the slider if max <= min:
1, # max
wxDefaultPosition,
wxDefaultSize,
wxVERTICAL | wxSL_INVERSE,
);
$self->slider_high($slider_high);
my $z_label_low = $self->{z_label_low} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
$z_label_low->SetFont($Slic3r::GUI::small_font);
my $z_label_high = $self->{z_label_high} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
$z_label_high->SetFont($Slic3r::GUI::small_font);
my $z_label_low_idx = $self->{z_label_low_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
$z_label_low_idx->SetFont($Slic3r::GUI::small_font);
my $z_label_high_idx = $self->{z_label_high_idx} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
$z_label_high_idx->SetFont($Slic3r::GUI::small_font);
$self->single_layer(0);
my $checkbox_singlelayer = $self->{checkbox_singlelayer} = Wx::CheckBox->new($self, -1, L("1 Layer"));
my $label_view_type = $self->{label_view_type} = Wx::StaticText->new($self, -1, L("View"));
my $choice_view_type = $self->{choice_view_type} = Wx::Choice->new($self, -1);
$choice_view_type->Append(L("Feature type"));
$choice_view_type->Append(L("Height"));
$choice_view_type->Append(L("Width"));
$choice_view_type->Append(L("Speed"));
$choice_view_type->Append(L("Volumetric flow rate"));
$choice_view_type->Append(L("Tool"));
$choice_view_type->SetSelection(0);
# the following value needs to be changed if new items are added into $choice_view_type before "Tool"
$self->{tool_idx} = 5;
my $label_show_features = $self->{label_show_features} = Wx::StaticText->new($self, -1, L("Show"));
my $combochecklist_features = $self->{combochecklist_features} = Wx::ComboCtrl->new();
$combochecklist_features->Create($self, -1, L("Feature types"), wxDefaultPosition, [200, -1], wxCB_READONLY);
my $feature_text = L("Feature types");
my $feature_items = L("Perimeter")."|"
.L("External perimeter")."|"
.L("Overhang perimeter")."|"
.L("Internal infill")."|"
.L("Solid infill")."|"
.L("Top solid infill")."|"
.L("Bridge infill")."|"
.L("Gap fill")."|"
.L("Skirt")."|"
.L("Support material")."|"
.L("Support material interface")."|"
.L("Wipe tower")."|"
.L("Custom");
Slic3r::GUI::create_combochecklist($combochecklist_features, $feature_text, $feature_items, 1);
my $checkbox_travel = $self->{checkbox_travel} = Wx::CheckBox->new($self, -1, L("Travel"));
my $checkbox_retractions = $self->{checkbox_retractions} = Wx::CheckBox->new($self, -1, L("Retractions"));
my $checkbox_unretractions = $self->{checkbox_unretractions} = Wx::CheckBox->new($self, -1, L("Unretractions"));
my $checkbox_shells = $self->{checkbox_shells} = Wx::CheckBox->new($self, -1, L("Shells"));
my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL);
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
my $vsizer_outer = Wx::BoxSizer->new(wxVERTICAL);
$vsizer->Add($slider_low, 3, wxALIGN_CENTER_HORIZONTAL, 0);
$vsizer->Add($z_label_low_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0);
$vsizer->Add($z_label_low, 0, wxALIGN_CENTER_HORIZONTAL, 0);
$hsizer->Add($vsizer, 0, wxEXPAND, 0);
$vsizer = Wx::BoxSizer->new(wxVERTICAL);
$vsizer->Add($slider_high, 3, wxALIGN_CENTER_HORIZONTAL, 0);
$vsizer->Add($z_label_high_idx, 0, wxALIGN_CENTER_HORIZONTAL, 0);
$vsizer->Add($z_label_high, 0, 0, 0);
$hsizer->Add($vsizer, 0, wxEXPAND, 0);
$vsizer_outer->Add($hsizer, 3, wxALIGN_CENTER_HORIZONTAL, 0);
$vsizer_outer->Add($checkbox_singlelayer, 0, wxTOP | wxALIGN_CENTER_HORIZONTAL, 5);
my $bottom_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$bottom_sizer->Add($label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->Add($choice_view_type, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($label_show_features, 0, wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->Add($combochecklist_features, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(20);
$bottom_sizer->Add($checkbox_travel, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($checkbox_retractions, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($checkbox_unretractions, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
$bottom_sizer->AddSpacer(10);
$bottom_sizer->Add($checkbox_shells, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$sizer->Add($canvas, 1, wxALL | wxEXPAND, 0);
$sizer->Add($vsizer_outer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5);
my $main_sizer = Wx::BoxSizer->new(wxVERTICAL);
$main_sizer->Add($sizer, 1, wxALL | wxEXPAND, 0);
$main_sizer->Add($bottom_sizer, 0, wxALL | wxEXPAND, 0);
EVT_SLIDER($self, $slider_low, sub {
$slider_high->SetValue($slider_low->GetValue) if $self->single_layer;
$self->set_z_idx_low ($slider_low ->GetValue)
});
EVT_SLIDER($self, $slider_high, sub {
$slider_low->SetValue($slider_high->GetValue) if $self->single_layer;
$self->set_z_idx_high($slider_high->GetValue)
});
EVT_KEY_DOWN($canvas, sub {
my ($s, $event) = @_;
my $key = $event->GetKeyCode;
if ($event->HasModifiers) {
$event->Skip;
} else {
if ($key == ord('U')) {
$slider_high->SetValue($slider_high->GetValue + 1);
$slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown());
$self->set_z_idx_high($slider_high->GetValue);
} elsif ($key == ord('D')) {
$slider_high->SetValue($slider_high->GetValue - 1);
$slider_low->SetValue($slider_high->GetValue) if ($event->ShiftDown());
$self->set_z_idx_high($slider_high->GetValue);
} elsif ($key == ord('S')) {
$checkbox_singlelayer->SetValue(! $checkbox_singlelayer->GetValue());
$self->single_layer($checkbox_singlelayer->GetValue());
if ($self->single_layer) {
$slider_low->SetValue($slider_high->GetValue);
$self->set_z_idx_high($slider_high->GetValue);
}
} else {
$event->Skip;
}
}
});
EVT_KEY_DOWN($slider_low, sub {
my ($s, $event) = @_;
my $key = $event->GetKeyCode;
if ($event->HasModifiers) {
$event->Skip;
} else {
if ($key == WXK_LEFT) {
} elsif ($key == WXK_RIGHT) {
$slider_high->SetFocus;
} else {
$event->Skip;
}
}
});
EVT_KEY_DOWN($slider_high, sub {
my ($s, $event) = @_;
my $key = $event->GetKeyCode;
if ($event->HasModifiers) {
$event->Skip;
} else {
if ($key == WXK_LEFT) {
$slider_low->SetFocus;
} elsif ($key == WXK_RIGHT) {
} else {
$event->Skip;
}
}
});
EVT_CHECKBOX($self, $checkbox_singlelayer, sub {
$self->single_layer($checkbox_singlelayer->GetValue());
if ($self->single_layer) {
$slider_low->SetValue($slider_high->GetValue);
$self->set_z_idx_high($slider_high->GetValue);
}
});
EVT_CHOICE($self, $choice_view_type, sub {
my $selection = $choice_view_type->GetCurrentSelection();
$self->{preferred_color_mode} = ($selection == $self->{tool_idx}) ? 'tool' : 'feature';
$self->gcode_preview_data->set_type($selection);
$self->reload_print;
});
EVT_CHECKLISTBOX($self, $combochecklist_features, sub {
my $flags = Slic3r::GUI::combochecklist_get_flags($combochecklist_features);
$self->gcode_preview_data->set_extrusion_flags($flags);
$self->refresh_print;
});
EVT_CHECKBOX($self, $checkbox_travel, sub {
$self->gcode_preview_data->set_travel_visible($checkbox_travel->IsChecked());
$self->refresh_print;
});
EVT_CHECKBOX($self, $checkbox_retractions, sub {
$self->gcode_preview_data->set_retractions_visible($checkbox_retractions->IsChecked());
$self->refresh_print;
});
EVT_CHECKBOX($self, $checkbox_unretractions, sub {
$self->gcode_preview_data->set_unretractions_visible($checkbox_unretractions->IsChecked());
$self->refresh_print;
});
EVT_CHECKBOX($self, $checkbox_shells, sub {
$self->gcode_preview_data->set_shells_visible($checkbox_shells->IsChecked());
$self->refresh_print;
});
$self->SetSizer($main_sizer);
$self->SetMinSize($self->GetSize);
$sizer->SetSizeHints($self);
# init canvas
$self->print($print);
$self->gcode_preview_data($gcode_preview_data);
# sets colors for gcode preview extrusion roles
my @extrusion_roles_colors = (
'Perimeter' => 'FFFF66',
'External perimeter' => 'FFA500',
'Overhang perimeter' => '0000FF',
'Internal infill' => 'B1302A',
'Solid infill' => 'D732D7',
'Top solid infill' => 'FF1A1A',
'Bridge infill' => '9999FF',
'Gap fill' => 'FFFFFF',
'Skirt' => '845321',
'Support material' => '00FF00',
'Support material interface' => '008000',
'Wipe tower' => 'B3E3AB',
'Custom' => '28CC94',
);
$self->gcode_preview_data->set_extrusion_paths_colors(\@extrusion_roles_colors);
$self->show_hide_ui_elements('none');
$self->reload_print;
return $self;
}
sub reload_print {
my ($self, $force) = @_;
Slic3r::GUI::_3DScene::reset_volumes($self->canvas);
$self->_loaded(0);
if (! $self->IsShown && ! $force) {
# $self->{reload_delayed} = 1;
return;
}
$self->load_print;
}
sub refresh_print {
my ($self) = @_;
$self->_loaded(0);
if (! $self->IsShown) {
return;
}
$self->load_print;
}
sub reset_gcode_preview_data {
my ($self) = @_;
$self->gcode_preview_data->reset;
Slic3r::GUI::_3DScene::reset_legend_texture();
}
sub load_print {
my ($self) = @_;
return if $self->_loaded;
# we require that there's at least one object and the posSlice step
# is performed on all of them (this ensures that _shifted_copies was
# populated and we know the number of layers)
my $n_layers = 0;
if ($self->print->object_step_done(STEP_SLICE)) {
my %z = (); # z => 1
foreach my $object (@{$self->{print}->objects}) {
foreach my $layer (@{$object->layers}, @{$object->support_layers}) {
$z{$layer->print_z} = 1;
}
}
$self->{layers_z} = [ sort { $a <=> $b } keys %z ];
$n_layers = scalar(@{$self->{layers_z}});
}
if ($n_layers == 0) {
$self->reset_sliders;
Slic3r::GUI::_3DScene::reset_legend_texture();
$self->canvas->Refresh; # clears canvas
return;
}
if ($self->{preferred_color_mode} eq 'tool_or_feature') {
# It is left to Slic3r to decide whether the print shall be colored by the tool or by the feature.
# Color by feature if it is a single extruder print.
my $extruders = $self->{print}->extruders;
my $type = (scalar(@{$extruders}) > 1) ? $self->{tool_idx} : 0;
$self->gcode_preview_data->set_type($type);
$self->{choice_view_type}->SetSelection($type);
# If the ->SetSelection changed the following line, revert it to "decide yourself".
$self->{preferred_color_mode} = 'tool_or_feature';
}
# Collect colors per extruder.
my @colors = ();
if (! $self->gcode_preview_data->empty() || $self->gcode_preview_data->type == $self->{tool_idx}) {
my @extruder_colors = @{$self->{config}->extruder_colour};
my @filament_colors = @{$self->{config}->filament_colour};
for (my $i = 0; $i <= $#extruder_colors; $i += 1) {
my $color = $extruder_colors[$i];
$color = $filament_colors[$i] if (! defined($color) || $color !~ m/^#[[:xdigit:]]{6}/);
$color = '#FFFFFF' if (! defined($color) || $color !~ m/^#[[:xdigit:]]{6}/);
push @colors, $color;
}
}
if ($self->IsShown) {
# used to set the sliders to the extremes of the current zs range
$self->{force_sliders_full_range} = 0;
if ($self->gcode_preview_data->empty) {
# load skirt and brim
Slic3r::GUI::_3DScene::set_print($self->canvas, $self->print);
Slic3r::GUI::_3DScene::load_print_toolpaths($self->canvas);
Slic3r::GUI::_3DScene::load_wipe_tower_toolpaths($self->canvas, \@colors);
foreach my $object (@{$self->print->objects}) {
Slic3r::GUI::_3DScene::load_print_object_toolpaths($self->canvas, $object, \@colors);
# Show the objects in very transparent color.
#my @volume_ids = $self->canvas->load_object($object->model_object);
#$self->canvas->volumes->[$_]->color->[3] = 0.2 for @volume_ids;
}
$self->show_hide_ui_elements('simple');
Slic3r::GUI::_3DScene::reset_legend_texture();
} else {
$self->{force_sliders_full_range} = (Slic3r::GUI::_3DScene::get_volumes_count($self->canvas) == 0);
Slic3r::GUI::_3DScene::set_print($self->canvas, $self->print);
Slic3r::GUI::_3DScene::load_gcode_preview($self->canvas, $self->gcode_preview_data, \@colors);
$self->show_hide_ui_elements('full');
# recalculates zs and update sliders accordingly
$self->{layers_z} = Slic3r::GUI::_3DScene::get_current_print_zs($self->canvas, 1);
$n_layers = scalar(@{$self->{layers_z}});
if ($n_layers == 0) {
# all layers filtered out
$self->reset_sliders;
$self->canvas->Refresh; # clears canvas
}
}
$self->update_sliders($n_layers) if ($n_layers > 0);
$self->_loaded(1);
}
}
sub reset_sliders {
my ($self) = @_;
$self->enabled(0);
$self->set_z_range(0,0);
$self->slider_low->Hide;
$self->slider_high->Hide;
$self->{z_label_low}->SetLabel("");
$self->{z_label_high}->SetLabel("");
$self->{z_label_low_idx}->SetLabel("");
$self->{z_label_high_idx}->SetLabel("");
}
sub update_sliders
{
my ($self, $n_layers) = @_;
my $z_idx_low = $self->slider_low->GetValue;
my $z_idx_high = $self->slider_high->GetValue;
$self->enabled(1);
$self->slider_low->SetRange(0, $n_layers - 1);
$self->slider_high->SetRange(0, $n_layers - 1);
if ($self->{force_sliders_full_range}) {
$z_idx_low = 0;
$z_idx_high = $n_layers - 1;
} elsif ($z_idx_high < $n_layers && ($self->single_layer || $z_idx_high != 0)) {
# search new indices for nearest z (size of $self->{layers_z} may change in dependence of what is shown)
if (defined($self->{z_low})) {
for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
if ($self->{layers_z}[$i] <= $self->{z_low}) {
$z_idx_low = $i;
last;
}
}
}
if (defined($self->{z_high})) {
for (my $i = scalar(@{$self->{layers_z}}) - 1; $i >= 0; $i -= 1) {
if ($self->{layers_z}[$i] <= $self->{z_high}) {
$z_idx_high = $i;
last;
}
}
}
} elsif ($z_idx_high >= $n_layers) {
# Out of range. Disable 'single layer' view.
$self->single_layer(0);
$self->{checkbox_singlelayer}->SetValue(0);
$z_idx_low = 0;
$z_idx_high = $n_layers - 1;
} else {
$z_idx_low = 0;
$z_idx_high = $n_layers - 1;
}
$self->slider_low->SetValue($z_idx_low);
$self->slider_high->SetValue($z_idx_high);
$self->slider_low->Show;
$self->slider_high->Show;
$self->set_z_range($self->{layers_z}[$z_idx_low], $self->{layers_z}[$z_idx_high]);
$self->Layout;
}
sub set_z_range
{
my ($self, $z_low, $z_high) = @_;
return if !$self->enabled;
$self->{z_low} = $z_low;
$self->{z_high} = $z_high;
$self->{z_label_low}->SetLabel(sprintf '%.2f', $z_low);
$self->{z_label_high}->SetLabel(sprintf '%.2f', $z_high);
my $layers_z = Slic3r::GUI::_3DScene::get_current_print_zs($self->canvas, 0);
for (my $i = 0; $i < scalar(@{$layers_z}); $i += 1) {
if (($z_low - 1e-6 < @{$layers_z}[$i]) && (@{$layers_z}[$i] < $z_low + 1e-6)) {
$self->{z_label_low_idx}->SetLabel(sprintf '%d', $i + 1);
last;
}
}
for (my $i = 0; $i < scalar(@{$layers_z}); $i += 1) {
if (($z_high - 1e-6 < @{$layers_z}[$i]) && (@{$layers_z}[$i] < $z_high + 1e-6)) {
$self->{z_label_high_idx}->SetLabel(sprintf '%d', $i + 1);
last;
}
}
Slic3r::GUI::_3DScene::set_toolpaths_range($self->canvas, $z_low - 1e-6, $z_high + 1e-6);
$self->canvas->Refresh if $self->IsShown;
}
sub set_z_idx_low
{
my ($self, $idx_low) = @_;
if ($self->enabled) {
my $idx_high = $self->slider_high->GetValue;
if ($idx_low >= $idx_high) {
$idx_high = $idx_low;
$self->slider_high->SetValue($idx_high);
}
$self->set_z_range($self->{layers_z}[$idx_low], $self->{layers_z}[$idx_high]);
}
}
sub set_z_idx_high
{
my ($self, $idx_high) = @_;
if ($self->enabled) {
my $idx_low = $self->slider_low->GetValue;
if ($idx_low > $idx_high) {
$idx_low = $idx_high;
$self->slider_low->SetValue($idx_low);
}
$self->set_z_range($self->{layers_z}[$idx_low], $self->{layers_z}[$idx_high]);
}
}
sub set_number_extruders {
my ($self, $number_extruders) = @_;
if ($self->{number_extruders} != $number_extruders) {
$self->{number_extruders} = $number_extruders;
my $type = ($number_extruders > 1) ?
$self->{tool_idx} # color by a tool number
: 0; # color by a feature type
$self->{choice_view_type}->SetSelection($type);
$self->gcode_preview_data->set_type($type);
$self->{preferred_color_mode} = ($type == $self->{tool_idx}) ? 'tool_or_feature' : 'feature';
}
}
sub show_hide_ui_elements {
my ($self, $what) = @_;
my $method = ($what eq 'full') ? 'Enable' : 'Disable';
$self->{$_}->$method for qw(label_show_features combochecklist_features checkbox_travel checkbox_retractions checkbox_unretractions checkbox_shells);
$method = ($what eq 'none') ? 'Disable' : 'Enable';
$self->{$_}->$method for qw(label_view_type choice_view_type);
}
# Called by the Platter wxNotebook when this page is activated.
sub OnActivate {
# my ($self) = @_;
# $self->reload_print(1) if ($self->{reload_delayed});
}
1;

View File

@@ -0,0 +1,221 @@
# Generate an anonymous or "lambda" 3D object. This gets used with the Add Generic option in Settings.
#
package Slic3r::GUI::Plater::LambdaObjectDialog;
use strict;
use warnings;
use utf8;
use Wx qw(wxTheApp :dialog :id :misc :sizer wxTAB_TRAVERSAL wxCB_READONLY wxTE_PROCESS_TAB);
use Wx::Event qw(EVT_CLOSE EVT_BUTTON EVT_COMBOBOX EVT_TEXT);
use Scalar::Util qw(looks_like_number);
use base 'Wx::Dialog';
sub new {
my $class = shift;
my ($parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, "Lambda Object", wxDefaultPosition, [500,500], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
# Note whether the window was already closed, so a pending update is not executed.
$self->{already_closed} = 0;
$self->{object_parameters} = {
type => "box",
dim => [1, 1, 1],
cyl_r => 1,
cyl_h => 1,
sph_rho => 1.0,
slab_h => 1.0,
slab_z => 0.0,
};
$self->{sizer} = Wx::BoxSizer->new(wxVERTICAL);
my $button_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
my $button_ok = $self->CreateStdDialogButtonSizer(wxOK);
my $button_cancel = $self->CreateStdDialogButtonSizer(wxCANCEL);
$button_sizer->Add($button_ok);
$button_sizer->Add($button_cancel);
EVT_BUTTON($self, wxID_OK, sub {
# validate user input
return if !$self->CanClose;
$self->EndModal(wxID_OK);
$self->Destroy;
});
EVT_BUTTON($self, wxID_CANCEL, sub {
# validate user input
return if !$self->CanClose;
$self->EndModal(wxID_CANCEL);
$self->Destroy;
});
my $optgroup_box;
$optgroup_box = $self->{optgroup_box} = Slic3r::GUI::OptionsGroup->new(
parent => $self,
title => 'Add Cube...',
on_change => sub {
# Do validation
my ($opt_id) = @_;
if ($opt_id == 0 || $opt_id == 1 || $opt_id == 2) {
if (!looks_like_number($optgroup_box->get_value($opt_id))) {
return 0;
}
}
$self->{object_parameters}->{dim}[$opt_id] = $optgroup_box->get_value($opt_id);
},
label_width => 100,
);
my @options = ("box", "slab", "cylinder", "sphere");
$self->{type} = Wx::ComboBox->new($self, 1, "box", wxDefaultPosition, wxDefaultSize, \@options, wxCB_READONLY);
$optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 0,
label => 'L',
type => 'f',
default => '1',
));
$optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 1,
label => 'W',
type => 'f',
default => '1',
));
$optgroup_box->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 2,
label => 'H',
type => 'f',
default => '1',
));
my $optgroup_cylinder;
$optgroup_cylinder = $self->{optgroup_cylinder} = Slic3r::GUI::OptionsGroup->new(
parent => $self,
title => 'Add Cylinder...',
on_change => sub {
# Do validation
my ($opt_id) = @_;
if ($opt_id eq 'cyl_r' || $opt_id eq 'cyl_h') {
if (!looks_like_number($optgroup_cylinder->get_value($opt_id))) {
return 0;
}
}
$self->{object_parameters}->{$opt_id} = $optgroup_cylinder->get_value($opt_id);
},
label_width => 100,
);
$optgroup_cylinder->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "cyl_r",
label => 'Radius',
type => 'f',
default => '1',
));
$optgroup_cylinder->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "cyl_h",
label => 'Height',
type => 'f',
default => '1',
));
my $optgroup_sphere;
$optgroup_sphere = $self->{optgroup_sphere} = Slic3r::GUI::OptionsGroup->new(
parent => $self,
title => 'Add Sphere...',
on_change => sub {
# Do validation
my ($opt_id) = @_;
if ($opt_id eq 'sph_rho') {
if (!looks_like_number($optgroup_sphere->get_value($opt_id))) {
return 0;
}
}
$self->{object_parameters}->{$opt_id} = $optgroup_sphere->get_value($opt_id);
},
label_width => 100,
);
$optgroup_sphere->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "sph_rho",
label => 'Rho',
type => 'f',
default => '1',
));
my $optgroup_slab;
$optgroup_slab = $self->{optgroup_slab} = Slic3r::GUI::OptionsGroup->new(
parent => $self,
title => 'Add Slab...',
on_change => sub {
# Do validation
my ($opt_id) = @_;
if ($opt_id eq 'slab_z' || $opt_id eq 'slab_h') {
if (!looks_like_number($optgroup_slab->get_value($opt_id))) {
return 0;
}
}
$self->{object_parameters}->{$opt_id} = $optgroup_slab->get_value($opt_id);
},
label_width => 100,
);
$optgroup_slab->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "slab_h",
label => 'H',
type => 'f',
default => '1',
));
$optgroup_slab->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => "slab_z",
label => 'Initial Z',
type => 'f',
default => '0',
));
EVT_COMBOBOX($self, 1, sub{
$self->{object_parameters}->{type} = $self->{type}->GetValue();
$self->_update_ui;
});
$self->{sizer}->Add($self->{type}, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($optgroup_box->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($optgroup_cylinder->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($optgroup_sphere->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($optgroup_slab->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->{sizer}->Add($button_sizer,0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->_update_ui;
$self->SetSizer($self->{sizer});
$self->{sizer}->Fit($self);
$self->{sizer}->SetSizeHints($self);
return $self;
}
sub CanClose {
return 1;
}
sub ObjectParameter {
my ($self) = @_;
return $self->{object_parameters};
}
sub _update_ui {
my ($self) = @_;
$self->{sizer}->Hide($self->{optgroup_cylinder}->sizer);
$self->{sizer}->Hide($self->{optgroup_slab}->sizer);
$self->{sizer}->Hide($self->{optgroup_box}->sizer);
$self->{sizer}->Hide($self->{optgroup_sphere}->sizer);
if ($self->{type}->GetValue eq "box") {
$self->{sizer}->Show($self->{optgroup_box}->sizer);
} elsif ($self->{type}->GetValue eq "cylinder") {
$self->{sizer}->Show($self->{optgroup_cylinder}->sizer);
} elsif ($self->{type}->GetValue eq "slab") {
$self->{sizer}->Show($self->{optgroup_slab}->sizer);
} elsif ($self->{type}->GetValue eq "sphere") {
$self->{sizer}->Show($self->{optgroup_sphere}->sizer);
}
$self->{sizer}->Fit($self);
$self->{sizer}->SetSizeHints($self);
}
1;

View File

@@ -1,20 +1,27 @@
# Cut an object at a Z position, keep either the top or the bottom of the object.
# This dialog gets opened with the "Cut..." button above the platter.
package Slic3r::GUI::Plater::ObjectCutDialog;
use strict;
use warnings;
use utf8;
use Slic3r::Geometry qw(PI X);
use Wx qw(:dialog :id :misc :sizer wxTAB_TRAVERSAL);
use Wx qw(wxTheApp :dialog :id :misc :sizer wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_CLOSE EVT_BUTTON);
use List::Util qw(max);
use base 'Wx::Dialog';
sub new {
my $class = shift;
my ($parent, %params) = @_;
my ($class, $parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, $params{object}->name, wxDefaultPosition, [500,500], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
$self->{model_object_idx} = $params{model_object_idx};
$self->{model_object} = $params{model_object};
$self->{new_model_objects} = [];
# Mark whether the mesh cut is valid.
# If not, it needs to be recalculated by _update() on wxTheApp->CallAfter() or on exit of the dialog.
$self->{mesh_cut_valid} = 0;
# Note whether the window was already closed, so a pending update is not executed.
$self->{already_closed} = 0;
# cut options
$self->{cut_options} = {
@@ -22,6 +29,9 @@ sub new {
keep_upper => 1,
keep_lower => 1,
rotate_lower => 1,
# preview => 1,
# Disabled live preview by default as it is not stable and/or the calculation takes too long for interactive usage.
preview => 0,
};
my $optgroup;
@@ -30,9 +40,18 @@ sub new {
title => 'Cut',
on_change => sub {
my ($opt_id) = @_;
$self->{cut_options}{$opt_id} = $optgroup->get_value($opt_id);
$self->_update;
# There seems to be an issue with wxWidgets 3.0.2/3.0.3, where the slider
# genates tens of events for a single value change.
# Only trigger the recalculation if the value changes
# or a live preview was activated and the mesh cut is not valid yet.
if ($self->{cut_options}{$opt_id} != $optgroup->get_value($opt_id) ||
! $self->{mesh_cut_valid} && $self->_life_preview_active()) {
$self->{cut_options}{$opt_id} = $optgroup->get_value($opt_id);
$self->{mesh_cut_valid} = 0;
wxTheApp->CallAfter(sub {
$self->_update;
});
}
},
label_width => 120,
);
@@ -70,6 +89,13 @@ sub new {
tooltip => 'If enabled, the lower part will be rotated by 180° so that the flat cut surface lies on the print bed.',
default => $self->{cut_options}{rotate_lower},
));
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'preview',
label => 'Show preview',
type => 'bool',
tooltip => 'If enabled, object will be cut in real time.',
default => $self->{cut_options}{preview},
));
{
my $cut_button_sizer = Wx::BoxSizer->new(wxVERTICAL);
$self->{btn_cut} = Wx::Button->new($self, -1, "Perform cut", wxDefaultPosition, wxDefaultSize);
@@ -86,12 +112,14 @@ sub new {
# right pane with preview canvas
my $canvas;
if ($Slic3r::GUI::have_OpenGL) {
$canvas = $self->{canvas} = Slic3r::GUI::PreviewCanvas->new($self);
$canvas->load_object($self->{model_object});
$canvas->set_bounding_box($self->{model_object}->bounding_box);
$canvas->set_auto_bed_shape;
$canvas = $self->{canvas} = Slic3r::GUI::3DScene->new($self);
Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $self->{model_object}, 0, [0]);
Slic3r::GUI::_3DScene::set_auto_bed_shape($canvas);
Slic3r::GUI::_3DScene::set_axes_length($canvas, 2.0 * max(@{ Slic3r::GUI::_3DScene::get_volumes_bounding_box($canvas)->size }));
$canvas->SetSize([500,500]);
$canvas->SetMinSize($canvas->GetSize);
Slic3r::GUI::_3DScene::set_config($canvas, $self->GetParent->{config});
Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($canvas, 1);
}
$self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
@@ -102,72 +130,155 @@ sub new {
$self->SetMinSize($self->GetSize);
$self->{sizer}->SetSizeHints($self);
# needed to actually free memory
EVT_CLOSE($self, sub {
EVT_BUTTON($self, $self->{btn_cut}, sub {
# Recalculate the cut if the preview was not active.
$self->_perform_cut() unless $self->{mesh_cut_valid};
# Adjust position / orientation of the split object halves.
if ($self->{new_model_objects}{lower}) {
if ($self->{cut_options}{rotate_lower}) {
$self->{new_model_objects}{lower}->rotate(PI, X);
$self->{new_model_objects}{lower}->center_around_origin; # align to Z = 0
}
}
if ($self->{new_model_objects}{upper}) {
$self->{new_model_objects}{upper}->center_around_origin; # align to Z = 0
}
# Note that the window was already closed, so a pending update will not be executed.
$self->{already_closed} = 1;
$self->EndModal(wxID_OK);
$self->Destroy;
$self->{canvas}->Destroy;
$self->Destroy();
});
EVT_BUTTON($self, $self->{btn_cut}, sub { $self->perform_cut });
EVT_CLOSE($self, sub {
# Note that the window was already closed, so a pending update will not be executed.
$self->{already_closed} = 1;
$self->EndModal(wxID_CANCEL);
$self->{canvas}->Destroy;
$self->Destroy();
});
$self->_update;
return $self;
}
sub _update {
# scale Z down to original size since we're using the transformed mesh for 3D preview
# and cut dialog but ModelObject::cut() needs Z without any instance transformation
sub _mesh_slice_z_pos
{
my ($self) = @_;
my $optgroup = $self->{optgroup};
# update canvas
if ($self->{canvas}) {
$self->{canvas}->SetCuttingPlane($self->{cut_options}{z});
$self->{canvas}->Render;
}
# update controls
my $z = $self->{cut_options}{z};
$optgroup->get_field('keep_upper')->toggle(my $have_upper = abs($z - $optgroup->get_option('z')->max) > 0.1);
$optgroup->get_field('keep_lower')->toggle(my $have_lower = $z > 0.1);
$optgroup->get_field('rotate_lower')->toggle($z > 0 && $self->{cut_options}{keep_lower});
# update cut button
if (($self->{cut_options}{keep_upper} && $have_upper)
|| ($self->{cut_options}{keep_lower} && $have_lower)) {
$self->{btn_cut}->Enable;
} else {
$self->{btn_cut}->Disable;
}
return $self->{cut_options}{z} / $self->{model_object}->instances->[0]->scaling_factor;
}
sub perform_cut {
# Only perform live preview if just a single part of the object shall survive.
sub _life_preview_active
{
my ($self) = @_;
# scale Z down to original size since we're using the transformed mesh for 3D preview
# and cut dialog but ModelObject::cut() needs Z without any instance transformation
my $z = $self->{cut_options}{z} / $self->{model_object}->instances->[0]->scaling_factor;
return $self->{cut_options}{preview} && ($self->{cut_options}{keep_upper} != $self->{cut_options}{keep_lower});
}
# Slice the mesh, keep the top / bottom part.
sub _perform_cut
{
my ($self) = @_;
# Early exit. If the cut is valid, don't recalculate it.
return if $self->{mesh_cut_valid};
my $z = $self->_mesh_slice_z_pos();
my ($new_model) = $self->{model_object}->cut($z);
my ($upper_object, $lower_object) = @{$new_model->objects};
$self->{new_model} = $new_model;
$self->{new_model_objects} = [];
$self->{new_model_objects} = {};
if ($self->{cut_options}{keep_upper} && $upper_object->volumes_count > 0) {
push @{$self->{new_model_objects}}, $upper_object;
$self->{new_model_objects}{upper} = $upper_object;
}
if ($self->{cut_options}{keep_lower} && $lower_object->volumes_count > 0) {
push @{$self->{new_model_objects}}, $lower_object;
if ($self->{cut_options}{rotate_lower}) {
$lower_object->rotate(PI, X);
$self->{new_model_objects}{lower} = $lower_object;
}
$self->{mesh_cut_valid} = 1;
}
sub _update {
my ($self) = @_;
# Don't update if the window was already closed.
# We are not sure whether the action planned by wxTheApp->CallAfter() may be triggered after the window is closed.
# Probably not, but better be safe than sorry, which is espetially true on multiple platforms.
return if $self->{already_closed};
# Only recalculate the cut, if the live cut preview is active.
my $life_preview_active = $self->_life_preview_active();
$self->_perform_cut() if $life_preview_active;
{
# scale Z down to original size since we're using the transformed mesh for 3D preview
# and cut dialog but ModelObject::cut() needs Z without any instance transformation
my $z = $self->_mesh_slice_z_pos();
# update canvas
if ($self->{canvas}) {
# get volumes to render
my @objects = ();
if ($life_preview_active) {
push @objects, values %{$self->{new_model_objects}};
} else {
push @objects, $self->{model_object};
}
my $z_cut = $z + $self->{model_object}->bounding_box->z_min;
# get section contour
my @expolygons = ();
foreach my $volume (@{$self->{model_object}->volumes}) {
next if !$volume->mesh;
next if $volume->modifier;
my $expp = $volume->mesh->slice([ $z_cut ])->[0];
push @expolygons, @$expp;
}
foreach my $expolygon (@expolygons) {
$self->{model_object}->instances->[0]->transform_polygon($_)
for @$expolygon;
$expolygon->translate(map Slic3r::Geometry::scale($_), @{ $self->{model_object}->instances->[0]->offset });
}
Slic3r::GUI::_3DScene::reset_volumes($self->{canvas});
Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $_, 0, [0]) for @objects;
Slic3r::GUI::_3DScene::set_cutting_plane($self->{canvas}, $self->{cut_options}{z}, [@expolygons]);
Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas});
Slic3r::GUI::_3DScene::render($self->{canvas});
}
}
$self->Close;
# update controls
{
my $z = $self->{cut_options}{z};
my $optgroup = $self->{optgroup};
$optgroup->get_field('keep_upper')->toggle(my $have_upper = abs($z - $optgroup->get_option('z')->max) > 0.1);
$optgroup->get_field('keep_lower')->toggle(my $have_lower = $z > 0.1);
$optgroup->get_field('rotate_lower')->toggle($z > 0 && $self->{cut_options}{keep_lower});
# Disabled live preview by default as it is not stable and/or the calculation takes too long for interactive usage.
# $optgroup->get_field('preview')->toggle($self->{cut_options}{keep_upper} != $self->{cut_options}{keep_lower});
# update cut button
if (($self->{cut_options}{keep_upper} && $have_upper)
|| ($self->{cut_options}{keep_lower} && $have_lower)) {
$self->{btn_cut}->Enable;
} else {
$self->{btn_cut}->Disable;
}
}
}
sub NewModelObjects {
my ($self) = @_;
return @{ $self->{new_model_objects} };
return values %{ $self->{new_model_objects} };
}
1;

View File

@@ -1,12 +1,16 @@
# Configuration of mesh modifiers and their parameters.
# This panel is inserted into ObjectSettingsDialog.
package Slic3r::GUI::Plater::ObjectPartsPanel;
use strict;
use warnings;
use utf8;
use File::Basename qw(basename);
use Wx qw(:misc :sizer :treectrl :button wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG
use Wx qw(:misc :sizer :treectrl :button :keycode wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL wxMOD_CONTROL
wxTheApp);
use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED);
use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED EVT_TREE_KEY_DOWN EVT_KEY_DOWN);
use List::Util qw(max);
use base 'Wx::Panel';
use constant ICON_OBJECT => 0;
@@ -14,22 +18,34 @@ use constant ICON_SOLIDMESH => 1;
use constant ICON_MODIFIERMESH => 2;
sub new {
my $class = shift;
my ($parent, %params) = @_;
my ($class, $parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
# C++ type Slic3r::ModelObject
my $object = $self->{model_object} = $params{model_object};
# Save state for sliders.
$self->{move_options} = {
x => 0,
y => 0,
z => 0,
};
$self->{last_coords} = {
x => 0,
y => 0,
z => 0,
};
# create TreeCtrl
my $tree = $self->{tree} = Wx::TreeCtrl->new($self, -1, wxDefaultPosition, [300, 100],
wxTR_NO_BUTTONS | wxSUNKEN_BORDER | wxTR_HAS_VARIABLE_ROW_HEIGHT
| wxTR_SINGLE | wxTR_NO_BUTTONS);
| wxTR_SINGLE);
{
$self->{tree_icons} = Wx::ImageList->new(16, 16, 1);
$tree->AssignImageList($self->{tree_icons});
$self->{tree_icons}->Add(Wx::Bitmap->new("$Slic3r::var/brick.png", wxBITMAP_TYPE_PNG)); # ICON_OBJECT
$self->{tree_icons}->Add(Wx::Bitmap->new("$Slic3r::var/package.png", wxBITMAP_TYPE_PNG)); # ICON_SOLIDMESH
$self->{tree_icons}->Add(Wx::Bitmap->new("$Slic3r::var/plugin.png", wxBITMAP_TYPE_PNG)); # ICON_MODIFIERMESH
$self->{tree_icons}->Add(Wx::Bitmap->new(Slic3r::var("brick.png"), wxBITMAP_TYPE_PNG)); # ICON_OBJECT
$self->{tree_icons}->Add(Wx::Bitmap->new(Slic3r::var("package.png"), wxBITMAP_TYPE_PNG)); # ICON_SOLIDMESH
$self->{tree_icons}->Add(Wx::Bitmap->new(Slic3r::var("plugin.png"), wxBITMAP_TYPE_PNG)); # ICON_MODIFIERMESH
my $rootId = $tree->AddRoot("Object", ICON_OBJECT);
$tree->SetPlData($rootId, { type => 'object' });
@@ -38,41 +54,116 @@ sub new {
# buttons
$self->{btn_load_part} = Wx::Button->new($self, -1, "Load part…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_load_modifier} = Wx::Button->new($self, -1, "Load modifier…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_load_lambda_modifier} = Wx::Button->new($self, -1, "Load generic…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_delete} = Wx::Button->new($self, -1, "Delete part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
if ($Slic3r::GUI::have_button_icons) {
$self->{btn_load_part}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/brick_add.png", wxBITMAP_TYPE_PNG));
$self->{btn_load_modifier}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/brick_add.png", wxBITMAP_TYPE_PNG));
$self->{btn_delete}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/brick_delete.png", wxBITMAP_TYPE_PNG));
}
$self->{btn_split} = Wx::Button->new($self, -1, "Split part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
$self->{btn_move_up} = Wx::Button->new($self, -1, "", wxDefaultPosition, [40, -1], wxBU_LEFT);
$self->{btn_move_down} = Wx::Button->new($self, -1, "", wxDefaultPosition, [40, -1], wxBU_LEFT);
$self->{btn_load_part}->SetBitmap(Wx::Bitmap->new(Slic3r::var("brick_add.png"), wxBITMAP_TYPE_PNG));
$self->{btn_load_modifier}->SetBitmap(Wx::Bitmap->new(Slic3r::var("brick_add.png"), wxBITMAP_TYPE_PNG));
$self->{btn_load_lambda_modifier}->SetBitmap(Wx::Bitmap->new(Slic3r::var("brick_add.png"), wxBITMAP_TYPE_PNG));
$self->{btn_delete}->SetBitmap(Wx::Bitmap->new(Slic3r::var("brick_delete.png"), wxBITMAP_TYPE_PNG));
$self->{btn_split}->SetBitmap(Wx::Bitmap->new(Slic3r::var("shape_ungroup.png"), wxBITMAP_TYPE_PNG));
$self->{btn_move_up}->SetBitmap(Wx::Bitmap->new(Slic3r::var("bullet_arrow_up.png"), wxBITMAP_TYPE_PNG));
$self->{btn_move_down}->SetBitmap(Wx::Bitmap->new(Slic3r::var("bullet_arrow_down.png"), wxBITMAP_TYPE_PNG));
# buttons sizer
my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$buttons_sizer->Add($self->{btn_load_part}, 0);
$buttons_sizer->Add($self->{btn_load_modifier}, 0);
$buttons_sizer->Add($self->{btn_delete}, 0);
my $buttons_sizer = Wx::GridSizer->new(2, 3);
$buttons_sizer->Add($self->{btn_load_part}, 0, wxEXPAND | wxBOTTOM | wxRIGHT, 5);
$buttons_sizer->Add($self->{btn_load_modifier}, 0, wxEXPAND | wxBOTTOM | wxRIGHT, 5);
$buttons_sizer->Add($self->{btn_load_lambda_modifier}, 0, wxEXPAND | wxBOTTOM, 5);
$buttons_sizer->Add($self->{btn_delete}, 0, wxEXPAND | wxRIGHT, 5);
$buttons_sizer->Add($self->{btn_split}, 0, wxEXPAND | wxRIGHT, 5);
{
my $up_down_sizer = Wx::GridSizer->new(1, 2);
$up_down_sizer->Add($self->{btn_move_up}, 0, wxEXPAND | wxRIGHT, 5);
$up_down_sizer->Add($self->{btn_move_down}, 0, wxEXPAND, 5);
$buttons_sizer->Add($up_down_sizer, 0, wxEXPAND, 5);
}
$self->{btn_load_part}->SetFont($Slic3r::GUI::small_font);
$self->{btn_load_modifier}->SetFont($Slic3r::GUI::small_font);
$self->{btn_load_lambda_modifier}->SetFont($Slic3r::GUI::small_font);
$self->{btn_delete}->SetFont($Slic3r::GUI::small_font);
$self->{btn_split}->SetFont($Slic3r::GUI::small_font);
$self->{btn_move_up}->SetFont($Slic3r::GUI::small_font);
$self->{btn_move_down}->SetFont($Slic3r::GUI::small_font);
# part settings panel
$self->{settings_panel} = Slic3r::GUI::Plater::OverrideSettingsPanel->new($self, on_change => sub { $self->{part_settings_changed} = 1; });
$self->{settings_panel} = Slic3r::GUI::Plater::OverrideSettingsPanel->new($self, on_change => sub { $self->{part_settings_changed} = 1; $self->_update_canvas; });
my $settings_sizer = Wx::StaticBoxSizer->new($self->{staticbox} = Wx::StaticBox->new($self, -1, "Part Settings"), wxVERTICAL);
$settings_sizer->Add($self->{settings_panel}, 1, wxEXPAND | wxALL, 0);
my $optgroup_movers;
$optgroup_movers = $self->{optgroup_movers} = Slic3r::GUI::OptionsGroup->new(
parent => $self,
title => 'Move',
on_change => sub {
my ($opt_id) = @_;
# There seems to be an issue with wxWidgets 3.0.2/3.0.3, where the slider
# genates tens of events for a single value change.
# Only trigger the recalculation if the value changes
# or a live preview was activated and the mesh cut is not valid yet.
if ($self->{move_options}{$opt_id} != $optgroup_movers->get_value($opt_id)) {
$self->{move_options}{$opt_id} = $optgroup_movers->get_value($opt_id);
wxTheApp->CallAfter(sub {
$self->_update;
});
}
},
label_width => 20,
);
$optgroup_movers->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'x',
type => 'slider',
label => 'X',
default => 0,
min => -($self->{model_object}->bounding_box->size->x)*4,
max => $self->{model_object}->bounding_box->size->x*4,
full_width => 1,
));
$optgroup_movers->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'y',
type => 'slider',
label => 'Y',
default => 0,
min => -($self->{model_object}->bounding_box->size->y)*4,
max => $self->{model_object}->bounding_box->size->y*4,
full_width => 1,
));
$optgroup_movers->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'z',
type => 'slider',
label => 'Z',
default => 0,
min => -($self->{model_object}->bounding_box->size->z)*4,
max => $self->{model_object}->bounding_box->size->z*4,
full_width => 1,
));
# left pane with tree
my $left_sizer = Wx::BoxSizer->new(wxVERTICAL);
$left_sizer->Add($tree, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
$left_sizer->Add($tree, 3, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
$left_sizer->Add($buttons_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
$left_sizer->Add($settings_sizer, 1, wxEXPAND | wxALL, 0);
$left_sizer->Add($settings_sizer, 5, wxEXPAND | wxALL, 0);
$left_sizer->Add($optgroup_movers->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
# right pane with preview canvas
my $canvas;
if ($Slic3r::GUI::have_OpenGL) {
$canvas = $self->{canvas} = Slic3r::GUI::PreviewCanvas->new($self);
$canvas->load_object($self->{model_object});
$canvas->set_bounding_box($self->{model_object}->bounding_box);
$canvas->set_auto_bed_shape;
$canvas->SetSize([500,500]);
$canvas = $self->{canvas} = Slic3r::GUI::3DScene->new($self);
Slic3r::GUI::_3DScene::enable_picking($canvas, 1);
Slic3r::GUI::_3DScene::set_select_by($canvas, 'volume');
Slic3r::GUI::_3DScene::register_on_select_object_callback($canvas, sub {
my ($volume_idx) = @_;
$self->reload_tree($volume_idx);
});
Slic3r::GUI::_3DScene::load_model_object($canvas, $self->{model_object}, 0, [0]);
Slic3r::GUI::_3DScene::set_auto_bed_shape($canvas);
Slic3r::GUI::_3DScene::set_axes_length($canvas, 2.0 * max(@{ Slic3r::GUI::_3DScene::get_volumes_bounding_box($canvas)->size }));
$canvas->SetSize([500,700]);
Slic3r::GUI::_3DScene::set_config($canvas, $self->GetParent->GetParent->GetParent->{config});
Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($canvas);
Slic3r::GUI::_3DScene::enable_force_zoom_to_bed($canvas, 1);
}
$self->{sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
@@ -89,11 +180,25 @@ sub new {
});
EVT_TREE_SEL_CHANGED($self, $tree, sub {
my ($self, $event) = @_;
return if $self->{disable_tree_sel_changed_event};
$self->selection_changed;
});
EVT_TREE_KEY_DOWN($self, $tree, \&on_tree_key_down);
EVT_BUTTON($self, $self->{btn_load_part}, sub { $self->on_btn_load(0) });
EVT_BUTTON($self, $self->{btn_load_modifier}, sub { $self->on_btn_load(1) });
EVT_BUTTON($self, $self->{btn_load_lambda_modifier}, sub { $self->on_btn_lambda(1) });
EVT_BUTTON($self, $self->{btn_delete}, \&on_btn_delete);
EVT_BUTTON($self, $self->{btn_split}, \&on_btn_split);
EVT_BUTTON($self, $self->{btn_move_up}, \&on_btn_move_up);
EVT_BUTTON($self, $self->{btn_move_down}, \&on_btn_move_down);
EVT_KEY_DOWN($canvas, sub {
my ($canvas, $event) = @_;
if ($event->GetKeyCode == WXK_DELETE) {
$canvas->GetParent->on_btn_delete;
} else {
$event->Skip;
}
});
$self->reload_tree;
@@ -101,20 +206,31 @@ sub new {
}
sub reload_tree {
my ($self) = @_;
my ($self, $selected_volume_idx) = @_;
$selected_volume_idx //= -1;
my $object = $self->{model_object};
my $tree = $self->{tree};
my $rootId = $tree->GetRootItem;
# despite wxWidgets states that DeleteChildren "will not generate any events unlike Delete() method",
# the MSW implementation of DeleteChildren actually calls Delete() for each item, so
# EVT_TREE_SEL_CHANGED is being called, with bad effects (the event handler is called; this
# subroutine is never continued; an invisible EndModal is called on the dialog causing Plater
# to continue its logic and rescheduling the background process etc. GH #2774)
$self->{disable_tree_sel_changed_event} = 1;
$tree->DeleteChildren($rootId);
$self->{disable_tree_sel_changed_event} = 0;
my $itemId;
my $selectedId = $rootId;
foreach my $volume_id (0..$#{$object->volumes}) {
my $volume = $object->volumes->[$volume_id];
my $icon = $volume->modifier ? ICON_MODIFIERMESH : ICON_SOLIDMESH;
$itemId = $tree->AppendItem($rootId, $volume->name || $volume_id, $icon);
my $itemId = $tree->AppendItem($rootId, $volume->name || $volume_id, $icon);
if ($volume_id == $selected_volume_idx) {
$selectedId = $itemId;
}
$tree->SetPlData($itemId, {
type => 'volume',
volume_id => $volume_id,
@@ -122,10 +238,13 @@ sub reload_tree {
}
$tree->ExpandAll;
# select last appended part
# This will trigger the selection_changed() event
Slic3r::GUI->CallAfter(sub {
$self->{tree}->SelectItem($itemId);
$self->{tree}->SelectItem($selectedId);
# SelectItem() should trigger EVT_TREE_SEL_CHANGED as per wxWidgets docs,
# but in fact it doesn't if the given item is already selected (this happens
# on first load)
$self->selection_changed;
});
}
@@ -144,43 +263,65 @@ sub selection_changed {
# deselect all meshes
if ($self->{canvas}) {
$_->{selected} = 0 for @{$self->{canvas}->volumes};
Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas});
}
# disable things as if nothing is selected
$self->{btn_delete}->Disable;
$self->{'btn_' . $_}->Disable for (qw(delete move_up move_down split));
$self->{settings_panel}->disable;
$self->{settings_panel}->set_config(undef);
# reset move sliders
$self->{optgroup_movers}->set_value("x", 0);
$self->{optgroup_movers}->set_value("y", 0);
$self->{optgroup_movers}->set_value("z", 0);
$self->{move_options} = {
x => 0,
y => 0,
z => 0,
};
$self->{last_coords} = {
x => 0,
y => 0,
z => 0,
};
if (my $itemData = $self->get_selection) {
my ($config, @opt_keys);
if ($itemData->{type} eq 'volume') {
# select volume in 3D preview
if ($self->{canvas}) {
$self->{canvas}->volumes->[ $itemData->{volume_id} ]{selected} = 1;
Slic3r::GUI::_3DScene::select_volume($self->{canvas}, $itemData->{volume_id});
}
$self->{btn_delete}->Enable;
$self->{btn_split}->Enable;
$self->{btn_move_up}->Enable if $itemData->{volume_id} > 0;
$self->{btn_move_down}->Enable if $itemData->{volume_id} + 1 < $self->{model_object}->volumes_count;
# attach volume config to settings panel
my $volume = $self->{model_object}->volumes->[ $itemData->{volume_id} ];
if ($volume->modifier) {
$self->{optgroup_movers}->enable;
} else {
$self->{optgroup_movers}->disable;
}
$config = $volume->config;
$self->{staticbox}->SetLabel('Part Settings');
# get default values
@opt_keys = @{Slic3r::Config::PrintRegion->new->get_keys};
} elsif ($itemData->{type} eq 'object') {
# select all object volumes in 3D preview
if ($self->{canvas}) {
$_->{selected} = 1 for @{$self->{canvas}->volumes};
}
# select nothing in 3D preview
# attach object config to settings panel
$self->{optgroup_movers}->disable;
$self->{staticbox}->SetLabel('Object Settings');
@opt_keys = (map @{$_->get_keys}, Slic3r::Config::PrintObject->new, Slic3r::Config::PrintRegion->new);
$config = $self->{model_object}->config;
}
# get default values
my $default_config = Slic3r::Config->new_from_defaults(@opt_keys);
my $default_config = Slic3r::Config::new_from_defaults_keys(\@opt_keys);
# append default extruder
push @opt_keys, 'extruder';
@@ -193,7 +334,7 @@ sub selection_changed {
$self->{settings_panel}->enable;
}
$self->{canvas}->Render if $self->{canvas};
Slic3r::GUI::_3DScene::render($self->{canvas}) if $self->{canvas};
}
sub on_btn_load {
@@ -214,7 +355,7 @@ sub on_btn_load {
$new_volume->set_name(basename($input_file));
# apply the same translation we applied to the object
$new_volume->mesh->translate(@{$self->{model_object}->origin_translation}, 0);
$new_volume->mesh->translate(@{$self->{model_object}->origin_translation});
# set a default extruder value, since user can't add it manually
$new_volume->config->set_ifndef('extruder', 0);
@@ -224,34 +365,134 @@ sub on_btn_load {
}
}
$self->reload_tree;
if ($self->{canvas}) {
$self->{canvas}->load_object($self->{model_object});
$self->{canvas}->Render;
$self->_parts_changed;
}
sub on_btn_lambda {
my ($self, $is_modifier) = @_;
my $dlg = Slic3r::GUI::Plater::LambdaObjectDialog->new($self);
if ($dlg->ShowModal() == wxID_CANCEL) {
return;
}
my $params = $dlg->ObjectParameter;
my $type = "".$params->{"type"};
my $name = "lambda-".$params->{"type"};
my $mesh;
if ($type eq "box") {
$mesh = Slic3r::TriangleMesh::cube($params->{"dim"}[0], $params->{"dim"}[1], $params->{"dim"}[2]);
} elsif ($type eq "cylinder") {
$mesh = Slic3r::TriangleMesh::cylinder($params->{"cyl_r"}, $params->{"cyl_h"});
} elsif ($type eq "sphere") {
$mesh = Slic3r::TriangleMesh::sphere($params->{"sph_rho"});
} elsif ($type eq "slab") {
$mesh = Slic3r::TriangleMesh::cube($self->{model_object}->bounding_box->size->x*1.5, $self->{model_object}->bounding_box->size->y*1.5, $params->{"slab_h"});
# box sets the base coordinate at 0,0, move to center of plate and move it up to initial_z
$mesh->translate(-$self->{model_object}->bounding_box->size->x*1.5/2.0, -$self->{model_object}->bounding_box->size->y*1.5/2.0, $params->{"slab_z"});
} else {
return;
}
$mesh->repair;
my $new_volume = $self->{model_object}->add_volume(mesh => $mesh);
$new_volume->set_modifier($is_modifier);
$new_volume->set_name($name);
# set a default extruder value, since user can't add it manually
$new_volume->config->set_ifndef('extruder', 0);
$self->{parts_changed} = 1;
$self->_parts_changed;
}
sub on_tree_key_down {
my ($self, $event) = @_;
my $keycode = $event->GetKeyCode;
# Wx >= 0.9911
if (defined(&Wx::TreeEvent::GetKeyEvent)) {
if ($event->GetKeyEvent->GetModifiers & wxMOD_CONTROL) {
if ($keycode == WXK_UP) {
$event->Skip;
$self->on_btn_move_up;
} elsif ($keycode == WXK_DOWN) {
$event->Skip;
$self->on_btn_move_down;
}
} elsif ($keycode == WXK_DELETE) {
$self->on_btn_delete;
}
}
}
sub on_btn_move_up {
my ($self) = @_;
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $volume_id = $itemData->{volume_id};
if ($self->{model_object}->move_volume_up($volume_id)) {
Slic3r::GUI::_3DScene::move_volume_up($self->{canvas}, $volume_id);
$self->{parts_changed} = 1;
$self->reload_tree($volume_id - 1);
}
}
}
sub on_btn_move_down {
my ($self) = @_;
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $volume_id = $itemData->{volume_id};
if ($self->{model_object}->move_volume_down($volume_id)) {
Slic3r::GUI::_3DScene::move_volume_down($self->{canvas}, $volume_id);
$self->{parts_changed} = 1;
$self->reload_tree($volume_id + 1);
}
}
}
sub on_btn_delete {
my ($self) = @_;
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
# if user is deleting the last solid part, throw error
if (!$volume->modifier && scalar(grep !$_->modifier, @{$self->{model_object}->volumes}) == 1) {
Slic3r::GUI::show_error($self, "You can't delete the last solid part from this object.");
return;
}
$self->{model_object}->delete_volume($itemData->{volume_id});
$self->{parts_changed} = 1;
}
$self->_parts_changed;
}
sub on_btn_split {
my ($self) = @_;
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
my $nozzle_dmrs = $self->GetParent->GetParent->GetParent->{config}->get('nozzle_diameter');
$self->{parts_changed} = 1 if $volume->split(scalar(@$nozzle_dmrs)) > 1;
}
$self->_parts_changed;
}
sub _parts_changed {
my ($self) = @_;
$self->reload_tree;
if ($self->{canvas}) {
$self->{canvas}->load_object($self->{model_object});
$self->{canvas}->Render;
Slic3r::GUI::_3DScene::reset_volumes($self->{canvas});
Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $self->{model_object}, 0, [0]);
Slic3r::GUI::_3DScene::zoom_to_volumes($self->{canvas});
Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas});
Slic3r::GUI::_3DScene::render($self->{canvas});
}
}
@@ -263,12 +504,17 @@ sub CanClose {
# validate options before allowing user to dismiss the dialog
# the validate method only works on full configs so we have
# to merge our settings with the default ones
my $config = Slic3r::Config->merge($self->GetParent->GetParent->GetParent->GetParent->GetParent->config, $self->model_object->config);
my $config = $self->GetParent->GetParent->GetParent->GetParent->GetParent->config->clone;
eval {
$config->apply($self->model_object->config);
$config->validate;
};
return 0 if Slic3r::GUI::catch_error($self);
return 1;
return ! Slic3r::GUI::catch_error($self);
}
sub Destroy {
my ($self) = @_;
$self->{canvas}->Destroy if ($self->{canvas});
}
sub PartsChanged {
@@ -281,4 +527,47 @@ sub PartSettingsChanged {
return $self->{part_settings_changed};
}
sub _update_canvas {
my ($self) = @_;
if ($self->{canvas}) {
Slic3r::GUI::_3DScene::reset_volumes($self->{canvas});
Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $self->{model_object}, 0, [0]);
# restore selection, if any
if (my $itemData = $self->get_selection) {
if ($itemData->{type} eq 'volume') {
Slic3r::GUI::_3DScene::select_volume($self->{canvas}, $itemData->{volume_id});
}
}
Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas});
Slic3r::GUI::_3DScene::render($self->{canvas});
}
}
sub _update {
my ($self) = @_;
my ($m_x, $m_y, $m_z) = ($self->{move_options}{x}, $self->{move_options}{y}, $self->{move_options}{z});
my ($l_x, $l_y, $l_z) = ($self->{last_coords}{x}, $self->{last_coords}{y}, $self->{last_coords}{z});
my $itemData = $self->get_selection;
if ($itemData && $itemData->{type} eq 'volume') {
my $d = Slic3r::Pointf3->new($m_x - $l_x, $m_y - $l_y, $m_z - $l_z);
my $volume = $self->{model_object}->volumes->[$itemData->{volume_id}];
$volume->mesh->translate(@{$d});
$self->{last_coords}{x} = $m_x;
$self->{last_coords}{y} = $m_y;
$self->{last_coords}{z} = $m_z;
}
$self->{parts_changed} = 1;
my @objects = ();
push @objects, $self->{model_object};
Slic3r::GUI::_3DScene::reset_volumes($self->{canvas});
Slic3r::GUI::_3DScene::load_model_object($self->{canvas}, $_, 0, [0]) for @objects;
Slic3r::GUI::_3DScene::update_volumes_colors_by_extruder($self->{canvas});
Slic3r::GUI::_3DScene::render($self->{canvas});
}
1;

View File

@@ -1,35 +0,0 @@
package Slic3r::GUI::Plater::ObjectPreviewDialog;
use strict;
use warnings;
use utf8;
use Wx qw(:dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_CLOSE);
use base 'Wx::Dialog';
sub new {
my $class = shift;
my ($parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, $params{object}->name, wxDefaultPosition, [500,500], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
$self->{model_object} = $params{model_object};
my $canvas = Slic3r::GUI::PreviewCanvas->new($self);
$canvas->load_object($self->{model_object});
$canvas->set_bounding_box($self->{model_object}->bounding_box);
$canvas->set_auto_bed_shape;
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
$sizer->Add($canvas, 1, wxEXPAND, 0);
$self->SetSizer($sizer);
$self->SetMinSize($self->GetSize);
# needed to actually free memory
EVT_CLOSE($self, sub {
$self->EndModal(wxID_OK);
$self->Destroy;
});
return $self;
}
1;

View File

@@ -1,18 +1,24 @@
# This dialog opens up when double clicked on an object line in the list at the right side of the platter.
# One may load additional STLs and additional modifier STLs,
# one may change the properties of the print per each modifier mesh or a Z-span.
package Slic3r::GUI::Plater::ObjectSettingsDialog;
use strict;
use warnings;
use utf8;
use Wx qw(:dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL);
use Wx qw(:dialog :id :misc :sizer :systemsettings :notebook wxTAB_TRAVERSAL wxTheApp);
use Wx::Event qw(EVT_BUTTON);
use base 'Wx::Dialog';
# Called with
# %params{object} of a Perl type Slic3r::GUI::Plater::Object
# %params{model_object} of a C++ type Slic3r::ModelObject
sub new {
my $class = shift;
my ($parent, %params) = @_;
my ($class, $parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, "Settings for " . $params{object}->name, wxDefaultPosition, [700,500], wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
$self->{$_} = $params{$_} for keys %params;
$self->{tabpanel} = Wx::Notebook->new($self, -1, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL);
$self->{tabpanel}->AddPage($self->{parts} = Slic3r::GUI::Plater::ObjectPartsPanel->new($self->{tabpanel}, model_object => $params{model_object}), "Parts");
$self->{tabpanel}->AddPage($self->{layers} = Slic3r::GUI::Plater::ObjectDialog::LayersTab->new($self->{tabpanel}), "Layers");
@@ -26,7 +32,11 @@ sub new {
# notify tabs
$self->{layers}->Closing;
# save window size
wxTheApp->save_window_pos($self, "object_settings");
$self->EndModal(wxID_OK);
$self->{parts}->Destroy;
$self->Destroy;
});
@@ -37,6 +47,10 @@ sub new {
$self->SetSizer($sizer);
$self->SetMinSize($self->GetSize);
$self->Layout;
wxTheApp->restore_window_pos($self, "object_settings");
return $self;
}
@@ -55,6 +69,7 @@ use base 'Wx::Panel';
sub model_object {
my ($self) = @_;
# $self->GetParent->GetParent is of type Slic3r::GUI::Plater::ObjectSettingsDialog
return $self->GetParent->GetParent->{model_object};
}
@@ -72,7 +87,7 @@ sub new {
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
{
my $label = Wx::StaticText->new($self, -1, "You can use this section to override the default layer height for parts of this object. Set layer height to zero to skip portions of the input file.",
my $label = Wx::StaticText->new($self, -1, "You can use this section to override the default layer height for parts of this object.",
wxDefaultPosition, [-1, 40]);
$label->SetFont(Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
$sizer->Add($label, 0, wxEXPAND | wxALL, 10);
@@ -82,7 +97,7 @@ sub new {
$sizer->Add($grid, 1, wxEXPAND | wxALL, 10);
$grid->CreateGrid(0, 3);
$grid->DisableDragRowSize;
$grid->HideRowLabels if &Wx::wxVERSION_STRING !~ / 2\.8\./;
$grid->HideRowLabels;
$grid->SetColLabelValue(0, "Min Z (mm)");
$grid->SetColLabelValue(1, "Max Z (mm)");
$grid->SetColLabelValue(2, "Layer height (mm)");
@@ -104,15 +119,20 @@ sub new {
my $value = $grid->GetCellValue($event->GetRow, $event->GetCol);
$value =~ s/,/./g;
$value =~ s/[^0-9.]//g;
$grid->SetCellValue($event->GetRow, $event->GetCol, $value);
$grid->SetCellValue($event->GetRow, $event->GetCol, ($event->GetCol == 2) ? $self->_clamp_layer_height($value) : $value);
# if there's no empty row, let's append one
for my $i (0 .. $grid->GetNumberRows-1) {
for my $i (0 .. $grid->GetNumberRows) {
if ($i == $grid->GetNumberRows) {
# if we're here then we found no empty row
$grid->AppendRows(1);
last;
}
if (!grep $grid->GetCellValue($i, $_), 0..2) {
return;
# exit loop if this row is empty
last;
}
}
$grid->AppendRows(1);
$self->{layers_changed} = 1;
});
@@ -123,6 +143,35 @@ sub new {
return $self;
}
sub _clamp_layer_height
{
my ($self, $value) = @_;
# $self->GetParent->GetParent is of type Slic3r::GUI::Plater::ObjectSettingsDialog
my $config = $self->GetParent->GetParent->{config};
if ($value =~ /^[0-9,.E]+$/) {
# Looks like a number. Validate the layer height.
my $nozzle_dmrs = $config->get('nozzle_diameter');
my $min_layer_heights = $config->get('min_layer_height');
my $max_layer_heights = $config->get('max_layer_height');
my $min_layer_height = 1000.;
my $max_layer_height = 0.;
my $max_nozzle_dmr = 0.;
for (my $i = 0; $i < int(@{$nozzle_dmrs}); $i += 1) {
$min_layer_height = $min_layer_heights->[$i] if ($min_layer_heights->[$i] < $min_layer_height);
$max_layer_height = $max_layer_heights->[$i] if ($max_layer_heights->[$i] > $max_layer_height);
$max_nozzle_dmr = $nozzle_dmrs ->[$i] if ($nozzle_dmrs ->[$i] > $max_nozzle_dmr );
}
$min_layer_height = 0.005 if ($min_layer_height < 0.005);
$max_layer_height = $max_nozzle_dmr * 0.75 if ($max_layer_height == 0.);
$max_layer_height = $max_nozzle_dmr if ($max_layer_height > $max_nozzle_dmr);
return ($value < $min_layer_height) ? $min_layer_height :
($value > $max_layer_height) ? $max_layer_height : $value;
} else {
# If an invalid numeric value has been entered, use the default layer height.
return $config->get('layer_height');
}
}
sub CanClose {
my $self = shift;

View File

@@ -1,3 +1,6 @@
# Included in ObjectSettingsDialog -> ObjectPartsPanel.
# Maintains, displays, adds and removes overrides of slicing parameters for an object and its modifier mesh.
package Slic3r::GUI::Plater::OverrideSettingsPanel;
use strict;
use warnings;
@@ -13,12 +16,25 @@ use constant ICON_MATERIAL => 0;
use constant ICON_SOLIDMESH => 1;
use constant ICON_MODIFIERMESH => 2;
my %icons = (
'Advanced' => 'wand.png',
'Extruders' => 'funnel.png',
'Extrusion Width' => 'funnel.png',
'Infill' => 'infill.png',
'Layers and Perimeters' => 'layers.png',
'Skirt and brim' => 'box.png',
'Speed' => 'time.png',
'Speed > Acceleration' => 'time.png',
'Support material' => 'building.png',
);
sub new {
my $class = shift;
my ($parent, %params) = @_;
my ($class, $parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
# C++ class Slic3r::DynamicPrintConfig, initially empty.
$self->{default_config} = Slic3r::Config->new;
$self->{config} = Slic3r::Config->new;
# On change callback.
$self->{on_change} = $params{on_change};
$self->{fixed_options} = {};
@@ -30,18 +46,33 @@ sub new {
# option selector
{
# create the button
my $btn = $self->{btn_add} = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new("$Slic3r::var/add.png", wxBITMAP_TYPE_PNG),
my $btn = $self->{btn_add} = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new(Slic3r::var("add.png"), wxBITMAP_TYPE_PNG),
wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE);
EVT_LEFT_DOWN($btn, sub {
my $menu = Wx::Menu->new;
# create category submenus
my %categories = (); # category => submenu
foreach my $opt_key (@{$self->{options}}) {
my $id = &Wx::NewId();
$menu->Append($id, $self->{option_labels}{$opt_key});
EVT_MENU($menu, $id, sub {
if (my $cat = $Slic3r::Config::Options->{$opt_key}{category}) {
$categories{$cat} //= Wx::Menu->new;
}
}
# append submenus to main menu
my @categories = ('Layers and Perimeters', 'Infill', 'Support material', 'Speed', 'Extruders', 'Extrusion Width', 'Advanced');
#foreach my $cat (sort keys %categories) {
foreach my $cat (@categories) {
wxTheApp->append_submenu($menu, $cat, "", $categories{$cat}, undef, $icons{$cat});
}
# append options to submenus
foreach my $opt_key (@{$self->{options}}) {
my $cat = $Slic3r::Config::Options->{$opt_key}{category} or next;
my $cb = sub {
$self->{config}->set($opt_key, $self->{default_config}->get($opt_key));
$self->update_optgroup;
$self->{on_change}->() if $self->{on_change};
});
$self->{on_change}->($opt_key) if $self->{on_change};
};
wxTheApp->append_menu_item($categories{$cat}, $self->{option_labels}{$opt_key},
$Slic3r::Config::Options->{$opt_key}{tooltip}, $cb);
}
$self->PopupMenu($menu, $btn->GetPosition);
$menu->Destroy;
@@ -74,11 +105,8 @@ sub set_config {
sub set_opt_keys {
my ($self, $opt_keys) = @_;
# sort options by category+label
$self->{option_labels} = {
map { $_ => sprintf('%s > %s', $Slic3r::Config::Options->{$_}{category}, $Slic3r::Config::Options->{$_}{full_label} // $Slic3r::Config::Options->{$_}{label}) } @$opt_keys
};
$self->{option_labels} = { map { $_ => $Slic3r::Config::Options->{$_}{full_label} // $Slic3r::Config::Options->{$_}{label} } @$opt_keys };
$self->{options} = [ sort { $self->{option_labels}{$a} cmp $self->{option_labels}{$b} } @$opt_keys ];
}
@@ -118,7 +146,7 @@ sub update_optgroup {
# disallow deleting fixed options
return undef if $self->{fixed_options}{$opt_key};
my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG),
my $btn = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new(Slic3r::var("delete.png"), wxBITMAP_TYPE_PNG),
wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE);
EVT_BUTTON($self, $btn, sub {
$self->{config}->erase($opt_key);
@@ -133,7 +161,7 @@ sub update_optgroup {
}
$self->{options_sizer}->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM, 0);
}
$self->Layout;
$self->GetParent->Layout; # we need this for showing scrollbars
}
# work around a wxMAC bug causing controls not being disabled when calling Disable() on a Window

View File

@@ -1,88 +0,0 @@
package Slic3r::GUI::Preferences;
use Wx qw(:dialog :id :misc :sizer :systemsettings wxTheApp);
use Wx::Event qw(EVT_BUTTON EVT_TEXT_ENTER);
use base 'Wx::Dialog';
sub new {
my ($class, $parent) = @_;
my $self = $class->SUPER::new($parent, -1, "Preferences", wxDefaultPosition, [500,200]);
$self->{values} = {};
my $optgroup;
$optgroup = Slic3r::GUI::OptionsGroup->new(
parent => $self,
title => 'General',
on_change => sub {
my ($opt_id) = @_;
$self->{values}{$opt_id} = $optgroup->get_value($opt_id);
},
label_width => 100,
);
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'mode',
type => 'select',
label => 'Mode',
tooltip => 'Choose between a simpler, basic mode and an expert mode with more options and more complicated interface.',
labels => ['Simple','Expert'],
values => ['simple','expert'],
default => $Slic3r::GUI::Settings->{_}{mode},
));
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'version_check',
type => 'bool',
label => 'Check for updates',
tooltip => 'If this is enabled, Slic3r will check for updates daily and display a reminder if a newer version is available.',
default => $Slic3r::GUI::Settings->{_}{version_check} // 1,
readonly => !wxTheApp->have_version_check,
));
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'remember_output_path',
type => 'bool',
label => 'Remember output directory',
tooltip => 'If this is enabled, Slic3r will prompt the last output directory instead of the one containing the input files.',
default => $Slic3r::GUI::Settings->{_}{remember_output_path},
));
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'autocenter',
type => 'bool',
label => 'Auto-center parts',
tooltip => 'If this is enabled, Slic3r will auto-center objects around the print bed center.',
default => $Slic3r::GUI::Settings->{_}{autocenter},
));
$optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
opt_id => 'background_processing',
type => 'bool',
label => 'Background processing',
tooltip => 'If this is enabled, Slic3r will pre-process objects as soon as they\'re loaded in order to save time when exporting G-code.',
default => $Slic3r::GUI::Settings->{_}{background_processing},
readonly => !$Slic3r::have_threads,
));
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
$sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
my $buttons = $self->CreateStdDialogButtonSizer(wxOK | wxCANCEL);
EVT_BUTTON($self, wxID_OK, sub { $self->_accept });
$sizer->Add($buttons, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
$self->SetSizer($sizer);
$sizer->SetSizeHints($self);
return $self;
}
sub _accept {
my $self = shift;
if ($self->{values}{mode}) {
Slic3r::GUI::warning_catcher($self)->("You need to restart Slic3r to make the changes effective.");
}
$Slic3r::GUI::Settings->{_}{$_} = $self->{values}{$_} for keys %{$self->{values}};
wxTheApp->save_settings;
$self->EndModal(wxID_OK);
$self->Close; # needed on Linux
}
1;

View File

@@ -1,642 +0,0 @@
package Slic3r::GUI::PreviewCanvas;
use strict;
use warnings;
use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS);
# must load OpenGL *before* Wx::GLCanvas
use OpenGL qw(:glconstants :glfunctions :glufunctions);
use base qw(Wx::GLCanvas Class::Accessor);
use Math::Trig qw(asin);
use List::Util qw(reduce min max first);
use Slic3r::Geometry qw(X Y Z MIN MAX triangle_normal normalize deg2rad tan scale unscale);
use Slic3r::Geometry::Clipper qw(offset_ex intersection_pl);
use Wx::GLCanvas qw(:all);
__PACKAGE__->mk_accessors( qw(quat dirty init mview_init
object_bounding_box
volumes initpos
sphi stheta
cutting_plane_z
cut_lines_vertices
bed_triangles
bed_grid_lines
origin
) );
use constant TRACKBALLSIZE => 0.8;
use constant TURNTABLE_MODE => 1;
use constant GROUND_Z => 0.02;
use constant SELECTED_COLOR => [0,1,0,1];
use constant COLORS => [ [1,1,0], [1,0.5,0.5], [0.5,1,0.5], [0.5,0.5,1] ];
# make OpenGL::Array thread-safe
{
no warnings 'redefine';
*OpenGL::Array::CLONE_SKIP = sub { 1 };
}
sub new {
my ($class, $parent) = @_;
my $self = $class->SUPER::new($parent);
$self->quat((0, 0, 0, 1));
$self->sphi(45);
$self->stheta(-45);
$self->reset_objects;
EVT_PAINT($self, sub {
my $dc = Wx::PaintDC->new($self);
return if !$self->object_bounding_box;
$self->Render($dc);
});
EVT_SIZE($self, sub { $self->dirty(1) });
EVT_IDLE($self, sub {
return unless $self->dirty;
return if !$self->IsShownOnScreen;
return if !$self->object_bounding_box;
$self->Resize( $self->GetSizeWH );
$self->Refresh;
});
EVT_MOUSEWHEEL($self, sub {
my ($self, $e) = @_;
my $zoom = ($e->GetWheelRotation() / $e->GetWheelDelta() / 10);
$zoom = $zoom > 0 ? (1.0 + $zoom) : 1 / (1.0 - $zoom);
my @pos3d = $self->mouse_to_3d($e->GetX(), $e->GetY());
$self->ZoomTo($zoom, $pos3d[0], $pos3d[1]);
$self->Refresh;
});
EVT_MOUSE_EVENTS($self, sub {
my ($self, $e) = @_;
if ($e->Dragging() && $e->LeftIsDown()) {
$self->handle_rotation($e);
} elsif ($e->Dragging() && $e->RightIsDown()) {
$self->handle_translation($e);
} elsif ($e->LeftUp() || $e->RightUp()) {
$self->initpos(undef);
} else {
$e->Skip();
}
});
return $self;
}
sub reset_objects {
my ($self) = @_;
$self->volumes([]);
$self->dirty(1);
}
# this method accepts a Slic3r::BoudingBox3f object
sub set_bounding_box {
my ($self, $bb) = @_;
$self->object_bounding_box($bb);
$self->dirty(1);
}
sub set_auto_bed_shape {
my ($self, $bed_shape) = @_;
# draw a default square bed around object center
my $max_size = max(@{ $self->object_bounding_box->size });
my $center = $self->object_bounding_box->center;
$self->set_bed_shape([
[ $center->x - $max_size, $center->y - $max_size ], #--
[ $center->x + $max_size, $center->y - $max_size ], #--
[ $center->x + $max_size, $center->y + $max_size ], #++
[ $center->x - $max_size, $center->y + $max_size ], #++
]);
$self->origin(Slic3r::Pointf->new(@$center[X,Y]));
}
sub set_bed_shape {
my ($self, $bed_shape) = @_;
# triangulate bed
my $expolygon = Slic3r::ExPolygon->new([ map [map scale($_), @$_], @$bed_shape ]);
my $bed_bb = $expolygon->bounding_box;
{
my @points = ();
foreach my $triangle (@{ $expolygon->triangulate }) {
push @points, map {+ unscale($_->x), unscale($_->y), GROUND_Z } @$triangle; #))
}
$self->bed_triangles(OpenGL::Array->new_list(GL_FLOAT, @points));
}
{
my @lines = ();
for (my $x = $bed_bb->x_min; $x <= $bed_bb->x_max; $x += scale 10) {
push @lines, Slic3r::Polyline->new([$x,$bed_bb->y_min], [$x,$bed_bb->y_max]);
}
for (my $y = $bed_bb->y_min; $y <= $bed_bb->y_max; $y += scale 10) {
push @lines, Slic3r::Polyline->new([$bed_bb->x_min,$y], [$bed_bb->x_max,$y]);
}
@lines = @{intersection_pl(\@lines, [ @$expolygon ])};
my @points = ();
foreach my $polyline (@lines) {
push @points, map {+ unscale($_->x), unscale($_->y), GROUND_Z } @$polyline; #))
}
$self->bed_grid_lines(OpenGL::Array->new_list(GL_FLOAT, @points));
}
$self->origin(Slic3r::Pointf->new(0,0));
}
sub load_object {
my ($self, $object, $all_instances) = @_;
my $z_min = $object->raw_bounding_box->z_min;
# color mesh(es) by material
my @materials = ();
# sort volumes: non-modifiers first
my @volumes = sort { ($a->modifier // 0) <=> ($b->modifier // 0) } @{$object->volumes};
foreach my $volume (@volumes) {
my @instances = $all_instances ? @{$object->instances} : $object->instances->[0];
foreach my $instance (@instances) {
my $mesh = $volume->mesh->clone;
$instance->transform_mesh($mesh);
my $material_id = $volume->material_id // '_';
my $color_idx = first { $materials[$_] eq $material_id } 0..$#materials;
if (!defined $color_idx) {
push @materials, $material_id;
$color_idx = $#materials;
}
my $color = [ @{COLORS->[ $color_idx % scalar(@{&COLORS}) ]} ];
push @$color, $volume->modifier ? 0.5 : 1;
push @{$self->volumes}, my $v = {
mesh => $mesh,
color => $color,
z_min => $z_min,
};
{
my $vertices = $mesh->vertices;
my @verts = map @{ $vertices->[$_] }, map @$_, @{$mesh->facets};
$v->{verts} = OpenGL::Array->new_list(GL_FLOAT, @verts);
}
{
my @norms = map { @$_, @$_, @$_ } @{$mesh->normals};
$v->{norms} = OpenGL::Array->new_list(GL_FLOAT, @norms);
}
}
}
}
sub SetCuttingPlane {
my ($self, $z) = @_;
$self->cutting_plane_z($z);
# perform cut and cache section lines
my @verts = ();
foreach my $volume (@{$self->volumes}) {
foreach my $volume (@{$self->volumes}) {
my $expolygons = $volume->{mesh}->slice([ $z + $volume->{z_min} ])->[0];
$expolygons = offset_ex([ map @$_, @$expolygons ], scale 0.1);
foreach my $line (map @{$_->lines}, map @$_, @$expolygons) {
push @verts, (
unscale($line->a->x), unscale($line->a->y), $z, #))
unscale($line->b->x), unscale($line->b->y), $z, #))
);
}
}
}
$self->cut_lines_vertices(OpenGL::Array->new_list(GL_FLOAT, @verts));
}
# Given an axis and angle, compute quaternion.
sub axis_to_quat {
my ($ax, $phi) = @_;
my $lena = sqrt(reduce { $a + $b } (map { $_ * $_ } @$ax));
my @q = map { $_ * (1 / $lena) } @$ax;
@q = map { $_ * sin($phi / 2.0) } @q;
$q[$#q + 1] = cos($phi / 2.0);
return @q;
}
# Project a point on the virtual trackball.
# If it is inside the sphere, map it to the sphere, if it outside map it
# to a hyperbola.
sub project_to_sphere {
my ($r, $x, $y) = @_;
my $d = sqrt($x * $x + $y * $y);
if ($d < $r * 0.70710678118654752440) { # Inside sphere
return sqrt($r * $r - $d * $d);
} else { # On hyperbola
my $t = $r / 1.41421356237309504880;
return $t * $t / $d;
}
}
sub cross {
my ($v1, $v2) = @_;
return (@$v1[1] * @$v2[2] - @$v1[2] * @$v2[1],
@$v1[2] * @$v2[0] - @$v1[0] * @$v2[2],
@$v1[0] * @$v2[1] - @$v1[1] * @$v2[0]);
}
# Simulate a track-ball. Project the points onto the virtual trackball,
# then figure out the axis of rotation, which is the cross product of
# P1 P2 and O P1 (O is the center of the ball, 0,0,0) Note: This is a
# deformed trackball-- is a trackball in the center, but is deformed
# into a hyperbolic sheet of rotation away from the center.
# It is assumed that the arguments to this routine are in the range
# (-1.0 ... 1.0).
sub trackball {
my ($p1x, $p1y, $p2x, $p2y) = @_;
if ($p1x == $p2x && $p1y == $p2y) {
# zero rotation
return (0.0, 0.0, 0.0, 1.0);
}
# First, figure out z-coordinates for projection of P1 and P2 to
# deformed sphere
my @p1 = ($p1x, $p1y, project_to_sphere(TRACKBALLSIZE, $p1x, $p1y));
my @p2 = ($p2x, $p2y, project_to_sphere(TRACKBALLSIZE, $p2x, $p2y));
# axis of rotation (cross product of P1 and P2)
my @a = cross(\@p2, \@p1);
# Figure out how much to rotate around that axis.
my @d = map { $_ * $_ } (map { $p1[$_] - $p2[$_] } 0 .. $#p1);
my $t = sqrt(reduce { $a + $b } @d) / (2.0 * TRACKBALLSIZE);
# Avoid problems with out-of-control values...
$t = 1.0 if ($t > 1.0);
$t = -1.0 if ($t < -1.0);
my $phi = 2.0 * asin($t);
return axis_to_quat(\@a, $phi);
}
# Build a rotation matrix, given a quaternion rotation.
sub quat_to_rotmatrix {
my ($q) = @_;
my @m = ();
$m[0] = 1.0 - 2.0 * (@$q[1] * @$q[1] + @$q[2] * @$q[2]);
$m[1] = 2.0 * (@$q[0] * @$q[1] - @$q[2] * @$q[3]);
$m[2] = 2.0 * (@$q[2] * @$q[0] + @$q[1] * @$q[3]);
$m[3] = 0.0;
$m[4] = 2.0 * (@$q[0] * @$q[1] + @$q[2] * @$q[3]);
$m[5] = 1.0 - 2.0 * (@$q[2] * @$q[2] + @$q[0] * @$q[0]);
$m[6] = 2.0 * (@$q[1] * @$q[2] - @$q[0] * @$q[3]);
$m[7] = 0.0;
$m[8] = 2.0 * (@$q[2] * @$q[0] - @$q[1] * @$q[3]);
$m[9] = 2.0 * (@$q[1] * @$q[2] + @$q[0] * @$q[3]);
$m[10] = 1.0 - 2.0 * (@$q[1] * @$q[1] + @$q[0] * @$q[0]);
$m[11] = 0.0;
$m[12] = 0.0;
$m[13] = 0.0;
$m[14] = 0.0;
$m[15] = 1.0;
return @m;
}
sub mulquats {
my ($q1, $rq) = @_;
return (@$q1[3] * @$rq[0] + @$q1[0] * @$rq[3] + @$q1[1] * @$rq[2] - @$q1[2] * @$rq[1],
@$q1[3] * @$rq[1] + @$q1[1] * @$rq[3] + @$q1[2] * @$rq[0] - @$q1[0] * @$rq[2],
@$q1[3] * @$rq[2] + @$q1[2] * @$rq[3] + @$q1[0] * @$rq[1] - @$q1[1] * @$rq[0],
@$q1[3] * @$rq[3] - @$q1[0] * @$rq[0] - @$q1[1] * @$rq[1] - @$q1[2] * @$rq[2])
}
sub handle_rotation {
my ($self, $e) = @_;
if (not defined $self->initpos) {
$self->initpos($e->GetPosition());
} else {
my $orig = $self->initpos;
my $new = $e->GetPosition();
my $size = $self->GetClientSize();
if (TURNTABLE_MODE) {
$self->sphi($self->sphi + ($new->x - $orig->x)*TRACKBALLSIZE);
$self->stheta($self->stheta + ($new->y - $orig->y)*TRACKBALLSIZE); #-
} else {
my @quat = trackball($orig->x / ($size->width / 2) - 1,
1 - $orig->y / ($size->height / 2), #/
$new->x / ($size->width / 2) - 1,
1 - $new->y / ($size->height / 2), #/
);
$self->quat(mulquats($self->quat, \@quat));
}
$self->initpos($new);
$self->Refresh;
}
}
sub handle_translation {
my ($self, $e) = @_;
if (not defined $self->initpos) {
$self->initpos($e->GetPosition());
} else {
my $new = $e->GetPosition();
my $orig = $self->initpos;
my @orig3d = $self->mouse_to_3d($orig->x, $orig->y); #)()
my @new3d = $self->mouse_to_3d($new->x, $new->y); #)()
glTranslatef($new3d[0] - $orig3d[0], $new3d[1] - $orig3d[1], 0);
$self->initpos($new);
$self->Refresh;
}
}
sub mouse_to_3d {
my ($self, $x, $y) = @_;
my @viewport = glGetIntegerv_p(GL_VIEWPORT); # 4 items
my @mview = glGetDoublev_p(GL_MODELVIEW_MATRIX); # 16 items
my @proj = glGetDoublev_p(GL_PROJECTION_MATRIX); # 16 items
my @projected = gluUnProject_p($x, $viewport[3] - $y, 1.0, @mview, @proj, @viewport);
return @projected;
}
sub ZoomTo {
my ($self, $factor, $tox, $toy) = @_;
return if !$self->init;
glTranslatef($tox, $toy, 0);
glMatrixMode(GL_MODELVIEW);
$self->Zoom($factor);
glTranslatef(-$tox, -$toy, 0);
}
sub Zoom {
my ($self, $factor) = @_;
glMatrixMode(GL_MODELVIEW);
glScalef($factor, $factor, 1);
}
sub GetContext {
my ($self) = @_;
if (Wx::wxVERSION >= 2.009) {
return $self->{context} ||= Wx::GLContext->new($self);
} else {
return $self->SUPER::GetContext;
}
}
sub SetCurrent {
my ($self, $context) = @_;
if (Wx::wxVERSION >= 2.009) {
return $self->SUPER::SetCurrent($context);
} else {
return $self->SUPER::SetCurrent;
}
}
sub ResetModelView {
my ($self, $factor) = @_;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
my $win_size = $self->GetClientSize();
my $ratio = $factor * min($win_size->width, $win_size->height) / (2 * max(@{ $self->object_bounding_box->size }));
glScalef($ratio, $ratio, 1);
}
sub Resize {
my ($self, $x, $y) = @_;
return unless $self->GetContext;
$self->dirty(0);
$self->SetCurrent($self->GetContext);
glViewport(0, 0, $x, $y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(
-$x/2, $x/2, -$y/2, $y/2,
-200, 10 * max(@{ $self->object_bounding_box->size }),
);
glMatrixMode(GL_MODELVIEW);
unless ($self->mview_init) {
$self->mview_init(1);
$self->ResetModelView(0.9);
}
}
sub InitGL {
my $self = shift;
return if $self->init;
return unless $self->GetContext;
$self->init(1);
glClearColor(0, 0, 0, 1);
glColor3f(1, 0, 0);
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
# ambient lighting
glLightModelfv_p(GL_LIGHT_MODEL_AMBIENT, 0.1, 0.1, 0.1, 1);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glLightfv_p(GL_LIGHT0, GL_POSITION, 0.5, 0.5, 1, 0);
glLightfv_p(GL_LIGHT0, GL_SPECULAR, 0.5, 0.5, 0.5, 1);
glLightfv_p(GL_LIGHT0, GL_DIFFUSE, 0.8, 0.8, 0.8, 1);
glLightfv_p(GL_LIGHT1, GL_POSITION, 1, 0, 0.5, 0);
glLightfv_p(GL_LIGHT1, GL_SPECULAR, 0.5, 0.5, 0.5, 1);
glLightfv_p(GL_LIGHT1, GL_DIFFUSE, 1, 1, 1, 1);
# Enables Smooth Color Shading; try GL_FLAT for (lack of) fun.
glShadeModel(GL_SMOOTH);
glMaterialfv_p(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, 0.5, 0.3, 0.3, 1);
glMaterialfv_p(GL_FRONT_AND_BACK, GL_SPECULAR, 1, 1, 1, 1);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50);
glMaterialfv_p(GL_FRONT_AND_BACK, GL_EMISSION, 0.1, 0, 0, 0.9);
# A handy trick -- have surface material mirror the color.
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_MULTISAMPLE);
}
sub Render {
my ($self, $dc) = @_;
# prevent calling SetCurrent() when window is not shown yet
return unless $self->IsShownOnScreen;
return unless my $context = $self->GetContext;
$self->SetCurrent($context);
$self->InitGL;
glClearColor(1, 1, 1, 1);
glClearDepth(1);
glDepthFunc(GL_LESS);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
my $bb = $self->object_bounding_box;
my $object_size = $bb->size;
glTranslatef(0, 0, -max(@$object_size[0..1]));
my @rotmat = quat_to_rotmatrix($self->quat);
glMultMatrixd_p(@rotmat[0..15]);
glRotatef($self->stheta, 1, 0, 0);
glRotatef($self->sphi, 0, 0, 1);
# center everything around 0,0 since that's where we're looking at (glOrtho())
my $center = $bb->center;
glTranslatef(-$center->x, -$center->y, 0); #,,
# draw objects
$self->draw_mesh;
# draw ground and axes
glDisable(GL_LIGHTING);
my $z0 = 0;
{
# draw ground
my $ground_z = GROUND_Z;
if ($self->bed_triangles) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(0.5, 0.5, 0.5, 0.3);
glNormal3d(0,0,1);
glVertexPointer_p(3, $self->bed_triangles);
glDrawArrays(GL_TRIANGLES, 0, $self->bed_triangles->elements / 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
# draw grid
glTranslatef(0, 0, 0.02);
glLineWidth(3);
glColor3f(1.0, 1.0, 1.0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer_p(3, $self->bed_grid_lines);
glDrawArrays(GL_LINES, 0, $self->bed_grid_lines->elements / 3);
glDisableClientState(GL_VERTEX_ARRAY);
}
{
# draw axes
$ground_z += 0.02;
my $origin = $self->origin;
my $axis_len = 2 * max(@{ $object_size });
glLineWidth(2);
glBegin(GL_LINES);
# draw line for x axis
glColor3f(1, 0, 0);
glVertex3f(@$origin, $ground_z);
glVertex3f($origin->x + $axis_len, $origin->y, $ground_z); #,,
# draw line for y axis
glColor3f(0, 1, 0);
glVertex3f(@$origin, $ground_z);
glVertex3f($origin->x, $origin->y + $axis_len, $ground_z); #++
# draw line for Z axis
glColor3f(0, 0, 1);
glVertex3f(@$origin, $ground_z);
glVertex3f(@$origin, $ground_z+$axis_len);
glEnd();
}
# draw cutting plane
if (defined $self->cutting_plane_z) {
my $plane_z = $z0 + $self->cutting_plane_z;
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
glColor4f(0.8, 0.8, 0.8, 0.5);
glVertex3f($bb->x_min-20, $bb->y_min-20, $plane_z);
glVertex3f($bb->x_max+20, $bb->y_min-20, $plane_z);
glVertex3f($bb->x_max+20, $bb->y_max+20, $plane_z);
glVertex3f($bb->x_min-20, $bb->y_max+20, $plane_z);
glEnd();
glEnable(GL_CULL_FACE);
glDisable(GL_BLEND);
}
}
glEnable(GL_LIGHTING);
glPopMatrix();
glFlush();
$self->SwapBuffers();
}
sub draw_mesh {
my $self = shift;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
foreach my $volume (@{$self->volumes}) {
glTranslatef(0, 0, -$volume->{z_min});
glVertexPointer_p(3, $volume->{verts});
glCullFace(GL_BACK);
glNormalPointer_p($volume->{norms});
if ($volume->{selected}) {
glColor4f(@{ &SELECTED_COLOR });
} else {
glColor4f(@{ $volume->{color} });
}
glDrawArrays(GL_TRIANGLES, 0, $volume->{verts}->elements / 3);
glTranslatef(0, 0, +$volume->{z_min});
}
glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
if (defined $self->cutting_plane_z) {
glLineWidth(2);
glColor3f(0, 0, 0);
glVertexPointer_p(3, $self->cut_lines_vertices);
glDrawArrays(GL_LINES, 0, $self->cut_lines_vertices->elements / 3);
}
glDisableClientState(GL_VERTEX_ARRAY);
}
1;

View File

@@ -1,3 +1,5 @@
# Status bar at the bottom of the main screen.
package Slic3r::GUI::ProgressStatusBar;
use strict;
use warnings;

View File

@@ -1,268 +0,0 @@
package Slic3r::GUI::SimpleTab;
use strict;
use warnings;
use utf8;
use File::Basename qw(basename);
use List::Util qw(first);
use Wx qw(:bookctrl :dialog :keycode :icon :id :misc :panel :sizer :window :systemsettings);
use Wx::Event qw(EVT_BUTTON EVT_CHOICE EVT_KEY_DOWN);
use base 'Wx::ScrolledWindow';
sub new {
my $class = shift;
my ($parent, %params) = @_;
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
$self->SetScrollbars(1, 1, 1, 1);
$self->{config} = Slic3r::Config->new;
$self->{optgroups} = [];
$self->{vsizer} = Wx::BoxSizer->new(wxVERTICAL);
$self->SetSizer($self->{vsizer});
$self->build;
{
my $label = Wx::StaticText->new($self, -1, "Want more options? Switch to the Expert Mode.", wxDefaultPosition, wxDefaultSize);
$label->SetFont(Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
$self->{vsizer}->Add($label, 0, wxEXPAND | wxALL, 10);
}
return $self;
}
sub init_config_options {
my ($self, @opt_keys) = @_;
$self->{config}->apply(Slic3r::Config->new_from_defaults(@opt_keys));
}
sub new_optgroup {
my ($self, $title, %params) = @_;
my $optgroup = Slic3r::GUI::ConfigOptionsGroup->new(
parent => $self,
title => $title,
config => $self->{config},
label_width => $params{label_width} // 200,
on_change => sub { $self->_on_value_change(@_) },
);
push @{$self->{optgroups}}, $optgroup;
$self->{vsizer}->Add($optgroup->sizer, 0, wxEXPAND | wxALL, 10);
return $optgroup;
}
sub load_config_file {
my $self = shift;
my ($file) = @_;
my $config = Slic3r::Config->load($file);
$self->load_config($config);
}
sub load_config {
my $self = shift;
my ($config) = @_;
foreach my $opt_key (@{$self->{config}->get_keys}) {
next unless $config->has($opt_key);
$self->{config}->set($opt_key, $config->get($opt_key));
}
$_->reload_config for @{$self->{optgroups}};
}
sub load_presets {}
sub is_dirty { 0 }
sub config { $_[0]->{config}->clone }
sub on_value_change {
my ($self, $cb) = @_;
$self->{on_value_change} = $cb;
}
sub on_presets_changed {}
# propagate event to the parent
sub _on_value_change {
my $self = shift;
$self->{on_value_change}->(@_) if $self->{on_value_change};
}
package Slic3r::GUI::SimpleTab::Print;
use base 'Slic3r::GUI::SimpleTab';
use Wx qw(:sizer);
sub name { 'print' }
sub title { 'Print Settings' }
sub build {
my $self = shift;
$self->init_config_options(qw(
layer_height perimeters top_solid_layers bottom_solid_layers
fill_density fill_pattern support_material support_material_spacing raft_layers
perimeter_speed infill_speed travel_speed
brim_width
complete_objects extruder_clearance_radius extruder_clearance_height
));
{
my $optgroup = $self->new_optgroup('General');
$optgroup->append_single_option_line('layer_height');
$optgroup->append_single_option_line('perimeters');
my $line = Slic3r::GUI::OptionsGroup::Line->new(
label => 'Solid layers',
);
$line->append_option($optgroup->get_option('top_solid_layers'));
$line->append_option($optgroup->get_option('bottom_solid_layers'));
$optgroup->append_line($line);
}
{
my $optgroup = $self->new_optgroup('Infill');
$optgroup->append_single_option_line('fill_density');
$optgroup->append_single_option_line('fill_pattern');
}
{
my $optgroup = $self->new_optgroup('Support material');
$optgroup->append_single_option_line('support_material');
$optgroup->append_single_option_line('support_material_spacing');
$optgroup->append_single_option_line('raft_layers');
}
{
my $optgroup = $self->new_optgroup('Speed');
$optgroup->append_single_option_line('perimeter_speed');
$optgroup->append_single_option_line('infill_speed');
$optgroup->append_single_option_line('travel_speed');
}
{
my $optgroup = $self->new_optgroup('Brim');
$optgroup->append_single_option_line('brim_width');
}
{
my $optgroup = $self->new_optgroup('Sequential printing');
$optgroup->append_single_option_line('complete_objects');
my $line = Slic3r::GUI::OptionsGroup::Line->new(
label => 'Extruder clearance (mm)',
);
$line->append_option($optgroup->get_option('extruder_clearance_radius'));
$line->append_option($optgroup->get_option('extruder_clearance_height'));
$optgroup->append_line($line);
}
}
package Slic3r::GUI::SimpleTab::Filament;
use base 'Slic3r::GUI::SimpleTab';
sub name { 'filament' }
sub title { 'Filament Settings' }
sub build {
my $self = shift;
$self->init_config_options(qw(
filament_diameter extrusion_multiplier
temperature first_layer_temperature bed_temperature first_layer_bed_temperature
));
{
my $optgroup = $self->new_optgroup('Filament');
$optgroup->append_single_option_line('filament_diameter', 0);
$optgroup->append_single_option_line('extrusion_multiplier', 0);
}
{
my $optgroup = $self->new_optgroup('Temperature (°C)');
{
my $line = Slic3r::GUI::OptionsGroup::Line->new(
label => 'Extruder',
);
$line->append_option($optgroup->get_option('first_layer_temperature', 0));
$line->append_option($optgroup->get_option('temperature', 0));
$optgroup->append_line($line);
}
{
my $line = Slic3r::GUI::OptionsGroup::Line->new(
label => 'Bed',
);
$line->append_option($optgroup->get_option('first_layer_bed_temperature'));
$line->append_option($optgroup->get_option('bed_temperature'));
$optgroup->append_line($line);
}
}
}
package Slic3r::GUI::SimpleTab::Printer;
use base 'Slic3r::GUI::SimpleTab';
sub name { 'printer' }
sub title { 'Printer Settings' }
sub build {
my $self = shift;
$self->init_config_options(qw(
z_offset
gcode_flavor
nozzle_diameter
retract_length retract_lift
start_gcode
end_gcode
));
{
my $optgroup = $self->new_optgroup('Size and coordinates');
# TODO: add bed_shape
$optgroup->append_single_option_line('z_offset');
}
{
my $optgroup = $self->new_optgroup('Firmware');
$optgroup->append_single_option_line('gcode_flavor');
}
{
my $optgroup = $self->new_optgroup('Extruder');
$optgroup->append_single_option_line('nozzle_diameter', 0);
}
{
my $optgroup = $self->new_optgroup('Retraction');
$optgroup->append_single_option_line('retract_length', 0);
$optgroup->append_single_option_line('retract_lift', 0);
}
{
my $optgroup = $self->new_optgroup('Start G-code',
label_width => 0,
);
my $option = $optgroup->get_option('start_gcode');
$option->full_width(1);
$option->height(150);
$optgroup->append_single_option_line($option);
}
{
my $optgroup = $self->new_optgroup('End G-code',
label_width => 0,
);
my $option = $optgroup->get_option('end_gcode');
$option->full_width(1);
$option->height(150);
$optgroup->append_single_option_line($option);
}
}
1;

View File

@@ -0,0 +1,70 @@
package Slic3r::GUI::SystemInfo;
use strict;
use warnings;
use utf8;
use Wx qw(:font :html :misc :dialog :sizer :systemsettings :frame :id wxTheClipboard);
use Wx::Event qw(EVT_HTML_LINK_CLICKED EVT_LEFT_DOWN EVT_BUTTON);
use Wx::Html;
use base 'Wx::Dialog';
sub new {
my ($class, %params) = @_;
my $self = $class->SUPER::new($params{parent}, -1, 'Slic3r Prusa Edition - System Information', wxDefaultPosition, [600, 340],
wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxRESIZE_BORDER);
$self->{text_info} = $params{text_info};
$self->SetBackgroundColour(Wx::wxWHITE);
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
$self->SetSizer($vsizer);
# text
my $text =
'<html>' .
'<body bgcolor="#ffffff" link="#808080">' .
($params{slic3r_info} // '') .
($params{copyright_info} // '') .
($params{system_info} // '') .
($params{opengl_info} // '') .
'</body>' .
'</html>';
my $html = $self->{html} = Wx::HtmlWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
my $font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
my $size = &Wx::wxMSW ? 8 : 10;
$html->SetFonts($font->GetFaceName, $font->GetFaceName, [$size * 1.5, $size * 1.4, $size * 1.3, $size, $size, $size, $size]);
$html->SetBorders(10);
$html->SetPage($text);
$vsizer->Add($html, 1, wxEXPAND | wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 0);
EVT_HTML_LINK_CLICKED($self, $html, \&link_clicked);
my $buttons = $self->CreateStdDialogButtonSizer(wxOK);
my $btn_copy_to_clipboard = Wx::Button->new($self, -1, "Copy to Clipboard", wxDefaultPosition, wxDefaultSize);
$buttons->Insert(0, $btn_copy_to_clipboard, 0, wxLEFT, 5);
EVT_BUTTON($self, $btn_copy_to_clipboard, \&copy_to_clipboard);
$self->SetEscapeId(wxID_CLOSE);
EVT_BUTTON($self, wxID_CLOSE, sub {
$self->EndModal(wxID_CLOSE);
$self->Close;
});
# $vsizer->Add($buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
$vsizer->Add($buttons, 0, wxEXPAND | wxALL, 5);
return $self;
}
sub link_clicked {
my ($self, $event) = @_;
Wx::LaunchDefaultBrowser($event->GetLinkInfo->GetHref);
$event->Skip(0);
}
sub copy_to_clipboard {
my ($self, $event) = @_;
my $data = $self->{text_info};
wxTheClipboard->Open;
wxTheClipboard->SetData(Wx::TextDataObject->new($data));
wxTheClipboard->Close;
}
1;

File diff suppressed because it is too large Load Diff

View File

@@ -4,41 +4,40 @@ use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
PI X Y Z A B X1 Y1 X2 Y2 Z1 Z2 MIN MAX epsilon slope
line_point_belongs_to_segment points_coincide distance_between_points
normalize tan move_points_3D
point_in_polygon point_in_segment segment_in_segment
polyline_lines polygon_lines
point_along_segment polygon_segment_having_point polygon_has_subsegment
deg2rad rad2deg
rotate_points move_points
dot perp polygon_points_visibility
line_intersection bounding_box bounding_box_intersect
angle3points
chained_path chained_path_from collinear scale unscale
rad2deg_dir bounding_box_center line_intersects_any douglas_peucker
polyline_remove_short_segments normal triangle_normal polygon_is_convex
scaled_epsilon bounding_box_3D size_3D size_2D
convex_hull directions_parallel directions_parallel_within
);
# Exported by this module. The last section starting with convex_hull is exported by Geometry.xsp
our @EXPORT_OK = qw(
PI epsilon
angle3points
collinear
dot
line_intersection
normalize
point_in_segment
polyline_lines
polygon_is_convex
polygon_segment_having_point
scale
unscale
scaled_epsilon
size_2D
X Y Z
convex_hull
chained_path_from
deg2rad
rad2deg
rad2deg_dir
);
use constant PI => 4 * atan2(1, 1);
use constant A => 0;
use constant B => 1;
use constant X => 0;
use constant Y => 1;
use constant Z => 2;
use constant X1 => 0;
use constant Y1 => 1;
use constant X2 => 2;
use constant Y2 => 3;
use constant Z1 => 4;
use constant Z2 => 5;
use constant MIN => 0;
use constant MAX => 1;
our $parallel_degrees_limit = abs(deg2rad(0.1));
sub epsilon () { 1E-4 }
sub scaled_epsilon () { epsilon / &Slic3r::SCALING_FACTOR }
@@ -46,81 +45,7 @@ sub scaled_epsilon () { epsilon / &Slic3r::SCALING_FACTOR }
sub scale ($) { $_[0] / &Slic3r::SCALING_FACTOR }
sub unscale ($) { $_[0] * &Slic3r::SCALING_FACTOR }
sub tan {
my ($angle) = @_;
return (sin $angle) / (cos $angle);
}
sub slope {
my ($line) = @_;
return undef if abs($line->[B][X] - $line->[A][X]) < epsilon; # line is vertical
return ($line->[B][Y] - $line->[A][Y]) / ($line->[B][X] - $line->[A][X]);
}
# this subroutine checks whether a given point may belong to a given
# segment given the hypothesis that it belongs to the line containing
# the segment
sub line_point_belongs_to_segment {
my ($point, $segment) = @_;
#printf " checking whether %f,%f may belong to segment %f,%f - %f,%f\n",
# @$point, map @$_, @$segment;
my @segment_extents = (
[ sort { $a <=> $b } map $_->[X], @$segment ],
[ sort { $a <=> $b } map $_->[Y], @$segment ],
);
return 0 if $point->[X] < ($segment_extents[X][0] - epsilon) || $point->[X] > ($segment_extents[X][1] + epsilon);
return 0 if $point->[Y] < ($segment_extents[Y][0] - epsilon) || $point->[Y] > ($segment_extents[Y][1] + epsilon);
return 1;
}
sub points_coincide {
my ($p1, $p2) = @_;
return 1 if abs($p2->[X] - $p1->[X]) < epsilon && abs($p2->[Y] - $p1->[Y]) < epsilon;
return 0;
}
sub distance_between_points {
my ($p1, $p2) = @_;
return sqrt((($p1->[X] - $p2->[X])**2) + ($p1->[Y] - $p2->[Y])**2);
}
# this will check whether a point is in a polygon regardless of polygon orientation
sub point_in_polygon {
my ($point, $polygon) = @_;
my ($x, $y) = @$point;
my $n = @$polygon;
my @x = map $_->[X], @$polygon;
my @y = map $_->[Y], @$polygon;
# Derived from the comp.graphics.algorithms FAQ,
# courtesy of Wm. Randolph Franklin
my ($i, $j);
my $side = 0; # 0 = outside; 1 = inside
for ($i = 0, $j = $n - 1; $i < $n; $j = $i++) {
if (
# If the y is between the (y-) borders...
($y[$i] <= $y && $y < $y[$j]) || ($y[$j] <= $y && $y < $y[$i])
and
# ...the (x,y) to infinity line crosses the edge
# from the ith point to the jth point...
($x < ($x[$j] - $x[$i]) * ($y - $y[$i]) / ($y[$j] - $y[$i]) + $x[$i])
) {
$side = not $side; # Jump the fence
}
}
# if point is not in polygon, let's check whether it belongs to the contour
if (!$side && 0) {
return 1 if polygon_segment_having_point($polygon, $point);
}
return $side;
}
# used by geometry.t, polygon_segment_having_point
sub point_in_segment {
my ($point, $line) = @_;
@@ -144,41 +69,15 @@ sub point_in_segment {
return abs($y3 - $y) < epsilon ? 1 : 0;
}
sub segment_in_segment {
my ($needle, $haystack) = @_;
# a segment is contained in another segment if its endpoints are contained
return point_in_segment($needle->[A], $haystack) && point_in_segment($needle->[B], $haystack);
}
# used by geometry.t
sub polyline_lines {
my ($polyline) = @_;
my @points = @$polyline;
return map Slic3r::Line->new(@points[$_, $_+1]), 0 .. $#points-1;
}
sub polygon_lines {
my ($polygon) = @_;
return polyline_lines([ @$polygon, $polygon->[0] ]);
}
# given a segment $p1-$p2, get the point at $distance from $p1 along segment
sub point_along_segment {
my ($p1, $p2, $distance) = @_;
my $point = [ @$p1 ];
my $line_length = sqrt( (($p2->[X] - $p1->[X])**2) + (($p2->[Y] - $p1->[Y])**2) );
for (X, Y) {
if ($p1->[$_] != $p2->[$_]) {
$point->[$_] = $p1->[$_] + ($p2->[$_] - $p1->[$_]) * $distance / $line_length;
}
}
return Slic3r::Point->new(@$point);
}
# given a $polygon, return the (first) segment having $point
# used by geometry.t
sub polygon_segment_having_point {
my ($polygon, $point) = @_;
@@ -188,15 +87,6 @@ sub polygon_segment_having_point {
return undef;
}
# return true if the given segment is contained in any edge of the polygon
sub polygon_has_subsegment {
my ($polygon, $segment) = @_;
foreach my $line (polygon_lines($polygon)) {
return 1 if segment_in_segment($segment, $line);
}
return 0;
}
# polygon must be simple (non complex) and ccw
sub polygon_is_convex {
my ($points) = @_;
@@ -207,70 +97,6 @@ sub polygon_is_convex {
return 1;
}
sub deg2rad {
my ($degrees) = @_;
return PI() * $degrees / 180;
}
sub rad2deg {
my ($rad) = @_;
return $rad / PI() * 180;
}
sub rad2deg_dir {
my ($rad) = @_;
$rad = ($rad < PI) ? (-$rad + PI/2) : ($rad + PI/2);
$rad += PI if $rad < 0;
return rad2deg($rad);
}
sub rotate_points {
my ($radians, $center, @points) = @_;
$center //= [0,0];
return map {
[
$center->[X] + cos($radians) * ($_->[X] - $center->[X]) - sin($radians) * ($_->[Y] - $center->[Y]),
$center->[Y] + cos($radians) * ($_->[Y] - $center->[Y]) + sin($radians) * ($_->[X] - $center->[X]),
]
} @points;
}
sub move_points {
my ($shift, @points) = @_;
return map {
my @p = @$_;
Slic3r::Point->new($shift->[X] + $p[X], $shift->[Y] + $p[Y]);
} @points;
}
sub move_points_3D {
my ($shift, @points) = @_;
return map [
$shift->[X] + $_->[X],
$shift->[Y] + $_->[Y],
$shift->[Z] + $_->[Z],
], @points;
}
sub normal {
my ($line1, $line2) = @_;
return [
($line1->[Y] * $line2->[Z]) - ($line1->[Z] * $line2->[Y]),
-($line2->[Z] * $line1->[X]) + ($line2->[X] * $line1->[Z]),
($line1->[X] * $line2->[Y]) - ($line1->[Y] * $line2->[X]),
];
}
sub triangle_normal {
my ($v1, $v2, $v3) = @_;
my $u = [ map +($v2->[$_] - $v1->[$_]), (X,Y,Z) ];
my $v = [ map +($v3->[$_] - $v1->[$_]), (X,Y,Z) ];
return normal($u, $v);
}
sub normalize {
my ($line) = @_;
@@ -280,38 +106,12 @@ sub normalize {
}
# 2D dot product
# used by 3DScene.pm
sub dot {
my ($u, $v) = @_;
return $u->[X] * $v->[X] + $u->[Y] * $v->[Y];
}
# 2D perp product
sub perp {
my ($u, $v) = @_;
return $u->[X] * $v->[Y] - $u->[Y] * $v->[X];
}
sub polygon_points_visibility {
my ($polygon, $p1, $p2) = @_;
my $our_line = [ $p1, $p2 ];
foreach my $line (polygon_lines($polygon)) {
my $intersection = line_intersection($our_line, $line, 1) // next;
next if grep points_coincide($intersection, $_), $p1, $p2;
return 0;
}
return 1;
}
sub line_intersects_any {
my ($line, $lines) = @_;
for (@$lines) {
return 1 if line_intersection($line, $_, 1);
}
return 0;
}
sub line_intersection {
my ($line1, $line2, $require_crossing) = @_;
$require_crossing ||= 0;
@@ -409,43 +209,6 @@ sub _line_intersection {
return [Slic3r::Point->new($x, $y), $h10 >= 0 && $h10 <= 1 && $h32 >= 0 && $h32 <= 1];
}
# http://paulbourke.net/geometry/lineline2d/
sub _line_intersection2 {
my ($line1, $line2) = @_;
my $denom = ($line2->[B][Y] - $line2->[A][Y]) * ($line1->[B][X] - $line1->[A][X])
- ($line2->[B][X] - $line2->[A][X]) * ($line1->[B][Y] - $line1->[A][Y]);
my $numerA = ($line2->[B][X] - $line2->[A][X]) * ($line1->[A][Y] - $line2->[A][Y])
- ($line2->[B][Y] - $line2->[A][Y]) * ($line1->[A][X] - $line2->[A][X]);
my $numerB = ($line1->[B][X] - $line1->[A][X]) * ($line1->[A][Y] - $line2->[A][Y])
- ($line1->[B][Y] - $line1->[A][Y]) * ($line1->[A][X] - $line2->[A][X]);
# are the lines coincident?
if (abs($numerA) < epsilon && abs($numerB) < epsilon && abs($denom) < epsilon) {
return Slic3r::Point->new(
($line1->[A][X] + $line1->[B][X]) / 2,
($line1->[A][Y] + $line1->[B][Y]) / 2,
);
}
# are the lines parallel?
if (abs($denom) < epsilon) {
return undef;
}
# is the intersection along the segments?
my $muA = $numerA / $denom;
my $muB = $numerB / $denom;
if ($muA < 0 || $muA > 1 || $muB < 0 || $muB > 1) {
return undef;
}
return Slic3r::Point->new(
$line1->[A][X] + $muA * ($line1->[B][X] - $line1->[A][X]),
$line1->[A][Y] + $muA * ($line1->[B][Y] - $line1->[A][Y]),
);
}
# 2D
sub bounding_box {
my ($points) = @_;
@@ -463,14 +226,6 @@ sub bounding_box {
return @bb[X1,Y1,X2,Y2];
}
sub bounding_box_center {
my ($bounding_box) = @_;
return Slic3r::Point->new(
($bounding_box->[X2] + $bounding_box->[X1]) / 2,
($bounding_box->[Y2] + $bounding_box->[Y1]) / 2,
);
}
sub size_2D {
my @bounding_box = bounding_box(@_);
return (
@@ -481,7 +236,7 @@ sub size_2D {
# bounding_box_intersect($d, @a, @b)
# Return true if the given bounding boxes @a and @b intersect
# in $d dimensions. Used by line_intersection().
# in $d dimensions. Used by sub collinear.
sub bounding_box_intersect {
my ( $d, @bb ) = @_; # Number of dimensions and box coordinates.
my @aa = splice( @bb, 0, 2 * $d ); # The first box.
@@ -497,27 +252,6 @@ sub bounding_box_intersect {
return 1;
}
# 3D
sub bounding_box_3D {
my ($points) = @_;
my @extents = (map [undef, undef], X,Y,Z);
foreach my $point (@$points) {
for (X,Y,Z) {
$extents[$_][MIN] = $point->[$_] if !defined $extents[$_][MIN] || $point->[$_] < $extents[$_][MIN];
$extents[$_][MAX] = $point->[$_] if !defined $extents[$_][MAX] || $point->[$_] > $extents[$_][MAX];
}
}
return @extents;
}
sub size_3D {
my ($points) = @_;
my @extents = bounding_box_3D($points);
return map $extents[$_][MAX] - $extents[$_][MIN], (X,Y,Z);
}
# this assumes a CCW rotation from $p2 to $p3 around $p1
sub angle3points {
my ($p1, $p2, $p3) = @_;
@@ -530,224 +264,4 @@ sub angle3points {
return $angle <= 0 ? $angle + 2*PI() : $angle;
}
sub polyline_remove_short_segments {
my ($points, $min_length, $isPolygon) = @_;
for (my $i = $isPolygon ? 0 : 1; $i < $#$points; $i++) {
if (distance_between_points($points->[$i-1], $points->[$i]) < $min_length) {
# we can remove $points->[$i]
splice @$points, $i, 1;
$i--;
}
}
}
sub douglas_peucker {
my ($points, $tolerance) = @_;
no warnings "recursion";
my $results = [];
my $dmax = 0;
my $index = 0;
for my $i (1..$#$points) {
my $d = $points->[$i]->distance_to(Slic3r::Line->new($points->[0], $points->[-1]));
if ($d > $dmax) {
$index = $i;
$dmax = $d;
}
}
if ($dmax >= $tolerance) {
my $dp1 = douglas_peucker([ @$points[0..$index] ], $tolerance);
$results = [
@$dp1[0..($#$dp1-1)],
@{douglas_peucker([ @$points[$index..$#$points] ], $tolerance)},
];
} else {
$results = [ $points->[0], $points->[-1] ];
}
return $results;
}
sub douglas_peucker2 {
my ($points, $tolerance) = @_;
my $anchor = 0;
my $floater = $#$points;
my @stack = ();
my %keep = ();
push @stack, [$anchor, $floater];
while (@stack) {
($anchor, $floater) = @{pop @stack};
# initialize line segment
my ($anchor_x, $anchor_y, $seg_len);
if (grep $points->[$floater][$_] != $points->[$anchor][$_], X, Y) {
$anchor_x = $points->[$floater][X] - $points->[$anchor][X];
$anchor_y = $points->[$floater][Y] - $points->[$anchor][Y];
$seg_len = sqrt(($anchor_x ** 2) + ($anchor_y ** 2));
# get the unit vector
$anchor_x /= $seg_len;
$anchor_y /= $seg_len;
} else {
$anchor_x = $anchor_y = $seg_len = 0;
}
# inner loop:
my $max_dist = 0;
my $farthest = $anchor + 1;
for my $i (($anchor + 1) .. $floater) {
my $dist_to_seg = 0;
# compare to anchor
my $vecX = $points->[$i][X] - $points->[$anchor][X];
my $vecY = $points->[$i][Y] - $points->[$anchor][Y];
$seg_len = sqrt(($vecX ** 2) + ($vecY ** 2));
# dot product:
my $proj = $vecX * $anchor_x + $vecY * $anchor_y;
if ($proj < 0) {
$dist_to_seg = $seg_len;
} else {
# compare to floater
$vecX = $points->[$i][X] - $points->[$floater][X];
$vecY = $points->[$i][Y] - $points->[$floater][Y];
$seg_len = sqrt(($vecX ** 2) + ($vecY ** 2));
# dot product:
$proj = $vecX * (-$anchor_x) + $vecY * (-$anchor_y);
if ($proj < 0) {
$dist_to_seg = $seg_len
} else { # calculate perpendicular distance to line (pythagorean theorem):
$dist_to_seg = sqrt(abs(($seg_len ** 2) - ($proj ** 2)));
}
if ($max_dist < $dist_to_seg) {
$max_dist = $dist_to_seg;
$farthest = $i;
}
}
}
if ($max_dist <= $tolerance) { # use line segment
$keep{$_} = 1 for $anchor, $floater;
} else {
push @stack, [$anchor, $farthest];
push @stack, [$farthest, $floater];
}
}
return [ map $points->[$_], sort keys %keep ];
}
sub arrange {
my ($total_parts, $partx, $party, $dist, $bb) = @_;
my $linint = sub {
my ($value, $oldmin, $oldmax, $newmin, $newmax) = @_;
return ($value - $oldmin) * ($newmax - $newmin) / ($oldmax - $oldmin) + $newmin;
};
# use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm
$partx += $dist;
$party += $dist;
my ($areax, $areay);
if (defined $bb) {
my $size = $bb->size;
($areax, $areay) = @$size[X,Y];
} else {
# bogus area size, large enough not to trigger the error below
$areax = $partx * $total_parts;
$areay = $party * $total_parts;
}
# this is how many cells we have available into which to put parts
my $cellw = int(($areax + $dist) / $partx);
my $cellh = int(($areay + $dist) / $party);
die "$total_parts parts won't fit in your print area!\n" if $total_parts > ($cellw * $cellh);
# width and height of space used by cells
my $w = $cellw * $partx;
my $h = $cellh * $party;
# left and right border positions of space used by cells
my $l = ($areax - $w) / 2;
my $r = $l + $w;
# top and bottom border positions
my $t = ($areay - $h) / 2;
my $b = $t + $h;
# list of cells, sorted by distance from center
my @cellsorder;
# work out distance for all cells, sort into list
for my $i (0..$cellw-1) {
for my $j (0..$cellh-1) {
my $cx = $linint->($i + 0.5, 0, $cellw, $l, $r);
my $cy = $linint->($j + 0.5, 0, $cellh, $t, $b);
my $xd = abs(($areax / 2) - $cx);
my $yd = abs(($areay / 2) - $cy);
my $c = {
location => [$cx, $cy],
index => [$i, $j],
distance => $xd * $xd + $yd * $yd - abs(($cellw / 2) - ($i + 0.5)),
};
BINARYINSERTIONSORT: {
my $index = $c->{distance};
my $low = 0;
my $high = @cellsorder;
while ($low < $high) {
my $mid = ($low + (($high - $low) / 2)) | 0;
my $midval = $cellsorder[$mid]->[0];
if ($midval < $index) {
$low = $mid + 1;
} elsif ($midval > $index) {
$high = $mid;
} else {
splice @cellsorder, $mid, 0, [$index, $c];
last BINARYINSERTIONSORT;
}
}
splice @cellsorder, $low, 0, [$index, $c];
}
}
}
# the extents of cells actually used by objects
my ($lx, $ty, $rx, $by) = (0, 0, 0, 0);
# now find cells actually used by objects, map out the extents so we can position correctly
for my $i (1..$total_parts) {
my $c = $cellsorder[$i - 1];
my $cx = $c->[1]->{index}->[0];
my $cy = $c->[1]->{index}->[1];
if ($i == 1) {
$lx = $rx = $cx;
$ty = $by = $cy;
} else {
$rx = $cx if $cx > $rx;
$lx = $cx if $cx < $lx;
$by = $cy if $cy > $by;
$ty = $cy if $cy < $ty;
}
}
# now we actually place objects into cells, positioned such that the left and bottom borders are at 0
my @positions = ();
for (1..$total_parts) {
my $c = shift @cellsorder;
my $cx = $c->[1]->{index}->[0] - $lx;
my $cy = $c->[1]->{index}->[1] - $ty;
push @positions, [$cx * $partx, $cy * $party];
}
if (defined $bb) {
$_->[X] += $bb->x_min for @positions;
$_->[Y] += $bb->y_min for @positions;
}
return @positions;
}
1;

View File

@@ -4,10 +4,11 @@ use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(offset offset_ex
diff_ex diff union_ex intersection_ex xor_ex JT_ROUND JT_MITER
JT_SQUARE is_counter_clockwise union_pt offset2 offset2_ex
intersection intersection_pl diff_pl union CLIPPER_OFFSET_SCALE
union_pt_chained diff_ppl intersection_ppl);
our @EXPORT_OK = qw(
offset offset2
offset_ex offset2_ex
diff_ex diff union_ex intersection_ex
JT_ROUND JT_MITER JT_SQUARE
intersection intersection_pl diff_pl union);
1;

View File

@@ -1,11 +1,9 @@
# Extends the C++ class Slic3r::Layer.
package Slic3r::Layer;
use strict;
use warnings;
use List::Util qw(first);
use Slic3r::Geometry qw(scale chained_path);
use Slic3r::Geometry::Clipper qw(union_ex intersection_ex);
# the following two were previously generated by Moo
sub print {
my $self = shift;
@@ -17,12 +15,6 @@ sub config {
return $self->object->config;
}
# the purpose of this method is to be overridden for ::Support layers
sub islands {
my $self = shift;
return $self->slices;
}
sub region {
my $self = shift;
my ($region_id) = @_;
@@ -39,94 +31,7 @@ sub regions {
return [ map $self->get_region($_), 0..($self->region_count-1) ];
}
sub merge_slices {
my ($self) = @_;
$_->merge_slices for @{$self->regions};
}
sub make_perimeters {
my $self = shift;
Slic3r::debugf "Making perimeters for layer %d\n", $self->id;
# keep track of regions whose perimeters we have already generated
my %done = (); # region_id => 1
for my $region_id (0..$#{$self->regions}) {
next if $done{$region_id};
my $layerm = $self->regions->[$region_id];
$done{$region_id} = 1;
# find compatible regions
my @layerms = ($layerm);
for my $i (($region_id+1)..$#{$self->regions}) {
my $config = $self->regions->[$i]->config;
my $layerm_config = $layerm->config;
if ($config->perimeter_extruder == $layerm_config->perimeter_extruder
&& $config->perimeters == $layerm_config->perimeters
&& $config->perimeter_speed == $layerm_config->perimeter_speed
&& $config->gap_fill_speed == $layerm_config->gap_fill_speed
&& $config->overhangs == $layerm_config->overhangs
&& $config->perimeter_extrusion_width == $layerm_config->perimeter_extrusion_width
&& $config->thin_walls == $layerm_config->thin_walls
&& $config->external_perimeters_first == $layerm_config->external_perimeters_first) {
push @layerms, $self->regions->[$i];
$done{$i} = 1;
}
}
if (@layerms == 1) { # optimization
$layerm->fill_surfaces->clear;
$layerm->make_perimeters($layerm->slices, $layerm->fill_surfaces);
} else {
# group slices (surfaces) according to number of extra perimeters
my %slices = (); # extra_perimeters => [ surface, surface... ]
foreach my $surface (map @{$_->slices}, @layerms) {
my $extra = $surface->extra_perimeters;
$slices{$extra} ||= [];
push @{$slices{$extra}}, $surface;
}
# merge the surfaces assigned to each group
my $new_slices = Slic3r::Surface::Collection->new;
foreach my $surfaces (values %slices) {
$new_slices->append(Slic3r::Surface->new(
surface_type => $surfaces->[0]->surface_type,
extra_perimeters => $surfaces->[0]->extra_perimeters,
expolygon => $_,
)) for @{union_ex([ map $_->p, @$surfaces ], 1)};
}
# make perimeters
my $fill_surfaces = Slic3r::Surface::Collection->new;
$layerm->make_perimeters($new_slices, $fill_surfaces);
# assign fill_surfaces to each layer
if ($fill_surfaces->count > 0) {
foreach my $lm (@layerms) {
my $expolygons = intersection_ex(
[ map $_->p, @$fill_surfaces ],
[ map $_->p, @{$lm->slices} ],
);
$lm->fill_surfaces->clear;
$lm->fill_surfaces->append(Slic3r::Surface->new(
surface_type => $fill_surfaces->[0]->surface_type,
extra_perimeters => $fill_surfaces->[0]->extra_perimeters,
expolygon => $_,
)) for @$expolygons;
}
}
}
}
}
package Slic3r::Layer::Support;
our @ISA = qw(Slic3r::Layer);
sub islands {
my $self = shift;
return [ @{$self->slices}, @{$self->support_islands} ];
}
1;

View File

@@ -1,277 +0,0 @@
package Slic3r::Layer::BridgeDetector;
use Moo;
use List::Util qw(first sum max min);
use Slic3r::Geometry qw(PI unscale scaled_epsilon rad2deg epsilon directions_parallel_within);
use Slic3r::Geometry::Clipper qw(intersection_pl intersection_ex union offset diff_pl union_ex
intersection_ppl);
has 'expolygon' => (is => 'ro', required => 1);
has 'lower_slices' => (is => 'rw', required => 1); # ExPolygons or ExPolygonCollection
has 'extrusion_width' => (is => 'rw', required => 1); # scaled
has 'resolution' => (is => 'rw', default => sub { PI/36 });
has '_edges' => (is => 'rw'); # Polylines representing the supporting edges
has '_anchors' => (is => 'rw'); # ExPolygons
has 'angle' => (is => 'rw');
sub BUILD {
my ($self) = @_;
# outset our bridge by an arbitrary amout; we'll use this outer margin
# for detecting anchors
my $grown = $self->expolygon->offset(+$self->extrusion_width);
# detect what edges lie on lower slices
$self->_edges(my $edges = []);
foreach my $lower (@{$self->lower_slices}) {
# turn bridge contour and holes into polylines and then clip them
# with each lower slice's contour
push @$edges, @{intersection_ppl($grown, [ $lower->contour ])};
}
Slic3r::debugf " bridge has %d support(s)\n", scalar(@$edges);
# detect anchors as intersection between our bridge expolygon and the lower slices
$self->_anchors(intersection_ex(
$grown,
[ map @$_, @{$self->lower_slices} ],
1, # safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some @edges
));
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output("bridge.svg",
expolygons => [ $self->expolygon ],
red_expolygons => $self->lower_slices,
polylines => $self->_edges,
);
}
}
sub detect_angle {
my ($self) = @_;
return undef if !@{$self->_edges};
my @edges = @{$self->_edges};
my $anchors = $self->_anchors;
if (!@$anchors) {
$self->angle(undef);
return undef;
}
# Outset the bridge expolygon by half the amount we used for detecting anchors;
# we'll use this one to clip our test lines and be sure that their endpoints
# are inside the anchors and not on their contours leading to false negatives.
my $clip_area = $self->expolygon->offset_ex(+$self->extrusion_width/2);
# we'll now try several directions using a rudimentary visibility check:
# bridge in several directions and then sum the length of lines having both
# endpoints within anchors
# we test angles according to configured resolution
my @angles = map { $_*$self->resolution } 0..(PI/$self->resolution);
# we also test angles of each bridge contour
push @angles, map $_->direction, map @{$_->lines}, @{$self->expolygon};
# we also test angles of each open supporting edge
# (this finds the optimal angle for C-shaped supports)
push @angles,
map Slic3r::Line->new($_->first_point, $_->last_point)->direction,
grep { !$_->first_point->coincides_with($_->last_point) }
@edges;
# remove duplicates
my $min_resolution = PI/180; # 1 degree
# proceed in reverse order so that when we compare first value with last one (-1)
# we remove the greatest one (PI) in case they are parallel (PI, 0)
@angles = reverse sort @angles;
for (my $i = 0; $i <= $#angles; ++$i) {
if (directions_parallel_within($angles[$i], $angles[$i-1], $min_resolution)) {
splice @angles, $i, 1;
--$i;
}
}
my %directions_coverage = (); # angle => score
my %directions_avg_length = (); # angle => score
my $line_increment = $self->extrusion_width;
my %unique_angles = map { $_ => 1 } @angles;
for my $angle (@angles) {
my $my_clip_area = [ map $_->clone, @$clip_area ];
my $my_anchors = [ map $_->clone, @$anchors ];
# rotate everything - the center point doesn't matter
$_->rotate(-$angle, [0,0]) for @$my_clip_area, @$my_anchors;
# generate lines in this direction
my $bounding_box = Slic3r::Geometry::BoundingBox->new_from_points([ map @$_, map @$_, @$my_anchors ]);
my @lines = ();
for (my $y = $bounding_box->y_min; $y <= $bounding_box->y_max; $y+= $line_increment) {
push @lines, Slic3r::Polyline->new(
[$bounding_box->x_min, $y],
[$bounding_box->x_max, $y],
);
}
my @clipped_lines = map Slic3r::Line->new(@$_), @{ intersection_pl(\@lines, [ map @$_, @$my_clip_area ]) };
# remove any line not having both endpoints within anchors
@clipped_lines = grep {
my $line = $_;
(first { $_->contains_point($line->a) } @$my_anchors)
&& (first { $_->contains_point($line->b) } @$my_anchors);
} @clipped_lines;
my @lengths = map $_->length, @clipped_lines;
# sum length of bridged lines
$directions_coverage{$angle} = sum(@lengths) // 0;
### The following produces more correct results in some cases and more broken in others.
### TODO: investigate, as it looks more reliable than line clipping.
###$directions_coverage{$angle} = sum(map $_->area, @{$self->coverage($angle)}) // 0;
# max length of bridged lines
$directions_avg_length{$angle} = @lengths ? (max(@lengths)) : -1;
}
# if no direction produced coverage, then there's no bridge direction
return undef if !defined first { $_ > 0 } values %directions_coverage;
# the best direction is the one causing most lines to be bridged (thus most coverage)
# and shortest max line length
my @sorted_directions = sort {
my $cmp;
my $coverage_diff = $directions_coverage{$a} - $directions_coverage{$b};
if (abs($coverage_diff) < $self->extrusion_width) {
$cmp = $directions_avg_length{$b} <=> $directions_avg_length{$a};
} else {
$cmp = ($coverage_diff > 0) ? 1 : -1;
}
$cmp;
} keys %directions_coverage;
$self->angle($sorted_directions[-1]);
if ($self->angle >= PI) {
$self->angle($self->angle - PI);
}
Slic3r::debugf " Optimal infill angle is %d degrees\n", rad2deg($self->angle);
return $self->angle;
}
sub coverage {
my ($self, $angle) = @_;
if (!defined $angle) {
return [] if !defined($angle = $self->angle);
}
# Clone our expolygon and rotate it so that we work with vertical lines.
my $expolygon = $self->expolygon->clone;
$expolygon->rotate(PI/2 - $angle, [0,0]);
# Outset the bridge expolygon by half the amount we used for detecting anchors;
# we'll use this one to generate our trapezoids and be sure that their vertices
# are inside the anchors and not on their contours leading to false negatives.
my $grown = $expolygon->offset_ex(+$self->extrusion_width/2);
# Compute trapezoids according to a vertical orientation
my $trapezoids = [ map @{$_->get_trapezoids2(PI/2)}, @$grown ];
# get anchors and rotate them too
my $anchors = [ map $_->clone, @{$self->_anchors} ];
$_->rotate(PI/2 - $angle, [0,0]) for @$anchors;
my @covered = (); # polygons
foreach my $trapezoid (@$trapezoids) {
my @polylines = map $_->as_polyline, @{$trapezoid->lines};
my @supported = @{intersection_pl(\@polylines, [map @$_, @$anchors])};
# not nice, we need a more robust non-numeric check
@supported = grep $_->length >= $self->extrusion_width, @supported;
if (@supported >= 2) {
push @covered, $trapezoid;
}
}
# merge trapezoids and rotate them back
my $coverage = union(\@covered);
$_->rotate(-(PI/2 - $angle), [0,0]) for @$coverage;
# intersect trapezoids with actual bridge area to remove extra margins
$coverage = intersection_ex($coverage, [ @{$self->expolygon} ]);
if (0) {
my @lines = map @{$_->lines}, @$trapezoids;
$_->rotate(-(PI/2 - $angle), [0,0]) for @lines;
require "Slic3r/SVG.pm";
Slic3r::SVG::output(
"coverage_" . rad2deg($angle) . ".svg",
expolygons => [$self->expolygon],
green_expolygons => $self->_anchors,
red_expolygons => $coverage,
lines => \@lines,
);
}
return $coverage;
}
# this method returns the bridge edges (as polylines) that are not supported
# but would allow the entire bridge area to be bridged with detected angle
# if supported too
sub unsupported_edges {
my ($self, $angle) = @_;
if (!defined $angle) {
return [] if !defined($angle = $self->angle);
}
# get bridge edges (both contour and holes)
my @bridge_edges = map $_->split_at_first_point, @{$self->expolygon};
$_->[0]->translate(1,0) for @bridge_edges; # workaround for Clipper bug, see comments in Slic3r::Polygon::clip_as_polyline()
# get unsupported edges
my $grown_lower = offset([ map @$_, @{$self->lower_slices} ], +$self->extrusion_width);
my $unsupported = diff_pl(
\@bridge_edges,
$grown_lower,
);
# split into individual segments and filter out edges parallel to the bridging angle
# TODO: angle tolerance should probably be based on segment length and flow width,
# so that we build supports whenever there's a chance that at least one or two bridge
# extrusions would be anchored within such length (i.e. a slightly non-parallel bridging
# direction might still benefit from anchors if long enough)
my $angle_tolerance = PI/180*5;
@$unsupported = map $_->as_polyline,
grep !directions_parallel_within($_->direction, $angle, $angle_tolerance),
map @{$_->lines},
@$unsupported;
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output(
"unsupported_" . rad2deg($angle) . ".svg",
expolygons => [$self->expolygon],
green_expolygons => $self->_anchors,
red_expolygons => union_ex($grown_lower),
no_arrows => 1,
polylines => \@bridge_edges,
red_polylines => $unsupported,
);
}
return $unsupported;
}
1;

View File

@@ -1,556 +0,0 @@
package Slic3r::Layer::Region;
use strict;
use warnings;
use List::Util qw(sum first);
use Slic3r::ExtrusionLoop ':roles';
use Slic3r::ExtrusionPath ':roles';
use Slic3r::Flow ':roles';
use Slic3r::Geometry qw(PI A B scale unscale chained_path points_coincide);
use Slic3r::Geometry::Clipper qw(union_ex diff_ex intersection_ex
offset offset_ex offset2 offset2_ex union_pt diff intersection
union diff intersection_ppl diff_ppl);
use Slic3r::Surface ':types';
# TODO: lazy
sub infill_area_threshold {
my $self = shift;
return $self->flow(FLOW_ROLE_SOLID_INFILL)->scaled_spacing ** 2;
}
sub id { return $_[0]->layer->id; }
sub slice_z { return $_[0]->layer->slice_z; }
sub print_z { return $_[0]->layer->print_z; }
sub height { return $_[0]->layer->height; }
sub object { return $_[0]->layer->object; }
sub print { return $_[0]->layer->print; }
sub config { return $_[0]->region->config; }
sub merge_slices {
my ($self) = @_;
my $expolygons = union_ex([ map $_->p, @{$self->slices} ]);
$self->slices->clear;
$self->slices->append(Slic3r::Surface->new(
expolygon => $_,
surface_type => S_TYPE_INTERNAL,
)) for @$expolygons;
}
sub make_perimeters {
my ($self, $slices, $fill_surfaces) = @_;
# other perimeters
my $perimeter_flow = $self->flow(FLOW_ROLE_PERIMETER);
my $mm3_per_mm = $perimeter_flow->mm3_per_mm;
my $pwidth = $perimeter_flow->scaled_width;
my $pspacing = $perimeter_flow->scaled_spacing;
# external perimeters
my $ext_perimeter_flow = $self->flow(FLOW_ROLE_EXTERNAL_PERIMETER);
my $ext_mm3_per_mm = $ext_perimeter_flow->mm3_per_mm;
my $ext_pwidth = $ext_perimeter_flow->scaled_width;
my $ext_pspacing = scale($ext_perimeter_flow->spacing_to($perimeter_flow));
# overhang perimeters
my $overhang_flow = $self->region->flow(FLOW_ROLE_PERIMETER, -1, 1, 0, -1, $self->layer->object);
my $mm3_per_mm_overhang = $overhang_flow->mm3_per_mm;
# solid infill
my $solid_infill_flow = $self->flow(FLOW_ROLE_SOLID_INFILL);
my $ispacing = $solid_infill_flow->scaled_spacing;
my $gap_area_threshold = $pwidth ** 2;
# Calculate the minimum required spacing between two adjacent traces.
# This should be equal to the nominal flow spacing but we experiment
# with some tolerance in order to avoid triggering medial axis when
# some squishing might work. Loops are still spaced by the entire
# flow spacing; this only applies to collapsing parts.
my $min_spacing = $pspacing * (1 - &Slic3r::INSET_OVERLAP_TOLERANCE);
my $ext_min_spacing = $ext_pspacing * (1 - &Slic3r::INSET_OVERLAP_TOLERANCE);
$self->perimeters->clear;
$self->thin_fills->clear;
my @contours = (); # array of Polygons with ccw orientation
my @holes = (); # array of Polygons with cw orientation
my @thin_walls = (); # array of ExPolygons
# we need to process each island separately because we might have different
# extra perimeters for each one
foreach my $surface (@$slices) {
# detect how many perimeters must be generated for this island
my $loop_number = $self->config->perimeters + ($surface->extra_perimeters || 0);
my @last = @{$surface->expolygon};
my @gaps = (); # array of ExPolygons
if ($loop_number > 0) {
# we loop one time more than needed in order to find gaps after the last perimeter was applied
for my $i (1 .. ($loop_number+1)) { # outer loop is 1
my @offsets = ();
if ($i == 1) {
# the minimum thickness of a single loop is:
# ext_width/2 + ext_spacing/2 + spacing/2 + width/2
if ($self->config->thin_walls) {
@offsets = @{offset2(
\@last,
-(0.5*$ext_pwidth + 0.5*$ext_min_spacing - 1),
+(0.5*$ext_min_spacing - 1),
)};
} else {
@offsets = @{offset(
\@last,
-0.5*$ext_pwidth,
)};
}
# look for thin walls
if ($self->config->thin_walls) {
my $diff = diff_ex(
\@last,
offset(\@offsets, +0.5*$ext_pwidth),
1, # medial axis requires non-overlapping geometry
);
push @thin_walls, @$diff;
}
} else {
my $distance = ($i == 2) ? $ext_pspacing : $pspacing;
if ($self->config->thin_walls) {
@offsets = @{offset2(
\@last,
-($distance + 0.5*$min_spacing - 1),
+(0.5*$min_spacing - 1),
)};
} else {
@offsets = @{offset(
\@last,
-$distance,
)};
}
# look for gaps
if ($self->region->config->gap_fill_speed > 0 && $self->config->fill_density > 0) {
# not using safety offset here would "detect" very narrow gaps
# (but still long enough to escape the area threshold) that gap fill
# won't be able to fill but we'd still remove from infill area
my $diff = diff_ex(
offset(\@last, -0.5*$pspacing),
offset(\@offsets, +0.5*$pspacing + 10), # safety offset
);
push @gaps, grep abs($_->area) >= $gap_area_threshold, @$diff;
}
}
last if !@offsets;
last if $i > $loop_number; # we were only looking for gaps this time
# clone polygons because these ExPolygons will go out of scope very soon
@last = @offsets;
foreach my $polygon (@offsets) {
if ($polygon->is_counter_clockwise) {
push @contours, $polygon;
} else {
push @holes, $polygon;
}
}
}
}
# fill gaps
if (@gaps) {
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output(
"gaps.svg",
expolygons => \@gaps,
);
}
# where $pwidth < thickness < 2*$pspacing, infill with width = 1.5*$pwidth
# where 0.5*$pwidth < thickness < $pwidth, infill with width = 0.5*$pwidth
my @gap_sizes = (
[ $pwidth, 2*$pspacing, unscale 1.5*$pwidth ],
[ 0.5*$pwidth, $pwidth, unscale 0.5*$pwidth ],
);
foreach my $gap_size (@gap_sizes) {
my @gap_fill = $self->_fill_gaps(@$gap_size, \@gaps);
$self->thin_fills->append(@gap_fill);
# Make sure we don't infill narrow parts that are already gap-filled
# (we only consider this surface's gaps to reduce the diff() complexity).
# Growing actual extrusions ensures that gaps not filled by medial axis
# are not subtracted from fill surfaces (they might be too short gaps
# that medial axis skips but infill might join with other infill regions
# and use zigzag).
my $w = $gap_size->[2];
my @filled = map {
@{($_->isa('Slic3r::ExtrusionLoop') ? $_->polygon->split_at_first_point : $_->polyline)
->grow(scale $w/2)};
} @gap_fill;
@last = @{diff(\@last, \@filled)};
}
}
# create one more offset to be used as boundary for fill
# we offset by half the perimeter spacing (to get to the actual infill boundary)
# and then we offset back and forth by half the infill spacing to only consider the
# non-collapsing regions
my $min_perimeter_infill_spacing = $ispacing * (1 - &Slic3r::INSET_OVERLAP_TOLERANCE);
$fill_surfaces->append(
map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_INTERNAL), # use a bogus surface type
@{offset2_ex(
[ map @{$_->simplify_p(&Slic3r::SCALED_RESOLUTION)}, @{union_ex(\@last)} ],
-($pspacing/2 + $min_perimeter_infill_spacing/2),
+$min_perimeter_infill_spacing/2,
)}
);
}
# process thin walls by collapsing slices to single passes
my @thin_wall_polylines = ();
if (@thin_walls) {
# the following offset2 ensures almost nothing in @thin_walls is narrower than $min_width
# (actually, something larger than that still may exist due to mitering or other causes)
my $min_width = $pwidth / 4;
@thin_walls = @{offset2_ex([ map @$_, @thin_walls ], -$min_width/2, +$min_width/2)};
# the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
@thin_wall_polylines = map @{$_->medial_axis($pwidth + $pspacing, $min_width)}, @thin_walls;
Slic3r::debugf " %d thin walls detected\n", scalar(@thin_wall_polylines) if $Slic3r::debug;
if (0) {
require "Slic3r/SVG.pm";
Slic3r::SVG::output(
"medial_axis.svg",
no_arrows => 1,
expolygons => \@thin_walls,
green_polylines => [ map $_->polygon->split_at_first_point, @{$self->perimeters} ],
red_polylines => \@thin_wall_polylines,
);
}
}
# find nesting hierarchies separately for contours and holes
my $contours_pt = union_pt(\@contours);
my $holes_pt = union_pt(\@holes);
# prepare grown lower layer slices for overhang detection
my $lower_slices = Slic3r::ExPolygon::Collection->new;
if ($self->layer->lower_layer && $self->region->config->overhangs) {
# We consider overhang any part where the entire nozzle diameter is not supported by the
# lower layer, so we take lower slices and offset them by half the nozzle diameter used
# in the current layer
my $nozzle_diameter = $self->layer->print->config->get_at('nozzle_diameter', $self->region->config->perimeter_extruder-1);
$lower_slices->append(
@{offset_ex([ map @$_, @{$self->layer->lower_layer->slices} ], scale +$nozzle_diameter/2)},
);
}
my $lower_slices_p = $lower_slices->polygons;
# prepare a coderef for traversing the PolyTree object
# external contours are root items of $contours_pt
# internal contours are the ones next to external
my $traverse;
$traverse = sub {
my ($polynodes, $depth, $is_contour) = @_;
# convert all polynodes to ExtrusionLoop objects
my $collection = Slic3r::ExtrusionPath::Collection->new;
my @children = ();
foreach my $polynode (@$polynodes) {
my $polygon = ($polynode->{outer} // $polynode->{hole})->clone;
my $role = EXTR_ROLE_PERIMETER;
my $loop_role = EXTRL_ROLE_DEFAULT;
my $root_level = $depth == 0;
my $no_children = !@{ $polynode->{children} };
my $is_external = $is_contour ? $root_level : $no_children;
my $is_internal = $is_contour ? $no_children : $root_level;
if ($is_external) {
# external perimeters are root level in case of contours
# and items with no children in case of holes
$role = EXTR_ROLE_EXTERNAL_PERIMETER;
$loop_role = EXTRL_ROLE_EXTERNAL_PERIMETER;
} elsif ($is_contour && $is_internal) {
# internal perimeters are root level in case of holes
# and items with no children in case of contours
$loop_role = EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER;
}
# detect overhanging/bridging perimeters
my @paths = ();
if ($self->region->config->overhangs && $lower_slices->count > 0) {
# get non-overhang paths by intersecting this loop with the grown lower slices
foreach my $polyline (@{ intersection_ppl([ $polygon ], $lower_slices_p) }) {
push @paths, Slic3r::ExtrusionPath->new(
polyline => $polyline,
role => $role,
mm3_per_mm => ($is_external ? $ext_mm3_per_mm : $mm3_per_mm),
width => ($is_external ? $ext_perimeter_flow->width : $perimeter_flow->width),
height => $self->height,
);
}
# get overhang paths by checking what parts of this loop fall
# outside the grown lower slices (thus where the distance between
# the loop centerline and original lower slices is >= half nozzle diameter
foreach my $polyline (@{ diff_ppl([ $polygon ], $lower_slices_p) }) {
push @paths, Slic3r::ExtrusionPath->new(
polyline => $polyline,
role => EXTR_ROLE_OVERHANG_PERIMETER,
mm3_per_mm => $mm3_per_mm_overhang,
width => $overhang_flow->width,
height => $self->height,
);
}
# reapply the nearest point search for starting point
# (clone because the collection gets DESTROY'ed)
# We allow polyline reversal because Clipper may have randomly
# reversed polylines during clipping.
my $collection = Slic3r::ExtrusionPath::Collection->new(@paths);
@paths = map $_->clone, @{$collection->chained_path(0)};
} else {
push @paths, Slic3r::ExtrusionPath->new(
polyline => $polygon->split_at_first_point,
role => $role,
mm3_per_mm => $mm3_per_mm,
width => $perimeter_flow->width,
height => $self->height,
);
}
my $loop = Slic3r::ExtrusionLoop->new_from_paths(@paths);
$loop->role($loop_role);
# return ccw contours and cw holes
# GCode.pm will convert all of them to ccw, but it needs to know
# what the holes are in order to compute the correct inwards move
# We do this on the final Loop object instead of the polygon because
# overhang clipping might have reversed its order since Clipper does
# not preserve polyline orientation.
if ($is_contour) {
$loop->make_counter_clockwise;
} else {
$loop->make_clockwise;
}
$collection->append($loop);
# save the children
push @children, $polynode->{children};
}
# if we're handling the top-level contours, add thin walls as candidates too
# in order to include them in the nearest-neighbor search
if ($is_contour && $depth == 0) {
foreach my $polyline (@thin_wall_polylines) {
$collection->append(Slic3r::ExtrusionPath->new(
polyline => $polyline,
role => EXTR_ROLE_EXTERNAL_PERIMETER,
mm3_per_mm => $mm3_per_mm,
width => $perimeter_flow->width,
height => $self->height,
));
}
}
# use a nearest neighbor search to order these children
# TODO: supply second argument to chained_path() too?
# Optimization: since islands are going to be sorted by slice anyway in the
# G-code export process, we skip chained_path here
my ($sorted_collection, @orig_indices);
if ($is_contour && $depth == 0) {
$sorted_collection = $collection;
@orig_indices = (0..$#$sorted_collection);
} else {
$sorted_collection = $collection->chained_path_indices(0);
@orig_indices = @{$sorted_collection->orig_indices};
}
my @loops = ();
foreach my $loop (@$sorted_collection) {
my $orig_index = shift @orig_indices;
if ($loop->isa('Slic3r::ExtrusionPath')) {
push @loops, $loop->clone;
} else {
# if this is an external contour find all holes belonging to this contour(s)
# and prepend them
if ($is_contour && $depth == 0) {
# $loop is the outermost loop of an island
my @holes = ();
for (my $i = 0; $i <= $#$holes_pt; $i++) {
if ($loop->polygon->contains_point($holes_pt->[$i]{outer}->first_point)) {
push @holes, splice @$holes_pt, $i, 1; # remove from candidates to reduce complexity
$i--;
}
}
# order holes efficiently
@holes = @holes[@{chained_path([ map {($_->{outer} // $_->{hole})->first_point} @holes ])}];
push @loops, reverse map $traverse->([$_], 0, 0), @holes;
}
# traverse children and prepend them to this loop
push @loops, $traverse->($children[$orig_index], $depth+1, $is_contour);
push @loops, $loop->clone;
}
}
return @loops;
};
# order loops from inner to outer (in terms of object slices)
my @loops = $traverse->($contours_pt, 0, 1);
# if brim will be printed, reverse the order of perimeters so that
# we continue inwards after having finished the brim
# TODO: add test for perimeter order
@loops = reverse @loops
if $self->region->config->external_perimeters_first
|| ($self->layer->id == 0 && $self->print->config->brim_width > 0);
# append perimeters
$self->perimeters->append(@loops);
}
sub _fill_gaps {
my ($self, $min, $max, $w, $gaps) = @_;
my $this = diff_ex(
offset2([ map @$_, @$gaps ], -$min/2, +$min/2),
offset2([ map @$_, @$gaps ], -$max/2, +$max/2),
1,
);
my $flow = $self->flow(FLOW_ROLE_SOLID_INFILL, 0, $w);
my %path_args = (
role => EXTR_ROLE_GAPFILL,
mm3_per_mm => $flow->mm3_per_mm,
width => $flow->width,
height => $self->height,
);
my @polylines = map @{$_->medial_axis($max, $min/2)}, @$this;
Slic3r::debugf " %d gaps filled with extrusion width = %s\n", scalar @$this, $w
if @$this;
for my $i (0..$#polylines) {
if ($polylines[$i]->isa('Slic3r::Polygon')) {
my $loop = Slic3r::ExtrusionLoop->new;
$loop->append(Slic3r::ExtrusionPath->new(polyline => $polylines[$i]->split_at_first_point, %path_args));
$polylines[$i] = $loop;
} elsif ($polylines[$i]->is_valid && $polylines[$i]->first_point->coincides_with($polylines[$i]->last_point)) {
# since medial_axis() now returns only Polyline objects, detect loops here
my $loop = Slic3r::ExtrusionLoop->new;
$loop->append(Slic3r::ExtrusionPath->new(polyline => $polylines[$i], %path_args));
$polylines[$i] = $loop;
} else {
$polylines[$i] = Slic3r::ExtrusionPath->new(polyline => $polylines[$i], %path_args);
}
}
return @polylines;
}
sub prepare_fill_surfaces {
my $self = shift;
# Note: in order to make the psPrepareInfill step idempotent, we should never
# alter fill_surfaces boundaries on which our idempotency relies since that's
# the only meaningful information returned by psPerimeters.
# if no solid layers are requested, turn top/bottom surfaces to internal
if ($self->config->top_solid_layers == 0) {
$_->surface_type(S_TYPE_INTERNAL) for @{$self->fill_surfaces->filter_by_type(S_TYPE_TOP)};
}
if ($self->config->bottom_solid_layers == 0) {
$_->surface_type(S_TYPE_INTERNAL)
for @{$self->fill_surfaces->filter_by_type(S_TYPE_BOTTOM)}, @{$self->fill_surfaces->filter_by_type(S_TYPE_BOTTOMBRIDGE)};
}
# turn too small internal regions into solid regions according to the user setting
if ($self->config->fill_density > 0) {
my $min_area = scale scale $self->config->solid_infill_below_area; # scaling an area requires two calls!
$_->surface_type(S_TYPE_INTERNALSOLID)
for grep { $_->area <= $min_area } @{$self->fill_surfaces->filter_by_type(S_TYPE_INTERNAL)};
}
}
sub process_external_surfaces {
my ($self, $lower_layer) = @_;
my @surfaces = @{$self->fill_surfaces};
my $margin = scale &Slic3r::EXTERNAL_INFILL_MARGIN;
my @bottom = ();
foreach my $surface (grep $_->is_bottom, @surfaces) {
my $grown = $surface->expolygon->offset_ex(+$margin);
# detect bridge direction before merging grown surfaces otherwise adjacent bridges
# would get merged into a single one while they need different directions
# also, supply the original expolygon instead of the grown one, because in case
# of very thin (but still working) anchors, the grown expolygon would go beyond them
my $angle;
if ($lower_layer) {
my $bridge_detector = Slic3r::Layer::BridgeDetector->new(
expolygon => $surface->expolygon,
lower_slices => $lower_layer->slices,
extrusion_width => $self->flow(FLOW_ROLE_INFILL, $self->height, 1)->scaled_width,
);
Slic3r::debugf "Processing bridge at layer %d:\n", $self->id;
$angle = $bridge_detector->detect_angle;
if (defined $angle && $self->object->config->support_material) {
$self->bridged->append(@{ $bridge_detector->coverage($angle) });
$self->unsupported_bridge_edges->append(@{ $bridge_detector->unsupported_edges });
}
}
push @bottom, map $surface->clone(expolygon => $_, bridge_angle => $angle), @$grown;
}
my @top = ();
foreach my $surface (grep $_->surface_type == S_TYPE_TOP, @surfaces) {
# give priority to bottom surfaces
my $grown = diff_ex(
$surface->expolygon->offset(+$margin),
[ map $_->p, @bottom ],
);
push @top, map $surface->clone(expolygon => $_), @$grown;
}
# if we're slicing with no infill, we can't extend external surfaces
# over non-existent infill
my @fill_boundaries = $self->config->fill_density > 0
? @surfaces
: grep $_->surface_type != S_TYPE_INTERNAL, @surfaces;
# intersect the grown surfaces with the actual fill boundaries
my @new_surfaces = ();
foreach my $group (@{Slic3r::Surface::Collection->new(@top, @bottom)->group}) {
push @new_surfaces,
map $group->[0]->clone(expolygon => $_),
@{intersection_ex(
[ map $_->p, @$group ],
[ map $_->p, @fill_boundaries ],
1, # to ensure adjacent expolygons are unified
)};
}
# subtract the new top surfaces from the other non-top surfaces and re-add them
my @other = grep $_->surface_type != S_TYPE_TOP && !$_->is_bottom, @surfaces;
foreach my $group (@{Slic3r::Surface::Collection->new(@other)->group}) {
push @new_surfaces, map $group->[0]->clone(expolygon => $_), @{diff_ex(
[ map $_->p, @$group ],
[ map $_->p, @new_surfaces ],
)};
}
$self->fill_surfaces->clear;
$self->fill_surfaces->append(@new_surfaces);
}
1;

View File

@@ -5,8 +5,6 @@ use warnings;
# a line is a two-points line
use parent 'Slic3r::Polyline';
use Slic3r::Geometry qw(A B X Y);
sub intersection {
my $self = shift;
my ($line, $require_crossing) = @_;

View File

@@ -1,20 +1,7 @@
# extends C++ class Slic3r::Model
package Slic3r::Model;
use List::Util qw(first max);
use Slic3r::Geometry qw(X Y Z move_points);
sub read_from_file {
my $class = shift;
my ($input_file) = @_;
my $model = $input_file =~ /\.stl$/i ? Slic3r::Format::STL->read_file($input_file)
: $input_file =~ /\.obj$/i ? Slic3r::Format::OBJ->read_file($input_file)
: $input_file =~ /\.amf(\.xml)?$/i ? Slic3r::Format::AMF->read_file($input_file)
: die "Input file must have .stl, .obj or .amf(.xml) extension\n";
$_->set_input_file($input_file) for @{$model->objects};
return $model;
}
use List::Util qw(first max any);
sub merge {
my $class = shift;
@@ -64,158 +51,7 @@ sub set_material {
return $material;
}
sub duplicate_objects_grid {
my ($self, $grid, $distance) = @_;
die "Grid duplication is not supported with multiple objects\n"
if @{$self->objects} > 1;
my $object = $self->objects->[0];
$object->clear_instances;
my $size = $object->bounding_box->size;
for my $x_copy (1..$grid->[X]) {
for my $y_copy (1..$grid->[Y]) {
$object->add_instance(
offset => Slic3r::Pointf->new(
($size->[X] + $distance) * ($x_copy-1),
($size->[Y] + $distance) * ($y_copy-1),
),
);
}
}
}
# this will append more instances to each object
# and then automatically rearrange everything
sub duplicate_objects {
my ($self, $copies_num, $distance, $bb) = @_;
foreach my $object (@{$self->objects}) {
my @instances = @{$object->instances};
foreach my $instance (@instances) {
$object->add_instance($instance) for 2..$copies_num;
}
}
$self->arrange_objects($distance, $bb);
}
# arrange objects preserving their instance count
# but altering their instance positions
sub arrange_objects {
my ($self, $distance, $bb) = @_;
# get the (transformed) size of each instance so that we take
# into account their different transformations when packing
my @instance_sizes = ();
foreach my $object (@{$self->objects}) {
push @instance_sizes, map $object->instance_bounding_box($_)->size, 0..$#{$object->instances};
}
my @positions = $self->_arrange(\@instance_sizes, $distance, $bb);
foreach my $object (@{$self->objects}) {
$_->set_offset(Slic3r::Pointf->new(@{shift @positions})) for @{$object->instances};
$object->update_bounding_box;
}
}
# duplicate the entire model preserving instance relative positions
sub duplicate {
my ($self, $copies_num, $distance, $bb) = @_;
my $model_size = $self->bounding_box->size;
my @positions = $self->_arrange([ map $model_size, 2..$copies_num ], $distance, $bb);
# note that this will leave the object count unaltered
foreach my $object (@{$self->objects}) {
my @instances = @{$object->instances}; # store separately to avoid recursion from add_instance() below
foreach my $instance (@instances) {
foreach my $pos (@positions) {
$object->add_instance(
offset => Slic3r::Pointf->new($instance->offset->[X] + $pos->[X], $instance->offset->[Y] + $pos->[Y]),
rotation => $instance->rotation,
scaling_factor => $instance->scaling_factor,
);
}
}
$object->update_bounding_box;
}
}
sub _arrange {
my ($self, $sizes, $distance, $bb) = @_;
# we supply unscaled data to arrange()
return Slic3r::Geometry::arrange(
scalar(@$sizes), # number of parts
max(map $_->x, @$sizes), # cell width
max(map $_->y, @$sizes), # cell height ,
$distance, # distance between cells
$bb, # bounding box of the area to fill (can be undef)
);
}
# this method splits objects into multiple distinct objects by walking their meshes
sub split_meshes {
my $self = shift;
my @objects = @{$self->objects};
@{$self->objects} = ();
foreach my $object (@objects) {
if (@{$object->volumes} > 1) {
# We can't split meshes if there's more than one material, because
# we can't group the resulting meshes by object afterwards
$self->_add_object($object);
next;
}
my $volume = $object->volumes->[0];
foreach my $mesh (@{$volume->mesh->split}) {
my $new_object = $self->add_object(
input_file => $object->input_file,
config => $object->config->clone,
layer_height_ranges => $object->layer_height_ranges, # TODO: this needs to be cloned
origin_translation => $object->origin_translation,
);
$new_object->add_volume(
mesh => $mesh,
name => $volume->name,
material_id => $volume->material_id,
config => $volume->config,
);
# add one instance per original instance
$new_object->add_instance(
offset => Slic3r::Pointf->new(@{$_->offset}),
rotation => $_->rotation,
scaling_factor => $_->scaling_factor,
) for @{ $object->instances // [] };
}
}
}
sub print_info {
my $self = shift;
$_->print_info for @{$self->objects};
}
sub get_material_name {
my $self = shift;
my ($material_id) = @_;
my $name;
if ($self->has_material($material_id)) {
$name //= $self->get_material($material_id)
->attributes->{$_} for qw(Name name);
}
$name //= $material_id;
return $name;
}
# Extends C++ class Slic3r::ModelMaterial
package Slic3r::Model::Material;
sub apply {
@@ -223,11 +59,10 @@ sub apply {
$self->set_attribute($_, $attributes{$_}) for keys %$attributes;
}
# Extends C++ class Slic3r::ModelObject
package Slic3r::Model::Object;
use File::Basename qw(basename);
use List::Util qw(first sum);
use Slic3r::Geometry qw(X Y Z rad2deg);
sub add_volume {
my $self = shift;
@@ -277,7 +112,6 @@ sub add_volume {
sub add_instance {
my $self = shift;
my %params = @_;
if (@_ == 1) {
# we have a Model::Instance
@@ -299,35 +133,6 @@ sub add_instance {
}
}
sub rotate {
my ($self, $angle, $axis) = @_;
# we accept angle in radians but mesh currently uses degrees
$angle = rad2deg($angle);
if ($axis == X) {
$_->mesh->rotate_x($angle) for @{$self->volumes};
} elsif ($axis == Y) {
$_->mesh->rotate_y($angle) for @{$self->volumes};
} elsif ($axis == Z) {
$_->mesh->rotate_z($angle) for @{$self->volumes};
}
$self->invalidate_bounding_box;
}
sub flip {
my ($self, $axis) = @_;
if ($axis == X) {
$_->mesh->flip_x for @{$self->volumes};
} elsif ($axis == Y) {
$_->mesh->flip_y for @{$self->volumes};
} elsif ($axis == Z) {
$_->mesh->flip_z for @{$self->volumes};
}
$self->invalidate_bounding_box;
}
sub mesh_stats {
my $self = shift;
@@ -335,29 +140,4 @@ sub mesh_stats {
return $self->volumes->[0]->mesh->stats;
}
sub print_info {
my $self = shift;
printf "Info about %s:\n", basename($self->input_file);
printf " size: x=%.3f y=%.3f z=%.3f\n", @{$self->raw_mesh->bounding_box->size};
if (my $stats = $self->mesh_stats) {
printf " number of facets: %d\n", $stats->{number_of_facets};
printf " number of shells: %d\n", $stats->{number_of_parts};
printf " volume: %.3f\n", $stats->{volume};
if ($self->needed_repair) {
printf " needed repair: yes\n";
printf " degenerate facets: %d\n", $stats->{degenerate_facets};
printf " edges fixed: %d\n", $stats->{edges_fixed};
printf " facets removed: %d\n", $stats->{facets_removed};
printf " facets added: %d\n", $stats->{facets_added};
printf " facets reversed: %d\n", $stats->{facets_reversed};
printf " backwards edges: %d\n", $stats->{backwards_edges};
} else {
printf " needed repair: no\n";
}
} else {
printf " number of facets: %d\n", scalar(map @{$_->facets}, grep !$_->modifier, @{$self->volumes});
}
}
1;

View File

@@ -7,4 +7,27 @@ sub new_scale {
return $class->new(map Slic3r::Geometry::scale($_), @_);
}
sub dump_perl {
my $self = shift;
return sprintf "[%s,%s]", @$self;
}
package Slic3r::Pointf;
use strict;
use warnings;
sub new_unscale {
my $class = shift;
return $class->new(map Slic3r::Geometry::unscale($_), @_);
}
package Slic3r::Pointf3;
use strict;
use warnings;
sub new_unscale {
my $class = shift;
return $class->new(map Slic3r::Geometry::unscale($_), @_);
}
1;

View File

@@ -5,91 +5,9 @@ use warnings;
# a polygon is a closed polyline.
use parent 'Slic3r::Polyline';
use Slic3r::Geometry qw(
polygon_segment_having_point
PI X1 X2 Y1 Y2 epsilon scaled_epsilon);
use Slic3r::Geometry::Clipper qw(intersection_pl);
sub wkt {
my $self = shift;
return sprintf "POLYGON((%s))", join ',', map "$_->[0] $_->[1]", @$self;
}
sub dump_perl {
my $self = shift;
return sprintf "[%s]", join ',', map "[$_->[0],$_->[1]]", @$self;
}
sub grow {
my $self = shift;
return $self->split_at_first_point->grow(@_);
}
# this method subdivides the polygon segments to that no one of them
# is longer than the length provided
sub subdivide {
my $self = shift;
my ($max_length) = @_;
my @points = @$self;
push @points, $points[0]; # append first point as this is a polygon
my @new_points = shift @points;
while (@points) {
while ($new_points[-1]->distance_to($points[0]) > $max_length) {
push @new_points, map Slic3r::Point->new(@$_),
Slic3r::Geometry::point_along_segment($new_points[-1], $points[0], $max_length);
}
push @new_points, shift @points;
}
pop @new_points; # remove last point as it coincides with first one
return Slic3r::Polygon->new(@new_points);
}
sub concave_points {
my ($self, $angle) = @_;
$angle //= PI;
# input angle threshold is checked on the internal side of the polygon
# but angle3points measures CCW angle, so we calculate the complementary angle
my $ccw_angle = 2*PI-$angle;
my @concave = ();
my @points = @$self;
my @points_pp = @{$self->pp};
for my $i (-1 .. ($#points-1)) {
# angle is measured in ccw orientation
my $vertex_angle = Slic3r::Geometry::angle3points(@points_pp[$i, $i-1, $i+1]);
if ($vertex_angle <= $ccw_angle) {
push @concave, $points[$i];
}
}
return [@concave];
}
sub convex_points {
my ($self, $angle) = @_;
$angle //= PI;
# input angle threshold is checked on the internal side of the polygon
# but angle3points measures CCW angle, so we calculate the complementary angle
my $ccw_angle = 2*PI-$angle;
my @convex = ();
my @points = @$self;
my @points_pp = @{$self->pp};
for my $i (-1 .. ($#points-1)) {
# angle is measured in ccw orientation
my $vertex_angle = Slic3r::Geometry::angle3points(@points_pp[$i, $i-1, $i+1]);
if ($vertex_angle >= $ccw_angle) {
push @convex, $points[$i];
}
}
return [@convex];
}
1;

View File

@@ -2,9 +2,7 @@ package Slic3r::Polyline;
use strict;
use warnings;
use List::Util qw(first);
use Slic3r::Geometry qw(X Y PI epsilon);
use Slic3r::Geometry::Clipper qw(JT_SQUARE);
use Slic3r::Geometry qw(X Y);
sub new_scale {
my $class = shift;
@@ -12,29 +10,9 @@ sub new_scale {
return $class->new(map [ Slic3r::Geometry::scale($_->[X]), Slic3r::Geometry::scale($_->[Y]) ], @points);
}
sub wkt {
sub dump_perl {
my $self = shift;
return sprintf "LINESTRING((%s))", join ',', map "$_->[0] $_->[1]", @$self;
}
sub bounding_box {
my $self = shift;
return Slic3r::Geometry::BoundingBox->new_from_points([ @$self ]);
}
sub size {
my $self = shift;
return [ Slic3r::Geometry::size_2D($self) ];
}
sub is_straight {
my ($self) = @_;
# Check that each segment's direction is equal to the line connecting
# first point and last point. (Checking each line against the previous
# one would have caused the error to accumulate.)
my $dir = Slic3r::Line->new($self->first_point, $self->last_point)->direction;
return !defined first { !$_->parallel_to($dir) } @{$self->lines};
return sprintf "[%s]", join ',', map "[$_->[0],$_->[1]]", @$self;
}
1;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More