[PSA] Avoid QIDI products (code review post)
▲ 29 r/QidiTech3D+1 crossposts

[PSA] Avoid QIDI products (code review post)

Introduction

So, I recently bought my first 3D printer (hurray!).

Now, it is worth noting I have zero experience in either 3D printing or 3D design. I am a software engineer by trade, a teamlead/techlead as of last few years. So, naturally software was what I paid attention to when choosing a printer.

My first stop was Bambu, but a bit of research showed they: α) Try to lock people down to their cloud, β) lack some features in their software depending on if you use Windows, Linux or Mac, γ) Run proprietary firmware on their printers.

Being an experienced software engineer I see problems in each point.

Next stop was QIDI, which doesn't seem to have either of those, at least that I'm aware of. But more importantly — even if I'm wrong, since they're using open source firmware, any unwanted features are easily removable.

To those of you not familiar with what "open source" is — it's like when you have a site like "yeggi" or "printables", where you can download a model, freely change it to your liking, and potentially send it back to the author "Hi, I improved your model, figured I'd show you in case you might want to incorporate them". The most beneficial part to you as a customer is not that you can edit it, but that someone can edit it and you will benefit for free.

That's to say, I wasn't planning to do any modifications to the printer firmware, but I know there will be some enthusiasts who are interested in improving the internals, which I as a QIDI customer would benefit from. Also, being open-source means the company can't lock you down to a cloud — people would just create their own firmware with this lock removed, which everyone would use since.

In hindsight, I should've done more research, because what I said is only partially true, but more on that later. In my defense — I know nothing is perfect and there's nothing ideal. I know there are problems with every vendor (wasn't expecting it is that bad with QIDI), and every software for that matter. So I only checked the most obvious problems and went on buying QIDI Plus4 printer.

It's going to be a longread — feel free to skip to the "Conclusions" section at the bottom. For those who will read it: well, I hope you'll have some fun. It ain't a fun situation for me as a QIDI customer, but… the printer does work, and I guess I'll just avoid updating my printer firmware 😉

First impressions

When my QIDI Tech (X-)Plus4 arrived, first thing I did was trying to update the firmware. Now, I think it's worth making a sidenote: if you're used to seeing software updates as a bad thing, that's something specific to proprietary ecosystem. I saw it with my MetaQuest3 headset as well. But in open-source (which QIDI Plus4 fw is) world new updates usually mean better performance and more features, so there was no reason for me to hesitate.

Well, printer told me there's a 1.8.2 update, but downloading it fails. "That's fine" I thought to myself. I live in a country with exceptionally poor internet (country-wide, that is), so the situation isn't unusual. I went looking for a version downloadable via a browser, which is when my first concern appeared…

The repo is this https://github.com/QIDITECH/QIDI_PLUS4. See any problems yet? The expected URL is this https://github.com/klipper3d/klipper. It's very different, right? It turns out QIDI just forked away Klipper and started developing it separately (well, "trying" to, I'd say).

Okay. That's fine. I just need the release, right? That's when the second oddity appeared… the "releases" page only has 1.7.1 as the latest version. Alright, I updated to it and reported a bug. I phrased it in a kinda stupid way — as a printer suggesting a non-existing update. I prefer to stick to Hanlon's razor, which suggests that's nobody's fault but the firmware is buggy. It may not be true, but let them figure that out.

QIDI Studio: first appearance

A few days passed, I successfully made my first prints, yay! Learned about slicers, had some jams due to me not setting up the temperature correctly… I'm happy overall and per my understanding, unless you're up to buying RFID-based filament spools (which I wasn't going to), the experience is ± same as with other printers.

But a thing that bugged me: why can't I add the printer to my slicer to send prints via LAN instead of carrying a USB stick each time…?

Well, apparently it works via QIDIStudio. So I installed it, added the printer and… it crashed. From that point on it was crashing on every launch.

It was the first time I heard about QIDIStudio and I didn't know if it was open-source, so I just searched for a way to report a bug and was referred to this Wiki page.

Now, I hope they'll fix the page, but as of a week ago it has no mention of Github, instead it says I should email the support via some unspecific email address. On the company site I found a dozen of different emails, none of which were relevant, so I just emailed to one related to Plus4 printer and asked to redirect if it's the wrong one.

Sent them logs that I could find and the stacktrace, which points at WebKit as source of crash. Please remember that, this is important.

After a bit of back-and-forth with the support they told me, quoting:

> First, remove the printer from your settings; then, when adding the printer again, add the port number 7125. > > Due to a conflict with WebKit in Linux, the software may crash. It is recommended to manually add the port number 7125 when adding a device.

The studio has no way to add a port, but I blindly typed it in via a colon and that worked. Crash was resolved.

Now, unless a software engineer, you'd probably take their words for granted: there's some incompatibility with some WebKit, okay… To me though that sounds weird. First of, the quote on 7125 is taken from here and there's no bugreport link to WebKit. It's just their own claim — no link to research/discussion, nothing.

But more importantly: no way it could be a bug anywhere but the studio itself. You see: when software connects to an IP, it trivially needs to know a port to connect to. Studio crashed because it didn't know a port (it is trivially derivable from the fact that adding it manually fixes the problem). The crash may reside inside WebKit, but it is obvious that WebKit wouldn't know where to connect if Studio didn't provide it with a port, which it doesn't.

"But it is a crash in WebKit, isn't it??" — you might ask. Well, let's clarify: it is inside libwebkit, which is a library that provides functions for other software. Missing port apparently results in libwebkit receiving some uninitialized data and crashing. Is that WebKit's problem? Actually, no. For performance reasons low-level libraries often lack parameter-checking (unless debugging is on), and rely on the user to provide the correct ones. It is a common practice, and if you ever coded in C or C++ you'd see sometimes crashes inside the standard library, which are actually caused by using it wrong.

What I just explained is one of the first things C and C++ programmers learn. And QIDI Studio is written in C++. If some QIDI software engineer looked at the stacktrace, saw the crash in libwebkit, and immediately concluded "it must be a WebKit bug" — that alone sets their quality to maybe around a junior level, no way any higher. It's the kind of question you can ask while interviewing a low-level programmer, except maybe not as directly because it would be too easy to figure out the answer.

At that point I already found the Github project page, and found multiple issues on that matter, such as this one, where their engineer recommends to set port 7125, and refers to this even older issue from year 2024.

QIDI Studio: code quality

First look

Now that I could guess the quality of QIDI software engineers (which by the end of this article is confirmed), I decided to see how long would it take me to fix the bug. Assuming I built the studio (which may take some time), I estimated the fix to be in around 15 minutes despite me not knowing the code.

First thing I did was looking at the commit history. And… it is not good, to put it mildly. The commit messages look like "Update deps", "Update main.yml", "update resource"… You see, in sw engineering the history is very important. I'm not going into details because that would bloat the article too much, but you can read this "old but gold" article by a HID subsystem kernel maintainer. The TL;DR is that commits must have descriptive names and only contain a single functional change (which is a vague concept that new programmers often struggle with).

My favorite commit message from QIDI Studio is "fix some bug". The commit removes some commented out code and uncomments a few lines. This reads as if the author is like "Dunno man, I did something and it fixed some bug. It's not much but it's an honest work".

I also looked through crash-related bug reports and found this funny one. It is a crash when moving QIDI Studio between multiple monitors. It's like, how do you even design a GUI app in such a way that it would crash upon moving? 🤷‍♂️ I understand a game could — but for an app that just uses a toolkit to render UI it is really hard to accidentally introduce a crash during movement between displays; yet somehow QIDI managed to. Not only they did — but the report stays unfixed since year 2024!

Building

Alright, enough slacking around, let's get to work.

The project uses CMake as the build system. I tried to build it directly on my Arch, but apparently newer Boost library introduced some incompatible changes, and since the Studio provides their own scripts for building on Fedora, to make it faster (me being naive lol) I popped up a Fedora container and tried running ./BuildLinux.sh (and then ./BuildFedora.sh.).

The scripts didn't work due to a lack of executable bit. That's a weird problem, because it's literally the first thing you stumble upon. My theory is QIDI engineers don't use them, but if anything that only makes things look worse, since that implies they have these scripts that not even CI is testing.

Whatever, it's a 30 seconds fix, I sent a PR and moved on.

Attempting to build results in error you must install the dependencies before. Use option -u with sudo". Inspecting the file revealed very interesting variables FOUND_GTK2_DEV and FOUND_GTK3_DEV, where the first one is never set and the second one is unconditionally set to 1.

The script also mentions a comment # for ubuntu 22.04, completely unrelated to the script functional (which is about Fedora). Odd.

Alright, let's try installing the deps:

[root@74be7385f7d7 project]# ./BuildFedora.sh -u
Updating linux ...
./BuildFedora.sh: line 104: apt: command not found

Find libgtk-3, installing: libgtk-3-dev libglew-dev libudev-dev libdbus-1-dev cmake git

./BuildFedora.sh: line 111: apt: command not found
done

[root@74be7385f7d7 project]# echo $?
0

There's sooo much wrong with it… I don't even know where to start. Well, for one, Fedora-specific script tries to use apt, which is a Ubuntu/Debian-specific utility. And when that fails, it just proceeds as if nothing happened! Then comes second failure — and again, the script is like "it's okay, everything's fine". And at the end it just prints done, and then I made sure to check the last command exitcode — and sure enough, it is 0, meaning "success".

So, anyway, I figured I'd just pop up a Ubuntu container and build the Studio there. So I did and I successfully installed the deps via the ./BuildFedora.sh script (fun).

Then I tried to build via ./BuildFedora.sh -b and… it built instantly! Wow, I mean, my laptop isn't the weakest, but for a moment I felt like I'm running a quantum computer, instant solution!

"What ingenuous algorithm could that be??" I wondered, and after looking at build dir everything became clear — it's empty. Inspecting the "help" output showed a suggestion at the bottom to use -dsi params to re-build. Two of them are marked optional, but I decided to try going the exact path (presumably) paved by the devs.

That produced long scrollback of building deps they decided to ship inside the repo, and in the quickly disappearing scrollback I frequently saw RED lines that looked like build errors — which didn't stop the build though. At some point build did fail.

And here it is interesting that building never produces an error exit code:

CMake Error at src/libslic3r/CMakeLists.txt:518 (find_package):
  […]
-- Configuring incomplete, errors occurred!
done
[8/9] Building Slic3r...
make: *** No rule to make target 'QIDIStudio'.  Stop.
/project
done
[02.07.2026-23:12:48] UBUNTU  /project ‹node-›  ‹›
╰─$ echo $?
0

Anyway, let me spare you of all the gory details: the process of building was more or less similar to what I just mentioned — get some errors, resolve, repeat. One interesting thing to note though: the deps installation actually lacked a lot of required deps and I had to install them manually on each error and re-run rebuild.

In the end it failed because their configuration is looking for some UserPresetSyncManager.cpp file:

CMake Error at src/slic3r/CMakeLists.txt:728 (add_library):
  Cannot find source file:

    QIDI/UserPresetSyncManager.cpp

  Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm
  .ccm .cxxm .c++m .h .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90
  .f95 .f03 .hip .ispc


CMake Error at src/slic3r/CMakeLists.txt:728 (add_library):
  No SOURCES given to target: libslic3r_gui

…which just doesn't exist. I searched over entire repo and build directory, and even used case-insensitive match just in case find -type f -name UserPresetSyncManager.cpp, to no avail.

So… QIDIStudio isn't even buildable.

So what gives, we don't know how to fix the infamous crash?

Well, I wasn't done yet. Even though I can't build and test my theories, but I at least could try to find where exactly the port is being added, just to see the logic.

I launched QIDIStudio (the official executable), spotted a label text in part of the GUI for adding the printers, and git-grepped by text Hostname, IP over their repo. That gave me a location in PrintConfig.cpp, and after inspecting the surrounding code a bit I figured they use print_host string as a key, which should then be used in other logic.

I git-grepped for this string and got a wall of locations referencing print_host in some way. After inspecting which ones seem to be setting print_host (as opposed to reading), I came to a function PhysicalPrinterDialog::OnOK() with this code snippet:

    m_printer_host = boost::any_cast<std::string>(m_optgroup->get_field("print_host")->get_value());
[…]
    m_config->set_key_value("print_host", new ConfigOptionString(m_printer_host));

Is that it? I looked around and found where the m_optgroup's print_host is being set:

void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgroup)
[…]
        m_printhost_browse_btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent& e) {
[…]
                m_optgroup->set_value("print_host", from_u8(get_host), true);

This looks like the "Browse" dialog which finds the printer on the Network, so it seems I am looking at the right code.

So, what's the solution to this wicked "WebKit bug" that poor QIDI engineers were unsuccessfully trying to solve since 2024 year? Well, the m_printer_host is just an std::string, so the solution is as simple as adding a + ":7125" to the aforementioned code, as in:

    m_config->set_key_value("print_host", new ConfigOptionString(m_printer_host + ":7125"));

Is it the only problem with this code?

No. Their whole algorithm is wrong, because if printer IP changes (because routers usually assign IPs dynamically), you'd need to re-add the printer again. I could understand the static assignment they did, weren't it for the fact both their printer and the Studio support a multicast protocol, which gets used when clicking the "Browse" button.

The "Browse" UI should not store the printer IP anywhere, instead it should be fetched dynamically every time you launch QIDIStudio.

Another unmentioned problem are cryptic comments all over the place:

    //31
[…]
    // y3
[…]
    //cj_3_cursor

And while at it: while navigating through sources I saw a bunch of commented out code in a lot of different places. It's completely useless, because nobody would remember why most of that code was commented out, unless the code comes with a comment explaining that (which it doesn't). Did they ever hear of git? — oh, wait…

Anything about QIDI Plus4 firmware?

I looked at this project shortly and it is pretty bad too. There I found the laziest commit title I ever seen in public projects, it's just called 1, that's it, a single character is the entire commit title. And no, it's not even a version (which was 1.6.0 at that point), the author just pressed a random key on their keyboard, looked at it and decided: "looks good enough!".

Commits themselves are huge and diffs are indiscernible.

Remember how I was surprised they forked Klipper away…? Well, here's the reason why: they just don't know how to develop software, which is a major obstacle in contributing anywhere. I'd argue if they forced themselves to contribute they'd inevitably learn how to write code properly, but that takes effort and QIDI decided to go down the path of least resistance.

Conclusions

Unbuildable project, years-long basic bugs, with some being solvable in 15 minutes, lack of error-checking in code, cryptic comments, commented out code, useless git-history, lack of low-level code understanding, lack of understanding how to collaborate with other projects and devs (no bugreports or discussions with other projects and forking off some of those, presumably expecting to code better but only making things worse)

Judging by code quality, QIDI lacks experienced programmers — the development is done by juniors at best, maybe even students.

Nowadays with AI taking off I wouldn't be surprised if it'll get even worse. I mean, they inevitably will use AI, just because everyone does these days. But it takes an experienced engineer to use it correctly, who are just not there in QIDI. If you ever saw the memes "we automated our company with AI" where the person fixes something that breaks on every step — that's what I expect gonna happen, unless they hire some seniors or at least middle-level programmers. Junior-vibe-coded firmware is our future, my fellow QIDIcustomerians.

I regret buying their printer now, but… oh well, I guess the printer works at least. Let's put it that way: I bought a QIDI printer so you don't have to 😄 As for me — I guess I'll abstain from updating my Plus4 printer firmware in the future.

To finish off: I know you might be curious "what to buy". Sorry, Idk. As mentioned, I am new to this 3D printing world, so Idk on the situation with other companies. One thing comes to my mind: I am using open-source PrusaSlicer and it's amazing. I looked at their git-history and it's good. Idk about their printers (I guess you'd have to research that yourself), but the QIDI problem is definitely not there. The downside with Prusa is their firmware isn't open-source. It is.

u/Hi-Angel — 3 days ago
▲ 57 r/mac

PSA: macOS 27 breaks booting non-macOS systems

Asahi team posted a PSA mentioning to be careful when upgrading to macOS 27 beta, because it's been confirmed to break boot of at least Asahi. However I'd note that AFAIK Asahi are using standard boot components such as Grub that's been used by many systems for decades, so likely Asahi is not the only system that breaks. I'd recommend to be careful updating if you have any other system besides macOS.

The attached link has more details, but the TL;DR of it is basically:

> If you have already upgraded to the beta and noticed that your Asahi partition has disappeared, do not stress. Your Asahi partition is still there, and you have not lost any data. > > We believe this to be a bug, and have filed a report (FB22994760).

Unfortunately Apple doesn't provide public links to the report, so we can't track it, though you can track Asahi team updates (hopefully they'll provide a post with details once this is addressed).

social.treehouse.systems
u/Hi-Angel — 25 days ago

Can't mirror an object because "an active body is required"

I'm trying to mirror an object (provided as `.STEP` and `.STL` files if that matters — same behavior). As in, the model is "left-handed" and I want to make a "right-handed" version.

I found it's done by switching to "Part Design" workbench and clicking the "Mirror" icon. Sounds easy. Except that doing so gives me error:

Error: \"To use Part Design, an active body is required in the document. Activate a body (double-click) or create a new one.\"

Well, I choose the object on the "Model" panel, so something's not right.

Turned out, it is very a popular error with dozens of post on the internet, none of which helped me so far. What I tried at this point:

  1. Double-clicking (as the error suggests) the object both directly and via the "Model" panel
  2. Creating a "new body" and using "Model" panel (top-left corner) to drag the object to the created body
  3. Switching to "Sketcher" workbench, creating a new sketch, then switching back to "Part Design" and trying all ways of dragging the object onto the new sketch
  4. Switching to "Part" workbench, then using "Shape from Mesh" and "Convert to Solid" which was suggested for a similar problem on yet another forum thread. To no avail. <br><br> I think this one required something else because I see now the option is grayed out (writing mostly from memory), but not sure this matters — somehow I managed to make both options work and mirroring was still spewing same error.

Any ideas, suggestions?

reddit.com
u/Hi-Angel — 2 months ago

How to make infinite grid?

Sorry, I'm new to FreeCAD, I looked around about using grids but it's all kinda confusing…

Basically, I downloaded someone's model, which I simply want to check if it has the proportions I need; and potentially resize a few parts.

So I need a grid, so I could rotate the object around and see what sizes it accords to in the grid. From what I found this seems to be implemented by:

  1. Switching to "Draft" workbench
  2. Enabling "Utilities → Toggle Grid"

It's fine, except that… the grid looks like this:

Abruptly ending grid

It goes into the object a few centimeters, and then ends abruptly. This is not very useful, how can I make it infinite?

And bonus points for explaining how to rotate the object within the grid (which I haven't looked at yet, but I already suppose it may not at all be clear).

reddit.com
u/Hi-Angel — 2 months ago