mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-09 00:31:19 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f140a1208 | ||
|
|
cb7d2c698d | ||
|
|
a38e6c61f2 |
@@ -311,7 +311,7 @@ function CreatePrinterBlock(OneModel)
|
|||||||
|
|
||||||
return '<div class="PrinterBlock" onClick="ChooseModel(\''+vendor+'\',\''+OneModel['model']+'\')">'+
|
return '<div class="PrinterBlock" onClick="ChooseModel(\''+vendor+'\',\''+OneModel['model']+'\')">'+
|
||||||
' <div class="PImg">'+
|
' <div class="PImg">'+
|
||||||
' <img class="ModelThumbnail" src="' + OneModel['cover'] + '" />'+
|
' <img class="ModelThumbnail" src="' + OneModel['cover'] + '" onerror="this.onerror=null;this.src=\'../img/printer-dummy.png\';"/>'+
|
||||||
' </div>'+
|
' </div>'+
|
||||||
' <div class="PrinterInfoMark">?</div>'+
|
' <div class="PrinterInfoMark">?</div>'+
|
||||||
' <div class="PrinterInfo">'+
|
' <div class="PrinterInfo">'+
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -83,6 +83,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <functional>
|
||||||
#include <gp_XY.hxx>
|
#include <gp_XY.hxx>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|||||||
@@ -261,6 +261,8 @@ set(lisbslic3r_sources
|
|||||||
GCode/PreciseSeam.cpp
|
GCode/PreciseSeam.cpp
|
||||||
GCode/PreciseSeam.hpp
|
GCode/PreciseSeam.hpp
|
||||||
GCode/PreciseSeamInternal.hpp
|
GCode/PreciseSeamInternal.hpp
|
||||||
|
#GCodeSender.cpp
|
||||||
|
#GCodeSender.hpp
|
||||||
GCode/SmallAreaInfillFlowCompensator.cpp
|
GCode/SmallAreaInfillFlowCompensator.cpp
|
||||||
GCode/SmallAreaInfillFlowCompensator.hpp
|
GCode/SmallAreaInfillFlowCompensator.hpp
|
||||||
GCode/SpiralVase.cpp
|
GCode/SpiralVase.cpp
|
||||||
@@ -445,6 +447,7 @@ set(lisbslic3r_sources
|
|||||||
SLA/SupportTreeBuildsteps.hpp
|
SLA/SupportTreeBuildsteps.hpp
|
||||||
SLA/SupportTree.cpp
|
SLA/SupportTree.cpp
|
||||||
SLA/SupportTree.hpp
|
SLA/SupportTree.hpp
|
||||||
|
#SLA/SupportTreeIGL.cpp
|
||||||
SLA/SupportTreeMesher.cpp
|
SLA/SupportTreeMesher.cpp
|
||||||
SLA/SupportTreeMesher.hpp
|
SLA/SupportTreeMesher.hpp
|
||||||
SlicesToTriangleMesh.cpp
|
SlicesToTriangleMesh.cpp
|
||||||
|
|||||||
@@ -2589,6 +2589,7 @@ void priv::create_face_types(FaceTypeMap &map,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include <CGAL/Polygon_mesh_processing/clip.h>
|
#include <CGAL/Polygon_mesh_processing/clip.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/corefinement.h>
|
||||||
bool priv::clip_cut(SurfacePatch &cut, CutMesh clipper)
|
bool priv::clip_cut(SurfacePatch &cut, CutMesh clipper)
|
||||||
{
|
{
|
||||||
CutMesh& tm = cut.mesh;
|
CutMesh& tm = cut.mesh;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "Emboss.hpp"
|
#include "Emboss.hpp"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <numeric>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <boost/nowide/convert.hpp>
|
#include <boost/nowide/convert.hpp>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#include "TDataStd_Name.hxx"
|
#include "TDataStd_Name.hxx"
|
||||||
#include "BRepBuilderAPI_Transform.hxx"
|
#include "BRepBuilderAPI_Transform.hxx"
|
||||||
#include "TopExp_Explorer.hxx"
|
#include "TopExp_Explorer.hxx"
|
||||||
|
#include "TopExp_Explorer.hxx"
|
||||||
#include "BRep_Tool.hxx"
|
#include "BRep_Tool.hxx"
|
||||||
#include "BRepTools.hxx"
|
#include "BRepTools.hxx"
|
||||||
#include <IMeshTools_Parameters.hxx>
|
#include <IMeshTools_Parameters.hxx>
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "Print.hpp"
|
#include "Print.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
|
#include "libslic3r.h"
|
||||||
#include "LocalesUtils.hpp"
|
#include "LocalesUtils.hpp"
|
||||||
#include "libslic3r/format.hpp"
|
#include "libslic3r/format.hpp"
|
||||||
#include "Time.hpp"
|
#include "Time.hpp"
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
#include "../PrintConfig.hpp"
|
#include "../PrintConfig.hpp"
|
||||||
#include "../Utils.hpp"
|
#include "../Utils.hpp"
|
||||||
#include "Print.hpp"
|
#include "Print.hpp"
|
||||||
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
|
#include "libslic3r/libslic3r.h"
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|||||||
@@ -0,0 +1,580 @@
|
|||||||
|
#include "GCodeSender.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <istream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
#include <boost/algorithm/string/trim.hpp>
|
||||||
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(__OpenBSD__)
|
||||||
|
#include <termios.h>
|
||||||
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <IOKit/serial/ioss.h>
|
||||||
|
#endif
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "/usr/include/asm-generic/ioctls.h"
|
||||||
|
|
||||||
|
/* The following definitions are kindly borrowed from:
|
||||||
|
/usr/include/asm-generic/termbits.h
|
||||||
|
Unfortunately we cannot just include that one because
|
||||||
|
it would redefine the "struct termios" already defined
|
||||||
|
the <termios.h> already included by Boost.ASIO. */
|
||||||
|
#define K_NCCS 19
|
||||||
|
struct termios2 {
|
||||||
|
tcflag_t c_iflag;
|
||||||
|
tcflag_t c_oflag;
|
||||||
|
tcflag_t c_cflag;
|
||||||
|
tcflag_t c_lflag;
|
||||||
|
cc_t c_line;
|
||||||
|
cc_t c_cc[K_NCCS];
|
||||||
|
speed_t c_ispeed;
|
||||||
|
speed_t c_ospeed;
|
||||||
|
};
|
||||||
|
#define BOTHER CBAUDEX
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define DEBUG_SERIAL
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
std::fstream fs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KEEP_SENT 20
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
GCodeSender::GCodeSender()
|
||||||
|
: io(), serial(io), can_send(false), sent(0), open(false), error(false),
|
||||||
|
connected(false), queue_paused(false)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
std::srand(std::time(nullptr));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
GCodeSender::~GCodeSender()
|
||||||
|
{
|
||||||
|
this->disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GCodeSender::connect(std::string devname, unsigned int baud_rate)
|
||||||
|
{
|
||||||
|
this->disconnect();
|
||||||
|
|
||||||
|
this->set_error_status(false);
|
||||||
|
try {
|
||||||
|
this->serial.open(devname);
|
||||||
|
|
||||||
|
this->serial.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::odd));
|
||||||
|
this->serial.set_option(boost::asio::serial_port_base::character_size(boost::asio::serial_port_base::character_size(8)));
|
||||||
|
this->serial.set_option(boost::asio::serial_port_base::flow_control(boost::asio::serial_port_base::flow_control::none));
|
||||||
|
this->serial.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));
|
||||||
|
this->set_baud_rate(baud_rate);
|
||||||
|
|
||||||
|
this->serial.close();
|
||||||
|
this->serial.open(devname);
|
||||||
|
this->serial.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none));
|
||||||
|
|
||||||
|
// set baud rate again because set_option overwrote it
|
||||||
|
this->set_baud_rate(baud_rate);
|
||||||
|
this->open = true;
|
||||||
|
this->reset();
|
||||||
|
} catch (boost::system::system_error &) {
|
||||||
|
this->set_error_status(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a reset firmware expect line numbers to start again from 1
|
||||||
|
this->sent = 0;
|
||||||
|
this->last_sent.clear();
|
||||||
|
|
||||||
|
/* Initialize debugger */
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
fs.open("serial.txt", std::fstream::out | std::fstream::trunc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// this gives some work to the io_service before it is started
|
||||||
|
// (post() runs the supplied function in its thread)
|
||||||
|
this->io.post(boost::bind(&GCodeSender::do_read, this));
|
||||||
|
|
||||||
|
// start reading in the background thread
|
||||||
|
boost::thread t(boost::bind(&boost::asio::io_service::run, &this->io));
|
||||||
|
this->background_thread.swap(t);
|
||||||
|
|
||||||
|
// always send a M105 to check for connection because firmware might be silent on connect
|
||||||
|
//FIXME Vojtech: This is being sent too early, leading to line number synchronization issues,
|
||||||
|
// from which the GCodeSender never recovers.
|
||||||
|
// this->send("M105", true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::set_baud_rate(unsigned int baud_rate)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// This does not support speeds > 115200
|
||||||
|
this->serial.set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
|
||||||
|
} catch (boost::system::system_error &) {
|
||||||
|
boost::asio::serial_port::native_handle_type handle = this->serial.native_handle();
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
termios ios;
|
||||||
|
::tcgetattr(handle, &ios);
|
||||||
|
::cfsetspeed(&ios, baud_rate);
|
||||||
|
speed_t newSpeed = baud_rate;
|
||||||
|
ioctl(handle, IOSSIOSPEED, &newSpeed);
|
||||||
|
::tcsetattr(handle, TCSANOW, &ios);
|
||||||
|
#elif __linux__
|
||||||
|
termios2 ios;
|
||||||
|
if (ioctl(handle, TCGETS2, &ios))
|
||||||
|
printf("Error in TCGETS2: %s\n", strerror(errno));
|
||||||
|
ios.c_ispeed = ios.c_ospeed = baud_rate;
|
||||||
|
ios.c_cflag &= ~CBAUD;
|
||||||
|
ios.c_cflag |= BOTHER | CLOCAL | CREAD;
|
||||||
|
ios.c_cc[VMIN] = 1; // Minimum of characters to read, prevents eof errors when 0 bytes are read
|
||||||
|
ios.c_cc[VTIME] = 1;
|
||||||
|
if (ioctl(handle, TCSETS2, &ios))
|
||||||
|
printf("Error in TCSETS2: %s\n", strerror(errno));
|
||||||
|
|
||||||
|
#elif __OpenBSD__
|
||||||
|
struct termios ios;
|
||||||
|
::tcgetattr(handle, &ios);
|
||||||
|
::cfsetspeed(&ios, baud_rate);
|
||||||
|
if (::tcsetattr(handle, TCSAFLUSH, &ios) != 0)
|
||||||
|
printf("Failed to set baud rate: %s\n", strerror(errno));
|
||||||
|
#else
|
||||||
|
//throw Slic3r::InvalidArgument("OS does not currently support custom bauds");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::disconnect()
|
||||||
|
{
|
||||||
|
if (!this->open) return;
|
||||||
|
this->open = false;
|
||||||
|
this->connected = false;
|
||||||
|
this->io.post(boost::bind(&GCodeSender::do_close, this));
|
||||||
|
this->background_thread.join();
|
||||||
|
this->io.reset();
|
||||||
|
/*
|
||||||
|
if (this->error_status()) {
|
||||||
|
throw(boost::system::system_error(boost::system::error_code(),
|
||||||
|
"Error while closing the device"));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
fs << "DISCONNECTED" << std::endl << std::flush;
|
||||||
|
fs.close();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GCodeSender::is_connected() const
|
||||||
|
{
|
||||||
|
return this->connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GCodeSender::wait_connected(unsigned int timeout) const
|
||||||
|
{
|
||||||
|
using namespace boost::posix_time;
|
||||||
|
ptime t0 = second_clock::local_time() + seconds(timeout);
|
||||||
|
while (!this->connected) {
|
||||||
|
if (second_clock::local_time() > t0) return false;
|
||||||
|
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
GCodeSender::queue_size() const
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
return this->queue.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::pause_queue()
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->queue_paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::resume_queue()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->queue_paused = false;
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::purge_queue(bool priority)
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
if (priority) {
|
||||||
|
// clear priority queue
|
||||||
|
std::list<std::string> empty;
|
||||||
|
std::swap(this->priqueue, empty);
|
||||||
|
} else {
|
||||||
|
// clear queue
|
||||||
|
std::queue<std::string> empty;
|
||||||
|
std::swap(this->queue, empty);
|
||||||
|
this->queue_paused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// purge log and return its contents
|
||||||
|
std::vector<std::string>
|
||||||
|
GCodeSender::purge_log()
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
||||||
|
std::vector<std::string> retval;
|
||||||
|
retval.reserve(this->log.size());
|
||||||
|
while (!this->log.empty()) {
|
||||||
|
retval.push_back(this->log.front());
|
||||||
|
this->log.pop();
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GCodeSender::getT() const
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
||||||
|
return this->T;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GCodeSender::getB() const
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
||||||
|
return this->B;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::do_close()
|
||||||
|
{
|
||||||
|
this->set_error_status(false);
|
||||||
|
boost::system::error_code ec;
|
||||||
|
this->serial.cancel(ec);
|
||||||
|
if (ec) this->set_error_status(true);
|
||||||
|
this->serial.close(ec);
|
||||||
|
if (ec) this->set_error_status(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::set_error_status(bool e)
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->error_mutex);
|
||||||
|
this->error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GCodeSender::error_status() const
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->error_mutex);
|
||||||
|
return this->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::do_read()
|
||||||
|
{
|
||||||
|
// read one line
|
||||||
|
boost::asio::async_read_until(
|
||||||
|
this->serial,
|
||||||
|
this->read_buffer,
|
||||||
|
'\n',
|
||||||
|
boost::bind(
|
||||||
|
&GCodeSender::on_read,
|
||||||
|
this,
|
||||||
|
boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::on_read(const boost::system::error_code& error,
|
||||||
|
size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
this->set_error_status(false);
|
||||||
|
if (error) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (error.value() == 45) {
|
||||||
|
// OS X bug: http://osdir.com/ml/lib.boost.asio.user/2008-08/msg00004.html
|
||||||
|
this->do_read();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// printf("ERROR: [%d] %s\n", error.value(), error.message().c_str());
|
||||||
|
// error can be true even because the serial port was closed.
|
||||||
|
// In this case it is not a real error, so ignore.
|
||||||
|
if (this->open) {
|
||||||
|
this->do_close();
|
||||||
|
this->set_error_status(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream is(&this->read_buffer);
|
||||||
|
std::string line;
|
||||||
|
std::getline(is, line);
|
||||||
|
if (!line.empty()) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
fs << "<< " << line << std::endl << std::flush;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// note that line might contain \r at its end
|
||||||
|
// parse incoming line
|
||||||
|
if (!this->connected
|
||||||
|
&& (boost::starts_with(line, "start")
|
||||||
|
|| boost::starts_with(line, "Grbl ")
|
||||||
|
|| boost::starts_with(line, "ok")
|
||||||
|
|| boost::contains(line, "T:"))) {
|
||||||
|
this->connected = true;
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->can_send = true;
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
} else if (boost::starts_with(line, "ok")) {
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
this->can_send = true;
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
} else if (boost::istarts_with(line, "resend") // Marlin uses "Resend: "
|
||||||
|
|| boost::istarts_with(line, "rs")) {
|
||||||
|
// extract the first number from line
|
||||||
|
boost::algorithm::trim_left_if(line, !boost::algorithm::is_digit());
|
||||||
|
size_t toresend = boost::lexical_cast<size_t>(line.substr(0, line.find_first_not_of("0123456789")));
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
fs << "!! line num out of sync: toresend = " << toresend << ", sent = " << sent << ", last_sent.size = " << last_sent.size() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (toresend > this->sent - this->last_sent.size() && toresend <= this->sent) {
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
|
||||||
|
const auto lines_to_resend = this->sent - toresend + 1;
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
fs << "!! resending " << lines_to_resend << " lines" << std::endl;
|
||||||
|
#endif
|
||||||
|
// move the unsent lines to priqueue
|
||||||
|
this->priqueue.insert(
|
||||||
|
this->priqueue.begin(), // insert at the beginning
|
||||||
|
this->last_sent.begin() + this->last_sent.size() - lines_to_resend,
|
||||||
|
this->last_sent.end()
|
||||||
|
);
|
||||||
|
|
||||||
|
// we can empty last_sent because it's not useful anymore
|
||||||
|
this->last_sent.clear();
|
||||||
|
|
||||||
|
// start resending with the requested line number
|
||||||
|
this->sent = toresend - 1;
|
||||||
|
this->can_send = true;
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
} else {
|
||||||
|
printf("Cannot resend %zu (oldest we have is %zu)\n", toresend, this->sent - this->last_sent.size());
|
||||||
|
}
|
||||||
|
} else if (boost::starts_with(line, "wait")) {
|
||||||
|
// ignore
|
||||||
|
} else {
|
||||||
|
// push any other line into the log
|
||||||
|
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
||||||
|
this->log.push(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse temperature info
|
||||||
|
{
|
||||||
|
size_t pos = line.find("T:");
|
||||||
|
if (pos != std::string::npos && line.size() > pos + 2) {
|
||||||
|
// we got temperature info
|
||||||
|
boost::lock_guard<boost::mutex> l(this->log_mutex);
|
||||||
|
this->T = line.substr(pos+2, line.find_first_not_of("0123456789.", pos+2) - (pos+2));
|
||||||
|
|
||||||
|
pos = line.find("B:");
|
||||||
|
if (pos != std::string::npos && line.size() > pos + 2) {
|
||||||
|
// we got bed temperature info
|
||||||
|
this->B = line.substr(pos+2, line.find_first_not_of("0123456789.", pos+2) - (pos+2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->do_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::send(const std::vector<std::string> &lines, bool priority)
|
||||||
|
{
|
||||||
|
// append lines to queue
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
for (std::vector<std::string>::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||||
|
if (priority) {
|
||||||
|
this->priqueue.push_back(*line);
|
||||||
|
} else {
|
||||||
|
this->queue.push(*line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::send(const std::string &line, bool priority)
|
||||||
|
{
|
||||||
|
// append line to queue
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
if (priority) {
|
||||||
|
this->priqueue.push_back(line);
|
||||||
|
} else {
|
||||||
|
this->queue.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::send()
|
||||||
|
{
|
||||||
|
this->io.post(boost::bind(&GCodeSender::do_send, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::do_send()
|
||||||
|
{
|
||||||
|
boost::lock_guard<boost::mutex> l(this->queue_mutex);
|
||||||
|
|
||||||
|
// printer is not connected or we're still waiting for the previous ack
|
||||||
|
if (!this->can_send) return;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (!this->priqueue.empty() || (!this->queue.empty() && !this->queue_paused)) {
|
||||||
|
if (!this->priqueue.empty()) {
|
||||||
|
line = this->priqueue.front();
|
||||||
|
this->priqueue.pop_front();
|
||||||
|
} else {
|
||||||
|
line = this->queue.front();
|
||||||
|
this->queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip comments
|
||||||
|
size_t comment_pos = line.find_first_of(';');
|
||||||
|
if (comment_pos != std::string::npos)
|
||||||
|
line.erase(comment_pos, std::string::npos);
|
||||||
|
boost::algorithm::trim(line);
|
||||||
|
|
||||||
|
// if line is not empty, send it
|
||||||
|
if (!line.empty()) break;
|
||||||
|
// if line is empty, process next item in queue
|
||||||
|
}
|
||||||
|
if (line.empty()) return;
|
||||||
|
|
||||||
|
// compute full line
|
||||||
|
++ this->sent;
|
||||||
|
#ifndef DEBUG_SERIAL
|
||||||
|
const auto line_num = this->sent;
|
||||||
|
#else
|
||||||
|
// In DEBUG_SERIAL mode, test line re-synchronization by sending bad line number 1/4 of the time
|
||||||
|
const auto line_num = std::rand() < RAND_MAX/4 ? 0 : this->sent;
|
||||||
|
#endif
|
||||||
|
std::string full_line = "N" + boost::lexical_cast<std::string>(line_num) + " " + line;
|
||||||
|
|
||||||
|
// calculate checksum
|
||||||
|
int cs = 0;
|
||||||
|
for (std::string::const_iterator it = full_line.begin(); it != full_line.end(); ++it)
|
||||||
|
cs = cs ^ *it;
|
||||||
|
|
||||||
|
// write line to device
|
||||||
|
full_line += "*";
|
||||||
|
full_line += boost::lexical_cast<std::string>(cs);
|
||||||
|
full_line += "\n";
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
fs << ">> " << full_line << std::flush;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this->last_sent.push_back(line);
|
||||||
|
this->can_send = false;
|
||||||
|
|
||||||
|
while (this->last_sent.size() > KEEP_SENT) {
|
||||||
|
this->last_sent.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can't supply boost::asio::buffer(full_line) to async_write() because full_line is on the
|
||||||
|
// stack and the buffer would lose its underlying storage causing memory corruption
|
||||||
|
std::ostream os(&this->write_buffer);
|
||||||
|
os << full_line;
|
||||||
|
boost::asio::async_write(this->serial, this->write_buffer, boost::bind(&GCodeSender::on_write, this, boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::on_write(const boost::system::error_code& error,
|
||||||
|
size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
this->set_error_status(false);
|
||||||
|
if (error) {
|
||||||
|
if (this->open) {
|
||||||
|
this->do_close();
|
||||||
|
this->set_error_status(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->do_send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::set_DTR(bool on)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) && !defined(__SYMBIAN32__)
|
||||||
|
boost::asio::serial_port_service::native_handle_type handle = this->serial.native_handle();
|
||||||
|
if (on)
|
||||||
|
EscapeCommFunction(handle, SETDTR);
|
||||||
|
else
|
||||||
|
EscapeCommFunction(handle, CLRDTR);
|
||||||
|
#else
|
||||||
|
int fd = this->serial.native_handle();
|
||||||
|
int status;
|
||||||
|
ioctl(fd, TIOCMGET, &status);
|
||||||
|
if (on)
|
||||||
|
status |= TIOCM_DTR;
|
||||||
|
else
|
||||||
|
status &= ~TIOCM_DTR;
|
||||||
|
ioctl(fd, TIOCMSET, &status);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCodeSender::reset()
|
||||||
|
{
|
||||||
|
set_DTR(false);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
set_DTR(true);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
set_DTR(false);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#ifndef slic3r_GCodeSender_hpp_
|
||||||
|
#define slic3r_GCodeSender_hpp_
|
||||||
|
|
||||||
|
#include "libslic3r.h"
|
||||||
|
#include <queue>
|
||||||
|
#include <boost/core/noncopyable.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <boost/asio/io_service.hpp>
|
||||||
|
#include <boost/asio/serial_port.hpp>
|
||||||
|
#include <boost/asio/streambuf.hpp>
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/bind/bind.hpp>
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
namespace asio = boost::asio;
|
||||||
|
|
||||||
|
class GCodeSender : private boost::noncopyable {
|
||||||
|
public:
|
||||||
|
GCodeSender();
|
||||||
|
~GCodeSender();
|
||||||
|
bool connect(std::string devname, unsigned int baud_rate);
|
||||||
|
void send(const std::vector<std::string> &lines, bool priority = false);
|
||||||
|
void send(const std::string &s, bool priority = false);
|
||||||
|
void disconnect();
|
||||||
|
bool error_status() const;
|
||||||
|
bool is_connected() const;
|
||||||
|
bool wait_connected(unsigned int timeout = 3) const;
|
||||||
|
size_t queue_size() const;
|
||||||
|
void pause_queue();
|
||||||
|
void resume_queue();
|
||||||
|
void purge_queue(bool priority = false);
|
||||||
|
std::vector<std::string> purge_log();
|
||||||
|
std::string getT() const;
|
||||||
|
std::string getB() const;
|
||||||
|
void set_DTR(bool on);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
asio::io_service io;
|
||||||
|
asio::serial_port serial;
|
||||||
|
boost::thread background_thread;
|
||||||
|
boost::asio::streambuf read_buffer, write_buffer;
|
||||||
|
bool open; // whether the serial socket is connected
|
||||||
|
bool connected; // whether the printer is online
|
||||||
|
bool error;
|
||||||
|
mutable boost::mutex error_mutex;
|
||||||
|
|
||||||
|
// this mutex guards queue, priqueue, can_send, queue_paused, sent, last_sent
|
||||||
|
mutable boost::mutex queue_mutex;
|
||||||
|
std::queue<std::string> queue;
|
||||||
|
std::list<std::string> priqueue;
|
||||||
|
bool can_send;
|
||||||
|
bool queue_paused;
|
||||||
|
size_t sent;
|
||||||
|
std::deque<std::string> last_sent;
|
||||||
|
|
||||||
|
// this mutex guards log, T, B
|
||||||
|
mutable boost::mutex log_mutex;
|
||||||
|
std::queue<std::string> log;
|
||||||
|
std::string T, B;
|
||||||
|
|
||||||
|
void set_baud_rate(unsigned int baud_rate);
|
||||||
|
void set_error_status(bool e);
|
||||||
|
void do_send();
|
||||||
|
void on_write(const boost::system::error_code& error, size_t bytes_transferred);
|
||||||
|
void do_close();
|
||||||
|
void do_read();
|
||||||
|
void on_read(const boost::system::error_code& error, size_t bytes_transferred);
|
||||||
|
void send();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif /* slic3r_GCodeSender_hpp_ */
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include "MedialAxis.hpp"
|
#include "MedialAxis.hpp"
|
||||||
|
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
#include <boost/polygon/polygon.hpp>
|
#include <boost/polygon/polygon.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "Format/AssimpImport.hpp"
|
#include "Format/AssimpImport.hpp"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
#include "Exception.hpp"
|
#include "Exception.hpp"
|
||||||
|
#include "Model.hpp"
|
||||||
#include "ModelArrange.hpp"
|
#include "ModelArrange.hpp"
|
||||||
#include "Arrange.hpp"
|
#include "Arrange.hpp"
|
||||||
#include "Geometry.hpp"
|
#include "Geometry.hpp"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "TriangleMesh.hpp"
|
#include "TriangleMesh.hpp"
|
||||||
#include "CustomGCode.hpp"
|
#include "CustomGCode.hpp"
|
||||||
#include "calib.hpp"
|
#include "calib.hpp"
|
||||||
|
#include "enum_bitmask.hpp"
|
||||||
#include "TextConfiguration.hpp"
|
#include "TextConfiguration.hpp"
|
||||||
#include "EmbossShape.hpp"
|
#include "EmbossShape.hpp"
|
||||||
#include "TriangleSelector.hpp"
|
#include "TriangleSelector.hpp"
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "TDataStd_Name.hxx"
|
#include "TDataStd_Name.hxx"
|
||||||
#include "BRepBuilderAPI_Transform.hxx"
|
#include "BRepBuilderAPI_Transform.hxx"
|
||||||
#include "TopExp_Explorer.hxx"
|
#include "TopExp_Explorer.hxx"
|
||||||
|
#include "TopExp_Explorer.hxx"
|
||||||
#include "BRep_Tool.hxx"
|
#include "BRep_Tool.hxx"
|
||||||
#include "Font_BRepFont.hxx"
|
#include "Font_BRepFont.hxx"
|
||||||
#include "Font_BRepTextBuilder.hxx"
|
#include "Font_BRepTextBuilder.hxx"
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string_view>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/dataview.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/wrapsizer.h>
|
#include <wx/wrapsizer.h>
|
||||||
|
|
||||||
#include "GUI_Utils.hpp"
|
#include "GUI_Utils.hpp"
|
||||||
|
|||||||
@@ -19,17 +19,20 @@
|
|||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
#include <wx/settings.h>
|
#include <wx/settings.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
#include <wx/grid.h>
|
#include <wx/grid.h>
|
||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
#include <wx/image.h>
|
#include <wx/image.h>
|
||||||
#include <wx/icon.h>
|
#include <wx/icon.h>
|
||||||
|
#include <wx/bmpbuttn.h>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
#include <wx/statbox.h>
|
#include <wx/statbox.h>
|
||||||
#include <wx/tglbtn.h>
|
#include <wx/tglbtn.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
#include <wx/settings.h>
|
#include <wx/settings.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
#include <wx/grid.h>
|
#include <wx/grid.h>
|
||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
@@ -35,12 +36,14 @@
|
|||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
#include <wx/image.h>
|
#include <wx/image.h>
|
||||||
#include <wx/icon.h>
|
#include <wx/icon.h>
|
||||||
|
#include <wx/bmpbuttn.h>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
#include <wx/gbsizer.h>
|
#include <wx/gbsizer.h>
|
||||||
#include <wx/statbox.h>
|
#include <wx/statbox.h>
|
||||||
#include <wx/tglbtn.h>
|
#include <wx/tglbtn.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/webrequest.h>
|
#include <wx/webrequest.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "Jobs/ProgressIndicator.hpp"
|
#include "Jobs/ProgressIndicator.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include "Jobs/ProgressIndicator.hpp"
|
#include "Jobs/ProgressIndicator.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
#include <wx/hyperlink.h>
|
#include <wx/hyperlink.h>
|
||||||
|
|
||||||
#include "Jobs/ProgressIndicator.hpp"
|
#include "Jobs/ProgressIndicator.hpp"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
#include <wx/hyperlink.h>
|
#include <wx/hyperlink.h>
|
||||||
|
|
||||||
#include "Jobs/ProgressIndicator.hpp"
|
#include "Jobs/ProgressIndicator.hpp"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <wx/toplevel.h>
|
#include <wx/toplevel.h>
|
||||||
#include <wx/timer.h>
|
#include <wx/timer.h>
|
||||||
|
#include "Widgets/Button.hpp"
|
||||||
#include "CapsuleButton.hpp"
|
#include "CapsuleButton.hpp"
|
||||||
|
|
||||||
namespace Slic3r::GUI { struct IntEvent; }
|
namespace Slic3r::GUI { struct IntEvent; }
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
#include "libslic3r/Polygon.hpp"
|
#include "libslic3r/Polygon.hpp"
|
||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
#include "Plater.hpp"
|
#include "Plater.hpp"
|
||||||
#include "Jobs/BoostThreadWorker.hpp"
|
#include "Jobs/BoostThreadWorker.hpp"
|
||||||
#include "Jobs/PlaterWorker.hpp"
|
#include "Jobs/PlaterWorker.hpp"
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
#include "slic3r/GUI/format.hpp"
|
#include "slic3r/GUI/format.hpp"
|
||||||
|
#include "slic3r/Utils/Bonjour.hpp"
|
||||||
|
|
||||||
#include "slic3r/GUI/Widgets/DialogButtons.hpp"
|
#include "slic3r/GUI/Widgets/DialogButtons.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/dataview.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/wrapsizer.h>
|
#include <wx/wrapsizer.h>
|
||||||
|
|
||||||
#include "GUI_Utils.hpp"
|
#include "GUI_Utils.hpp"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// #include "libslic3r/GCodeSender.hpp"
|
||||||
#include "ConfigManipulation.hpp"
|
#include "ConfigManipulation.hpp"
|
||||||
#include "I18N.hpp"
|
#include "I18N.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "DeviceErrorDialog.hpp"
|
#include "DeviceErrorDialog.hpp"
|
||||||
#include "Plater.hpp"
|
#include "Plater.hpp"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
#include "ReleaseNote.hpp"
|
#include "ReleaseNote.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "nanosvg/nanosvgrast.h"
|
#include "nanosvg/nanosvgrast.h"
|
||||||
|
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <wx/dcgraph.h>
|
#include <wx/dcgraph.h>
|
||||||
#include <wx/dcmemory.h>
|
#include <wx/dcmemory.h>
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include "AboutDialog.hpp"
|
#include "AboutDialog.hpp"
|
||||||
#include "MsgDialog.hpp"
|
#include "MsgDialog.hpp"
|
||||||
#include "Plater.hpp"
|
#include "Plater.hpp"
|
||||||
|
#include "format.hpp"
|
||||||
|
|
||||||
#include "WebUserLoginDialog.hpp"
|
#include "WebUserLoginDialog.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -172,10 +172,12 @@
|
|||||||
|
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
|
#include "libslic3r/I18N.hpp"
|
||||||
#include "libslic3r/PresetBundle.hpp"
|
#include "libslic3r/PresetBundle.hpp"
|
||||||
#include "libslic3r/InstanceLock.hpp"
|
#include "libslic3r/InstanceLock.hpp"
|
||||||
#include "libslic3r/Thread.hpp"
|
#include "libslic3r/Thread.hpp"
|
||||||
#include "libslic3r/miniz_extension.hpp"
|
#include "libslic3r/miniz_extension.hpp"
|
||||||
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "slic3r/plugin/PluginManager.hpp"
|
#include "slic3r/plugin/PluginManager.hpp"
|
||||||
#include "slic3r/plugin/host/PluginHostUi.hpp"
|
#include "slic3r/plugin/host/PluginHostUi.hpp"
|
||||||
#include "slic3r/plugin/PythonInterpreter.hpp"
|
#include "slic3r/plugin/PythonInterpreter.hpp"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "libslic3r/Config.hpp"
|
#include "libslic3r/Config.hpp"
|
||||||
#include "libslic3r/PresetBundle.hpp"
|
#include "libslic3r/PresetBundle.hpp"
|
||||||
#include "libslic3r/Preset.hpp"
|
#include "libslic3r/Preset.hpp"
|
||||||
|
#include "libslic3r/Config.hpp"
|
||||||
#include "libslic3r/PrintConfig.hpp"
|
#include "libslic3r/PrintConfig.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
#include <nanosvg/nanosvg.h>
|
#include <nanosvg/nanosvg.h>
|
||||||
#include <nanosvg/nanosvgrast.h>
|
#include <nanosvg/nanosvgrast.h>
|
||||||
#include "OpenGLManager.hpp"
|
#include "OpenGLManager.hpp"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|||||||
@@ -113,6 +113,7 @@
|
|||||||
#include "MsgDialog.hpp"
|
#include "MsgDialog.hpp"
|
||||||
#include "Notebook.hpp"
|
#include "Notebook.hpp"
|
||||||
#include "GUI_Factories.hpp"
|
#include "GUI_Factories.hpp"
|
||||||
|
#include "GUI_ObjectList.hpp"
|
||||||
#include "NotificationManager.hpp"
|
#include "NotificationManager.hpp"
|
||||||
#include "MarkdownTip.hpp"
|
#include "MarkdownTip.hpp"
|
||||||
#include "NetworkTestDialog.hpp"
|
#include "NetworkTestDialog.hpp"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "wx/evtloop.h"
|
#include "wx/evtloop.h"
|
||||||
|
|
||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
#include "Plater.hpp"
|
#include "Plater.hpp"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
#include "MediaPlayCtrl.h"
|
#include "MediaPlayCtrl.h"
|
||||||
#include "MediaFilePanel.h"
|
#include "MediaFilePanel.h"
|
||||||
|
#include "Plater.hpp"
|
||||||
#include "BindDialog.hpp"
|
#include "BindDialog.hpp"
|
||||||
|
|
||||||
#include "DeviceCore/DevManager.h"
|
#include "DeviceCore/DevManager.h"
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
#include <wx/settings.h>
|
#include <wx/settings.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
#include <wx/grid.h>
|
#include <wx/grid.h>
|
||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
@@ -30,12 +31,14 @@
|
|||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
#include <wx/image.h>
|
#include <wx/image.h>
|
||||||
#include <wx/icon.h>
|
#include <wx/icon.h>
|
||||||
|
#include <wx/bmpbuttn.h>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
#include <wx/gbsizer.h>
|
#include <wx/gbsizer.h>
|
||||||
#include <wx/statbox.h>
|
#include <wx/statbox.h>
|
||||||
#include <wx/tglbtn.h>
|
#include <wx/tglbtn.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/webrequest.h>
|
#include <wx/webrequest.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
|
#include "I18N.hpp"
|
||||||
#include "libslic3r_version.h"
|
#include "libslic3r_version.h"
|
||||||
#include "slic3r/Utils/Http.hpp"
|
#include "slic3r/Utils/Http.hpp"
|
||||||
#include "libslic3r/AppConfig.hpp"
|
#include "libslic3r/AppConfig.hpp"
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
#include <miniz.h>
|
#include <miniz.h>
|
||||||
#include <OrcaCloudServiceAgent.hpp>
|
#include <OrcaCloudServiceAgent.hpp>
|
||||||
|
#include <wx/event.h>
|
||||||
#include <wx/utils.h>
|
#include <wx/utils.h>
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|||||||
@@ -79,6 +79,7 @@
|
|||||||
#include "libslic3r_version.h"
|
#include "libslic3r_version.h"
|
||||||
#include "wxExtensions.hpp"
|
#include "wxExtensions.hpp"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
#include "libslic3r/Preset.hpp"
|
#include "libslic3r/Preset.hpp"
|
||||||
#include "libslic3r/PresetBundle.hpp"
|
#include "libslic3r/PresetBundle.hpp"
|
||||||
#include "slic3r/GUI/Widgets/Button.hpp"
|
#include "slic3r/GUI/Widgets/Button.hpp"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "Jobs/ProgressIndicator.hpp"
|
#include "Jobs/ProgressIndicator.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/dataview.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
@@ -31,8 +32,10 @@
|
|||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/wrapsizer.h>
|
#include <wx/wrapsizer.h>
|
||||||
#include <wx/event.h>
|
#include <wx/event.h>
|
||||||
|
#include <wx/hyperlink.h>
|
||||||
#include <wx/richtext/richtextctrl.h>
|
#include <wx/richtext/richtextctrl.h>
|
||||||
|
|
||||||
#include "AmsMappingPopup.hpp"
|
#include "AmsMappingPopup.hpp"
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/dataview.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
@@ -37,6 +38,7 @@
|
|||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/wrapsizer.h>
|
#include <wx/wrapsizer.h>
|
||||||
#include <wx/srchctrl.h>
|
#include <wx/srchctrl.h>
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/dataview.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/wrapsizer.h>
|
#include <wx/wrapsizer.h>
|
||||||
#include <wx/srchctrl.h>
|
#include <wx/srchctrl.h>
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <wx/dataview.h>
|
#include <wx/dataview.h>
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/dataview.h>
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
#include <wx/font.h>
|
#include <wx/font.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#include <wx/popupwin.h>
|
#include <wx/popupwin.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/artprov.h>
|
||||||
#include <wx/wrapsizer.h>
|
#include <wx/wrapsizer.h>
|
||||||
#include <wx/srchctrl.h>
|
#include <wx/srchctrl.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// #include "libslic3r/GCodeSender.hpp"
|
||||||
//#include "slic3r/Utils/Serial.hpp"
|
//#include "slic3r/Utils/Serial.hpp"
|
||||||
#include "Tab.hpp"
|
#include "Tab.hpp"
|
||||||
#include "PresetHints.hpp"
|
#include "PresetHints.hpp"
|
||||||
@@ -101,6 +102,8 @@
|
|||||||
#include "Widgets/MultiNozzleSync.hpp"
|
#include "Widgets/MultiNozzleSync.hpp"
|
||||||
#include "Widgets/SwitchButton.hpp"
|
#include "Widgets/SwitchButton.hpp"
|
||||||
#include "Widgets/TabCtrl.hpp"
|
#include "Widgets/TabCtrl.hpp"
|
||||||
|
#include "Widgets/ComboBox.hpp"
|
||||||
|
#include "Search.hpp"
|
||||||
#include "BedShapeDialog.hpp"
|
#include "BedShapeDialog.hpp"
|
||||||
#include "libslic3r/GCode/Thumbnails.hpp"
|
#include "libslic3r/GCode/Thumbnails.hpp"
|
||||||
#include "WipeTowerDialog.hpp"
|
#include "WipeTowerDialog.hpp"
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#include "../GUI/DeviceCore/DevConfig.h"
|
#include "../GUI/DeviceCore/DevConfig.h"
|
||||||
#include "../GUI/DeviceCore/DevExtruderSystem.h"
|
#include "../GUI/DeviceCore/DevExtruderSystem.h"
|
||||||
#include "../GUI/DeviceCore/DevManager.h"
|
#include "../GUI/DeviceCore/DevManager.h"
|
||||||
|
#include "../GUI/DeviceCore/DevStorage.h"
|
||||||
|
#include "libslic3r/FlushVolCalc.hpp"
|
||||||
#include "../GUI/Plater.hpp"
|
#include "../GUI/Plater.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "slic3r/GUI/Jobs/Worker.hpp"
|
#include "slic3r/GUI/Jobs/Worker.hpp"
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ void StyleManager::init_trunc_names(float max_width) {
|
|||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
|
||||||
// for get DPI
|
// for get DPI
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/MainFrame.hpp"
|
#include "slic3r/GUI/MainFrame.hpp"
|
||||||
#include "slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp"
|
#include "slic3r/GUI/Gizmos/GizmoObjectManipulation.hpp"
|
||||||
|
|
||||||
@@ -553,6 +554,8 @@ bool StyleManager::set_wx_font(const wxFont &wx_font, std::unique_ptr<FontFile>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <libslic3r/AppConfig.hpp>
|
||||||
|
#include "WxFontUtils.hpp"
|
||||||
#include "fast_float/fast_float.h"
|
#include "fast_float/fast_float.h"
|
||||||
|
|
||||||
// StylesSerializable
|
// StylesSerializable
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
#include "slic3r/GUI/UpdateDialogs.hpp"
|
#include "slic3r/GUI/UpdateDialogs.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
#include "slic3r/GUI/format.hpp"
|
#include "slic3r/GUI/format.hpp"
|
||||||
#include "slic3r/GUI/NotificationManager.hpp"
|
#include "slic3r/GUI/NotificationManager.hpp"
|
||||||
|
|||||||
@@ -25,11 +25,19 @@ extern const char* const INSTALL_STATE_FILE;
|
|||||||
// Plugin config and orca.host.ui payloads both cross the boundary as plain JSON-compatible
|
// Plugin config and orca.host.ui payloads both cross the boundary as plain JSON-compatible
|
||||||
// values, so both go through these.
|
// values, so both go through these.
|
||||||
|
|
||||||
inline pybind11::object json_to_py(const nlohmann::json& j)
|
// Maximum nesting depth for JSON <-> Python conversion. A self-referential or pathologically
|
||||||
|
// deep value would otherwise recurse until the native C stack overflows, an uncatchable crash;
|
||||||
|
// past this bound we raise instead. 200 is far beyond any legitimate plugin config or UI payload.
|
||||||
|
inline constexpr int kMaxJsonConversionDepth = 200;
|
||||||
|
|
||||||
|
inline pybind11::object json_to_py(const nlohmann::json& j, int depth = 0)
|
||||||
{
|
{
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
if (depth > kMaxJsonConversionDepth)
|
||||||
|
throw py::value_error("Plugin JSON value nested too deeply");
|
||||||
|
|
||||||
switch (j.type()) {
|
switch (j.type()) {
|
||||||
case json::value_t::null: return py::none();
|
case json::value_t::null: return py::none();
|
||||||
case json::value_t::boolean: return py::bool_(j.get<bool>());
|
case json::value_t::boolean: return py::bool_(j.get<bool>());
|
||||||
@@ -40,24 +48,27 @@ inline pybind11::object json_to_py(const nlohmann::json& j)
|
|||||||
case json::value_t::array: {
|
case json::value_t::array: {
|
||||||
py::list lst;
|
py::list lst;
|
||||||
for (const auto& e : j)
|
for (const auto& e : j)
|
||||||
lst.append(json_to_py(e));
|
lst.append(json_to_py(e, depth + 1));
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
case json::value_t::object: {
|
case json::value_t::object: {
|
||||||
py::dict d;
|
py::dict d;
|
||||||
for (auto it = j.begin(); it != j.end(); ++it)
|
for (auto it = j.begin(); it != j.end(); ++it)
|
||||||
d[py::str(it.key())] = json_to_py(it.value());
|
d[py::str(it.key())] = json_to_py(it.value(), depth + 1);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
default: return py::none();
|
default: return py::none();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline nlohmann::json py_to_json(const pybind11::handle& o)
|
inline nlohmann::json py_to_json(const pybind11::handle& o, int depth = 0)
|
||||||
{
|
{
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
if (depth > kMaxJsonConversionDepth)
|
||||||
|
throw py::value_error("Plugin value nested too deeply (possible cycle)");
|
||||||
|
|
||||||
if (o.is_none())
|
if (o.is_none())
|
||||||
return json(nullptr);
|
return json(nullptr);
|
||||||
if (py::isinstance<py::bool_>(o)) // bool before int (bool subclasses int in Python)
|
if (py::isinstance<py::bool_>(o)) // bool before int (bool subclasses int in Python)
|
||||||
@@ -73,13 +84,13 @@ inline nlohmann::json py_to_json(const pybind11::handle& o)
|
|||||||
if (py::isinstance<py::dict>(o)) {
|
if (py::isinstance<py::dict>(o)) {
|
||||||
json obj = json::object();
|
json obj = json::object();
|
||||||
for (auto item : py::reinterpret_borrow<py::dict>(o))
|
for (auto item : py::reinterpret_borrow<py::dict>(o))
|
||||||
obj[py::str(item.first).cast<std::string>()] = py_to_json(item.second);
|
obj[py::str(item.first).cast<std::string>()] = py_to_json(item.second, depth + 1);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
if (py::isinstance<py::list>(o) || py::isinstance<py::tuple>(o)) {
|
if (py::isinstance<py::list>(o) || py::isinstance<py::tuple>(o)) {
|
||||||
json arr = json::array();
|
json arr = json::array();
|
||||||
for (auto e : o)
|
for (auto e : o)
|
||||||
arr.push_back(py_to_json(e));
|
arr.push_back(py_to_json(e, depth + 1));
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
return py::str(o).cast<std::string>(); // fallback: str()
|
return py::str(o).cast<std::string>(); // fallback: str()
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ add_executable(${_TEST_NAME}_tests
|
|||||||
test_plugin_sort.cpp
|
test_plugin_sort.cpp
|
||||||
test_plugin_cloud_metadata.cpp
|
test_plugin_cloud_metadata.cpp
|
||||||
test_plugin_audit.cpp
|
test_plugin_audit.cpp
|
||||||
|
test_plugin_json_depth.cpp
|
||||||
test_shortcuts.cpp
|
test_shortcuts.cpp
|
||||||
test_file_url.cpp
|
test_file_url.cpp
|
||||||
test_user_manager.cpp
|
test_user_manager.cpp
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#include <catch2/catch_all.hpp>
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include <slic3r/plugin/PluginFsUtils.hpp>
|
||||||
|
#include <slic3r/plugin/PluginManager.hpp>
|
||||||
|
#include <slic3r/plugin/PythonInterpreter.hpp>
|
||||||
|
|
||||||
|
#include "plugin_test_utils.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <exception>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <pybind11/embed.h>
|
||||||
|
#include <pybind11/gil.h>
|
||||||
|
#include <pybind11/pytypes.h>
|
||||||
|
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Brings the embedded interpreter up for one test and tears it down before boost::log does,
|
||||||
|
// mirroring the ScopedPluginManager idiom in the other plugin tests.
|
||||||
|
struct ScopedPluginManager
|
||||||
|
{
|
||||||
|
ScopedDataDir python_data_dir{"plugin-json-depth"};
|
||||||
|
bool initialized = PluginManager::instance().initialize();
|
||||||
|
~ScopedPluginManager()
|
||||||
|
{
|
||||||
|
PluginManager::instance().shutdown();
|
||||||
|
PythonInterpreter::instance().shutdown();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("py_to_json raises instead of overflowing on pathologically deep input", "[PluginHost][Python]")
|
||||||
|
{
|
||||||
|
ScopedPluginManager manager;
|
||||||
|
REQUIRE(manager.initialized);
|
||||||
|
namespace py = pybind11;
|
||||||
|
py::gil_scoped_acquire gil;
|
||||||
|
|
||||||
|
// [[[ ... 0 ... ]]] nested 300 deep: past the 200 conversion-depth cap, but shallow enough
|
||||||
|
// that the pre-fix code returns without crashing, so a regression fails cleanly rather than
|
||||||
|
// taking the process down. Built in C++ so the test does not depend on Python builtins.
|
||||||
|
py::object deep = py::int_(0);
|
||||||
|
for (int i = 0; i < 300; ++i) {
|
||||||
|
py::list wrapper;
|
||||||
|
wrapper.append(deep);
|
||||||
|
deep = std::move(wrapper);
|
||||||
|
}
|
||||||
|
CHECK_THROWS_AS(py_to_json(deep), std::exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("py_to_json still converts reasonably nested input", "[PluginHost][Python]")
|
||||||
|
{
|
||||||
|
ScopedPluginManager manager;
|
||||||
|
REQUIRE(manager.initialized);
|
||||||
|
namespace py = pybind11;
|
||||||
|
py::gil_scoped_acquire gil;
|
||||||
|
|
||||||
|
py::dict d;
|
||||||
|
d["a"] = py::int_(1);
|
||||||
|
py::list inner;
|
||||||
|
inner.append(py::str("x"));
|
||||||
|
inner.append(py::int_(2));
|
||||||
|
d["b"] = inner;
|
||||||
|
|
||||||
|
const nlohmann::json j = py_to_json(d);
|
||||||
|
CHECK(j.at("a").get<std::int64_t>() == 1);
|
||||||
|
CHECK(j.at("b").at(0).get<std::string>() == "x");
|
||||||
|
CHECK(j.at("b").at(1).get<std::int64_t>() == 2);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user