fix some bug

This commit is contained in:
QIDI TECH
2025-02-26 20:25:18 +08:00
parent ffb5d3da8a
commit a19b41c650
17 changed files with 511 additions and 79 deletions

View File

@@ -84,17 +84,26 @@ fi
DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release) DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release)
VERSION=$(awk -F= '/^VERSION_ID=/ {print $2}' /etc/os-release) VERSION=$(awk -F= '/^VERSION_ID=/ {print $2}' /etc/os-release)
# treat ubuntu as debian # OSLIKE is a space-delineated list of similar distributions
if [ "${DISTRIBUTION}" == "ubuntu" ] OSLIKE=$(awk -F= '/^ID_LIKE=/ {print $2}' /etc/os-release | tr -d '"')
then
DISTRIBUTION="debian" # Iterate over a list of candidate distribution targets, first match is used
fi for CANDIDATE in ${DISTRIBUTION} ${OSLIKE}; do
if [ ! -f ./linux.d/${DISTRIBUTION} ] if [ -f ./linux.d/${CANDIDATE} ]
then
TARGET_DISTRO="${CANDIDATE}"
break
fi
done
if [ -z ${TARGET_DISTRO} ]
then then
echo "Your distribution does not appear to be currently supported by these build scripts" echo "Your distribution does not appear to be currently supported by these build scripts"
exit 1 exit 1
fi 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}" echo "FOUND_GTK3=${FOUND_GTK3}"
if [[ -z "${FOUND_GTK3_DEV}" ]] if [[ -z "${FOUND_GTK3_DEV}" ]]

View File

@@ -9,7 +9,7 @@ set -x
# the simplicity of a single Docker image and a one-time compilation # the simplicity of a single Docker image and a one-time compilation
# seems better. # seems better.
docker build -t qidistudio \ docker build -t qidistudio \
--build-arg USER=$USER \ --build-arg USER=${USER:-root} \
--build-arg UID=$(id -u) \ --build-arg UID=$(id -u) \
--build-arg GID=$(id -g) \ --build-arg GID=$(id -g) \
$PROJECT_ROOT $PROJECT_ROOT

81
DockerEntrypoint.sh Normal file
View File

@@ -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 $*"

View File

@@ -5,15 +5,24 @@ set -x
# -h $HOSTNAME \ # -h $HOSTNAME \
# If there's problems with the X display, try this # If there's problems with the X display, try this
# -v /tmp/.X11-unix:/tmp/.X11-unix \ # -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 \ docker run \
`# Use the hosts networking. Printer wifi and also dbus communication` \ `# Use the hosts networking. Printer wifi and also dbus communication` \
--net=host \ --net=host \
`# Some X installs will not have permissions to talk to sockets for shared memory` \ `# Some X installs will not have permissions to talk to sockets for shared memory` \
--ipc host \ --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` \ `# 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` \ `# Pass the X display number to the container` \
-e DISPLAY=$DISPLAY \ -e DISPLAY=$DISPLAY \
`# It seems that libGL and dbus things need privileged mode` \ `# It seems that libGL and dbus things need privileged mode` \
@@ -24,4 +33,3 @@ docker run \
--rm \ --rm \
`# Pass all parameters from this script to the qidi ENTRYPOINT binary` \ `# Pass all parameters from this script to the qidi ENTRYPOINT binary` \
qidistudio $* qidistudio $*

View File

@@ -1,5 +1,4 @@
FROM docker.io/ubuntu:22.04 FROM docker.io/ubuntu:24.10
LABEL maintainer "DeftDawg <DeftDawg@gmail.com>"
# Disable interactive package configuration # Disable interactive package configuration
RUN apt-get update && \ RUN apt-get update && \
@@ -14,6 +13,7 @@ RUN apt-get update && apt-get install -y \
build-essential \ build-essential \
cmake \ cmake \
curl \ curl \
xvfb \
eglexternalplatform-dev \ eglexternalplatform-dev \
extra-cmake-modules \ extra-cmake-modules \
file \ file \
@@ -39,7 +39,6 @@ RUN apt-get update && apt-get install -y \
libssl-dev \ libssl-dev \
libudev-dev \ libudev-dev \
libwayland-dev \ libwayland-dev \
libwebkit2gtk-4.0-dev \
libxkbcommon-dev \ libxkbcommon-dev \
locales \ locales \
locales-all \ locales-all \
@@ -47,6 +46,7 @@ RUN apt-get update && apt-get install -y \
pkgconf \ pkgconf \
sudo \ sudo \
wayland-protocols \ wayland-protocols \
libwebkit2gtk-4.1-dev \
wget wget
# Change your locale here if you want. See the output # 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 # the CA cert path on every startup
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt 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 WORKDIR /QIDIStudio
# Update System dependencies
# 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 ./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 # Build dependencies in ./deps
RUN ./BuildLinux.sh -d RUN ./BuildLinux.sh -d
@@ -73,7 +111,7 @@ RUN ./BuildLinux.sh -d
RUN ./BuildLinux.sh -s RUN ./BuildLinux.sh -s
# Build AppImage # Build AppImage
ENV container podman ENV container=podman
RUN ./BuildLinux.sh -i RUN ./BuildLinux.sh -i
# It's easier to run QIDI Studio as the same username, # 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 # to keep permissions the same. Just in case, defaults
# are root. # are root.
SHELL ["/bin/bash", "-l", "-c"] SHELL ["/bin/bash", "-l", "-c"]
ARG USER=root
ARG UID=0 # Point FFMPEG Library search to the binary built upon QIDIStudio build time
ARG GID=0 ENV LD_LIBRARY_PATH=/QIDIStudio/build/package/bin
RUN [[ "$UID" != "0" ]] \
&& groupadd -f -g $GID $USER \
&& useradd -u $UID -g $GID $USER
# Using an entrypoint instead of CMD because the binary # Using an entrypoint instead of CMD because the binary
# accepts several command line arguments. # 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"]

View File

@@ -6814,16 +6814,16 @@ msgstr "Beschäftigt"
msgid "QIDI Cool Plate" msgid "QIDI Cool Plate"
msgstr "QIDI Cool Plate" msgstr "QIDI Cool Plate"
msgid "Bamabu Engineering Plate" msgid "QIDI Engineering Plate"
msgstr "QIDI Engineering Plate" msgstr "QIDI Engineering Plate"
msgid "Bamabu Smooth PEI Plate" msgid "QIDI Smooth PEI Plate"
msgstr "QIDI Smooth PEI Plate" msgstr "QIDI Smooth PEI Plate"
msgid "High temperature Plate" msgid "High temperature Plate"
msgstr "High temperature Plate" msgstr "High temperature Plate"
msgid "Bamabu Textured PEI Plate" msgid "QIDI Textured PEI Plate"
msgstr "QIDI Textured PEI Plate" msgstr "QIDI Textured PEI Plate"
msgid "QIDI Cool Plate SuperTack" msgid "QIDI Cool Plate SuperTack"
@@ -14784,7 +14784,7 @@ msgstr ""
#~ msgid "Backup interval" #~ msgid "Backup interval"
#~ msgstr "Sicherungsintervall" #~ msgstr "Sicherungsintervall"
#~ msgid "Bamabu High Temperature Plate" #~ msgid "QIDI High Temperature Plate"
#~ msgstr "QIDI High Temperature Plate" #~ msgstr "QIDI High Temperature Plate"
#~ msgid "" #~ msgid ""

Binary file not shown.

104
src/.vscode/settings.json vendored Normal file
View File

@@ -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"
}
}

View File

@@ -274,6 +274,10 @@ else ()
COMMAND ln -sfn "zh_cn" "${BIN_RESOURCES_DIR}/i18n/zh_CN" COMMAND ln -sfn "zh_cn" "${BIN_RESOURCES_DIR}/i18n/zh_CN"
COMMENT "Symlinking zh_CN language setting to zh_cn" COMMENT "Symlinking zh_CN language setting to zh_cn"
VERBATIM) 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()
endif () endif ()

View File

@@ -149,6 +149,25 @@ std::map<int, std::string> 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."} {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{ typedef struct _sliced_plate_info{
int plate_id{0}; int plate_id{0};
size_t sliced_time {0}; size_t sliced_time {0};
@@ -159,6 +178,14 @@ typedef struct _sliced_plate_info{
size_t generate_support_material_time {0}; size_t generate_support_material_time {0};
size_t triangle_count{0}; size_t triangle_count{0};
std::string warning_message; 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<object_info_t> objects;
std::vector<filament_info_t> filaments;
}sliced_plate_info_t; }sliced_plate_info_t;
typedef struct _sliced_info { typedef struct _sliced_info {
@@ -170,6 +197,7 @@ typedef struct _sliced_info {
size_t export_time; size_t export_time;
std::vector<std::string> upward_machines; std::vector<std::string> upward_machines;
std::vector<std::string> downward_machines; std::vector<std::string> downward_machines;
std::vector<std::string> upward_compatibility_taint;
}sliced_info_t; }sliced_info_t;
std::vector<PrintBase::SlicingStatus> g_slicing_warnings; std::vector<PrintBase::SlicingStatus> 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; j["downward_compatible_machine"] = sliced_info.downward_machines;
if (sliced_info.upward_machines.size() > 0) if (sliced_info.upward_machines.size() > 0)
j["upward_compatible_machine"] = sliced_info.upward_machines; 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["plate_index"] = plate_id;
j["return_code"] = code; j["return_code"] = code;
j["error_string"] = error_message; 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++) for (size_t index = 0; index < sliced_info.sliced_plates.size(); index++)
{ {
json plate_json; json plate_json;
plate_json["id"] = sliced_info.sliced_plates[index].plate_id; sliced_plate_info_t& sliced_plate_info = sliced_info.sliced_plates[index];
plate_json["sliced_time"] = sliced_info.sliced_plates[index].sliced_time; plate_json["id"] = sliced_plate_info.plate_id;
plate_json["sliced_time_with_cache"] = sliced_info.sliced_plates[index].sliced_time_with_cache; plate_json["sliced_time"] = sliced_plate_info.sliced_time;
//1.9.5 plate_json["sliced_time_with_cache"] = sliced_plate_info.sliced_time_with_cache;
plate_json["make_perimeters_time"] = sliced_info.sliced_plates[index].make_perimeters_time; plate_json["make_perimeters_time"] = sliced_plate_info.make_perimeters_time;
plate_json["infill_time"] = sliced_info.sliced_plates[index].infill_time; plate_json["infill_time"] = sliced_plate_info.infill_time;
plate_json["generate_support_material_time"] = sliced_info.sliced_plates[index].generate_support_material_time; plate_json["generate_support_material_time"] = sliced_plate_info.generate_support_material_time;
plate_json["triangle_count"] = sliced_info.sliced_plates[index].triangle_count; plate_json["triangle_count"] = sliced_plate_info.triangle_count;
plate_json["warning_message"] = sliced_info.sliced_plates[index].warning_message; plate_json["warning_message"] = sliced_plate_info.warning_message;
j["sliced_plates"].push_back(plate_json);
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) for (auto& iter: key_values)
j[iter.first] = iter.second; 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; /*BOOST_LOG_TRIVIAL(info) << "begin to setup params, argc=" << argc << std::endl;
for (int index=0; index < argc; index++) for (int index=0; index < argc; index++)
BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <<std::endl; BOOST_LOG_TRIVIAL(info) << "index="<< index <<", arg is "<< argv[index] <<std::endl;
int debug_argc = 11; int debug_argc = 5;
char *debug_argv[] = { char* debug_argv[] = {
"F:\work\projects\qidi_debug\qidi_slicer\build_debug\src\Debug\qidi-studio.exe", "F:\work\projects\qidi_debug\qidi_slicer\build_debug\src\Debug\qidi-studio.exe",
"--debug=2", "--debug=2",
"--load-settings", //"--uptodate",
"machine.json;process.json", //"--load-settings",
"--load-filaments", //"machine_A1.json",
"filament.json;filament.json;filament.json;filament.json;filament.json;filament.json", //"--load-defaultfila",
//"--load-filaments",
//"filament_pla_basic_A1.json;filament_pla_basic_A1.json",
"--export-3mf=output.3mf", "--export-3mf=output.3mf",
"--filament-colour", //"--filament-colour",
"#FFFFFFFF;#0000FFFF;#00FF00FF;#FF0000FF;#00000000;#FFFF00FF", //"#CD056D;#702829",
//"--nozzle-volume-type",
//"Standard,High Flow",
//"--filament-map-mode",
//"Auto",
//"--filament-map",
//"1,2,1,2",
"--slice=0", "--slice=0",
"1.3mf" "stl_test.3mf"
}; };
if (! this->setup(debug_argc, debug_argv))*/ if (! this->setup(debug_argc, debug_argv))*/
if (!this->setup(argc, 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(); int downward_check_size = downward_check_printers.size();
if (downward_check_size > 0) if (downward_check_size > 0)
{ {
@@ -3609,16 +3696,18 @@ int CLI::run(int argc, char **argv)
int failed_count = 0; int failed_count = 0;
for (int index = 0; index < plate_count; index ++) 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); Slic3r::GUI::PartPlate* cur_plate = (Slic3r::GUI::PartPlate *)partplate_list.get_plate(index);
Vec3d size = plate_obj_size_infos[index].obj_bbox.size(); Vec3d size = plate_obj_size_infos[index].obj_bbox.size();
//1.9.7.52 //1.9.7.52
bool is_sequence = false; bool is_sequence = false;
get_print_sequence(cur_plate, m_print_config, is_sequence); 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 ++) 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. // Loop through transform options.
bool user_center_specified = false; 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.infill_time = slice_time[TIME_INFILL];
sliced_plate_info.generate_support_material_time = slice_time[TIME_GENERATE_SUPPORT]; 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<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)];
auto it_wipe = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [](const std::pair<ExtrusionRole, float>& 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<ConfigOptionFloat>("machine_load_filament_time");
//ConfigOptionFloat* machine_unload_filament_time_opt = m_print_config.option<ConfigOptionFloat>("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<ExtrusionRole, float>& 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<const ConfigOptionStrings*>(m_print_config.option("filament_ids"));
std::vector<float> filament_diameters = gcode_result->filament_diameters;
std::vector<float> 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) { if (max_slicing_time_per_plate != 0) {
long long time_cost = end_time - start_time; long long time_cost = end_time - start_time;
//1.9.5 //1.9.5
@@ -6687,8 +6874,8 @@ std::string CLI::output_filepath(const ModelObject &object, unsigned int index,
// use --outputdir when available // use --outputdir when available
file_name = object.name.empty()?object.input_file:object.name; file_name = object.name.empty()?object.input_file:object.name;
file_name = "obj_"+std::to_string(index)+"_"+file_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; size_t pos = file_name.rfind(ext), ext_pos = file_name.size() - ext.size();
if (pos != ext_pos) if ((pos == std::string::npos) || (pos != ext_pos))
file_name += ext; file_name += ext;
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << ": dir = "<< path_dir<<", file_name="<<file_name<< ", pos = "<<pos<<", ext_pos="<<ext_pos; BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << ": dir = "<< path_dir<<", file_name="<<file_name<< ", pos = "<<pos<<", ext_pos="<<ext_pos;

View File

@@ -370,7 +370,7 @@ static constexpr const char *FONT_WEIGHT_ATTR = "weight";
// Store / load of EmbossShape // Store / load of EmbossShape
static constexpr const char *OLD_SHAPE_TAG = "slic3rpe:shape"; static constexpr const char *OLD_SHAPE_TAG = "slic3rpe:shape";
static constexpr const char *SHAPE_TAG = "BambuStudioShape"; static constexpr const char *SHAPE_TAG = "QIDIStudioShape";
static constexpr const char *SHAPE_SCALE_ATTR = "scale"; static constexpr const char *SHAPE_SCALE_ATTR = "scale";
static constexpr const char *UNHEALED_ATTR = "unhealed"; static constexpr const char *UNHEALED_ATTR = "unhealed";
static constexpr const char *SVG_FILE_PATH_ATTR = "filepath"; static constexpr const char *SVG_FILE_PATH_ATTR = "filepath";

View File

@@ -4590,7 +4590,7 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
} }
else if (status == 400 && code == HttpErrorCertRevoked) { else if (status == 400 && code == HttpErrorCertRevoked) {
if (!m_show_error_msgdlg) { if (!m_show_error_msgdlg) {
MessageDialog msg_dlg(nullptr, _L("Your software certificate has been revoked, please update Bambu Studio software."), "", wxAPPLY | wxOK); MessageDialog msg_dlg(nullptr, _L("Your software certificate has been revoked, please update QIDI Studio software."), "", wxAPPLY | wxOK);
m_show_error_msgdlg = true; m_show_error_msgdlg = true;
auto modal_result = msg_dlg.ShowModal(); auto modal_result = msg_dlg.ShowModal();
m_show_error_msgdlg = false; m_show_error_msgdlg = false;
@@ -5025,7 +5025,7 @@ void GUI_App::process_network_msg(std::string dev_id, std::string msg)
else if (msg == "update_studio") { else if (msg == "update_studio") {
BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_studio"; BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_studio";
if (!m_show_error_msgdlg) { if (!m_show_error_msgdlg) {
MessageDialog msg_dlg(nullptr, _L("Please try updating Bambu Studio and then try again."), "", wxAPPLY | wxOK); MessageDialog msg_dlg(nullptr, _L("Please try updating QIDI Studio and then try again."), "", wxAPPLY | wxOK);
m_show_error_msgdlg = true; m_show_error_msgdlg = true;
auto modal_result = msg_dlg.ShowModal(); auto modal_result = msg_dlg.ShowModal();
m_show_error_msgdlg = false; m_show_error_msgdlg = false;
@@ -5034,7 +5034,7 @@ void GUI_App::process_network_msg(std::string dev_id, std::string msg)
else if (msg == "update_fixed_studio") { else if (msg == "update_fixed_studio") {
BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_fixed_studio"; BOOST_LOG_TRIVIAL(info) << "process_network_msg, update_fixed_studio";
if (!m_show_error_msgdlg) { if (!m_show_error_msgdlg) {
MessageDialog msg_dlg(nullptr, _L("Please try updating Bambu Studio and then try again."), "", wxAPPLY | wxOK); MessageDialog msg_dlg(nullptr, _L("Please try updating QIDI Studio and then try again."), "", wxAPPLY | wxOK);
m_show_error_msgdlg = true; m_show_error_msgdlg = true;
auto modal_result = msg_dlg.ShowModal(); auto modal_result = msg_dlg.ShowModal();
m_show_error_msgdlg = false; m_show_error_msgdlg = false;
@@ -5043,7 +5043,7 @@ void GUI_App::process_network_msg(std::string dev_id, std::string msg)
else if (msg == "cert_expired") { else if (msg == "cert_expired") {
BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_expired"; BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_expired";
if (!m_show_error_msgdlg) { if (!m_show_error_msgdlg) {
MessageDialog msg_dlg(nullptr, _L("The certificate has expired. Please check the time settings or update Bambu Studio and try again."), "", wxAPPLY | wxOK); MessageDialog msg_dlg(nullptr, _L("The certificate has expired. Please check the time settings or update QIDI Studio and try again."), "", wxAPPLY | wxOK);
m_show_error_msgdlg = true; m_show_error_msgdlg = true;
auto modal_result = msg_dlg.ShowModal(); auto modal_result = msg_dlg.ShowModal();
m_show_error_msgdlg = false; m_show_error_msgdlg = false;
@@ -5052,7 +5052,7 @@ void GUI_App::process_network_msg(std::string dev_id, std::string msg)
else if (msg == "cert_revoked") { else if (msg == "cert_revoked") {
BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_revoked"; BOOST_LOG_TRIVIAL(info) << "process_network_msg, cert_revoked";
if (!m_show_error_msgdlg) { if (!m_show_error_msgdlg) {
MessageDialog msg_dlg(nullptr, _L("The certificate is no longer valid and the printing functions are unavailable. If you need printing. Please visit the official website at https://bambulab.com/ to download and update."), "", wxAPPLY | wxOK); MessageDialog msg_dlg(nullptr, _L("The certificate is no longer valid and the printing functions are unavailable. If you need printing. Please visit the official website at https://qidi3d.com/ to download and update."), "", wxAPPLY | wxOK);
m_show_error_msgdlg = true; m_show_error_msgdlg = true;
auto modal_result = msg_dlg.ShowModal(); auto modal_result = msg_dlg.ShowModal();
m_show_error_msgdlg = false; m_show_error_msgdlg = false;

View File

@@ -1889,7 +1889,7 @@ wxBoxSizer* MainFrame::create_side_tools()
//y //y
// if (check_qdt_farm_client_installed()) { // if (check_qdt_farm_client_installed()) {
// SideButton *send_to_multi_app_btn = new SideButton(p, _L("Send to Bambu Farm Manager Client"), ""); // SideButton *send_to_multi_app_btn = new SideButton(p, _L("Send to QIDI Farm Manager Client"), "");
// send_to_multi_app_btn->SetCornerRadius(0); // send_to_multi_app_btn->SetCornerRadius(0);
// p->append_button(send_to_multi_app_btn); // p->append_button(send_to_multi_app_btn);
@@ -4031,15 +4031,15 @@ bool MainFrame::check_qdt_farm_client_installed()
{ {
#ifdef WIN32 #ifdef WIN32
HKEY hKey; HKEY hKey;
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Bambulab\\Bambu Farm Manager Client"), 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\\bambu-farm-client\\shell\\open\\command"), 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) { 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); RegCloseKey(hKey);
return true; return true;
} else { } 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; return false;
} }

View File

@@ -7599,8 +7599,8 @@ void Plater::priv::on_action_send_to_multi_app(SimpleEvent &)
#ifdef WIN32 #ifdef WIN32
HKEY hKey; HKEY hKey;
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Bambulab\\Bambu Farm Manager Client"), 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\\bambu-farm-client\\shell\\open\\command"), 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) { if (result == ERROR_SUCCESS || result_backup == ERROR_SUCCESS) {
RegCloseKey(hKey); RegCloseKey(hKey);
@@ -7624,14 +7624,14 @@ void Plater::priv::on_action_send_to_multi_app(SimpleEvent &)
wxString filepath = wxString::FromUTF8(data._3mf_path.string()); wxString filepath = wxString::FromUTF8(data._3mf_path.string());
filepath.Replace("\\", "/"); filepath.Replace("\\", "/");
std::string filePath = "?version=v1.6.0&path=" + filepath.ToStdString() + "&name=" + filename.utf8_string(); 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)) { 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(); msgdialog.ShowModal();
} }
} else { } 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(); msgdialog.ShowModal();
} }
#endif // WIN32 #endif // WIN32

View File

@@ -904,7 +904,7 @@ static wxString MACHINE_BED_TYPE_STRING[BED_TYPE_COUNT] = {
_L("QIDI Cool Plate"), _L("QIDI Cool Plate"),
_L("QIDI Engineering Plate"), _L("QIDI Engineering Plate"),
_L("QIDI Smooth PEI Plate") + "/" + _L("High temperature 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") _L("QIDI Cool Plate SuperTack")
}; };

View File

@@ -812,9 +812,9 @@ void WebViewPanel::SetMakerlabUrl(std::string url) {
auto host = wxGetApp().get_model_http_url(wxGetApp().app_config->get_country_code()); auto host = wxGetApp().get_model_http_url(wxGetApp().app_config->get_country_code());
std::string LabUrl; std::string LabUrl;
if (url == "") if (url == "")
LabUrl = (boost::format("%1%makerlab?from=bambustudio") % host).str(); LabUrl = (boost::format("%1%makerlab?from=qidistudio") % host).str();
else 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; 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(); std::string strRegion = wxGetApp().app_config->get_country_code();
wxString MakerSupplyUrl; wxString MakerSupplyUrl;
if (strRegion == "CN") if (strRegion == "CN")
MakerSupplyUrl = "https://bambulab.tmall.com/category-1761686934.htm?from=bambustudio"; MakerSupplyUrl = "https://qiditech.tmall.com/category-1761686934.htm?from=qidistudio";
else else
MakerSupplyUrl = "https://store.bambulab.com/collections/makers-supply?from=bambustudio"; MakerSupplyUrl = "https://store.qiditech.com/collections/makers-supply?from=qidistudio";
wxLaunchDefaultBrowser(MakerSupplyUrl); wxLaunchDefaultBrowser(MakerSupplyUrl);
} }

View File

@@ -276,8 +276,8 @@ int NetworkAgent::initialize_network_module(bool using_backup)
connect_printer_ptr = reinterpret_cast<func_connect_printer>(get_network_function("qidi_network_connect_printer")); connect_printer_ptr = reinterpret_cast<func_connect_printer>(get_network_function("qidi_network_connect_printer"));
disconnect_printer_ptr = reinterpret_cast<func_disconnect_printer>(get_network_function("qidi_network_disconnect_printer")); disconnect_printer_ptr = reinterpret_cast<func_disconnect_printer>(get_network_function("qidi_network_disconnect_printer"));
send_message_to_printer_ptr = reinterpret_cast<func_send_message_to_printer>(get_network_function("qidi_network_send_message_to_printer")); send_message_to_printer_ptr = reinterpret_cast<func_send_message_to_printer>(get_network_function("qidi_network_send_message_to_printer"));
check_cert_ptr = reinterpret_cast<func_check_cert>(get_network_function("bambu_network_update_cert")); check_cert_ptr = reinterpret_cast<func_check_cert>(get_network_function("qidi_network_update_cert"));
install_device_cert_ptr = reinterpret_cast<func_install_device_cert>(get_network_function("bambu_network_install_device_cert")); install_device_cert_ptr = reinterpret_cast<func_install_device_cert>(get_network_function("qidi_network_install_device_cert"));
start_discovery_ptr = reinterpret_cast<func_start_discovery>(get_network_function("qidi_network_start_discovery")); start_discovery_ptr = reinterpret_cast<func_start_discovery>(get_network_function("qidi_network_start_discovery"));
change_user_ptr = reinterpret_cast<func_change_user>(get_network_function("qidi_network_change_user")); change_user_ptr = reinterpret_cast<func_change_user>(get_network_function("qidi_network_change_user"));
is_user_login_ptr = reinterpret_cast<func_is_user_login>(get_network_function("qidi_network_is_user_login")); is_user_login_ptr = reinterpret_cast<func_is_user_login>(get_network_function("qidi_network_is_user_login"));