mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-09-26 21:23:16 +08:00
Merge branch 'master' into fs_svg
This commit is contained in:
commit
bc51ad7525
@ -1,3 +1,7 @@
|
|||||||
|
min_slic3r_version = 2.6.0-alpha4
|
||||||
|
0.2.4 Enable pad for Anycubic SLA profiles
|
||||||
|
0.2.3 Added Photon Mono printer.
|
||||||
|
0.2.2 Added Photon Mono SE printer.
|
||||||
min_slic3r_version = 2.6.0-alpha2
|
min_slic3r_version = 2.6.0-alpha2
|
||||||
0.2.1 Added Eolas Prints filaments.
|
0.2.1 Added Eolas Prints filaments.
|
||||||
0.2.0 Added Photon Mono X printer.
|
0.2.0 Added Photon Mono X printer.
|
||||||
|
@ -73,6 +73,13 @@ technology = FFF
|
|||||||
family = PREDATOR
|
family = PREDATOR
|
||||||
default_materials = Generic PLA @PREDATOR; Generic PETG @PREDATOR; Generic ABS @PREDATOR
|
default_materials = Generic PLA @PREDATOR; Generic PETG @PREDATOR; Generic ABS @PREDATOR
|
||||||
|
|
||||||
|
[printer_model:PHOTON MONO]
|
||||||
|
name = Photon Mono
|
||||||
|
variants = default
|
||||||
|
technology = SLA
|
||||||
|
family = PHOTON MONO
|
||||||
|
default_materials = Generic Blue Resin @MONO 0.05
|
||||||
|
|
||||||
[printer_model:PHOTON MONO X]
|
[printer_model:PHOTON MONO X]
|
||||||
name = Photon Mono X
|
name = Photon Mono X
|
||||||
variants = default
|
variants = default
|
||||||
@ -80,6 +87,13 @@ technology = SLA
|
|||||||
family = PHOTON MONO
|
family = PHOTON MONO
|
||||||
default_materials = Generic Blue Resin @MONO 0.05
|
default_materials = Generic Blue Resin @MONO 0.05
|
||||||
|
|
||||||
|
[printer_model:PHOTON MONO SE]
|
||||||
|
name = Photon Mono SE
|
||||||
|
variants = default
|
||||||
|
technology = SLA
|
||||||
|
family = PHOTON MONO
|
||||||
|
default_materials = Generic Blue Resin @MONO 0.05
|
||||||
|
|
||||||
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
# All presets starting with asterisk, for example *common*, are intermediate and they will
|
||||||
# not make it into the user interface.
|
# not make it into the user interface.
|
||||||
|
|
||||||
@ -2327,11 +2341,10 @@ z_offset = 0
|
|||||||
## SLA printers
|
## SLA printers
|
||||||
|
|
||||||
[sla_print:*common print ANYCUBIC SLA*]
|
[sla_print:*common print ANYCUBIC SLA*]
|
||||||
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
compatible_printers_condition = printer_notes=~/.*VENDOR_ANYCUBIC.*/ and printer_notes=~/.*SLA.*/
|
||||||
layer_height = 0.05
|
layer_height = 0.05
|
||||||
output_filename_format = [input_filename_base].pwmx
|
|
||||||
pad_edge_radius = 0.5
|
pad_edge_radius = 0.5
|
||||||
pad_enable = 0
|
pad_enable = 1
|
||||||
pad_max_merge_distance = 50
|
pad_max_merge_distance = 50
|
||||||
pad_wall_height = 0
|
pad_wall_height = 0
|
||||||
pad_wall_thickness = 1
|
pad_wall_thickness = 1
|
||||||
@ -2355,20 +2368,38 @@ support_pillar_widening_factor = 0
|
|||||||
supports_enable = 1
|
supports_enable = 1
|
||||||
support_small_pillar_diameter_percent = 60%
|
support_small_pillar_diameter_percent = 60%
|
||||||
|
|
||||||
[sla_print:0.05 Normal @ANYCUBIC]
|
[sla_print:0.05 Normal @ANYCUBIC ABSTRACT]
|
||||||
inherits = *common print ANYCUBIC SLA*
|
inherits = *common print ANYCUBIC SLA*
|
||||||
|
compatible_printers_condition = printer_notes=~/.*ABSTRACT_ONLY.*/
|
||||||
layer_height = 0.05
|
layer_height = 0.05
|
||||||
|
|
||||||
|
[sla_print:0.05 Normal @ANYCUBIC MONO]
|
||||||
|
inherits = 0.05 Normal @ANYCUBIC ABSTRACT
|
||||||
|
compatible_printers_condition = printer_notes=~/.*PHOTONMONO\n.*/
|
||||||
|
output_filename_format = [input_filename_base].pwmo
|
||||||
|
|
||||||
|
[sla_print:0.05 Normal @ANYCUBIC MONO X]
|
||||||
|
inherits = 0.05 Normal @ANYCUBIC ABSTRACT
|
||||||
|
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX\n.*/
|
||||||
|
output_filename_format = [input_filename_base].pwmx
|
||||||
|
|
||||||
|
[sla_print:0.05 Normal @ANYCUBIC MONO SE]
|
||||||
|
inherits = 0.05 Normal @ANYCUBIC ABSTRACT
|
||||||
|
compatible_printers_condition = printer_notes=~/.*PHOTONMONOSE\n.*/
|
||||||
|
output_filename_format = [input_filename_base].pwma
|
||||||
|
|
||||||
|
|
||||||
## SLA materials
|
## SLA materials
|
||||||
|
|
||||||
|
#MONO series printer need a significantly reduced exposure time but are otherwise compatible
|
||||||
[sla_material:*common ANYCUBIC SLA*]
|
[sla_material:*common ANYCUBIC SLA*]
|
||||||
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
compatible_printers_condition = printer_notes=~/.*VENDOR_ANYCUBIC.*/ and printer_notes=~/.*SLA.*/
|
||||||
compatible_prints_condition = layer_height == 0.05
|
compatible_prints_condition = layer_height == 0.05
|
||||||
exposure_time = 7
|
exposure_time = 7
|
||||||
initial_exposure_time = 40
|
initial_exposure_time = 40
|
||||||
initial_layer_height = 0.05
|
initial_layer_height = 0.05
|
||||||
material_correction = 1,1,1
|
material_correction = 1,1,1
|
||||||
material_notes = LIFT_DISTANCE=8.0\nLIFT_SPEED=2.5\nRETRACT_SPEED=3.0\nBOTTOM_LIFT_SPEED=2.0\nBOTTOM_LIFT_DISTANCE=9.0\nDELAY_BEFORE_EXPOSURE=0.5
|
material_notes = #Distances are defined in mm, speeds are defined in mm/s.\n#Delay is defined in s.\nLIFT_DISTANCE=8.0\nLIFT_SPEED=2.5\nRETRACT_SPEED=3.0\nBOTTOM_LIFT_SPEED=2.0\nBOTTOM_LIFT_DISTANCE=9.0\nDELAY_BEFORE_EXPOSURE=0.5\nANTIALIASING=1
|
||||||
|
|
||||||
[sla_material:*common 0.05 ANYCUBIC SLA*]
|
[sla_material:*common 0.05 ANYCUBIC SLA*]
|
||||||
inherits = *common ANYCUBIC SLA*
|
inherits = *common ANYCUBIC SLA*
|
||||||
@ -2380,10 +2411,66 @@ initial_exposure_time = 40
|
|||||||
material_type = Tough
|
material_type = Tough
|
||||||
material_vendor = Generic
|
material_vendor = Generic
|
||||||
material_colour = #6080EC
|
material_colour = #6080EC
|
||||||
compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
|
compatible_printers_condition = printer_notes=~/.*MONO.*/ and printer_notes=~/.*VENDOR_ANYCUBIC.*/ and printer_notes=~/.*SLA.*/
|
||||||
|
|
||||||
## Printers
|
## Printers
|
||||||
|
|
||||||
|
[printer:Anycubic Photon Mono]
|
||||||
|
printer_technology = SLA
|
||||||
|
printer_model = PHOTON MONO
|
||||||
|
printer_variant = default
|
||||||
|
default_sla_material_profile = Generic Blue Resin @MONO 0.05
|
||||||
|
default_sla_print_profile = 0.05 Normal @ANYCUBIC
|
||||||
|
thumbnails = 224x168
|
||||||
|
sla_archive_format = pwmo
|
||||||
|
bed_shape = 0x0,82.62x0,82.62x130.56,0x130.56
|
||||||
|
display_orientation = landscape
|
||||||
|
display_mirror_x = 1
|
||||||
|
display_mirror_y = 0
|
||||||
|
display_pixels_x = 1620
|
||||||
|
display_pixels_y = 2560
|
||||||
|
display_width = 82.62
|
||||||
|
display_height = 130.56
|
||||||
|
max_print_height = 165
|
||||||
|
elefant_foot_compensation = 0.2
|
||||||
|
elefant_foot_min_width = 0.2
|
||||||
|
min_exposure_time = 0.8
|
||||||
|
max_exposure_time = 120
|
||||||
|
min_initial_exposure_time = 0.8
|
||||||
|
max_initial_exposure_time = 300
|
||||||
|
printer_correction = 1,1,1
|
||||||
|
gamma_correction = 1
|
||||||
|
area_fill = 50
|
||||||
|
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.'\nPRINTER_VENDOR_ANYCUBIC\nPRINTER_MODEL_PHOTONMONO\nPRINTER_TECHNOLOGY_SLA\n
|
||||||
|
|
||||||
|
[printer:Anycubic Photon Mono SE]
|
||||||
|
printer_technology = SLA
|
||||||
|
printer_model = PHOTON MONO SE
|
||||||
|
printer_variant = default
|
||||||
|
default_sla_material_profile = Generic Blue Resin @MONO 0.05
|
||||||
|
default_sla_print_profile = 0.05 Normal @ANYCUBIC
|
||||||
|
thumbnails = 224x168
|
||||||
|
sla_archive_format = pwms
|
||||||
|
bed_shape = 0x0,82.62x0,82.62x130.56,0x130.56
|
||||||
|
display_orientation = landscape
|
||||||
|
display_mirror_x = 1
|
||||||
|
display_mirror_y = 0
|
||||||
|
display_pixels_x = 1620
|
||||||
|
display_pixels_y = 2560
|
||||||
|
display_width = 82.62
|
||||||
|
display_height = 130.56
|
||||||
|
max_print_height = 160
|
||||||
|
elefant_foot_compensation = 0.2
|
||||||
|
elefant_foot_min_width = 0.2
|
||||||
|
min_exposure_time = 0.8
|
||||||
|
max_exposure_time = 120
|
||||||
|
min_initial_exposure_time = 0.8
|
||||||
|
max_initial_exposure_time = 300
|
||||||
|
printer_correction = 1,1,1
|
||||||
|
gamma_correction = 1
|
||||||
|
area_fill = 45
|
||||||
|
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.'\nPRINTER_VENDOR_ANYCUBIC\nPRINTER_MODEL_PHOTONMONOSE\nPRINTER_TECHNOLOGY_SLA\n
|
||||||
|
|
||||||
[printer:Anycubic Photon Mono X]
|
[printer:Anycubic Photon Mono X]
|
||||||
printer_technology = SLA
|
printer_technology = SLA
|
||||||
printer_model = PHOTON MONO X
|
printer_model = PHOTON MONO X
|
||||||
@ -2410,4 +2497,4 @@ max_initial_exposure_time = 300
|
|||||||
printer_correction = 1,1,1
|
printer_correction = 1,1,1
|
||||||
gamma_correction = 1
|
gamma_correction = 1
|
||||||
area_fill = 45
|
area_fill = 45
|
||||||
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.'\nPRINTER_VENDOR_ANYCUBIC\nPRINTER_MODEL_PHOTONMONOX\n
|
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.'\nPRINTER_VENDOR_ANYCUBIC\nPRINTER_MODEL_PHOTONMONOX\nPRINTER_TECHNOLOGY_SLA\n
|
BIN
resources/profiles/Anycubic/PHOTON MONO SE_thumbnail.png
Normal file
BIN
resources/profiles/Anycubic/PHOTON MONO SE_thumbnail.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
BIN
resources/profiles/Anycubic/PHOTON MONO_thumbnail.png
Normal file
BIN
resources/profiles/Anycubic/PHOTON MONO_thumbnail.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
@ -32,20 +32,20 @@ BeadingStrategyPtr BeadingStrategyFactory::makeStrategy(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
BeadingStrategyPtr ret = std::make_unique<DistributedBeadingStrategy>(preferred_bead_width_inner, preferred_transition_length, transitioning_angle, wall_split_middle_threshold, wall_add_middle_threshold, inward_distributed_center_wall_count);
|
BeadingStrategyPtr ret = std::make_unique<DistributedBeadingStrategy>(preferred_bead_width_inner, preferred_transition_length, transitioning_angle, wall_split_middle_threshold, wall_add_middle_threshold, inward_distributed_center_wall_count);
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Applying the Redistribute meta-strategy with outer-wall width = " << preferred_bead_width_outer << ", inner-wall width = " << preferred_bead_width_inner << ".";
|
BOOST_LOG_TRIVIAL(trace) << "Applying the Redistribute meta-strategy with outer-wall width = " << preferred_bead_width_outer << ", inner-wall width = " << preferred_bead_width_inner << ".";
|
||||||
ret = std::make_unique<RedistributeBeadingStrategy>(preferred_bead_width_outer, minimum_variable_line_ratio, std::move(ret));
|
ret = std::make_unique<RedistributeBeadingStrategy>(preferred_bead_width_outer, minimum_variable_line_ratio, std::move(ret));
|
||||||
|
|
||||||
if (print_thin_walls) {
|
if (print_thin_walls) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Applying the Widening Beading meta-strategy with minimum input width " << min_feature_size << " and minimum output width " << min_bead_width << ".";
|
BOOST_LOG_TRIVIAL(trace) << "Applying the Widening Beading meta-strategy with minimum input width " << min_feature_size << " and minimum output width " << min_bead_width << ".";
|
||||||
ret = std::make_unique<WideningBeadingStrategy>(std::move(ret), min_feature_size, min_bead_width);
|
ret = std::make_unique<WideningBeadingStrategy>(std::move(ret), min_feature_size, min_bead_width);
|
||||||
}
|
}
|
||||||
if (outer_wall_offset > 0) {
|
if (outer_wall_offset > 0) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Applying the OuterWallOffset meta-strategy with offset = " << outer_wall_offset << ".";
|
BOOST_LOG_TRIVIAL(trace) << "Applying the OuterWallOffset meta-strategy with offset = " << outer_wall_offset << ".";
|
||||||
ret = std::make_unique<OuterWallInsetBeadingStrategy>(outer_wall_offset, std::move(ret));
|
ret = std::make_unique<OuterWallInsetBeadingStrategy>(outer_wall_offset, std::move(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Apply the LimitedBeadingStrategy last, since that adds a 0-width marker wall which other beading strategies shouldn't touch.
|
//Apply the LimitedBeadingStrategy last, since that adds a 0-width marker wall which other beading strategies shouldn't touch.
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Applying the Limited Beading meta-strategy with maximum bead count = " << max_bead_count << ".";
|
BOOST_LOG_TRIVIAL(trace) << "Applying the Limited Beading meta-strategy with maximum bead count = " << max_bead_count << ".";
|
||||||
ret = std::make_unique<LimitedBeadingStrategy>(max_bead_count, std::move(ret));
|
ret = std::make_unique<LimitedBeadingStrategy>(max_bead_count, std::move(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -129,8 +129,8 @@ set(SLIC3R_SOURCES
|
|||||||
Format/SL1.cpp
|
Format/SL1.cpp
|
||||||
Format/SL1_SVG.hpp
|
Format/SL1_SVG.hpp
|
||||||
Format/SL1_SVG.cpp
|
Format/SL1_SVG.cpp
|
||||||
Format/pwmx.hpp
|
Format/AnycubicSLA.hpp
|
||||||
Format/pwmx.cpp
|
Format/AnycubicSLA.cpp
|
||||||
Format/STEP.hpp
|
Format/STEP.hpp
|
||||||
Format/STEP.cpp
|
Format/STEP.cpp
|
||||||
GCode/ThumbnailData.cpp
|
GCode/ThumbnailData.cpp
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "pwmx.hpp"
|
#include "AnycubicSLA.hpp"
|
||||||
#include "GCode/ThumbnailData.hpp"
|
#include "GCode/ThumbnailData.hpp"
|
||||||
#include "SLA/RasterBase.hpp"
|
#include "SLA/RasterBase.hpp"
|
||||||
#include "libslic3r/SLAPrint.hpp"
|
#include "libslic3r/SLAPrint.hpp"
|
||||||
@ -22,6 +22,8 @@
|
|||||||
#define CFG_DELAY_BEFORE_EXPOSURE "DELAY_BEFORE_EXPOSURE"
|
#define CFG_DELAY_BEFORE_EXPOSURE "DELAY_BEFORE_EXPOSURE"
|
||||||
#define CFG_BOTTOM_LIFT_SPEED "BOTTOM_LIFT_SPEED"
|
#define CFG_BOTTOM_LIFT_SPEED "BOTTOM_LIFT_SPEED"
|
||||||
#define CFG_BOTTOM_LIFT_DISTANCE "BOTTOM_LIFT_DISTANCE"
|
#define CFG_BOTTOM_LIFT_DISTANCE "BOTTOM_LIFT_DISTANCE"
|
||||||
|
#define CFG_ANTIALIASING "ANTIALIASING"
|
||||||
|
|
||||||
|
|
||||||
#define PREV_W 224
|
#define PREV_W 224
|
||||||
#define PREV_H 168
|
#define PREV_H 168
|
||||||
@ -31,7 +33,7 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
static void pwx_get_pixel_span(const std::uint8_t* ptr, const std::uint8_t* end,
|
static void anycubicsla_get_pixel_span(const std::uint8_t* ptr, const std::uint8_t* end,
|
||||||
std::uint8_t& pixel, size_t& span_len)
|
std::uint8_t& pixel, size_t& span_len)
|
||||||
{
|
{
|
||||||
size_t max_len;
|
size_t max_len;
|
||||||
@ -46,7 +48,7 @@ static void pwx_get_pixel_span(const std::uint8_t* ptr, const std::uint8_t* end,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PWXRasterEncoder
|
struct AnycubicSLARasterEncoder
|
||||||
{
|
{
|
||||||
sla::EncodedRaster operator()(const void *ptr,
|
sla::EncodedRaster operator()(const void *ptr,
|
||||||
size_t w,
|
size_t w,
|
||||||
@ -62,7 +64,7 @@ struct PWXRasterEncoder
|
|||||||
const std::uint8_t *src = reinterpret_cast<const std::uint8_t *>(ptr);
|
const std::uint8_t *src = reinterpret_cast<const std::uint8_t *>(ptr);
|
||||||
const std::uint8_t *src_end = src + size;
|
const std::uint8_t *src_end = src + size;
|
||||||
while (src < src_end) {
|
while (src < src_end) {
|
||||||
pwx_get_pixel_span(src, src_end, pixel, span_len);
|
anycubicsla_get_pixel_span(src, src_end, pixel, span_len);
|
||||||
src += span_len;
|
src += span_len;
|
||||||
// fully transparent of fully opaque pixel
|
// fully transparent of fully opaque pixel
|
||||||
if (pixel == 0 || pixel == 0xF0) {
|
if (pixel == 0 || pixel == 0xF0) {
|
||||||
@ -78,27 +80,27 @@ struct PWXRasterEncoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sla::EncodedRaster(std::move(dst), "pwx");
|
return sla::EncodedRaster(std::move(dst), "pwimg");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using ConfMap = std::map<std::string, std::string>;
|
using ConfMap = std::map<std::string, std::string>;
|
||||||
|
|
||||||
typedef struct pwmx_format_intro
|
typedef struct anycubicsla_format_intro
|
||||||
{
|
{
|
||||||
char tag[12];
|
char tag[12];
|
||||||
std::uint32_t version; // value 1
|
std::uint32_t version; // value 1 (also known as 515, 516 and 517)
|
||||||
std::uint32_t area_num; // unknown - usually 4
|
std::uint32_t area_num; // Number of tables - usually 4
|
||||||
std::uint32_t header_data_offset;
|
std::uint32_t header_data_offset;
|
||||||
std::float_t intro24; // unknown - usually 0
|
std::uint32_t software_data_offset; // unused in version 1
|
||||||
std::uint32_t preview_data_offset;
|
std::uint32_t preview_data_offset;
|
||||||
std::float_t intro32; // unknown
|
std::uint32_t layer_color_offset; // unused in version 1
|
||||||
std::uint32_t layer_data_offset;
|
std::uint32_t layer_data_offset;
|
||||||
std::float_t intro40; // unknown
|
std::uint32_t extra_data_offset; // unused here (only used in version 516)
|
||||||
std::uint32_t image_data_offset;
|
std::uint32_t image_data_offset;
|
||||||
} pwmx_format_intro;
|
} anycubicsla_format_intro;
|
||||||
|
|
||||||
typedef struct pwmx_format_header
|
typedef struct anycubicsla_format_header
|
||||||
{
|
{
|
||||||
char tag[12];
|
char tag[12];
|
||||||
std::uint32_t payload_size;
|
std::uint32_t payload_size;
|
||||||
@ -121,11 +123,11 @@ typedef struct pwmx_format_header
|
|||||||
std::uint32_t per_layer_override; // ? unknown meaning ?
|
std::uint32_t per_layer_override; // ? unknown meaning ?
|
||||||
std::uint32_t print_time_s;
|
std::uint32_t print_time_s;
|
||||||
std::uint32_t transition_layer_count;
|
std::uint32_t transition_layer_count;
|
||||||
std::uint32_t unknown; // ? usually 0 ?
|
std::uint32_t transition_layer_type; // usually 0
|
||||||
|
|
||||||
} pwmx_format_header;
|
} anycubicsla_format_header;
|
||||||
|
|
||||||
typedef struct pwmx_format_preview
|
typedef struct anycubicsla_format_preview
|
||||||
{
|
{
|
||||||
char tag[12];
|
char tag[12];
|
||||||
std::uint32_t payload_size;
|
std::uint32_t payload_size;
|
||||||
@ -134,16 +136,16 @@ typedef struct pwmx_format_preview
|
|||||||
std::uint32_t preview_h;
|
std::uint32_t preview_h;
|
||||||
// raw image data in BGR565 format
|
// raw image data in BGR565 format
|
||||||
std::uint8_t pixels[PREV_W * PREV_H * 2];
|
std::uint8_t pixels[PREV_W * PREV_H * 2];
|
||||||
} pwmx_format_preview;
|
} anycubicsla_format_preview;
|
||||||
|
|
||||||
typedef struct pwmx_format_layers_header
|
typedef struct anycubicsla_format_layers_header
|
||||||
{
|
{
|
||||||
char tag[12];
|
char tag[12];
|
||||||
std::uint32_t payload_size;
|
std::uint32_t payload_size;
|
||||||
std::uint32_t layer_count;
|
std::uint32_t layer_count;
|
||||||
} pwmx_format_layers_header;
|
} anycubicsla_format_layers_header;
|
||||||
|
|
||||||
typedef struct pwmx_format_layer
|
typedef struct anycubicsla_format_layer
|
||||||
{
|
{
|
||||||
std::uint32_t image_offset;
|
std::uint32_t image_offset;
|
||||||
std::uint32_t image_size;
|
std::uint32_t image_size;
|
||||||
@ -153,20 +155,20 @@ typedef struct pwmx_format_layer
|
|||||||
std::float_t layer_height_mm;
|
std::float_t layer_height_mm;
|
||||||
std::float_t layer44; // unkown - usually 0
|
std::float_t layer44; // unkown - usually 0
|
||||||
std::float_t layer48; // unkown - usually 0
|
std::float_t layer48; // unkown - usually 0
|
||||||
} pwmx_format_layer;
|
} anycubicsla_format_layer;
|
||||||
|
|
||||||
typedef struct pwmx_format_misc
|
typedef struct anycubicsla_format_misc
|
||||||
{
|
{
|
||||||
std::float_t bottom_layer_height_mm;
|
std::float_t bottom_layer_height_mm;
|
||||||
std::float_t bottom_lift_distance_mm;
|
std::float_t bottom_lift_distance_mm;
|
||||||
std::float_t bottom_lift_speed_mms;
|
std::float_t bottom_lift_speed_mms;
|
||||||
|
|
||||||
} pwmx_format_misc;
|
} anycubicsla_format_misc;
|
||||||
|
|
||||||
class PwmxFormatConfigDef : public ConfigDef
|
class AnycubicSLAFormatConfigDef : public ConfigDef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PwmxFormatConfigDef()
|
AnycubicSLAFormatConfigDef()
|
||||||
{
|
{
|
||||||
add(CFG_LIFT_DISTANCE, coFloat);
|
add(CFG_LIFT_DISTANCE, coFloat);
|
||||||
add(CFG_LIFT_SPEED, coFloat);
|
add(CFG_LIFT_SPEED, coFloat);
|
||||||
@ -174,17 +176,18 @@ public:
|
|||||||
add(CFG_DELAY_BEFORE_EXPOSURE, coFloat);
|
add(CFG_DELAY_BEFORE_EXPOSURE, coFloat);
|
||||||
add(CFG_BOTTOM_LIFT_DISTANCE, coFloat);
|
add(CFG_BOTTOM_LIFT_DISTANCE, coFloat);
|
||||||
add(CFG_BOTTOM_LIFT_SPEED, coFloat);
|
add(CFG_BOTTOM_LIFT_SPEED, coFloat);
|
||||||
|
add(CFG_ANTIALIASING, coInt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PwmxFormatDynamicConfig : public DynamicConfig
|
class AnycubicSLAFormatDynamicConfig : public DynamicConfig
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PwmxFormatDynamicConfig(){};
|
AnycubicSLAFormatDynamicConfig(){};
|
||||||
const ConfigDef *def() const override { return &config_def; }
|
const ConfigDef *def() const override { return &config_def; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PwmxFormatConfigDef config_def;
|
AnycubicSLAFormatConfigDef config_def;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -222,8 +225,8 @@ template<class T> void crop_value(T &val, T val_min, T val_max)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_preview(pwmx_format_preview &p,
|
void fill_preview(anycubicsla_format_preview &p,
|
||||||
pwmx_format_misc &/*m*/,
|
anycubicsla_format_misc &/*m*/,
|
||||||
const ThumbnailsList &thumbnails)
|
const ThumbnailsList &thumbnails)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -266,9 +269,8 @@ void fill_preview(pwmx_format_preview &p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fill_header(anycubicsla_format_header &h,
|
||||||
void fill_header(pwmx_format_header &h,
|
anycubicsla_format_misc &m,
|
||||||
pwmx_format_misc &m,
|
|
||||||
const SLAPrint &print,
|
const SLAPrint &print,
|
||||||
std::uint32_t layer_count)
|
std::uint32_t layer_count)
|
||||||
{
|
{
|
||||||
@ -282,7 +284,7 @@ void fill_header(pwmx_format_header &h,
|
|||||||
auto mat_opt = cfg.option("material_notes");
|
auto mat_opt = cfg.option("material_notes");
|
||||||
std::string mnotes = mat_opt? cfg.option("material_notes")->serialize() : "";
|
std::string mnotes = mat_opt? cfg.option("material_notes")->serialize() : "";
|
||||||
// create a config parser from the material notes
|
// create a config parser from the material notes
|
||||||
Slic3r::PwmxFormatDynamicConfig mat_cfg;
|
Slic3r::AnycubicSLAFormatDynamicConfig mat_cfg;
|
||||||
SLAPrintStatistics stats = print.print_statistics();
|
SLAPrintStatistics stats = print.print_statistics();
|
||||||
|
|
||||||
// sanitize the string config
|
// sanitize the string config
|
||||||
@ -314,6 +316,13 @@ void fill_header(pwmx_format_header &h,
|
|||||||
h.per_layer_override = 0;
|
h.per_layer_override = 0;
|
||||||
|
|
||||||
// TODO - expose these variables to the UI rather than using material notes
|
// TODO - expose these variables to the UI rather than using material notes
|
||||||
|
if (mat_cfg.has(CFG_ANTIALIASING)) {
|
||||||
|
h.antialiasing = get_cfg_value_i(mat_cfg, CFG_ANTIALIASING);
|
||||||
|
crop_value(h.antialiasing, (uint32_t) 0, (uint32_t) 1);
|
||||||
|
} else {
|
||||||
|
h.antialiasing = 1;
|
||||||
|
}
|
||||||
|
|
||||||
h.delay_before_exposure_s = get_cfg_value_f(mat_cfg, CFG_DELAY_BEFORE_EXPOSURE, 0.5f);
|
h.delay_before_exposure_s = get_cfg_value_f(mat_cfg, CFG_DELAY_BEFORE_EXPOSURE, 0.5f);
|
||||||
crop_value(h.delay_before_exposure_s, 0.0f, 1000.0f);
|
crop_value(h.delay_before_exposure_s, 0.0f, 1000.0f);
|
||||||
|
|
||||||
@ -356,7 +365,7 @@ void fill_header(pwmx_format_header &h,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<sla::RasterBase> PwmxArchive::create_raster() const
|
std::unique_ptr<sla::RasterBase> AnycubicSLAArchive::create_raster() const
|
||||||
{
|
{
|
||||||
sla::Resolution res;
|
sla::Resolution res;
|
||||||
sla::PixelDim pxdim;
|
sla::PixelDim pxdim;
|
||||||
@ -389,13 +398,13 @@ std::unique_ptr<sla::RasterBase> PwmxArchive::create_raster() const
|
|||||||
return sla::create_raster_grayscale_aa(res, pxdim, gamma, tr);
|
return sla::create_raster_grayscale_aa(res, pxdim, gamma, tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
sla::RasterEncoder PwmxArchive::get_encoder() const
|
sla::RasterEncoder AnycubicSLAArchive::get_encoder() const
|
||||||
{
|
{
|
||||||
return PWXRasterEncoder{};
|
return AnycubicSLARasterEncoder{};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endian safe write of little endian 32bit ints
|
// Endian safe write of little endian 32bit ints
|
||||||
static void pwmx_write_int32(std::ofstream &out, std::uint32_t val)
|
static void anycubicsla_write_int32(std::ofstream &out, std::uint32_t val)
|
||||||
{
|
{
|
||||||
const char i1 = (val & 0xFF);
|
const char i1 = (val & 0xFF);
|
||||||
const char i2 = (val >> 8) & 0xFF;
|
const char i2 = (val >> 8) & 0xFF;
|
||||||
@ -407,104 +416,106 @@ static void pwmx_write_int32(std::ofstream &out, std::uint32_t val)
|
|||||||
out.write((const char *) &i3, 1);
|
out.write((const char *) &i3, 1);
|
||||||
out.write((const char *) &i4, 1);
|
out.write((const char *) &i4, 1);
|
||||||
}
|
}
|
||||||
static void pwmx_write_float(std::ofstream &out, std::float_t val)
|
static void anycubicsla_write_float(std::ofstream &out, std::float_t val)
|
||||||
{
|
{
|
||||||
std::uint32_t *f = (std::uint32_t *) &val;
|
std::uint32_t *f = (std::uint32_t *) &val;
|
||||||
pwmx_write_int32(out, *f);
|
anycubicsla_write_int32(out, *f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwmx_write_intro(std::ofstream &out, pwmx_format_intro &i)
|
static void anycubicsla_write_intro(std::ofstream &out, anycubicsla_format_intro &i)
|
||||||
{
|
{
|
||||||
out.write(TAG_INTRO, sizeof(i.tag));
|
out.write(TAG_INTRO, sizeof(i.tag));
|
||||||
pwmx_write_int32(out, i.version);
|
anycubicsla_write_int32(out, i.version);
|
||||||
pwmx_write_int32(out, i.area_num);
|
anycubicsla_write_int32(out, i.area_num);
|
||||||
pwmx_write_int32(out, i.header_data_offset);
|
anycubicsla_write_int32(out, i.header_data_offset);
|
||||||
pwmx_write_int32(out, i.intro24);
|
anycubicsla_write_int32(out, i.software_data_offset);
|
||||||
pwmx_write_int32(out, i.preview_data_offset);
|
anycubicsla_write_int32(out, i.preview_data_offset);
|
||||||
pwmx_write_int32(out, i.intro32);
|
anycubicsla_write_int32(out, i.layer_color_offset);
|
||||||
pwmx_write_int32(out, i.layer_data_offset);
|
anycubicsla_write_int32(out, i.layer_data_offset);
|
||||||
pwmx_write_int32(out, i.intro40);
|
anycubicsla_write_int32(out, i.extra_data_offset);
|
||||||
pwmx_write_int32(out, i.image_data_offset);
|
anycubicsla_write_int32(out, i.image_data_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwmx_write_header(std::ofstream &out, pwmx_format_header &h)
|
static void anycubicsla_write_header(std::ofstream &out, anycubicsla_format_header &h)
|
||||||
{
|
{
|
||||||
out.write(TAG_HEADER, sizeof(h.tag));
|
out.write(TAG_HEADER, sizeof(h.tag));
|
||||||
pwmx_write_int32(out, h.payload_size);
|
anycubicsla_write_int32(out, h.payload_size);
|
||||||
pwmx_write_float(out, h.pixel_size_um);
|
anycubicsla_write_float(out, h.pixel_size_um);
|
||||||
pwmx_write_float(out, h.layer_height_mm);
|
anycubicsla_write_float(out, h.layer_height_mm);
|
||||||
pwmx_write_float(out, h.exposure_time_s);
|
anycubicsla_write_float(out, h.exposure_time_s);
|
||||||
pwmx_write_float(out, h.delay_before_exposure_s);
|
anycubicsla_write_float(out, h.delay_before_exposure_s);
|
||||||
pwmx_write_float(out, h.bottom_exposure_time_s);
|
anycubicsla_write_float(out, h.bottom_exposure_time_s);
|
||||||
pwmx_write_float(out, h.bottom_layer_count);
|
anycubicsla_write_float(out, h.bottom_layer_count);
|
||||||
pwmx_write_float(out, h.lift_distance_mm);
|
anycubicsla_write_float(out, h.lift_distance_mm);
|
||||||
pwmx_write_float(out, h.lift_speed_mms);
|
anycubicsla_write_float(out, h.lift_speed_mms);
|
||||||
pwmx_write_float(out, h.retract_speed_mms);
|
anycubicsla_write_float(out, h.retract_speed_mms);
|
||||||
pwmx_write_float(out, h.volume_ml);
|
anycubicsla_write_float(out, h.volume_ml);
|
||||||
pwmx_write_int32(out, h.antialiasing);
|
anycubicsla_write_int32(out, h.antialiasing);
|
||||||
pwmx_write_int32(out, h.res_x);
|
anycubicsla_write_int32(out, h.res_x);
|
||||||
pwmx_write_int32(out, h.res_y);
|
anycubicsla_write_int32(out, h.res_y);
|
||||||
pwmx_write_float(out, h.weight_g);
|
anycubicsla_write_float(out, h.weight_g);
|
||||||
pwmx_write_float(out, h.price);
|
anycubicsla_write_float(out, h.price);
|
||||||
pwmx_write_int32(out, h.price_currency);
|
anycubicsla_write_int32(out, h.price_currency);
|
||||||
pwmx_write_int32(out, h.per_layer_override);
|
anycubicsla_write_int32(out, h.per_layer_override);
|
||||||
pwmx_write_int32(out, h.print_time_s);
|
anycubicsla_write_int32(out, h.print_time_s);
|
||||||
pwmx_write_int32(out, h.transition_layer_count);
|
anycubicsla_write_int32(out, h.transition_layer_count);
|
||||||
pwmx_write_int32(out, h.unknown);
|
anycubicsla_write_int32(out, h.transition_layer_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwmx_write_preview(std::ofstream &out, pwmx_format_preview &p)
|
static void anycubicsla_write_preview(std::ofstream &out, anycubicsla_format_preview &p)
|
||||||
{
|
{
|
||||||
out.write(TAG_PREVIEW, sizeof(p.tag));
|
out.write(TAG_PREVIEW, sizeof(p.tag));
|
||||||
pwmx_write_int32(out, p.payload_size);
|
anycubicsla_write_int32(out, p.payload_size);
|
||||||
pwmx_write_int32(out, p.preview_w);
|
anycubicsla_write_int32(out, p.preview_w);
|
||||||
pwmx_write_int32(out, p.preview_dpi);
|
anycubicsla_write_int32(out, p.preview_dpi);
|
||||||
pwmx_write_int32(out, p.preview_h);
|
anycubicsla_write_int32(out, p.preview_h);
|
||||||
out.write((const char*) p.pixels, sizeof(p.pixels));
|
out.write((const char*) p.pixels, sizeof(p.pixels));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwmx_write_layers_header(std::ofstream &out, pwmx_format_layers_header &h)
|
static void anycubicsla_write_layers_header(std::ofstream &out, anycubicsla_format_layers_header &h)
|
||||||
{
|
{
|
||||||
out.write(TAG_LAYERS, sizeof(h.tag));
|
out.write(TAG_LAYERS, sizeof(h.tag));
|
||||||
pwmx_write_int32(out, h.payload_size);
|
anycubicsla_write_int32(out, h.payload_size);
|
||||||
pwmx_write_int32(out, h.layer_count);
|
anycubicsla_write_int32(out, h.layer_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwmx_write_layer(std::ofstream &out, pwmx_format_layer &l)
|
static void anycubicsla_write_layer(std::ofstream &out, anycubicsla_format_layer &l)
|
||||||
{
|
{
|
||||||
pwmx_write_int32(out, l.image_offset);
|
anycubicsla_write_int32(out, l.image_offset);
|
||||||
pwmx_write_int32(out, l.image_size);
|
anycubicsla_write_int32(out, l.image_size);
|
||||||
pwmx_write_float(out, l.lift_distance_mm);
|
anycubicsla_write_float(out, l.lift_distance_mm);
|
||||||
pwmx_write_float(out, l.lift_speed_mms);
|
anycubicsla_write_float(out, l.lift_speed_mms);
|
||||||
pwmx_write_float(out, l.exposure_time_s);
|
anycubicsla_write_float(out, l.exposure_time_s);
|
||||||
pwmx_write_float(out, l.layer_height_mm);
|
anycubicsla_write_float(out, l.layer_height_mm);
|
||||||
pwmx_write_float(out, l.layer44);
|
anycubicsla_write_float(out, l.layer44);
|
||||||
pwmx_write_float(out, l.layer48);
|
anycubicsla_write_float(out, l.layer48);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PwmxArchive::export_print(const std::string fname,
|
void AnycubicSLAArchive::export_print(const std::string fname,
|
||||||
const SLAPrint &print,
|
const SLAPrint &print,
|
||||||
const ThumbnailsList &thumbnails,
|
const ThumbnailsList &thumbnails,
|
||||||
const std::string &/*projectname*/)
|
const std::string &/*projectname*/)
|
||||||
{
|
{
|
||||||
std::uint32_t layer_count = m_layers.size();
|
std::uint32_t layer_count = m_layers.size();
|
||||||
|
|
||||||
pwmx_format_intro intro = {};
|
anycubicsla_format_intro intro = {};
|
||||||
pwmx_format_header header = {};
|
anycubicsla_format_header header = {};
|
||||||
pwmx_format_preview preview = {};
|
anycubicsla_format_preview preview = {};
|
||||||
pwmx_format_layers_header layers_header = {};
|
anycubicsla_format_layers_header layers_header = {};
|
||||||
pwmx_format_misc misc = {};
|
anycubicsla_format_misc misc = {};
|
||||||
std::vector<uint8_t> layer_images;
|
std::vector<uint8_t> layer_images;
|
||||||
std::uint32_t image_offset;
|
std::uint32_t image_offset;
|
||||||
|
|
||||||
intro.version = 1;
|
assert(m_version == ANYCUBIC_SLA_FORMAT_VERSION_1);
|
||||||
|
|
||||||
|
intro.version = m_version;
|
||||||
intro.area_num = 4;
|
intro.area_num = 4;
|
||||||
intro.header_data_offset = sizeof(intro);
|
intro.header_data_offset = sizeof(intro);
|
||||||
intro.preview_data_offset = sizeof(intro) + sizeof(header);
|
intro.preview_data_offset = sizeof(intro) + sizeof(header);
|
||||||
intro.layer_data_offset = intro.preview_data_offset + sizeof(preview);
|
intro.layer_data_offset = intro.preview_data_offset + sizeof(preview);
|
||||||
intro.image_data_offset = intro.layer_data_offset +
|
intro.image_data_offset = intro.layer_data_offset +
|
||||||
sizeof(layers_header) +
|
sizeof(layers_header) +
|
||||||
(sizeof(pwmx_format_layer) * layer_count);
|
(sizeof(anycubicsla_format_layer) * layer_count);
|
||||||
|
|
||||||
fill_header(header, misc, print, layer_count);
|
fill_header(header, misc, print, layer_count);
|
||||||
fill_preview(preview, misc, thumbnails);
|
fill_preview(preview, misc, thumbnails);
|
||||||
@ -513,21 +524,21 @@ void PwmxArchive::export_print(const std::string fname,
|
|||||||
// open the file and write the contents
|
// open the file and write the contents
|
||||||
std::ofstream out;
|
std::ofstream out;
|
||||||
out.open(fname, std::ios::binary | std::ios::out | std::ios::trunc);
|
out.open(fname, std::ios::binary | std::ios::out | std::ios::trunc);
|
||||||
pwmx_write_intro(out, intro);
|
anycubicsla_write_intro(out, intro);
|
||||||
pwmx_write_header(out, header);
|
anycubicsla_write_header(out, header);
|
||||||
pwmx_write_preview(out, preview);
|
anycubicsla_write_preview(out, preview);
|
||||||
|
|
||||||
layers_header.payload_size = intro.image_data_offset - intro.layer_data_offset -
|
layers_header.payload_size = intro.image_data_offset - intro.layer_data_offset -
|
||||||
sizeof(layers_header.tag) - sizeof(layers_header.payload_size);
|
sizeof(layers_header.tag) - sizeof(layers_header.payload_size);
|
||||||
layers_header.layer_count = layer_count;
|
layers_header.layer_count = layer_count;
|
||||||
pwmx_write_layers_header(out, layers_header);
|
anycubicsla_write_layers_header(out, layers_header);
|
||||||
|
|
||||||
//layers
|
//layers
|
||||||
layer_images.reserve(layer_count * LAYER_SIZE_ESTIMATE);
|
layer_images.reserve(layer_count * LAYER_SIZE_ESTIMATE);
|
||||||
image_offset = intro.image_data_offset;
|
image_offset = intro.image_data_offset;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (const sla::EncodedRaster &rst : m_layers) {
|
for (const sla::EncodedRaster &rst : m_layers) {
|
||||||
pwmx_format_layer l;
|
anycubicsla_format_layer l;
|
||||||
std::memset(&l, 0, sizeof(l));
|
std::memset(&l, 0, sizeof(l));
|
||||||
l.image_offset = image_offset;
|
l.image_offset = image_offset;
|
||||||
l.image_size = rst.size();
|
l.image_size = rst.size();
|
||||||
@ -543,7 +554,7 @@ void PwmxArchive::export_print(const std::string fname,
|
|||||||
l.lift_speed_mms = header.lift_speed_mms;
|
l.lift_speed_mms = header.lift_speed_mms;
|
||||||
}
|
}
|
||||||
image_offset += l.image_size;
|
image_offset += l.image_size;
|
||||||
pwmx_write_layer(out, l);
|
anycubicsla_write_layer(out, l);
|
||||||
// add the rle encoded layer image into the buffer
|
// add the rle encoded layer image into the buffer
|
||||||
const char* img_start = reinterpret_cast<const char*>(rst.data());
|
const char* img_start = reinterpret_cast<const char*>(rst.data());
|
||||||
const char* img_end = img_start + rst.size();
|
const char* img_end = img_start + rst.size();
|
81
src/libslic3r/Format/AnycubicSLA.hpp
Normal file
81
src/libslic3r/Format/AnycubicSLA.hpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#ifndef _SLIC3R_FORMAT_PWMX_HPP_
|
||||||
|
#define _SLIC3R_FORMAT_PWMX_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "SLAArchiveWriter.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
|
|
||||||
|
#define ANYCUBIC_SLA_FORMAT_VERSION_1 1
|
||||||
|
#define ANYCUBIC_SLA_FORMAT_VERSION_515 515
|
||||||
|
#define ANYCUBIC_SLA_FORMAT_VERSION_516 516
|
||||||
|
#define ANYCUBIC_SLA_FORMAT_VERSION_517 517
|
||||||
|
|
||||||
|
#define ANYCUBIC_SLA_FORMAT_VERSIONED(FILEFORMAT, NAME, VERSION) \
|
||||||
|
{ FILEFORMAT, { FILEFORMAT, [] (const auto &cfg) { return std::make_unique<AnycubicSLAArchive>(cfg, VERSION); } } }
|
||||||
|
|
||||||
|
#define ANYCUBIC_SLA_FORMAT(FILEFORMAT, NAME) \
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED(FILEFORMAT, NAME, ANYCUBIC_SLA_FORMAT_VERSION_1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
// Supports only ANYCUBIC_SLA_VERSION_1
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pws", "Photon / Photon S", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pw0", "Photon Zero", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pwx", "Photon X", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
|
||||||
|
// Supports ANYCUBIC_SLA_VERSION_1 and ANYCUBIC_SLA_VERSION_515
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pwmo", "Photon Mono", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pwms", "Photon Mono SE", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("dlp", "Photon Ultra", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pwmx", "Photon Mono X", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pmsq", "Photon Mono SQ", ANYCUBIC_SLA_VERSION_1),
|
||||||
|
|
||||||
|
// Supports ANYCUBIC_SLA_VERSION_515 and ANYCUBIC_SLA_VERSION_516
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pwma", "Photon Mono 4K", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pm3", "Photon M3", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pm3m", "Photon M3 Max", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
|
||||||
|
// Supports NYCUBIC_SLA_VERSION_515 and ANYCUBIC_SLA_VERSION_516 and ANYCUBIC_SLA_VERSION_517
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pwmb", "Photon Mono X 6K / Photon M3 Plus", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("dl2p", "Photon Photon D2", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pmx2", "Photon Mono X2", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
ANYCUBIC_SLA_FORMAT_VERSIONED("pm3r", "Photon M3 Premium", ANYCUBIC_SLA_VERSION_515),
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class AnycubicSLAArchive: public SLAArchiveWriter {
|
||||||
|
SLAPrinterConfig m_cfg;
|
||||||
|
uint16_t m_version;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<sla::RasterBase> create_raster() const override;
|
||||||
|
sla::RasterEncoder get_encoder() const override;
|
||||||
|
|
||||||
|
SLAPrinterConfig & cfg() { return m_cfg; }
|
||||||
|
const SLAPrinterConfig & cfg() const { return m_cfg; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AnycubicSLAArchive() = default;
|
||||||
|
explicit AnycubicSLAArchive(const SLAPrinterConfig &cfg):
|
||||||
|
m_cfg(cfg), m_version(ANYCUBIC_SLA_FORMAT_VERSION_1) {}
|
||||||
|
explicit AnycubicSLAArchive(SLAPrinterConfig &&cfg):
|
||||||
|
m_cfg(std::move(cfg)), m_version(ANYCUBIC_SLA_FORMAT_VERSION_1) {}
|
||||||
|
|
||||||
|
explicit AnycubicSLAArchive(const SLAPrinterConfig &cfg, uint16_t version):
|
||||||
|
m_cfg(cfg), m_version(version) {}
|
||||||
|
explicit AnycubicSLAArchive(SLAPrinterConfig &&cfg, uint16_t version):
|
||||||
|
m_cfg(std::move(cfg)), m_version(version) {}
|
||||||
|
|
||||||
|
void export_print(const std::string fname,
|
||||||
|
const SLAPrint &print,
|
||||||
|
const ThumbnailsList &thumbnails,
|
||||||
|
const std::string &projectname = "") override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Slic3r::sla
|
||||||
|
|
||||||
|
#endif // _SLIC3R_FORMAT_PWMX_HPP_
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "SL1.hpp"
|
#include "SL1.hpp"
|
||||||
#include "SL1_SVG.hpp"
|
#include "SL1_SVG.hpp"
|
||||||
#include "pwmx.hpp"
|
#include "AnycubicSLA.hpp"
|
||||||
|
|
||||||
#include "libslic3r/libslic3r.h"
|
#include "libslic3r/libslic3r.h"
|
||||||
|
|
||||||
@ -33,10 +33,9 @@ static const std::map<std::string, ArchiveEntry> REGISTERED_ARCHIVES {
|
|||||||
"SL2",
|
"SL2",
|
||||||
{ "sl1_svg", [] (const auto &cfg) { return std::make_unique<SL1_SVGArchive>(cfg); } }
|
{ "sl1_svg", [] (const auto &cfg) { return std::make_unique<SL1_SVGArchive>(cfg); } }
|
||||||
},
|
},
|
||||||
{
|
ANYCUBIC_SLA_FORMAT("pwmo", "Photon Mono"),
|
||||||
"pwmx",
|
ANYCUBIC_SLA_FORMAT("pwmx", "Photon Mono X"),
|
||||||
{ "pwmx", [] (const auto &cfg) { return std::make_unique<PwmxArchive>(cfg); } }
|
ANYCUBIC_SLA_FORMAT("pwms", "Photon Mono SE"),
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<SLAArchiveWriter>
|
std::unique_ptr<SLAArchiveWriter>
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
#ifndef _SLIC3R_FORMAT_PWMX_HPP_
|
|
||||||
#define _SLIC3R_FORMAT_PWMX_HPP_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "SLAArchiveWriter.hpp"
|
|
||||||
|
|
||||||
#include "libslic3r/PrintConfig.hpp"
|
|
||||||
|
|
||||||
namespace Slic3r {
|
|
||||||
|
|
||||||
class PwmxArchive: public SLAArchiveWriter {
|
|
||||||
SLAPrinterConfig m_cfg;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::unique_ptr<sla::RasterBase> create_raster() const override;
|
|
||||||
sla::RasterEncoder get_encoder() const override;
|
|
||||||
|
|
||||||
SLAPrinterConfig & cfg() { return m_cfg; }
|
|
||||||
const SLAPrinterConfig & cfg() const { return m_cfg; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
PwmxArchive() = default;
|
|
||||||
explicit PwmxArchive(const SLAPrinterConfig &cfg): m_cfg(cfg) {}
|
|
||||||
explicit PwmxArchive(SLAPrinterConfig &&cfg): m_cfg(std::move(cfg)) {}
|
|
||||||
|
|
||||||
void export_print(const std::string fname,
|
|
||||||
const SLAPrint &print,
|
|
||||||
const ThumbnailsList &thumbnails,
|
|
||||||
const std::string &projectname = "") override;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Slic3r::sla
|
|
||||||
|
|
||||||
#endif // _SLIC3R_FORMAT_PWMX_HPP_
|
|
@ -3083,8 +3083,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
|
|
||||||
std::string cooling_marker_setspeed_comments;
|
std::string cooling_marker_setspeed_comments;
|
||||||
if (m_enable_cooling_markers) {
|
if (m_enable_cooling_markers) {
|
||||||
if (path.role().is_bridge() &&
|
if (path.role().is_bridge())
|
||||||
(!path.role().is_perimeter() || !this->config().enable_dynamic_fan_speeds.get_at(m_writer.extruder()->id())))
|
|
||||||
gcode += ";_BRIDGE_FAN_START\n";
|
gcode += ";_BRIDGE_FAN_START\n";
|
||||||
else
|
else
|
||||||
cooling_marker_setspeed_comments = ";_EXTRUDE_SET_SPEED";
|
cooling_marker_setspeed_comments = ";_EXTRUDE_SET_SPEED";
|
||||||
@ -3120,7 +3119,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
double last_set_speed = new_points[0].speed * 60.0;
|
double last_set_speed = new_points[0].speed * 60.0;
|
||||||
double last_set_fan_speed = new_points[0].fan_speed;
|
double last_set_fan_speed = new_points[0].fan_speed;
|
||||||
gcode += m_writer.set_speed(last_set_speed, "", cooling_marker_setspeed_comments);
|
gcode += m_writer.set_speed(last_set_speed, "", cooling_marker_setspeed_comments);
|
||||||
gcode += ";_SET_FAN_SPEED" + std::to_string(int(last_set_fan_speed)) + "\n";
|
gcode += "\n;_SET_FAN_SPEED" + std::to_string(int(last_set_fan_speed)) + "\n";
|
||||||
Vec2d prev = this->point_to_gcode_quantized(new_points[0].p);
|
Vec2d prev = this->point_to_gcode_quantized(new_points[0].p);
|
||||||
for (size_t i = 1; i < new_points.size(); i++) {
|
for (size_t i = 1; i < new_points.size(); i++) {
|
||||||
const ProcessedPoint &processed_point = new_points[i];
|
const ProcessedPoint &processed_point = new_points[i];
|
||||||
@ -3135,10 +3134,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
}
|
}
|
||||||
if (last_set_fan_speed != processed_point.fan_speed) {
|
if (last_set_fan_speed != processed_point.fan_speed) {
|
||||||
last_set_fan_speed = processed_point.fan_speed;
|
last_set_fan_speed = processed_point.fan_speed;
|
||||||
gcode += ";_SET_FAN_SPEED" + std::to_string(int(last_set_fan_speed)) + "\n";
|
gcode += "\n;_SET_FAN_SPEED" + std::to_string(int(last_set_fan_speed)) + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gcode += ";_RESET_FAN_SPEED\n";
|
gcode += "\n;_RESET_FAN_SPEED\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_enable_cooling_markers)
|
if (m_enable_cooling_markers)
|
||||||
|
@ -3867,7 +3867,9 @@ void PrintConfigDef::init_sla_params()
|
|||||||
def->multiline = true;
|
def->multiline = true;
|
||||||
def->full_width = true;
|
def->full_width = true;
|
||||||
def->height = 13;
|
def->height = 13;
|
||||||
def->mode = comAdvanced;
|
// TODO currently notes are the only way to pass data
|
||||||
|
// for non-PrusaResearch printers. We therefore need to always show them
|
||||||
|
def->mode = comSimple;
|
||||||
def->set_default_value(new ConfigOptionString(""));
|
def->set_default_value(new ConfigOptionString(""));
|
||||||
|
|
||||||
def = this->add("material_vendor", coString);
|
def = this->add("material_vendor", coString);
|
||||||
|
@ -1178,19 +1178,6 @@ void PrintObject::discover_vertical_shells()
|
|||||||
};
|
};
|
||||||
bool spiral_vase = this->print()->config().spiral_vase.value;
|
bool spiral_vase = this->print()->config().spiral_vase.value;
|
||||||
size_t num_layers = spiral_vase ? std::min(size_t(this->printing_region(0).config().bottom_solid_layers), m_layers.size()) : m_layers.size();
|
size_t num_layers = spiral_vase ? std::min(size_t(this->printing_region(0).config().bottom_solid_layers), m_layers.size()) : m_layers.size();
|
||||||
coordf_t min_layer_height = this->slicing_parameters().min_layer_height;
|
|
||||||
// Does this region possibly produce more than 1 top or bottom layer?
|
|
||||||
auto has_extra_layers_fn = [min_layer_height](const PrintRegionConfig &config) {
|
|
||||||
auto num_extra_layers = [min_layer_height](int num_solid_layers, coordf_t min_shell_thickness) {
|
|
||||||
if (num_solid_layers == 0)
|
|
||||||
return 0;
|
|
||||||
int n = num_solid_layers - 1;
|
|
||||||
int n2 = int(ceil(min_shell_thickness / min_layer_height));
|
|
||||||
return std::max(n, n2 - 1);
|
|
||||||
};
|
|
||||||
return num_extra_layers(config.top_solid_layers, config.top_solid_min_thickness) +
|
|
||||||
num_extra_layers(config.bottom_solid_layers, config.bottom_solid_min_thickness) > 0;
|
|
||||||
};
|
|
||||||
std::vector<DiscoverVerticalShellsCacheEntry> cache_top_botom_regions(num_layers, DiscoverVerticalShellsCacheEntry());
|
std::vector<DiscoverVerticalShellsCacheEntry> cache_top_botom_regions(num_layers, DiscoverVerticalShellsCacheEntry());
|
||||||
bool top_bottom_surfaces_all_regions = this->num_printing_regions() > 1 && ! m_config.interface_shells.value;
|
bool top_bottom_surfaces_all_regions = this->num_printing_regions() > 1 && ! m_config.interface_shells.value;
|
||||||
// static constexpr const float top_bottom_expansion_coeff = 1.05f;
|
// static constexpr const float top_bottom_expansion_coeff = 1.05f;
|
||||||
@ -1199,18 +1186,6 @@ void PrintObject::discover_vertical_shells()
|
|||||||
if (top_bottom_surfaces_all_regions) {
|
if (top_bottom_surfaces_all_regions) {
|
||||||
// This is a multi-material print and interface_shells are disabled, meaning that the vertical shell thickness
|
// This is a multi-material print and interface_shells are disabled, meaning that the vertical shell thickness
|
||||||
// is calculated over all materials.
|
// is calculated over all materials.
|
||||||
// Is the "ensure vertical wall thickness" applicable to any region?
|
|
||||||
bool has_extra_layers = false;
|
|
||||||
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id) {
|
|
||||||
const PrintRegionConfig &config = this->printing_region(region_id).config();
|
|
||||||
if (has_extra_layers_fn(config)) {
|
|
||||||
has_extra_layers = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (! has_extra_layers)
|
|
||||||
// The "ensure vertical wall thickness" feature is not applicable to any of the regions. Quit.
|
|
||||||
return;
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - start : cache top / bottom";
|
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - start : cache top / bottom";
|
||||||
//FIXME Improve the heuristics for a grain size.
|
//FIXME Improve the heuristics for a grain size.
|
||||||
size_t grain_size = std::max(num_layers / 16, size_t(1));
|
size_t grain_size = std::max(num_layers / 16, size_t(1));
|
||||||
@ -1280,11 +1255,6 @@ void PrintObject::discover_vertical_shells()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
const PrintRegion ®ion = this->printing_region(region_id);
|
|
||||||
if (! has_extra_layers_fn(region.config()))
|
|
||||||
// Zero or 1 layer, there is no additional vertical wall thickness enforced.
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//FIXME Improve the heuristics for a grain size.
|
//FIXME Improve the heuristics for a grain size.
|
||||||
size_t grain_size = std::max(num_layers / 16, size_t(1));
|
size_t grain_size = std::max(num_layers / 16, size_t(1));
|
||||||
|
|
||||||
@ -1395,13 +1365,25 @@ void PrintObject::discover_vertical_shells()
|
|||||||
coordf_t print_z = layer->print_z;
|
coordf_t print_z = layer->print_z;
|
||||||
int i = int(idx_layer) + 1;
|
int i = int(idx_layer) + 1;
|
||||||
int itop = int(idx_layer) + n_top_layers;
|
int itop = int(idx_layer) + n_top_layers;
|
||||||
|
bool at_least_one_top_projected = false;
|
||||||
for (; i < int(cache_top_botom_regions.size()) &&
|
for (; i < int(cache_top_botom_regions.size()) &&
|
||||||
(i < itop || m_layers[i]->print_z - print_z < region_config.top_solid_min_thickness - EPSILON);
|
(i < itop || m_layers[i]->print_z - print_z < region_config.top_solid_min_thickness - EPSILON);
|
||||||
++ i) {
|
++ i) {
|
||||||
|
at_least_one_top_projected = true;
|
||||||
const DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[i];
|
const DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[i];
|
||||||
combine_holes(cache.holes);
|
combine_holes(cache.holes);
|
||||||
combine_shells(cache.top_surfaces);
|
combine_shells(cache.top_surfaces);
|
||||||
}
|
}
|
||||||
|
if (!at_least_one_top_projected && i < int(cache_top_botom_regions.size())) {
|
||||||
|
// Lets consider this a special case - with only 1 top solid and minimal shell thickness settings, the
|
||||||
|
// boundaries of solid layers are not anchored over/under perimeters, so lets fix it by adding at least one
|
||||||
|
// perimeter width of area
|
||||||
|
Polygons anchor_area = intersection(expand(cache_top_botom_regions[idx_layer].top_surfaces,
|
||||||
|
layerm->flow(frExternalPerimeter).scaled_spacing()),
|
||||||
|
to_polygons(m_layers[i]->lslices));
|
||||||
|
combine_shells(anchor_area);
|
||||||
|
}
|
||||||
|
|
||||||
if (one_more_layer_below_top_bottom_surfaces)
|
if (one_more_layer_below_top_bottom_surfaces)
|
||||||
if (i < int(cache_top_botom_regions.size()) &&
|
if (i < int(cache_top_botom_regions.size()) &&
|
||||||
(i <= itop || m_layers[i]->bottom_z() - print_z < region_config.top_solid_min_thickness - EPSILON))
|
(i <= itop || m_layers[i]->bottom_z() - print_z < region_config.top_solid_min_thickness - EPSILON))
|
||||||
@ -1412,13 +1394,23 @@ void PrintObject::discover_vertical_shells()
|
|||||||
coordf_t bottom_z = layer->bottom_z();
|
coordf_t bottom_z = layer->bottom_z();
|
||||||
int i = int(idx_layer) - 1;
|
int i = int(idx_layer) - 1;
|
||||||
int ibottom = int(idx_layer) - n_bottom_layers;
|
int ibottom = int(idx_layer) - n_bottom_layers;
|
||||||
|
bool at_least_one_bottom_projected = false;
|
||||||
for (; i >= 0 &&
|
for (; i >= 0 &&
|
||||||
(i > ibottom || bottom_z - m_layers[i]->bottom_z() < region_config.bottom_solid_min_thickness - EPSILON);
|
(i > ibottom || bottom_z - m_layers[i]->bottom_z() < region_config.bottom_solid_min_thickness - EPSILON);
|
||||||
-- i) {
|
-- i) {
|
||||||
|
at_least_one_bottom_projected = true;
|
||||||
const DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[i];
|
const DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[i];
|
||||||
combine_holes(cache.holes);
|
combine_holes(cache.holes);
|
||||||
combine_shells(cache.bottom_surfaces);
|
combine_shells(cache.bottom_surfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!at_least_one_bottom_projected && i >= 0) {
|
||||||
|
Polygons anchor_area = intersection(expand(cache_top_botom_regions[idx_layer].bottom_surfaces,
|
||||||
|
layerm->flow(frExternalPerimeter).scaled_spacing()),
|
||||||
|
to_polygons(m_layers[i]->lslices));
|
||||||
|
combine_shells(anchor_area);
|
||||||
|
}
|
||||||
|
|
||||||
if (one_more_layer_below_top_bottom_surfaces)
|
if (one_more_layer_below_top_bottom_surfaces)
|
||||||
if (i >= 0 &&
|
if (i >= 0 &&
|
||||||
(i > ibottom || bottom_z - m_layers[i]->print_z < region_config.bottom_solid_min_thickness - EPSILON))
|
(i > ibottom || bottom_z - m_layers[i]->print_z < region_config.bottom_solid_min_thickness - EPSILON))
|
||||||
@ -1514,10 +1506,19 @@ void PrintObject::discover_vertical_shells()
|
|||||||
// Finally expand the infill a bit to remove tiny gaps between solid infill and the other regions.
|
// Finally expand the infill a bit to remove tiny gaps between solid infill and the other regions.
|
||||||
narrow_sparse_infill_region_radius - tiny_overlap_radius, ClipperLib::jtSquare);
|
narrow_sparse_infill_region_radius - tiny_overlap_radius, ClipperLib::jtSquare);
|
||||||
|
|
||||||
|
Polygons internal_volume;
|
||||||
|
{
|
||||||
|
Polygons shrinked_bottom_slice = idx_layer > 0 ? to_polygons(m_layers[idx_layer - 1]->lslices) : Polygons{};
|
||||||
|
Polygons shrinked_upper_slice = idx_layer > 0 ? to_polygons(m_layers[idx_layer + 1]->lslices) : Polygons{};
|
||||||
|
internal_volume = intersection(shrinked_bottom_slice, shrinked_upper_slice);
|
||||||
|
}
|
||||||
|
|
||||||
// The opening operation may cause scattered tiny drops on the smooth parts of the model, filter them out
|
// The opening operation may cause scattered tiny drops on the smooth parts of the model, filter them out
|
||||||
regularized_shell.erase(std::remove_if(regularized_shell.begin(), regularized_shell.end(),
|
regularized_shell.erase(std::remove_if(regularized_shell.begin(), regularized_shell.end(),
|
||||||
[&min_perimeter_infill_spacing](const ExPolygon &p) {
|
[&min_perimeter_infill_spacing, &internal_volume](const ExPolygon &p) {
|
||||||
return p.area() < min_perimeter_infill_spacing * scaled(8.0);
|
return p.area() < min_perimeter_infill_spacing * scaled(1.5) ||
|
||||||
|
(p.area() < min_perimeter_infill_spacing * scaled(8.0) &&
|
||||||
|
diff(to_polygons(p), internal_volume).empty());
|
||||||
}),
|
}),
|
||||||
regularized_shell.end());
|
regularized_shell.end());
|
||||||
}
|
}
|
||||||
|
@ -836,7 +836,8 @@ void GCodeViewer::refresh(const GCodeProcessorResult& gcode_result, const std::v
|
|||||||
case EMoveType::Extrude:
|
case EMoveType::Extrude:
|
||||||
{
|
{
|
||||||
m_extrusions.ranges.height.update_from(round_to_bin(curr.height));
|
m_extrusions.ranges.height.update_from(round_to_bin(curr.height));
|
||||||
m_extrusions.ranges.width.update_from(round_to_bin(curr.width));
|
if (curr.extrusion_role != GCodeExtrusionRole::Custom || is_visible(GCodeExtrusionRole::Custom))
|
||||||
|
m_extrusions.ranges.width.update_from(round_to_bin(curr.width));
|
||||||
m_extrusions.ranges.fan_speed.update_from(curr.fan_speed);
|
m_extrusions.ranges.fan_speed.update_from(curr.fan_speed);
|
||||||
m_extrusions.ranges.temperature.update_from(curr.temperature);
|
m_extrusions.ranges.temperature.update_from(curr.temperature);
|
||||||
if (curr.extrusion_role != GCodeExtrusionRole::Custom || is_visible(GCodeExtrusionRole::Custom))
|
if (curr.extrusion_role != GCodeExtrusionRole::Custom || is_visible(GCodeExtrusionRole::Custom))
|
||||||
@ -3944,6 +3945,20 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_view_type == EViewType::Width || m_view_type == EViewType::VolumetricRate) {
|
||||||
|
const auto custom_it = std::find(m_roles.begin(), m_roles.end(), GCodeExtrusionRole::Custom);
|
||||||
|
if (custom_it != m_roles.end()) {
|
||||||
|
const bool custom_visible = is_visible(GCodeExtrusionRole::Custom);
|
||||||
|
const wxString btn_text = custom_visible ? _u8L("Hide Custom GCode") : _u8L("Show Custom GCode");
|
||||||
|
ImGui::Separator();
|
||||||
|
if (imgui.button(btn_text, ImVec2(-1.0f, 0.0f), true)) {
|
||||||
|
m_extrusions.role_visibility_flags = custom_visible ? m_extrusions.role_visibility_flags & ~(1 << int(GCodeExtrusionRole::Custom)) :
|
||||||
|
m_extrusions.role_visibility_flags | (1 << int(GCodeExtrusionRole::Custom));
|
||||||
|
wxGetApp().plater()->refresh_print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// total estimated printing time section
|
// total estimated printing time section
|
||||||
if (show_estimated_time) {
|
if (show_estimated_time) {
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
@ -78,32 +78,7 @@ std::vector<DriveData> RemovableDriveManager::search_for_removable_drives() cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int eject_alt(const std::wstring& volume_access_path)
|
|
||||||
{
|
|
||||||
HANDLE handle = CreateFileW(volume_access_path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
|
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "Alt Ejecting " << volume_access_path << " failed (handle == INVALID_HANDLE_VALUE): " << GetLastError();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
DWORD deviceControlRetVal(0);
|
|
||||||
//these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger.
|
|
||||||
//sd cards does trigger WM_DEVICECHANGE messege, usb drives dont
|
|
||||||
BOOL e1 = DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "FSCTL_LOCK_VOLUME " << e1 << " ; " << deviceControlRetVal << " ; " << GetLastError();
|
|
||||||
BOOL e2 = DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "FSCTL_DISMOUNT_VOLUME " << e2 << " ; " << deviceControlRetVal << " ; " << GetLastError();
|
|
||||||
|
|
||||||
// some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here with FALSE as third parameter, which should set PreventMediaRemoval
|
|
||||||
BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
|
||||||
if (error == 0) {
|
|
||||||
CloseHandle(handle);
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "Alt Ejecting " << volume_access_path << " failed (IOCTL_STORAGE_EJECT_MEDIA)" << deviceControlRetVal << " " << GetLastError();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
CloseHandle(handle);
|
|
||||||
BOOST_LOG_TRIVIAL(info) << "Alt Ejecting finished";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// From https://github.com/microsoft/Windows-driver-samples/tree/main/usb/usbview
|
// From https://github.com/microsoft/Windows-driver-samples/tree/main/usb/usbview
|
||||||
@ -485,7 +460,7 @@ int eject_inner(const std::string& path)
|
|||||||
DEVINST dev_inst = get_dev_inst_by_device_number(device_number, drive_type, dos_device_name);
|
DEVINST dev_inst = get_dev_inst_by_device_number(device_number, drive_type, dos_device_name);
|
||||||
if (dev_inst == 0) {
|
if (dev_inst == 0) {
|
||||||
BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1%: Invalid device instance handle. Going to try alternative ejecting method.", path);
|
BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1%: Invalid device instance handle. Going to try alternative ejecting method.", path);
|
||||||
return eject_alt(volume_access_path);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PNP_VETO_TYPE veto_type = PNP_VetoTypeUnknown;
|
PNP_VETO_TYPE veto_type = PNP_VetoTypeUnknown;
|
||||||
@ -524,7 +499,7 @@ int eject_inner(const std::string& path)
|
|||||||
if (res == CR_SUCCESS && veto_type == PNP_VetoTypeUnknown) {
|
if (res == CR_SUCCESS && veto_type == PNP_VetoTypeUnknown) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(warning) << GUI::format("Ejecting of %1% has failed: Request to eject device has failed. Another request will follow. Veto type: %2%", path, veto_type);
|
BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1% has failed: Request to eject device has failed. Another request will follow. Veto type: %2%", path, veto_type);
|
||||||
|
|
||||||
// But on some PC, SD cards ejects only with its own dev_inst.
|
// But on some PC, SD cards ejects only with its own dev_inst.
|
||||||
res = CM_Request_Device_EjectW(dev_inst, &veto_type, veto_name, MAX_PATH, 0);
|
res = CM_Request_Device_EjectW(dev_inst, &veto_type, veto_name, MAX_PATH, 0);
|
||||||
@ -537,6 +512,76 @@ int eject_inner(const std::string& path)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this method should be called in worker thread. It does SLEEP.
|
||||||
|
// Alternative ejecting to eject_inner method.
|
||||||
|
// Success or Fail is passed directly to UI by events
|
||||||
|
void eject_alt(std::string path, wxEvtHandler* callback_evt_handler, DriveData drive_data)
|
||||||
|
{
|
||||||
|
// Transform path to correct form
|
||||||
|
std::wstring wpath = std::wstring();
|
||||||
|
wpath += boost::nowide::widen(path)[0]; // drive letter wide
|
||||||
|
wpath[0] &= ~0x20; // make sure drive letter is uppercase
|
||||||
|
std::wstring volume_access_path = L"\\\\.\\" + wpath + L":"; // for CreateFile
|
||||||
|
|
||||||
|
HANDLE handle = CreateFileW(volume_access_path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Alt ejecting " << volume_access_path << " failed (handle == INVALID_HANDLE_VALUE): " << GetLastError();
|
||||||
|
assert(callback_evt_handler);
|
||||||
|
if (callback_evt_handler)
|
||||||
|
wxPostEvent(callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(std::move(drive_data), false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DWORD deviceControlRetVal(0);
|
||||||
|
//these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger.
|
||||||
|
//sd cards does trigger WM_DEVICECHANGE messege, usb drives dont
|
||||||
|
BOOL e1;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
e1 = DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
||||||
|
if (e1)
|
||||||
|
break;
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << "Alt Ejecting: FSCTL_LOCK_VOLUME failed. Try " << i << ". " << GetLastError();
|
||||||
|
Sleep(500);
|
||||||
|
}
|
||||||
|
if (e1 == 0) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Alt Ejecting " << volume_access_path << " failed to Lock the device. Ejecting has failed. " << GetLastError();
|
||||||
|
assert(callback_evt_handler);
|
||||||
|
if (callback_evt_handler)
|
||||||
|
wxPostEvent(callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(std::move(drive_data), false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BOOST_LOG_TRIVIAL(info) << "Alt Ejecting: FSCTL_LOCK_VOLUME success.";
|
||||||
|
|
||||||
|
BOOL e2 = DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
||||||
|
if (e2 == 0) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Alt Ejecting " << volume_access_path << " failed to dismount the volume. Ejecting has failed. " << GetLastError();
|
||||||
|
assert(callback_evt_handler);
|
||||||
|
if (callback_evt_handler)
|
||||||
|
wxPostEvent(callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(std::move(drive_data), false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BOOST_LOG_TRIVIAL(info) << "Alt Ejecting: FSCTL_DISMOUNT_VOLUME success.";
|
||||||
|
|
||||||
|
// some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here with FALSE as third parameter, which should set PreventMediaRemoval
|
||||||
|
BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
|
||||||
|
if (error == 0) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Alt Ejecting " << volume_access_path << " failed (IOCTL_STORAGE_EJECT_MEDIA)" << deviceControlRetVal << " " << GetLastError();
|
||||||
|
assert(callback_evt_handler);
|
||||||
|
if (callback_evt_handler)
|
||||||
|
wxPostEvent(callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(std::move(drive_data), false)));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
BOOST_LOG_TRIVIAL(info) << "Alt Ejecting finished";
|
||||||
|
assert(callback_evt_handler);
|
||||||
|
if (callback_evt_handler)
|
||||||
|
wxPostEvent(callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(drive_data), true)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
// Called from UI therefore it blocks the UI thread.
|
// Called from UI therefore it blocks the UI thread.
|
||||||
// It also blocks updates at the worker thread.
|
// It also blocks updates at the worker thread.
|
||||||
@ -561,12 +606,18 @@ void RemovableDriveManager::eject_drive()
|
|||||||
if (m_callback_evt_handler)
|
if (m_callback_evt_handler)
|
||||||
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(*it_drive_data), true)));
|
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(*it_drive_data), true)));
|
||||||
} else {
|
} else {
|
||||||
|
if (m_eject_thread.joinable())
|
||||||
|
m_eject_thread.join();
|
||||||
|
m_eject_thread = boost::thread(eject_alt, m_last_save_path, m_callback_evt_handler, std::move(*it_drive_data));
|
||||||
|
|
||||||
// failed to eject
|
// failed to eject
|
||||||
// this should not happen, throwing exception might be the way here
|
// this should not happen, throwing exception might be the way here
|
||||||
|
/*
|
||||||
BOOST_LOG_TRIVIAL(error) << "Ejecting has failed.";
|
BOOST_LOG_TRIVIAL(error) << "Ejecting has failed.";
|
||||||
assert(m_callback_evt_handler);
|
assert(m_callback_evt_handler);
|
||||||
if (m_callback_evt_handler)
|
if (m_callback_evt_handler)
|
||||||
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));
|
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// drive not found in m_current_drives
|
// drive not found in m_current_drives
|
||||||
|
@ -93,6 +93,7 @@ private:
|
|||||||
bool m_initialized { false };
|
bool m_initialized { false };
|
||||||
wxEvtHandler* m_callback_evt_handler { nullptr };
|
wxEvtHandler* m_callback_evt_handler { nullptr };
|
||||||
|
|
||||||
|
|
||||||
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
// Worker thread, worker thread synchronization and callbacks to the UI thread.
|
// Worker thread, worker thread synchronization and callbacks to the UI thread.
|
||||||
void thread_proc();
|
void thread_proc();
|
||||||
@ -105,6 +106,12 @@ private:
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Another worker thread, used only to perform alt_eject method (external SD cards only).
|
||||||
|
// Does not share data with m_thread
|
||||||
|
boost::thread m_eject_thread;
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
// Called from update() to enumerate removable drives.
|
// Called from update() to enumerate removable drives.
|
||||||
std::vector<DriveData> search_for_removable_drives() const;
|
std::vector<DriveData> search_for_removable_drives() const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user