mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 16:51:21 -06:00
Merge remote-tracking branch 'origin/master' into ys_selection
This commit is contained in:
commit
d806e8e5e1
42 changed files with 1101 additions and 820 deletions
|
@ -333,6 +333,13 @@ Transform3d GLVolume::world_matrix() const
|
|||
return m;
|
||||
}
|
||||
|
||||
bool GLVolume::is_left_handed() const
|
||||
{
|
||||
const Vec3d &m1 = m_instance_transformation.get_mirror();
|
||||
const Vec3d &m2 = m_volume_transformation.get_mirror();
|
||||
return m1.x() * m1.y() * m1.z() * m2.x() * m2.y() * m2.z() < 0.;
|
||||
}
|
||||
|
||||
const BoundingBoxf3& GLVolume::transformed_bounding_box() const
|
||||
{
|
||||
assert(bounding_box.defined || bounding_box.min(0) >= bounding_box.max(0) || bounding_box.min(1) >= bounding_box.max(1) || bounding_box.min(2) >= bounding_box.max(2));
|
||||
|
@ -401,6 +408,8 @@ void GLVolume::render() const
|
|||
if (!is_active)
|
||||
return;
|
||||
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
glsafe(::glCullFace(GL_BACK));
|
||||
glsafe(::glPushMatrix());
|
||||
|
||||
|
@ -410,6 +419,8 @@ void GLVolume::render() const
|
|||
else
|
||||
this->indexed_vertex_array.render();
|
||||
glsafe(::glPopMatrix());
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) const
|
||||
|
@ -420,6 +431,9 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
|
|||
if (!indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)
|
||||
return;
|
||||
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first));
|
||||
GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
|
||||
if (n_triangles + n_quads == 0)
|
||||
|
@ -481,6 +495,9 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
|
|||
}
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
void GLVolume::render_legacy() const
|
||||
|
@ -489,6 +506,9 @@ void GLVolume::render_legacy() const
|
|||
if (!is_active)
|
||||
return;
|
||||
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first));
|
||||
GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
|
||||
if (n_triangles + n_quads == 0)
|
||||
|
@ -520,6 +540,9 @@ void GLVolume::render_legacy() const
|
|||
glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first));
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
if (this->is_left_handed())
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
std::vector<int> GLVolumeCollection::load_object(
|
||||
|
|
|
@ -388,6 +388,7 @@ public:
|
|||
int instance_idx() const { return this->composite_id.instance_id; }
|
||||
|
||||
Transform3d world_matrix() const;
|
||||
bool is_left_handed() const;
|
||||
|
||||
const BoundingBoxf3& transformed_bounding_box() const;
|
||||
const BoundingBoxf3& transformed_convex_hull_bounding_box() const;
|
||||
|
|
|
@ -59,6 +59,8 @@ enum {
|
|||
USB_PID_MK3 = 2,
|
||||
USB_PID_MMU_BOOT = 3,
|
||||
USB_PID_MMU_APP = 4,
|
||||
USB_PID_CW1_BOOT = 7,
|
||||
USB_PID_CW1_APP = 8,
|
||||
};
|
||||
|
||||
// This enum discriminates the kind of information in EVT_AVRDUDE,
|
||||
|
@ -77,6 +79,13 @@ wxDEFINE_EVENT(EVT_AVRDUDE, wxCommandEvent);
|
|||
wxDECLARE_EVENT(EVT_ASYNC_DIALOG, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_ASYNC_DIALOG, wxCommandEvent);
|
||||
|
||||
struct Avr109Pid
|
||||
{
|
||||
unsigned boot;
|
||||
unsigned app;
|
||||
|
||||
Avr109Pid(unsigned boot, unsigned app) : boot(boot), app(app) {}
|
||||
};
|
||||
|
||||
// Private
|
||||
|
||||
|
@ -146,24 +155,40 @@ struct FirmwareDialog::priv
|
|||
void flashing_done(AvrDudeComplete complete);
|
||||
void enable_port_picker(bool enable);
|
||||
void load_hex_file(const wxString &path);
|
||||
void queue_status(wxString message);
|
||||
void queue_error(const wxString &message);
|
||||
void queue_event(AvrdudeEvent aevt, wxString message);
|
||||
|
||||
bool ask_model_id_mismatch(const std::string &printer_model);
|
||||
bool check_model_id();
|
||||
void wait_for_mmu_bootloader(unsigned retries);
|
||||
void mmu_reboot(const SerialPortInfo &port);
|
||||
void lookup_port_mmu();
|
||||
void avr109_wait_for_bootloader(Avr109Pid usb_pid, unsigned retries);
|
||||
void avr109_reboot(const SerialPortInfo &port);
|
||||
void avr109_lookup_port(Avr109Pid usb_pid);
|
||||
void prepare_common();
|
||||
void prepare_mk2();
|
||||
void prepare_mk3();
|
||||
void prepare_mm_control();
|
||||
void prepare_avr109(Avr109Pid usb_pid);
|
||||
void perform_upload();
|
||||
|
||||
void user_cancel();
|
||||
void on_avrdude(const wxCommandEvent &evt);
|
||||
void on_async_dialog(const wxCommandEvent &evt);
|
||||
void ensure_joined();
|
||||
|
||||
void queue_status(wxString message) { queue_event(AE_STATUS, std::move(message)); }
|
||||
|
||||
template<class ...Args> void queue_message(const wxString &format, Args... args) {
|
||||
auto message = wxString::Format(format, args...);
|
||||
BOOST_LOG_TRIVIAL(info) << message;
|
||||
message.Append('\n');
|
||||
queue_event(AE_MESSAGE, std::move(message));
|
||||
}
|
||||
|
||||
template<class ...Args> void queue_error(const wxString &format, Args... args) {
|
||||
queue_message(format, args...);
|
||||
queue_event(AE_STATUS, _(L("Flashing failed: ")) + wxString::Format(format, args...));
|
||||
avrdude->cancel();
|
||||
}
|
||||
|
||||
static const char* avr109_dev_name(Avr109Pid usb_pid);
|
||||
};
|
||||
|
||||
void FirmwareDialog::priv::find_serial_ports()
|
||||
|
@ -259,26 +284,18 @@ void FirmwareDialog::priv::enable_port_picker(bool enable)
|
|||
void FirmwareDialog::priv::load_hex_file(const wxString &path)
|
||||
{
|
||||
hex_file = HexFile(path.wx_str());
|
||||
enable_port_picker(hex_file.device != HexFile::DEV_MM_CONTROL);
|
||||
const bool auto_lookup = hex_file.device == HexFile::DEV_MM_CONTROL || hex_file.device == HexFile::DEV_CW1;
|
||||
enable_port_picker(! auto_lookup);
|
||||
}
|
||||
|
||||
void FirmwareDialog::priv::queue_status(wxString message)
|
||||
void FirmwareDialog::priv::queue_event(AvrdudeEvent aevt, wxString message)
|
||||
{
|
||||
auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId());
|
||||
evt->SetExtraLong(AE_STATUS);
|
||||
evt->SetExtraLong(aevt);
|
||||
evt->SetString(std::move(message));
|
||||
wxQueueEvent(this->q, evt);
|
||||
}
|
||||
|
||||
void FirmwareDialog::priv::queue_error(const wxString &message)
|
||||
{
|
||||
auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId());
|
||||
evt->SetExtraLong(AE_STATUS);
|
||||
evt->SetString(wxString::Format(_(L("Flashing failed: %s")), message));
|
||||
|
||||
wxQueueEvent(this->q, evt); avrdude->cancel();
|
||||
}
|
||||
|
||||
bool FirmwareDialog::priv::ask_model_id_mismatch(const std::string &printer_model)
|
||||
{
|
||||
// model_id in the hex file doesn't match what the printer repoted.
|
||||
|
@ -356,7 +373,7 @@ bool FirmwareDialog::priv::check_model_id()
|
|||
// return false;
|
||||
}
|
||||
|
||||
void FirmwareDialog::priv::wait_for_mmu_bootloader(unsigned retries)
|
||||
void FirmwareDialog::priv::avr109_wait_for_bootloader(Avr109Pid usb_pid, unsigned retries)
|
||||
{
|
||||
enum {
|
||||
SLEEP_MS = 500,
|
||||
|
@ -367,61 +384,63 @@ void FirmwareDialog::priv::wait_for_mmu_bootloader(unsigned retries)
|
|||
|
||||
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_MMU_BOOT;
|
||||
return port.id_vendor != USB_VID_PRUSA || port.id_product != usb_pid.boot;
|
||||
}), ports.end());
|
||||
|
||||
if (ports.size() == 1) {
|
||||
port = ports[0];
|
||||
return;
|
||||
} else if (ports.size() > 1) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Several VID/PID 0x2c99/3 devices found";
|
||||
queue_error(_(L("Multiple Original Prusa i3 MMU 2.0 devices found. Please only connect one at a time for flashing.")));
|
||||
queue_message("Several VID/PID 0x2c99/%u devices found", usb_pid.boot);
|
||||
queue_error(_(L("Multiple %s devices found. Please only connect one at a time for flashing.")), avr109_dev_name(usb_pid));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FirmwareDialog::priv::mmu_reboot(const SerialPortInfo &port)
|
||||
void FirmwareDialog::priv::avr109_reboot(const SerialPortInfo &port)
|
||||
{
|
||||
asio::io_service io;
|
||||
Serial serial(io, port.port, 1200);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
|
||||
void FirmwareDialog::priv::lookup_port_mmu()
|
||||
void FirmwareDialog::priv::avr109_lookup_port(Avr109Pid usb_pid)
|
||||
{
|
||||
static const auto msg_not_found =
|
||||
"The Multi Material Control device was not found.\n"
|
||||
"If the device is connected, please press the Reset button next to the USB connector ...";
|
||||
const char *dev_name = avr109_dev_name(usb_pid);
|
||||
const wxString msg_not_found = wxString::Format(
|
||||
_(L("The %s device was not found.\n"
|
||||
"If the device is connected, please press the Reset button next to the USB connector ...")),
|
||||
dev_name);
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Flashing MMU 2.0, looking for VID/PID 0x2c99/3 or 0x2c99/4 ...";
|
||||
queue_message("Flashing %s, looking for VID/PID 0x2c99/%u or 0x2c99/%u ...", dev_name, usb_pid.boot, usb_pid.app);
|
||||
|
||||
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_MMU_BOOT &&
|
||||
port.id_product != USB_PID_MMU_APP;
|
||||
port.id_product != usb_pid.boot &&
|
||||
port.id_product != usb_pid.app;
|
||||
}), ports.end());
|
||||
|
||||
if (ports.size() == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MMU 2.0 device not found, asking the user to press Reset and waiting for the device to show up ...";
|
||||
queue_status(_(L(msg_not_found)));
|
||||
wait_for_mmu_bootloader(30);
|
||||
queue_message("The %s device was not found.", dev_name);
|
||||
queue_status(msg_not_found);
|
||||
avr109_wait_for_bootloader(usb_pid, 30);
|
||||
} else if (ports.size() > 1) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Several VID/PID 0x2c99/3 devices found";
|
||||
queue_error(_(L("Multiple Original Prusa i3 MMU 2.0 devices found. Please only connect one at a time for flashing.")));
|
||||
queue_message("Several VID/PID 0x2c99/%u devices found", usb_pid.boot);
|
||||
queue_error(_(L("Multiple %s devices found. Please only connect one at a time for flashing.")), dev_name);
|
||||
} else {
|
||||
if (ports[0].id_product == USB_PID_MMU_APP) {
|
||||
if (ports[0].id_product == usb_pid.app) {
|
||||
// The device needs to be rebooted into the bootloader mode
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Found VID/PID 0x2c99/4 at `%1%`, rebooting the device ...") % ports[0].port;
|
||||
mmu_reboot(ports[0]);
|
||||
wait_for_mmu_bootloader(10);
|
||||
queue_message("Found VID/PID 0x2c99/%u at `%s`, rebooting the device ...", usb_pid.app, ports[0].port);
|
||||
avr109_reboot(ports[0]);
|
||||
avr109_wait_for_bootloader(usb_pid, 10);
|
||||
|
||||
if (! port) {
|
||||
// The device in bootloader mode was not found, inform the user and wait some more...
|
||||
BOOST_LOG_TRIVIAL(info) << "MMU 2.0 bootloader device not found after reboot, asking the user to press Reset and waiting for the device to show up ...";
|
||||
queue_status(_(L(msg_not_found)));
|
||||
wait_for_mmu_bootloader(30);
|
||||
queue_message("%s device not found after reboot", dev_name);
|
||||
queue_status(msg_not_found);
|
||||
avr109_wait_for_bootloader(usb_pid, 30);
|
||||
}
|
||||
} else {
|
||||
port = ports[0];
|
||||
|
@ -498,16 +517,16 @@ void FirmwareDialog::priv::prepare_mk3()
|
|||
avrdude->push_args(std::move(args));
|
||||
}
|
||||
|
||||
void FirmwareDialog::priv::prepare_mm_control()
|
||||
void FirmwareDialog::priv::prepare_avr109(Avr109Pid usb_pid)
|
||||
{
|
||||
port = boost::none;
|
||||
lookup_port_mmu();
|
||||
avr109_lookup_port(usb_pid);
|
||||
if (! port) {
|
||||
queue_error(_(L("The device could not have been found")));
|
||||
queue_error(_(L("The %s device could not have been found")), avr109_dev_name(usb_pid));
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("Found VID/PID 0x2c99/3 at `%1%`, flashing ...") % port->port;
|
||||
queue_message("Found VID/PID 0x2c99/%u at `%s`, flashing ...", usb_pid.boot, port->port);
|
||||
queue_status(label_status_flashing);
|
||||
|
||||
std::vector<std::string> args {{
|
||||
|
@ -568,7 +587,11 @@ void FirmwareDialog::priv::perform_upload()
|
|||
break;
|
||||
|
||||
case HexFile::DEV_MM_CONTROL:
|
||||
this->prepare_mm_control();
|
||||
this->prepare_avr109(Avr109Pid(USB_PID_MMU_BOOT, USB_PID_MMU_APP));
|
||||
break;
|
||||
|
||||
case HexFile::DEV_CW1:
|
||||
this->prepare_avr109(Avr109Pid(USB_PID_CW1_BOOT, USB_PID_CW1_APP));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -576,7 +599,11 @@ void FirmwareDialog::priv::perform_upload()
|
|||
break;
|
||||
}
|
||||
} catch (const std::exception &ex) {
|
||||
queue_error(wxString::Format(_(L("Error accessing port at %s: %s")), port->port, ex.what()));
|
||||
if (port) {
|
||||
queue_error(_(L("Error accessing port at %s: %s")), port->port, ex.what());
|
||||
} else {
|
||||
queue_error(_(L("Error: %s")), ex.what());
|
||||
}
|
||||
}
|
||||
})
|
||||
.on_message(std::move([q, extra_verbose](const char *msg, unsigned /* size */) {
|
||||
|
@ -688,6 +715,19 @@ void FirmwareDialog::priv::ensure_joined()
|
|||
avrdude.reset();
|
||||
}
|
||||
|
||||
const char* FirmwareDialog::priv::avr109_dev_name(Avr109Pid usb_pid) {
|
||||
switch (usb_pid.boot) {
|
||||
case USB_PID_MMU_BOOT:
|
||||
return "Prusa MMU 2.0 Control";
|
||||
break;
|
||||
case USB_PID_CW1_BOOT:
|
||||
return "Prusa CurWa";
|
||||
break;
|
||||
|
||||
default: throw std::runtime_error((boost::format("Invalid avr109 device USB PID: %1%") % usb_pid.boot).str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Public
|
||||
|
||||
|
@ -757,7 +797,7 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
|
|||
|
||||
vsizer->Add(grid, 0, wxEXPAND | wxTOP | wxBOTTOM, SPACING);
|
||||
|
||||
p->spoiler = new wxCollapsiblePane(panel, wxID_ANY, _(L("Advanced: avrdude output log")), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE | wxCP_NO_TLW_RESIZE);
|
||||
p->spoiler = new wxCollapsiblePane(panel, wxID_ANY, _(L("Advanced: Output log")), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE | wxCP_NO_TLW_RESIZE);
|
||||
auto *spoiler_pane = p->spoiler->GetPane();
|
||||
auto *spoiler_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
p->txt_stdout = new wxTextCtrl(spoiler_pane, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
|
||||
|
|
|
@ -380,7 +380,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
|
|||
|
||||
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
|
||||
{
|
||||
const Point& mouse_pos = canvas.get_local_mouse_position();
|
||||
const Vec2d mouse_pos = canvas.get_local_mouse_position();
|
||||
const Rect& rect = get_bar_rect_screen(canvas);
|
||||
float x = (float)mouse_pos(0);
|
||||
float y = (float)mouse_pos(1);
|
||||
|
@ -3915,19 +3915,25 @@ Size GLCanvas3D::get_canvas_size() const
|
|||
w *= factor;
|
||||
h *= factor;
|
||||
#else
|
||||
const float factor = 1.0;
|
||||
const float factor = 1.0f;
|
||||
#endif
|
||||
|
||||
return Size(w, h, factor);
|
||||
}
|
||||
|
||||
Point GLCanvas3D::get_local_mouse_position() const
|
||||
Vec2d GLCanvas3D::get_local_mouse_position() const
|
||||
{
|
||||
if (m_canvas == nullptr)
|
||||
return Point();
|
||||
return Vec2d::Zero();
|
||||
|
||||
wxPoint mouse_pos = m_canvas->ScreenToClient(wxGetMousePosition());
|
||||
return Point(mouse_pos.x, mouse_pos.y);
|
||||
const double factor =
|
||||
#if ENABLE_RETINA_GL
|
||||
m_retina_helper->get_scale_factor();
|
||||
#else
|
||||
1.0;
|
||||
#endif
|
||||
return Vec2d(factor * mouse_pos.x, factor * mouse_pos.y);
|
||||
}
|
||||
|
||||
void GLCanvas3D::reset_legend_texture()
|
||||
|
@ -4397,11 +4403,13 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
|
|||
if ((m_canvas == nullptr) && (m_context == nullptr))
|
||||
return;
|
||||
|
||||
wxGetApp().imgui()->set_display_size((float)w, (float)h);
|
||||
auto *imgui = wxGetApp().imgui();
|
||||
imgui->set_display_size((float)w, (float)h);
|
||||
const float font_size = 1.5f * wxGetApp().em_unit();
|
||||
#if ENABLE_RETINA_GL
|
||||
wxGetApp().imgui()->set_style_scaling(m_retina_helper->get_scale_factor());
|
||||
imgui->set_scaling(font_size, 1.0f, m_retina_helper->get_scale_factor());
|
||||
#else
|
||||
wxGetApp().imgui()->set_style_scaling(m_canvas->GetContentScaleFactor());
|
||||
imgui->set_scaling(font_size, m_canvas->GetContentScaleFactor(), 1.0f);
|
||||
#endif
|
||||
|
||||
// ensures that this canvas is current
|
||||
|
@ -4979,6 +4987,9 @@ void GLCanvas3D::_render_sla_slices() const
|
|||
{
|
||||
const SLAPrintObject* obj = print_objects[i];
|
||||
|
||||
if (!obj->is_step_done(slaposSliceSupports))
|
||||
continue;
|
||||
|
||||
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_bottom = m_sla_caps[0].triangles.find(i);
|
||||
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_top = m_sla_caps[1].triangles.find(i);
|
||||
{
|
||||
|
@ -5002,24 +5013,12 @@ void GLCanvas3D::_render_sla_slices() const
|
|||
Pointf3s &top_obj_triangles = it_caps_top->second.object;
|
||||
Pointf3s &top_sup_triangles = it_caps_top->second.supports;
|
||||
|
||||
const std::vector<SLAPrintObject::Instance>& instances = obj->instances();
|
||||
struct InstanceTransform
|
||||
{
|
||||
Vec3d offset;
|
||||
float rotation;
|
||||
};
|
||||
|
||||
std::vector<InstanceTransform> instance_transforms;
|
||||
for (const SLAPrintObject::Instance& inst : instances)
|
||||
{
|
||||
instance_transforms.push_back({ to_3d(unscale(inst.shift), 0.), Geometry::rad2deg(inst.rotation) });
|
||||
}
|
||||
|
||||
if ((bottom_obj_triangles.empty() || bottom_sup_triangles.empty() || top_obj_triangles.empty() || top_sup_triangles.empty()) &&
|
||||
obj->is_step_done(slaposIndexSlices) && !obj->get_slice_index().empty())
|
||||
!obj->get_slice_index().empty())
|
||||
{
|
||||
double layer_height = print->default_object_config().layer_height.value;
|
||||
double initial_layer_height = print->material_config().initial_layer_height.value;
|
||||
bool left_handed = obj->is_left_handed();
|
||||
|
||||
coord_t key_zero = obj->get_slice_index().front().print_level();
|
||||
// Slice at the center of the slab starting at clip_min_z will be rendered for the lower plane.
|
||||
|
@ -5038,10 +5037,10 @@ void GLCanvas3D::_render_sla_slices() const
|
|||
const ExPolygons& sup_bottom = slice_low.get_slice(soSupport);
|
||||
// calculate model bottom cap
|
||||
if (bottom_obj_triangles.empty() && !obj_bottom.empty())
|
||||
bottom_obj_triangles = triangulate_expolygons_3d(obj_bottom, clip_min_z - plane_shift_z, true);
|
||||
bottom_obj_triangles = triangulate_expolygons_3d(obj_bottom, clip_min_z - plane_shift_z, ! left_handed);
|
||||
// calculate support bottom cap
|
||||
if (bottom_sup_triangles.empty() && !sup_bottom.empty())
|
||||
bottom_sup_triangles = triangulate_expolygons_3d(sup_bottom, clip_min_z - plane_shift_z, true);
|
||||
bottom_sup_triangles = triangulate_expolygons_3d(sup_bottom, clip_min_z - plane_shift_z, ! left_handed);
|
||||
}
|
||||
|
||||
if (slice_high.is_valid()) {
|
||||
|
@ -5049,49 +5048,43 @@ void GLCanvas3D::_render_sla_slices() const
|
|||
const ExPolygons& sup_top = slice_high.get_slice(soSupport);
|
||||
// calculate model top cap
|
||||
if (top_obj_triangles.empty() && !obj_top.empty())
|
||||
top_obj_triangles = triangulate_expolygons_3d(obj_top, clip_max_z + plane_shift_z, false);
|
||||
top_obj_triangles = triangulate_expolygons_3d(obj_top, clip_max_z + plane_shift_z, left_handed);
|
||||
// calculate support top cap
|
||||
if (top_sup_triangles.empty() && !sup_top.empty())
|
||||
top_sup_triangles = triangulate_expolygons_3d(sup_top, clip_max_z + plane_shift_z, false);
|
||||
top_sup_triangles = triangulate_expolygons_3d(sup_top, clip_max_z + plane_shift_z, left_handed);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bottom_obj_triangles.empty() || !top_obj_triangles.empty() || !bottom_sup_triangles.empty() || !top_sup_triangles.empty())
|
||||
{
|
||||
for (const InstanceTransform& inst : instance_transforms)
|
||||
for (const SLAPrintObject::Instance& inst : obj->instances())
|
||||
{
|
||||
::glPushMatrix();
|
||||
::glTranslated(inst.offset(0), inst.offset(1), inst.offset(2));
|
||||
::glRotatef(inst.rotation, 0.0, 0.0, 1.0);
|
||||
|
||||
::glBegin(GL_TRIANGLES);
|
||||
|
||||
::glColor3f(1.0f, 0.37f, 0.0f);
|
||||
|
||||
for (const Vec3d& v : bottom_obj_triangles)
|
||||
{
|
||||
::glVertex3dv((GLdouble*)v.data());
|
||||
}
|
||||
|
||||
for (const Vec3d& v : top_obj_triangles)
|
||||
{
|
||||
::glVertex3dv((GLdouble*)v.data());
|
||||
}
|
||||
|
||||
::glColor3f(1.0f, 0.0f, 0.37f);
|
||||
|
||||
for (const Vec3d& v : bottom_sup_triangles)
|
||||
{
|
||||
::glVertex3dv((GLdouble*)v.data());
|
||||
}
|
||||
|
||||
for (const Vec3d& v : top_sup_triangles)
|
||||
{
|
||||
::glVertex3dv((GLdouble*)v.data());
|
||||
}
|
||||
|
||||
::glEnd();
|
||||
|
||||
::glTranslated(unscale<double>(inst.shift.x()), unscale<double>(inst.shift.y()), 0);
|
||||
::glRotatef(Geometry::rad2deg(inst.rotation), 0.0, 0.0, 1.0);
|
||||
if (obj->is_left_handed())
|
||||
// The polygons are mirrored by X.
|
||||
::glScalef(-1.0, 1.0, 1.0);
|
||||
::glEnableClientState(GL_VERTEX_ARRAY);
|
||||
::glColor3f(1.0f, 0.37f, 0.0f);
|
||||
if (!bottom_obj_triangles.empty()) {
|
||||
::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_obj_triangles.front().data());
|
||||
::glDrawArrays(GL_TRIANGLES, 0, bottom_obj_triangles.size());
|
||||
}
|
||||
if (! top_obj_triangles.empty()) {
|
||||
::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_obj_triangles.front().data());
|
||||
::glDrawArrays(GL_TRIANGLES, 0, top_obj_triangles.size());
|
||||
}
|
||||
::glColor3f(1.0f, 0.0f, 0.37f);
|
||||
if (! bottom_sup_triangles.empty()) {
|
||||
::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_sup_triangles.front().data());
|
||||
::glDrawArrays(GL_TRIANGLES, 0, bottom_sup_triangles.size());
|
||||
}
|
||||
if (! top_sup_triangles.empty()) {
|
||||
::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_sup_triangles.front().data());
|
||||
::glDrawArrays(GL_TRIANGLES, 0, top_sup_triangles.size());
|
||||
}
|
||||
::glDisableClientState(GL_VERTEX_ARRAY);
|
||||
::glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
@ -6209,6 +6202,8 @@ void GLCanvas3D::_load_shells_fff()
|
|||
|
||||
void GLCanvas3D::_load_shells_sla()
|
||||
{
|
||||
//FIXME use reload_scene
|
||||
#if 1
|
||||
const SLAPrint* print = this->sla_print();
|
||||
if (print->objects().empty())
|
||||
// nothing to render, return
|
||||
|
@ -6218,23 +6213,30 @@ void GLCanvas3D::_load_shells_sla()
|
|||
int obj_idx = 0;
|
||||
for (const SLAPrintObject* obj : print->objects())
|
||||
{
|
||||
if (!obj->is_step_done(slaposIndexSlices))
|
||||
if (!obj->is_step_done(slaposSliceSupports))
|
||||
continue;
|
||||
|
||||
unsigned int initial_volumes_count = (unsigned int)m_volumes.volumes.size();
|
||||
|
||||
// selects only instances which were sliced
|
||||
const ModelObject* model_obj = obj->model_object();
|
||||
std::vector<int> instance_idxs(model_obj->instances.size());
|
||||
for (int i = 0; i < (int)model_obj->instances.size(); ++i)
|
||||
const std::vector<SLAPrintObject::Instance>& sla_instances = obj->instances();
|
||||
std::vector<int> instances_model_idxs(sla_instances.size());
|
||||
for (int i = 0; i < (int)sla_instances.size(); ++i)
|
||||
{
|
||||
instance_idxs[i] = i;
|
||||
instances_model_idxs[i] = (int)sla_instances[i].instance_id.id;
|
||||
}
|
||||
|
||||
m_volumes.load_object(model_obj, obj_idx, instance_idxs, "object", m_use_VBOs && m_initialized);
|
||||
std::vector<int> sliced_instance_idxs;
|
||||
for (int i = 0; i < (int)model_obj->instances.size(); ++i)
|
||||
{
|
||||
if (std::find(instances_model_idxs.begin(), instances_model_idxs.end(), (int)model_obj->instances[i]->id().id) != instances_model_idxs.end())
|
||||
sliced_instance_idxs.push_back(i);
|
||||
}
|
||||
|
||||
const std::vector<SLAPrintObject::Instance>& instances = obj->instances();
|
||||
m_volumes.load_object(model_obj, obj_idx, sliced_instance_idxs, "object", m_use_VBOs && m_initialized);
|
||||
|
||||
for (const SLAPrintObject::Instance& instance : instances)
|
||||
for (const SLAPrintObject::Instance& instance : sla_instances)
|
||||
{
|
||||
Vec3d offset = unscale(instance.shift(0), instance.shift(1), 0);
|
||||
Vec3d rotation(0.0, 0.0, (double)instance.rotation);
|
||||
|
@ -6257,6 +6259,7 @@ void GLCanvas3D::_load_shells_sla()
|
|||
v.composite_id.volume_id = -1;
|
||||
v.set_instance_offset(offset);
|
||||
v.set_instance_rotation(rotation);
|
||||
v.set_instance_mirror(X, obj->is_left_handed() ? -1. : 1.);
|
||||
}
|
||||
|
||||
// add pad
|
||||
|
@ -6275,6 +6278,7 @@ void GLCanvas3D::_load_shells_sla()
|
|||
v.composite_id.volume_id = -1;
|
||||
v.set_instance_offset(offset);
|
||||
v.set_instance_rotation(rotation);
|
||||
v.set_instance_mirror(X, obj->is_left_handed() ? -1. : 1.);
|
||||
}
|
||||
|
||||
// finalize volumes and sends geometry to gpu
|
||||
|
@ -6297,6 +6301,9 @@ void GLCanvas3D::_load_shells_sla()
|
|||
}
|
||||
|
||||
update_volumes_colors_by_extruder();
|
||||
#else
|
||||
this->reload_scene(true, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLCanvas3D::_update_gcode_volumes_visibility(const GCodePreviewData& preview_data)
|
||||
|
|
|
@ -634,6 +634,7 @@ public:
|
|||
m_sla_caps[id].reset();
|
||||
}
|
||||
}
|
||||
void reset_clipping_planes_cache() { m_sla_caps[0].triangles.clear(); m_sla_caps[1].triangles.clear(); }
|
||||
void set_use_clipping_planes(bool use) { m_use_clipping_planes = use; }
|
||||
|
||||
void set_color_by(const std::string& value);
|
||||
|
@ -699,7 +700,7 @@ public:
|
|||
void on_paint(wxPaintEvent& evt);
|
||||
|
||||
Size get_canvas_size() const;
|
||||
Point get_local_mouse_position() const;
|
||||
Vec2d get_local_mouse_position() const;
|
||||
|
||||
void reset_legend_texture();
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ bool GUI_App::OnInit()
|
|||
const wxString resources_dir = from_u8(Slic3r::resources_dir());
|
||||
wxCHECK_MSG(wxDirExists(resources_dir), false,
|
||||
wxString::Format("Resources path does not exist or is not a directory: %s", resources_dir));
|
||||
wxCHECK_MSG(m_imgui->init(), false, "Failed to initialize ImGui");
|
||||
|
||||
SetAppName("Slic3rPE-beta");
|
||||
SetAppDisplayName("Slic3r Prusa Edition");
|
||||
|
@ -136,6 +135,10 @@ bool GUI_App::OnInit()
|
|||
app_config->save();
|
||||
});
|
||||
|
||||
// initialize label colors and fonts
|
||||
init_label_colours();
|
||||
init_fonts();
|
||||
|
||||
load_language();
|
||||
|
||||
// Suppress the '- default -' presets.
|
||||
|
@ -148,9 +151,6 @@ bool GUI_App::OnInit()
|
|||
|
||||
// Let the libslic3r know the callback, which will translate messages on demand.
|
||||
Slic3r::I18N::set_translate_callback(libslic3r_translate_callback);
|
||||
// initialize label colors and fonts
|
||||
init_label_colours();
|
||||
init_fonts();
|
||||
|
||||
// application frame
|
||||
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
View3D::View3D(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
||||
View3D::View3D(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
||||
: m_canvas_widget(nullptr)
|
||||
, m_canvas(nullptr)
|
||||
{
|
||||
|
@ -155,7 +155,9 @@ void View3D::render()
|
|||
m_canvas->set_as_dirty();
|
||||
}
|
||||
|
||||
Preview::Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
|
||||
Preview::Preview(
|
||||
wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
||||
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
|
||||
: m_canvas_widget(nullptr)
|
||||
, m_canvas(nullptr)
|
||||
, m_double_slider_sizer(nullptr)
|
||||
|
@ -179,14 +181,14 @@ Preview::Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_t
|
|||
, m_volumes_cleanup_required(false)
|
||||
#endif // __linux__
|
||||
{
|
||||
if (init(parent, bed, camera, view_toolbar))
|
||||
if (init(parent, bed, camera, view_toolbar, model))
|
||||
{
|
||||
show_hide_ui_elements("none");
|
||||
load_print();
|
||||
}
|
||||
}
|
||||
|
||||
bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar)
|
||||
bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model)
|
||||
{
|
||||
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
|
||||
return false;
|
||||
|
@ -196,6 +198,7 @@ bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view
|
|||
m_canvas = _3DScene::get_canvas(this->m_canvas_widget);
|
||||
m_canvas->allow_multisample(GLCanvas3DManager::can_multisample());
|
||||
m_canvas->set_config(m_config);
|
||||
m_canvas->set_model(model);
|
||||
m_canvas->set_process(m_process);
|
||||
m_canvas->enable_legend_texture(true);
|
||||
m_canvas->enable_dynamic_background(true);
|
||||
|
@ -773,7 +776,7 @@ void Preview::load_print_as_sla()
|
|||
std::vector<double> zs;
|
||||
double initial_layer_height = print->material_config().initial_layer_height.value;
|
||||
for (const SLAPrintObject* obj : print->objects())
|
||||
if (obj->is_step_done(slaposIndexSlices) && !obj->get_slice_index().empty())
|
||||
if (obj->is_step_done(slaposSliceSupports) && !obj->get_slice_index().empty())
|
||||
{
|
||||
auto low_coord = obj->get_slice_index().front().print_level();
|
||||
for (auto& rec : obj->get_slice_index())
|
||||
|
@ -781,6 +784,8 @@ void Preview::load_print_as_sla()
|
|||
}
|
||||
sort_remove_duplicates(zs);
|
||||
|
||||
m_canvas->reset_clipping_planes_cache();
|
||||
|
||||
n_layers = (unsigned int)zs.size();
|
||||
if (n_layers == 0)
|
||||
{
|
||||
|
|
|
@ -102,7 +102,8 @@ class Preview : public wxPanel
|
|||
PrusaDoubleSlider* m_slider {nullptr};
|
||||
|
||||
public:
|
||||
Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = [](){});
|
||||
Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
||||
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = [](){});
|
||||
virtual ~Preview();
|
||||
|
||||
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
|
||||
|
@ -120,7 +121,7 @@ public:
|
|||
void refresh_print();
|
||||
|
||||
private:
|
||||
bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar);
|
||||
bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model);
|
||||
|
||||
void bind_event_handlers();
|
||||
void unbind_event_handlers();
|
||||
|
|
|
@ -185,7 +185,10 @@ void GLGizmoCut::on_render_for_picking(const Selection& selection) const
|
|||
|
||||
void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit, const Selection& selection)
|
||||
{
|
||||
const float approx_height = m_imgui->scaled(11.0f);
|
||||
y = std::min(y, bottom_limit - approx_height);
|
||||
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
|
||||
|
||||
m_imgui->set_next_window_bg_alpha(0.5f);
|
||||
m_imgui->begin(_(L("Cut")), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
|
|
|
@ -565,8 +565,7 @@ void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
RENDER_AGAIN:
|
||||
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
|
||||
|
||||
const float scaling = m_imgui->get_style_scaling();
|
||||
const ImVec2 window_size(285.f * scaling, 300.f * scaling);
|
||||
const ImVec2 window_size(m_imgui->scaled(15.f, 16.5f));
|
||||
ImGui::SetNextWindowPos(ImVec2(x, y - std::max(0.f, y+window_size.y-bottom_limit) ));
|
||||
ImGui::SetNextWindowSize(ImVec2(window_size));
|
||||
|
||||
|
@ -817,7 +816,7 @@ void GLGizmoSlaSupports::editing_mode_apply_changes()
|
|||
// Recalculate support structures once the editing mode is left.
|
||||
// m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
// m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
wxGetApp().plater()->reslice_SLA_supports(*m_model_object);
|
||||
wxGetApp().CallAfter([this]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object); });
|
||||
}
|
||||
m_editing_mode = false;
|
||||
m_unsaved_changes = false;
|
||||
|
@ -870,7 +869,7 @@ void GLGizmoSlaSupports::auto_generate()
|
|||
m_model_object->sla_support_points.clear();
|
||||
m_model_object->sla_points_status = sla::PointsStatus::Generating;
|
||||
m_editing_mode_cache.clear();
|
||||
wxGetApp().plater()->reslice_SLA_supports(*m_model_object);
|
||||
wxGetApp().CallAfter([this]() { wxGetApp().plater()->reslice_SLA_supports(*m_model_object); });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,31 +27,25 @@ namespace GUI {
|
|||
|
||||
ImGuiWrapper::ImGuiWrapper()
|
||||
: m_glyph_ranges(nullptr)
|
||||
, m_font_size(18.0)
|
||||
, m_font_texture(0)
|
||||
, m_style_scaling(1.0)
|
||||
, m_mouse_buttons(0)
|
||||
, m_disabled(false)
|
||||
, m_new_frame_open(false)
|
||||
{
|
||||
}
|
||||
|
||||
ImGuiWrapper::~ImGuiWrapper()
|
||||
{
|
||||
destroy_device_objects();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::init()
|
||||
{
|
||||
ImGui::CreateContext();
|
||||
|
||||
init_default_font(m_style_scaling);
|
||||
init_input();
|
||||
init_style();
|
||||
|
||||
ImGui::GetIO().IniFilename = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
ImGuiWrapper::~ImGuiWrapper()
|
||||
{
|
||||
destroy_font();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
void ImGuiWrapper::set_language(const std::string &language)
|
||||
|
@ -87,7 +81,7 @@ void ImGuiWrapper::set_language(const std::string &language)
|
|||
|
||||
if (ranges != m_glyph_ranges) {
|
||||
m_glyph_ranges = ranges;
|
||||
init_default_font(m_style_scaling);
|
||||
destroy_font();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,13 +92,21 @@ void ImGuiWrapper::set_display_size(float w, float h)
|
|||
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void ImGuiWrapper::set_style_scaling(float scaling)
|
||||
void ImGuiWrapper::set_scaling(float font_size, float scale_style, float scale_both)
|
||||
{
|
||||
if (!std::isnan(scaling) && !std::isinf(scaling) && scaling != m_style_scaling) {
|
||||
ImGui::GetStyle().ScaleAllSizes(scaling / m_style_scaling);
|
||||
init_default_font(scaling);
|
||||
m_style_scaling = scaling;
|
||||
font_size *= scale_both;
|
||||
scale_style *= scale_both;
|
||||
|
||||
if (m_font_size == font_size && m_style_scaling == scale_style) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_font_size = font_size;
|
||||
|
||||
ImGui::GetStyle().ScaleAllSizes(scale_style / m_style_scaling);
|
||||
m_style_scaling = scale_style;
|
||||
|
||||
destroy_font();
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt)
|
||||
|
@ -165,8 +167,9 @@ void ImGuiWrapper::new_frame()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_font_texture == 0)
|
||||
create_device_objects();
|
||||
if (m_font_texture == 0) {
|
||||
init_font();
|
||||
}
|
||||
|
||||
ImGui::NewFrame();
|
||||
m_new_frame_open = true;
|
||||
|
@ -179,6 +182,12 @@ void ImGuiWrapper::render()
|
|||
m_new_frame_open = false;
|
||||
}
|
||||
|
||||
ImVec2 ImGuiWrapper::calc_text_size(const wxString &text)
|
||||
{
|
||||
auto text_utf8 = into_u8(text);
|
||||
return ImGui::CalcTextSize(text_utf8.c_str());
|
||||
}
|
||||
|
||||
void ImGuiWrapper::set_next_window_pos(float x, float y, int flag)
|
||||
{
|
||||
ImGui::SetNextWindowPos(ImVec2(x, y), (ImGuiCond)flag);
|
||||
|
@ -259,7 +268,8 @@ void ImGuiWrapper::text(const std::string &label)
|
|||
|
||||
void ImGuiWrapper::text(const wxString &label)
|
||||
{
|
||||
this->text(into_u8(label).c_str());
|
||||
auto label_utf8 = into_u8(label);
|
||||
this->text(label_utf8.c_str());
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::combo(const wxString& label, const std::vector<std::string>& options, int& selection)
|
||||
|
@ -328,32 +338,23 @@ bool ImGuiWrapper::want_any_input() const
|
|||
return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput;
|
||||
}
|
||||
|
||||
void ImGuiWrapper::init_default_font(float scaling)
|
||||
void ImGuiWrapper::init_font()
|
||||
{
|
||||
static const float font_size = 18.0f;
|
||||
const float font_size = m_font_size * m_style_scaling;
|
||||
|
||||
destroy_fonts_texture();
|
||||
destroy_font();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->Clear();
|
||||
ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), font_size * scaling, nullptr, m_glyph_ranges);
|
||||
ImFont* font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf").c_str(), font_size, nullptr, m_glyph_ranges);
|
||||
if (font == nullptr) {
|
||||
font = io.Fonts->AddFontDefault();
|
||||
if (font == nullptr) {
|
||||
throw std::runtime_error("ImGui: Could not load deafult font");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiWrapper::create_device_objects()
|
||||
{
|
||||
create_fonts_texture();
|
||||
}
|
||||
|
||||
void ImGuiWrapper::create_fonts_texture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||
|
@ -559,14 +560,9 @@ bool ImGuiWrapper::display_initialized() const
|
|||
return io.DisplaySize.x >= 0.0f && io.DisplaySize.y >= 0.0f;
|
||||
}
|
||||
|
||||
void ImGuiWrapper::destroy_device_objects()
|
||||
void ImGuiWrapper::destroy_font()
|
||||
{
|
||||
destroy_fonts_texture();
|
||||
}
|
||||
|
||||
void ImGuiWrapper::destroy_fonts_texture()
|
||||
{
|
||||
if (m_font_texture) {
|
||||
if (m_font_texture != 0) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->TexID = 0;
|
||||
glDeleteTextures(1, &m_font_texture);
|
||||
|
|
|
@ -18,10 +18,8 @@ namespace GUI {
|
|||
|
||||
class ImGuiWrapper
|
||||
{
|
||||
typedef std::map<std::string, ImFont*> FontsMap;
|
||||
|
||||
FontsMap m_fonts;
|
||||
const ImWchar *m_glyph_ranges;
|
||||
float m_font_size;
|
||||
unsigned m_font_texture;
|
||||
float m_style_scaling;
|
||||
unsigned m_mouse_buttons;
|
||||
|
@ -33,20 +31,24 @@ public:
|
|||
ImGuiWrapper();
|
||||
~ImGuiWrapper();
|
||||
|
||||
bool init();
|
||||
void read_glsl_version();
|
||||
|
||||
void set_language(const std::string &language);
|
||||
void set_display_size(float w, float h);
|
||||
void set_style_scaling(float scaling);
|
||||
void set_scaling(float font_size, float scale_style, float scale_both);
|
||||
bool update_mouse_data(wxMouseEvent &evt);
|
||||
bool update_key_data(wxKeyEvent &evt);
|
||||
|
||||
float get_font_size() const { return m_font_size; }
|
||||
float get_style_scaling() const { return m_style_scaling; }
|
||||
|
||||
void new_frame();
|
||||
void render();
|
||||
|
||||
float scaled(float x) const { return x * m_font_size * m_style_scaling; }
|
||||
ImVec2 scaled(float x, float y) const { return ImVec2(x * m_font_size * m_style_scaling, y * m_font_size * m_style_scaling); }
|
||||
ImVec2 calc_text_size(const wxString &text);
|
||||
|
||||
void set_next_window_pos(float x, float y, int flag);
|
||||
void set_next_window_bg_alpha(float alpha);
|
||||
|
||||
|
@ -73,15 +75,12 @@ public:
|
|||
bool want_any_input() const;
|
||||
|
||||
private:
|
||||
void init_default_font(float scaling);
|
||||
void create_device_objects();
|
||||
void create_fonts_texture();
|
||||
void init_font();
|
||||
void init_input();
|
||||
void init_style();
|
||||
void render_draw_data(ImDrawData *draw_data);
|
||||
bool display_initialized() const;
|
||||
void destroy_device_objects();
|
||||
void destroy_fonts_texture();
|
||||
void destroy_font();
|
||||
|
||||
static const char* clipboard_get(void* user_data);
|
||||
static void clipboard_set(void* user_data, const char* text);
|
||||
|
|
|
@ -1350,7 +1350,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this);
|
||||
|
||||
view3D = new View3D(q, bed, camera, view_toolbar, &model, config, &background_process);
|
||||
preview = new Preview(q, bed, camera, view_toolbar, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); });
|
||||
preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); });
|
||||
|
||||
panels.push_back(view3D);
|
||||
panels.push_back(preview);
|
||||
|
|
|
@ -118,17 +118,17 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection)
|
|||
if (needs_reset)
|
||||
clear();
|
||||
|
||||
if (volume->is_modifier)
|
||||
m_mode = Volume;
|
||||
else if (!contains_volume(volume_idx))
|
||||
m_mode = Instance;
|
||||
// else -> keep current mode
|
||||
if (!contains_volume(volume_idx))
|
||||
m_mode = volume->is_modifier ? Volume : Instance;
|
||||
else
|
||||
// keep current mode
|
||||
return;
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case Volume:
|
||||
{
|
||||
if (volume->volume_idx() >= 0 && (is_empty() || (volume->instance_idx() == get_instance_idx())))
|
||||
if ((volume->volume_idx() >= 0) && (is_empty() || (volume->instance_idx() == get_instance_idx())))
|
||||
_add_volume(volume_idx);
|
||||
|
||||
break;
|
||||
|
@ -439,6 +439,8 @@ void Selection::translate(const Vec3d& displacement, bool local)
|
|||
if (!m_valid)
|
||||
return;
|
||||
|
||||
EMode translation_type = m_mode;
|
||||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
if ((m_mode == Volume) || (*m_volumes)[i]->is_wipe_tower)
|
||||
|
@ -452,13 +454,22 @@ void Selection::translate(const Vec3d& displacement, bool local)
|
|||
}
|
||||
}
|
||||
else if (m_mode == Instance)
|
||||
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
|
||||
{
|
||||
if (_is_from_fully_selected_instance(i))
|
||||
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
|
||||
else
|
||||
{
|
||||
Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
|
||||
(*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
translation_type = Volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !DISABLE_INSTANCES_SYNCH
|
||||
if (m_mode == Instance)
|
||||
if (translation_type == Instance)
|
||||
_synchronize_unselected_instances(SYNC_ROTATION_NONE);
|
||||
else if (m_mode == Volume)
|
||||
else if (translation_type == Volume)
|
||||
_synchronize_unselected_volumes();
|
||||
#endif // !DISABLE_INSTANCES_SYNCH
|
||||
|
||||
|
@ -970,7 +981,23 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const
|
|||
::glTranslated(center(0), center(1), center(2));
|
||||
if (!boost::starts_with(sidebar_field, "position"))
|
||||
{
|
||||
Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
Transform3d orient_matrix = Transform3d::Identity();
|
||||
if (boost::starts_with(sidebar_field, "scale"))
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else if (boost::starts_with(sidebar_field, "rotation"))
|
||||
{
|
||||
if (boost::ends_with(sidebar_field, "x"))
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else if (boost::ends_with(sidebar_field, "y"))
|
||||
{
|
||||
const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation();
|
||||
if (rotation(0) == 0.0)
|
||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
else
|
||||
orient_matrix.rotate(Eigen::AngleAxisd(rotation(2), Vec3d::UnitZ()));
|
||||
}
|
||||
}
|
||||
|
||||
::glMultMatrixd(orient_matrix.data());
|
||||
}
|
||||
}
|
||||
|
@ -1667,5 +1694,29 @@ void Selection::_ensure_on_bed()
|
|||
}
|
||||
}
|
||||
|
||||
bool Selection::_is_from_fully_selected_instance(unsigned int volume_idx) const
|
||||
{
|
||||
struct SameInstance
|
||||
{
|
||||
int obj_idx;
|
||||
int inst_idx;
|
||||
GLVolumePtrs& volumes;
|
||||
|
||||
SameInstance(int obj_idx, int inst_idx, GLVolumePtrs& volumes) : obj_idx(obj_idx), inst_idx(inst_idx), volumes(volumes) {}
|
||||
bool operator () (unsigned int i) { return (volumes[i]->volume_idx() >= 0) && (volumes[i]->object_idx() == obj_idx) && (volumes[i]->instance_idx() == inst_idx); }
|
||||
};
|
||||
|
||||
if ((unsigned int)m_volumes->size() <= volume_idx)
|
||||
return false;
|
||||
|
||||
GLVolume* volume = (*m_volumes)[volume_idx];
|
||||
int object_idx = volume->object_idx();
|
||||
if ((int)m_model->objects.size() <= object_idx)
|
||||
return false;
|
||||
|
||||
unsigned int count = (unsigned int)std::count_if(m_list.begin(), m_list.end(), SameInstance(object_idx, volume->instance_idx(), *m_volumes));
|
||||
return count == (unsigned int)m_model->objects[object_idx]->volumes.size();
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -299,6 +299,7 @@ private:
|
|||
void _synchronize_unselected_instances(SyncRotationType sync_rotation_type);
|
||||
void _synchronize_unselected_volumes();
|
||||
void _ensure_on_bed();
|
||||
bool _is_from_fully_selected_instance(unsigned int volume_idx) const;
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
@ -18,6 +18,7 @@ static HexFile::DeviceKind parse_device_kind(const std::string &str)
|
|||
if (str == "mk2") { return HexFile::DEV_MK2; }
|
||||
else if (str == "mk3") { return HexFile::DEV_MK3; }
|
||||
else if (str == "mm-control") { return HexFile::DEV_MM_CONTROL; }
|
||||
else if (str == "cw1") { return HexFile::DEV_CW1; }
|
||||
else { return HexFile::DEV_GENERIC; }
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ struct HexFile
|
|||
DEV_MK2,
|
||||
DEV_MK3,
|
||||
DEV_MM_CONTROL,
|
||||
DEV_CW1,
|
||||
};
|
||||
|
||||
boost::filesystem::path path;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue