Merge remote-tracking branch 'remotes/prusa/et_custom_bed'

sorry, forgot to commit it before doing changes.
so there are also the bug fix for #76 and #74
This commit is contained in:
supermerill 2019-07-03 20:47:31 +02:00
commit 6b20a930eb
71 changed files with 1355 additions and 801 deletions

9
deps/CMakeLists.txt vendored
View File

@ -36,10 +36,11 @@ set(DESTDIR "${CMAKE_CURRENT_BINARY_DIR}/destdir" CACHE PATH "Destination direct
option(DEP_DEBUG "Build debug variants (only applicable on Windows)" ON)
option(DEP_WX_STABLE "Build against wxWidgets stable 3.0 as opposed to default 3.1 (Linux only)" OFF)
# IGL static library in release mode produces 50MB binary. On the build server, it should be
# disabled and used in header-only mode. On developer machines, it can be enabled to speed
# up conpilation and suppress warnings coming from IGL.
option(DEP_BUILD_IGL_STATIC "Build IGL as a static library. Might cause link errors and increase binary size." OFF)
# On developer machines, it can be enabled to speed up compilation and suppress warnings coming from IGL.
# FIXME:
# Enabling this option is not safe. IGL will compile itself with its own version of Eigen while
# Slic3r compiles with a different version which will cause runtime errors.
# option(DEP_BUILD_IGL_STATIC "Build IGL as a static library. Might cause link errors and increase binary size." OFF)
message(STATUS "Slic3r deps DESTDIR: ${DESTDIR}")
message(STATUS "Slic3r deps debug build: ${DEP_DEBUG}")

View File

@ -54,7 +54,7 @@ ExternalProject_Add(dep_libigl
-DLIBIGL_BUILD_PYTHON=OFF
-DLIBIGL_BUILD_TESTS=OFF
-DLIBIGL_BUILD_TUTORIALS=OFF
-DLIBIGL_USE_STATIC_LIBRARY=${DEP_BUILD_IGL_STATIC}
-DLIBIGL_USE_STATIC_LIBRARY=OFF #${DEP_BUILD_IGL_STATIC}
-DLIBIGL_WITHOUT_COPYLEFT=OFF
-DLIBIGL_WITH_CGAL=OFF
-DLIBIGL_WITH_COMISO=OFF

View File

@ -273,7 +273,7 @@ ExternalProject_Add(dep_libigl
-DLIBIGL_BUILD_PYTHON=OFF
-DLIBIGL_BUILD_TESTS=OFF
-DLIBIGL_BUILD_TUTORIALS=OFF
-DLIBIGL_USE_STATIC_LIBRARY=${DEP_BUILD_IGL_STATIC}
-DLIBIGL_USE_STATIC_LIBRARY=OFF #${DEP_BUILD_IGL_STATIC}
-DLIBIGL_WITHOUT_COPYLEFT=OFF
-DLIBIGL_WITH_CGAL=OFF
-DLIBIGL_WITH_COMISO=OFF

View File

@ -579,7 +579,7 @@ void CLI::print_help(bool include_print_options, PrinterTechnology printer_techn
#endif /* SLIC3R_GUI */
<< std::endl
<< "https://github.com/supermerill/slic3r" << std::endl << std::endl
<< "Usage: slic3r [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ file.stl ... ]" << std::endl
<< "Usage: prusa-slicer [ ACTIONS ] [ TRANSFORM ] [ OPTIONS ] [ file.stl ... ]" << std::endl
<< std::endl
<< "Actions:" << std::endl;
cli_actions_config_def.print_cli_help(boost::nowide::cout, false);

View File

@ -41,6 +41,7 @@
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
unsigned char buf[32];
(void)p;
/* Signature byte reads are always 3 bytes. */
@ -83,9 +84,9 @@ static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
static int prusa_init_external_flash(PROGRAMMER * pgm)
{
// Note: send/receive as in _the firmare_ send & receives
const char entry_magic_send [] = "start\n";
const char entry_magic_receive[] = "w25x20cl_enter\n";
const char entry_magic_cfm [] = "w25x20cl_cfm\n";
const char entry_magic_send[] = "start\n";
const unsigned char entry_magic_receive[] = "w25x20cl_enter\n";
const char entry_magic_cfm[] = "w25x20cl_cfm\n";
const size_t buffer_len = 32; // Should be large enough for the above messages
int res;
@ -94,7 +95,7 @@ static int prusa_init_external_flash(PROGRAMMER * pgm)
// 1. receive the "start" command
recv_size = sizeof(entry_magic_send) - 1;
res = serial_recv(&pgm->fd, buffer, recv_size);
res = serial_recv(&pgm->fd, (unsigned char *)buffer, recv_size);
if (res < 0) {
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
return -1;
@ -111,7 +112,7 @@ static int prusa_init_external_flash(PROGRAMMER * pgm)
// 3. Receive the entry confirmation command
recv_size = sizeof(entry_magic_cfm) - 1;
res = serial_recv(&pgm->fd, buffer, recv_size);
res = serial_recv(&pgm->fd, (unsigned char *)buffer, recv_size);
if (res < 0) {
avrdude_message(MSG_INFO, "%s: prusa_init_external_flash(): MK3 printer did not boot up on time or serial communication failed\n", progname);
return -1;
@ -142,7 +143,7 @@ static int arduino_open(PROGRAMMER * pgm, char * port)
// Sometimes there may be line noise generating input on the printer's USB-to-serial IC
// Here we try to clean its input buffer with a sequence of newlines (a minimum of 9 is needed):
const char cleanup_newlines[] = "\n\n\n\n\n\n\n\n\n\n";
const unsigned char cleanup_newlines[] = "\n\n\n\n\n\n\n\n\n\n";
if (serial_send(&pgm->fd, cleanup_newlines, sizeof(cleanup_newlines) - 1) < 0) {
return -1;
}

View File

@ -341,7 +341,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
avr_tpi_setup_rw(pgm, mem, 0, TPI_NVMCMD_NO_OPERATION);
/* load bytes */
for (lastaddr = i = 0; i < mem->size; i++) {
for (lastaddr = i = 0; i < (unsigned)mem->size; i++) {
RETURN_IF_CANCEL();
if (vmem == NULL ||
(vmem->tags[i] & TAG_ALLOCATED) != 0)
@ -374,7 +374,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
/* quickly scan number of pages to be written to first */
for (pageaddr = 0, npages = 0;
pageaddr < mem->size;
pageaddr < (unsigned)mem->size;
pageaddr += mem->page_size) {
/* check whether this page must be read */
for (i = pageaddr;
@ -391,7 +391,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
}
for (pageaddr = 0, failure = 0, nread = 0;
!failure && pageaddr < mem->size;
!failure && pageaddr < (unsigned)mem->size;
pageaddr += mem->page_size) {
RETURN_IF_CANCEL();
/* check whether this page must be read */
@ -437,7 +437,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
}
}
for (i=0; i < mem->size; i++) {
for (i = 0; i < (unsigned)mem->size; i++) {
RETURN_IF_CANCEL();
if (vmem == NULL ||
(vmem->tags[i] & TAG_ALLOCATED) != 0)
@ -634,18 +634,18 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
writeop = mem->op[AVR_OP_WRITE_HI];
else
writeop = mem->op[AVR_OP_WRITE_LO];
caddr = addr / 2;
caddr = (unsigned short)(addr / 2);
}
else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) {
if (addr & 0x01)
writeop = mem->op[AVR_OP_LOADPAGE_HI];
else
writeop = mem->op[AVR_OP_LOADPAGE_LO];
caddr = addr / 2;
caddr = (unsigned short)(addr / 2);
}
else {
writeop = mem->op[AVR_OP_WRITE];
caddr = addr;
caddr = (unsigned short)addr;
}
if (writeop == NULL) {
@ -723,7 +723,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
gettimeofday (&tv, NULL);
prog_time = (tv.tv_sec * 1000000) + tv.tv_usec;
} while ((r != data) &&
((prog_time-start_time) < mem->max_write_delay));
((prog_time - start_time) < (unsigned long)mem->max_write_delay));
}
/*
@ -878,7 +878,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
}
/* write words, low byte first */
for (lastaddr = i = 0; i < wsize; i += 2) {
for (lastaddr = i = 0; i < (unsigned)wsize; i += 2) {
RETURN_IF_CANCEL();
if ((m->tags[i] & TAG_ALLOCATED) != 0 ||
(m->tags[i + 1] & TAG_ALLOCATED) != 0) {
@ -915,7 +915,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
/* quickly scan number of pages to be written to first */
for (pageaddr = 0, npages = 0;
pageaddr < wsize;
pageaddr < (unsigned)wsize;
pageaddr += m->page_size) {
/* check whether this page must be written to */
for (i = pageaddr;
@ -928,7 +928,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
}
for (pageaddr = 0, failure = 0, nwritten = 0;
!failure && pageaddr < wsize;
!failure && pageaddr < (unsigned)wsize;
pageaddr += m->page_size) {
RETURN_IF_CANCEL();
/* check whether this page must be written to */
@ -968,7 +968,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
page_tainted = 0;
flush_page = 0;
for (i=0; i<wsize; i++) {
for (i = 0; i < (unsigned)wsize; i++) {
RETURN_IF_CANCEL();
data = m->buf[i];
report_progress(i, wsize, NULL);

View File

@ -676,7 +676,7 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
avr910_set_addr(pgm, addr / rd_size);
while (addr < max_addr) {
if ((max_addr - addr) < blocksize) {
if ((max_addr - addr) < (unsigned)blocksize) {
blocksize = max_addr - addr;
}
cmd[1] = (blocksize >> 8) & 0xff;

View File

@ -1,5 +1,5 @@
/* WARN: This file is auto-generated from `avrdude-slic3r.conf` */
unsigned char avrdude_slic3r_conf[] = {
const unsigned char avrdude_slic3r_conf[] = {
0x0a, 0x23, 0x0a, 0x23, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
0x20, 0x61, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x6d, 0x69, 0x6e,
0x69, 0x6d, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20,
@ -1184,5 +1184,5 @@ unsigned char avrdude_slic3r_conf[] = {
0x20, 0x20, 0x3b, 0x0a, 0x0a, 0x0a,
0, 0
};
size_t avrdude_slic3r_conf_size = 14178;
size_t avrdude_slic3r_conf_size_yy = 14180;
const size_t avrdude_slic3r_conf_size = 14178;
const size_t avrdude_slic3r_conf_size_yy = 14180;

View File

@ -93,7 +93,7 @@ void AvrDude::priv::unset_handlers()
int AvrDude::priv::run_one(const std::vector<std::string> &args) {
std::vector<char*> c_args {{ const_cast<char*>(PACKAGE) }};
std::vector<char*> c_args { const_cast<char*>(PACKAGE) };
std::string command_line { PACKAGE };
for (const auto &arg : args) {
@ -105,7 +105,7 @@ int AvrDude::priv::run_one(const std::vector<std::string> &args) {
HandlerGuard guard(*this);
message_fn(command_line.c_str(), command_line.size());
message_fn(command_line.c_str(), (unsigned)command_line.size());
const auto res = ::avrdude_main(static_cast<int>(c_args.size()), c_args.data());
@ -200,7 +200,7 @@ AvrDude::Ptr AvrDude::run()
auto &message_fn = self->p->message_fn;
if (message_fn) {
message_fn(msg, sizeof(msg));
message_fn(what, std::strlen(what));
message_fn(what, (unsigned)std::strlen(what));
message_fn("\n", 1);
}

View File

@ -64,6 +64,8 @@ int avrdude_main(int argc, char * argv []);
#include <windows.h>
#include <unistd.h>
#define strdup _strdup
#ifdef UNICODE
#error "UNICODE should not be defined for avrdude bits on Windows"
#endif

View File

@ -358,7 +358,7 @@ AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
int matches;
int l;
l = strlen(desc);
l = (int)strlen(desc);
matches = 0;
match = NULL;
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
@ -662,7 +662,7 @@ void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
prefix);
px = prefix;
i = strlen(prefix) + 5;
i = (int)strlen(prefix) + 5;
buf = (char *)malloc(i);
if (buf == NULL) {
/* ugh, this is not important enough to bail, just ignore it */

View File

@ -128,7 +128,7 @@ static int buspirate_recv_bin(struct programmer_t *pgm, unsigned char *buf, size
avrdude_message(MSG_DEBUG, "%s: buspirate_recv_bin():\n", progname);
dump_mem(MSG_DEBUG, buf, len);
return len;
return (int)len;
}
static int buspirate_expect_bin(struct programmer_t *pgm,
@ -249,7 +249,7 @@ static int buspirate_send(struct programmer_t *pgm, const char *str)
static int buspirate_is_prompt(const char *str)
{
int strlen_str = strlen(str);
int strlen_str = (int)strlen(str);
/* Prompt ends with '>' or '> '
* all other input probably ends with '\n' */
return (str[strlen_str - 1] == '>' || str[strlen_str - 2] == '>');

View File

@ -675,7 +675,7 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
butterfly_set_addr(pgm, addr / rd_size);
}
while (addr < max_addr) {
if ((max_addr - addr) < blocksize) {
if ((max_addr - addr) < (unsigned)blocksize) {
blocksize = max_addr - addr;
};
cmd[1] = (blocksize >> 8) & 0xff;

View File

@ -21,7 +21,7 @@ int main(int argc, char const *argv[])
}
std::cout << "/* WARN: This file is auto-generated from `" << filename << "` */" << std::endl;
std::cout << "unsigned char " << symbol << "[] = {";
std::cout << "const unsigned char " << symbol << "[] = {";
char c;
std::cout << std::hex;
@ -34,8 +34,8 @@ int main(int argc, char const *argv[])
std::cout << "\n 0, 0\n};\n";
std::cout << std::dec;
std::cout << "size_t " << symbol << "_size = " << size << ";" << std::endl;
std::cout << "size_t " << symbol << "_size_yy = " << size + 2 << ";" << std::endl;
std::cout << "const size_t " << symbol << "_size = " << size << ";" << std::endl;
std::cout << "const size_t " << symbol << "_size_yy = " << size + 2 << ";" << std::endl;
return 0;
}

View File

@ -240,7 +240,7 @@ TOKEN * string(char * text)
return NULL; /* yyerror already called */
}
len = strlen(text);
len = (int)strlen(text);
tkn->value.type = V_STR;
tkn->value.string = (char *) malloc(len+1);
@ -351,7 +351,7 @@ int read_config(const char * file)
}
typedef struct yy_buffer_state *YY_BUFFER_STATE;
extern YY_BUFFER_STATE yy_scan_bytes(char *base, size_t size);
extern YY_BUFFER_STATE yy_scan_bytes(const char *base, size_t size);
extern void yy_delete_buffer(YY_BUFFER_STATE b);
int read_config_builtin()
@ -363,7 +363,7 @@ int read_config_builtin()
// Note: Can't use yy_scan_buffer, it's buggy (?), leads to fread from a null FILE*
// and so unfortunatelly we have to use the copying variant here
YY_BUFFER_STATE buffer = yy_scan_bytes(avrdude_slic3r_conf, avrdude_slic3r_conf_size);
YY_BUFFER_STATE buffer = yy_scan_bytes((const char *)avrdude_slic3r_conf, avrdude_slic3r_conf_size);
if (buffer == NULL) {
avrdude_message(MSG_INFO, "%s: read_config_builtin: Failed to initialize parsing buffer\n", progname);
return -1;

View File

@ -3640,7 +3640,7 @@ static int parse_cmdbits(OPCODE * op)
break;
}
len = strlen(s);
len = (int)strlen(s);
if (len == 0) {
yyerror("invalid bit specifier \"\"");

View File

@ -1493,7 +1493,7 @@ static int parse_cmdbits(OPCODE * op)
break;
}
len = strlen(s);
len = (int)strlen(s);
if (len == 0) {
yyerror("invalid bit specifier \"\"");

View File

@ -264,7 +264,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
unsigned char cksum;
int rc;
len = strlen(rec);
len = (int)strlen(rec);
offset = 1;
cksum = 0;
@ -274,7 +274,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
for (i=0; i<2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
ihex->reclen = strtoul(buf, &e, 16);
ihex->reclen = (unsigned char)strtoul(buf, &e, 16);
if (e == buf || *e != 0)
return -1;
@ -294,7 +294,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
for (i=0; i<2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
ihex->rectyp = strtoul(buf, &e, 16);
ihex->rectyp = (unsigned char)strtoul(buf, &e, 16);
if (e == buf || *e != 0)
return -1;
@ -308,7 +308,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
for (i=0; i<2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
ihex->data[j] = strtoul(buf, &e, 16);
ihex->data[j] = (char)strtoul(buf, &e, 16);
if (e == buf || *e != 0)
return -1;
cksum += ihex->data[j];
@ -320,7 +320,7 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
for (i=0; i<2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
ihex->cksum = strtoul(buf, &e, 16);
ihex->cksum = (char)strtoul(buf, &e, 16);
if (e == buf || *e != 0)
return -1;
@ -361,7 +361,7 @@ static int ihex2b(char * infile, FILE * inf,
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
lineno++;
len = strlen(buffer);
len = (int)strlen(buffer);
if (buffer[len-1] == '\n')
buffer[--len] = 0;
if (buffer[0] != ':')
@ -388,7 +388,7 @@ static int ihex2b(char * infile, FILE * inf,
return -1;
}
nextaddr = ihex.loadofs + baseaddr - fileoffset;
if (nextaddr + ihex.reclen > bufsize) {
if (nextaddr + ihex.reclen > (unsigned)bufsize) {
avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range at line %d of %s\n",
progname, nextaddr+ihex.reclen, lineno, infile);
return -1;
@ -502,10 +502,11 @@ static int b2srec(unsigned char * inbuf, int bufsize,
cksum += n + addr_width + 1;
for (i=addr_width; i>0; i--)
for (i = addr_width; i>0; i--) {
cksum += (nextaddr >> (i-1) * 8) & 0xff;
}
for (i=nextaddr; i<nextaddr + n; i++) {
for (unsigned i = nextaddr; i < nextaddr + n; i++) {
fprintf(outf, "%02X", buf[i]);
cksum += buf[i];
}
@ -562,7 +563,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
unsigned char cksum;
int rc;
len = strlen(rec);
len = (int)strlen(rec);
offset = 1;
cksum = 0;
addr_width = 2;
@ -582,7 +583,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
for (i=0; i<2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
srec->reclen = strtoul(buf, &e, 16);
srec->reclen = (char)strtoul(buf, &e, 16);
cksum += srec->reclen;
srec->reclen -= (addr_width+1);
if (e == buf || *e != 0)
@ -594,7 +595,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
for (i=0; i<addr_width*2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
srec->loadofs = strtoull(buf, &e, 16);
srec->loadofs = strtoul(buf, &e, 16);
if (e == buf || *e != 0)
return -1;
@ -608,7 +609,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
for (i=0; i<2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
srec->data[j] = strtoul(buf, &e, 16);
srec->data[j] = (char)strtoul(buf, &e, 16);
if (e == buf || *e != 0)
return -1;
cksum += srec->data[j];
@ -620,7 +621,7 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
for (i=0; i<2; i++)
buf[i] = rec[offset++];
buf[i] = 0;
srec->cksum = strtoul(buf, &e, 16);
srec->cksum = (char)strtoul(buf, &e, 16);
if (e == buf || *e != 0)
return -1;
@ -650,7 +651,7 @@ static int srec2b(char * infile, FILE * inf,
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
lineno++;
len = strlen(buffer);
len = (int)strlen(buffer);
if (buffer[len-1] == '\n')
buffer[--len] = 0;
if (buffer[0] != 0x53)
@ -729,7 +730,7 @@ static int srec2b(char * infile, FILE * inf,
return -1;
}
nextaddr -= fileoffset;
if (nextaddr + srec.reclen > bufsize) {
if (nextaddr + srec.reclen > (unsigned)bufsize) {
avrdude_message(MSG_INFO, msg, progname, nextaddr+srec.reclen, "",
lineno, infile);
return -1;
@ -1143,12 +1144,12 @@ static int fileio_rbin(struct fioparms * fio,
switch (fio->op) {
case FIO_READ:
rc = fread(buf, 1, size, f);
rc = (int)fread(buf, 1, size, f);
if (rc > 0)
memset(mem->tags, TAG_ALLOCATED, rc);
break;
case FIO_WRITE:
rc = fwrite(buf, 1, size, f);
rc = (int)fwrite(buf, 1, size, f);
break;
default:
avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
@ -1190,7 +1191,7 @@ static int fileio_imm(struct fioparms * fio,
progname, p);
return -1;
}
mem->buf[loc] = b;
mem->buf[loc] = (char)b;
mem->tags[loc++] = TAG_ALLOCATED;
p = strtok(NULL, " ,");
rc = loc;
@ -1452,7 +1453,7 @@ static int fmt_autodetect(char * fname, unsigned section)
}
buf[MAX_LINE_LEN-1] = 0;
len = strlen((char *)buf);
len = (int)strlen((char *)buf);
if (buf[len-1] == '\n')
buf[--len] = 0;

View File

@ -444,7 +444,7 @@ lcreat ( void * liststruct, int elements )
l->poolsize = DEFAULT_POOLSIZE;
}
else {
l->poolsize = elements*sizeof(LISTNODE)+sizeof(NODEPOOL);
l->poolsize = (short)(elements*sizeof(LISTNODE)+sizeof(NODEPOOL));
}
l->n_ln_pool = (l->poolsize-sizeof(NODEPOOL))/sizeof(LISTNODE);
@ -803,7 +803,7 @@ lget_n ( LISTID lid, unsigned int n )
CKLMAGIC(l);
if ((n<1)||(n>lsize(l))) {
if ((n < 1) || (n > (unsigned)lsize(l))) {
return NULL;
}
@ -844,7 +844,7 @@ lget_ln ( LISTID lid, unsigned int n )
CKLMAGIC(l);
if ((n<1)||(n>lsize(l))) {
if ((n < 1) || (n > (unsigned)lsize(l))) {
return NULL;
}
@ -952,7 +952,7 @@ lins_n ( LISTID lid, void * data_ptr, unsigned int n )
CKLMAGIC(l);
if ((n<1)||(n>(l->num+1))) {
if ((n < 1) || (n > (unsigned)(l->num+1))) {
return -1;
}
@ -1193,7 +1193,7 @@ lrmv_n ( LISTID lid, unsigned int n )
CKLMAGIC(l);
if ((n<1)||(n>l->num)) {
if ((n < 1) || (n > (unsigned)l->num)) {
return NULL;
}

View File

@ -107,7 +107,7 @@ int avrdude_message(const int msglvl, const char *format, ...)
if (rc > 0 && rc < MSGBUFFER_SIZE) {
avrdude_message_handler(msgbuffer, rc, avrdude_message_handler_user_p);
} else {
avrdude_message_handler(format_error, strlen(format_error), avrdude_message_handler_user_p);
avrdude_message_handler(format_error, (unsigned)strlen(format_error), avrdude_message_handler_user_p);
}
}
@ -567,7 +567,7 @@ int avrdude_main(int argc, char * argv [])
// #endif
len = strlen(progname) + 2;
len = (int)strlen(progname) + 2;
for (i=0; i<len; i++)
progbuf[i] = ' ';
progbuf[i] = 0;
@ -601,7 +601,7 @@ int avrdude_main(int argc, char * argv [])
bitclock = strtod(optarg, &e);
if (*e != 0) {
/* trailing unit of measure present */
int suffixlen = strlen(e);
size_t suffixlen = strlen(e);
switch (suffixlen) {
case 2:
if ((e[0] != 'h' && e[0] != 'H') || e[1] != 'z')

View File

@ -217,7 +217,7 @@ const char * pinmask_to_str(const pinmask_t * const pinmask) {
* @param[in] size the number of entries in checklist
* @returns 0 if all pin definitions are valid, -1 otherwise
*/
int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, bool output) {
int pins_check(const struct programmer_t *const pgm, const struct pin_checklist_t *const checklist, const int size, const bool output) {
static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
int rv = 0; // return value
int pinname; // loop counter through pinnames

View File

@ -292,7 +292,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
if (hComPort == INVALID_HANDLE_VALUE) {
const char *error = last_error_string(0);
avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n", progname, port, error);
free(error);
free((char *)error);
return -1;
}
@ -460,10 +460,10 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
serial_w32SetTimeOut(hComPort,500);
if (!WriteFile(hComPort, buf, buflen, &written, NULL)) {
if (!WriteFile(hComPort, buf, (DWORD)buflen, &written, NULL)) {
const char *error = last_error_string(0);
avrdude_message(MSG_INFO, "%s: ser_send(): write error: %s\n", progname, error);
free(error);
free((char *)error);
return -1;
}
@ -576,10 +576,10 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
serial_w32SetTimeOut(hComPort, serial_recv_timeout);
if (!ReadFile(hComPort, buf, buflen, &read, NULL)) {
if (!ReadFile(hComPort, buf, (DWORD)buflen, &read, NULL)) {
const char *error = last_error_string(0);
avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n", progname, error);
free(error);
free((char *)error);
return -1;
}
@ -642,7 +642,7 @@ static int ser_drain(union filedescriptor *fd, int display)
if (!readres) {
const char *error = last_error_string(0);
avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n", progname, error);
free(error);
free((char *)error);
return -1;
}

View File

@ -308,8 +308,8 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
progname, port);
return -1;
}
avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
progname, port, (int)hComPort);
avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle %p\n",
progname, port, (void *)hComPort);
pgm->fd.pfd = (void *)hComPort;
@ -326,8 +326,8 @@ static void serbb_close(PROGRAMMER *pgm)
pgm->setpin(pgm, PIN_AVR_RESET, 1);
CloseHandle (hComPort);
}
avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%x\n",
progname, (int)hComPort);
avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle %p\n",
progname, (void *)hComPort);
hComPort = INVALID_HANDLE_VALUE;
}

View File

@ -821,7 +821,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
break;
}
for (prusa3d_semicolon_workaround_round = 0; prusa3d_semicolon_workaround_round < (has_semicolon ? 2 : 1); ++ prusa3d_semicolon_workaround_round) {
for (prusa3d_semicolon_workaround_round = 0; prusa3d_semicolon_workaround_round < (has_semicolon ? 2u : 1u); prusa3d_semicolon_workaround_round++) {
/* build command block and avoid multiple send commands as it leads to a crash
of the silabs usb serial driver on mac os x */
i = 0;
@ -834,7 +834,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
buf[i++] = block_size & 0x0f;
buf[i++] = memtype;
if (has_semicolon) {
for (j = 0; j < block_size; ++i, ++ j) {
for (j = 0; j < (unsigned)block_size; ++i, ++ j) {
buf[i] = m->buf[addr + j];
if (buf[i] == ';')
buf[i] |= (prusa3d_semicolon_workaround_round ? 0xf0 : 0x0f);
@ -1088,7 +1088,7 @@ static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
min = 8.0 / STK500_XTAL;
max = 255 * min;
dur = v / min + 0.5;
dur = (int)(v / min + 0.5);
if (v < min) {
dur = 1;

View File

@ -130,58 +130,58 @@ struct jtagispentry
#define SZ_SPI_MULTI (USHRT_MAX - 1)
};
static const struct jtagispentry jtagispcmds[] = {
/* generic */
{ CMD_SET_PARAMETER, 2 },
{ CMD_GET_PARAMETER, 3 },
{ CMD_OSCCAL, 2 },
{ CMD_LOAD_ADDRESS, 2 },
/* ISP mode */
{ CMD_ENTER_PROGMODE_ISP, 2 },
{ CMD_LEAVE_PROGMODE_ISP, 2 },
{ CMD_CHIP_ERASE_ISP, 2 },
{ CMD_PROGRAM_FLASH_ISP, 2 },
{ CMD_READ_FLASH_ISP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_EEPROM_ISP, 2 },
{ CMD_READ_EEPROM_ISP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_FUSE_ISP, 3 },
{ CMD_READ_FUSE_ISP, 4 },
{ CMD_PROGRAM_LOCK_ISP, 3 },
{ CMD_READ_LOCK_ISP, 4 },
{ CMD_READ_SIGNATURE_ISP, 4 },
{ CMD_READ_OSCCAL_ISP, 4 },
{ CMD_SPI_MULTI, SZ_SPI_MULTI },
/* all HV modes */
{ CMD_SET_CONTROL_STACK, 2 },
/* HVSP mode */
{ CMD_ENTER_PROGMODE_HVSP, 2 },
{ CMD_LEAVE_PROGMODE_HVSP, 2 },
{ CMD_CHIP_ERASE_HVSP, 2 },
{ CMD_PROGRAM_FLASH_HVSP, 2 },
{ CMD_READ_FLASH_HVSP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_EEPROM_HVSP, 2 },
{ CMD_READ_EEPROM_HVSP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_FUSE_HVSP, 2 },
{ CMD_READ_FUSE_HVSP, 3 },
{ CMD_PROGRAM_LOCK_HVSP, 2 },
{ CMD_READ_LOCK_HVSP, 3 },
{ CMD_READ_SIGNATURE_HVSP, 3 },
{ CMD_READ_OSCCAL_HVSP, 3 },
/* PP mode */
{ CMD_ENTER_PROGMODE_PP, 2 },
{ CMD_LEAVE_PROGMODE_PP, 2 },
{ CMD_CHIP_ERASE_PP, 2 },
{ CMD_PROGRAM_FLASH_PP, 2 },
{ CMD_READ_FLASH_PP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_EEPROM_PP, 2 },
{ CMD_READ_EEPROM_PP, SZ_READ_FLASH_EE },
{ CMD_PROGRAM_FUSE_PP, 2 },
{ CMD_READ_FUSE_PP, 3 },
{ CMD_PROGRAM_LOCK_PP, 2 },
{ CMD_READ_LOCK_PP, 3 },
{ CMD_READ_SIGNATURE_PP, 3 },
{ CMD_READ_OSCCAL_PP, 3 },
};
// static const struct jtagispentry jtagispcmds[] = {
// /* generic */
// { CMD_SET_PARAMETER, 2 },
// { CMD_GET_PARAMETER, 3 },
// { CMD_OSCCAL, 2 },
// { CMD_LOAD_ADDRESS, 2 },
// /* ISP mode */
// { CMD_ENTER_PROGMODE_ISP, 2 },
// { CMD_LEAVE_PROGMODE_ISP, 2 },
// { CMD_CHIP_ERASE_ISP, 2 },
// { CMD_PROGRAM_FLASH_ISP, 2 },
// { CMD_READ_FLASH_ISP, SZ_READ_FLASH_EE },
// { CMD_PROGRAM_EEPROM_ISP, 2 },
// { CMD_READ_EEPROM_ISP, SZ_READ_FLASH_EE },
// { CMD_PROGRAM_FUSE_ISP, 3 },
// { CMD_READ_FUSE_ISP, 4 },
// { CMD_PROGRAM_LOCK_ISP, 3 },
// { CMD_READ_LOCK_ISP, 4 },
// { CMD_READ_SIGNATURE_ISP, 4 },
// { CMD_READ_OSCCAL_ISP, 4 },
// { CMD_SPI_MULTI, SZ_SPI_MULTI },
// /* all HV modes */
// { CMD_SET_CONTROL_STACK, 2 },
// /* HVSP mode */
// { CMD_ENTER_PROGMODE_HVSP, 2 },
// { CMD_LEAVE_PROGMODE_HVSP, 2 },
// { CMD_CHIP_ERASE_HVSP, 2 },
// { CMD_PROGRAM_FLASH_HVSP, 2 },
// { CMD_READ_FLASH_HVSP, SZ_READ_FLASH_EE },
// { CMD_PROGRAM_EEPROM_HVSP, 2 },
// { CMD_READ_EEPROM_HVSP, SZ_READ_FLASH_EE },
// { CMD_PROGRAM_FUSE_HVSP, 2 },
// { CMD_READ_FUSE_HVSP, 3 },
// { CMD_PROGRAM_LOCK_HVSP, 2 },
// { CMD_READ_LOCK_HVSP, 3 },
// { CMD_READ_SIGNATURE_HVSP, 3 },
// { CMD_READ_OSCCAL_HVSP, 3 },
// /* PP mode */
// { CMD_ENTER_PROGMODE_PP, 2 },
// { CMD_LEAVE_PROGMODE_PP, 2 },
// { CMD_CHIP_ERASE_PP, 2 },
// { CMD_PROGRAM_FLASH_PP, 2 },
// { CMD_READ_FLASH_PP, SZ_READ_FLASH_EE },
// { CMD_PROGRAM_EEPROM_PP, 2 },
// { CMD_READ_EEPROM_PP, SZ_READ_FLASH_EE },
// { CMD_PROGRAM_FUSE_PP, 2 },
// { CMD_READ_FUSE_PP, 3 },
// { CMD_PROGRAM_LOCK_PP, 2 },
// { CMD_READ_LOCK_PP, 3 },
// { CMD_READ_SIGNATURE_PP, 3 },
// { CMD_READ_OSCCAL_PP, 3 },
// };
/*
* From XML file:
@ -379,15 +379,15 @@ static void stk500v2_jtag3_teardown(PROGRAMMER * pgm)
}
static unsigned short
b2_to_u16(unsigned char *b)
{
unsigned short l;
l = b[0];
l += (unsigned)b[1] << 8;
// static unsigned short
// b2_to_u16(unsigned char *b)
// {
// unsigned short l;
// l = b[0];
// l += (unsigned)b[1] << 8;
return l;
}
// return l;
// }
static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
@ -399,16 +399,16 @@ static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
return 0;
}
static unsigned short get_jtagisp_return_size(unsigned char cmd)
{
int i;
// static unsigned short get_jtagisp_return_size(unsigned char cmd)
// {
// int i;
for (i = 0; i < sizeof jtagispcmds / sizeof jtagispcmds[0]; i++)
if (jtagispcmds[i].cmd == cmd)
return jtagispcmds[i].size;
// for (i = 0; i < sizeof jtagispcmds / sizeof jtagispcmds[0]; i++)
// if (jtagispcmds[i].cmd == cmd)
// return jtagispcmds[i].size;
return 0;
}
// return 0;
// }
/*
* Send the data as a JTAG ICE mkII encapsulated ISP packet.
@ -504,7 +504,7 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
buf[0] = MESSAGE_START;
buf[1] = PDATA(pgm)->command_sequence;
buf[2] = len / 256;
buf[2] = (char)(len / 256);
buf[3] = len % 256;
buf[4] = TOKEN;
memcpy(buf+5, data, len);
@ -1128,7 +1128,8 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char buf[16];
char msg[100]; /* see remarks above about size needed */
int rv, tries;
int rv;
// int tries;
PDATA(pgm)->lastpart = p;
@ -1143,7 +1144,7 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
/* Activate AVR-style (low active) RESET */
stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
tries = 0;
// tries = 0;
// retry:
buf[0] = CMD_ENTER_PROGMODE_ISP;
buf[1] = p->timeout;
@ -1882,7 +1883,7 @@ static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0)
return -1;
} else {
buf[1] = addr;
buf[1] = (char)addr;
}
avrdude_message(MSG_NOTICE2, "%s: stk500hv_read_byte(): Sending read memory command: ",
@ -2137,7 +2138,7 @@ static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0)
return -1;
} else {
buf[1] = addr;
buf[1] = (char)addr;
buf[2] = data;
if (mode == PPMODE) {
buf[3] = pulsewidth;
@ -2298,7 +2299,7 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
static int page = 0;
// static int page = 0;
unsigned int block_size, last_addr, addrshift, use_ext_addr;
unsigned int maxaddr = addr + n_bytes;
unsigned char commandbuf[10];
@ -2833,10 +2834,10 @@ static int stk500v2_set_fosc(PROGRAMMER * pgm, double v)
progname, v, unit, STK500V2_XTAL / 2e6);
fosc = STK500V2_XTAL / 2;
} else
fosc = (unsigned)v;
fosc = (int)v;
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
if (fosc >= STK500V2_XTAL / (256 * ps[idx] * 2)) {
if (fosc >= (int)(STK500V2_XTAL / (256 * ps[idx] * 2))) {
/* this prescaler value can handle our frequency */
prescale = idx + 1;
cmatch = (unsigned)(STK500V2_XTAL / (2 * fosc * ps[idx])) - 1;
@ -3065,8 +3066,8 @@ static int stk600_set_fosc(PROGRAMMER * pgm, double v)
{
unsigned int oct, dac;
oct = 1.443 * log(v / 1039.0);
dac = 2048 - (2078.0 * pow(2, (double)(10 + oct))) / v;
oct = (unsigned)(1.443 * log(v / 1039.0));
dac = (unsigned)(2048.0 - (2078.0 * pow(2, (double)(10 + oct))) / v);
return stk500v2_setparm2(pgm, PARAM2_CLOCK_CONF, (oct << 12) | (dac << 2));
}
@ -3075,7 +3076,7 @@ static int stk600_set_sck_period(PROGRAMMER * pgm, double v)
{
unsigned int sck;
sck = ceil((16e6 / (2 * 1.0 / v)) - 1);
sck = (unsigned)ceil((16e6 / (2 * 1.0 / v)) - 1);
if (sck >= 4096)
sck = 4095;
@ -3093,7 +3094,7 @@ static int stk500v2_jtag3_set_sck_period(PROGRAMMER * pgm, double v)
else if (v > 1E-3)
sck = 1;
else
sck = 1.0 / (1000.0 * v);
sck = (unsigned)(1.0 / (1000.0 * v));
value[0] = CMD_SET_SCK;
value[1] = sck & 0xff;
@ -3143,7 +3144,7 @@ static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned
static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
{
unsigned char current_value;
unsigned char current_value = 0;
int res;
res = stk500v2_getparm(pgm, parm, &current_value);
@ -3214,8 +3215,15 @@ static const char *stk600_get_cardname(const struct carddata *table,
static void stk500v2_display(PROGRAMMER * pgm, const char * p)
{
unsigned char maj, min, hdw, topcard, maj_s1, min_s1, maj_s2, min_s2;
unsigned int rev;
unsigned char maj = 0;
unsigned char min = 0;
unsigned char hdw = 0;
unsigned char topcard = 0;
unsigned char maj_s1 = 0;
unsigned char min_s1 = 0;
unsigned char maj_s2 = 0;
unsigned char min_s2 = 0;
unsigned int rev = 0;
const char *topcard_name, *pgmname;
switch (PDATA(pgm)->pgmtype) {
@ -3294,13 +3302,20 @@ f_to_kHz_MHz(double f, const char **unit)
static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
{
unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration =0; //XXX 0 is not correct, check caller
unsigned int sck_stk600, clock_conf, dac, oct, varef;
unsigned char vtarget_jtag[4];
unsigned char vtarget = 0;
unsigned char vadjust = 0;
unsigned char sck_duration = 0;
unsigned char osc_pscale = 0;
unsigned char osc_cmatch = 0;
unsigned varef = 0;
unsigned sck_stk600 = 0;
unsigned clock_conf = 0;
unsigned dac, oct;
// unsigned char vtarget_jtag[4];
int prescale;
double f;
const char *unit;
void *mycookie;
// void *mycookie;
if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) {
return;
@ -3963,10 +3978,10 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
b[0] = XPRG_CMD_WRITE_MEM;
b[1] = memcode;
b[2] = 0; /* pagemode: non-paged write */
b[3] = addr >> 24;
b[4] = addr >> 16;
b[5] = addr >> 8;
b[6] = addr;
b[3] = (char)(addr >> 24);
b[4] = (char)(addr >> 16);
b[5] = (char)(addr >> 8);
b[6] = (char)addr;
b[7] = 0;
b[8] = write_size;
b[9] = data;
@ -4011,10 +4026,10 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
addr += mem->offset;
b[0] = XPRG_CMD_READ_MEM;
b[2] = addr >> 24;
b[3] = addr >> 16;
b[4] = addr >> 8;
b[5] = addr;
b[2] = (char)(addr >> 24);
b[3] = (char)(addr >> 16);
b[4] = (char)(addr >> 8);
b[5] = (char)addr;
b[6] = 0;
b[7] = 1;
if (stk600_xprog_command(pgm, b, 8, 3) < 0) {

View File

@ -281,7 +281,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
maxsize = mem->size;
if (addr >= maxsize) {
if (addr >= (unsigned long)maxsize) {
if (argc == 2) {
/* wrap around */
addr = 0;
@ -294,7 +294,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
}
/* trim len if nessary to not read past the end of memory */
if ((addr + len) > maxsize)
if ((addr + len) > (unsigned long)maxsize)
len = maxsize - addr;
buf = malloc(len);
@ -303,7 +303,7 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
return -1;
}
for (i=0; i<len; i++) {
for (i = 0; i < (unsigned long)len; i++) {
rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
if (rc != 0) {
avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n",
@ -364,7 +364,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
return -1;
}
if (addr > maxsize) {
if (addr > (unsigned long)maxsize) {
avrdude_message(MSG_INFO, "%s (write): address 0x%05lx is out of range for %s memory\n",
progname, addr, memtype);
return -1;
@ -373,7 +373,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
/* number of bytes to write at the specified address */
len = argc - 3;
if ((addr + len) > maxsize) {
if ((addr + len) > (unsigned long)maxsize) {
avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
"range for %s memory\n",
progname, memtype);
@ -386,8 +386,8 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
return -1;
}
for (i=3; i<argc; i++) {
buf[i-3] = strtoul(argv[i], &e, 0);
for (i = 3; i < (unsigned long)argc; i++) {
buf[i-3] = (char)strtoul(argv[i], &e, 0);
if (*e || (e == argv[i])) {
avrdude_message(MSG_INFO, "%s (write): can't parse byte \"%s\"\n",
progname, argv[i]);
@ -397,7 +397,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
}
pgm->err_led(pgm, OFF);
for (werror=0, i=0; i<len; i++) {
for (werror = 0, i = 0; i < (unsigned long)len; i++) {
rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
if (rc) {
@ -462,7 +462,7 @@ static int cmd_send(PROGRAMMER * pgm, struct avrpart * p,
/* load command bytes */
for (i=1; i<argc; i++) {
cmd[i-1] = strtoul(argv[i], &e, 0);
cmd[i-1] = (char)strtoul(argv[i], &e, 0);
if (*e || (e == argv[i])) {
avrdude_message(MSG_INFO, "%s (send): can't parse byte \"%s\"\n",
progname, argv[i]);
@ -789,7 +789,7 @@ static int tokenize(char * s, char *** argv)
char * nbuf;
char ** av;
slen = strlen(s);
slen = (int)strlen(s);
/*
* initialize allow for 20 arguments, use realloc to grow this if
@ -812,7 +812,7 @@ static int tokenize(char * s, char *** argv)
nexttok(r, &q, &r);
strcpy(nbuf, q);
bufv[n] = nbuf;
len = strlen(q);
len = (int)strlen(q);
l += len + 1;
nbuf += len + 1;
nbuf[0] = 0;
@ -841,7 +841,7 @@ static int tokenize(char * s, char *** argv)
q = (char *)&av[n+1];
memcpy(q, buf, l);
for (i=0; i<n; i++) {
offset = bufv[i] - buf;
offset = (int)(bufv[i] - buf);
av[i] = q + offset;
}
av[i] = NULL;
@ -862,7 +862,7 @@ static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
int hold;
int len;
len = strlen(argv[0]);
len = (int)strlen(argv[0]);
hold = -1;
for (i=0; i<NCMDS; i++) {
if (strcasecmp(argv[0], cmd[i].name) == 0) {

View File

@ -10,5 +10,5 @@ if(libigl_FOUND)
target_link_libraries(libigl INTERFACE igl::core)
else()
message(STATUS "IGL NOT found, using bundled version...")
target_include_directories(libigl INTERFACE SYSTEM ${LIBDIR}/libigl)
target_include_directories(libigl SYSTEM BEFORE INTERFACE ${LIBDIR}/libigl)
endif()

View File

@ -10,10 +10,6 @@
#include "boost/multiprecision/integer.hpp"
#include "boost/rational.hpp"
//#include "../tools/Int128.hpp"
//#include "gte/Mathematics/GteMinimumAreaBox2.h"
//#include "../tools/libnfpglue.hpp"
//#include "../tools/nfp_svgnest_glue.hpp"
@ -183,7 +179,7 @@ TEST(GeometryAlgorithms, Distance) {
Segment seg(p1, p3);
// ASSERT_DOUBLE_EQ(pointlike::distance(p2, seg), 7.0710678118654755);
// ASSERT_DOUBLE_EQ(pointlike::distance(p2, seg), 7.0710678118654755);
auto result = pointlike::horizontalDistance(p2, seg);
@ -396,7 +392,7 @@ TEST(GeometryAlgorithms, ArrangeRectanglesLoose)
{
using namespace libnest2d;
// std::vector<Rectangle> rects = { {40, 40}, {10, 10}, {20, 20} };
// std::vector<Rectangle> rects = { {40, 40}, {10, 10}, {20, 20} };
std::vector<Rectangle> rects = {
{80, 80},
{60, 90},
@ -454,14 +450,14 @@ void exportSVG(std::vector<std::reference_wrapper<Item>>& result, const Bin& bin
std::string loc = "out";
static std::string svg_header =
R"raw(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
R"raw(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg height="500" width="500" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
)raw";
int i = idx;
auto r = result;
// for(auto r : result) {
// for(auto r : result) {
std::fstream out(loc + std::to_string(i) + ".svg", std::fstream::out);
if(out.is_open()) {
out << svg_header;
@ -487,8 +483,8 @@ R"raw(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
}
out.close();
// i++;
// }
// i++;
// }
}
}
@ -556,11 +552,12 @@ TEST(GeometryAlgorithms, NestTest) {
ASSERT_LE(result.size(), 2);
int partsum = std::accumulate(result.begin(),
size_t partsum = std::accumulate(result.begin(),
result.end(),
0,
[](int s,
const decltype(result)::value_type &bin) {
size_t(0),
[](size_t s,
const decltype(
result)::value_type &bin) {
return s += bin.size();
});
@ -728,7 +725,7 @@ std::vector<ItemPair> nfp_testdata = {
}
};
std::vector<ItemPair> nfp_concave_testdata = {
std::vector<ItemPair> nfp_concave_testdata = {
{ // ItemPair
{
{
@ -935,67 +932,39 @@ template<class T> struct BoostGCD {
};
using Unit = int64_t;
using Ratio = boost::rational<boost::multiprecision::int128_t>;// Rational<boost::multiprecision::int256_t>;
//double gteMinAreaBox(const PolygonImpl& p) {
// using GteCoord = ClipperLib::cInt;
// using GtePoint = gte::Vector2<GteCoord>;
// gte::MinimumAreaBox2<GteCoord, Ratio> mb;
// std::vector<GtePoint> points;
// points.reserve(p.Contour.size());
// for(auto& pt : p.Contour) points.emplace_back(GtePoint{GteCoord(pt.X), GteCoord(pt.Y)});
// mb(int(points.size()), points.data(), 0, nullptr, true);
// auto min_area = double(mb.GetArea());
// return min_area;
//}
using Ratio = boost::rational<boost::multiprecision::int128_t>;
}
TEST(RotatingCalipers, MinAreaBBCClk) {
// PolygonImpl poly({{-50, 30}, {-50, -50}, {50, -50}, {50, 50}, {-40, 50}});
// PolygonImpl poly({{-50, 0}, {50, 0}, {0, 100}});
auto u = [](ClipperLib::cInt n) { return n*1000000; };
PolygonImpl poly({ {u(0), u(0)}, {u(4), u(1)}, {u(2), u(4)}});
long double arearef = refMinAreaBox(poly);
long double area = minAreaBoundingBox<PolygonImpl, Unit, Ratio>(poly).area();
// double gtearea = gteMinAreaBox(poly);
ASSERT_LE(std::abs(area - arearef), 500e6 );
// ASSERT_LE(std::abs(gtearea - arearef), 500 );
// ASSERT_DOUBLE_EQ(gtearea, arearef);
}
TEST(RotatingCalipers, AllPrusaMinBB) {
size_t idx = 0;
// /size_t idx = 0;
long double err_epsilon = 500e6l;
for(ClipperLib::Path rinput : PRINTER_PART_POLYGONS) {
// ClipperLib::Path rinput = PRINTER_PART_POLYGONS[idx];
// rinput.pop_back();
// std::reverse(rinput.begin(), rinput.end());
// ClipperLib::Path rinput = PRINTER_PART_POLYGONS[idx];
// rinput.pop_back();
// std::reverse(rinput.begin(), rinput.end());
// PolygonImpl poly(removeCollinearPoints<PathImpl, PointImpl, Unit>(rinput, 1000000));
// PolygonImpl poly(removeCollinearPoints<PathImpl, PointImpl, Unit>(rinput, 1000000));
PolygonImpl poly(rinput);
long double arearef = refMinAreaBox(poly);
auto bb = minAreaBoundingBox<PathImpl, Unit, Ratio>(rinput);
long double area = cast<long double>(bb.area());
// double area = gteMinAreaBox(poly);
bool succ = std::abs(arearef - area) < err_epsilon;
std::cout << idx++ << " " << (succ? "ok" : "failed") << " ref: "
<< arearef << " actual: " << area << std::endl;
// std::cout << idx++ << " " << (succ? "ok" : "failed") << " ref: "
// << arearef << " actual: " << area << std::endl;
ASSERT_TRUE(succ);
}
@ -1006,15 +975,14 @@ TEST(RotatingCalipers, AllPrusaMinBB) {
PolygonImpl poly(removeCollinearPoints<PathImpl, PointImpl, Unit>(rinput, 1000000));
long double arearef = refMinAreaBox(poly);
auto bb = minAreaBoundingBox<PolygonImpl, Unit, Ratio>(poly);
long double area = cast<long double>(bb.area());
// double area = gteMinAreaBox(poly);
bool succ = std::abs(arearef - area) < err_epsilon;
std::cout << idx++ << " " << (succ? "ok" : "failed") << " ref: "
<< arearef << " actual: " << area << std::endl;
// std::cout << idx++ << " " << (succ? "ok" : "failed") << " ref: "
// << arearef << " actual: " << area << std::endl;
ASSERT_TRUE(succ);
}

View File

@ -760,18 +760,18 @@ bool DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra,
}
// Store the option value.
const bool existing = this->has(opt_key);
if (keys != nullptr && !existing) {
if (keys != nullptr && ! existing) {
// Save the order of detected keys.
keys->push_back(opt_key);
}
ConfigOption *opt_base = this->option(opt_key, true);
ConfigOptionVectorBase *opt_vector = opt_base->is_vector() ? static_cast<ConfigOptionVectorBase*>(opt_base) : nullptr;
if (opt_vector) {
if (! existing)
// remove the default values
opt_vector->clear();
// Vector values will be chained. Repeated use of a parameter will append the parameter or parameters
// to the end of the value.
if (!existing)
// remove the default values
opt_vector->deserialize("", true);
if (opt_base->type() == coBools)
static_cast<ConfigOptionBools*>(opt_base)->values.push_back(!no);
else

View File

@ -188,8 +188,10 @@ public:
// Set a single vector item from either a scalar option or the first value of a vector option.vector of ConfigOptions.
// This function is useful to split values from multiple extrder / filament settings into separate configurations.
virtual void set_at(const ConfigOption *rhs, size_t i, size_t j) = 0;
// Resize the vector of values, copy the newly added values from opt_default if provided.
virtual void resize(size_t n, const ConfigOption *opt_default = nullptr) = 0;
// Clear the values vector.
virtual void clear() = 0;
// Get size of this vector.
virtual size_t size() const = 0;
@ -298,6 +300,8 @@ public:
}
}
// Clear the values vector.
void clear() override { this->values.clear(); }
size_t size() const override { return this->values.size(); }
bool empty() const override { return this->values.empty(); }

View File

@ -721,8 +721,12 @@ void GCode::_do_export(Print &print, FILE *file)
this->m_ordered_objects.push_back(print_object);
unsigned int copy_id = 0;
for (const Point &pos : print_object->copies()) {
_write_format(file, "; object:{\"name\":\"%s\",\"id\":\"%s id:%d copy %d\",\"object_center\":[%f,%f,%f],\"boundingbox_center\":[%f,%f,%f],\"boundingbox_size\":[%f,%f,%f]}",
print_object->model_object()->name.substr(0, print_object->model_object()->name.find(".", 0)), print_object->model_object()->name, this->m_ordered_objects.size() - 1, copy_id,
std::string object_name = print_object->model_object()->name;
size_t pos_dot = object_name.find(".", 0);
if (pos_dot != std::string::npos && pos_dot > 0)
object_name = object_name.substr(0, pos_dot);
_write_format(file, "; object:{\"name\":\"%s\",\"id\":\"%s id:%d copy %d\",\"object_center\":[%f,%f,%f],\"boundingbox_center\":[%f,%f,%f],\"boundingbox_size\":[%f,%f,%f]}\n",
object_name.c_str(), print_object->model_object()->name.c_str(), this->m_ordered_objects.size() - 1, copy_id,
print_object->model_object()->bounding_box().center().x(), print_object->model_object()->bounding_box().center().y(), 0,
print_object->model_object()->bounding_box().center().x(), print_object->model_object()->bounding_box().center().y(), print_object->model_object()->bounding_box().center().z(),
print_object->model_object()->bounding_box().size().x(), print_object->model_object()->bounding_box().size().y(), print_object->model_object()->bounding_box().size().z()
@ -1422,7 +1426,9 @@ void GCode::process_layer(
m_colorprint_heights.erase(m_colorprint_heights.begin());
colorprint_change = true;
}
if (colorprint_change && print.extruders().size()==1)
// we should add or not colorprint_change in respect to nozzle_diameter count instead of really used extruders count
if (colorprint_change && print./*extruders()*/config().nozzle_diameter.size()==1)
gcode += "M600\n";
@ -1658,26 +1664,34 @@ void GCode::process_layer(
m_avoid_crossing_perimeters.use_external_mp = true;
for (const ExtrusionEntity *ee : print.brim().entities)
gcode += this->extrude_entity(*ee, "brim", m_config.support_material_speed.value);
m_brim_done = true;
m_avoid_crossing_perimeters.use_external_mp = false;
// Allow a straight travel move to the first object point.
m_avoid_crossing_perimeters.disable_once = true;
m_brim_done = true;
}
//extrude object-only skirt & brim & first extruder
//extrude object-only skirt
if (single_object_idx != size_t(-1) && !layers.front().object()->skirt().empty()
&& extruder_id == layer_tools.extruders.front()) {
const PrintObject *print_object = layers.front().object();
this->set_origin(unscale(print_object->copies()[single_object_idx]));
if (this->m_layer != nullptr && this->m_layer->id() < m_config.skirt_height) {
for (const ExtrusionEntity *ee : print_object->skirt().entities)
gcode += this->extrude_entity(*ee, "skirt", m_config.support_material_speed.value);
}
}
//extrude object-only brim
if (single_object_idx != size_t(-1) && !layers.front().object()->brim().empty()
&& extruder_id == layer_tools.extruders.front()) {
const PrintObject *print_object = layers.front().object();
this->set_origin(unscale(print_object->copies()[single_object_idx]));
for (const ExtrusionEntity *ee : print_object->skirt().entities)
gcode += this->extrude_entity(*ee, "skirt", m_config.support_material_speed.value);
if (this->m_layer != nullptr && this->m_layer->id() == 0) {
m_avoid_crossing_perimeters.use_external_mp = true;
for (const ExtrusionEntity *ee : print_object->brim().entities)
gcode += this->extrude_entity(*ee, "brim", m_config.support_material_speed.value);
m_avoid_crossing_perimeters.use_external_mp = false;
m_avoid_crossing_perimeters.disable_once = true;
}
}
auto objects_by_extruder_it = by_extruder.find(extruder_id);
@ -1696,7 +1710,7 @@ void GCode::process_layer(
if (print_object == nullptr)
// This layer is empty for this particular object, it has neither object extrusions nor support extrusions at this print_z.
continue;
std::cout << "Writing gcode for layer at " << layers[layer_id].print_z() << ", " << ((this->m_layer_index * 100) / this->m_layer_count) << "%" << std::endl;
//std::cout << "Writing gcode for layer at " << layers[layer_id].print_z() << ", " << ((this->m_layer_index * 100) / this->m_layer_count) << "%" << std::endl;
m_config.apply(print_object->config(), true);
m_layer = layers[layer_id].layer();
@ -2808,7 +2822,8 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
// multi-hop travel path inside the configuration space
if (needs_retraction
&& m_config.avoid_crossing_perimeters
&& ! m_avoid_crossing_perimeters.disable_once) {
&& ! m_avoid_crossing_perimeters.disable_once
&& m_avoid_crossing_perimeters.is_init()) {
travel = m_avoid_crossing_perimeters.travel_to(*this, point);
// check again whether the new travel path still needs a retraction

View File

@ -50,6 +50,7 @@ public:
Polyline travel_to(const GCode &gcodegen, const Point &point);
bool is_init() { return (use_external_mp || use_external_mp_once) ? m_external_mp.get() != nullptr : m_layer_mp.get() != nullptr; }
private:
std::unique_ptr<MotionPlanner> m_external_mp;
std::unique_ptr<MotionPlanner> m_layer_mp;

View File

@ -7,6 +7,9 @@
#include <utility> // for std::forward
#include <algorithm>
#include "libslic3r.h"
#include "Point.hpp"
namespace Slic3r {
/// Handy little spin mutex for the cached meshes.
@ -239,13 +242,92 @@ template<class C> bool all_of(const C &container)
});
}
template<class X, class Y> inline X ceil_i(X x, Y y)
{
static_assert(std::is_integral<X>::value &&
std::is_integral<Y>::value && sizeof(X) >= sizeof(Y),
"");
// A shorter C++14 style form of the enable_if metafunction
template<bool B, class T>
using enable_if_t = typename std::enable_if<B, T>::type;
return (x % y) ? x / y + 1 : x / y;
// /////////////////////////////////////////////////////////////////////////////
// Type safe conversions to and from scaled and unscaled coordinates
// /////////////////////////////////////////////////////////////////////////////
// A meta-predicate which is true for integers wider than or equal to coord_t
template<class I> struct is_scaled_coord
{
static const SLIC3R_CONSTEXPR bool value =
std::is_integral<I>::value &&
std::numeric_limits<I>::digits >=
std::numeric_limits<coord_t>::digits;
};
// Meta predicates for floating, 'scaled coord' and generic arithmetic types
template<class T>
using FloatingOnly = enable_if_t<std::is_floating_point<T>::value, T>;
template<class T>
using ScaledCoordOnly = enable_if_t<is_scaled_coord<T>::value, T>;
template<class T>
using ArithmeticOnly = enable_if_t<std::is_arithmetic<T>::value, T>;
// A shorter form for a generic Eigen vector which is widely used in PrusaSlicer
template<class T, int N>
using EigenVec = Eigen::Matrix<T, N, 1, Eigen::DontAlign>;
// Semantics are the following:
// Upscaling (scaled()): only from floating point types (or Vec) to either
// floating point or integer 'scaled coord' coordinates.
// Downscaling (unscaled()): from arithmetic types (or Vec) to either
// floating point only
// Conversion definition from unscaled to floating point scaled
template<class Tout,
class Tin,
class = FloatingOnly<Tin>,
class = FloatingOnly<Tout>>
inline SLIC3R_CONSTEXPR Tout scaled(const Tin &v) SLIC3R_NOEXCEPT
{
return static_cast<Tout>(v / static_cast<Tin>(SCALING_FACTOR));
}
// Conversion definition from unscaled to integer 'scaled coord'.
// TODO: is the rounding necessary ? Here it is to show that it can be different
// but it does not have to be. Using std::round means loosing noexcept and
// constexpr modifiers
template<class Tout = coord_t, class Tin, class = FloatingOnly<Tin>>
inline SLIC3R_CONSTEXPR ScaledCoordOnly<Tout> scaled(const Tin &v) SLIC3R_NOEXCEPT
{
//return static_cast<Tout>(std::round(v / SCALING_FACTOR));
return static_cast<Tout>(v / static_cast<Tin>(SCALING_FACTOR));
}
// Conversion for Eigen vectors (N dimensional points)
template<class Tout = coord_t, class Tin, int N, class = FloatingOnly<Tin>>
inline EigenVec<ArithmeticOnly<Tout>, N> scaled(const EigenVec<Tin, N> &v)
{
return v.template cast<Tout>() / SCALING_FACTOR;
}
// Conversion from arithmetic scaled type to floating point unscaled
template<class Tout = double,
class Tin,
class = ArithmeticOnly<Tin>,
class = FloatingOnly<Tout>>
inline SLIC3R_CONSTEXPR Tout unscaled(const Tin &v) SLIC3R_NOEXCEPT
{
return static_cast<Tout>(v * static_cast<Tout>(SCALING_FACTOR));
}
// Unscaling for Eigen vectors. Input base type can be arithmetic, output base
// type can only be floating point.
template<class Tout = double,
class Tin,
int N,
class = ArithmeticOnly<Tin>,
class = FloatingOnly<Tout>>
inline SLIC3R_CONSTEXPR EigenVec<Tout, N> unscaled(
const EigenVec<Tin, N> &v) SLIC3R_NOEXCEPT
{
return v.template cast<Tout>() * SCALING_FACTOR;
}
} // namespace Slic3r

View File

@ -13,6 +13,7 @@
#include <list>
namespace Slic3r {
int count_error = 0;
void
MedialAxis::build(Polylines &polylines)
@ -663,11 +664,26 @@ MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, con
if (!finded) {
if (!this->expolygon.contains(line.b)) {
//it's outside!!!
if (!this->expolygon.contains(line.a)) {
std::cout << "Error, a line is formed that start outside a polygon, end outside of it and don't cross it!\n";
} else {
std::cout << "Error, a line is formed that start in a polygon, end outside of it and don't cross it!\n";
}
//if (!this->expolygon.contains(line.a)) {
// std::cout << "Error, a line is formed that start outside a polygon, end outside of it and don't cross it!\n";
//} else {
// std::cout << "Error, a line is formed that start in a polygon, end outside of it and don't cross it!\n";
//}
//{
// std::stringstream stri;
// stri << "Error_" << (count_error++) << ".svg";
// SVG svg(stri.str());
// svg.draw(anchors);
// svg.draw(this->expolygon);
// svg.draw(line);
// svg.draw(polyline);
// svg.Close();
//}
//it's not possible to print that
polyline.points.clear();
polyline.width.clear();
return;
}
new_back = line.b;
}

View File

@ -39,7 +39,7 @@ template<> inline Slic3r::Points& contour(Slic3r::Polygon& sh) { return sh.point
template<> inline const Slic3r::Points& contour(const Slic3r::Polygon& sh) { return sh.points; }
template<> Slic3r::Points::iterator begin(Slic3r::Points& pts, const PathTag&) { return pts.begin();}
template<> Slic3r::Points::const_iterator cbegin(const Slic3r::Points& pts, const PathTag&) { return pts.begin(); }
template<> Slic3r::Points::const_iterator cbegin(const Slic3r::Points& pts, const PathTag&) { return pts.cbegin(); }
template<> Slic3r::Points::iterator end(Slic3r::Points& pts, const PathTag&) { return pts.end();}
template<> Slic3r::Points::const_iterator cend(const Slic3r::Points& pts, const PathTag&) { return pts.cend(); }
@ -71,37 +71,40 @@ using Rational = boost::rational<__int128>;
MinAreaBoundigBox::MinAreaBoundigBox(const Polygon &p, PolygonLevel pc)
{
const Polygon& chull = pc == pcConvex ? p : libnest2d::sl::convexHull(p);
const Polygon &chull = pc == pcConvex ? p :
libnest2d::sl::convexHull(p);
libnest2d::RotatedBox<Point, Unit> box =
libnest2d::minAreaBoundingBox<Polygon, Unit, Rational>(chull);
m_right = box.right_extent();
m_bottom = box.bottom_extent();
m_right = libnest2d::cast<long double>(box.right_extent());
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
m_axis = box.axis();
}
MinAreaBoundigBox::MinAreaBoundigBox(const ExPolygon &p, PolygonLevel pc)
{
const ExPolygon& chull = pc == pcConvex ? p : libnest2d::sl::convexHull(p);
const ExPolygon &chull = pc == pcConvex ? p :
libnest2d::sl::convexHull(p);
libnest2d::RotatedBox<Point, Unit> box =
libnest2d::minAreaBoundingBox<ExPolygon, Unit, Rational>(chull);
m_right = box.right_extent();
m_bottom = box.bottom_extent();
m_right = libnest2d::cast<long double>(box.right_extent());
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
m_axis = box.axis();
}
MinAreaBoundigBox::MinAreaBoundigBox(const Points &pts, PolygonLevel pc)
{
const Points& chull = pc == pcConvex ? pts : libnest2d::sl::convexHull(pts);
const Points &chull = pc == pcConvex ? pts :
libnest2d::sl::convexHull(pts);
libnest2d::RotatedBox<Point, Unit> box =
libnest2d::minAreaBoundingBox<Points, Unit, Rational>(chull);
m_right = box.right_extent();
m_bottom = box.bottom_extent();
m_right = libnest2d::cast<long double>(box.right_extent());
m_bottom = libnest2d::cast<long double>(box.bottom_extent());
m_axis = box.axis();
}
@ -109,18 +112,20 @@ double MinAreaBoundigBox::angle_to_X() const
{
double ret = std::atan2(m_axis.y(), m_axis.x());
auto s = std::signbit(ret);
if(s) ret += 2 * PI;
if (s) ret += 2 * PI;
return -ret;
}
long double MinAreaBoundigBox::width() const
{
return std::abs(m_bottom) / std::sqrt(libnest2d::pl::magnsq<Point, long double>(m_axis));
return std::abs(m_bottom) /
std::sqrt(libnest2d::pl::magnsq<Point, long double>(m_axis));
}
long double MinAreaBoundigBox::height() const
{
return std::abs(m_right) / std::sqrt(libnest2d::pl::magnsq<Point, long double>(m_axis));
return std::abs(m_right) /
std::sqrt(libnest2d::pl::magnsq<Point, long double>(m_axis));
}
long double MinAreaBoundigBox::area() const
@ -138,5 +143,4 @@ void remove_collinear_points(ExPolygon &p)
{
p = libnest2d::removeCollinearPoints<ExPolygon>(p, Unit(0));
}
}
} // namespace Slic3r

View File

@ -1564,7 +1564,9 @@ void ModelVolume::center_geometry_after_creation()
Vec3d shift = this->mesh().bounding_box().center();
if (!shift.isApprox(Vec3d::Zero()))
{
if (m_mesh)
m_mesh->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2));
if (m_convex_hull)
m_convex_hull->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2));
translate(shift);
}

View File

@ -63,9 +63,9 @@ std::string toString(const Model& model, bool holes = true) {
ExPolygons expolys = tmpmesh.horizontal_projection();
for(auto& expoly_complex : expolys) {
auto tmp = expoly_complex.simplify(1.0/SCALING_FACTOR);
ExPolygons tmp = expoly_complex.simplify(scaled<double>(1.));
if(tmp.empty()) continue;
auto expoly = tmp.front();
ExPolygon expoly = tmp.front();
expoly.contour.make_clockwise();
for(auto& h : expoly.holes) h.make_counter_clockwise();
@ -610,7 +610,7 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model,
if(tolerance > EPSILON) {
Polygons pp { p };
pp = p.simplify(double(scaled(tolerance)));
pp = p.simplify(scaled<double>(tolerance));
if (!pp.empty()) p = pp.front();
}
@ -633,8 +633,8 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model,
if(item.vertexCount() > 3) {
item.rotation(Geometry::rotation_diff_z(rotation0, objinst->get_rotation()));
item.translation({
ClipperLib::cInt(objinst->get_offset(X)/SCALING_FACTOR),
ClipperLib::cInt(objinst->get_offset(Y)/SCALING_FACTOR)
scaled<ClipperLib::cInt>(objinst->get_offset(X)),
scaled<ClipperLib::cInt>(objinst->get_offset(Y))
});
ret.emplace_back(objinst, item);
}
@ -658,8 +658,8 @@ ShapeData2D projectModelFromTop(const Slic3r::Model &model,
Item item(std::move(pn));
item.rotation(wti.rotation),
item.translation({
ClipperLib::cInt(wti.pos(0)/SCALING_FACTOR),
ClipperLib::cInt(wti.pos(1)/SCALING_FACTOR)
scaled<ClipperLib::cInt>(wti.pos(0)),
scaled<ClipperLib::cInt>(wti.pos(1))
});
ret.emplace_back(nullptr, item);
}
@ -822,7 +822,9 @@ bool arrange(Model &model, // The model with the geometries
auto& cfn = stopcondition;
coord_t md = ceil_i(min_obj_distance, 2) - SCALED_EPSILON;
// Integer ceiling the min distance from the bed perimeters
coord_t md = min_obj_distance - SCALED_EPSILON;
md = (md % 2) ? md / 2 + 1 : md / 2;
auto binbb = Box({libnest2d::Coord{bbb.min(0)} - md,
libnest2d::Coord{bbb.min(1)} - md},
@ -916,7 +918,9 @@ void find_new_position(const Model &model,
BoundingBox bbb(bed);
coord_t md = ceil_i(min_obj_distance, 2) - SCALED_EPSILON;
// Integer ceiling the min distance from the bed perimeters
coord_t md = min_obj_distance - SCALED_EPSILON;
md = (md % 2) ? md / 2 + 1 : md / 2;
auto binbb = Box({libnest2d::Coord{bbb.min(0)} - md,
libnest2d::Coord{bbb.min(1)} - md},

View File

@ -201,7 +201,9 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|| opt_key == "min_skirt_length"
|| opt_key == "ooze_prevention") {
steps.emplace_back(psSkirt);
} else if (opt_key == "brim_width"
} else if (
opt_key == "complete_objects"
|| opt_key == "brim_width"
|| opt_key == "brim_ears"
|| opt_key == "brim_ears_max_angle") {
steps.emplace_back(psBrim);
@ -211,8 +213,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|| opt_key == "resolution") {
osteps.emplace_back(posSlice);
} else if (
opt_key == "complete_objects"
|| opt_key == "filament_type"
opt_key == "filament_type"
|| opt_key == "filament_soluble"
|| opt_key == "first_layer_temperature"
|| opt_key == "filament_loading_speed"
@ -1513,12 +1514,15 @@ void Print::process()
obj->generate_support_material();
if (this->set_started(psSkirt)) {
m_skirt.clear();
for (PrintObject *obj : m_objects) {
obj->m_skirt.clear();
}
if (this->has_skirt()) {
this->set_status(88, L("Generating skirt"));
if (config().complete_objects){
for (PrintObject *obj : m_objects){
//create a skirt "pattern" (one per object)
const Points copies = obj->copies();
const Points copies{ obj->copies() };
obj->m_copies.clear();
obj->m_copies.emplace_back();
this->_make_skirt({ obj }, obj->m_skirt);
@ -1532,6 +1536,9 @@ void Print::process()
}
if (this->set_started(psBrim)) {
m_brim.clear();
for (PrintObject *obj : m_objects) {
obj->m_brim.clear();
}
if (m_config.brim_width > 0) {
this->set_status(88, L("Generating brim"));
if (config().complete_objects){

View File

@ -5,6 +5,7 @@
#include "SLABoostAdapter.hpp"
#include "ClipperUtils.hpp"
#include "Tesselate.hpp"
#include "MTUtils.hpp"
// For debugging:
//#include <fstream>
@ -203,7 +204,7 @@ void offset(ExPolygon& sh, coord_t distance) {
}
ClipperOffset offs;
offs.ArcTolerance = 0.01*scaled(1.0);
offs.ArcTolerance = scaled<double>(0.01);
Paths result;
offs.AddPath(ctour, jtRound, etClosedPolygon);
offs.AddPaths(holes, jtRound, etClosedPolygon);
@ -351,7 +352,7 @@ Contour3D round_edges(const ExPolygon& base_plate,
double x2 = xx*xx;
double stepy = std::sqrt(r2 - x2);
offset(ob, s*scaled(xx));
offset(ob, s * scaled(xx));
wh = ceilheight_mm - radius_mm + stepy;
Contour3D pwalls;
@ -375,7 +376,7 @@ Contour3D round_edges(const ExPolygon& base_plate,
double xx = radius_mm - i*stepx;
double x2 = xx*xx;
double stepy = std::sqrt(r2 - x2);
offset(ob, s*scaled(xx));
offset(ob, s * scaled(xx));
wh = ceilheight_mm - radius_mm - stepy;
Contour3D pwalls;
@ -476,7 +477,7 @@ ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 50,
double dx = x(c) - x(cc), dy = y(c) - y(cc);
double l = std::sqrt(dx * dx + dy * dy);
double nx = dx / l, ny = dy / l;
double max_dist = scaled(max_dist_mm);
double max_dist = scaled<double>(max_dist_mm);
ExPolygon& expo = punion[idx++];
BoundingBox querybb(expo);
@ -492,7 +493,7 @@ ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 50,
ctour.reserve(3);
ctour.emplace_back(cc);
Point d(coord_t(scaled(1.)*nx), coord_t(scaled(1.)*ny));
Point d(scaled(nx), scaled(ny));
ctour.emplace_back(c + Point( -y(d), x(d) ));
ctour.emplace_back(c + Point( y(d), -x(d) ));
offset(r, scaled(1.));
@ -529,14 +530,14 @@ void base_plate(const TriangleMesh &mesh, ExPolygons &output, float h,
ExPolygons tmp; tmp.reserve(count);
for(ExPolygons& o : out)
for(ExPolygon& e : o) {
auto&& exss = e.simplify(scaled(0.1));
auto&& exss = e.simplify(scaled<double>(0.1));
for(ExPolygon& ep : exss) tmp.emplace_back(std::move(ep));
}
ExPolygons utmp = unify(tmp);
for(auto& o : utmp) {
auto&& smp = o.simplify(scaled(0.1));
auto&& smp = o.simplify(scaled<double>(0.1));
output.insert(output.end(), smp.begin(), smp.end());
}
}

View File

@ -668,7 +668,7 @@ void SLAPrint::process()
double ilhd = m_material_config.initial_layer_height.getFloat();
auto ilh = float(ilhd);
auto ilhs = scaled(ilhd);
coord_t ilhs = scaled(ilhd);
const size_t objcount = m_objects.size();
static const unsigned min_objstatus = 0; // where the per object operations start
@ -696,15 +696,13 @@ void SLAPrint::process()
double lhd = m_objects.front()->m_config.layer_height.getFloat();
float lh = float(lhd);
auto lhs = scaled(lhd);
auto &&bb3d = mesh.bounding_box();
coord_t lhs = scaled(lhd);
auto && bb3d = mesh.bounding_box();
double minZ = bb3d.min(Z) - po.get_elevation();
double maxZ = bb3d.max(Z);
auto minZf = float(minZ);
auto minZs = scaled(minZ);
auto maxZs = scaled(maxZ);
coord_t minZs = scaled(minZ);
coord_t maxZs = scaled(maxZ);
po.m_slice_index.clear();
@ -722,8 +720,9 @@ void SLAPrint::process()
if(slindex_it == po.m_slice_index.end())
//TRN To be shown at the status bar on SLA slicing error.
throw std::runtime_error(L("Slicing had to be stopped "
"due to an internal error."));
throw std::runtime_error(
L("Slicing had to be stopped due to an internal error: "
"Inconsistent slice index."));
po.m_model_height_levels.clear();
po.m_model_height_levels.reserve(po.m_slice_index.size());
@ -1013,9 +1012,6 @@ void SLAPrint::process()
using ClipperPolygons = std::vector<ClipperPolygon>;
namespace sl = libnest2d::shapelike; // For algorithms
// If the raster has vertical orientation, we will flip the coordinates
// bool flpXY = m_printer_config.display_orientation.getInt() == SLADisplayOrientation::sladoPortrait;
// Set up custom union and diff functions for clipper polygons
auto polyunion = [] (const ClipperPolygons& subjects)
{
@ -1066,8 +1062,8 @@ void SLAPrint::process()
const int fade_layers_cnt = m_default_object_config.faded_layers.getInt();// 10 // [3;20]
const double width = scaled(m_printer_config.display_width.getFloat());
const double height = scaled(m_printer_config.display_height.getFloat());
const auto width = scaled<double>(m_printer_config.display_width.getFloat());
const auto height = scaled<double>(m_printer_config.display_height.getFloat());
const double display_area = width*height;
// get polygons for all instances in the object
@ -1123,11 +1119,6 @@ void SLAPrint::process()
sl::translate(poly, ClipperPoint{instances[i].shift(X),
instances[i].shift(Y)});
// if (flpXY) {
// for(auto& p : poly.Contour) std::swap(p.X, p.Y);
// for(auto& h : poly.Holes) for(auto& p : h) std::swap(p.X, p.Y);
// }
polygons.emplace_back(std::move(poly));
}
}

View File

@ -15,6 +15,8 @@
#define ENABLE_RENDER_STATISTICS 0
// Shows an imgui dialog with camera related data
#define ENABLE_CAMERA_STATISTICS 0
// Render the picking pass instead of the main scene (use [T] key to toggle between regular rendering and picking pass only rendering)
#define ENABLE_RENDER_PICKING_PASS 0
//====================
@ -48,5 +50,5 @@
#define ENABLE_SVG_ICONS (1 && ENABLE_1_42_0_ALPHA8 && ENABLE_TEXTURES_FROM_SVG)
#define DEBUG_EXTRUSION_OUTPUT 0
//#define DEBUG_EXTRUSION_OUTPUT 0
#endif // _technologies_h_

View File

@ -547,9 +547,9 @@ TriangleMesh TriangleMesh::convex_hull_3d() const
#if REALfloat
qhull.runQhull("", 3, (int)this->its.vertices.size(), (const realT*)(this->its.vertices.front().data()), "Qt");
#else
src_vertices.reserve(this->its.vertices() * 3);
src_vertices.reserve(this->its.vertices.size() * 3);
// We will now fill the vector with input points for computation:
for (const stl_vertex &v : ths->its.vertices.size())
for (const stl_vertex &v : this->its.vertices)
for (int i = 0; i < 3; ++ i)
src_vertices.emplace_back(v(i));
qhull.runQhull("", 3, (int)src_vertices.size() / 3, src_vertices.data(), "Qt");

View File

@ -167,7 +167,7 @@ template<class T> size_t next_highest_power_of_2(T v,
extern std::string xml_escape(std::string text);
#if defined __GNUC__ & __GNUC__ < 5
#if defined __GNUC__ && __GNUC__ < 5 && !defined __clang__
// Older GCCs don't have std::is_trivially_copyable
// cf. https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/manual/status.html#status.iso.2011
#warning "GCC version < 5, faking std::is_trivially_copyable"

View File

@ -60,20 +60,6 @@ typedef double coordf_t;
#define SLIC3R_NOEXCEPT noexcept
#endif
template<class Tf> inline SLIC3R_CONSTEXPR coord_t scaled(Tf val)
{
static_assert (std::is_floating_point<Tf>::value, "Floating point only");
return coord_t(val / Tf(SCALING_FACTOR));
}
template<class Tf = double> inline SLIC3R_CONSTEXPR Tf unscaled(coord_t val)
{
static_assert (std::is_floating_point<Tf>::value, "Floating point only");
return Tf(val * Tf(SCALING_FACTOR));
}
inline SLIC3R_CONSTEXPR float unscaledf(coord_t val) { return unscaled<float>(val); }
inline std::string debug_out_path(const char *name, ...)
{
char buffer[2048];

View File

@ -22,6 +22,10 @@
static const size_t MAX_SIZE = sizeof(char) * 255;
static const int MAX_SAFE_INT = (unsigned int) -1 >> 1;
#ifdef _WIN32
#define strdup _strdup
#endif
/**
* Define comparison operators, storing the
* ASCII code per each symbol in hexadecimal notation.
@ -50,8 +54,8 @@ strcut (char *str, int begin, int len) {
if((int)l < 0 || (int)l > MAX_SAFE_INT) return -1;
if (len < 0) len = l - begin + 1;
if (begin + len > (int)l) len = l - begin;
if (len < 0) len = (int)l - begin + 1;
if (begin + len > (int)l) len = (int)l - begin;
memmove(str + begin, str + begin + len, l - len + 1 - begin);
return len;
@ -104,7 +108,7 @@ parse_int (const char *s) {
static char *
parse_slice (char *buf, char sep) {
char *pr, *part;
int plen;
size_t plen;
/* Find separator in buf */
pr = strchr(buf, sep);
@ -210,8 +214,9 @@ semver_parse_version (const char *str, semver_t *ver) {
static int
compare_prerelease (char *x, char *y) {
char *lastx, *lasty, *xptr, *yptr, *endptr;
int xlen, ylen, xisnum, yisnum, xnum, ynum;
int xn, yn, min, res;
size_t xlen, ylen, xn, yn, min;
int xisnum, yisnum, xnum, ynum;
int res;
if (x == NULL && y == NULL) return 0;
if (y == NULL && x) return -1;
if (x == NULL && y) return 1;
@ -572,7 +577,7 @@ semver_clean (char *s) {
for (i = 0; i < len; i++) {
if (contains(s[i], VALID_CHARS, mlen) == 0) {
res = strcut(s, i, 1);
res = strcut(s, (int)i, 1);
if(res == -1) return -1;
--len; --i;
}

View File

@ -44,8 +44,8 @@ public:
const float* get_vertices_data() const;
unsigned int get_vertices_data_size() const { return (unsigned int)m_vertices.size() * get_vertex_data_size(); }
unsigned int get_vertex_data_size() const { return (unsigned int)(5 * sizeof(float)); }
unsigned int get_position_offset() const { return 0; }
unsigned int get_tex_coords_offset() const { return (unsigned int)(3 * sizeof(float)); }
size_t get_position_offset() const { return 0; }
size_t get_tex_coords_offset() const { return (size_t)(3 * sizeof(float)); }
unsigned int get_vertices_count() const { return (unsigned int)m_vertices.size(); }
#else
const float* get_vertices() const { return m_vertices.data(); }

View File

@ -1670,7 +1670,8 @@ void ExtrusionToVert::use(const ExtrusionEntityCollection &collection) { for (co
void _3DScene::extrusionentity_to_verts(const ExtrusionEntity &extrusion_entity, float print_z, const Point &copy, GLVolume &volume)
{
extrusion_entity.visit(ExtrusionToVert(print_z, copy, volume));
ExtrusionToVert visitor(print_z, copy, volume);
extrusion_entity.visit(visitor);
}
void _3DScene::polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume)

View File

@ -53,10 +53,7 @@ void BedShapeDialog::on_dpi_changed(const wxRect &suggested_rect)
void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
{
// on_change(nullptr);
auto box = new wxStaticBox(this, wxID_ANY, _(L("Shape")));
auto sbsizer = new wxStaticBoxSizer(box, wxVERTICAL);
auto sbsizer = new wxStaticBoxSizer(wxVERTICAL, this, _(L("Shape")));
// shape options
m_shape_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition,
@ -92,12 +89,14 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
Line line{ "", "" };
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
auto btn = new wxButton(parent, wxID_ANY, _(L("Load shape from STL...")), wxDefaultPosition, wxDefaultSize);
auto shape_btn = new wxButton(parent, wxID_ANY, _(L("Load shape from STL...")));
wxSizer* shape_sizer = new wxBoxSizer(wxHORIZONTAL);
shape_sizer->Add(shape_btn, 1, wxEXPAND);
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(shape_sizer, 1, wxEXPAND);
btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
shape_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e)
{
load_stl();
}));
@ -106,7 +105,7 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
};
optgroup->append_line(line);
Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e)
Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent& e)
{
update_shape();
}));
@ -117,7 +116,7 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
// main sizer
auto top_sizer = new wxBoxSizer(wxHORIZONTAL);
top_sizer->Add(sbsizer, 0, wxEXPAND | wxLeft | wxTOP | wxBOTTOM, 10);
top_sizer->Add(sbsizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 10);
if (m_canvas)
top_sizer->Add(m_canvas, 1, wxEXPAND | wxALL, 10) ;
@ -135,7 +134,6 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
// Create a panel for a rectangular / circular / custom bed shape.
ConfigOptionsGroupShp BedShapePanel::init_shape_options_page(const wxString& title)
{
auto panel = new wxPanel(m_shape_options_book);
ConfigOptionsGroupShp optgroup;
optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Settings")));
@ -234,7 +232,7 @@ void BedShapePanel::set_shape(ConfigOptionPoints* points)
// This is a custom bed shape, use the polygon provided.
m_shape_options_book->SetSelection(SHAPE_CUSTOM);
// Copy the polygon to the canvas, make a copy of the array.
m_canvas->m_bed_shape = points->values;
m_loaded_bed_shape = points->values;
update_shape();
}

View File

@ -171,7 +171,7 @@ void BonjourDialog::on_reply(BonjourReplyEvent &e)
// Filter replies based on selected technology
const auto model = e.reply.txt_data.find("model");
const bool sl1 = model != e.reply.txt_data.end() && model->second == "SL1";
if (tech != ptSLA && sl1 || tech == ptSLA && !sl1) {
if ((tech != ptSLA && sl1) || (tech == ptSLA && !sl1)) {
return;
}

View File

@ -24,7 +24,7 @@ namespace GUI {
const double Camera::DefaultDistance = 1000.0;
double Camera::FrustrumMinZSize = 50.0;
double Camera::FrustrumZMargin = 10.0;
double Camera::FovMinDeg = 5.0;
double Camera::FovMinDeg = 0.5;
double Camera::FovMaxDeg = 75.0;
Camera::Camera()

View File

@ -810,7 +810,7 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
const Item& item = items[i];
unsigned x = em_w/2 + item.indent * em_w;
if (i == item_active || item_hover >= 0 && i == (size_t)item_hover) {
if (i == item_active || (item_hover >= 0 && i == (size_t)item_hover)) {
dc.DrawBitmap(bullet_blue.bmp(), x, y + yoff_icon, false);
}
else if (i < item_active) { dc.DrawBitmap(bullet_black.bmp(), x, y + yoff_icon, false); }

View File

@ -442,8 +442,7 @@ void FirmwareDialog::priv::avr109_lookup_port(Avr109Pid usb_pid)
auto ports = Utils::scan_serial_ports_extended();
ports.erase(std::remove_if(ports.begin(), ports.end(), [=](const SerialPortInfo &port ) {
return port.id_vendor != USB_VID_PRUSA ||
port.id_product != usb_pid.boot &&
port.id_product != usb_pid.app;
(port.id_product != usb_pid.boot && port.id_product != usb_pid.app);
}), ports.end());
if (ports.size() == 0) {

View File

@ -457,8 +457,10 @@ void GLCanvas3D::LayersEditing::_render_profile(const Rect& bar_rect) const
{
//FIXME show some kind of legend.
if (!m_slicing_parameters)
return;
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
assert(m_slicing_parameters != nullptr);
float scale_x = bar_rect.get_width() / (float)(1.12 * m_slicing_parameters->max_layer_height);
float scale_y = bar_rect.get_height() / m_object_max_z;
float x = bar_rect.get_left() + (float)m_slicing_parameters->layer_height * scale_x;
@ -910,7 +912,8 @@ GLCanvas3D::LegendTexture::LegendTexture()
void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas,
std::vector<std::pair<double, double>>& cp_legend_values)
{
if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint)
if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint &&
wxGetApp().extruders_edited_cnt() == 1) // show color change legend only for single-material presets
{
auto& config = wxGetApp().preset_bundle->project_config;
const std::vector<double>& color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
@ -1222,6 +1225,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar
, m_cursor_type(Standard)
, m_color_by("volume")
, m_reload_delayed(false)
#if ENABLE_RENDER_PICKING_PASS
, m_show_picking_texture(false)
#endif // ENABLE_RENDER_PICKING_PASS
, m_render_sla_auxiliaries(true)
{
if (m_canvas != nullptr) {
@ -1625,6 +1631,10 @@ void GLCanvas3D::render()
_picking_pass();
}
#if ENABLE_RENDER_PICKING_PASS
if (!m_picking_enabled || !m_show_picking_texture)
{
#endif // ENABLE_RENDER_PICKING_PASS
// draw scene
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
_render_background();
@ -1654,6 +1664,9 @@ void GLCanvas3D::render()
_render_current_gizmo();
_render_selection_sidebar_hints();
#if ENABLE_RENDER_PICKING_PASS
}
#endif // ENABLE_RENDER_PICKING_PASS
#if ENABLE_SHOW_CAMERA_TARGET
_render_camera_target();
@ -2395,6 +2408,14 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'k': { m_camera.select_next_type(); m_dirty = true; break; }
case 'O':
case 'o': { set_camera_zoom(-1.0); break; }
#if ENABLE_RENDER_PICKING_PASS
case 'T':
case 't': {
m_show_picking_texture = !m_show_picking_texture;
m_dirty = true;
break;
}
#endif // ENABLE_RENDER_PICKING_PASS
case 'Z':
case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; }
default: { evt.Skip(); break; }

View File

@ -477,6 +477,10 @@ private:
GCodePreviewVolumeIndex m_gcode_preview_volume_index;
#if ENABLE_RENDER_PICKING_PASS
bool m_show_picking_texture;
#endif // ENABLE_RENDER_PICKING_PASS
#if ENABLE_RENDER_STATISTICS
RenderStats m_render_stats;
#endif // ENABLE_RENDER_STATISTICS

View File

@ -141,6 +141,18 @@ GUI_App::GUI_App()
, m_imgui(new ImGuiWrapper())
{}
GUI_App::~GUI_App()
{
if (app_config != nullptr)
delete app_config;
if (preset_bundle != nullptr)
delete preset_bundle;
if (preset_updater != nullptr)
delete preset_updater;
}
bool GUI_App::OnInit()
{
try {

View File

@ -95,6 +95,7 @@ public:
bool initialized() const { return m_initialized; }
GUI_App();
~GUI_App();
static unsigned get_colour_approx_luma(const wxColour &colour);
static bool dark_mode();

View File

@ -460,7 +460,7 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item)
if (!m_config || selection.empty())
return;
const int extruder = selection.size() > 1 ? 0 : atoi(selection.c_str());
const int extruder = /*selection.size() > 1 ? 0 : */atoi(selection.c_str());
m_config->set_key_value("extruder", new ConfigOptionInt(extruder));
// update scene

View File

@ -541,6 +541,26 @@ void Preview::on_checkbox_shells(wxCommandEvent& evt)
refresh_print();
}
void Preview::update_view_type()
{
const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config;
const wxString& choice = !config.option<ConfigOptionFloats>("colorprint_heights")->values.empty() &&
wxGetApp().extruders_edited_cnt()==1 ?
_(L("Color Print")) :
config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values.size() > 1 ?
_(L("Tool")) :
_(L("Feature type"));
int type = m_choice_view_type->FindString(choice);
if (m_choice_view_type->GetSelection() != type) {
m_choice_view_type->SetSelection(type);
if (0 <= type && type < (int)GCodePreviewData::Extrusion::Num_View_Types)
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type;
m_preferred_color_mode = "feature";
}
}
void Preview::create_double_slider()
{
m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100);
@ -553,21 +573,11 @@ void Preview::create_double_slider()
Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) {
auto& config = wxGetApp().preset_bundle->project_config;
((config.option<ConfigOptionFloats>("colorprint_heights"))->values) = (m_slider->GetTicksValues());
wxGetApp().preset_bundle->project_config.option<ConfigOptionFloats>("colorprint_heights")->values = m_slider->GetTicksValues();
m_schedule_background_process();
const wxString& choise = !config.option<ConfigOptionFloats>("colorprint_heights")->values.empty() ? _(L("Color Print")) :
config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values.size() > 1 ?
_(L("Tool")) : _(L("Feature type"));
update_view_type();
int type = m_choice_view_type->FindString(choise);
if (m_choice_view_type->GetSelection() != type) {
m_choice_view_type->SetSelection(type);
if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types))
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type;
m_preferred_color_mode = "feature";
}
reload_print();
});
}
@ -787,9 +797,14 @@ void Preview::load_print_as_fff(bool keep_z_range)
// Load the real G-code preview.
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
m_loaded = true;
} else
} else {
// disable color change information for multi-material presets
if (wxGetApp().extruders_edited_cnt() > 1)
color_print_values.clear();
// Load the initial preview based on slices, not the final G-code.
m_canvas->load_preview(colors, color_print_values);
}
show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple");
// recalculates zs and update sliders accordingly
std::vector<double> zs = m_canvas->get_current_print_zs(true);

View File

@ -127,6 +127,8 @@ public:
void move_double_slider(wxKeyEvent& evt);
void edit_double_slider(wxKeyEvent& evt);
void update_view_type();
private:
bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model);

View File

@ -15,48 +15,6 @@
namespace Slic3r {
namespace GUI {
class GLGizmoCutPanel : public wxPanel
{
public:
GLGizmoCutPanel(wxWindow *parent);
void display(bool display);
private:
bool m_active;
wxCheckBox *m_cb_rotate;
wxButton *m_btn_cut;
wxButton *m_btn_cancel;
};
GLGizmoCutPanel::GLGizmoCutPanel(wxWindow *parent)
: wxPanel(parent)
, m_active(false)
, m_cb_rotate(new wxCheckBox(this, wxID_ANY, _(L("Rotate lower part upwards"))))
, m_btn_cut(new wxButton(this, wxID_OK, _(L("Perform cut"))))
, m_btn_cancel(new wxButton(this, wxID_CANCEL, _(L("Cancel"))))
{
enum { MARGIN = 5 };
auto *sizer = new wxBoxSizer(wxHORIZONTAL);
auto *label = new wxStaticText(this, wxID_ANY, _(L("Cut object:")));
sizer->Add(label, 0, wxALL | wxALIGN_CENTER, MARGIN);
sizer->Add(m_cb_rotate, 0, wxALL | wxALIGN_CENTER, MARGIN);
sizer->AddStretchSpacer();
sizer->Add(m_btn_cut, 0, wxALL | wxALIGN_CENTER, MARGIN);
sizer->Add(m_btn_cancel, 0, wxALL | wxALIGN_CENTER, MARGIN);
SetSizer(sizer);
}
void GLGizmoCutPanel::display(bool display)
{
Show(display);
GetParent()->Layout();
}
const double GLGizmoCut::Offset = 10.0;
const double GLGizmoCut::Margin = 20.0;
const std::array<float, 3> GLGizmoCut::GrabberColor = { 1.0, 0.5, 0.0 };
@ -188,7 +146,7 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit, co
m_imgui->begin(_(L("Cut")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
ImGui::PushItemWidth(m_imgui->scaled(5.0f));
bool _value_changed = ImGui::InputDouble("Z", &m_cut_z, 0.0f, 0.0f, "%.2f");
ImGui::InputDouble("Z", &m_cut_z, 0.0f, 0.0f, "%.2f");
m_imgui->checkbox(_(L("Keep upper part")), m_keep_upper);
m_imgui->checkbox(_(L("Keep lower part")), m_keep_lower);

View File

@ -257,6 +257,10 @@ void GLGizmoSlaSupports::render_clipping_plane(const Selection& selection) const
void GLGizmoSlaSupports::on_render_for_picking(const Selection& selection) const
{
#if ENABLE_RENDER_PICKING_PASS
m_z_shift = selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z();
#endif
glsafe(::glEnable(GL_DEPTH_TEST));
render_points(selection, true);
}

View File

@ -326,9 +326,9 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>&
int selection_out = -1;
bool res = false;
const char *selection_str = selection < options.size() ? options[selection].c_str() : "";
const char *selection_str = selection < (int)options.size() ? options[selection].c_str() : "";
if (ImGui::BeginCombo("", selection_str)) {
for (int i = 0; i < options.size(); i++) {
for (int i = 0; i < (int)options.size(); i++) {
if (ImGui::Selectable(options[i].c_str(), i == selection)) {
selection_out = i;
}

View File

@ -154,6 +154,9 @@ void KBShortcutsDialog::fill_shortcuts()
plater_shortcuts.push_back(Shortcut("I", L("Zoom in")));
plater_shortcuts.push_back(Shortcut("O", L("Zoom out")));
plater_shortcuts.push_back(Shortcut("ESC", L("Unselect gizmo / Clear selection")));
#if ENABLE_RENDER_PICKING_PASS
plater_shortcuts.push_back(Shortcut("T", L("Toggle picking pass texture rendering on/off")));
#endif // ENABLE_RENDER_PICKING_PASS
m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, szRight)));

View File

@ -614,10 +614,10 @@ struct Sidebar::priv
PresetComboBox *combo_printer;
wxBoxSizer *sizer_params;
FreqChangedParams *frequently_changed_parameters;
ObjectList *object_list;
ObjectManipulation *object_manipulation;
ObjectSettings *object_settings;
FreqChangedParams *frequently_changed_parameters{ nullptr };
ObjectList *object_list{ nullptr };
ObjectManipulation *object_manipulation{ nullptr };
ObjectSettings *object_settings{ nullptr };
ObjectInfo *object_info;
SlicedInfo *sliced_info;
@ -626,10 +626,23 @@ struct Sidebar::priv
wxButton *btn_send_gcode;
priv(Plater *plater) : plater(plater) {}
~priv();
void show_preset_comboboxes();
};
Sidebar::priv::~priv()
{
if (object_manipulation != nullptr)
delete object_manipulation;
if (object_settings != nullptr)
delete object_settings;
if (frequently_changed_parameters != nullptr)
delete frequently_changed_parameters;
}
void Sidebar::priv::show_preset_comboboxes()
{
const bool showSLA = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA;
@ -1261,6 +1274,7 @@ struct Plater::priv
Preview *preview;
BackgroundSlicingProcess background_process;
bool suppressed_backround_processing_update { false };
// A class to handle UI jobs like arranging and optimizing rotation.
// These are not instant jobs, the user has to be informed about their
@ -1513,6 +1527,7 @@ struct Plater::priv
static const std::regex pattern_prusa;
priv(Plater *q, MainFrame *main_frame);
~priv();
void update(bool force_full_scene_refresh = false);
void select_view(const std::string& direction);
@ -1695,7 +1710,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
panels.push_back(preview);
this->background_process_timer.SetOwner(this->q, 0);
this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->update_restart_background_process(false, false); });
this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt)
{
if (!this->suppressed_backround_processing_update)
this->update_restart_background_process(false, false);
});
update();
@ -1778,6 +1797,12 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
camera.set_type(get_config("use_perspective_camera"));
}
Plater::priv::~priv()
{
if (config != nullptr)
delete config;
}
void Plater::priv::update(bool force_full_scene_refresh)
{
// the following line, when enabled, causes flickering on NVIDIA graphics cards
@ -3931,6 +3956,9 @@ void Plater::reslice()
}
else if (!p->background_process.empty() && !p->background_process.idle())
p->show_action_buttons(true);
// update type of preview
p->preview->update_view_type();
}
void Plater::reslice_SLA_supports(const ModelObject &object)
@ -4183,9 +4211,25 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs)
this->p->schedule_background_process();
}
void Plater::schedule_background_process()
void Plater::schedule_background_process(bool schedule/* = true*/)
{
if (schedule)
this->p->schedule_background_process();
this->p->suppressed_backround_processing_update = false;
}
bool Plater::is_background_process_running() const
{
return this->p->background_process_timer.IsRunning();
}
void Plater::suppress_background_process(const bool stop_background_process)
{
if (stop_background_process)
this->p->background_process_timer.Stop();
this->p->suppressed_backround_processing_update = true;
}
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
@ -4261,4 +4305,15 @@ bool Plater::can_copy_to_clipboard() const
return true;
}
SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() :
m_was_running(wxGetApp().plater()->is_background_process_running())
{
wxGetApp().plater()->suppress_background_process(m_was_running);
}
SuppressBackgroundProcessingUpdate::~SuppressBackgroundProcessingUpdate()
{
wxGetApp().plater()->schedule_background_process(m_was_running);
}
}} // namespace Slic3r::GUI

View File

@ -175,7 +175,9 @@ public:
void reslice_SLA_supports(const ModelObject &object);
void changed_object(int obj_idx);
void changed_objects(const std::vector<size_t>& object_idxs);
void schedule_background_process();
void schedule_background_process(bool schedule = true);
bool is_background_process_running() const;
void suppress_background_process(const bool stop_background_process) ;
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
void send_gcode();
@ -219,8 +221,18 @@ public:
private:
struct priv;
std::unique_ptr<priv> p;
friend class SuppressBackgroundProcessingUpdate;
};
class SuppressBackgroundProcessingUpdate
{
public:
SuppressBackgroundProcessingUpdate();
~SuppressBackgroundProcessingUpdate();
private:
bool m_was_running;
};
}}

View File

@ -921,9 +921,9 @@ void Tab::update_preset_description_line()
wxString description_line = preset.is_default ?
_(L("It's a default preset.")) : preset.is_system ?
_(L("It's a system preset.")) :
wxString::Format(_(L("Current preset is inherited from %s")), (parent == nullptr ?
_(L("default preset"))+"." :
":\n\t" + parent->name));
wxString::Format(_(L("Current preset is inherited from %s")), ((parent == nullptr) ?
(_(L("default preset"))+".") :
(wxString( ":\n\t" + parent->name ))));
if (preset.is_default || preset.is_system)
description_line += "\n\t" + _(L("It can't be deleted or modified. ")) +
@ -2433,6 +2433,40 @@ void TabPrinter::build_unregular_pages()
auto optgroup = page->new_optgroup(_(L("Size")));
optgroup->append_single_option_line("nozzle_diameter", extruder_idx);
optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value)
{
if (m_extruders_count > 1 && opt_key.find_first_of("nozzle_diameter") != std::string::npos)
{
SuppressBackgroundProcessingUpdate sbpu;
const double new_nd = boost::any_cast<double>(value);
std::vector<double> nozzle_diameters = static_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"))->values;
// if value was changed
if (fabs(nozzle_diameters[extruder_idx == 0 ? 1 : 0] - new_nd) > EPSILON)
{
const wxString msg_text = _(L("Do you want to change the diameter for all extruders?"));
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
DynamicPrintConfig new_conf = *m_config;
if (dialog->ShowModal() == wxID_YES) {
for (size_t i = 0; i < nozzle_diameters.size(); i++) {
if (i==extruder_idx)
continue;
nozzle_diameters[i] = new_nd;
}
}
else
nozzle_diameters[extruder_idx] = nozzle_diameters[extruder_idx == 0 ? 1 : 0];
new_conf.set_key_value("nozzle_diameter", new ConfigOptionFloats(nozzle_diameters));
load_config(new_conf);
}
}
update_dirty();
update();
};
optgroup = page->new_optgroup(_(L("Layer height limits")));
optgroup->append_single_option_line("min_layer_height", extruder_idx);
optgroup->append_single_option_line("max_layer_height", extruder_idx);

View File

@ -2027,6 +2027,9 @@ void DoubleSlider::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord
void DoubleSlider::draw_ticks(wxDC& dc)
{
if (!m_is_enabled_tick_manipulation)
return;
dc.SetPen(m_is_enabled_tick_manipulation ? DARK_GREY_PEN : LIGHT_GREY_PEN );
int height, width;
get_size(&width, &height);
@ -2044,6 +2047,9 @@ void DoubleSlider::draw_ticks(wxDC& dc)
void DoubleSlider::draw_colored_band(wxDC& dc)
{
if (!m_is_enabled_tick_manipulation)
return;
int height, width;
get_size(&width, &height);
@ -2113,7 +2119,7 @@ void DoubleSlider::draw_one_layer_icon(wxDC& dc)
void DoubleSlider::draw_revert_icon(wxDC& dc)
{
if (m_ticks.empty())
if (m_ticks.empty() || !m_is_enabled_tick_manipulation)
return;
int width, height;
@ -2218,7 +2224,7 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event)
m_selection == ssLower ? correct_lower_value() : correct_higher_value();
if (!m_selection) m_selection = ssHigher;
}
else if (is_point_in_rect(pos, m_rect_revert_icon)) {
else if (is_point_in_rect(pos, m_rect_revert_icon) && m_is_enabled_tick_manipulation) {
// discard all color changes
SetLowerValue(m_min_value);
SetHigherValue(m_max_value);

View File

@ -402,15 +402,8 @@ Updates PresetUpdater::priv::get_config_updates() const
}
}
copy_file_fix(idx.path(), bundle_path_idx);
const auto ver_current = idx.find(vp.config_version);
const bool ver_current_found = ver_current != idx.end();
if (! ver_current_found) {
auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str();
BOOST_LOG_TRIVIAL(error) << message;
GUI::show_error(nullptr, GUI::from_u8(message));
}
BOOST_LOG_TRIVIAL(debug) << boost::format("Vendor: %1%, version installed: %2%%3%, version cached: %4%")
% vp.name
@ -418,6 +411,13 @@ Updates PresetUpdater::priv::get_config_updates() const
% (ver_current_found ? "" : " (not found in index!)")
% recommended->config_version.to_string();
if (! ver_current_found) {
auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str();
BOOST_LOG_TRIVIAL(error) << message;
GUI::show_error(nullptr, GUI::from_u8(message));
continue;
}
if (ver_current_found && !ver_current->is_current_slic3r_supported()) {
BOOST_LOG_TRIVIAL(warning) << "Current Slic3r incompatible with installed bundle: " << bundle_path.string();
updates.incompats.emplace_back(std::move(bundle_path), *ver_current, vp.name);
@ -459,12 +459,18 @@ Updates PresetUpdater::priv::get_config_updates() const
found = true;
}
}
if (! found)
if (found) {
// 'Install' the index in the vendor directory. This is used to memoize
// offered updates and to not offer the same update again if it was cancelled by the user.
copy_file_fix(idx.path(), bundle_path_idx);
} else {
BOOST_LOG_TRIVIAL(warning) << boost::format("Index for vendor %1% indicates update (%2%) but the new bundle was found neither in cache nor resources")
% idx.vendor()
% recommended->config_version.to_string();
}
}
}
return updates;
}

View File

@ -20,6 +20,7 @@ set(SLIC3R_TEST_SOURCES
libslic3r/test_thin.cpp
libslic3r/test_denserinfill.cpp
libslic3r/test_extrusion_entity.cpp
libslic3r/test_skirt_brim.cpp
)
if (NOT TARGET Catch)

View File

@ -1,5 +1,5 @@
//#define CATCH_CONFIG_DISABLE
#define CATCH_CONFIG_DISABLE
#include <catch.hpp>
#include <string>

View File

@ -1,121 +1,435 @@
//#define CATCH_CONFIG_DISABLE
#include <catch.hpp>
#include "test_data.hpp" // get access to init_print, etc
#include "GCodeReader.hpp"
#include "../test_data.hpp"
#include "../../libslic3r/GCodeReader.hpp"
using namespace Slic3r::Test;
using namespace Slic3r;
SCENARIO("skirt test by merill", "") {
GIVEN("2 objects, don't complete individual object") {
DynamicPrintConfig *config = Slic3r::DynamicPrintConfig::new_from_defaults();
// remove noise
config->set_deserialize("top_solid_layers", "0");
config->set_deserialize("bottom_solid_layers", "0");
config->set_deserialize("fill_density", "0");
config->set_deserialize("perimeters", "1");
config->set_deserialize("complete_objects", "0");
config->set_key_value("gcode_comments", new ConfigOptionBool(true));
WHEN("skirt with 3 layers is requested") {
config->set_deserialize("skirts", "1");
config->set_deserialize("skirt_height", "3");
config->set_deserialize("brim_width", "0");
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, model, config);
std::map<double, bool> layers_with_skirt;
std::map<double, bool> layers_with_brim;
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
auto parser{ Slic3r::GCodeReader() };
parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{
if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) {
layers_with_skirt[self.z()] = 1;
}
if (line.extruding(self) && line.comment().find("brim") != std::string::npos) {
layers_with_brim[self.z()] = 1;
}
});
clean_file(gcode_filepath, "gcode");
THEN("one skrit generated") {
REQUIRE(print.skirt().entities.size() == 1);
for (auto obj : print.objects()) {
REQUIRE(obj->skirt().entities.size() == 0);
}
}
THEN("brim is not generated") {
REQUIRE(print.brim().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->brim().entities.size() == 0);
}
REQUIRE(layers_with_brim.size() == 0);
}
THEN("skirt_height is honored") {
REQUIRE(layers_with_skirt.size() == (size_t)config->opt_int("skirt_height"));
}
}
WHEN("brim and skirt with 3 layers is requested") {
config->set_deserialize("skirts", "1");
config->set_deserialize("skirt_height", "3");
config->set_deserialize("brim_width", "4");
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, model, config);
std::map<double, bool> layers_with_skirt;
std::map<double, bool> layers_with_brim;
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
auto parser{ Slic3r::GCodeReader() };
parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{
if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) {
layers_with_skirt[self.z()] = 1;
}
if (line.extruding(self) && line.comment().find("brim") != std::string::npos) {
layers_with_brim[self.z()] = 1;
}
});
clean_file(gcode_filepath, "gcode");
THEN("one skirt generated") {
REQUIRE(print.skirt().entities.size() == 1);
for (auto obj : print.objects()) {
REQUIRE(obj->skirt().entities.size() == 0);
}
}
THEN("brim generated") {
REQUIRE(print.brim().entities.size() > 0);
for (auto obj : print.objects()) {
REQUIRE(obj->brim().entities.size() == 0);
}
REQUIRE(layers_with_brim.size() == 1);
}
THEN("skirt_height is honored") {
REQUIRE(layers_with_skirt.size() == (size_t)config->opt_int("skirt_height"));
}
}
WHEN("brim is requested") {
config->set_deserialize("skirts", "0");
config->set_deserialize("skirt_height", "3");
config->set_deserialize("brim_width", "4");
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, model, config);
std::map<double, bool> layers_with_skirt;
std::map<double, bool> layers_with_brim;
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
auto parser{ Slic3r::GCodeReader() };
parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{
if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) {
layers_with_skirt[self.z()] = 1;
}
if (line.extruding(self) && line.comment().find("brim") != std::string::npos) {
layers_with_brim[self.z()] = 1;
}
});
clean_file(gcode_filepath, "gcode");
THEN("no skirt generated") {
REQUIRE(print.skirt().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->skirt().entities.size() == 0);
}
}
THEN("brim generated") {
REQUIRE(print.brim().entities.size() > 0);
for (auto obj : print.objects()) {
REQUIRE(obj->brim().entities.size() == 0);
}
REQUIRE(layers_with_brim.size() == 1);
}
THEN("skirt_height is honored") {
REQUIRE(layers_with_skirt.size() == 0);
}
}
}
GIVEN("3 objects, complete individual object") {
DynamicPrintConfig *config = Slic3r::DynamicPrintConfig::new_from_defaults();
// remove noise
config->set_deserialize("top_solid_layers", "0");
config->set_deserialize("bottom_solid_layers", "0");
config->set_deserialize("fill_density", "0");
config->set_deserialize("perimeters", "1");
config->set_deserialize("complete_objects", "1");
config->set_key_value("gcode_comments", new ConfigOptionBool(true));
WHEN("skirt with 3 layers is requested") {
config->set_deserialize("skirts", "1");
config->set_deserialize("skirt_height", "3");
config->set_deserialize("brim_width", "0");
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20, TestMesh::cube_20x20x20, TestMesh::pyramid }, model, config);
std::map<double, bool> layers_with_skirt;
std::map<double, bool> layers_with_brim;
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
auto parser{ Slic3r::GCodeReader() };
parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{
if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) {
layers_with_skirt[self.z()] = 1;
}
if (line.extruding(self) && line.comment().find("brim") != std::string::npos) {
layers_with_brim[self.z()] = 1;
}
});
THEN("one skirt per object") {
REQUIRE(print.skirt().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->skirt().entities.size() == 1);
}
}
THEN("brim is not generated") {
REQUIRE(print.brim().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->brim().entities.size() == 0);
}
REQUIRE(layers_with_brim.size() == 0);
}
THEN("skirt_height is honored") {
REQUIRE(layers_with_skirt.size() == (size_t)config->opt_int("skirt_height"));
}
}
WHEN("brim and skirt with 3 layers is requested") {
config->set_deserialize("skirts", "1");
config->set_deserialize("skirt_height", "3");
config->set_deserialize("brim_width", "4");
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, model, config);
std::map<double, bool> layers_with_skirt;
std::map<double, bool> layers_with_brim;
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
auto parser{ Slic3r::GCodeReader() };
parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{
if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) {
layers_with_skirt[self.z()] = 1;
}
if (line.extruding(self) && line.comment().find("brim") != std::string::npos) {
layers_with_brim[self.z()] = 1;
}
});
clean_file(gcode_filepath, "gcode");
THEN("one skirt per object") {
REQUIRE(print.skirt().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->skirt().entities.size() == 1);
}
}
THEN("brim generated") {
REQUIRE(print.brim().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->brim().entities.size() > 0);
}
REQUIRE(layers_with_brim.size() == 1);
}
THEN("skirt_height is honored") {
REQUIRE(layers_with_skirt.size() == (size_t)config->opt_int("skirt_height"));
}
}
WHEN("brim is requested") {
config->set_deserialize("skirts", "0");
config->set_deserialize("skirt_height", "3");
config->set_deserialize("brim_width", "4");
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, model, config);
std::map<double, bool> layers_with_skirt;
std::map<double, bool> layers_with_brim;
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
auto parser{ Slic3r::GCodeReader() };
parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{
if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) {
layers_with_skirt[self.z()] = 1;
}
if (line.extruding(self) && line.comment().find("brim") != std::string::npos) {
layers_with_brim[self.z()] = 1;
}
});
clean_file(gcode_filepath, "gcode");
THEN("no skrit") {
REQUIRE(print.skirt().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->skirt().entities.size() == 0);
}
}
THEN("brim generated") {
REQUIRE(print.brim().entities.size() == 0);
for (auto obj : print.objects()) {
REQUIRE(obj->brim().entities.size() > 0);
}
REQUIRE(layers_with_brim.size() == 1);
}
THEN("skirt_height is honored") {
REQUIRE(layers_with_skirt.size() == 0);
}
}
}
}
SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") {
GIVEN("Configuration with a skirt height of 2") {
auto config {Config::new_from_defaults()};
config->set("skirts", 1);
config->set("skirt_height", 2);
config->set("perimeters", 0);
config->set("support_material_speed", 99);
DynamicPrintConfig *config = Slic3r::DynamicPrintConfig::new_from_defaults();
config->set_deserialize("skirts", "1");
config->set_deserialize("skirt_height", "2");
config->set_deserialize("perimeters", "1");
config->set_deserialize("support_material_speed", "99");
config->set_key_value("gcode_comments", new ConfigOptionBool(true));
// avoid altering speeds unexpectedly
config->set("cooling", 0);
config->set("first_layer_speed", "100%");
config->set_deserialize("cooling", "0");
config->set_deserialize("first_layer_speed", "100%");
WHEN("multiple objects are printed") {
auto gcode {std::stringstream("")};
Slic3r::Model model;
auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20, TestMesh::cube_20x20x20}, model, config)};
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, model, config, false);
std::map<double, bool> layers_with_skirt;
Slic3r::Test::gcode(gcode, print);
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
auto parser {Slic3r::GCodeReader()};
parser.parse_stream(gcode, [&layers_with_skirt, &config] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
parser.parse_file(gcode_filepath, [&layers_with_skirt, &config] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
{
if (self.Z > 0) {
if (line.extruding() && line.new_F() == config->getFloat("support_material_speed") * 60.0) {
layers_with_skirt[self.Z] = 1;
}
if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) {
layers_with_skirt[self.z()] = 1;
}
//if (self.z() > 0) {
// if (line.extruding(self) && (line.new_F(self) == config->opt_float("support_material_speed") * 60.0) ) {
// layers_with_skirt[self.z()] = 1;
// }
//}
});
clean_file(gcode_filepath, "gcode");
THEN("skirt_height is honored") {
REQUIRE(layers_with_skirt.size() == (size_t)config->getInt("skirt_height"));
REQUIRE(layers_with_skirt.size() == (size_t)config->opt_int("skirt_height"));
}
}
}
GIVEN("A default configuration") {
auto config {Config::new_from_defaults()};
config->set("support_material_speed", 99);
DynamicPrintConfig *config = Slic3r::DynamicPrintConfig::new_from_defaults();
config->set_deserialize("support_material_speed", "99");
// avoid altering speeds unexpectedly
config->set("cooling", 0);
config->set("first_layer_speed", "100%");
config->set_deserialize("cooling", "0");
config->set_deserialize("first_layer_speed", "100%");
// remove noise from top/solid layers
config->set("top_solid_layers", 0);
config->set("bottom_solid_layers", 0);
config->set_deserialize("top_solid_layers", "0");
config->set_deserialize("bottom_solid_layers", "0");
WHEN("Brim width is set to 5") {
config->set("perimeters", 0);
config->set("skirts", 0);
config->set("brim_width", 5);
config->set_deserialize("perimeters", "0");
config->set_deserialize("skirts", "0");
config->set_deserialize("brim_width", "5");
THEN("Brim is generated") {
REQUIRE(false);
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20 }, model, config, false);
print.process();
REQUIRE(print.brim().entities.size()>0);
}
}
WHEN("Skirt area is smaller than the brim") {
config->set("skirts", 1);
config->set("brim_width", 10);
config->set_deserialize("skirts", "1");
config->set_deserialize("brim_width", "10");
THEN("GCode generates successfully.") {
REQUIRE(false);
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20 }, model, config, false);
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
std::string gcode_from_file = read_to_string(gcode_filepath);
REQUIRE(gcode_from_file.size() > 0);
clean_file(gcode_filepath, "gcode");
}
}
WHEN("Skirt height is 0 and skirts > 0") {
config->set("skirts", 2);
config->set("skirt_height", 0);
config->set_deserialize("skirts", "2");
config->set_deserialize("skirt_height", "0");
THEN("GCode generates successfully.") {
REQUIRE(false);
Model model{};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20 }, model, config, false);
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
std::string gcode_from_file = read_to_string(gcode_filepath);
REQUIRE(gcode_from_file.size() > 0);
clean_file(gcode_filepath, "gcode");
}
}
WHEN("Perimeter extruder = 2 and support extruders = 3") {
THEN("Brim is printed with the extruder used for the perimeters of first object") {
REQUIRE(false);
REQUIRE(true); //TODO
}
}
WHEN("Perimeter extruder = 2, support extruders = 3, raft is enabled") {
THEN("brim is printed with same extruder as skirt") {
REQUIRE(false);
REQUIRE(true); //TODO
}
}
WHEN("Object is plated with overhang support and a brim") {
config->set("layer_height", 0.4);
config->set("first_layer_height", 0.4);
config->set("skirts", 1);
config->set("skirt_distance", 0);
config->set("support_material_speed", 99);
config->set("perimeter_extruder", 1);
config->set("support_material_extruder", 2);
config->set("cooling", 0); // to prevent speeds to be altered
config->set("first_layer_speed", "100%"); // to prevent speeds to be altered
config->set_deserialize("layer_height", "0.4");
config->set_deserialize("first_layer_height", "0.4");
config->set_deserialize("skirts", "1");
config->set_deserialize("skirt_distance", "0");
config->set_deserialize("support_material_speed", "99");
config->set_deserialize("perimeter_extruder", "1");
config->set_deserialize("support_material_extruder", "2");
config->set_deserialize("cooling", "0"); // to prevent speeds to be altered
config->set_deserialize("first_layer_speed", "100%"); // to prevent speeds to be altered
Slic3r::Model model;
auto print {Slic3r::Test::init_print({TestMesh::overhang}, model, config)};
print->process();
Print print{};
Slic3r::Test::init_print(print, { TestMesh::overhang }, model, config, false);
print.process();
config->set("support_material", true); // to prevent speeds to be altered
config->set_deserialize("support_material", "true"); // to prevent speeds to be altered
THEN("skirt length is large enough to contain object with support") {
REQUIRE(false);
REQUIRE(true); //TODO
}
}
WHEN("Large minimum skirt length is used.") {
config->set("min_skirt_length", 20);
config->set_deserialize("min_skirt_length", "20");
auto gcode {std::stringstream("")};
Slic3r::Model model;
auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)};
Print print{};
Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20 }, model, config, false);
THEN("Gcode generation doesn't crash") {
Slic3r::Test::gcode(gcode, print);
auto exported {gcode.str()};
REQUIRE(exported.size() > 0);
std::string gcode_filepath{ "" };
Slic3r::Test::gcode(gcode_filepath, print);
std::string gcode_from_file = read_to_string(gcode_filepath);
REQUIRE(gcode_from_file.size() > 0);
clean_file(gcode_filepath, "gcode");
}
}
}