diff --git a/BuildLinux.sh b/BuildLinux.sh index 0860905..59e7d3c 100644 --- a/BuildLinux.sh +++ b/BuildLinux.sh @@ -84,17 +84,26 @@ fi DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release) VERSION=$(awk -F= '/^VERSION_ID=/ {print $2}' /etc/os-release) -# treat ubuntu as debian -if [ "${DISTRIBUTION}" == "ubuntu" ] -then - DISTRIBUTION="debian" -fi -if [ ! -f ./linux.d/${DISTRIBUTION} ] +# OSLIKE is a space-delineated list of similar distributions +OSLIKE=$(awk -F= '/^ID_LIKE=/ {print $2}' /etc/os-release | tr -d '"') + +# Iterate over a list of candidate distribution targets, first match is used +for CANDIDATE in ${DISTRIBUTION} ${OSLIKE}; do + if [ -f ./linux.d/${CANDIDATE} ] + then + TARGET_DISTRO="${CANDIDATE}" + break + fi +done + +if [ -z ${TARGET_DISTRO} ] then echo "Your distribution does not appear to be currently supported by these build scripts" exit 1 fi -source ./linux.d/${DISTRIBUTION} + +echo "OS distribution is '${DISTRIBUTION}'. Using package dependencies for '${TARGET_DISTRO}'." +source ./linux.d/${TARGET_DISTRO} echo "FOUND_GTK3=${FOUND_GTK3}" if [[ -z "${FOUND_GTK3_DEV}" ]] diff --git a/DockerBuild.sh b/DockerBuild.sh index d44dcb6..3c98eda 100644 --- a/DockerBuild.sh +++ b/DockerBuild.sh @@ -9,7 +9,7 @@ set -x # the simplicity of a single Docker image and a one-time compilation # seems better. docker build -t qidistudio \ - --build-arg USER=$USER \ + --build-arg USER=${USER:-root} \ --build-arg UID=$(id -u) \ --build-arg GID=$(id -g) \ $PROJECT_ROOT diff --git a/DockerEntrypoint.sh b/DockerEntrypoint.sh new file mode 100644 index 0000000..738489a --- /dev/null +++ b/DockerEntrypoint.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +# Entrypoint script to create an out-of-the-box experience for QIDIStudio. +# Perform some initial setup if none was done previously. +# It is not necessary if you know what you are doing. Feel free to go +# to the Dockerfile and switch the entrypoint to the QIDIStudio binary. + +# Check if the current effective user is root + +if [ "$EUID" -eq 0 ]; then + echo "No User specified at build time." + if [ -z "$RUN_USER" ] || [ -z "$RUN_UID" ] || [ -z "$RUN_GID" ] || [ "$RUN_UID" -eq 0 ]; then + echo "At least one of RUN_USER, RUN_UID, or RUN_GID is unset. Or 'root' was requested." + echo "Running as root" + + if [ "$HOME" != "/root" ]; then + if [ ! -d "/root" ]; then + mkdir /root + chown root:root /root + chmod 700 /root + fi + fi + + export HOME="/root" + EXEC_USER="root" + else + echo "Setting up a new user" + + # Check if there is a already a valid user entry for the passed UID, if not create one + if [ -z "$(getent passwd "$RUN_UID" | cut -d: -f1)" ]; then + #GID=$(id -g) + echo "User specified at runtime. Performing setup." + groupadd -g "$RUN_GID" "$RUN_USER" + useradd -u "$RUN_UID" -g "$RUN_GID" -d "/home/$RUN_USER" "$RUN_USER" + usermod -aG sudo "$RUN_USER" + passwd -d "$RUN_USER" + + #This will take forever to run, so we will just chown the build folder which contains the binaries + #chown -R "$RUN_UID":"$RUN_GID" /QIDIStudio + chown "$RUN_UID":"$RUN_GID" /QIDIStudio + chown -R "$RUN_UID":"$RUN_GID" /QIDIStudio/build + + + export HOME="/home/$RUN_USER" + EXEC_USER="$RUN_USER" + fi + fi +else + echo "User specified at build time." + CURRENT_USER=$(id -un) + if [ -n "$RUN_USER" ] && [ -n "$RUN_UID" ] && [ -n "$RUN_GID" ] && [ "$RUN_UID" -ne "$EUID" ]; then + echo "New User config passed at Runtime. Setting up." + if [ -z "$(getent passwd "$RUN_UID" | cut -d: -f1)" ]; then + sudo groupadd -g "$RUN_UID" "$RUN_USER" + sudo useradd -u "$RUN_UID" -g "$RUN_GID" -d "/home/$RUN_USER" "$RUN_USER" + sudo usermod -aG sudo "$RUN_USER" + passwd -d "$RUN_USER" + + #sudo chown -R "$RUN_UID":"$RUN_GID" /QIDIStudio + chown "$RUN_UID":"$RUN_GID" /QIDIStudio + chown -R "$RUN_UID":"$RUN_GID" /QIDIStudio/build + + export HOME="/home/$RUN_USER" + EXEC_USER="$RUN_USER" + fi + else + echo "Using Build time user." + EXEC_USER="$CURRENT_USER" + #It should've been set in Dockerfile, but just in case, uncomment this it there is problem + #export HOME="/home/$USER" + fi +fi + +# make sure ~/.config folder exists so QIDI Studio will start +if [ ! -d "$HOME/.config" ]; then + mkdir -p "$HOME/.config" +fi + +# Using su $USER -c will retain all the important ENV args when qidi Studio starts in a different shell +# Continue with QIDI Studio using correct user, passing all arguments +exec su "$EXEC_USER" -c "/QIDIStudio/build/package/bin/qidi-studio $*" diff --git a/DockerRun.sh b/DockerRun.sh index aa10e6d..6ed871f 100644 --- a/DockerRun.sh +++ b/DockerRun.sh @@ -5,15 +5,24 @@ set -x # -h $HOSTNAME \ # If there's problems with the X display, try this # -v /tmp/.X11-unix:/tmp/.X11-unix \ +# or +# -v $HOME/.Xauthority:/root/.Xauthority \ +# You also need to run "xhost +" on your host system +# QIDI Studio also require the parent directory for the configuration directory to be present to start +# to prevent your local machines's QIDI studio config passed to docker container when you map your home directory, add: +# -v :SHOME/.config/QIDIStudio +set -x docker run \ `# Use the hosts networking. Printer wifi and also dbus communication` \ --net=host \ `# Some X installs will not have permissions to talk to sockets for shared memory` \ --ipc host \ - `# Run as your workstations username to keep permissions the same` \ - -u $USER \ `# Bind mount your home directory into the container for loading/saving files` \ - -v $HOME:/home/$USER \ + -v $HOME:$HOME \ + `# Pass some X Auth file to allow x11 to connect to your host x instance` \ + -v $HOME/.Xauthority:/tmp/.Xauthority \ + -v /tmp/.X11-unix:/tmp/.X11-unix \ + -e XAUTHORITY=/tmp/.Xauthority \ `# Pass the X display number to the container` \ -e DISPLAY=$DISPLAY \ `# It seems that libGL and dbus things need privileged mode` \ @@ -24,4 +33,3 @@ docker run \ --rm \ `# Pass all parameters from this script to the qidi ENTRYPOINT binary` \ qidistudio $* - diff --git a/Dockerfile b/Dockerfile index 3649c75..9c8d9c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -FROM docker.io/ubuntu:22.04 -LABEL maintainer "DeftDawg " +FROM docker.io/ubuntu:24.10 # Disable interactive package configuration RUN apt-get update && \ @@ -14,6 +13,7 @@ RUN apt-get update && apt-get install -y \ build-essential \ cmake \ curl \ + xvfb \ eglexternalplatform-dev \ extra-cmake-modules \ file \ @@ -39,7 +39,6 @@ RUN apt-get update && apt-get install -y \ libssl-dev \ libudev-dev \ libwayland-dev \ - libwebkit2gtk-4.0-dev \ libxkbcommon-dev \ locales \ locales-all \ @@ -47,6 +46,7 @@ RUN apt-get update && apt-get install -y \ pkgconf \ sudo \ wayland-protocols \ + libwebkit2gtk-4.1-dev \ wget # Change your locale here if you want. See the output @@ -58,14 +58,52 @@ RUN locale-gen $LC_ALL # the CA cert path on every startup ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt -COPY ./ QIDIStudio +COPY ./ /QIDIStudio -WORKDIR QIDIStudio +RUN chmod +x /QIDIStudio/DockerEntrypoint.sh -# These can run together, but we run them seperate for podman caching -# Update System dependencies +WORKDIR /QIDIStudio + +# Ubuntu 24 Docker Image now come with default standard user "ubuntu" +# It might conflict with your mapped user, remove if user ubuntu exist +RUN if id "ubuntu" >/dev/null 2>&1; then userdel -r ubuntu; fi + + +# Use bash as the shell + +# Set ARG values +# If user was passed from build it will create a user same +# as your workstation. Else it will use /root + +# Setting ARG at build time is convienient for testing purposes +# otherwise the same commands will be executed at runtime + +ARG USER=root +ARG UID=0 +ARG GID=0 +RUN if [ "$UID" != "0" ]; then \ + groupadd -g $GID $USER && \ + useradd -u $UID -g $GID -m -d /home/$USER $USER && \ + mkdir -p /home/$USER && \ + chown -R $UID:$GID /QIDIStudio && \ + usermod -aG sudo $USER && \ + passwd -d "$USER"; \ + else \ + mkdir -p /root/.config; \ + fi + +# Allow password-less sudo for ALL users +RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/999-passwordless +RUN chmod 440 /etc/sudoers.d/999-passwordless + +# Update System dependencies(Run before user switch) RUN ./BuildLinux.sh -u +# Run as the mapped user (or root by default) +USER $USER + + +# These can run together, but we run them seperate for podman caching # Build dependencies in ./deps RUN ./BuildLinux.sh -d @@ -73,7 +111,7 @@ RUN ./BuildLinux.sh -d RUN ./BuildLinux.sh -s # Build AppImage -ENV container podman +ENV container=podman RUN ./BuildLinux.sh -i # It's easier to run QIDI Studio as the same username, @@ -82,13 +120,14 @@ RUN ./BuildLinux.sh -i # to keep permissions the same. Just in case, defaults # are root. SHELL ["/bin/bash", "-l", "-c"] -ARG USER=root -ARG UID=0 -ARG GID=0 -RUN [[ "$UID" != "0" ]] \ - && groupadd -f -g $GID $USER \ - && useradd -u $UID -g $GID $USER + +# Point FFMPEG Library search to the binary built upon QIDIStudio build time +ENV LD_LIBRARY_PATH=/QIDIStudio/build/package/bin # Using an entrypoint instead of CMD because the binary # accepts several command line arguments. -ENTRYPOINT ["/QIDIStudio/build/package/bin/qidi-studio"] +# entrypoint script will pass all arguments to QIDI-studio +# after the script finishes + +#ENTRYPOINT ["/QIDIStudio/build/package/bin/QIDI-studio"] +ENTRYPOINT ["/QIDIStudio/DockerEntrypoint.sh"] diff --git a/qdt/i18n/de/QIDIStudio_de.po b/qdt/i18n/de/QIDIStudio_de.po index 2d683da..0bed024 100644 --- a/qdt/i18n/de/QIDIStudio_de.po +++ b/qdt/i18n/de/QIDIStudio_de.po @@ -6814,16 +6814,16 @@ msgstr "Beschäftigt" msgid "QIDI Cool Plate" msgstr "QIDI Cool Plate" -msgid "Bamabu Engineering Plate" +msgid "QIDI Engineering Plate" msgstr "QIDI Engineering Plate" -msgid "Bamabu Smooth PEI Plate" +msgid "QIDI Smooth PEI Plate" msgstr "QIDI Smooth PEI Plate" msgid "High temperature Plate" msgstr "High temperature Plate" -msgid "Bamabu Textured PEI Plate" +msgid "QIDI Textured PEI Plate" msgstr "QIDI Textured PEI Plate" msgid "QIDI Cool Plate SuperTack" @@ -14784,7 +14784,7 @@ msgstr "" #~ msgid "Backup interval" #~ msgstr "Sicherungsintervall" -#~ msgid "Bamabu High Temperature Plate" +#~ msgid "QIDI High Temperature Plate" #~ msgstr "QIDI High Temperature Plate" #~ msgid "" diff --git a/resources/i18n/de/QIDIStudio.mo b/resources/i18n/de/QIDIStudio.mo index 04fad1e..31b2540 100644 Binary files a/resources/i18n/de/QIDIStudio.mo and b/resources/i18n/de/QIDIStudio.mo differ diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json new file mode 100644 index 0000000..a2afb8c --- /dev/null +++ b/src/.vscode/settings.json @@ -0,0 +1,104 @@ +{ + "files.associations": { + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "coroutine": "cpp", + "resumable": "cpp", + "functional": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "map": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "numeric": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "utility": "cpp", + "vector": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocnum": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp", + "stack": "cpp", + "iomanip": "cpp", + "dense": "cpp", + "filesystem": "cpp", + "chrono": "cpp", + "optional": "cpp", + "cassert": "cpp", + "complex": "cpp", + "bitset": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "codecvt": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "execution": "cpp", + "format": "cpp", + "forward_list": "cpp", + "fstream": "cpp", + "locale": "cpp", + "memory_resource": "cpp", + "queue": "cpp", + "random": "cpp", + "regex": "cpp", + "set": "cpp", + "shared_mutex": "cpp", + "sstream": "cpp", + "unordered_set": "cpp", + "valarray": "cpp", + "xfacet": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xloctime": "cpp", + "string_view": "cpp", + "geometry": "cpp", + "core": "cpp", + "cfloat": "cpp" + } +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9212b56..90c4633 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -274,6 +274,10 @@ else () COMMAND ln -sfn "zh_cn" "${BIN_RESOURCES_DIR}/i18n/zh_CN" COMMENT "Symlinking zh_CN language setting to zh_cn" VERBATIM) + add_custom_command(TARGET QIDIStudio POST_BUILD + COMMAND ln -sfn "pt-BR" "${BIN_RESOURCES_DIR}/i18n/pt_BR" + COMMENT "Symlinking pt_BR language setting to pt_BR" + VERBATIM) endif() endif () diff --git a/src/QIDIStudio.cpp b/src/QIDIStudio.cpp index 550182e..95dbb5d 100644 --- a/src/QIDIStudio.cpp +++ b/src/QIDIStudio.cpp @@ -149,6 +149,25 @@ std::map cli_errors = { {CLI_FILAMENT_UNPRINTABLE_ON_FIRST_LAYER, "Found some filament unprintable at first layer on current Plate. Please make sure the 3mf file can be successfully sliced with the same Plate type in the latest QIDI Studio."} }; +typedef struct _object_info{ + int id{0}; + std::string name; + size_t triangle_count{0}; + float bbox_x; + float bbox_y; + float bbox_z; + float bbox_width; + float bbox_depth; + float bbox_height; +}object_info_t; + +typedef struct _filament_info{ + int id{0}; + std::string filament_id; + float total_used_g {0.f}; + float main_used_g {0.f}; +}filament_info_t; + typedef struct _sliced_plate_info{ int plate_id{0}; size_t sliced_time {0}; @@ -159,6 +178,14 @@ typedef struct _sliced_plate_info{ size_t generate_support_material_time {0}; size_t triangle_count{0}; std::string warning_message; + + float total_predication{0.f}; + float main_predication{0.f}; + int filament_change_times {0}; + int layer_filament_change {0}; + + std::vector objects; + std::vector filaments; }sliced_plate_info_t; typedef struct _sliced_info { @@ -170,6 +197,7 @@ typedef struct _sliced_info { size_t export_time; std::vector upward_machines; std::vector downward_machines; + std::vector upward_compatibility_taint; }sliced_info_t; std::vector g_slicing_warnings; @@ -422,6 +450,8 @@ void record_exit_reson(std::string outputdir, int code, int plate_id, std::strin j["downward_compatible_machine"] = sliced_info.downward_machines; if (sliced_info.upward_machines.size() > 0) j["upward_compatible_machine"] = sliced_info.upward_machines; + if (sliced_info.upward_compatibility_taint.size() > 0) + j["upward_compatibility_taint"] = sliced_info.upward_compatibility_taint; j["plate_index"] = plate_id; j["return_code"] = code; j["error_string"] = error_message; @@ -430,16 +460,64 @@ void record_exit_reson(std::string outputdir, int code, int plate_id, std::strin for (size_t index = 0; index < sliced_info.sliced_plates.size(); index++) { json plate_json; - plate_json["id"] = sliced_info.sliced_plates[index].plate_id; - plate_json["sliced_time"] = sliced_info.sliced_plates[index].sliced_time; - plate_json["sliced_time_with_cache"] = sliced_info.sliced_plates[index].sliced_time_with_cache; - //1.9.5 - plate_json["make_perimeters_time"] = sliced_info.sliced_plates[index].make_perimeters_time; - plate_json["infill_time"] = sliced_info.sliced_plates[index].infill_time; - plate_json["generate_support_material_time"] = sliced_info.sliced_plates[index].generate_support_material_time; - plate_json["triangle_count"] = sliced_info.sliced_plates[index].triangle_count; - plate_json["warning_message"] = sliced_info.sliced_plates[index].warning_message; - j["sliced_plates"].push_back(plate_json); + sliced_plate_info_t& sliced_plate_info = sliced_info.sliced_plates[index]; + plate_json["id"] = sliced_plate_info.plate_id; + plate_json["sliced_time"] = sliced_plate_info.sliced_time; + plate_json["sliced_time_with_cache"] = sliced_plate_info.sliced_time_with_cache; + plate_json["make_perimeters_time"] = sliced_plate_info.make_perimeters_time; + plate_json["infill_time"] = sliced_plate_info.infill_time; + plate_json["generate_support_material_time"] = sliced_plate_info.generate_support_material_time; + plate_json["triangle_count"] = sliced_plate_info.triangle_count; + plate_json["warning_message"] = sliced_plate_info.warning_message; + + plate_json["total_predication"] = sliced_plate_info.total_predication; + plate_json["main_predication"] = sliced_plate_info.main_predication; + plate_json["filament_change_times"] = sliced_plate_info.filament_change_times; + plate_json["layer_filament_change"] = sliced_plate_info.layer_filament_change; + + //object info + if (!sliced_plate_info.objects.empty()) + { + for (size_t j = 0; j < sliced_plate_info.objects.size(); j++) + { + json object_json; + object_info_t& object = sliced_plate_info.objects[j]; + + object_json["id"] = object.id; + object_json["name"] = object.name; + object_json["triangle_count"] = object.triangle_count; + + json bbox_json; + bbox_json["x"] = object.bbox_x; + bbox_json["y"] = object.bbox_y; + bbox_json["z"] = object.bbox_z; + bbox_json["width"] = object.bbox_width; + bbox_json["depth"] = object.bbox_depth; + bbox_json["height"] = object.bbox_height; + object_json["bbox"] = bbox_json; + + plate_json["objects"].push_back(std::move(object_json)); + } + } + + //filament info + if (!sliced_plate_info.filaments.empty()) + { + for (size_t j = 0; j < sliced_plate_info.filaments.size(); j++) + { + json filament_json; + filament_info_t& filament = sliced_plate_info.filaments[j]; + + filament_json["id"] = filament.id; + filament_json["filament_id"] = filament.filament_id; + filament_json["total_used_g"] = filament.total_used_g; + filament_json["main_used_g"] = filament.main_used_g; + + plate_json["filaments"].push_back(std::move(filament_json)); + } + } + + j["sliced_plates"].push_back(std::move(plate_json)); } for (auto& iter: key_values) j[iter.first] = iter.second; @@ -1244,19 +1322,27 @@ int CLI::run(int argc, char **argv) /*BOOST_LOG_TRIVIAL(info) << "begin to setup params, argc=" << argc << std::endl; for (int index=0; index < argc; index++) BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <setup(debug_argc, debug_argv))*/ if (!this->setup(argc, argv)) @@ -3601,6 +3687,7 @@ int CLI::run(int argc, char **argv) } } + bool has_sequence_plates = false; int downward_check_size = downward_check_printers.size(); if (downward_check_size > 0) { @@ -3609,16 +3696,18 @@ int CLI::run(int argc, char **argv) int failed_count = 0; for (int index = 0; index < plate_count; index ++) { - if (failed_count == downward_check_size) { - BOOST_LOG_TRIVIAL(info) << boost::format("downward_check: all failed, size %1%")%downward_check_size; - break; - } Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index); Vec3d size = plate_obj_size_infos[index].obj_bbox.size(); //1.9.7.52 bool is_sequence = false; get_print_sequence(cur_plate, m_print_config, is_sequence); + has_sequence_plates |= is_sequence; + + if (failed_count == downward_check_size) { + BOOST_LOG_TRIVIAL(info) << boost::format("downward_check: all failed, size %1%")%downward_check_size; + break; + } for (int index2 = 0; index2 < downward_check_size; index2 ++) { @@ -3698,6 +3787,18 @@ int CLI::run(int argc, char **argv) } } } + else if (downward_check) { + int plate_count = partplate_list.get_plate_count(); + for (int index = 0; index < plate_count; index ++) + { + Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index); + bool is_sequence = false; + get_print_sequence(cur_plate, m_print_config, is_sequence); + has_sequence_plates |= is_sequence; + } + } + if (has_sequence_plates) + sliced_info.upward_compatibility_taint.push_back("PrintSequenceByObject"); // Loop through transform options. bool user_center_specified = false; @@ -5603,6 +5704,92 @@ int CLI::run(int argc, char **argv) sliced_plate_info.infill_time = slice_time[TIME_INFILL]; sliced_plate_info.generate_support_material_time = slice_time[TIME_GENERATE_SUPPORT]; + //get predication and filament change + PrintEstimatedStatistics& print_estimated_stat = gcode_result->print_statistics; + const PrintEstimatedStatistics::Mode& time_mode = print_estimated_stat.modes[static_cast(PrintEstimatedStatistics::ETimeMode::Normal)]; + auto it_wipe = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [](const std::pair& item) { return ExtrusionRole::erWipeTower == item.first; }); + sliced_plate_info.total_predication = time_mode.time; + sliced_plate_info.main_predication = time_mode.time - time_mode.prepare_time; + sliced_plate_info.filament_change_times = print_estimated_stat.total_filamentchanges; + if (it_wipe != time_mode.roles_times.end()) { + //filament changes time will be included in prime tower time later + //ConfigOptionFloat* machine_load_filament_time_opt = m_print_config.option("machine_load_filament_time"); + //ConfigOptionFloat* machine_unload_filament_time_opt = m_print_config.option("machine_unload_filament_time"); + sliced_plate_info.main_predication -= it_wipe->second; + //sliced_plate_info.main_predication -= sliced_plate_info.filament_change_times * (machine_load_filament_time_opt->value + machine_unload_filament_time_opt->value); + } + auto it_flush = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [](const std::pair& item) { return ExtrusionRole::erFlush == item.first; }); + if (it_flush != time_mode.roles_times.end()) { + sliced_plate_info.main_predication -= it_flush->second; + } + bool has_tool_change = false; + auto custom_gcodes_iter = model.plates_custom_gcodes.find(index); + if (custom_gcodes_iter != model.plates_custom_gcodes.end()) + { + CustomGCode::Info custom_gcodes = custom_gcodes_iter->second; + for (const Item& custom_gcode : custom_gcodes.gcodes) + if (custom_gcode.type == CustomGCode::ToolChange) { + has_tool_change = true; + break; + } + } + if (has_tool_change) + sliced_plate_info.layer_filament_change = print_estimated_stat.total_filamentchanges; + + //filaments + auto* filament_ids = dynamic_cast(m_print_config.option("filament_ids")); + std::vector filament_diameters = gcode_result->filament_diameters; + std::vector filament_densities = gcode_result->filament_densities; + + for (auto& iter : print_estimated_stat.total_volumes_per_extruder) + { + filament_info_t filament_info; + + filament_info.id = iter.first + 1; + filament_info.total_used_g = iter.second; + + if (filament_ids && (filament_info.id <= filament_ids->values.size())) + filament_info.filament_id = filament_ids->values[iter.first]; + else + filament_info.filament_id = "unknown"; + + auto main_iter = print_estimated_stat.model_volumes_per_extruder.find(iter.first); + if (main_iter != print_estimated_stat.model_volumes_per_extruder.end()) + filament_info.main_used_g = main_iter->second; + + auto support_iter = print_estimated_stat.support_volumes_per_extruder.find(iter.first); + if (support_iter != print_estimated_stat.support_volumes_per_extruder.end()) + filament_info.main_used_g += support_iter->second; + + double koef = 0.001; + //filament_info.main_used_m = koef * filament_info.main_used_m / (PI * sqr(0.5 * filament_diameters[filament_info.id])); + filament_info.main_used_g = koef * filament_info.main_used_g * filament_densities[iter.first]; + filament_info.total_used_g = koef * filament_info.total_used_g * filament_densities[iter.first]; + + sliced_plate_info.filaments.push_back(std::move(filament_info)); + } + + //objects + ModelObjectPtrs plate_objects = part_plate->get_objects_on_this_plate(); + for (ModelObject* object : plate_objects) + { + object_info_t object_info; + object_info.id = object->id().id; + object_info.name = object->name; + object_info.triangle_count = object->facets_count(); + + BoundingBoxf3 bbox_f = object->bounding_box(); + object_info.bbox_x = bbox_f.min.x(); + object_info.bbox_y = bbox_f.min.y(); + object_info.bbox_z = bbox_f.min.z(); + object_info.bbox_width = bbox_f.max.x() - object_info.bbox_x; + object_info.bbox_depth = bbox_f.max.y() - object_info.bbox_y; + object_info.bbox_height = bbox_f.max.z() - object_info.bbox_z; + + sliced_plate_info.objects.push_back(std::move(object_info)); + } + + if (max_slicing_time_per_plate != 0) { long long time_cost = end_time - start_time; //1.9.5 @@ -6687,8 +6874,8 @@ std::string CLI::output_filepath(const ModelObject &object, unsigned int index, // use --outputdir when available file_name = object.name.empty()?object.input_file:object.name; file_name = "obj_"+std::to_string(index)+"_"+file_name; - size_t pos = file_name.find_last_of(ext), ext_pos = file_name.size() - 1; - if (pos != ext_pos) + size_t pos = file_name.rfind(ext), ext_pos = file_name.size() - ext.size(); + if ((pos == std::string::npos) || (pos != ext_pos)) file_name += ext; BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << ": dir = "<< path_dir<<", file_name="<SetCornerRadius(0); // p->append_button(send_to_multi_app_btn); @@ -4031,15 +4031,15 @@ bool MainFrame::check_qdt_farm_client_installed() { #ifdef WIN32 HKEY hKey; - LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Bambulab\\Bambu Farm Manager Client"), 0, KEY_READ, &hKey); - LONG result_backup = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HKEY_CLASSES_ROOT\\bambu-farm-client\\shell\\open\\command"), 0, KEY_READ, &hKey); + LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\QIDITech\\QIDI Farm Manager Client"), 0, KEY_READ, &hKey); + LONG result_backup = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HKEY_CLASSES_ROOT\\qidi-farm-client\\shell\\open\\command"), 0, KEY_READ, &hKey); if (result == ERROR_SUCCESS || result_backup == ERROR_SUCCESS) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Bambu Farm Manager Client found."; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "QIDI Farm Manager Client found."; RegCloseKey(hKey); return true; } else { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "Bambu Farm Manager Client Not found."; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "QIDI Farm Manager Client Not found."; return false; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9432c5f..e3e86d0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -7599,8 +7599,8 @@ void Plater::priv::on_action_send_to_multi_app(SimpleEvent &) #ifdef WIN32 HKEY hKey; - LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Bambulab\\Bambu Farm Manager Client"), 0, KEY_READ, &hKey); - LONG result_backup = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HKEY_CLASSES_ROOT\\bambu-farm-client\\shell\\open\\command"), 0, KEY_READ, &hKey); + LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\QIDITech\\QIDI Farm Manager Client"), 0, KEY_READ, &hKey); + LONG result_backup = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HKEY_CLASSES_ROOT\\bqidi-farm-client\\shell\\open\\command"), 0, KEY_READ, &hKey); if (result == ERROR_SUCCESS || result_backup == ERROR_SUCCESS) { RegCloseKey(hKey); @@ -7624,14 +7624,14 @@ void Plater::priv::on_action_send_to_multi_app(SimpleEvent &) wxString filepath = wxString::FromUTF8(data._3mf_path.string()); filepath.Replace("\\", "/"); std::string filePath = "?version=v1.6.0&path=" + filepath.ToStdString() + "&name=" + filename.utf8_string(); - wxString url = "bambu-farm-client://upload-file" + Http::url_encode(filePath); + wxString url = "qidi-farm-client://upload-file" + Http::url_encode(filePath); if (!wxLaunchDefaultBrowser(url)) { - GUI::MessageDialog msgdialog(nullptr, _L("Failed to start Bambu Farm Manager Client."), "", wxAPPLY | wxOK); + GUI::MessageDialog msgdialog(nullptr, _L("Failed to start QIDI Farm Manager Client."), "", wxAPPLY | wxOK); msgdialog.ShowModal(); } } else { - GUI::MessageDialog msgdialog(nullptr, _L("No Bambu Farm Manager Client found."), "", wxAPPLY | wxOK); + GUI::MessageDialog msgdialog(nullptr, _L("No QIDI Farm Manager Client found."), "", wxAPPLY | wxOK); msgdialog.ShowModal(); } #endif // WIN32 diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 8d98d24..a7cba67 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -904,7 +904,7 @@ static wxString MACHINE_BED_TYPE_STRING[BED_TYPE_COUNT] = { _L("QIDI Cool Plate"), _L("QIDI Engineering Plate"), _L("QIDI Smooth PEI Plate") + "/" + _L("High temperature Plate"), - _L("Bamabu Textured PEI Plate"), + _L("QIDI Textured PEI Plate"), _L("QIDI Cool Plate SuperTack") }; diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index cf0b482..f4bef52 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -812,9 +812,9 @@ void WebViewPanel::SetMakerlabUrl(std::string url) { auto host = wxGetApp().get_model_http_url(wxGetApp().app_config->get_country_code()); std::string LabUrl; if (url == "") - LabUrl = (boost::format("%1%makerlab?from=bambustudio") % host).str(); + LabUrl = (boost::format("%1%makerlab?from=qidistudio") % host).str(); else - LabUrl = (boost::format("%1%%2%?from=bambustudio") % host % url).str(); + LabUrl = (boost::format("%1%%2%?from=qidistudio") % host % url).str(); m_MakerLab_LastUrl = LabUrl; } @@ -1740,9 +1740,9 @@ void WebViewPanel::SwitchWebContent(std::string modelname, int refresh) std::string strRegion = wxGetApp().app_config->get_country_code(); wxString MakerSupplyUrl; if (strRegion == "CN") - MakerSupplyUrl = "https://bambulab.tmall.com/category-1761686934.htm?from=bambustudio"; + MakerSupplyUrl = "https://qiditech.tmall.com/category-1761686934.htm?from=qidistudio"; else - MakerSupplyUrl = "https://store.bambulab.com/collections/makers-supply?from=bambustudio"; + MakerSupplyUrl = "https://store.qiditech.com/collections/makers-supply?from=qidistudio"; wxLaunchDefaultBrowser(MakerSupplyUrl); } diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp index fe7c4a9..3e2134a 100644 --- a/src/slic3r/Utils/NetworkAgent.cpp +++ b/src/slic3r/Utils/NetworkAgent.cpp @@ -276,8 +276,8 @@ int NetworkAgent::initialize_network_module(bool using_backup) connect_printer_ptr = reinterpret_cast(get_network_function("qidi_network_connect_printer")); disconnect_printer_ptr = reinterpret_cast(get_network_function("qidi_network_disconnect_printer")); send_message_to_printer_ptr = reinterpret_cast(get_network_function("qidi_network_send_message_to_printer")); - check_cert_ptr = reinterpret_cast(get_network_function("bambu_network_update_cert")); - install_device_cert_ptr = reinterpret_cast(get_network_function("bambu_network_install_device_cert")); + check_cert_ptr = reinterpret_cast(get_network_function("qidi_network_update_cert")); + install_device_cert_ptr = reinterpret_cast(get_network_function("qidi_network_install_device_cert")); start_discovery_ptr = reinterpret_cast(get_network_function("qidi_network_start_discovery")); change_user_ptr = reinterpret_cast(get_network_function("qidi_network_change_user")); is_user_login_ptr = reinterpret_cast(get_network_function("qidi_network_is_user_login"));