scottbez1 / splitflap

DIY split-flap display
https://scottbez1.github.io/splitflap
Other
3.09k stars 257 forks source link

Font Rework and SVG Generation #92

Closed dmadison closed 3 years ago

dmadison commented 3 years ago

This PR overhauls how fonts are handled in the SCAD assembly, and adds a font generation feature for rendering SVG font files for cutting. The goal is to make it easy to generate custom split-flap fonts for desktop cutting machines (Cricut, Silhouette, etc.).

Changes:

Also included:

With these new options I've tweaked the default letter scaling width (0.8 of previous) so that letters such as 'M' don't exceed the flap bounds. I've also nudged the X and Y offsets so the letters are better centered with the Roboto font.

Here's a comparison of the font versions in the main assembly (render_flaps at 1 for front flaps only).

Main Assembly, Before (master, 008593c)

sf-font-before-008593c

All default settings.

Main Assembly, After (fonts, eca0516)

sf-font-after-eca0516

letter_gap_comp set to True. Note the consistent slope of the '4' from top to bottom.

Font Generation

font_generator.scad renders a string of text across an X/Y array of flaps. This uses the same flap and font settings as the main assembly and can be customized to change the font, scaling, position offsets, and more. Here is the assembly with 40 flaps (A-Z, 0-9, and punctuation) with Roboto:

splitflap-font-roboto

Default settings circa eca0516, with letter_gap_comp set to True.

And here's the same file after exporting to SVG (python scripts/generate_fonts.py. The letters are passed through the optimizer so the lines on the flap won't be cut twice:

splitflap-font-svg

The Python script allows overriding most of the parameters from the command line, so font generation can be automated if need be. The flap outlines are purposefully exported for alignment purposes.


I think this is fairly complete, but please let me know if you see anything amiss!

scottbez1 commented 3 years ago

This looks really exciting! I've been thinking about doing the letter gap compensation ever since I threw together the font rendering, but never got around to it since it was just used for rough visual checks; it's great to have this now that you're rendering flap designs!

Will try to review this weekend!

On a related note, have you thought about an option to render the flaps/font as 2 separate files for double-sided printing? I believe some people have done double-sided printing on a big sheet and then cut out the flaps from that (and I think this is what Oat Foundry does for their flaps). I've also thought about potentially printing on sticker paper and applying a whole page at once to a bunch of die-cut flaps sitting in an alignment jig, which could also use the same double-sided rendering. The two changes needed would be to render the fonts with bleed off the edge of the flap, and to adjust the layout of the top and bottom half of each letter so they match up double-sided. Anyway, just figured I'd throw that out there!

dmadison commented 3 years ago

On a related note, have you thought about an option to render the flaps/font as 2 separate files for double-sided printing?

I hadn't thought about that! My goal with this was to generate the letters for cutting out of vinyl, but you're right you could absolutely modify it for double-sided printing.

I'm not familiar with how files are prepared for the double-sided printing process, but I think that the letter drawing function I wrote already places the top/bottom letters correctly. That is to say, both the top and bottom letters are drawn on the flap in the correct position without any sort of additional transformations. You'd only need to render half of the flaps, bump the letter 'half' value up by one in the function call, and then export the sheet again. It gets moderately more complicated if the whole sheet needs to be mirrored, but not by much.

For bleed, I suppose we could scale the 3D flap before performing the intersection? We'd need to do a bit of math against the flap dimensions if we wanted it to be in real units but it should be feasible!

scottbez1 commented 3 years ago

Regarding bleed, I didn't realize when reviewing that the letter rendering is using a 3d intersection rather than 2d; I think it'd be preferable to do the intersection operation in 2d before extruding the letter/flap, which would then also mean you could apply the 2d offset operator to the flap shape before intersecting to specify a bleed distance in real units. That would also more closely match the guidance from the README of preferring 2d operations when possible and using an extrude as "late" as possible (In general, solid objects such as the enclosure sides or spool components are built from 2d primitives and then extruded to the appropriate thickness for 3d rendering, rather than using 3d primitives.)

dmadison commented 3 years ago

You're right, I've separated out the flap module into its 2D and 3D components and changed the flap_letter function to use a 2D intersection. Quick render tests show a ~25% render time improvement for font_generator.scad, with presumably similar speed improvements to the Python script.

scottbez1 commented 3 years ago

Thanks!