Pleasant3D is now open source

I hadn’t too much time for developing Pleasant3D lately. Sorry for that!

However, I did some work on Pleasant3D in the last year:

  • Better (more performant) versions of the Quicklook  plugins (for previewing STL and GCode files in the Finder)
  • An experimental implementation of a DAE file import plug-in
  • Experimental support for printing directly from Pleasant3D (still not functional, but the infrastructure is there…)
  • Support for different devices (3D printers, CNC mills etc.)

… and some other stuff.

Unfortunately, I currently don’t have the time to develop, test and stabilize the current code on my own in order to release a new binary version of Pleasant3D.

So starting today, I open source the complete code base of Pleasant3D:

(The slicer plugins of Pleasant3D were open source from the beginning. I’ll mark the old open source BitBucket repository as obsolete.)

I’d be very happy, if some of you 3D-printing (or CNC-milling) Mac developers out there would help with the further development of Pleasant3D!

Please note, that the published sources aren’t in a fully tested state. As far as I can tell, the project builds and runs after a clean ‘clone’. Be sure to use Xcode 4 and to choose “Pleasant3D/32-bit” as build scheme.
However, there seem to be some issues with the Quicklook generators in this version (they seem to run in Debug mode, but crash when running in the real world…).
Also the OpenCL slicer seems to be broken in the current version.

The  stable version of Pleasant3D (v2.0) is (and will be) still available as pre-built binary release: Download Pleasant3D

Flat Teardrop

The teardrop is around in the 3D printing scene virtually forever. It’s even part of RepRap’s icon.
This geometric shape is used whenever an object with horizontal holes is printed. This avoids overhangs greater than 45° at the top of the hole, which are not (or at least not easily and clean) printable on FDM printers without support material.
Some people use teardrops only for larger holes (>4 or 5 mm diameter), since the overhangs are not such a big problem on smaller holes. While this is generally true, I tend to use teardrops even for smaller holes (3mm or even 1mm), since it turns out, that even these tiny holes look cleaner when printed in teardrop shape.
It always was kind of tricky to design objects containing teardrop shapes in classic CAD apps, since the teardrop shape isn’t a standard primitive in those applications (at least not in those I used).
This luckily changed with the release of OpenSCAD and it’s ability to use user written libraries.
At the latest with the release of Randy Young’s great Libs.scad library, using teardrops instead of cylinders for punching holes into objects is easy as pie.

Here’s the code of teardrop module from the Libs.scad library. I changed the Libs.scad code on my computer to use the polygon code instead of whosawwhatsis’ projection code, since the projection code takes forever to render in CGAL mode.

module teardrop(radius=5, length=10, angle=90) {

	rotate([0, angle, 0]) union() {
		linear_extrude(height = length, center = true, convexity = radius, twist = 0)
			circle(r = radius, center = true);
		linear_extrude(height = length, center = true, convexity = radius, twist = 0)
			polygon(points = [
				[radius * -cos(-45), radius * sin(-45)],
				[radius * -cos(-45), radius * -sin(-45)],
				[(sin(-135) + cos(-135)) * radius, 0]],
				paths = [[0, 1, 2]]);
// This code take forever to render:
// teardrop module by whosawhatsis <>
// Creative Commons LGPL, 2010.  I added default values and resolution code
/*	rotate([0, angle, 0]) union() {
		linear_extrude(height = length, center = true, convexity = radius, twist = 0)
			circle(r = radius, center = true);
		linear_extrude(height = length, center = true, convexity = radius, twist = 0)
			projection(cut = false) rotate([0, -angle, 0])
			translate([0, 0, radius * sin(45) * 1.5])
			cylinder(h = radius * sin(45), r1 = radius * sin(45), r2 = 0,
					center = true);

The problem with teardrop holes is, that they need considerably more space. This can be a real problem, when the main object is limited in size for one reason or another.

For example, this is a ball bearing retainer:


When simply using teardrops instead of cylinders for the holes, the result would be this:

As you can see, the larger footprint of the teardrop shape becomes a real problem with the larger holes in front and back of the retainer. In this case, the structural stability might still be good enough, since the smaller center bore  is still closed at the top. But often teardrop holes just aren’t an option unless you significantly re-design the main object (and usually make it larger).

Well, it turns out there is another option after all:

Introducing the Flat Teardrop

The solution is simple. Although overhangs > 45° are a problem in 3D printing, reasonably short bridges aren’t!

So why not just cut off the dead space in the tip of a teardrop?




I wrote a new module in OpenSCAD, called flatteardrop. This module is derived from the original teardrop module in Libs.scad:

module flatteardrop(radius=5, length=10, angle=90, luck=0) {

	sx1 = radius * sin(-45);
	sx2 = radius * -sin(-45);
	sy = radius * -cos(-45);
	ex = 0;
	ey = (sin(-135) + cos(-135)) * radius;

	dx= ex-sx1;
	dy = ey-sy;

	eys = -radius-luck;
	dys = eys-sy;
	ex1 = sy+dys*dx/dy;
	ex2 = -ex1;

	rotate([0, angle, 0]) union() {
		linear_extrude(height = length, center = true, convexity = radius, twist = 0)
			circle(r = radius, center = true);
		linear_extrude(height = length, center = true, convexity = radius, twist = 0)
			polygon(points = [
				[sy, sx1],
				[sy, sx2],
				[eys, ex2],
				[eys, ex1]],
				paths = [[0, 1, 2, 3]]);

Since the top is cut at radius height of the theoretical cylinder inside the teardrop, it might be a problem when the bridged part at top of the flat teardrop sags a bit during printing. This might happen when the bridge gets longer, i.e. on larger teardrops.

As a countermeasure it’s possible to add a little bit height to the cut “for luck”. To do so, set the value of the luck parameter to the additional height. However, the default value of this parameter is 0 and simply can be omitted in most cases.

The module makes use of the resolution function of the Libs.scad library. If you add the flatteardrop module to this library (as I did on my computer), it just works. If you plan to use the flatteardrop module separately, you might want to comment out the line


or set $fn to a fixed value (e.g. 36).

The mill’s soul

IMG_2456.JPGI just published v0.4 of Pleasant Mill‘s firmware on Github yesterday:

As you might guess from the version number, this firmware isn’t finished yet and probably still has some bugs to fix (help’s highly appreciated, BTW :).

As mentioned before, I use a Seeduino Mega and some Pololu A4983 stepper motor drivers.

One recent addition on the hardware side was a 24V/6.3A power supply. I also glued some small heat sinks on the A4983 chips.

Then I increased the current to 1.68A, the max current, the stepper motors (SY42STH47-1684B) are rated for. Driving the steppers at 24V/1.68A enabled me to dramatically increase the top feedrate for the machine (about 1800mm/min instead 600mm/min). Unfortunately, the little heat sinks weren’t enough and the thermal shutdown of the A4983 kicked in after a few minutes. So I had to lower the current to about 1.2A again (and the max feedrate to 1100mm/min).

As you can see in the image at the top of this page, I’m still using a messy bread board for the electronics. As soon as I have the feeling to know the main issues with the whole shebang, I’ll build some kind of Seeeduino Mega shield, of course.

Right now, I plan to put the stepper motor drivers on a separate daughter PCB, somehow integrated in some kind of big ass heat sink.

If anyone knows a good way to cool the tiny A4983 chips on the Pololu breakout boards, please let me know!

The just published firmware release contains code for the G2/G3 commands (arcs) and for several drilling cycles (G81, G82, G83, G85, G89 and G73, see video below).

The drilling cycle commands also recognize the L (loop) parmeter, which is nice to drill multiple holes in a row. Just switch to incremental positioning (G91) and use something like G81 X10 Y0 Z-12 R1 L7 to drill 7 holes along Y=0mm, 10mm apart and 12mm deep. Don’t forget to switch back to absolute positioning (G90) after :)

I also added the M6 (tool change) command. Of course, I have no automatic tool changer (and I don’t really plan to build one). On the Pleasant Mill, the M6 command pauses the G-code processing and displays a message on the LCD, containing the tool number, requested by the G-code program and waiting for feedback from the operator.

For example, the line

M6 T3

results in


I even wrote some code to save a “tool database” in the Seeeduino’s EEPROM, so the LCD would say something like “Insert tool: 3mm drill bit”, but this code doesn’t work properly yet.

Both, the drilling cycles and the tool change command are showed off in the following video:

And here’s the G-code, I sent to the machine during the video:

G0 Z3
G0 X2 Y2 ; Simple drilling cycle
G81 X6 Y0 Z-8 R2 F300 L4
G0 X2 Y7 ; Drilling cycle with dwell
G82 X6 Y0 P500 L4
G0 X2 Y12
G4 P1000 ; Peck Drilling cylce
G83 X6 Y0 Q2 L4
G0 X2 Y17; Peck drilling cycle, high speed
G73 X6 Y0 Q3 L4
G0 X2 Y22 ; Drilling cycle, slow retract
G85 X6 Y0 L4
G0 X2 Y27; Drilling cycle with dwell, slow retract
G89 X6 Y0 P500 L4
G0 X0 Y-25 Z19.5 ; Tool change position
M6 T2 ;  Change Tool
G0 X2 Y32
G81 X6 Y0 Z-5 R2 L4
G0 X2 Y34
G81 X6 Y0 Z-5 R2 L4
G0 X0 Y25 Z13.5

I also implemented the commands G54 to G59. Each of these commands switches the machine to one of 6 “work coordinate systems” (WCSs). These are 6 user defined “zero positions”, saved in the machines EEPROM.

To define a WCS, use the “Jog XZ”, “Jog Z” and “Jog AB” functions in the mill’s UI (“Cartesian”) to move to the desired position. Then choose the menu command “Set WCS” to save this position in the EEPROM. You also can view already saved positions with the “Show WCS” command.

When writing G-code, you can then use one of the commands G54 to G59 to load the previously saved positions as zero positions.

In order to get the whole WCS stuff working, you need to “home” the machine once (either by sending the G28 command or by choosing “Find home” from the Cartesian menu in the UI). This is necessary to give the firmware an idea of the machine’s absolute zero position. If you try to save a WCS position in the UI or to use G54 to G59 without homing, an error is displayed.