Automatically incrementing serial numbers
-
I had an idea, and posted it on the PS GitHub Repo: Crazy idea.
RRF3 (likely) already has all the scripting capability required to implement automatically incrementing serial numbers, if we could get a slicer to play along.
I envision the ability to pre-slice the digits of the serial number, accessed by a GOTO mechanism, or something, and print them in place as requested based on a given serial number. The serial number could even be acquired over a network, from a central source, so a print farm can be incrementing the numbers together. (Or, just have a different prefix for each machine and they all increment them locally, or whatever).
I am not well-versed in the capabilities of RRF3 g-code scripting. How could we make this happen?
-
I like this idea, I think this is something that can already be done in SLS job-prepping software (aka slicer), for example.
inb4 new RRF feature:
printing text (on XY-plane)
Gnnn S"string" Xnnn Ynnn Dnnn Hnnn Lnnn Tn.n Fn Nnwhere X, Y are the starting coordinates (of the base line of the text), D is the direction (0 - 360° or 0 - 2pi, where 0° is parallel to the x axis), H is the font height, L (optional) is the maximum allowed length unto which the text needs to be compressed in length, F (optional) is the selected font
Edit: N (optional) is nozzle size so that it can be somehow avoided to print unreadable letters
T (optional) is the layer thickness, not sure if this is a value that is usually passed on to RRF by the slicer.did I miss anything?
all this would require is, as you implied, a pre-sliced alphabet. And the slicer must somehow pass the starting coordinate, the rest can be done by RRF.
looking forward to the discussion on this topic!
-
A few quick thoughts in response. I definitely like the idea of the slicer having a "serial number origin", maybe per layer, that it could orient the selected numbers to.
The string would not be placed in the g-code manually like "044455", it should be passed as an argument, or automatically retrieved and saved into the file.
I envision that these g-code files will be kind of "portable" in a different sense than we are used to. The file would/could itself keep track of what serial number it should use next time, and possibly a record of all the serial numbers it has already printed.
This way when we start a print, we don't have to wait for any potential issues retrieving a serial number from a server or anything -- we just start printing and have a correct, unique serial number.
While the print is going, the firmware can execute code to find a new serial number for the next time the file will be printed, and append it to the list correctly in the file. If no external/central source of serial numbers is used, it could simply increment by one internally.
Each digit of the serial number could be like a region in PrusaSlicer. A region is what is created when a modifier creates new perimeters. So, each digit would be surrounded by x perimeters, and have its own infill, etc. It would essentially be a discrete island embedded in the selected location.
The scripting g-code would only really need to be able to jump back and forth between the main print, and the correct digit for the correct place of the serial number.
Perhaps, using your idea of the serial number origin, the number digits could be sliced in relative X/Y coordinates. So, when the slicer goes to the serial number origin, it could change to relative mode, print the island for that layer of the digit, and continue after.
I don't know if the relative positioning trick would really be necessary. However, if the file had multiple objects all with different serial numbers in different absolute positions, we could re use at least some of the digit slices if possible, instead of having to replicate identical digits for each absolute position.
Thank you for the thoughts and, please continue to provide them!
-
So I have a couple of thoughts on this. My experience lies in using something like this in my profession. One of my job responsibilities is machine tool(CNC) programming. I have set up a couple of machines that automatically engrave serial numbers/dates/etc. The easiest implementation of serial numbers that I have come across is as follows.
The main machining program calls a sub routine for each line that you want to machine. You pass the numbers/digits you want to engrave into the sub via parameters in the sub call. You also specify XYZ start locations, and font size as globals right before calling the sub. To control the serial number we just increment a global variable for each program call and write an updated value to that global variable after the engraving has finished. The example of this would be that we always want to engrave the string ABC000, but we update the 000 lines of the string every time we run the code.
On the CNC equipment the program for engraving is a program that just lives on the control. For 3D printing I could see this being an issue. I would think we want the slicer to build a sub program that are already the appropriate size/orientation and then use program calls to perform the correct action(the "pre sliced" alphabet mentioned above). (A better solution would be for the slicer to input these at the "bottom" of a program, to GOTO command referred to in the @bot first post here). The relative positioning seems like the best bet for this to keep it simple (I hate relative positioning as it causes machines to crash, but I think its the best use for it in this case).
In this case the slicer will probably have to call the individual letter/number islands multiple times for each digit at each layer. Because this is the case I don't think it makes sense to write a ton of code for RRF to do much a bunch of work. I think most of it lies in the slicer.
-
since we're still in the "collecting ideas" phase of this, I want to add another aspect to the discussion.
I'd argue that the point of this idea is to enhance serial part production via FFF. As such, when producing hundreds if not thousands of a part, the aim is to fill the printer's build plate with as many instances of the part as possible. This is as of now done in the slicer. The slicer doesn't multiply the instances of the sliced gcode though, but slices the whole plate of models, at least not as I'm aware - looking at you, Cura - which not only adds to slicing time (negligible), but also file size (less negligible). It also means that parts aren't actually identical, since the infill structure is "fixed" and thus might be oriented differently in each instance (also possibly rather negligible).
It would however mean, for the sake of adding serial numbers into the parts, that for each instance of the part on the plate there needs to be an increment in the SN. If the slicer were to slice one instance of the model, using relative coordinates and then jumping to the next starting point in each layer, effectively printing a full plate of parts but only referring to a single version of the gcode, this wouldn't be an issue since the SN would already have been incremented by the previous instance of the part.
I realise this is one, but probably not the most important reason to rethink how slicers handle mass printing of a single part...
So if we, like indicated above already, make all of this the responsibility of the slicer, we could make a list of requirements:
- adding the function of "text" gcode aka pre-sliced alphabet, possibly appended to the end of the gcode, and using goto to print the actual text (does RRF already support goto?)
- adding a way to insert/position the text on a model in the slicer
- adding the capability to RRF of altering the gcode to increment a variable that is the string of the SN or is used to calculate it
- per my idea above, change the handling of how multiple instances of a model are printed, e.g. using one instance of gcode instead of many - this would also make mass production more consistent with how I imagine it is already done on belt printers, so running the same gcode over and over
some things to keep in mind:
- we're still talking about text in the XY direction only. depending on the model, this might not be feasible, but I don't see how this would work on a surface that is not coplanar with the xy plane
- depending on the model, it would also mean that the build plate can be packed less optimal
please let me know if you think that this is OT and shouldn't be discussed here...
Best, Niklas
-
It’s an interesting concept!
Given that the serial number should be supplied by a server, wouldn’t it be easier to request a new GCODE for each print? Adding serial number plates in a slicer world be much more flexible than adding it via RFF. -
@pakue That is a very interesting idea. The network-acquired serial number was an afterthought I included when typing up the message. Originally, I had only thought that the individual g-code file would self-increment. But your idea leads to a magnificent world of g-code streaming servers. Kinda like the way the world is inching towards binary-streaming servers: no installing software, run it remotely and stream the input/output.
-
@sonderzug Those are some great thoughts. I'll have to come back and read again to fully absorb them, but I like it a lot. I actually have been always thinking about this in 3D -- not X/Y planar. The "regions" could be any arbitrary orientation. To achieve the 3D version, we would just have to keep track of the separate layers of the digit, rather than have one layer that could be replicated for all layers of the digit. It certainly adds a bit of complexity, but I think it's manageable.
The idea of instancing g-code is a very good one. PrusaSlicer already instances the models (when requested, with the instance command). So, it shouldn't be too much of a stretch to implement that into g-code as well. In PS, you can either copy/paste an object, which makes two separate objects, but an instance is truly an instance -- any changes made to one, are transferred to the other and sliced. The g-code is all one thing, though, but with the ability to robustly handle relative positioning/instancing, this could all work together nicely.
-
@bot Ok, it will be interesting to see how this would work across non-XY-coplanar surfaces. to illustrate, I whipped up a quick demonstrator...
easiest case: text lines printed on planar surface (this should be the first goal IMO since this is basically what we discussed until now)
more difficult, since it is basically just an arrangement of bumps/path offsets in the perimeters* (outermost perimeter might suffice):
also more difficult than the first, since it involves more perimeters and cutting out of the infill: negative extrusion
to me, the preferred version for text on vertical or non-horizontal surfaces: slightly inward extruded text, this looks the best, but is basically a copy of #2 but with more perimeters affected
*thinking more about this description of how the text is displayed, this might actually be the way to add text (or texture, for that matter) afterwards - offsetting the perimeter by x for certain areas over y amount of layers... doesn't Ideamaker allow to apply textures to STL files? How do they do it?
food for thought...
-
@sonderzug Yes, part of the problem that arises, especially in the "3D placement" case, like you mention and illustrate with your photos, is that the numbers become "merged" with the part, and the perimeter of the serial numbers is one and the same as the rest of the model.
This is where we could make the "engineering compromise." The slicer would actually produce a separate 3D region, which contains the digit. It would have its own infill and perimeters.
Imagine if that region is a single digit of the serial number. Each digit gets its own region. That is what makes this possible. The reserved region remains the same volume, so the toolpaths of the main part don't change.
-
@bot Here is an example with the spaces for 3 digits reserbed. (These would be HUUUGE digits. This is just an example.)
-
instead of a digit, could it be a QR code or bar code? Perhaps more space efficient at the expense of human readability?
-
@bot Why not do it via a displacement map on the actual STL/3MF/mesh? That makes it very flexible to add other things instead of characters and is independent of the part surface.
-
@phaedrux Barcode would be more practival than QR code. I don't know how we could encode every possible serial number in QR codes in an efficient manner. Even if we separate the code into chunks, it's still a lot of chunks to generate and store as toolpaths. But, I don't know the specs -- maybe it turns out to be fewer toolpaths than with all digit combinations? The barcode would be a direct replacement for numerical digits, afaik.
@Pakue from what I can envision, I don't see a way to make the numbers dynamically change for each print if we emboss the numbers directly into the main print. We need discrete regions that can be sliced, printed, and stored separately.
-
@bot I'd imagine it is easier (and more flexible) to reslice with a different parameter (serial number or similar), than it is to dynamically replace portions of existing gcode and handling it on the µC. Especially if the printer is running via an SBC that has more than enough compute power for slicing.