Compare commits
191 Commits
Version_1.
...
V1.1.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c610a76ba | ||
|
|
1f38488c27 | ||
|
|
f3d619b9b8 | ||
|
|
7db4414838 | ||
|
|
b2ca6dda6a | ||
|
|
ab349ad81b | ||
|
|
53b881144c | ||
|
|
ecff478fd4 | ||
|
|
43fc6f262a | ||
|
|
18a0c7bd80 | ||
|
|
007578e041 | ||
|
|
e6b82214e5 | ||
|
|
5ed1560c59 | ||
|
|
a6ed4e65cb | ||
|
|
ca82d85cc2 | ||
|
|
f69a71d1f5 | ||
|
|
e61c252aee | ||
|
|
146a4a15ed | ||
|
|
4bdb7b76df | ||
|
|
9509b4ffab | ||
|
|
8413db6570 | ||
|
|
bebee387c5 | ||
|
|
7e1ce117f7 | ||
|
|
a23a37cbca | ||
|
|
df89ee4f35 | ||
|
|
141752edf2 | ||
|
|
7a86f18bac | ||
|
|
61424985ac | ||
|
|
ad0b449ad4 | ||
|
|
6e8f38f01a | ||
|
|
24cff06406 | ||
|
|
4277d8118c | ||
|
|
7de8f0817f | ||
|
|
4e223315f8 | ||
|
|
db53ba056c | ||
|
|
5005a1df1b | ||
|
|
2b8deba938 | ||
|
|
6cf7a38bb9 | ||
|
|
be65279049 | ||
|
|
aca63cc7e0 | ||
|
|
90f64f7151 | ||
|
|
84312d4cb8 | ||
|
|
df194b11c8 | ||
|
|
8e9d4777f4 | ||
|
|
5d9df179dd | ||
|
|
8912079f62 | ||
|
|
e505af5cc7 | ||
|
|
11bda61bc8 | ||
|
|
4c9bbc53a3 | ||
|
|
e9146c950a | ||
|
|
3d288f47b1 | ||
|
|
69126621fc | ||
|
|
b7e961c443 | ||
|
|
5b5ff0a1eb | ||
|
|
e033b37e75 | ||
|
|
f25014959b | ||
|
|
78513b7b86 | ||
|
|
0fe9657904 | ||
|
|
f0c70857ae | ||
|
|
e21feab522 | ||
|
|
5b7a66b64c | ||
|
|
c2d1c70e10 | ||
|
|
a1c4285ffc | ||
|
|
ad0215fa2f | ||
|
|
8ef53eceee | ||
|
|
9e5911b2c3 | ||
|
|
4e0134d651 | ||
|
|
783b825007 | ||
|
|
201cb4a2fd | ||
|
|
125abfca57 | ||
|
|
e77259c80b | ||
|
|
0b00c61781 | ||
|
|
13d99fd843 | ||
|
|
f743590509 | ||
|
|
323538586d | ||
|
|
cb05d9d4a0 | ||
|
|
01cbd4c5d4 | ||
|
|
25062b9f99 | ||
|
|
d4f6c80a43 | ||
|
|
ee237cfc16 | ||
|
|
a9889b297e | ||
|
|
508ba0444c | ||
|
|
090eebdabc | ||
|
|
5368acee65 | ||
|
|
c2b5393b82 | ||
|
|
4404fdc03c | ||
|
|
8c0b581581 | ||
|
|
96b64539e2 | ||
|
|
e768b990a8 | ||
|
|
a2ddbe8eb4 | ||
|
|
a3e0809506 | ||
|
|
b13c47456b | ||
|
|
6121002516 | ||
|
|
8fa61058d4 | ||
|
|
0053429d72 | ||
|
|
da44f549e1 | ||
|
|
04ad174e91 | ||
|
|
9c52fb3733 | ||
|
|
128a023c41 | ||
|
|
b9452a91a2 | ||
|
|
cc68470ac8 | ||
|
|
0de9767ff0 | ||
|
|
3217389d20 | ||
|
|
05d820c13d | ||
|
|
68553eba55 | ||
|
|
6e4ada127d | ||
|
|
4d2d510050 | ||
|
|
825c980cef | ||
|
|
2a46a2f415 | ||
|
|
ea3407798b | ||
|
|
9917cfeb69 | ||
|
|
d06a7dfa89 | ||
|
|
ecde3d5864 | ||
|
|
446c2c4e75 | ||
|
|
2466489049 | ||
|
|
b9997e7ee2 | ||
|
|
b6d7c8a367 | ||
|
|
05e2b540ab | ||
|
|
0491f84149 | ||
|
|
88c9efa548 | ||
|
|
e6a64eb5cb | ||
|
|
a630648563 | ||
|
|
d884ef371d | ||
|
|
2f86351eab | ||
|
|
eeeb2a5437 | ||
|
|
8153dcc1b1 | ||
|
|
65a85dae84 | ||
|
|
2b269ea194 | ||
|
|
63f899f4a5 | ||
|
|
4d6feb71b9 | ||
|
|
d783651751 | ||
|
|
9b04886c3a | ||
|
|
3a99562743 | ||
|
|
5183107d79 | ||
|
|
8c672c53c7 | ||
|
|
3039c76417 | ||
|
|
f33a08f704 | ||
|
|
5ccb55ff98 | ||
|
|
764ce01063 | ||
|
|
58e2343a2e | ||
|
|
6485825ad8 | ||
|
|
2387bc9cdb | ||
|
|
63daf0c087 | ||
|
|
516d3a3313 | ||
|
|
470b3a19ed | ||
|
|
759c6732b8 | ||
|
|
c31585e5ba | ||
|
|
8cca851e84 | ||
|
|
00718edfa7 | ||
|
|
f82a8a4ca1 | ||
|
|
4407c9eb62 | ||
|
|
74f7fce027 | ||
|
|
354224679e | ||
|
|
92119cf9f5 | ||
|
|
0401c46f99 | ||
|
|
9d43e47a54 | ||
|
|
354ae2e282 | ||
|
|
4ffa594874 | ||
|
|
e795f88c09 | ||
|
|
e7028531e0 | ||
|
|
0d1dd29341 | ||
|
|
c56cfdb727 | ||
|
|
bfc036deae | ||
|
|
87ab8bd8dd | ||
|
|
ce3ad490b7 | ||
|
|
74d0317dd0 | ||
|
|
1c9ce7ec05 | ||
|
|
2a8cdc3414 | ||
|
|
cea37f9f7d | ||
|
|
48ed13e6f1 | ||
|
|
7a7fb7da00 | ||
|
|
02857e3fd8 | ||
|
|
8cb30a7329 | ||
|
|
1fc08d237c | ||
|
|
ee616bbbb6 | ||
|
|
30e9b00baf | ||
|
|
172b1893e2 | ||
|
|
04b1c22cc6 | ||
|
|
2046b2f21f | ||
|
|
1eb7e979b0 | ||
|
|
82f75eb146 | ||
|
|
7c6e614b3b | ||
|
|
76aaf50055 | ||
|
|
d76b009f40 | ||
|
|
ca4f336d62 | ||
|
|
9856ad7031 | ||
|
|
f6271b0c90 | ||
|
|
bc68a07f47 | ||
|
|
ec446edb36 | ||
|
|
4c3e3eea6d | ||
|
|
4bdbc32044 |
2
.gitignore
vendored
@@ -12,7 +12,6 @@ xs/MANIFEST.bak
|
||||
xs/assertlib*
|
||||
.init_bundle.ini
|
||||
.vs/*
|
||||
local-lib
|
||||
/src/TAGS
|
||||
/.vscode/
|
||||
build-linux/*
|
||||
@@ -22,3 +21,4 @@ deps/build-linux/*
|
||||
**/.idea/
|
||||
.pkg_cache
|
||||
CMakeUserPresets.json
|
||||
/src/slic3r/QIDI
|
||||
|
||||
132
Build.PL
@@ -1,132 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
print "This script is currently used for installing Perl dependenices for running\n";
|
||||
print "the libslic3r unit / integration tests through Perl prove.\n";
|
||||
print "If you don't plan to run the unit / integration tests, you don't need to\n";
|
||||
print "install these dependencies to build and run QIDISlicer.\n";
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Config;
|
||||
use File::Spec;
|
||||
|
||||
my %prereqs = qw(
|
||||
Devel::CheckLib 0
|
||||
ExtUtils::MakeMaker 6.80
|
||||
ExtUtils::ParseXS 3.22
|
||||
ExtUtils::XSpp 0
|
||||
ExtUtils::XSpp::Cmd 0
|
||||
ExtUtils::CppGuess 0
|
||||
ExtUtils::Typemaps 0
|
||||
ExtUtils::Typemaps::Basic 0
|
||||
File::Basename 0
|
||||
File::Spec 0
|
||||
Getopt::Long 0
|
||||
Module::Build::WithXSpp 0.14
|
||||
Moo 1.003001
|
||||
POSIX 0
|
||||
Scalar::Util 0
|
||||
Test::More 0
|
||||
IO::Scalar 0
|
||||
Time::HiRes 0
|
||||
);
|
||||
my %recommends = qw(
|
||||
Class::XSAccessor 0
|
||||
Test::Harness 0
|
||||
);
|
||||
|
||||
my $sudo = grep { $_ eq '--sudo' } @ARGV;
|
||||
my $nolocal = grep { $_ eq '--nolocal' } @ARGV;
|
||||
|
||||
my @missing_prereqs = ();
|
||||
if ($ENV{SLIC3R_NO_AUTO}) {
|
||||
foreach my $module (sort keys %prereqs) {
|
||||
my $version = $prereqs{$module};
|
||||
next if eval "use $module $version; 1";
|
||||
push @missing_prereqs, $module if exists $prereqs{$module};
|
||||
print "Missing prerequisite $module $version\n";
|
||||
}
|
||||
foreach my $module (sort keys %recommends) {
|
||||
my $version = $recommends{$module};
|
||||
next if eval "use $module $version; 1";
|
||||
print "Missing optional $module $version\n";
|
||||
}
|
||||
} else {
|
||||
my @try = (
|
||||
$ENV{CPANM} // (),
|
||||
File::Spec->catfile($Config{sitebin}, 'cpanm'),
|
||||
File::Spec->catfile($Config{installscript}, 'cpanm'),
|
||||
);
|
||||
|
||||
my $cpanm;
|
||||
foreach my $path (@try) {
|
||||
if (-e $path) { # don't use -x because it fails on Windows
|
||||
$cpanm = $path;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if (!$cpanm) {
|
||||
if ($^O =~ /^(?:darwin|linux)$/ && system(qw(which cpanm)) == 0) {
|
||||
$cpanm = 'cpanm';
|
||||
}
|
||||
}
|
||||
die <<'EOF'
|
||||
cpanm was not found. Please install it before running this script.
|
||||
|
||||
There are several ways to install cpanm, try one of these:
|
||||
|
||||
apt-get install cpanminus
|
||||
curl -L http://cpanmin.us | perl - --sudo App::cpanminus
|
||||
cpan App::cpanminus
|
||||
|
||||
If it is installed in a non-standard location you can do:
|
||||
|
||||
CPANM=/path/to/cpanm perl Build.PL
|
||||
|
||||
EOF
|
||||
if !$cpanm;
|
||||
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';
|
||||
|
||||
my %modules = (%prereqs, %recommends);
|
||||
foreach my $module (sort keys %modules) {
|
||||
my $version = $modules{$module};
|
||||
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}) {
|
||||
push @missing_prereqs, $module;
|
||||
} else {
|
||||
printf "Don't worry, this module is optional.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "\n";
|
||||
print "In the next step, you need to build the QIDISlicer 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__
|
||||
@@ -29,7 +29,6 @@ option(SLIC3R_FHS "Assume QIDISlicer is to be installed in a FHS d
|
||||
option(SLIC3R_PCH "Use precompiled headers" 1)
|
||||
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
|
||||
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
|
||||
option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and integration tests" 0)
|
||||
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
|
||||
option(SLIC3R_UBSAN "Enable UBSan on Clang and GCC" 0)
|
||||
option(SLIC3R_ENABLE_FORMAT_STEP "Enable compilation of STEP file support" ON)
|
||||
@@ -72,7 +71,6 @@ option(SLIC3R_BUILD_TESTS "Build unit tests" ON)
|
||||
|
||||
if (IS_CROSS_COMPILE)
|
||||
message("Detected cross compilation setup. Tests and encoding checks will be forcedly disabled!")
|
||||
set(SLIC3R_PERL_XS OFF CACHE BOOL "" FORCE)
|
||||
set(SLIC3R_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
endif ()
|
||||
|
||||
@@ -165,9 +163,6 @@ if(NOT WIN32)
|
||||
add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>")
|
||||
endif()
|
||||
|
||||
# To be able to link libslic3r with the Perl XS module.
|
||||
# Once we get rid of Perl and libslic3r is linked statically, we can get rid of -fPIC
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# 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
|
||||
@@ -239,7 +234,8 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
|
||||
endif ()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder" )
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-enum-constexpr-conversion" )
|
||||
|
||||
# On GCC and Clang, no return from a non-void function is a warning only. Here, we make it an error.
|
||||
add_compile_options(-Werror=return-type)
|
||||
|
||||
@@ -608,12 +604,6 @@ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Q
|
||||
|
||||
add_dependencies(gettext_make_pot hintsToPot)
|
||||
|
||||
# Perl bindings, currently only used for the unit / integration tests of libslic3r.
|
||||
# Also runs the unit / integration tests.
|
||||
#FIXME Port the tests into C++ to finally get rid of the Perl!
|
||||
if (SLIC3R_PERL_XS)
|
||||
add_subdirectory(xs)
|
||||
endif ()
|
||||
|
||||
if(SLIC3R_BUILD_SANDBOXES)
|
||||
add_subdirectory(sandboxes)
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
{
|
||||
"build_systems":
|
||||
[
|
||||
{
|
||||
"name": "List",
|
||||
//"file_regex": " at ([^-\\s]*) line ([0-9]*)",
|
||||
// "file_regex": " at (D\\:\\/src\\/Slic3r\\/.*?) line ([0-9]*)",
|
||||
"shell_cmd": "ls -l"
|
||||
},
|
||||
{
|
||||
"name": "Run",
|
||||
"working_dir": "$project_path",
|
||||
"file_regex": " at (.*?) line ([0-9]*)",
|
||||
// "shell_cmd": "chdir & perl slic3r.pl --DataDir \"C:\\Users\\Public\\Documents\\QIDI3D\\Slic3r settings MK2\" --gui \"..\\Slic3r-tests\\gap fill torture 20 -rt.stl\""
|
||||
"shell_cmd": "chdir & perl slic3r.pl"
|
||||
},
|
||||
{
|
||||
"name": "full",
|
||||
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
|
||||
"shell_cmd": "chdir & perl Build.pl"
|
||||
},
|
||||
{
|
||||
"name": "xs",
|
||||
"working_dir": "$project_path/build",
|
||||
// for Visual Studio:
|
||||
"file_regex": "^(..[^:]*)\\(([0-9]+)\\)(.*)$",
|
||||
// For GCC:
|
||||
// "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
|
||||
"shell_cmd": "chdir & ninja -j 6 -v",
|
||||
"env": {
|
||||
// "PATH": "C:\\Program Files (x86)\\MSBuild\\12.0\\bin\\amd64;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\BIN\\amd64;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\Common7\\IDE;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\Common7\\Tools;%PATH%;c:\\wperl64d\\site\\bin;c:\\wperl64d\\bin",
|
||||
// "PERL_CPANM_HOME": "c:\\wperl64d\\cpanm",
|
||||
// "WXDIR": "D:\\src-perl\\wxWidgets-3.0.3-beta1",
|
||||
// "BOOST_DIR": "D:\\src-perl\\boost_1_61_0",
|
||||
// "BOOST_INCLUDEDIR": "D:\\src-perl\\boost_1_61_0",
|
||||
// "BOOST_LIBRARYDIR": "D:\\src-perl\\boost_1_61_0\\stage\\x64\\lib",
|
||||
// "SLIC3R_STATIC": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "xs & run",
|
||||
"working_dir": "$project_path/build",
|
||||
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
|
||||
"shell_cmd": "chdir & ninja -j 6 & cd .. & perl slic3r.pl --gui \"..\\Slic3r-tests\\star3-big2.stl\""
|
||||
},
|
||||
{
|
||||
"name": "Slic3r - clean",
|
||||
"working_dir": "$project_path/build",
|
||||
"file_regex": "^(..[^:]*)(?::|\\()([0-9]+)(?::|\\))(?:([0-9]+):)?\\s*(.*)",
|
||||
"shell_cmd": ["chdir & ninja clean"]
|
||||
},
|
||||
{
|
||||
"name": "run tests",
|
||||
"working_dir": "$project_path/build",
|
||||
// for Visual Studio:
|
||||
"file_regex": "^(..[^:]*)\\(([0-9]+)\\)(.*)$",
|
||||
"shell_cmd": "chdir & ctest --verbose"
|
||||
},
|
||||
{
|
||||
"name": "Clean & Configure",
|
||||
"working_dir": "$project_path",
|
||||
// for Visual Studio:
|
||||
"file_regex": "^(..[^:]*)(?::|\\()([0-9]+)(?::|\\))(?:([0-9]+):)?\\s*(.*)",
|
||||
"shell_cmd": "chdir & rmdir /S /Q build & mkdir build & cd build & cmake -G Ninja .. -DCMAKE_COLOR_MAKEFILE=OFF -DCMAKE_RULE_PROGRESS=OFF -DCMAKE_RULE_MESSAGES=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo"
|
||||
},
|
||||
{
|
||||
"name": "Configure",
|
||||
"working_dir": "$project_path/build",
|
||||
// for Visual Studio:
|
||||
"file_regex": "^(..[^:]*)(?::|\\()([0-9]+)(?::|\\))(?:([0-9]+):)?\\s*(.*)",
|
||||
"shell_cmd": "cmake -G Ninja .. -DCMAKE_COLOR_MAKEFILE=OFF -DCMAKE_RULE_PROGRESS=OFF -DCMAKE_RULE_MESSAGES=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo"
|
||||
}
|
||||
],
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
"path": ".",
|
||||
// "folder_exclude_patterns": [".svn", "._d", ".metadata", ".settings"],
|
||||
"file_exclude_patterns": ["XS.c", "*.pch", "*.ilk", "*.js" ]
|
||||
}
|
||||
],
|
||||
|
||||
"settings":
|
||||
{
|
||||
"sublimegdb_workingdir": "${folder:${project_path:run}}",
|
||||
// NOTE: You MUST provide --interpreter=mi for the plugin to work
|
||||
// "sublimegdb_commandline": "D:\\Qt\\Tools\\mingw492_32\\bin\\gdb.exe --interpreter=mi -ex 'target localhost:2345'",
|
||||
// "sublimegdb_commandline": "D:\\Qt\\Tools\\mingw492_32\\bin\\gdb.exe --interpreter=mi perl --args perl slic3r.pl",
|
||||
// "sublimegdb_commandline": "D:\\Qt\\Tools\\mingw492_32\\bin\\gdb.exe --interpreter=mi perl --args slic3r.pl ",
|
||||
// "sublimegdb_commandline": "D:\\Qt\\Tools\\mingw492_32\\bin\\gdb.exe --interpreter=mi -e C:\\Strawberry\\perl\\bin\\perl.exe -s C:\\Strawberry\\perl\\site\\lib\\auto\\Slic3r\\XS\\XS.xs.dll --args perl slic3r.pl -j 1 --gui D:\\src\\Slic3r-tests\\star3-big.stl",
|
||||
"sublimegdb_commandline": "D:\\Qt\\Tools\\mingw492_32\\bin\\gdb.exe --interpreter=mi perl.exe --args perl slic3r.pl -j 1 --gui", // D:\\src\\Slic3r-tests\\star3-big.stl",
|
||||
// "sublimegdb_commandline": "D:\\Qt\\Tools\\mingw492_32\\bin\\gdb.exe --interpreter=mi -x slic3r.gdb",
|
||||
// "arguments": "slic3r -j 1 --gui ../Slic3r-tests/star3-big.stl",
|
||||
// "arguments": "../slic3r.pl -j 1 --gui",
|
||||
// "sublimegdb_exec_cmd": "-exec-continue",
|
||||
|
||||
// Add "pending breakpoints" for symbols that are dynamically loaded from
|
||||
// external shared libraries
|
||||
"debug_ext" : true,
|
||||
"run_after_init": false,
|
||||
"close_views": false
|
||||
}
|
||||
}
|
||||
115
README.md
@@ -4,30 +4,123 @@
|
||||
# QIDISlicer
|
||||
QIDISlicer is a professional 3D printer slicing software,which is perfectly compatible with all printers and 3D printing filaments of QIDI Technology. Multi-platform support, simple inerface, easy to use, complate functions, easy to learn 3D printing.
|
||||
|
||||
**Notice:QIDISlicer as a new software dedicated to QIDI's new high speed printers, please make sure your firmware version is V 4.0.0 or above.**
|
||||
|
||||
QIDISlicer is based on [PrusaSlicer](https://github.com/prusa3d/PrusaSlicer) by Prusa Research, which is from [Slic3r](https://github.com/Slic3r/Slic3r) by Alessandro Ranellucci and the RepRap community.
|
||||
Thanks to PrusaSlicer, Bambulab and OrcaSlicer for their contributions to the 3D printing community.
|
||||
|
||||
See the [QIDI's homepage](https://qidi3d.com) for more information.
|
||||
|
||||
### Firmware
|
||||
<details open>
|
||||
<summary>Content Navigation</summary>
|
||||
<ol>
|
||||
<li>
|
||||
<a href="#function-introduction">Function Introduction</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#wiki">Wiki</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#Supporting-QIDI-Link-App">Supporting QIDI Link App</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#report-issues-and-make-suggestions">Report Issues and Make Suggestions</a>
|
||||
<ul>
|
||||
<li><a href="#some-formatting-requirements">Some Formatting Requirements</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#license">License</a>
|
||||
</li>
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
You can find the printer's firmware here:
|
||||
----
|
||||
|
||||
[X-MAX 3](https://github.com/QIDITECH/QIDI_MAX3)
|
||||
## Function Introduction
|
||||
|
||||
[X-Plus 3](https://github.com/QIDITECH/QIDI_PLUS3)
|
||||
<p align="center">
|
||||
<img src="/readmeRes/UI.png" alt="UI">
|
||||
</p>
|
||||
|
||||
[X-smart 3](https://github.com/QIDITECH/QIDI_SMART3)
|
||||
### Key features are:
|
||||
|
||||
### Report Issues and Make Suggestions
|
||||
* **Slicer:** Fast and stable 3D model slicer
|
||||
* **Printer:** Perfect compatibility with all high-speed 3D printers of QIDI TECH
|
||||
* **Filament:** Perfect compatibility with all filaments of QIDI TECH and some general filaments
|
||||
* **LAN:** The printer can be directly connected through IP, convenient, safe and stable
|
||||
* **Internet:** Remote connection, start printing anytime, anywhere
|
||||
|
||||
Please send your question in the form of video or pictures to us through the [After-Sales Service](https://qidi3d.com/pages/warranty-policy-after-sales-support), we will reply to your information within 12 hours.
|
||||
### Other major features are:
|
||||
|
||||
Please try to contact us through [After-Sales Service](https://qidi3d.com/pages/warranty-policy-after-sales-support) and report problems or suggestions. On github, we cannot obtain your order information, operation records and other private intelligence, nor can we generate after-sales orders, send repair files, etc. Thank you for your understanding and cooperation.
|
||||
* **Model:** A variety of model operations, move, scale, rotate, crop, color, repair, combine, split, and more
|
||||
* **Parameter:** Rich parameter Settings, fine adjustment for a variety of complex models and application scenarios
|
||||
* **Calibration:** Multiple calibration functions to adjust the best parameters according to the actual situation
|
||||
|
||||
### License
|
||||
----
|
||||
|
||||
## wiki
|
||||
|
||||
The wiki below aims to provide a detailed explanation of the QIDISlicer settings, how to get the most out of them as
|
||||
well as how to calibrate and setup your printer.
|
||||
|
||||
The wiki is work in progress so bear with us while we get it up and running!
|
||||
|
||||
**[Access the wiki here](https://wiki.qidi3d.com/en/software/QIDISlicier)**
|
||||
|
||||
----
|
||||
|
||||
## Supporting QIDI Link App
|
||||
|
||||
**[Access QIDI Link App Guide Here](https://wiki.qidi3d.com/en/app)**
|
||||
|
||||
The supporting QIDI Link App supports IOS and Android platforms. In the app, you can scan the code to connect to the printer, remotely monitor the printer's printing progress, control the printer's printing parameters, and perform operations such as feeding and returning materials.
|
||||
<p align="center">
|
||||
<img src="/readmeRes/qidilink.png" alt="Add filament option ——Seal">
|
||||
</p>
|
||||
|
||||
----
|
||||
|
||||
## Report Issues and Make Suggestions
|
||||
|
||||
Please send your question in the form of video or pictures to us through
|
||||
the [After-Sales Service](https://qidi3d.com/pages/warranty-policy-after-sales-support), we will reply to your
|
||||
information within 12 hours.
|
||||
|
||||
Please try to contact us through [After-Sales Service](https://qidi3d.com/pages/warranty-policy-after-sales-support) and
|
||||
report problems or suggestions. On github, we cannot obtain your order information, operation records and other private
|
||||
intelligence, nor can we generate after-sales orders, send repair files, etc. Thank you for your understanding and
|
||||
cooperation.
|
||||
|
||||
### Some formatting requirements
|
||||
|
||||
#### Issue Title:
|
||||
|
||||
Briefly describe the issue (e.g., `could not open file`)
|
||||
|
||||
#### Description:
|
||||
|
||||
Provide a detailed description of the issue.This will help our engineers quickly locate the problem and assist you in
|
||||
resolving it
|
||||
|
||||
- **Issue Description**:
|
||||
- A clear explanation of the problem.
|
||||
- Compare the expected behavior with the actual behavior.
|
||||
|
||||
- **Steps to Reproduce**:
|
||||
1. Step one
|
||||
2. Step two
|
||||
3. Step three
|
||||
|
||||
- Specific steps to reproduce the issue. Include a precise sequence of actions if possible.
|
||||
|
||||
- **Additional Information**:
|
||||
- **Screenshots/Images**: Attach relevant screenshots or images that help in understanding the issue. Please add or
|
||||
link to images here.
|
||||
- **Environment Information**:
|
||||
- Operating System Version
|
||||
- Browser/Application Version
|
||||
- Other relevant environment details
|
||||
|
||||
## License
|
||||
|
||||
QIDISlicer is licensed under the _GNU Affero General Public License, version 3_. QIDISlicer is based on PrusaSlicer by PrusaResearch.
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
# 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 \$gui_toolkit = Alien::wxWidgets->config->{toolkit};
|
||||
#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);
|
||||
cmake_set_var('GUI_TOOLKIT', \$gui_toolkit);
|
||||
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}")
|
||||
message(STATUS " AlienWx_GUI_TOOLKIT = ${AlienWx_GUI_TOOLKIT}")
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(AlienWx
|
||||
REQUIRED_VARS AlienWx_INCLUDE_DIRS AlienWx_LIBRARIES
|
||||
# HANDLE_COMPONENTS
|
||||
VERSION_VAR AlienWx_VERSION)
|
||||
@@ -1,88 +0,0 @@
|
||||
# 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)
|
||||
5
deps/+LibBGCode/LibBGCode.cmake
vendored
@@ -1,9 +1,8 @@
|
||||
set(LibBGCode_SOURCE_DIR "" CACHE PATH "Optionally specify local LibBGCode source directory")
|
||||
|
||||
set(_source_dir_line
|
||||
URL https://github.com/prusa3d/libbgcode/archive/bc390aab4427589a6402b4c7f65cf4d0a8f987ec.zip
|
||||
URL_HASH SHA256=0c86cb67232089728233014f937e2a07d133a61e31dd8811a9c905e563a49f24
|
||||
)
|
||||
URL https://github.com/prusa3d/libbgcode/archive/6f43cb004ef3d3bda37dde49f6235e24d2717629.zip
|
||||
URL_HASH SHA256=eb5198caecb6a693a294af6a56c37b0adb1eb159a34a9c3116970b80659ee9f9)
|
||||
|
||||
if (LibBGCode_SOURCE_DIR)
|
||||
set(_source_dir_line "SOURCE_DIR;${LibBGCode_SOURCE_DIR};BUILD_ALWAYS;ON")
|
||||
|
||||
2
deps/+OpenVDB/OpenVDB.cmake
vendored
@@ -15,7 +15,7 @@ endif ()
|
||||
|
||||
add_cmake_project(OpenVDB
|
||||
# 8.2 patched
|
||||
URL https://github.com/tamasmeszaros/openvdb/archive/a68fd58d0e2b85f01adeb8b13d7555183ab10aa5.zip
|
||||
URL https://github.com/prusa3d/openvdb/archive/a68fd58d0e2b85f01adeb8b13d7555183ab10aa5.zip
|
||||
URL_HASH SHA256=f353e7b99bd0cbfc27ac9082de51acf32a8bc0b3e21ff9661ecca6f205ec1d81
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# This package loads all the non-GUI Slic3r perl packages.
|
||||
|
||||
package Slic3r;
|
||||
|
||||
# Copyright holder: Alessandro Ranellucci
|
||||
# This application is licensed under the GNU Affero General Public License, version 3
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Config;
|
||||
require v5.10;
|
||||
|
||||
our $VERSION = VERSION();
|
||||
our $BUILD = BUILD();
|
||||
our $FORK_NAME = FORK_NAME();
|
||||
|
||||
our $debug = 0;
|
||||
sub debugf {
|
||||
printf @_ if $debug;
|
||||
}
|
||||
|
||||
our $loglevel = 0;
|
||||
|
||||
BEGIN {
|
||||
$debug = 1 if (defined($ENV{'SLIC3R_DEBUGOUT'}) && $ENV{'SLIC3R_DEBUGOUT'} == 1);
|
||||
print "Debugging output enabled\n" if $debug;
|
||||
}
|
||||
|
||||
use FindBin;
|
||||
|
||||
use Moo 1.003001;
|
||||
|
||||
use Slic3r::XS; # import all symbols (constants etc.) before they get parsed
|
||||
use Slic3r::Config;
|
||||
use Slic3r::GCode::Reader;
|
||||
use Slic3r::Line;
|
||||
use Slic3r::Model;
|
||||
use Slic3r::Point;
|
||||
use Slic3r::Polygon;
|
||||
use Slic3r::Polyline;
|
||||
our $build = eval "use Slic3r::Build; 1";
|
||||
|
||||
# Scaling between the float and integer coordinates.
|
||||
# Floats are in mm.
|
||||
use constant SCALING_FACTOR => 0.000001;
|
||||
|
||||
# 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);
|
||||
|
||||
1;
|
||||
@@ -1,32 +0,0 @@
|
||||
# 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;
|
||||
use utf8;
|
||||
|
||||
use List::Util qw(first max);
|
||||
|
||||
# C++ Slic3r::PrintConfigDef exported as a Perl hash of hashes.
|
||||
# The C++ counterpart is a constant singleton.
|
||||
our $Options = print_config_def();
|
||||
|
||||
# Generate accessors.
|
||||
{
|
||||
no strict 'refs';
|
||||
for my $opt_key (keys %$Options) {
|
||||
*{$opt_key} = sub {
|
||||
#print "Slic3r::Config::accessor $opt_key\n";
|
||||
$_[0]->get($opt_key)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
package Slic3r::Config::Static;
|
||||
use parent 'Slic3r::Config';
|
||||
|
||||
sub Slic3r::Config::GCode::new { Slic3r::Config::Static::new_GCodeConfig }
|
||||
sub Slic3r::Config::Print::new { Slic3r::Config::Static::new_PrintConfig }
|
||||
|
||||
1;
|
||||
@@ -1,90 +0,0 @@
|
||||
# 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', '_extrusion_axis', 'config'),
|
||||
);
|
||||
}
|
||||
|
||||
sub parse {
|
||||
my $self = shift;
|
||||
my ($gcode, $cb) = @_;
|
||||
|
||||
foreach my $raw_line (split /\R+/, $gcode) {
|
||||
print "$raw_line\n" if $Verbose || $ENV{SLIC3R_TESTS_GCODE};
|
||||
my $line = $raw_line;
|
||||
$line =~ s/\s*;(.*)//; # strip comment
|
||||
my %info = (comment => $1, raw => $raw_line);
|
||||
|
||||
# parse command
|
||||
my ($command, @args) = split /\s+/, $line;
|
||||
$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 {
|
||||
$info{"dist_$axis"} = 0;
|
||||
$info{"new_$axis"} = $self->$axis;
|
||||
}
|
||||
}
|
||||
$info{dist_XY} = sqrt(($info{dist_X}**2) + ($info{dist_Y}**2));
|
||||
if (exists $args{E}) {
|
||||
if ($info{dist_E} > 0) {
|
||||
$info{extruding} = 1;
|
||||
} elsif ($info{dist_E} < 0) {
|
||||
$info{retracting} = 1
|
||||
}
|
||||
} else {
|
||||
$info{travel} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# run callback
|
||||
$cb->($self, $command, \%args, \%info);
|
||||
|
||||
# update coordinates
|
||||
if ($command =~ /^(?:G[01]|G92)$/) {
|
||||
for my $axis (@AXES, 'F') {
|
||||
$self->$axis($args{$axis}) if exists $args{$axis};
|
||||
}
|
||||
}
|
||||
|
||||
# TODO: update temperatures
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,36 +0,0 @@
|
||||
package Slic3r::Geometry;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
# Exported by this module. The last section starting with convex_hull is exported by Geometry.xsp
|
||||
our @EXPORT_OK = qw(
|
||||
PI epsilon
|
||||
|
||||
scale
|
||||
unscale
|
||||
scaled_epsilon
|
||||
|
||||
X Y Z
|
||||
convex_hull
|
||||
deg2rad
|
||||
rad2deg
|
||||
);
|
||||
|
||||
use constant PI => 4 * atan2(1, 1);
|
||||
use constant A => 0;
|
||||
use constant B => 1;
|
||||
use constant X1 => 0;
|
||||
use constant Y1 => 1;
|
||||
use constant X2 => 2;
|
||||
use constant Y2 => 3;
|
||||
|
||||
sub epsilon () { 1E-4 }
|
||||
sub scaled_epsilon () { epsilon / &Slic3r::SCALING_FACTOR }
|
||||
|
||||
sub scale ($) { $_[0] / &Slic3r::SCALING_FACTOR }
|
||||
sub unscale ($) { $_[0] * &Slic3r::SCALING_FACTOR }
|
||||
|
||||
1;
|
||||
@@ -1,8 +0,0 @@
|
||||
package Slic3r::Line;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# a line is a two-points line
|
||||
use parent 'Slic3r::Polyline';
|
||||
|
||||
1;
|
||||
@@ -1,136 +0,0 @@
|
||||
# extends C++ class Slic3r::Model
|
||||
package Slic3r::Model;
|
||||
|
||||
use List::Util qw(first max any);
|
||||
|
||||
sub merge {
|
||||
my $class = shift;
|
||||
my @models = @_;
|
||||
|
||||
my $new_model = ref($class)
|
||||
? $class
|
||||
: $class->new;
|
||||
|
||||
$new_model->add_object($_) for map @{$_->objects}, @models;
|
||||
return $new_model;
|
||||
}
|
||||
|
||||
sub add_object {
|
||||
my $self = shift;
|
||||
|
||||
if (@_ == 1) {
|
||||
# we have a Model::Object
|
||||
my ($object) = @_;
|
||||
return $self->_add_object_clone($object);
|
||||
} else {
|
||||
my (%args) = @_;
|
||||
|
||||
my $new_object = $self->_add_object;
|
||||
|
||||
$new_object->set_name($args{name})
|
||||
if defined $args{name};
|
||||
$new_object->set_input_file($args{input_file})
|
||||
if defined $args{input_file};
|
||||
$new_object->config->apply($args{config})
|
||||
if defined $args{config};
|
||||
$new_object->set_layer_height_ranges($args{layer_height_ranges})
|
||||
if defined $args{layer_height_ranges};
|
||||
$new_object->set_origin_translation($args{origin_translation})
|
||||
if defined $args{origin_translation};
|
||||
|
||||
return $new_object;
|
||||
}
|
||||
}
|
||||
|
||||
sub set_material {
|
||||
my $self = shift;
|
||||
my ($material_id, $attributes) = @_;
|
||||
|
||||
my $material = $self->add_material($material_id);
|
||||
$material->apply($attributes // {});
|
||||
return $material;
|
||||
}
|
||||
|
||||
# Extends C++ class Slic3r::ModelMaterial
|
||||
package Slic3r::Model::Material;
|
||||
|
||||
sub apply {
|
||||
my ($self, $attributes) = @_;
|
||||
$self->set_attribute($_, $attributes{$_}) for keys %$attributes;
|
||||
}
|
||||
|
||||
# Extends C++ class Slic3r::ModelObject
|
||||
package Slic3r::Model::Object;
|
||||
|
||||
use List::Util qw(first sum);
|
||||
|
||||
sub add_volume {
|
||||
my $self = shift;
|
||||
|
||||
my $new_volume;
|
||||
if (@_ == 1) {
|
||||
# we have a Model::Volume
|
||||
my ($volume) = @_;
|
||||
|
||||
$new_volume = $self->_add_volume_clone($volume);
|
||||
|
||||
if ($volume->material_id ne '') {
|
||||
# merge material attributes and config (should we rename materials in case of duplicates?)
|
||||
if (my $material = $volume->object->model->get_material($volume->material_id)) {
|
||||
my %attributes = %{ $material->attributes };
|
||||
if ($self->model->has_material($volume->material_id)) {
|
||||
%attributes = (%attributes, %{ $self->model->get_material($volume->material_id)->attributes })
|
||||
}
|
||||
my $new_material = $self->model->set_material($volume->material_id, {%attributes});
|
||||
$new_material->config->apply($material->config);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my %args = @_;
|
||||
|
||||
$new_volume = $self->_add_volume($args{mesh});
|
||||
|
||||
$new_volume->set_name($args{name})
|
||||
if defined $args{name};
|
||||
$new_volume->set_material_id($args{material_id})
|
||||
if defined $args{material_id};
|
||||
$new_volume->set_modifier($args{modifier})
|
||||
if defined $args{modifier};
|
||||
$new_volume->config->apply($args{config})
|
||||
if defined $args{config};
|
||||
}
|
||||
|
||||
if ($new_volume->material_id ne '' && !defined $self->model->get_material($new_volume->material_id)) {
|
||||
# TODO: this should be a trigger on Volume::material_id
|
||||
$self->model->set_material($new_volume->material_id);
|
||||
}
|
||||
|
||||
$self->invalidate_bounding_box;
|
||||
|
||||
return $new_volume;
|
||||
}
|
||||
|
||||
sub add_instance {
|
||||
my $self = shift;
|
||||
|
||||
if (@_ == 1) {
|
||||
# we have a Model::Instance
|
||||
my ($instance) = @_;
|
||||
return $self->_add_instance_clone($instance);
|
||||
} else {
|
||||
my (%args) = @_;
|
||||
|
||||
my $new_instance = $self->_add_instance;
|
||||
|
||||
$new_instance->set_rotations($args{rotation})
|
||||
if defined $args{rotation};
|
||||
$new_instance->set_scaling_factors($args{scaling_factor})
|
||||
if defined $args{scaling_factor};
|
||||
$new_instance->set_offset($args{offset})
|
||||
if defined $args{offset};
|
||||
|
||||
return $new_instance;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,28 +0,0 @@
|
||||
package Slic3r::Point;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub new_scale {
|
||||
my $class = shift;
|
||||
return $class->new(map Slic3r::Geometry::scale($_), @_);
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -1,8 +0,0 @@
|
||||
package Slic3r::Polygon;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# a polygon is a closed polyline.
|
||||
use parent 'Slic3r::Polyline';
|
||||
|
||||
1;
|
||||
@@ -1,13 +0,0 @@
|
||||
package Slic3r::Polyline;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::Geometry qw(X Y);
|
||||
|
||||
sub new_scale {
|
||||
my $class = shift;
|
||||
my @points = map { ref($_) eq 'Slic3r::Point' ? $_->pp : $_ } @_;
|
||||
return $class->new(map [ Slic3r::Geometry::scale($_->[X]), Slic3r::Geometry::scale($_->[Y]) ], @points);
|
||||
}
|
||||
|
||||
1;
|
||||
BIN
readmeRes/UI.png
Normal file
|
After Width: | Height: | Size: 168 KiB |
BIN
readmeRes/qidilink.png
Normal file
|
After Width: | Height: | Size: 560 KiB |
BIN
resources/icon.icns
Normal file
BIN
resources/icons/Q1 Pro_thumbnail.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 7.1 KiB |
@@ -1,56 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#4479FB" d="M196,256H60c-33.1,0-60-26.9-60-60V60C0,26.9,26.9,0,60,0h136c33.1,0,60,26.9,60,60v136
|
||||
C256,229.1,229.1,256,196,256z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M194.5,188.5c-7.6-3.5-15-7.5-22.2-11.8c-6.8-4.2-13.1-8.5-18.7-12.9c17.1-13.5,23.2-36.1,13.2-56.7
|
||||
c-12.7-26.1-46.3-39.2-75.2-29.1c-31.6,11-41,43-25.8,68.7c-48.2-53.1,7.3-123.8,85-99.8c26.2,8.1,48.9,25.8,60.8,50.2
|
||||
C227.4,129.7,219.5,165.3,194.5,188.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M34.7,158.5c17.6,36.2,59,57.6,100.3,54.8c-16.2-6.1-32-16-45-29c-7.8-7.8-13.8-16-18.2-24.2
|
||||
c-9.1-6.3-16.9-14.3-23-23.6C37.5,118.9,34.6,99.6,39,82C24.6,104.1,21.9,132.2,34.7,158.5L34.7,158.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M234.5,206.6c-28.2,6.1-68-4.1-97.8-26.7c-35.1-26.6-43.5-60.9-19.9-78.1c-8,18.8,7,47.1,40.6,71.4
|
||||
C181.1,190.4,209.2,202,234.5,206.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M187.4,212.9c-29.6,5.2-68.1-7.9-94.8-34.2c-33-32.6-35.5-73.3-5.5-90.8c12-7,27.4-9.2,43.6-7.3
|
||||
c-4.7,1.3-9.2,3.1-13.2,5.4c-30,17.5-26.8,58.9,7.2,92.4C142.6,196.1,165.4,208.1,187.4,212.9L187.4,212.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M60,252c-30.9,0-56-25.1-56-56V60C4,29.1,29.1,4,60,4h136c30.9,0,56,25.1,56,56v136c0,30.9-25.1,56-56,56
|
||||
H60z"/>
|
||||
<g>
|
||||
<path fill="#303AB2" d="M196,8c28.7,0,52,23.3,52,52v136c0,28.7-23.3,52-52,52H60c-28.7,0-52-23.3-52-52V60C8,31.3,31.3,8,60,8
|
||||
H196 M196,0H60C26.9,0,0,26.9,0,60v136c0,33.1,26.9,60,60,60h136c33.1,0,60-26.9,60-60V60C256,26.9,229.1,0,196,0L196,0z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path fill="#303AB2" d="M145,177.9v-13.2v-21.3c0-2.3,1.2-4.5,3.2-5.6l28.3-16.3l13-7.5V93c0-4.6-2.5-8.9-6.5-11.2l-57.8-33.4
|
||||
c-4-2.3-8.9-2.3-13,0L54.5,81.8c-4,2.3-6.5,6.6-6.5,11.2v66.7c0,4.6,2.5,8.9,6.5,11.2l57.8,33.4c4,2.3,8.9,2.3,13,0l19.7-11.4l0,0
|
||||
V177.9z M125.2,115.2c-4,2.3-6.5,6.6-6.5,11.2v55.4c0,5-5.4,8.1-9.7,5.6l-44.8-25.9c-2-1.2-3.2-3.3-3.2-5.6V96.7
|
||||
c0-2.3,1.2-4.5,3.2-5.6l51.3-29.6c2-1.2,4.5-1.2,6.5,0l38.3,22.1c4.3,2.5,4.3,8.7,0,11.2L125.2,115.2z"/>
|
||||
<path fill="#303AB2" d="M198.3,108.9l-8.8,5.1v18.2v1.8v22.1v7.5c0,2.3-1.2,4.4-3.2,5.5l0,0l-0.7,0.4l-0.9,0.5l-8.1,4.7l-5.2,3
|
||||
L145,192.9l0,0v6.4v3.1v0.1c0,0,0,0,0,0v0.4c0.1,4.8,5.2,7.9,9.5,5.7l0.2-0.1l5.2-3l44.9-26c2-1.2,3.2-3.3,3.2-5.6v-59.4
|
||||
C208,109.5,202.6,106.4,198.3,108.9z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 7.1 KiB |
@@ -1,56 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#4479FB" d="M196,256H60c-33.1,0-60-26.9-60-60V60C0,26.9,26.9,0,60,0h136c33.1,0,60,26.9,60,60v136
|
||||
C256,229.1,229.1,256,196,256z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M194.5,188.5c-7.6-3.5-15-7.5-22.2-11.8c-6.8-4.2-13.1-8.5-18.7-12.9c17.1-13.5,23.2-36.1,13.2-56.7
|
||||
c-12.7-26.1-46.3-39.2-75.2-29.1c-31.6,11-41,43-25.8,68.7c-48.2-53.1,7.3-123.8,85-99.8c26.2,8.1,48.9,25.8,60.8,50.2
|
||||
C227.4,129.7,219.5,165.3,194.5,188.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M34.7,158.5c17.6,36.2,59,57.6,100.3,54.8c-16.2-6.1-32-16-45-29c-7.8-7.8-13.8-16-18.2-24.2
|
||||
c-9.1-6.3-16.9-14.3-23-23.6C37.5,118.9,34.6,99.6,39,82C24.6,104.1,21.9,132.2,34.7,158.5L34.7,158.5z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M234.5,206.6c-28.2,6.1-68-4.1-97.8-26.7c-35.1-26.6-43.5-60.9-19.9-78.1c-8,18.8,7,47.1,40.6,71.4
|
||||
C181.1,190.4,209.2,202,234.5,206.6z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M187.4,212.9c-29.6,5.2-68.1-7.9-94.8-34.2c-33-32.6-35.5-73.3-5.5-90.8c12-7,27.4-9.2,43.6-7.3
|
||||
c-4.7,1.3-9.2,3.1-13.2,5.4c-30,17.5-26.8,58.9,7.2,92.4C142.6,196.1,165.4,208.1,187.4,212.9L187.4,212.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
<path fill="#FFFFFF" d="M60,252c-30.9,0-56-25.1-56-56V60C4,29.1,29.1,4,60,4h136c30.9,0,56,25.1,56,56v136c0,30.9-25.1,56-56,56
|
||||
H60z"/>
|
||||
<g>
|
||||
<path fill="#303AB2" d="M196,8c28.7,0,52,23.3,52,52v136c0,28.7-23.3,52-52,52H60c-28.7,0-52-23.3-52-52V60C8,31.3,31.3,8,60,8
|
||||
H196 M196,0H60C26.9,0,0,26.9,0,60v136c0,33.1,26.9,60,60,60h136c33.1,0,60-26.9,60-60V60C256,26.9,229.1,0,196,0L196,0z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path fill="#303AB2" d="M145,177.9v-13.2v-21.3c0-2.3,1.2-4.5,3.2-5.6l28.3-16.3l13-7.5V93c0-4.6-2.5-8.9-6.5-11.2l-57.8-33.4
|
||||
c-4-2.3-8.9-2.3-13,0L54.5,81.8c-4,2.3-6.5,6.6-6.5,11.2v66.7c0,4.6,2.5,8.9,6.5,11.2l57.8,33.4c4,2.3,8.9,2.3,13,0l19.7-11.4l0,0
|
||||
V177.9z M125.2,115.2c-4,2.3-6.5,6.6-6.5,11.2v55.4c0,5-5.4,8.1-9.7,5.6l-44.8-25.9c-2-1.2-3.2-3.3-3.2-5.6V96.7
|
||||
c0-2.3,1.2-4.5,3.2-5.6l51.3-29.6c2-1.2,4.5-1.2,6.5,0l38.3,22.1c4.3,2.5,4.3,8.7,0,11.2L125.2,115.2z"/>
|
||||
<path fill="#303AB2" d="M198.3,108.9l-8.8,5.1v18.2v1.8v22.1v7.5c0,2.3-1.2,4.4-3.2,5.5l0,0l-0.7,0.4l-0.9,0.5l-8.1,4.7l-5.2,3
|
||||
L145,192.9l0,0v6.4v3.1v0.1c0,0,0,0,0,0v0.4c0.1,4.8,5.2,7.9,9.5,5.7l0.2-0.1l5.2-3l44.9-26c2-1.2,3.2-3.3,3.2-5.6v-59.4
|
||||
C208,109.5,202.6,106.4,198.3,108.9z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 5.7 KiB |
BIN
resources/icons/X-Plus 4_thumbnail.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 437 B After Width: | Height: | Size: 437 B |
6
resources/icons/add_machine_list_disable.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<path fill="#ADADAF" d="M11,11V5h2v6h6v2h-6v6h-2v-6H5v-2H11z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 437 B |
17
resources/icons/cost_weight.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<path fill="#4479FB" d="M14.6,13.1l-1.4-7.3c-0.1-0.6-0.7-1.1-1.4-1.1H9.5C9.9,4.3,10,3.9,10,3.4c0-1.1-0.9-2-2-2s-2,0.9-2,2
|
||||
c0,0.5,0.2,1,0.5,1.3H4.1c-0.7,0-1.2,0.5-1.4,1.1l-1.4,7.3c-0.2,0.8,0.5,1.6,1.4,1.6h10.5C14.1,14.7,14.8,13.9,14.6,13.1z M8,2.3
|
||||
c0.6,0,1,0.5,1,1s-0.5,1-1,1s-1-0.5-1-1S7.4,2.3,8,2.3z M13.6,13.5c0,0-0.1,0.1-0.3,0.1H2.7c-0.2,0-0.3-0.1-0.3-0.1
|
||||
c0-0.1-0.1-0.1-0.1-0.2L3.8,6c0-0.2,0.2-0.3,0.4-0.3h7.7c0.2,0,0.4,0.1,0.4,0.3l1.4,7.3C13.7,13.4,13.6,13.5,13.6,13.5z"/>
|
||||
<g>
|
||||
<path fill="#4479FB" d="M6.9,12c-0.2-0.4-0.4-0.7-0.6-0.9c-0.2-0.2-0.4-0.4-0.6-0.6H5.4v1.6H4.5V8.2h0.9v1.6h0.2l1.1-1.6h1
|
||||
l-1.3,1.9c0.3,0.3,0.6,0.6,0.8,0.8c0.2,0.3,0.5,0.7,0.7,1.1H6.9z"/>
|
||||
<path fill="#4479FB" d="M11.5,11.9C11.3,12,11.1,12,11,12.1c-0.2,0-0.4,0.1-0.7,0.1c-0.4,0-0.8-0.1-1.1-0.2
|
||||
c-0.3-0.2-0.6-0.4-0.8-0.7c-0.2-0.3-0.3-0.6-0.3-1c0-0.4,0.1-0.8,0.3-1.1c0.2-0.3,0.4-0.6,0.8-0.7c0.3-0.2,0.7-0.3,1.1-0.3
|
||||
c0.2,0,0.4,0,0.6,0.1c0.2,0,0.4,0.1,0.5,0.1V9c-0.4-0.1-0.7-0.2-1-0.2c-0.4,0-0.7,0.1-1,0.3C9.1,9.4,9,9.7,9,10.2
|
||||
c0,0.3,0.1,0.5,0.2,0.7c0.1,0.2,0.3,0.3,0.5,0.4c0.2,0.1,0.4,0.1,0.7,0.1c0.2,0,0.3,0,0.4,0v-0.9h-0.4V9.8h1.2V11.9z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 417 B |
6
resources/icons/delete_machine_list_disable.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<path fill="#ADADAF" d="M5,13v-2h14v2H5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 417 B |
7
resources/icons/edit_machine_list_able.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<path fill="#4479fb" d="M16.8,3l-2,2H5v14h14V9.2l2-2V20c0,0.6-0.4,1-1,1H4c-0.6,0-1-0.4-1-1V4c0-0.6,0.4-1,1-1H16.8z M20.5,2.1
|
||||
l1.4,1.4l-9.2,9.2l-1.4,0l0-1.4L20.5,2.1z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 543 B |
|
Before Width: | Height: | Size: 543 B After Width: | Height: | Size: 543 B |
155
resources/icons/param_cross hatch.svg
Normal file
@@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="10px" height="10px" viewBox="0 0 10 10" enable-background="new 0 0 10 10" xml:space="preserve">
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="0.7" y="0.6" width="3.7" height="3.7">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="0.7" y="0.6" width="3.7" height="3.7" id="mask1_7_73_2_">
|
||||
<path id="path3_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g5" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask1_7_73_2_)">
|
||||
<path id="path4" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,4.3l1.6-1.6L2.7,1L1,2.7L2.7,4.3z"/>
|
||||
<path id="path5" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,3.5l0.8-0.8L2.7,1.8L1.8,2.7L2.7,3.5z"/>
|
||||
<path id="path31" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,4.3l1.6-1.6L2.7,1L1,2.7L2.7,4.3z"/>
|
||||
<path id="path32" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,3.5l0.8-0.8L2.7,1.8L1.8,2.7L2.7,3.5z"/>
|
||||
<path id="path50" fill="none" stroke="#999999" stroke-width="0.3" d="M2.7,4.3l1.6-1.6L2.7,1L1,2.7L2.7,4.3z"/>
|
||||
<path id="path51" fill="none" stroke="#999999" stroke-width="0.3" d="M2.7,3.5l0.8-0.8L2.7,1.8L1.8,2.7L2.7,3.5z"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_1_" filterUnits="userSpaceOnUse" x="4" y="0.6" width="3.7" height="3.7">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="4" y="0.6" width="3.7" height="3.7" id="mask2_7_73_2_">
|
||||
<path id="path6_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_1_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g8" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask2_7_73_2_)">
|
||||
<path id="path7" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,4.3l1.6-1.6L6,1L4.4,2.7L6,4.3z"/>
|
||||
<path id="path8" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,3.5l0.8-0.8L6,1.8L5.1,2.7L6,3.5z"/>
|
||||
<path id="path33" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,4.3l1.6-1.6L6,1L4.4,2.7L6,4.3z"/>
|
||||
<path id="path34" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,3.5l0.8-0.8L6,1.8L5.1,2.7L6,3.5z"/>
|
||||
<path id="path52" fill="none" stroke="#999999" stroke-width="0.3" d="M6,4.3l1.6-1.6L6,1L4.4,2.7L6,4.3z"/>
|
||||
<path id="path53" fill="none" stroke="#999999" stroke-width="0.3" d="M6,3.5l0.8-0.8L6,1.8L5.1,2.7L6,3.5z"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_2_" filterUnits="userSpaceOnUse" x="7.3" y="0.7" width="2.1" height="3.5">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="7.3" y="0.7" width="2.1" height="3.5" id="mask3_7_73_2_">
|
||||
<path id="path9_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_2_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g11" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask3_7_73_2_)">
|
||||
<path id="path10" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,4.2L7.6,2.6l1.6-1.7"/>
|
||||
<path id="path11" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,3.4L8.4,2.6l0.8-0.8"/>
|
||||
<path id="path35" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,4.2L7.6,2.6l1.6-1.7"/>
|
||||
<path id="path36" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,3.4L8.4,2.6l0.8-0.8"/>
|
||||
<path id="path54" fill="none" stroke="#999999" stroke-width="0.3" d="M9.2,4.2L7.6,2.6l1.6-1.7"/>
|
||||
<path id="path55" fill="none" stroke="#999999" stroke-width="0.3" d="M9.5,3.7l-1-1l1-1"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_3_" filterUnits="userSpaceOnUse" x="0.7" y="4" width="3.7" height="3.7">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="0.7" y="4" width="3.7" height="3.7" id="mask4_7_73_2_">
|
||||
<path id="path12_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_3_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g14" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask4_7_73_2_)">
|
||||
<path id="path13" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,7.6L4.3,6L2.7,4.4L1.1,6L2.7,7.6z"/>
|
||||
<path id="path14" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,6.9L3.5,6L2.7,5.2L1.8,6L2.7,6.9z"/>
|
||||
<path id="path37" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,7.6L4.3,6L2.7,4.4L1.1,6L2.7,7.6z"/>
|
||||
<path id="path38" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M2.7,6.9L3.5,6L2.7,5.2L1.8,6L2.7,6.9z"/>
|
||||
<path id="path56" fill="none" stroke="#999999" stroke-width="0.3" d="M2.7,7.6L4.3,6L2.7,4.4L1.1,6L2.7,7.6z"/>
|
||||
<path id="path57" fill="none" stroke="#999999" stroke-width="0.3" d="M2.7,6.9L3.5,6L2.7,5.2L1.8,6L2.7,6.9z"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_4_" filterUnits="userSpaceOnUse" x="4" y="4" width="3.7" height="3.7">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="4" y="4" width="3.7" height="3.7" id="mask5_7_73_2_">
|
||||
<path id="path15_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_4_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g17" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask5_7_73_2_)">
|
||||
<path id="path16" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,7.6L7.6,6L6,4.4L4.4,6L6,7.6z"/>
|
||||
<path id="path17" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,6.9L6.9,6L6,5.2L5.2,6L6,6.9z"/>
|
||||
<path id="path39" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,7.6L7.6,6L6,4.4L4.4,6L6,7.6z"/>
|
||||
<path id="path40" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M6,6.9L6.9,6L6,5.2L5.2,6L6,6.9z"/>
|
||||
<path id="path58" fill="none" stroke="#999999" stroke-width="0.3" d="M6,7.6L7.6,6L6,4.4L4.4,6L6,7.6z"/>
|
||||
<path id="path59" fill="none" stroke="#999999" stroke-width="0.3" d="M6,6.9L6.9,6L6,5.2L5.2,6L6,6.9z"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_5_" filterUnits="userSpaceOnUse" x="7.3" y="4" width="2.1" height="3.5">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="7.3" y="4" width="2.1" height="3.5" id="mask6_7_73_2_">
|
||||
<path id="path18_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_5_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g20" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask6_7_73_2_)">
|
||||
<path id="path19" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,7.6L7.6,5.9l1.6-1.6"/>
|
||||
<path id="path20" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,6.7L8.4,5.9l0.8-0.8"/>
|
||||
<path id="path41" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,7.6L7.6,5.9l1.6-1.6"/>
|
||||
<path id="path42" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M9.2,6.7L8.4,5.9l0.8-0.8"/>
|
||||
<path id="path60" fill="none" stroke="#999999" stroke-width="0.3" d="M9.2,7.6L7.6,5.9l1.6-1.6"/>
|
||||
<path id="path61" fill="none" stroke="#999999" stroke-width="0.3" d="M9.4,7l-1-1l1-1"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_6_" filterUnits="userSpaceOnUse" x="0.7" y="7.2" width="3.6" height="2.2">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="0.7" y="7.2" width="3.6" height="2.2" id="mask7_7_73_2_">
|
||||
<path id="path21_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_6_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g23" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask7_7_73_2_)">
|
||||
<path id="path22" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M0.9,9.3l1.7-1.7l1.7,1.7"/>
|
||||
<path id="path23" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M1.8,9.3l0.8-0.9l0.8,0.9"/>
|
||||
<path id="path43" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M0.9,9.3l1.7-1.7l1.7,1.7"/>
|
||||
<path id="path44" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M1.8,9.3l0.8-0.9l0.8,0.9"/>
|
||||
<path id="path62" fill="none" stroke="#999999" stroke-width="0.3" d="M0.9,9.3l1.7-1.7l1.7,1.7"/>
|
||||
<path id="path63" fill="none" stroke="#999999" stroke-width="0.3" d="M1.8,9.4l0.9-1l0.9,1.1"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_7_" filterUnits="userSpaceOnUse" x="4.1" y="7.3" width="3.5" height="2">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="4.1" y="7.3" width="3.5" height="2" id="mask8_7_73_2_">
|
||||
<path id="path24_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_7_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g26" transform="translate(-0.06473357,-0.11884544)" mask="url(#mask8_7_73_2_)">
|
||||
<path id="path25" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M4.3,9.3l1.6-1.7l1.7,1.7"/>
|
||||
<path id="path26" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M5.1,9.3l0.8-0.9l0.8,0.9"/>
|
||||
<path id="path45" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M4.3,9.3l1.6-1.7l1.7,1.7"/>
|
||||
<path id="path46" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M5.1,9.3l0.8-0.9l0.8,0.9"/>
|
||||
<path id="path64" fill="none" stroke="#999999" stroke-width="0.3" d="M4.3,9.3l1.6-1.7l1.7,1.7"/>
|
||||
<path id="path65" fill="none" stroke="#999999" stroke-width="0.3" d="M5.1,9.3l0.8-0.9l0.8,0.9"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_8_" filterUnits="userSpaceOnUse" x="7.3" y="7.3" width="2.1" height="2">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="7.3" y="7.3" width="2.1" height="2" id="mask9_7_73_2_">
|
||||
<path id="path27_2_" fill="#FFFFFF" filter="url(#Adobe_OpacityMaskFilter_8_)" d="M10,0.1H0v10h10V0.1z"/>
|
||||
</mask>
|
||||
<g id="g29" transform="translate(-0.13363557,-0.18774744)" mask="url(#mask9_7_73_2_)">
|
||||
<path id="path28" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M7.5,9.3l1.7-1.7"/>
|
||||
<path id="path29" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M8.4,9.3l0.8-0.9"/>
|
||||
<path id="path47" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M7.5,9.3l1.7-1.7"/>
|
||||
<path id="path48" fill="none" stroke="#B5BFC2" stroke-width="0.3" d="M8.4,9.3l0.8-0.9"/>
|
||||
<path id="path66" fill="none" stroke="#999999" stroke-width="0.3" d="M7.5,9.3l1.7-1.7"/>
|
||||
<path id="path67" fill="none" stroke="#999999" stroke-width="0.3" d="M8.3,9.5l1.1-1.3"/>
|
||||
</g>
|
||||
<path id="path68" fill="none" stroke="#4479FB" stroke-width="0.478" d="M2.4,0.7l6.9,6.9"/>
|
||||
<path id="path68-8" fill="none" stroke="#4479FB" stroke-width="0.4997" d="M0.7,2.2l6.9,7.1"/>
|
||||
<path id="path69" fill="none" stroke="#4479FB" stroke-width="0.478" d="M0.7,5.6l3.6,3.7"/>
|
||||
<path id="path70" fill="none" stroke="#4479FB" stroke-width="0.5048" d="M5.7,0.7l3.6,3.5"/>
|
||||
<path id="rect1" fill="none" stroke="#4479FB" stroke-width="0.406" stroke-linejoin="round" stroke-miterlimit="3.9" d="M1.5,0.7h7
|
||||
c0.5,0,0.9,0.4,0.9,0.9v6.9c0,0.5-0.4,0.9-0.9,0.9h-7C1,9.3,0.7,8.9,0.7,8.5V1.5C0.7,1.1,1,0.7,1.5,0.7z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
13
resources/icons/print_time.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<path fill="#4479FB" d="M8.5,9.2L8.3,9.1c-0.2,0-0.4,0-0.5,0L7.5,9.2c-1.3,0.4-2.3,1.6-2.3,3v0.5h5.5v-0.5
|
||||
C10.8,10.8,9.8,9.6,8.5,9.2z"/>
|
||||
<path fill="#4479FB" d="M7.9,6.8l-2-1.4c0,0,0-0.1,0-0.1h4.2c0,0,0.1,0.1,0,0.1l-2,1.4C8,6.9,7.9,6.9,7.9,6.8z"/>
|
||||
<path fill="#4479FB" d="M13.3,14h-0.4v-1.8c0-1.7-0.9-3.3-2.3-4.2c1.4-0.9,2.3-2.5,2.3-4.2V2h0.4C13.7,2,14,1.7,14,1.4
|
||||
s-0.3-0.7-0.6-0.7H2.7C2.3,0.7,2,1,2,1.4S2.3,2,2.7,2h0.4v1.8c0,1.7,0.9,3.3,2.3,4.2c-1.4,0.9-2.3,2.5-2.3,4.2V14H2.7
|
||||
C2.3,14,2,14.3,2,14.6c0,0.4,0.3,0.7,0.6,0.7h10.7c0.4,0,0.6-0.3,0.6-0.7C14,14.3,13.7,14,13.3,14z M4.1,12.2c0-1.4,0.8-2.7,2-3.4
|
||||
C6.3,8.6,6.5,8.3,6.5,8c0-0.3-0.2-0.6-0.4-0.7c-1.2-0.7-2-2-2-3.4V2h7.9v1.8c0,1.4-0.8,2.7-2,3.4C9.6,7.4,9.5,7.7,9.5,8
|
||||
c0,0.3,0.2,0.6,0.4,0.7c1.2,0.7,2,2,2,3.4V14H4.1V12.2z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
8
resources/icons/refresh_machine_list_able.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||
<path fill="#4479fb" d="M5.5,4.4C7.2,2.9,9.5,2,12,2c5.5,0,10,4.5,10,10c0,2.1-0.7,4.1-1.8,5.7L17,12h3c0-4.4-3.6-8-8-8
|
||||
C9.8,4,7.9,4.8,6.5,6.2L5.5,4.4z M18.5,19.6c-1.8,1.5-4,2.4-6.5,2.4C6.5,22,2,17.5,2,12c0-2.1,0.7-4.1,1.8-5.7L7,12H4
|
||||
c0,4.4,3.6,8,8,8c2.2,0,4.1-0.8,5.5-2.2L18.5,19.6z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 659 B |
|
Before Width: | Height: | Size: 659 B After Width: | Height: | Size: 659 B |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 119 KiB |
BIN
resources/icons/user_dark.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
@@ -1,3 +1,15 @@
|
||||
min_slic3r_version = 1.1.7
|
||||
1.1.7 Optimize parameters
|
||||
min_slic3r_version = 1.1.6
|
||||
1.1.6 Optimize parameters
|
||||
min_slic3r_version = 1.1.5
|
||||
1.1.5 Optimize parameters
|
||||
min_slic3r_version = 1.1.4
|
||||
1.1.4 Optimize parameters
|
||||
min_slic3r_version = 1.1.3
|
||||
1.1.3 Optimize parameters
|
||||
min_slic3r_version = 1.1.2
|
||||
1.1.2 Optimize parameters
|
||||
min_slic3r_version = 1.1.1
|
||||
1.1.1 Optimize parameters
|
||||
min_slic3r_version = 1.1.0
|
||||
|
||||
60
resources/profiles/QIDITechnology/Q1 Pro.svg
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="694.5px" height="694.5px" viewBox="0 0 694.5 694.5" enable-background="new 0 0 694.5 694.5" xml:space="preserve">
|
||||
<rect fill="#FFFFFF" width="1.4" height="694.5"/>
|
||||
<rect x="693.1" y="15.7" fill="#FFFFFF" width="1.4" height="678.8"/>
|
||||
<rect x="0" y="693.1" fill="#FFFFFF" width="694.5" height="1.4"/>
|
||||
<rect x="559.1" fill="#FFFFFF" width="1.4" height="694.5"/>
|
||||
<rect x="417.4" fill="#FFFFFF" width="1.4" height="694.5"/>
|
||||
<rect x="275.7" y="15.7" fill="#FFFFFF" width="1.4" height="678.8"/>
|
||||
<rect x="133.9" y="14.2" fill="#FFFFFF" width="1.4" height="680.3"/>
|
||||
<rect x="21.1" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="49.4" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="77.8" y="14.2" fill="#FFFFFF" width="0.4" height="680.3"/>
|
||||
<rect x="106.1" y="14.2" fill="#FFFFFF" width="0.4" height="680.3"/>
|
||||
<rect x="162.8" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="191.1" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="219.5" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="247.8" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="304.5" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="332.9" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="361.2" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="389.6" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="446.3" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="474.6" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="502.9" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="531.3" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="588" y="0" fill="#FFFFFF" width="0.4" height="694.5"/>
|
||||
<rect x="616.3" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="644.7" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="673" y="15.7" fill="#FFFFFF" width="0.4" height="678.8"/>
|
||||
<rect x="0" y="559.1" fill="#FFFFFF" width="694.5" height="1.4"/>
|
||||
<rect x="0" y="417.4" fill="#FFFFFF" width="694.5" height="1.4"/>
|
||||
<rect x="0" y="275.7" fill="#FFFFFF" width="694.5" height="1.4"/>
|
||||
<rect x="0" y="133.9" fill="#FFFFFF" width="694.5" height="1.4"/>
|
||||
<rect x="0" y="21.1" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="49.4" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="77.8" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="106.1" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="162.8" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="191.1" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="219.5" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="247.8" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="304.5" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="332.9" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="361.2" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="389.6" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="446.3" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="474.6" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="502.9" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="531.3" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="588" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="616.3" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="644.7" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<rect x="0" y="673" fill="#FFFFFF" width="694.5" height="0.4"/>
|
||||
<polygon fill="#FFFFFF" points="694.5,15.7 588.1,15.7 588.1,0 589.6,0 589.6,14 694.5,14 "/>
|
||||
<polygon fill="#FFFFFF" points="327.5,15.7 69.4,15.7 69.4,0 70.9,0 70.9,14 326,14 326,0 327.5,0 "/>
|
||||
<rect x="327.5" y="0" fill="#FFFFFF" width="260.9" height="1.4"/>
|
||||
<rect x="0" y="0" fill="#FFFFFF" width="69.4" height="1.4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
BIN
resources/profiles/QIDITechnology/Q1 Pro_bed.STL
Normal file
BIN
resources/profiles/QIDITechnology/Q1 Pro_thumbnail.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
resources/profiles/QIDITechnology/X-MAX 3_bed.stl
Normal file
BIN
resources/profiles/QIDITechnology/X-Plus 3_bed.stl
Normal file
73
resources/profiles/QIDITechnology/X-Plus 4.svg
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1_x5F_复制" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px" viewBox="0 0 864.6 864.6" enable-background="new 0 0 864.6 864.6" xml:space="preserve">
|
||||
<rect x="0" y="843.1" fill="#FFFFFF" width="830.6" height="0.4"/>
|
||||
<rect x="0.4" y="814.8" fill="#FFFFFF" width="829.5" height="0.4"/>
|
||||
<rect x="0" y="785.9" fill="#FFFFFF" width="863.8" height="1.4"/>
|
||||
<rect x="0" y="758.1" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="729.7" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="701.4" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="673" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="644.2" fill="#FFFFFF" width="863.8" height="1.4"/>
|
||||
<rect x="0" y="616.3" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="588" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="559.6" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="531.3" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="502.4" fill="#FFFFFF" width="863.8" height="1.4"/>
|
||||
<rect x="0.1" y="474.6" fill="#FFFFFF" width="863.7" height="0.4"/>
|
||||
<rect x="0" y="446.3" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0.1" y="417.9" fill="#FFFFFF" width="863.7" height="0.4"/>
|
||||
<rect x="0" y="389.6" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="360.7" fill="#FFFFFF" width="863.8" height="1.4"/>
|
||||
<rect x="0" y="332.9" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="304.5" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="276.2" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="247.8" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="219" fill="#FFFFFF" width="863.8" height="1.4"/>
|
||||
<rect x="0" y="191.1" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="162.8" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="134.4" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="106.1" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="77.3" fill="#FFFFFF" width="863.8" height="1.4"/>
|
||||
<rect y="863.2" fill="#FFFFFF" width="830.6" height="1.4"/>
|
||||
<rect x="100.6" fill="#FFFFFF" width="764" height="1.4"/>
|
||||
<rect y="8.5" fill="#FFFFFF" width="100.6" height="1.4"/>
|
||||
<rect x="829.2" y="806.5" fill="#FFFFFF" width="35.4" height="1.4"/>
|
||||
<rect x="829.2" y="807.9" fill="#FFFFFF" width="1.4" height="56.7"/>
|
||||
<rect x="99.2" y="0" fill="#FFFFFF" width="1.4" height="9.2"/>
|
||||
<rect x="0" y="8.9" fill="#FFFFFF" width="1.4" height="855.7"/>
|
||||
<rect x="863.2" fill="#FFFFFF" width="1.4" height="807.2"/>
|
||||
<rect x="0" y="49.4" fill="#FFFFFF" width="863.8" height="0.4"/>
|
||||
<rect x="0" y="21.1" fill="#FFFFFF" width="864.6" height="0.4"/>
|
||||
<rect x="21.1" y="9.6" fill="#FFFFFF" width="0.4" height="855"/>
|
||||
<rect x="49.4" y="9.6" fill="#FFFFFF" width="0.4" height="855"/>
|
||||
<rect x="77.3" y="9.6" fill="#FFFFFF" width="1.4" height="855"/>
|
||||
<rect x="106.1" y="0.7" fill="#FFFFFF" width="0.4" height="863.9"/>
|
||||
<rect x="134.4" y="0.7" fill="#FFFFFF" width="0.4" height="863.9"/>
|
||||
<rect x="162.8" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="191.1" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="219" y="0" fill="#FFFFFF" width="1.4" height="864.6"/>
|
||||
<rect x="247.8" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="276.2" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="304.5" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="332.9" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="360.7" y="0" fill="#FFFFFF" width="1.4" height="864.6"/>
|
||||
<rect x="389.6" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="417.9" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="446.3" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="474.6" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="502.4" y="0" fill="#FFFFFF" width="1.4" height="864.6"/>
|
||||
<rect x="531.3" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="559.6" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="588" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="616.3" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="644.2" y="0" fill="#FFFFFF" width="1.4" height="864.6"/>
|
||||
<rect x="673" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="701.4" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="729.7" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="758.1" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="785.9" y="0" fill="#FFFFFF" width="1.4" height="864.6"/>
|
||||
<rect x="814.8" y="0" fill="#FFFFFF" width="0.4" height="864.6"/>
|
||||
<rect x="843.1" y="0" fill="#FFFFFF" width="0.4" height="807.2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
BIN
resources/profiles/QIDITechnology/X-Plus 4_bed.STL
Normal file
BIN
resources/profiles/QIDITechnology/X-Plus 4_thumbnail.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 7.6 KiB |
@@ -18,6 +18,7 @@ var LangText={
|
||||
"t16": "Calibration",
|
||||
"t17": "Pressure Advance",
|
||||
"t18": "Exclude Objects",
|
||||
"t19": "Max Volumetric Speed",
|
||||
|
||||
"l0": "Learn more:",
|
||||
"l1": "You can download the 3D model from the following link.",
|
||||
@@ -62,6 +63,10 @@ var LangText={
|
||||
"l41": "4.PA calibration does not work with PETG.",
|
||||
"l42": "When multiple models are printed at the same time, you can stop printing a model in the middle of printing.",
|
||||
"l43": "Note: Models with the same file name are treated as the same object.",
|
||||
"l44": "Different filaments have different maximum volume speed.",
|
||||
"l45": "Nozzle material, caliber, printing temperature, etc., will affect the maximum volume speed.",
|
||||
"l46": "During the test, the printing speed will increase layer by layer. When there is a hole or missing wire on the surface of the model, it indicates that the layer has reached the maximum volume speed, and the maximum volume speed is calculated according to the ratio of height.",
|
||||
"l47": "Or you can find a solution through WIKI.",
|
||||
},
|
||||
"zh_CN": {
|
||||
"t1": "用户指南",
|
||||
@@ -82,6 +87,7 @@ var LangText={
|
||||
"t16": "校准",
|
||||
"t17": "压力提前",
|
||||
"t18": "排除对象",
|
||||
"t19": "最大体积速度",
|
||||
|
||||
"l0": "了解更多:",
|
||||
"l1": "您可以从以下链接下载3D模型。",
|
||||
@@ -126,6 +132,10 @@ var LangText={
|
||||
"l41": "4.PA校准不适用于PETG。",
|
||||
"l42": "当多个模型同时打印时,你可以在打印中途停止某个模型的打印。",
|
||||
"l43": "注:相同文件名的模型会被视为同一对象。",
|
||||
"l44": "不同线材的最大体积速度各不相同。",
|
||||
"l45": "喷嘴材质、口径、打印温度、等都会影响最大体积速度。",
|
||||
"l46": "测试时打印速度会逐层增加,当模型表面出现空洞或缺丝时,说明该层已达到最大体积速度,根据高度比例算出最大体积速度。",
|
||||
"l47": "或者你可以通过WIKI来找到解决方案。",
|
||||
},
|
||||
"ja": {
|
||||
"t1": "ユーザーガイド",
|
||||
@@ -146,6 +156,7 @@ var LangText={
|
||||
"t16": "較正",
|
||||
"t17": "圧力前進",
|
||||
"t18": "対象をはずします",
|
||||
"t19": "最大体積速度です",
|
||||
|
||||
"l0": "もっと詳しく知る:",
|
||||
"l1": "3Dモデルは以下のWebサイトからダウンロードできます。",
|
||||
@@ -190,6 +201,10 @@ var LangText={
|
||||
"l41": "4.PA キャリブレーションは PETG では機能しません。",
|
||||
"l42": "複数のモデルが同時に印刷されている場合は、あるモデルの印刷を途中でやめることができます。",
|
||||
"l43": "注:同じファイル名のモデルは、同じ対象として扱われます。",
|
||||
"l44": "最大体積速度は線材によって異なります。",
|
||||
"l45": "ノズルの材質、口径、印刷温度などが最大体積速度に影響します。",
|
||||
"l46": "テスト時の印刷速度は層ごとに増加します。模型の表面に穴ができたり、糸が欠けたりした場合、その層が最大体積速度に達したことを示し、高さの割合から最大体積速度を算出します。",
|
||||
"l47": "WIKIで解決策を見つけることもできます.",
|
||||
},
|
||||
"fr": {
|
||||
"t1": "Guide de l'utilisateur",
|
||||
@@ -210,6 +225,7 @@ var LangText={
|
||||
"t16": "Étalonnage",
|
||||
"t17": "Avance de pression",
|
||||
"t18": "Exclure des objets",
|
||||
"t19": "Vitesse volumétrique Max",
|
||||
|
||||
"l0": "Apprendre encore plus:",
|
||||
"l1": "Vous pouvez télécharger des modèles 3D à partir des sites Web suivants.",
|
||||
@@ -254,6 +270,10 @@ var LangText={
|
||||
"l41": "4.L'étalonnage PA ne fonctionne pas avec le PETG.",
|
||||
"l42": "Lorsque plusieurs modèles sont imprimés en même temps, vous pouvez arrêter l’impression d’un modèle au milieu de l’impression.",
|
||||
"l43": "Note: les modèles avec le même nom de fichier sont traités comme le même objet.",
|
||||
"l44": "Différents filaments ont une vitesse de volume maximale différente.",
|
||||
"l45": "Le matériau de la buse, le calibre, la température d’impression, etc., affecteront la vitesse de volume maximum.",
|
||||
"l46": "Pendant l’essai, la vitesse d’impression augmentera couche par couche. Quand il y a un trou ou un fil manquant sur la surface du modèle, cela indique que la couche a atteint la vitesse volumique maximale, et la vitesse volumique maximale est calculée selon le rapport de la hauteur.",
|
||||
"l47": "Ou vous pouvez trouver une solution via WIKI.",
|
||||
},
|
||||
"de": {
|
||||
"t1": "Benutzerhandbuch",
|
||||
@@ -274,6 +294,7 @@ var LangText={
|
||||
"t16": "Kalibrierung",
|
||||
"t17": "Druckvorschub",
|
||||
"t18": "Subjekt wird eliminiert",
|
||||
"t19": "Maximale geschwindigkeit",
|
||||
|
||||
"l0": "Erfahren Sie mehr:",
|
||||
"l1": "Sie können 3D-Modelle von den folgenden Websites herunterladen.",
|
||||
@@ -318,6 +339,10 @@ var LangText={
|
||||
"l41": "4.Die PA-Kalibrierung funktioniert nicht mit PETG.",
|
||||
"l42": "Wenn sie mehrere modelle gleichzeitig drucken, können sie den druckvorgang beenden.",
|
||||
"l43": "Anmerkung: ein modell mit dem gleichen namen wird als gleiches objekt betrachtet.",
|
||||
"l44": "Es gibt eine vielzahl Von lichtern mit maximale geschwindigkeit.",
|
||||
"l45": "Die düsen, der durchmesser, die drucktemperatur all das beeinflusst die maximale geschwindigkeit.",
|
||||
"l46": "Bei den tests wird die druckgeschwindigkeit etage für etage erhöht Wenn eine öffnung Oder keine linie in der oberfläche eines modells angezeigt wird, zeigt sie an, dass sie die höchstgeschwindigkeit erreicht hat und dass die höchste geschwindigkeit nach höhe angegeben wird.",
|
||||
"l47": "Oder Sie finden eine Lösung über WIKI.",
|
||||
},
|
||||
"be": {
|
||||
"t1": "Кіраўніцтва карыстальніка",
|
||||
@@ -338,6 +363,7 @@ var LangText={
|
||||
"t16": "Каліброўка",
|
||||
"t17": "Увеличение давления",
|
||||
"t18": "Исключить объекты из списка",
|
||||
"t19": "Максимальная объемная частота вращения",
|
||||
|
||||
"l0": "даведацца больш:",
|
||||
"l1": "Вы можаце загрузіць 3D-мадэлі з наступных сайтаў.",
|
||||
@@ -382,6 +408,10 @@ var LangText={
|
||||
"l41": "4.Калибровка PA не работает с PETG.",
|
||||
"l42": "Когда одновременно печатаются несколько моделей, можно прекратить печатание модели в процессе печати.",
|
||||
"l43": "Примечание: модели с одним и тем же именем файла рассматриваются как Один и тот же объект.",
|
||||
"l44": "Различные нити накала имеют разную максимальную объемную скорость.",
|
||||
"l45": "Материал сопла, калибр, температура печати и т.д., повлияет на максимальную объемную скорость.",
|
||||
"l46": "Во время теста скорость печати будет увеличиваться слой за слоем. Если на поверхности модели имеется отверстие или недостающая проволока, это указывает на то, что слой достиг максимальной объемной скорости, а максимальная объемная скорость рассчитывается в соответствии с отношением высоты.",
|
||||
"l47": "Или вы можете найти решение через WIKI.",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ li {
|
||||
}
|
||||
.accordion > li ol {
|
||||
width: 100%;
|
||||
background-color: #333;
|
||||
background-color: #333333;
|
||||
}
|
||||
.accordion > li ol li {
|
||||
position: relative;
|
||||
|
||||
1432
resources/web/guide/filament_table.html
Normal file
BIN
resources/web/guide/img/MaxVolumetricSpeed.gif
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
resources/web/guide/img/Q1 Pro.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
resources/web/guide/img/Q1 ProPoster.png
Normal file
|
After Width: | Height: | Size: 517 KiB |
BIN
resources/web/guide/img/QIDILink.png
Normal file
|
After Width: | Height: | Size: 502 KiB |
BIN
resources/web/guide/img/X-Plus 4.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
resources/web/guide/img/X-Plus4Poster.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -61,6 +61,10 @@
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div class="trans" tid="t18"></div>
|
||||
</li>
|
||||
<li menu="QIDILink" class="MenuBtn" onClick="GotoMenu('QIDILink')">
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div>QIDI Link</div>
|
||||
</li>
|
||||
<li menu="ModelDownload" class="MenuBtn" onClick="GotoMenu('ModelDownload')">
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div class="trans" tid="t13"></div>
|
||||
@@ -83,6 +87,10 @@
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div class="trans" tid="t17"></div>
|
||||
</li>
|
||||
<li menu="MaxVolumetricSpeed" class="MenuBtn" onClick="GotoMenu('MaxVolumetricSpeed')">
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div class="trans" tid="t19"></div>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
|
||||
@@ -93,6 +101,14 @@
|
||||
<i class="fa fa-caret-right"></i>
|
||||
</label>
|
||||
<ol>
|
||||
<li menu="X-Plus 4" class="MenuBtn" onClick="GotoMenu('X-Plus 4')">
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div>X-Plus 4</div>
|
||||
</li>
|
||||
<li menu="Q1 Pro" class="MenuBtn" onClick="GotoMenu('Q1 Pro')">
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div>Q1 Pro</div>
|
||||
</li>
|
||||
<li menu="X-MAX 3" class="MenuBtn" onClick="GotoMenu('X-MAX 3')">
|
||||
<div class="MenuBtnIcon"><img src="img/MenuBtnIcon.svg"/></div>
|
||||
<div>X-MAX 3</div>
|
||||
@@ -162,6 +178,10 @@
|
||||
<div class="AutozoomImage"><img src="img/ExcludeObjects.gif"/></div>
|
||||
<div class="ThumbnailTitle trans" tid="t18"></div>
|
||||
</div>
|
||||
<div class="Thumbnail" onClick="GotoMenu('QIDILink')">
|
||||
<div class="AutozoomImage"><img src="img/QIDILink.png"/></div>
|
||||
<div class="ThumbnailTitle">QIDI Link</div>
|
||||
</div>
|
||||
<div class="Thumbnail" onClick="GotoMenu('ModelDownload')">
|
||||
<div class="AutozoomImage"><img src="img/DownloadModel.png"/></div>
|
||||
<div class="ThumbnailTitle trans" tid="t13"></div>
|
||||
@@ -174,6 +194,10 @@
|
||||
<div class="AutozoomImage"><img src="img/PressureAdvance.gif"/></div>
|
||||
<div class="ThumbnailTitle trans" tid="t17"></div>
|
||||
</div>
|
||||
<div class="Thumbnail" onClick="GotoMenu('MaxVolumetricSpeed')">
|
||||
<div class="AutozoomImage"><img src="img/MaxVolumetricSpeed.gif"/></div>
|
||||
<div class="ThumbnailTitle trans" tid="t19"></div>
|
||||
</div>
|
||||
<div class="Thumbnail" onClick="GotoMenu('IssueReport')">
|
||||
<div class="AutozoomImage"><img src="img/IssueReport.png"/></div>
|
||||
<div class="ThumbnailTitle trans" tid="t6"></div>
|
||||
@@ -232,6 +256,11 @@
|
||||
<div class="AutozoomImage"><img src="img/ExcludeObjects.gif"/></div>
|
||||
</div>
|
||||
|
||||
<div class="IntroduceBoard" board="QIDILink">
|
||||
<div class="IntroduceTitle">QIDI Link</div>
|
||||
<div class="AutozoomImage"><img src="img/QIDILink.png"/></div>
|
||||
</div>
|
||||
|
||||
<div class="IntroduceBoard" board="ModelDownload">
|
||||
<div class="IntroduceTitle trans" tid="t13"></div>
|
||||
<div class="IntroduceTextBold trans" tid="l1"></div>
|
||||
@@ -294,6 +323,26 @@
|
||||
<div class="CenterImage"><img src="img/PressureAdvanceTower.png"/></div>
|
||||
</div>
|
||||
|
||||
<div class="IntroduceBoard" board="MaxVolumetricSpeed">
|
||||
<div class="IntroduceTitle trans" tid="t19"></div>
|
||||
<div class="IntroduceText trans" tid="l44"></div>
|
||||
<div class="IntroduceText trans" tid="l45"></div>
|
||||
<div class="AutozoomImage"><img src="img/MaxVolumetricSpeed.gif"/></div>
|
||||
<div class="IntroduceText trans" tid="l46"></div>
|
||||
</div>
|
||||
|
||||
<div class="IntroduceBoard" board="X-Plus 4">
|
||||
<div class="AutozoomImage"><img src="img/X-Plus4Poster.png"/></div>
|
||||
<div class="IntroduceTextBold trans" tid="l0"></div>
|
||||
<div class="IntroduceText">https://qidi3d.com/products/plus4-3d-printer</div>
|
||||
</div>
|
||||
|
||||
<div class="IntroduceBoard" board="Q1 Pro">
|
||||
<div class="AutozoomImage"><img src="img/Q1 ProPoster.png"/></div>
|
||||
<div class="IntroduceTextBold trans" tid="l0"></div>
|
||||
<div class="IntroduceText">https://qidi3d.com/products/q1-pro-3d-printer</div>
|
||||
</div>
|
||||
|
||||
<div class="IntroduceBoard" board="X-MAX 3">
|
||||
<div class="AutozoomImage"><img src="img/X-MAX3Poster.png"/></div>
|
||||
<div class="IntroduceTextBold trans" tid="l0"></div>
|
||||
@@ -314,246 +363,42 @@
|
||||
|
||||
<div class="IntroduceBoard" board="Filaments">
|
||||
<div class="FilamentsTable">
|
||||
<table cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Filament</th>
|
||||
<th>Drying box</th>
|
||||
<th>Anneal</th>
|
||||
<th>Water resistance</th>
|
||||
<th>Corrosion resistance</th>
|
||||
<th>Creep resistance</th>
|
||||
<th>HDT 0.45</th>
|
||||
<th>HDT 1.80</th>
|
||||
<th>Tensile strength(MPa)</th>
|
||||
<th>Tensile modulus(MPa)</th>
|
||||
<th>Elongation at break(%)</th>
|
||||
<th>Flexural strength(MPa)</th>
|
||||
<th>Flexural modulus(MPa)</th>
|
||||
<th>Notch impact strength(KJ/㎡)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>ABS Odorless</td>
|
||||
<td>≤30%</td>
|
||||
<td>/</td>
|
||||
<td>++</td>
|
||||
<td>+</td>
|
||||
<td>+++</td>
|
||||
<td>92℃</td>
|
||||
<td>86℃</td>
|
||||
<td>41.65 ± 0.27</td>
|
||||
<td>2351.00 ± 92.00</td>
|
||||
<td>7.95 ± 4.53</td>
|
||||
<td>67.81 ± 0.54</td>
|
||||
<td>2400.00 ± 79.69</td>
|
||||
<td>20.03 ± 1.32</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>ABS Rapido</td>
|
||||
<td>≤30%</td>
|
||||
<td>/</td>
|
||||
<td>++</td>
|
||||
<td>+</td>
|
||||
<td>+++</td>
|
||||
<td>85℃</td>
|
||||
<td>/</td>
|
||||
<td>41 ± 1</td>
|
||||
<td>3850 ± 150</td>
|
||||
<td>11 ± 1</td>
|
||||
<td>77.5 ± 2.5</td>
|
||||
<td>77.5 ± 2.5</td>
|
||||
<td>20 ± 2</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>ABS-GF25</td>
|
||||
<td>≤30%</td>
|
||||
<td>/</td>
|
||||
<td>+++</td>
|
||||
<td>+</td>
|
||||
<td>+++</td>
|
||||
<td>97℃</td>
|
||||
<td>93℃</td>
|
||||
<td>48.48 ± 0.61</td>
|
||||
<td>3752.13 ± 68.39</td>
|
||||
<td>2.10 ± 0.10</td>
|
||||
<td>78.80 ± 1.26</td>
|
||||
<td>3531.71 ± 75.79</td>
|
||||
<td>8.91 ± 0.63</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>ASA</td>
|
||||
<td>≤30%</td>
|
||||
<td>/</td>
|
||||
<td>+++</td>
|
||||
<td>+</td>
|
||||
<td>+++</td>
|
||||
<td>94℃</td>
|
||||
<td>86℃</td>
|
||||
<td>38.50 ± 1.60</td>
|
||||
<td>2317.00 ± 246.00</td>
|
||||
<td>5.20 ± 1.40</td>
|
||||
<td>64.49 ± 1.30</td>
|
||||
<td>2399.00 ± 147.00</td>
|
||||
<td>12.90 ± 0.90</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>ASA-Aero</td>
|
||||
<td>≤30%</td>
|
||||
<td>/</td>
|
||||
<td>++</td>
|
||||
<td>+</td>
|
||||
<td>++</td>
|
||||
<td>70℃</td>
|
||||
<td>55℃</td>
|
||||
<td>8.25 ± 0.15</td>
|
||||
<td>593.99 ± 24.34</td>
|
||||
<td>11.52 ± 0.58</td>
|
||||
<td>14.31 ± 1.66</td>
|
||||
<td>457.94 ± 20.84</td>
|
||||
<td>2.29 ± 0.13</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>PA12-CF</td>
|
||||
<td>≤15%</td>
|
||||
<td>80-100℃</td>
|
||||
<td>+</td>
|
||||
<td>++</td>
|
||||
<td>+</td>
|
||||
<td>149.6℃</td>
|
||||
<td>112.4℃</td>
|
||||
<td>87.49 ± 2.81</td>
|
||||
<td>5438.40 ± 282.82</td>
|
||||
<td>2.59 ± 0.19</td>
|
||||
<td>133.17 ± 4.66</td>
|
||||
<td>4667.43 ± 339.80</td>
|
||||
<td>6.11 ± 1.45</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>PAHT-CF</td>
|
||||
<td>≤15%</td>
|
||||
<td>80-100℃</td>
|
||||
<td>++</td>
|
||||
<td>+++</td>
|
||||
<td>+++</td>
|
||||
<td>192.3℃</td>
|
||||
<td>121.7℃</td>
|
||||
<td>104.90 ± 1.99</td>
|
||||
<td>8383.26 ± 419.53</td>
|
||||
<td>1.60 ± 0.07</td>
|
||||
<td>147.70 ± 4.09</td>
|
||||
<td>5969.35 ± 145.28</td>
|
||||
<td>6.17 ± 0.2</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>PC/ABS-FR</td>
|
||||
<td>≤15%</td>
|
||||
<td>/</td>
|
||||
<td>+++</td>
|
||||
<td>+</td>
|
||||
<td>+++</td>
|
||||
<td>88℃</td>
|
||||
<td>83℃</td>
|
||||
<td>52.51 ± 0.28</td>
|
||||
<td>2588.73 ± 64.81</td>
|
||||
<td>5.55 ± 0.99</td>
|
||||
<td>85.95 ± 0.83</td>
|
||||
<td>2504.55 ± 22.88</td>
|
||||
<td>8.39 ± 0.46</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>PET-CF</td>
|
||||
<td>≤15%</td>
|
||||
<td>80-100℃</td>
|
||||
<td>+++</td>
|
||||
<td>+++</td>
|
||||
<td>+++</td>
|
||||
<td>148.8℃</td>
|
||||
<td>112.1℃</td>
|
||||
<td>87.41 ± 3.57</td>
|
||||
<td>6025.53 ± 355.46</td>
|
||||
<td>1.99 ±0.18</td>
|
||||
<td>122.69 ± 5.19</td>
|
||||
<td>5313.21 ± 197.89</td>
|
||||
<td>5.57 ± 0.58</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>PETG-Tough</td>
|
||||
<td>≤20%</td>
|
||||
<td>/</td>
|
||||
<td>+++</td>
|
||||
<td>++</td>
|
||||
<td>+++</td>
|
||||
<td>78℃</td>
|
||||
<td>73℃</td>
|
||||
<td>40.3±0.6</td>
|
||||
<td>1780±80</td>
|
||||
<td>4.0±0.2</td>
|
||||
<td>62.8±0.4</td>
|
||||
<td>1919±54</td>
|
||||
<td>13.9±2.3</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>PLA Rapido</td>
|
||||
<td>≤30%</td>
|
||||
<td>/</td>
|
||||
<td>+</td>
|
||||
<td>+</td>
|
||||
<td>+</td>
|
||||
<td>57℃</td>
|
||||
<td>/</td>
|
||||
<td>39 ± 3</td>
|
||||
<td>4650 ± 150</td>
|
||||
<td>12.5 ± 2.5</td>
|
||||
<td>72.5 ± 2.5</td>
|
||||
<td>2850 ± 150</td>
|
||||
<td>6 ± 2</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>PLA Rapido Matte</td>
|
||||
<td>≤30%</td>
|
||||
<td>/</td>
|
||||
<td>+</td>
|
||||
<td>+</td>
|
||||
<td>+</td>
|
||||
<td>58℃</td>
|
||||
<td>/</td>
|
||||
<td>39 ± 3</td>
|
||||
<td>2400 ± 200</td>
|
||||
<td>3 ± 1</td>
|
||||
<td>77.5 ± 2.5</td>
|
||||
<td>2200 ± 200</td>
|
||||
<td>7.5 ± 1.5</td>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in 1" :key="index">
|
||||
<td>UltraPA</td>
|
||||
<td>≤15%</td>
|
||||
<td>/</td>
|
||||
<td>++</td>
|
||||
<td>++</td>
|
||||
<td>++</td>
|
||||
<td>77.8℃</td>
|
||||
<td>73.1℃</td>
|
||||
<td>86.15 ± 0.56</td>
|
||||
<td>3609.22 ± 153.31</td>
|
||||
<td>11.68 ± 3.36</td>
|
||||
<td>121.47 ± 3.14</td>
|
||||
<td>3314.03 ±181.88</td>
|
||||
<td>5.78 ± 0.30</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<iframe id="filamentTableIframe" class="table-container" style="width: 100%; height: 1000px; border: none;"></iframe>
|
||||
</div>
|
||||
<div class="IntroduceTextBold trans" tid="l0"></div>
|
||||
<div class="IntroduceText">https://qidi3d.com/collections/filaments</div>
|
||||
</div>
|
||||
<script>
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const lang = urlParams.get('lang') || 'en';
|
||||
var iframe = document.getElementById('filamentTableIframe');
|
||||
iframe.src = 'filament_table.html?lang=' + lang;
|
||||
</script>
|
||||
|
||||
<div class="IssueBoard" board="IssueReport">
|
||||
<div class="IntroduceTitle trans" tid="t6"></div>
|
||||
<div class="IntroduceText trans" tid="l2"></div>
|
||||
<div class="IntroduceText trans" tid="l3"></div>
|
||||
<div><br></div>
|
||||
<div class="IntroduceText trans" tid="l47"></div>
|
||||
<div class="IntroduceText">https://wiki.qidi3d.com</div>
|
||||
<div class="EmailBlock">
|
||||
<div class="PrinterBlock">
|
||||
<div class="CenterImage"><img src="img/X-Plus 4.png"/></div>
|
||||
<div class="ThumbnailTitle">X-Plus 4</div>
|
||||
<div class="IntroduceText">
|
||||
<b>E-mail:</b><br/>Plus4support@qidi3d.com<br>Plus4Ams@qidi3d.com<br/><br>
|
||||
<b>Skype:</b><br/>Plus4support@qidi3d.com
|
||||
</div>
|
||||
</div>
|
||||
<div class="PrinterBlock">
|
||||
<div class="CenterImage"><img src="img/Q1 Pro.png"/></div>
|
||||
<div class="ThumbnailTitle">Q1 Pro</div>
|
||||
<div class="IntroduceText">
|
||||
<b>E-mail:</b><br/>Q1support@qidi3d.com<br>Q1AMS@qidi3d.com<br/><br>
|
||||
<b>Skype:</b><br/>Q1support@qidi3d.com
|
||||
</div>
|
||||
</div>
|
||||
<div class="PrinterBlock">
|
||||
<div class="CenterImage"><img src="img/X-MAX 3.png"/></div>
|
||||
<div class="ThumbnailTitle">X-MAX 3</div>
|
||||
|
||||
@@ -4,6 +4,7 @@ body {
|
||||
align-items: center;
|
||||
/* <20><>ҳ<EFBFBD><D2B3>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ߶<C4B8> */
|
||||
height: 100vh;
|
||||
background: #EEEEEE;
|
||||
}
|
||||
|
||||
#GifBoard {
|
||||
|
||||
BIN
resources/web/qidi/link_connection.png
Normal file
|
After Width: | Height: | Size: 502 KiB |
28
resources/web/qidi/link_missing_connection.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Printer Connection Required</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/home.css" />
|
||||
<script type="text/javascript" src="../data/text.js"></script>
|
||||
<script type="text/javascript" src="../guide/js/jquery-3.6.0.min.js"></script>
|
||||
<script type="text/javascript" src="../guide/js/json2.js"></script>
|
||||
<script type="text/javascript" src="../guide/js/globalapi.js"></script>
|
||||
<script type="text/javascript" src="../guide/js/home.js"></script>
|
||||
</head>
|
||||
<body onLoad="OnInit()">
|
||||
<div id="GifBoard">
|
||||
<div class="GifBlock">
|
||||
<div class="UG_TITLE trans" tid="t4"></div>
|
||||
<div class="UG_DESC trans" tid="wk2">
|
||||
Please set up your printer connection to view the device.
|
||||
</div>
|
||||
<div class="UG_IMG"><img src="link_connection.png" /></div>
|
||||
</div>
|
||||
</div>
|
||||
<!--<h1 class="trans" tid="t4">Printer Connection</h1>
|
||||
<p class="trans">Please set up your printer connection to view the device.</p>
|
||||
<img src="setup_connection.gif" alt="Printer connection setup demonstration" style="max-width: 100%; height: auto; display: block;"/>-->
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.7 MiB |
70
src/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"typeinfo": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"map": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
//B64
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/nowide/args.hpp>
|
||||
@@ -130,12 +132,6 @@ int CLI::run(int argc, char **argv)
|
||||
// On Unix systems, the qidi-slicer binary may be symlinked to give the application a different meaning.
|
||||
boost::algorithm::iends_with(boost::filesystem::path(argv[0]).filename().string(), "gcodeviewer");
|
||||
#endif // _WIN32
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
std::pair<int, int> opengl_version = { 0, 0 };
|
||||
#if ENABLE_OPENGL_DEBUG_OPTION
|
||||
bool opengl_debug = false;
|
||||
#endif // ENABLE_OPENGL_DEBUG_OPTION
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
|
||||
const std::vector<std::string> &load_configs = m_config.option<ConfigOptionStrings>("load", true)->values;
|
||||
const ForwardCompatibilitySubstitutionRule config_substitution_rule = m_config.option<ConfigOptionEnum<ForwardCompatibilitySubstitutionRule>>("config_compatibility", true)->value;
|
||||
@@ -174,7 +170,11 @@ int CLI::run(int argc, char **argv)
|
||||
m_print_config.apply(config);
|
||||
}
|
||||
|
||||
#ifdef SLIC3R_GUI
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
std::pair<int, int> opengl_version = { 0, 0 };
|
||||
bool opengl_debug = false;
|
||||
bool opengl_compatibility_profile = false;
|
||||
// search for special keys into command line parameters
|
||||
auto it = std::find(m_actions.begin(), m_actions.end(), "gcodeviewer");
|
||||
if (it != m_actions.end()) {
|
||||
@@ -185,30 +185,37 @@ int CLI::run(int argc, char **argv)
|
||||
|
||||
it = std::find(m_actions.begin(), m_actions.end(), "opengl-version");
|
||||
if (it != m_actions.end()) {
|
||||
std::string opengl_version_str = m_config.opt_string("opengl-version");
|
||||
if (std::find(Slic3r::GUI::OpenGLVersions::core_str.begin(), Slic3r::GUI::OpenGLVersions::core_str.end(), opengl_version_str) == Slic3r::GUI::OpenGLVersions::core_str.end()) {
|
||||
if (std::find(Slic3r::GUI::OpenGLVersions::precore_str.begin(), Slic3r::GUI::OpenGLVersions::precore_str.end(), opengl_version_str) == Slic3r::GUI::OpenGLVersions::precore_str.end()) {
|
||||
boost::nowide::cerr << "Found invalid OpenGL version: " << opengl_version_str << std::endl;
|
||||
opengl_version_str.clear();
|
||||
const Semver opengl_minimum = Semver(3,2,0);
|
||||
const std::string opengl_version_str = m_config.opt_string("opengl-version");
|
||||
boost::optional<Semver> semver = Semver::parse(opengl_version_str);
|
||||
if (semver.has_value() && (*semver) >= opengl_minimum ) {
|
||||
opengl_version.first = semver->maj();
|
||||
opengl_version.second = semver->min();
|
||||
if (std::find(Slic3r::GUI::OpenGLVersions::core.begin(), Slic3r::GUI::OpenGLVersions::core.end(), std::make_pair(opengl_version.first, opengl_version.second)) == Slic3r::GUI::OpenGLVersions::core.end()) {
|
||||
opengl_version = { 0, 0 };
|
||||
boost::nowide::cerr << "Required OpenGL version " << opengl_version_str << " not recognized.\n Option 'opengl-version' ignored." << std::endl;
|
||||
}
|
||||
} else
|
||||
boost::nowide::cerr << "Required OpenGL version " << opengl_version_str << " is invalid. Must be greater than or equal to " <<
|
||||
opengl_minimum.to_string() << "\n Option 'opengl-version' ignored." << std::endl;
|
||||
start_gui = true;
|
||||
m_actions.erase(it);
|
||||
}
|
||||
|
||||
if (!opengl_version_str.empty()) {
|
||||
std::vector<std::string> tokens;
|
||||
boost::split(tokens, opengl_version_str, boost::is_any_of("."), boost::token_compress_on);
|
||||
opengl_version.first = std::stoi(tokens[0].c_str());
|
||||
opengl_version.second = std::stoi(tokens[1].c_str());
|
||||
}
|
||||
it = std::find(m_actions.begin(), m_actions.end(), "opengl-compatibility");
|
||||
if (it != m_actions.end()) {
|
||||
start_gui = true;
|
||||
opengl_compatibility_profile = true;
|
||||
// reset version as compatibility profile always take the highest version
|
||||
// supported by the graphic card
|
||||
opengl_version = std::make_pair(0, 0);
|
||||
m_actions.erase(it);
|
||||
}
|
||||
|
||||
it = std::find(m_actions.begin(), m_actions.end(), "opengl-debug");
|
||||
if (it != m_actions.end()) {
|
||||
start_gui = true;
|
||||
#if ENABLE_OPENGL_DEBUG_OPTION
|
||||
opengl_debug = true;
|
||||
#endif // ENABLE_OPENGL_DEBUG_OPTION
|
||||
m_actions.erase(it);
|
||||
}
|
||||
#else
|
||||
@@ -222,6 +229,16 @@ int CLI::run(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
#else // SLIC3R_GUI
|
||||
// If there is no GUI, we shall ignore the parameters. Remove them from the list.
|
||||
for (const std::string& s : { "opengl-version", "opengl-compatibility", "opengl-debug", "gcodeviewer" }) {
|
||||
auto it = std::find(m_actions.cbegin(), m_actions.cend(), s);
|
||||
if (it != m_actions.end()) {
|
||||
boost::nowide::cerr << "Parameter '" << s << "' is ignored, this PrusaSlicer build is CLI only." << std::endl;
|
||||
m_actions.erase(it);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read input file(s) if any.
|
||||
for (const std::string& file : m_input_files)
|
||||
@@ -702,10 +719,9 @@ int CLI::run(int argc, char **argv)
|
||||
params.download_url = download_url;
|
||||
params.delete_after_load = delete_after_load;
|
||||
#if ENABLE_GL_CORE_PROFILE
|
||||
#if ENABLE_OPENGL_DEBUG_OPTION
|
||||
params.opengl_version = opengl_version;
|
||||
params.opengl_debug = opengl_debug;
|
||||
#endif // ENABLE_OPENGL_DEBUG_OPTION
|
||||
params.opengl_compatibiity_profile = opengl_compatibility_profile;
|
||||
#endif // ENABLE_GL_CORE_PROFILE
|
||||
return Slic3r::GUI::GUI_Run(params);
|
||||
#else // SLIC3R_GUI
|
||||
@@ -781,6 +797,7 @@ bool CLI::setup(int argc, char **argv)
|
||||
set_var_dir((path_resources / "icons").string());
|
||||
set_local_dir((path_resources / "localization").string());
|
||||
set_sys_shapes_dir((path_resources / "shapes").string());
|
||||
set_custom_gcodes_dir((path_resources / "custom_gcodes").string());
|
||||
|
||||
// Parse all command line options into a DynamicConfig.
|
||||
// If any option is unsupported, print usage and abort immediately.
|
||||
@@ -805,6 +822,11 @@ bool CLI::setup(int argc, char **argv)
|
||||
set_logging_level(opt_loglevel->value);
|
||||
}
|
||||
|
||||
{
|
||||
const ConfigOptionInt *opt_threads = m_config.opt<ConfigOptionInt>("threads");
|
||||
if (opt_threads != nullptr)
|
||||
thread_count = opt_threads->value;
|
||||
}
|
||||
//FIXME Validating at this stage most likely does not make sense, as the config is not fully initialized yet.
|
||||
std::string validity = m_config.validate();
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ int wmain(int argc, wchar_t **argv)
|
||||
// In that case, use Mesa.
|
||||
(::GetSystemMetrics(SM_REMOTESESSION) && !force_hw) ||
|
||||
// Try to load the default OpenGL driver and test its context version.
|
||||
! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0);
|
||||
! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(3, 2);
|
||||
#endif /* SLIC3R_GUI */
|
||||
|
||||
wchar_t path_to_exe[MAX_PATH + 1] = { 0 };
|
||||
|
||||
@@ -153,7 +153,7 @@ void AppConfig::set_defaults()
|
||||
set("default_action_on_new_project", "none"); // , "keep(transfer)", "discard" or "save"
|
||||
|
||||
if (get("color_mapinulation_panel").empty())
|
||||
set("color_mapinulation_panel", "0");
|
||||
set("color_mapinulation_panel", "1");
|
||||
|
||||
if (get("order_volumes").empty())
|
||||
set("order_volumes", "1");
|
||||
@@ -211,11 +211,33 @@ void AppConfig::set_defaults()
|
||||
|
||||
if (get("sys_menu_enabled").empty())
|
||||
set("sys_menu_enabled", "1");
|
||||
//B45
|
||||
|
||||
#endif // _WIN32
|
||||
// B45
|
||||
if (get("machine_list_minification").empty())
|
||||
set("machine_list_minification", "1");
|
||||
#endif // _WIN32
|
||||
|
||||
//B64
|
||||
if (get("user_token").empty())
|
||||
set("user_token", "");
|
||||
|
||||
//y5
|
||||
if(get("user_head_url").empty())
|
||||
set("user_head_url", "");
|
||||
|
||||
if(get("user_head_name").empty())
|
||||
set("user_head_name", "");
|
||||
|
||||
if (get("sending_interval").empty()) {
|
||||
set("sending_interval", "5");
|
||||
}
|
||||
|
||||
if (get("max_send").empty()) {
|
||||
set("max_send", "3");
|
||||
}
|
||||
|
||||
if (get("machine_list_net").empty())
|
||||
set("machine_list_net", "0");
|
||||
// Remove legacy window positions/sizes
|
||||
erase("", "main_frame_maximized");
|
||||
erase("", "main_frame_pos");
|
||||
|
||||
@@ -41,8 +41,8 @@ BeadingStrategyPtr BeadingStrategyFactory::makeStrategy(const coord_t preferred_
|
||||
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);
|
||||
}
|
||||
|
||||
if (outer_wall_offset > 0) {
|
||||
//w39
|
||||
if (outer_wall_offset != 0){//if (outer_wall_offset > 0) {
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <functional>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "utils/VoronoiUtils.hpp"
|
||||
|
||||
#include "utils/linearAlg2D.hpp"
|
||||
#include "Utils.hpp"
|
||||
@@ -19,26 +18,9 @@
|
||||
#include "Geometry/VoronoiUtilsCgal.hpp"
|
||||
#include "../EdgeGrid.hpp"
|
||||
|
||||
#include "Geometry/VoronoiUtils.hpp"
|
||||
#define SKELETAL_TRAPEZOIDATION_BEAD_SEARCH_MAX 1000 //A limit to how long it'll keep searching for adjacent beads. Increasing will re-use beadings more often (saving performance), but search longer for beading (costing performance).
|
||||
|
||||
namespace boost::polygon {
|
||||
|
||||
template<> struct geometry_concept<Slic3r::Arachne::PolygonsSegmentIndex>
|
||||
{
|
||||
typedef segment_concept type;
|
||||
};
|
||||
|
||||
template<> struct segment_traits<Slic3r::Arachne::PolygonsSegmentIndex>
|
||||
{
|
||||
typedef coord_t coordinate_type;
|
||||
typedef Slic3r::Point point_type;
|
||||
static inline point_type get(const Slic3r::Arachne::PolygonsSegmentIndex &CSegment, direction_1d dir)
|
||||
{
|
||||
return dir.to_int() ? CSegment.p() : CSegment.next().p();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost::polygon
|
||||
|
||||
namespace Slic3r::Arachne
|
||||
{
|
||||
@@ -108,8 +90,7 @@ static void export_graph_to_svg(const std::string
|
||||
}
|
||||
#endif
|
||||
|
||||
SkeletalTrapezoidation::node_t& SkeletalTrapezoidation::makeNode(vd_t::vertex_type& vd_node, Point p)
|
||||
{
|
||||
SkeletalTrapezoidation::node_t &SkeletalTrapezoidation::makeNode(const VD::vertex_type &vd_node, Point p) {
|
||||
auto he_node_it = vd_node_to_he_node.find(&vd_node);
|
||||
if (he_node_it == vd_node_to_he_node.end())
|
||||
{
|
||||
@@ -124,8 +105,7 @@ SkeletalTrapezoidation::node_t& SkeletalTrapezoidation::makeNode(vd_t::vertex_ty
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletalTrapezoidation::transferEdge(Point from, Point to, vd_t::edge_type& vd_edge, edge_t*& prev_edge, Point& start_source_point, Point& end_source_point, const std::vector<Segment>& segments)
|
||||
{
|
||||
void SkeletalTrapezoidation::transferEdge(Point from, Point to, const VD::edge_type &vd_edge, edge_t *&prev_edge, Point &start_source_point, Point &end_source_point, const std::vector<Segment> &segments) {
|
||||
auto he_edge_it = vd_edge_to_he_edge.find(vd_edge.twin());
|
||||
if (he_edge_it != vd_edge_to_he_edge.end())
|
||||
{ // Twin segment(s) have already been made
|
||||
@@ -235,22 +215,18 @@ void SkeletalTrapezoidation::transferEdge(Point from, Point to, vd_t::edge_type&
|
||||
}
|
||||
}
|
||||
|
||||
Points SkeletalTrapezoidation::discretize(const vd_t::edge_type& vd_edge, const std::vector<Segment>& segments)
|
||||
Points SkeletalTrapezoidation::discretize(const VD::edge_type& vd_edge, const std::vector<Segment>& segments)
|
||||
{
|
||||
assert(Geometry::VoronoiUtils::is_in_range<coord_t>(vd_edge));
|
||||
/*Terminology in this function assumes that the edge moves horizontally from
|
||||
left to right. This is not necessarily the case; the edge can go in any
|
||||
direction, but it helps to picture it in a certain direction in your head.*/
|
||||
|
||||
const vd_t::cell_type* left_cell = vd_edge.cell();
|
||||
const vd_t::cell_type* right_cell = vd_edge.twin()->cell();
|
||||
const VD::cell_type *left_cell = vd_edge.cell();
|
||||
const VD::cell_type *right_cell = vd_edge.twin()->cell();
|
||||
|
||||
assert(VoronoiUtils::p(vd_edge.vertex0()).x() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge.vertex0()).x() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(vd_edge.vertex0()).y() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge.vertex0()).y() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(vd_edge.vertex1()).x() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge.vertex1()).x() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(vd_edge.vertex1()).y() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge.vertex1()).y() >= std::numeric_limits<coord_t>::lowest());
|
||||
|
||||
Point start = VoronoiUtils::p(vd_edge.vertex0()).cast<coord_t>();
|
||||
Point end = VoronoiUtils::p(vd_edge.vertex1()).cast<coord_t>();
|
||||
Point start = Geometry::VoronoiUtils::to_point(vd_edge.vertex0()).cast<coord_t>();
|
||||
Point end = Geometry::VoronoiUtils::to_point(vd_edge.vertex1()).cast<coord_t>();
|
||||
|
||||
bool point_left = left_cell->contains_point();
|
||||
bool point_right = right_cell->contains_point();
|
||||
@@ -260,17 +236,17 @@ Points SkeletalTrapezoidation::discretize(const vd_t::edge_type& vd_edge, const
|
||||
}
|
||||
else if (point_left != point_right) //This is a parabolic edge between a point and a line.
|
||||
{
|
||||
Point p = VoronoiUtils::getSourcePoint(*(point_left ? left_cell : right_cell), segments);
|
||||
const Segment& s = VoronoiUtils::getSourceSegment(*(point_left ? right_cell : left_cell), segments);
|
||||
return VoronoiUtils::discretizeParabola(p, s, start, end, discretization_step_size, transitioning_angle);
|
||||
Point p = Geometry::VoronoiUtils::get_source_point(*(point_left ? left_cell : right_cell), segments.begin(), segments.end());
|
||||
const Segment& s = Geometry::VoronoiUtils::get_source_segment(*(point_left ? right_cell : left_cell), segments.begin(), segments.end());
|
||||
return Geometry::VoronoiUtils::discretize_parabola(p, s, start, end, discretization_step_size, transitioning_angle);
|
||||
}
|
||||
else //This is a straight edge between two points.
|
||||
{
|
||||
/*While the edge is straight, it is still discretized since the part
|
||||
becomes narrower between the two points. As such it may need different
|
||||
beadings along the way.*/
|
||||
Point left_point = VoronoiUtils::getSourcePoint(*left_cell, segments);
|
||||
Point right_point = VoronoiUtils::getSourcePoint(*right_cell, segments);
|
||||
Point left_point = Geometry::VoronoiUtils::get_source_point(*left_cell, segments.begin(), segments.end());
|
||||
Point right_point = Geometry::VoronoiUtils::get_source_point(*right_cell, segments.begin(), segments.end());
|
||||
coord_t d = (right_point - left_point).cast<int64_t>().norm();
|
||||
Point middle = (left_point + right_point) / 2;
|
||||
Point x_axis_dir = perp(Point(right_point - left_point));
|
||||
@@ -350,8 +326,7 @@ Points SkeletalTrapezoidation::discretize(const vd_t::edge_type& vd_edge, const
|
||||
}
|
||||
}
|
||||
|
||||
bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector<Segment>& segments)
|
||||
{
|
||||
bool SkeletalTrapezoidation::computePointCellRange(const VD::cell_type &cell, Point &start_source_point, Point &end_source_point, const VD::edge_type *&starting_vd_edge, const VD::edge_type *&ending_vd_edge, const std::vector<Segment> &segments) {
|
||||
if (cell.incident_edge()->is_infinite())
|
||||
return false; //Infinite edges only occur outside of the polygon. Don't copy any part of this cell.
|
||||
|
||||
@@ -359,16 +334,16 @@ bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point&
|
||||
// Copy whole cell into graph or not at all
|
||||
|
||||
// If the cell.incident_edge()->vertex0() is far away so much that it doesn't even fit into Vec2i64, then there is no way that it will be inside the input polygon.
|
||||
if (const vd_t::vertex_type &vert = *cell.incident_edge()->vertex0();
|
||||
if (const VD::vertex_type &vert = *cell.incident_edge()->vertex0();
|
||||
vert.x() >= double(std::numeric_limits<int64_t>::max()) || vert.x() <= double(std::numeric_limits<int64_t>::lowest()) ||
|
||||
vert.y() >= double(std::numeric_limits<int64_t>::max()) || vert.y() <= double(std::numeric_limits<int64_t>::lowest()))
|
||||
return false; // Don't copy any part of this cell
|
||||
|
||||
const Point source_point = VoronoiUtils::getSourcePoint(cell, segments);
|
||||
const PolygonsPointIndex source_point_index = VoronoiUtils::getSourcePointIndex(cell, segments);
|
||||
Vec2i64 some_point = VoronoiUtils::p(cell.incident_edge()->vertex0());
|
||||
const Point source_point = Geometry::VoronoiUtils::get_source_point(cell, segments.begin(), segments.end());
|
||||
const PolygonsPointIndex source_point_index = Geometry::VoronoiUtils::get_source_point_index(cell, segments.begin(), segments.end());
|
||||
Vec2i64 some_point = Geometry::VoronoiUtils::to_point(cell.incident_edge()->vertex0());
|
||||
if (some_point == source_point.cast<int64_t>())
|
||||
some_point = VoronoiUtils::p(cell.incident_edge()->vertex1());
|
||||
some_point = Geometry::VoronoiUtils::to_point(cell.incident_edge()->vertex1());
|
||||
|
||||
//Test if the some_point is even inside the polygon.
|
||||
//The edge leading out of a polygon must have an endpoint that's not in the corner following the contour of the polygon at that vertex.
|
||||
@@ -377,16 +352,16 @@ bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point&
|
||||
if (!LinearAlg2D::isInsideCorner(source_point_index.prev().p(), source_point_index.p(), source_point_index.next().p(), some_point))
|
||||
return false; // Don't copy any part of this cell
|
||||
|
||||
vd_t::edge_type* vd_edge = cell.incident_edge();
|
||||
const VD::edge_type* vd_edge = cell.incident_edge();
|
||||
do {
|
||||
assert(vd_edge->is_finite());
|
||||
if (Vec2i64 p1 = VoronoiUtils::p(vd_edge->vertex1()); p1 == source_point.cast<int64_t>()) {
|
||||
if (Vec2i64 p1 = Geometry::VoronoiUtils::to_point(vd_edge->vertex1()); p1 == source_point.cast<int64_t>()) {
|
||||
start_source_point = source_point;
|
||||
end_source_point = source_point;
|
||||
starting_vd_edge = vd_edge->next();
|
||||
ending_vd_edge = vd_edge;
|
||||
} else {
|
||||
assert((VoronoiUtils::p(vd_edge->vertex0()) == source_point.cast<int64_t>() || !vd_edge->is_secondary()) && "point cells must end in the point! They cannot cross the point with an edge, because collinear edges are not allowed in the input.");
|
||||
assert((Geometry::VoronoiUtils::to_point(vd_edge->vertex0()) == source_point.cast<int64_t>() || !vd_edge->is_secondary()) && "point cells must end in the point! They cannot cross the point with an edge, because collinear edges are not allowed in the input.");
|
||||
}
|
||||
}
|
||||
while (vd_edge = vd_edge->next(), vd_edge != cell.incident_edge());
|
||||
@@ -395,46 +370,6 @@ bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point&
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkeletalTrapezoidation::computeSegmentCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector<Segment>& segments)
|
||||
{
|
||||
const Segment &source_segment = VoronoiUtils::getSourceSegment(cell, segments);
|
||||
const Point from = source_segment.from();
|
||||
const Point to = source_segment.to();
|
||||
|
||||
// Find starting edge
|
||||
// Find end edge
|
||||
bool seen_possible_start = false;
|
||||
bool after_start = false;
|
||||
bool ending_edge_is_set_before_start = false;
|
||||
vd_t::edge_type* edge = cell.incident_edge();
|
||||
do {
|
||||
if (edge->is_infinite())
|
||||
continue;
|
||||
|
||||
Vec2i64 v0 = VoronoiUtils::p(edge->vertex0());
|
||||
Vec2i64 v1 = VoronoiUtils::p(edge->vertex1());
|
||||
|
||||
assert(!(v0 == to.cast<int64_t>() && v1 == from.cast<int64_t>() ));
|
||||
if (v0 == to.cast<int64_t>() && !after_start) { // Use the last edge which starts in source_segment.to
|
||||
starting_vd_edge = edge;
|
||||
seen_possible_start = true;
|
||||
}
|
||||
else if (seen_possible_start) {
|
||||
after_start = true;
|
||||
}
|
||||
|
||||
if (v1 == from.cast<int64_t>() && (!ending_vd_edge || ending_edge_is_set_before_start)) {
|
||||
ending_edge_is_set_before_start = !after_start;
|
||||
ending_vd_edge = edge;
|
||||
}
|
||||
} while (edge = edge->next(), edge != cell.incident_edge());
|
||||
|
||||
assert(starting_vd_edge && ending_vd_edge);
|
||||
assert(starting_vd_edge != ending_vd_edge);
|
||||
|
||||
start_source_point = source_segment.to();
|
||||
end_source_point = source_segment.from();
|
||||
}
|
||||
|
||||
SkeletalTrapezoidation::SkeletalTrapezoidation(const Polygons& polys, const BeadingStrategy& beading_strategy,
|
||||
double transitioning_angle, coord_t discretization_step_size,
|
||||
@@ -450,194 +385,6 @@ SkeletalTrapezoidation::SkeletalTrapezoidation(const Polygons& polys, const Bead
|
||||
constructFromPolygons(polys);
|
||||
}
|
||||
|
||||
static bool has_finite_edge_with_non_finite_vertex(const Geometry::VoronoiDiagram &voronoi_diagram)
|
||||
{
|
||||
for (const VoronoiUtils::vd_t::edge_type &edge : voronoi_diagram.edges()) {
|
||||
if (edge.is_finite()) {
|
||||
assert(edge.vertex0() != nullptr && edge.vertex1() != nullptr);
|
||||
if (edge.vertex0() == nullptr || edge.vertex1() == nullptr || !VoronoiUtils::is_finite(*edge.vertex0()) ||
|
||||
!VoronoiUtils::is_finite(*edge.vertex1()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool detect_missing_voronoi_vertex(const Geometry::VoronoiDiagram &voronoi_diagram, const std::vector<SkeletalTrapezoidation::Segment> &segments) {
|
||||
if (has_finite_edge_with_non_finite_vertex(voronoi_diagram))
|
||||
return true;
|
||||
|
||||
for (VoronoiUtils::vd_t::cell_type cell : voronoi_diagram.cells()) {
|
||||
if (!cell.incident_edge())
|
||||
continue; // There is no spoon
|
||||
|
||||
if (cell.contains_segment()) {
|
||||
const SkeletalTrapezoidation::Segment &source_segment = VoronoiUtils::getSourceSegment(cell, segments);
|
||||
const Point from = source_segment.from();
|
||||
const Point to = source_segment.to();
|
||||
|
||||
// Find starting edge
|
||||
// Find end edge
|
||||
bool seen_possible_start = false;
|
||||
bool after_start = false;
|
||||
bool ending_edge_is_set_before_start = false;
|
||||
VoronoiUtils::vd_t::edge_type *starting_vd_edge = nullptr;
|
||||
VoronoiUtils::vd_t::edge_type *ending_vd_edge = nullptr;
|
||||
VoronoiUtils::vd_t::edge_type *edge = cell.incident_edge();
|
||||
do {
|
||||
if (edge->is_infinite() || edge->vertex0() == nullptr || edge->vertex1() == nullptr || !VoronoiUtils::is_finite(*edge->vertex0()) || !VoronoiUtils::is_finite(*edge->vertex1()))
|
||||
continue;
|
||||
|
||||
Vec2i64 v0 = VoronoiUtils::p(edge->vertex0());
|
||||
Vec2i64 v1 = VoronoiUtils::p(edge->vertex1());
|
||||
|
||||
assert(!(v0 == to.cast<int64_t>() && v1 == from.cast<int64_t>()));
|
||||
if (v0 == to.cast<int64_t>() && !after_start) { // Use the last edge which starts in source_segment.to
|
||||
starting_vd_edge = edge;
|
||||
seen_possible_start = true;
|
||||
} else if (seen_possible_start) {
|
||||
after_start = true;
|
||||
}
|
||||
|
||||
if (v1 == from.cast<int64_t>() && (!ending_vd_edge || ending_edge_is_set_before_start)) {
|
||||
ending_edge_is_set_before_start = !after_start;
|
||||
ending_vd_edge = edge;
|
||||
}
|
||||
} while (edge = edge->next(), edge != cell.incident_edge());
|
||||
|
||||
if (!starting_vd_edge || !ending_vd_edge || starting_vd_edge == ending_vd_edge)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool has_missing_twin_edge(const SkeletalTrapezoidationGraph &graph)
|
||||
{
|
||||
for (const auto &edge : graph.edges)
|
||||
if (edge.twin == nullptr)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
using PointMap = SkeletalTrapezoidation::PointMap;
|
||||
|
||||
inline static void rotate_back_skeletal_trapezoidation_graph_after_fix(SkeletalTrapezoidationGraph &graph,
|
||||
const double fix_angle,
|
||||
const PointMap &vertex_mapping)
|
||||
{
|
||||
for (STHalfEdgeNode &node : graph.nodes) {
|
||||
// If a mapping exists between a rotated point and an original point, use this mapping. Otherwise, rotate a point in the opposite direction.
|
||||
if (auto node_it = vertex_mapping.find(node.p); node_it != vertex_mapping.end())
|
||||
node.p = node_it->second;
|
||||
else
|
||||
node.p.rotate(-fix_angle);
|
||||
}
|
||||
}
|
||||
|
||||
bool detect_voronoi_edge_intersecting_input_segment(const Geometry::VoronoiDiagram &voronoi_diagram, const std::vector<VoronoiUtils::Segment> &segments)
|
||||
{
|
||||
for (VoronoiUtils::vd_t::cell_type cell : voronoi_diagram.cells()) {
|
||||
if (!cell.incident_edge())
|
||||
continue; // Degenerated cell, there is no spoon
|
||||
|
||||
if (!cell.contains_segment())
|
||||
continue; // Skip cells that don't contain segments.
|
||||
|
||||
const VoronoiUtils::Segment &source_segment = VoronoiUtils::getSourceSegment(cell, segments);
|
||||
const Vec2d source_segment_from = source_segment.from().cast<double>();
|
||||
const Vec2d source_segment_vec = source_segment.to().cast<double>() - source_segment_from;
|
||||
|
||||
Point start_source_point, end_source_point;
|
||||
VoronoiUtils::vd_t::edge_type *begin_voronoi_edge = nullptr, *end_voronoi_edge = nullptr;
|
||||
SkeletalTrapezoidation::computeSegmentCellRange(cell, start_source_point, end_source_point, begin_voronoi_edge, end_voronoi_edge, segments);
|
||||
// All Voronoi vertices must be on left side of the source segment, otherwise Voronoi diagram is invalid.
|
||||
// FIXME Lukas H.: Be aware that begin_voronoi_edge and end_voronoi_edge could be nullptr in some specific cases.
|
||||
// It mostly happens when there is some missing Voronoi, for example, in GH issue #8846 (IssuesWithMysteriousPerimeters.3mf).
|
||||
if (begin_voronoi_edge != nullptr && end_voronoi_edge != nullptr)
|
||||
for (VoronoiUtils::vd_t::edge_type *edge = begin_voronoi_edge; edge != end_voronoi_edge; edge = edge->next())
|
||||
if (const Vec2d edge_v1(edge->vertex1()->x(), edge->vertex1()->y()); Slic3r::cross2(source_segment_vec, edge_v1 - source_segment_from) < 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum class VoronoiDiagramStatus {
|
||||
NO_ISSUE_DETECTED,
|
||||
MISSING_VORONOI_VERTEX,
|
||||
NON_PLANAR_VORONOI_DIAGRAM,
|
||||
VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT,
|
||||
OTHER_TYPE_OF_VORONOI_DIAGRAM_DEGENERATION
|
||||
};
|
||||
|
||||
// Try to detect cases when some Voronoi vertex is missing, when the Voronoi diagram
|
||||
// is not planar or some Voronoi edge is intersecting input segment.
|
||||
VoronoiDiagramStatus detect_voronoi_diagram_known_issues(const Geometry::VoronoiDiagram &voronoi_diagram,
|
||||
const std::vector<SkeletalTrapezoidation::Segment> &segments)
|
||||
{
|
||||
if (const bool has_missing_voronoi_vertex = detect_missing_voronoi_vertex(voronoi_diagram, segments); has_missing_voronoi_vertex) {
|
||||
return VoronoiDiagramStatus::MISSING_VORONOI_VERTEX;
|
||||
} else if (const bool has_voronoi_edge_intersecting_input_segment = detect_voronoi_edge_intersecting_input_segment(voronoi_diagram, segments); has_voronoi_edge_intersecting_input_segment) {
|
||||
// Detection if Voronoi edge is intersecting input segment detects at least one model in GH issue #8446.
|
||||
return VoronoiDiagramStatus::VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT;
|
||||
} else if (const bool is_voronoi_diagram_planar = Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(voronoi_diagram, segments); !is_voronoi_diagram_planar) {
|
||||
// Detection of non-planar Voronoi diagram detects at least GH issues #8474, #8514 and #8446.
|
||||
return VoronoiDiagramStatus::NON_PLANAR_VORONOI_DIAGRAM;
|
||||
}
|
||||
return VoronoiDiagramStatus::NO_ISSUE_DETECTED;
|
||||
}
|
||||
|
||||
inline static std::pair<PointMap, double> try_to_fix_degenerated_voronoi_diagram_by_rotation(
|
||||
Geometry::VoronoiDiagram &voronoi_diagram,
|
||||
const Polygons &polys,
|
||||
Polygons &polys_rotated,
|
||||
std::vector<SkeletalTrapezoidation::Segment> &segments,
|
||||
const std::vector<double> &fix_angles)
|
||||
{
|
||||
const Polygons polys_rotated_original = polys_rotated;
|
||||
double fixed_by_angle = fix_angles.front();
|
||||
PointMap vertex_mapping;
|
||||
|
||||
for (const double &fix_angle : fix_angles) {
|
||||
vertex_mapping.clear();
|
||||
polys_rotated = polys_rotated_original;
|
||||
fixed_by_angle = fix_angle;
|
||||
|
||||
for (Polygon &poly : polys_rotated)
|
||||
poly.rotate(fix_angle);
|
||||
|
||||
assert(polys_rotated.size() == polys.size());
|
||||
for (size_t poly_idx = 0; poly_idx < polys.size(); ++poly_idx) {
|
||||
assert(polys_rotated[poly_idx].size() == polys[poly_idx].size());
|
||||
for (size_t point_idx = 0; point_idx < polys[poly_idx].size(); ++point_idx)
|
||||
vertex_mapping.insert({polys_rotated[poly_idx][point_idx], polys[poly_idx][point_idx]});
|
||||
}
|
||||
|
||||
segments.clear();
|
||||
for (size_t poly_idx = 0; poly_idx < polys_rotated.size(); poly_idx++)
|
||||
for (size_t point_idx = 0; point_idx < polys_rotated[poly_idx].size(); point_idx++)
|
||||
segments.emplace_back(&polys_rotated, poly_idx, point_idx);
|
||||
|
||||
voronoi_diagram.clear();
|
||||
construct_voronoi(segments.begin(), segments.end(), &voronoi_diagram);
|
||||
|
||||
#ifdef ARACHNE_DEBUG_VORONOI
|
||||
{
|
||||
static int iRun = 0;
|
||||
dump_voronoi_to_svg(debug_out_path("arachne_voronoi-diagram-rotated-%d.svg", iRun++).c_str(), voronoi_diagram, to_points(polys), to_lines(polys));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (detect_voronoi_diagram_known_issues(voronoi_diagram, segments) == VoronoiDiagramStatus::NO_ISSUE_DETECTED)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(voronoi_diagram));
|
||||
|
||||
return {vertex_mapping, fixed_by_angle};
|
||||
}
|
||||
|
||||
void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys)
|
||||
{
|
||||
@@ -670,8 +417,8 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys)
|
||||
}
|
||||
#endif
|
||||
|
||||
Geometry::VoronoiDiagram voronoi_diagram;
|
||||
construct_voronoi(segments.begin(), segments.end(), &voronoi_diagram);
|
||||
VD voronoi_diagram;
|
||||
voronoi_diagram.construct_voronoi(segments.cbegin(), segments.cend());
|
||||
|
||||
#ifdef ARACHNE_DEBUG_VORONOI
|
||||
{
|
||||
@@ -680,45 +427,15 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys)
|
||||
}
|
||||
#endif
|
||||
|
||||
// When any Voronoi vertex is missing, the Voronoi diagram is not planar, or some voronoi edge is
|
||||
// intersecting input segment, rotate the input polygon and try again.
|
||||
VoronoiDiagramStatus status = detect_voronoi_diagram_known_issues(voronoi_diagram, segments);
|
||||
const std::vector<double> fix_angles = {PI / 6, PI / 5, PI / 7, PI / 11};
|
||||
double fixed_by_angle = fix_angles.front();
|
||||
|
||||
PointMap vertex_mapping;
|
||||
// polys_copy is referenced through items stored in the std::vector segments.
|
||||
Polygons polys_copy = polys;
|
||||
if (status != VoronoiDiagramStatus::NO_ISSUE_DETECTED) {
|
||||
if (status == VoronoiDiagramStatus::MISSING_VORONOI_VERTEX)
|
||||
BOOST_LOG_TRIVIAL(warning) << "Detected missing Voronoi vertex, input polygons will be rotated back and forth.";
|
||||
else if (status == VoronoiDiagramStatus::NON_PLANAR_VORONOI_DIAGRAM)
|
||||
BOOST_LOG_TRIVIAL(warning) << "Detected non-planar Voronoi diagram, input polygons will be rotated back and forth.";
|
||||
else if (status == VoronoiDiagramStatus::VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT)
|
||||
BOOST_LOG_TRIVIAL(warning) << "Detected Voronoi edge intersecting input segment, input polygons will be rotated back and forth.";
|
||||
|
||||
std::tie(vertex_mapping, fixed_by_angle) = try_to_fix_degenerated_voronoi_diagram_by_rotation(voronoi_diagram, polys, polys_copy, segments, fix_angles);
|
||||
|
||||
VoronoiDiagramStatus status_after_fix = detect_voronoi_diagram_known_issues(voronoi_diagram, segments);
|
||||
assert(status_after_fix == VoronoiDiagramStatus::NO_ISSUE_DETECTED);
|
||||
if (status_after_fix == VoronoiDiagramStatus::MISSING_VORONOI_VERTEX)
|
||||
BOOST_LOG_TRIVIAL(error) << "Detected missing Voronoi vertex even after the rotation of input.";
|
||||
else if (status_after_fix == VoronoiDiagramStatus::NON_PLANAR_VORONOI_DIAGRAM)
|
||||
BOOST_LOG_TRIVIAL(error) << "Detected non-planar Voronoi diagram even after the rotation of input.";
|
||||
else if (status_after_fix == VoronoiDiagramStatus::VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT)
|
||||
BOOST_LOG_TRIVIAL(error) << "Detected Voronoi edge intersecting input segment even after the rotation of input.";
|
||||
}
|
||||
|
||||
process_voronoi_diagram:
|
||||
assert(this->graph.edges.empty() && this->graph.nodes.empty() && this->vd_edge_to_he_edge.empty() && this->vd_node_to_he_node.empty());
|
||||
for (vd_t::cell_type cell : voronoi_diagram.cells()) {
|
||||
for (const VD::cell_type &cell : voronoi_diagram.cells()) {
|
||||
if (!cell.incident_edge())
|
||||
continue; // There is no spoon
|
||||
|
||||
Point start_source_point;
|
||||
Point end_source_point;
|
||||
vd_t::edge_type* starting_voronoi_edge = nullptr;
|
||||
vd_t::edge_type* ending_voronoi_edge = nullptr;
|
||||
const VD::edge_type *starting_voronoi_edge = nullptr;
|
||||
const VD::edge_type *ending_voronoi_edge = nullptr;
|
||||
// Compute and store result in above variables
|
||||
|
||||
if (cell.contains_point()) {
|
||||
@@ -727,7 +444,12 @@ process_voronoi_diagram:
|
||||
continue;
|
||||
} else {
|
||||
assert(cell.contains_segment());
|
||||
computeSegmentCellRange(cell, start_source_point, end_source_point, starting_voronoi_edge, ending_voronoi_edge, segments);
|
||||
Geometry::SegmentCellRange<Point> cell_range = Geometry::VoronoiUtils::compute_segment_cell_range(cell, segments.cbegin(), segments.cend());
|
||||
assert(cell_range.is_valid());
|
||||
start_source_point = cell_range.segment_start_point;
|
||||
end_source_point = cell_range.segment_end_point;
|
||||
starting_voronoi_edge = cell_range.edge_begin;
|
||||
ending_voronoi_edge = cell_range.edge_end;
|
||||
}
|
||||
|
||||
if (!starting_voronoi_edge || !ending_voronoi_edge) {
|
||||
@@ -736,68 +458,30 @@ process_voronoi_diagram:
|
||||
}
|
||||
|
||||
// Copy start to end edge to graph
|
||||
assert(Geometry::VoronoiUtils::is_in_range<coord_t>(*starting_voronoi_edge));
|
||||
edge_t* prev_edge = nullptr;
|
||||
assert(VoronoiUtils::p(starting_voronoi_edge->vertex1()).x() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(starting_voronoi_edge->vertex1()).x() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(starting_voronoi_edge->vertex1()).y() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(starting_voronoi_edge->vertex1()).y() >= std::numeric_limits<coord_t>::lowest());
|
||||
transferEdge(start_source_point, VoronoiUtils::p(starting_voronoi_edge->vertex1()).cast<coord_t>(), *starting_voronoi_edge, prev_edge, start_source_point, end_source_point, segments);
|
||||
transferEdge(start_source_point, Geometry::VoronoiUtils::to_point(starting_voronoi_edge->vertex1()).cast<coord_t>(), *starting_voronoi_edge, prev_edge, start_source_point, end_source_point, segments);
|
||||
node_t* starting_node = vd_node_to_he_node[starting_voronoi_edge->vertex0()];
|
||||
starting_node->data.distance_to_boundary = 0;
|
||||
|
||||
constexpr bool is_next_to_start_or_end = true;
|
||||
graph.makeRib(prev_edge, start_source_point, end_source_point, is_next_to_start_or_end);
|
||||
for (vd_t::edge_type* vd_edge = starting_voronoi_edge->next(); vd_edge != ending_voronoi_edge; vd_edge = vd_edge->next()) {
|
||||
for (const VD::edge_type* vd_edge = starting_voronoi_edge->next(); vd_edge != ending_voronoi_edge; vd_edge = vd_edge->next()) {
|
||||
assert(vd_edge->is_finite());
|
||||
|
||||
assert(VoronoiUtils::p(vd_edge->vertex0()).x() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge->vertex0()).x() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(vd_edge->vertex0()).y() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge->vertex0()).y() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(vd_edge->vertex1()).x() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge->vertex1()).x() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(vd_edge->vertex1()).y() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(vd_edge->vertex1()).y() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(Geometry::VoronoiUtils::is_in_range<coord_t>(*vd_edge));
|
||||
|
||||
Point v1 = VoronoiUtils::p(vd_edge->vertex0()).cast<coord_t>();
|
||||
Point v2 = VoronoiUtils::p(vd_edge->vertex1()).cast<coord_t>();
|
||||
Point v1 = Geometry::VoronoiUtils::to_point(vd_edge->vertex0()).cast<coord_t>();
|
||||
Point v2 = Geometry::VoronoiUtils::to_point(vd_edge->vertex1()).cast<coord_t>();
|
||||
transferEdge(v1, v2, *vd_edge, prev_edge, start_source_point, end_source_point, segments);
|
||||
|
||||
graph.makeRib(prev_edge, start_source_point, end_source_point, vd_edge->next() == ending_voronoi_edge);
|
||||
}
|
||||
|
||||
assert(VoronoiUtils::p(starting_voronoi_edge->vertex0()).x() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(starting_voronoi_edge->vertex0()).x() >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(VoronoiUtils::p(starting_voronoi_edge->vertex0()).y() <= std::numeric_limits<coord_t>::max() && VoronoiUtils::p(starting_voronoi_edge->vertex0()).y() >= std::numeric_limits<coord_t>::lowest());
|
||||
transferEdge(VoronoiUtils::p(ending_voronoi_edge->vertex0()).cast<coord_t>(), end_source_point, *ending_voronoi_edge, prev_edge, start_source_point, end_source_point, segments);
|
||||
transferEdge(Geometry::VoronoiUtils::to_point(ending_voronoi_edge->vertex0()).cast<coord_t>(), end_source_point, *ending_voronoi_edge, prev_edge, start_source_point, end_source_point, segments);
|
||||
prev_edge->to->data.distance_to_boundary = 0;
|
||||
}
|
||||
|
||||
// For some input polygons, as in GH issues #8474 and #8514 resulting Voronoi diagram is degenerated because it is not planar.
|
||||
// When this degenerated Voronoi diagram is processed, the resulting half-edge structure contains some edges that don't have
|
||||
// a twin edge. Based on this, we created a fast mechanism that detects those causes and tries to recompute the Voronoi
|
||||
// diagram on slightly rotated input polygons that usually make the Voronoi generator generate a non-degenerated Voronoi diagram.
|
||||
if (status == VoronoiDiagramStatus::NO_ISSUE_DETECTED && has_missing_twin_edge(this->graph)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Detected degenerated Voronoi diagram, input polygons will be rotated back and forth.";
|
||||
status = VoronoiDiagramStatus::OTHER_TYPE_OF_VORONOI_DIAGRAM_DEGENERATION;
|
||||
std::tie(vertex_mapping, fixed_by_angle) = try_to_fix_degenerated_voronoi_diagram_by_rotation(voronoi_diagram, polys, polys_copy, segments, fix_angles);
|
||||
|
||||
assert(!detect_missing_voronoi_vertex(voronoi_diagram, segments));
|
||||
if (detect_missing_voronoi_vertex(voronoi_diagram, segments))
|
||||
BOOST_LOG_TRIVIAL(error) << "Detected missing Voronoi vertex after the rotation of input.";
|
||||
|
||||
assert(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(voronoi_diagram));
|
||||
|
||||
this->graph.edges.clear();
|
||||
this->graph.nodes.clear();
|
||||
this->vd_edge_to_he_edge.clear();
|
||||
this->vd_node_to_he_node.clear();
|
||||
|
||||
goto process_voronoi_diagram;
|
||||
}
|
||||
|
||||
if (status != VoronoiDiagramStatus::NO_ISSUE_DETECTED) {
|
||||
assert(!has_missing_twin_edge(this->graph));
|
||||
|
||||
if (has_missing_twin_edge(this->graph))
|
||||
BOOST_LOG_TRIVIAL(error) << "Detected degenerated Voronoi diagram even after the rotation of input.";
|
||||
}
|
||||
|
||||
if (status != VoronoiDiagramStatus::NO_ISSUE_DETECTED)
|
||||
rotate_back_skeletal_trapezoidation_graph_after_fix(this->graph, fixed_by_angle, vertex_mapping);
|
||||
|
||||
#ifdef ARACHNE_DEBUG
|
||||
assert(Geometry::VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(voronoi_diagram));
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
#include <Arachne/utils/VoronoiUtils.hpp>
|
||||
|
||||
#include "utils/HalfEdgeGraph.hpp"
|
||||
#include "utils/PolygonsSegmentIndex.hpp"
|
||||
@@ -26,8 +25,9 @@
|
||||
//#define ARACHNE_DEBUG
|
||||
//#define ARACHNE_DEBUG_VORONOI
|
||||
|
||||
namespace Slic3r::Arachne
|
||||
{
|
||||
namespace Slic3r::Arachne {
|
||||
|
||||
using VD = Slic3r::Geometry::VoronoiDiagram;
|
||||
|
||||
/*!
|
||||
* Main class of the dynamic beading strategies.
|
||||
@@ -50,8 +50,6 @@ deposition modeling" by Kuipers et al.
|
||||
*/
|
||||
class SkeletalTrapezoidation
|
||||
{
|
||||
using pos_t = double;
|
||||
using vd_t = boost::polygon::voronoi_diagram<pos_t>;
|
||||
using graph_t = SkeletalTrapezoidationGraph;
|
||||
using edge_t = STHalfEdge;
|
||||
using node_t = STHalfEdgeNode;
|
||||
@@ -83,7 +81,6 @@ class SkeletalTrapezoidation
|
||||
|
||||
public:
|
||||
using Segment = PolygonsSegmentIndex;
|
||||
using PointMap = ankerl::unordered_dense::map<Point, Point, PointHash>;
|
||||
using NodeSet = ankerl::unordered_dense::set<node_t*>;
|
||||
|
||||
/*!
|
||||
@@ -168,9 +165,9 @@ protected:
|
||||
* mapping each voronoi VD edge to the corresponding halfedge HE edge
|
||||
* In case the result segment is discretized, we map the VD edge to the *last* HE edge
|
||||
*/
|
||||
ankerl::unordered_dense::map<vd_t::edge_type*, edge_t*> vd_edge_to_he_edge;
|
||||
ankerl::unordered_dense::map<vd_t::vertex_type*, node_t*> vd_node_to_he_node;
|
||||
node_t& makeNode(vd_t::vertex_type& vd_node, Point p); //!< Get the node which the VD node maps to, or create a new mapping if there wasn't any yet.
|
||||
ankerl::unordered_dense::map<const VD::edge_type *, edge_t *> vd_edge_to_he_edge;
|
||||
ankerl::unordered_dense::map<const VD::vertex_type *, node_t *> vd_node_to_he_node;
|
||||
node_t &makeNode(const VD::vertex_type &vd_node, Point p); //!< Get the node which the VD node maps to, or create a new mapping if there wasn't any yet.
|
||||
|
||||
/*!
|
||||
* (Eventual) returned 'polylines per index' result (from generateToolpaths):
|
||||
@@ -181,7 +178,7 @@ protected:
|
||||
* Transfer an edge from the VD to the HE and perform discretization of parabolic edges (and vertex-vertex edges)
|
||||
* \p prev_edge serves as input and output. May be null as input.
|
||||
*/
|
||||
void transferEdge(Point from, Point to, vd_t::edge_type& vd_edge, edge_t*& prev_edge, Point& start_source_point, Point& end_source_point, const std::vector<Segment>& segments);
|
||||
void transferEdge(Point from, Point to, const VD::edge_type &vd_edge, edge_t *&prev_edge, Point &start_source_point, Point &end_source_point, const std::vector<Segment> &segments);
|
||||
|
||||
/*!
|
||||
* Discretize a Voronoi edge that represents the medial axis of a vertex-
|
||||
@@ -208,7 +205,7 @@ protected:
|
||||
* \return A number of coordinates along the edge where the edge is broken
|
||||
* up into discrete pieces.
|
||||
*/
|
||||
Points discretize(const vd_t::edge_type& segment, const std::vector<Segment>& segments);
|
||||
Points discretize(const VD::edge_type& segment, const std::vector<Segment>& segments);
|
||||
|
||||
/*!
|
||||
* Compute the range of line segments that surround a cell of the skeletal
|
||||
@@ -234,33 +231,7 @@ protected:
|
||||
* /return Whether the cell is inside of the polygon. If it's outside of the
|
||||
* polygon we should skip processing it altogether.
|
||||
*/
|
||||
static bool computePointCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector<Segment>& segments);
|
||||
|
||||
/*!
|
||||
* Compute the range of line segments that surround a cell of the skeletal
|
||||
* graph that belongs to a line segment of the medial axis.
|
||||
*
|
||||
* This should only be used on cells that belong to a central line segment
|
||||
* of the skeletal graph, e.g. trapezoid cells, not triangular cells.
|
||||
*
|
||||
* The resulting line segments is just the first and the last segment. They
|
||||
* are linked to the neighboring segments, so you can iterate over the
|
||||
* segments until you reach the last segment.
|
||||
* \param cell The cell to compute the range of line segments for.
|
||||
* \param[out] start_source_point The start point of the source segment of
|
||||
* this cell.
|
||||
* \param[out] end_source_point The end point of the source segment of this
|
||||
* cell.
|
||||
* \param[out] starting_vd_edge The edge of the Voronoi diagram where the
|
||||
* loop around the cell starts.
|
||||
* \param[out] ending_vd_edge The edge of the Voronoi diagram where the loop
|
||||
* around the cell ends.
|
||||
* \param points All vertices of the input Polygons.
|
||||
* \param segments All edges of the input Polygons.
|
||||
* /return Whether the cell is inside of the polygon. If it's outside of the
|
||||
* polygon we should skip processing it altogether.
|
||||
*/
|
||||
static void computeSegmentCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector<Segment>& segments);
|
||||
static bool computePointCellRange(const VD::cell_type &cell, Point &start_source_point, Point &end_source_point, const VD::edge_type *&starting_vd_edge, const VD::edge_type *&ending_vd_edge, const std::vector<Segment> &segments);
|
||||
|
||||
/*!
|
||||
* For VD cells associated with an input polygon vertex, we need to separate the node at the end and start of the cell into two
|
||||
@@ -603,7 +574,7 @@ protected:
|
||||
*/
|
||||
void generateLocalMaximaSingleBeads();
|
||||
|
||||
friend bool detect_voronoi_edge_intersecting_input_segment(const Geometry::VoronoiDiagram &voronoi_diagram, const std::vector<VoronoiUtils::Segment> &segments);
|
||||
friend bool detect_voronoi_edge_intersecting_input_segment(const VD &voronoi_diagram, const std::vector<Segment> &segments);
|
||||
};
|
||||
|
||||
} // namespace Slic3r::Arachne
|
||||
|
||||
@@ -156,7 +156,6 @@ struct PathsPointIndexLocator
|
||||
}
|
||||
};
|
||||
|
||||
using PolygonsPointIndexLocator = PathsPointIndexLocator<Polygons>;
|
||||
|
||||
}//namespace Slic3r::Arachne
|
||||
|
||||
|
||||
@@ -27,5 +27,24 @@ public:
|
||||
|
||||
} // namespace Slic3r::Arachne
|
||||
|
||||
namespace boost::polygon {
|
||||
|
||||
template<> struct geometry_concept<Slic3r::Arachne::PolygonsSegmentIndex>
|
||||
{
|
||||
typedef segment_concept type;
|
||||
};
|
||||
|
||||
template<> struct segment_traits<Slic3r::Arachne::PolygonsSegmentIndex>
|
||||
{
|
||||
typedef coord_t coordinate_type;
|
||||
typedef Slic3r::Point point_type;
|
||||
|
||||
static inline point_type get(const Slic3r::Arachne::PolygonsSegmentIndex &CSegment, direction_1d dir)
|
||||
{
|
||||
return dir.to_int() ? CSegment.to() : CSegment.from();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost::polygon
|
||||
|
||||
#endif//UTILS_POLYGONS_SEGMENT_INDEX_H
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
//Copyright (c) 2021 Ultimaker B.V.
|
||||
//CuraEngine is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
#include <stack>
|
||||
#include <optional>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "linearAlg2D.hpp"
|
||||
#include "VoronoiUtils.hpp"
|
||||
|
||||
namespace Slic3r::Arachne
|
||||
{
|
||||
|
||||
Vec2i64 VoronoiUtils::p(const vd_t::vertex_type *node)
|
||||
{
|
||||
const double x = node->x();
|
||||
const double y = node->y();
|
||||
assert(std::isfinite(x) && std::isfinite(y));
|
||||
assert(x <= double(std::numeric_limits<int64_t>::max()) && x >= std::numeric_limits<int64_t>::lowest());
|
||||
assert(y <= double(std::numeric_limits<int64_t>::max()) && y >= std::numeric_limits<int64_t>::lowest());
|
||||
return {int64_t(x + 0.5 - (x < 0)), int64_t(y + 0.5 - (y < 0))}; // Round to the nearest integer coordinates.
|
||||
}
|
||||
|
||||
Point VoronoiUtils::getSourcePoint(const vd_t::cell_type& cell, const std::vector<Segment>& segments)
|
||||
{
|
||||
assert(cell.contains_point());
|
||||
if(!cell.contains_point())
|
||||
BOOST_LOG_TRIVIAL(debug) << "Voronoi cell doesn't contain a source point!";
|
||||
|
||||
switch (cell.source_category()) {
|
||||
case boost::polygon::SOURCE_CATEGORY_SINGLE_POINT:
|
||||
assert(false && "Voronoi diagram is always constructed using segments, so cell.source_category() shouldn't be SOURCE_CATEGORY_SINGLE_POINT!\n");
|
||||
BOOST_LOG_TRIVIAL(error) << "Voronoi diagram is always constructed using segments, so cell.source_category() shouldn't be SOURCE_CATEGORY_SINGLE_POINT!";
|
||||
break;
|
||||
case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT:
|
||||
assert(cell.source_index() < segments.size());
|
||||
return segments[cell.source_index()].to();
|
||||
break;
|
||||
case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT:
|
||||
assert(cell.source_index() < segments.size());
|
||||
return segments[cell.source_index()].from();
|
||||
break;
|
||||
default:
|
||||
assert(false && "getSourcePoint should only be called on point cells!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
assert(false && "cell.source_category() is equal to an invalid value!\n");
|
||||
BOOST_LOG_TRIVIAL(error) << "cell.source_category() is equal to an invalid value!";
|
||||
return {};
|
||||
}
|
||||
|
||||
PolygonsPointIndex VoronoiUtils::getSourcePointIndex(const vd_t::cell_type& cell, const std::vector<Segment>& segments)
|
||||
{
|
||||
assert(cell.contains_point());
|
||||
if(!cell.contains_point())
|
||||
BOOST_LOG_TRIVIAL(debug) << "Voronoi cell doesn't contain a source point!";
|
||||
|
||||
assert(cell.source_category() != boost::polygon::SOURCE_CATEGORY_SINGLE_POINT);
|
||||
switch (cell.source_category()) {
|
||||
case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT: {
|
||||
assert(cell.source_index() < segments.size());
|
||||
PolygonsPointIndex ret = segments[cell.source_index()];
|
||||
++ret;
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT: {
|
||||
assert(cell.source_index() < segments.size());
|
||||
return segments[cell.source_index()];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false && "getSourcePoint should only be called on point cells!\n");
|
||||
break;
|
||||
}
|
||||
PolygonsPointIndex ret = segments[cell.source_index()];
|
||||
return ++ret;
|
||||
}
|
||||
|
||||
const VoronoiUtils::Segment &VoronoiUtils::getSourceSegment(const vd_t::cell_type &cell, const std::vector<Segment> &segments)
|
||||
{
|
||||
assert(cell.contains_segment());
|
||||
if (!cell.contains_segment())
|
||||
BOOST_LOG_TRIVIAL(debug) << "Voronoi cell doesn't contain a source segment!";
|
||||
|
||||
return segments[cell.source_index()];
|
||||
}
|
||||
|
||||
class PointMatrix
|
||||
{
|
||||
public:
|
||||
double matrix[4];
|
||||
|
||||
PointMatrix()
|
||||
{
|
||||
matrix[0] = 1;
|
||||
matrix[1] = 0;
|
||||
matrix[2] = 0;
|
||||
matrix[3] = 1;
|
||||
}
|
||||
|
||||
PointMatrix(double rotation)
|
||||
{
|
||||
rotation = rotation / 180 * M_PI;
|
||||
matrix[0] = cos(rotation);
|
||||
matrix[1] = -sin(rotation);
|
||||
matrix[2] = -matrix[1];
|
||||
matrix[3] = matrix[0];
|
||||
}
|
||||
|
||||
PointMatrix(const Point p)
|
||||
{
|
||||
matrix[0] = p.x();
|
||||
matrix[1] = p.y();
|
||||
double f = sqrt((matrix[0] * matrix[0]) + (matrix[1] * matrix[1]));
|
||||
matrix[0] /= f;
|
||||
matrix[1] /= f;
|
||||
matrix[2] = -matrix[1];
|
||||
matrix[3] = matrix[0];
|
||||
}
|
||||
|
||||
static PointMatrix scale(double s)
|
||||
{
|
||||
PointMatrix ret;
|
||||
ret.matrix[0] = s;
|
||||
ret.matrix[3] = s;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Point apply(const Point p) const
|
||||
{
|
||||
return Point(coord_t(p.x() * matrix[0] + p.y() * matrix[1]), coord_t(p.x() * matrix[2] + p.y() * matrix[3]));
|
||||
}
|
||||
|
||||
Point unapply(const Point p) const
|
||||
{
|
||||
return Point(coord_t(p.x() * matrix[0] + p.y() * matrix[2]), coord_t(p.x() * matrix[1] + p.y() * matrix[3]));
|
||||
}
|
||||
};
|
||||
Points VoronoiUtils::discretizeParabola(const Point& p, const Segment& segment, Point s, Point e, coord_t approximate_step_size, float transitioning_angle)
|
||||
{
|
||||
Points discretized;
|
||||
// x is distance of point projected on the segment ab
|
||||
// xx is point projected on the segment ab
|
||||
const Point a = segment.from();
|
||||
const Point b = segment.to();
|
||||
const Point ab = b - a;
|
||||
const Point as = s - a;
|
||||
const Point ae = e - a;
|
||||
const coord_t ab_size = ab.cast<int64_t>().norm();
|
||||
const coord_t sx = as.cast<int64_t>().dot(ab.cast<int64_t>()) / ab_size;
|
||||
const coord_t ex = ae.cast<int64_t>().dot(ab.cast<int64_t>()) / ab_size;
|
||||
const coord_t sxex = ex - sx;
|
||||
|
||||
assert((as.cast<int64_t>().dot(ab.cast<int64_t>()) / int64_t(ab_size)) <= std::numeric_limits<coord_t>::max());
|
||||
assert((ae.cast<int64_t>().dot(ab.cast<int64_t>()) / int64_t(ab_size)) <= std::numeric_limits<coord_t>::max());
|
||||
|
||||
const Point ap = p - a;
|
||||
const coord_t px = ap.cast<int64_t>().dot(ab.cast<int64_t>()) / ab_size;
|
||||
|
||||
assert((ap.cast<int64_t>().dot(ab.cast<int64_t>()) / int64_t(ab_size)) <= std::numeric_limits<coord_t>::max());
|
||||
|
||||
Point pxx;
|
||||
Line(a, b).distance_to_infinite_squared(p, &pxx);
|
||||
const Point ppxx = pxx - p;
|
||||
const coord_t d = ppxx.cast<int64_t>().norm();
|
||||
const PointMatrix rot = PointMatrix(perp(ppxx));
|
||||
|
||||
if (d == 0)
|
||||
{
|
||||
discretized.emplace_back(s);
|
||||
discretized.emplace_back(e);
|
||||
return discretized;
|
||||
}
|
||||
|
||||
const float marking_bound = atan(transitioning_angle * 0.5);
|
||||
int64_t msx = - marking_bound * int64_t(d); // projected marking_start
|
||||
int64_t mex = marking_bound * int64_t(d); // projected marking_end
|
||||
|
||||
assert(msx <= std::numeric_limits<coord_t>::max());
|
||||
assert(double(msx) * double(msx) <= double(std::numeric_limits<int64_t>::max()));
|
||||
assert(mex <= std::numeric_limits<coord_t>::max());
|
||||
assert(double(msx) * double(msx) / double(2 * d) + double(d / 2) <= std::numeric_limits<coord_t>::max());
|
||||
|
||||
const coord_t marking_start_end_h = msx * msx / (2 * d) + d / 2;
|
||||
Point marking_start = rot.unapply(Point(coord_t(msx), marking_start_end_h)) + pxx;
|
||||
Point marking_end = rot.unapply(Point(coord_t(mex), marking_start_end_h)) + pxx;
|
||||
const int dir = (sx > ex) ? -1 : 1;
|
||||
if (dir < 0)
|
||||
{
|
||||
std::swap(marking_start, marking_end);
|
||||
std::swap(msx, mex);
|
||||
}
|
||||
|
||||
bool add_marking_start = msx * int64_t(dir) > int64_t(sx - px) * int64_t(dir) && msx * int64_t(dir) < int64_t(ex - px) * int64_t(dir);
|
||||
bool add_marking_end = mex * int64_t(dir) > int64_t(sx - px) * int64_t(dir) && mex * int64_t(dir) < int64_t(ex - px) * int64_t(dir);
|
||||
|
||||
const Point apex = rot.unapply(Point(0, d / 2)) + pxx;
|
||||
bool add_apex = int64_t(sx - px) * int64_t(dir) < 0 && int64_t(ex - px) * int64_t(dir) > 0;
|
||||
|
||||
assert(!(add_marking_start && add_marking_end) || add_apex);
|
||||
if(add_marking_start && add_marking_end && !add_apex)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(warning) << "Failing to discretize parabola! Must add an apex or one of the endpoints.";
|
||||
}
|
||||
|
||||
const coord_t step_count = static_cast<coord_t>(static_cast<float>(std::abs(ex - sx)) / approximate_step_size + 0.5);
|
||||
|
||||
discretized.emplace_back(s);
|
||||
for (coord_t step = 1; step < step_count; step++)
|
||||
{
|
||||
assert(double(sxex) * double(step) <= double(std::numeric_limits<int64_t>::max()));
|
||||
const int64_t x = int64_t(sx) + int64_t(sxex) * int64_t(step) / int64_t(step_count) - int64_t(px);
|
||||
assert(double(x) * double(x) <= double(std::numeric_limits<int64_t>::max()));
|
||||
assert(double(x) * double(x) / double(2 * d) + double(d / 2) <= double(std::numeric_limits<int64_t>::max()));
|
||||
const int64_t y = int64_t(x) * int64_t(x) / int64_t(2 * d) + int64_t(d / 2);
|
||||
|
||||
if (add_marking_start && msx * int64_t(dir) < int64_t(x) * int64_t(dir))
|
||||
{
|
||||
discretized.emplace_back(marking_start);
|
||||
add_marking_start = false;
|
||||
}
|
||||
if (add_apex && int64_t(x) * int64_t(dir) > 0)
|
||||
{
|
||||
discretized.emplace_back(apex);
|
||||
add_apex = false; // only add the apex just before the
|
||||
}
|
||||
if (add_marking_end && mex * int64_t(dir) < int64_t(x) * int64_t(dir))
|
||||
{
|
||||
discretized.emplace_back(marking_end);
|
||||
add_marking_end = false;
|
||||
}
|
||||
assert(x <= std::numeric_limits<coord_t>::max() && x >= std::numeric_limits<coord_t>::lowest());
|
||||
assert(y <= std::numeric_limits<coord_t>::max() && y >= std::numeric_limits<coord_t>::lowest());
|
||||
const Point result = rot.unapply(Point(x, y)) + pxx;
|
||||
discretized.emplace_back(result);
|
||||
}
|
||||
if (add_apex)
|
||||
{
|
||||
discretized.emplace_back(apex);
|
||||
}
|
||||
if (add_marking_end)
|
||||
{
|
||||
discretized.emplace_back(marking_end);
|
||||
}
|
||||
discretized.emplace_back(e);
|
||||
return discretized;
|
||||
}
|
||||
|
||||
}//namespace Slic3r::Arachne
|
||||
@@ -1,47 +0,0 @@
|
||||
//Copyright (c) 2020 Ultimaker B.V.
|
||||
//CuraEngine is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
|
||||
#ifndef UTILS_VORONOI_UTILS_H
|
||||
#define UTILS_VORONOI_UTILS_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include <boost/polygon/voronoi.hpp>
|
||||
|
||||
#include "PolygonsSegmentIndex.hpp"
|
||||
|
||||
namespace Slic3r::Arachne
|
||||
{
|
||||
|
||||
/*!
|
||||
*/
|
||||
class VoronoiUtils
|
||||
{
|
||||
public:
|
||||
using Segment = PolygonsSegmentIndex;
|
||||
using voronoi_data_t = double;
|
||||
using vd_t = boost::polygon::voronoi_diagram<voronoi_data_t>;
|
||||
|
||||
static Point getSourcePoint(const vd_t::cell_type &cell, const std::vector<Segment> &segments);
|
||||
static const Segment &getSourceSegment(const vd_t::cell_type &cell, const std::vector<Segment> &segments);
|
||||
static PolygonsPointIndex getSourcePointIndex(const vd_t::cell_type &cell, const std::vector<Segment> &segments);
|
||||
|
||||
static Vec2i64 p(const vd_t::vertex_type *node);
|
||||
|
||||
/*!
|
||||
* Discretize a parabola based on (approximate) step size.
|
||||
* The \p approximate_step_size is measured parallel to the \p source_segment, not along the parabola.
|
||||
*/
|
||||
static Points discretizeParabola(const Point &source_point, const Segment &source_segment, Point start, Point end, coord_t approximate_step_size, float transitioning_angle);
|
||||
|
||||
static inline bool is_finite(const VoronoiUtils::vd_t::vertex_type &vertex)
|
||||
{
|
||||
return std::isfinite(vertex.x()) && std::isfinite(vertex.y());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Slic3r::Arachne
|
||||
|
||||
#endif // UTILS_VORONOI_UTILS_H
|
||||