On the way to improve the performance of my Monkeyprint DLP printer software I recently rewrote the code that hollows the model and generates the fill patterns. I think my method is pretty neat, so I thought I’d share it here. If you like an image processing approach to model hollowing, continue reading!
Monkeyprint includes options to model hollowing or fill the model with a rectangular pattern. Printing your models hollow or with internal grid structures can significantly reduce the peel-off forces — which increases your vat coatings life.
Hollowing a 3d model can be quite error prone and computationally expensive. So I decided against doing the model hollowing and fill structure generation on the actual 3d model. Instead, I do it virtually: My method is completely based on image processing of the slice images. This makes the procedure very robust.
The process consists of only a few very simple and common image operators.
Binary erosion: This morphological image operator shrinks all white model regions of the slice image by a user defined wall thickness. For more info check out this article on wikipedia. The result of an erode operation is illustrated below:
Subtract: this arithmetic image operator combines two images by simply subtracting the pixel values of one of the images from the pixel values of the other image. Where the subtracted image is black, the output is unchanged, where it is white the output will be black.
Multiply: another arithmetic image operator that simply multiplies the pixel values of two images and divides them by 255 afterwards. Performed on binary images this operation behaves like a binary addition. Where both images are white the result is white as well. Where one of the images is black, the result is black.
So how does it all come together?
The following diagram illustrates the whole process:
In addition, the fill pattern moves by one pixel in X and Y direction from each slice to the next. This ensures that the vat floor coating will be worn evenly.
The image operations are all done using the OpenCV 2.4 library through its Python bindings. This is very simple, for example for binary erosion:
# Import OpenCV 2.4 and Numpy.
# Create the erosion kernel, radius is wall thickness.
kernel = numpy.ones((radius,radius), numpy.uint8)
# Erode the image.
imageEroded = cv2.erode(inputImage, kernel, iterations=1)
It’s easy as that and the performance is extraordinarily good compared to using the Scipy binary erosion or my self made erosion code that took about 1500 times longer.
If you like this, make sure to check out Monkeyprint. You can also find the image processing sources in my Github.
In case of questions or suggestions, please comment below.
Oh, and by the way: happy new year!
5 thoughts on “3d DLP slicer image handling”
Great job！And I really want to know，how to juage a image need fill?Thank you very much!
thanks for your comment 🙂
If I get your question right, you want to know when it makes sense to use fill structures?
Well, that depends on your model. If, for example, your model is very large using fill structures drastically reduces the adhesion force to the VAT floor. I would say you can safely use fill structures if a solid model is not important (which might be the case if you print transparent parts).
Does this answer your question?
thanks for your reply.
I’m sorry I did not clarify my question. In this gif
http://robotsinthesun.org/wp-content/uploads/2015/12/slicingSmall.gif ，not all layers are filled, so my question is ,how to jugae a layer need fill?
Very interesting! You just do not talk about how you manage the Z hollowing.
For X/Y, it’s very clear and clever! but how do you manage the Z.
Do you compare pixel per pixel for each sliced image?
sorry for the delay, I was quite busy with work and studies…
For the Z-axis I check the slice images above and below that correspond to the wall thickness specified by the user. If they’re black for a certain pixel (i.e. there’s no model at that position) I turn the corresponding pixel white, so a wall is formed. It was a bit more involved but without checking the code, that’s the simple explanation.