Compare commits

...

42 Commits
v3.0 ... main

Author SHA1 Message Date
Matt McWilliams 2d69a58af1 Add new spiral thank you to Pip Chodorov 2021-11-07 20:16:57 -05:00
mmcwilliams 89c8f32b3b Update license to current year 2021-10-15 11:39:38 -04:00
mmcwilliams b1b33e1b4f Ignore *.csg 2021-10-15 11:39:24 -04:00
mmcwilliams 01106665d2 Create correct CSG folder before building. Do not commit csg files because they are intermediary? For now. 2021-10-15 11:39:18 -04:00
mmcwilliams fa5726a6a8 Build script now runs deps.sh before building to prevent running commands that aren't available.
Script now compiles csg files. TODO: fix the csg2step.py script by using latest FreeCAD logic.
Script allows for input of a size (50ft/100ft) or an part (from FILES) to render fewer files.
Migrate bulk of the loop into a render_part() function that can be re-used.
2021-10-15 11:20:11 -04:00
mmcwilliams 97737b0ba6 Merge remote-tracking branch 'origin/master' 2021-10-15 02:48:56 -04:00
mmcwilliams 484c32fbf7 Add a dep.sh file to check whether all required dependencies are installed 2021-10-15 02:48:50 -04:00
Matt McWilliams 16f618a727 rename the "spiral_bottom_insert" module to "spiral_insert" because the void is not specifically for the bottom insert anymore and is the same for both "top" and "bottom" spirals in the unified design. 2021-10-12 13:52:58 -04:00
Matt McWilliams d915f255dc Comment to preserve sanity: the seemingly-duplicate module "spiral_bottom_insert_single" is NOT the same as the Super8 insert: it has a different threading for a different screw. 2021-10-12 13:50:34 -04:00
Matt McWilliams 9b99318412 Fix a typo in the notes as caught by Levi Pratt 2021-10-12 12:34:23 -04:00
Matt McWilliams 842e0ff3fc Change default model to "spiral" 2021-02-17 22:14:07 -05:00
Matt McWilliams 69da7420fe Add engraved roman numerals into the spindle screws to tell the difference between the double layer and the single layer spindles. 2021-02-17 22:13:22 -05:00
Matt McWilliams 73a614bb01 Render the new single-layer spindle. Still needs to be rendered and added to the README. 2021-02-17 21:57:55 -05:00
Matt McWilliams ce3ffbd9d3 Add a build script for updating the library 2021-02-12 15:47:37 -05:00
Matt McWilliams 39529b9038 Add a spot in the README for other spiral projects. 2021-01-21 09:37:58 -05:00
mmcwilliams 9d58753183 Merge remote-tracking branch 'origin/master' 2020-09-12 10:57:09 -04:00
mmcwilliams e1083bd548 Simplify v3 scripts by removing vestigial modules. 2020-09-12 10:57:01 -04:00
sixteenmillimeter ba557087db
Fix typo in README 2020-09-01 22:31:30 -04:00
mmcwilliams 1ce5d947c0 Trick my render process into displaying degrees properly 2020-08-29 18:23:39 -04:00
mmcwilliams 70b3a7d8c7 Link openscad in /docs 2020-08-29 18:14:08 -04:00
mmcwilliams fe506a165b Update links in /docs with proper relative paths 2020-08-29 18:05:26 -04:00
mmcwilliams ce6285d277 Move index on docs page 2020-08-29 18:02:04 -04:00
mmcwilliams b7b501db1a Add all .zip files as sixteenmillimeter.com links. Host on my own site and track all downloads 2020-08-29 17:25:31 -04:00
mmcwilliams 991db37faf Not sure what I did there. Sorry to those browsing this git history. 2020-08-29 15:43:05 -04:00
mmcwilliams f09742cc90 Revert "Change create->generate. Update sentence linking to development notes."
This reverts commit 6c677f32f7.
2020-08-29 15:42:19 -04:00
mmcwilliams 6c677f32f7 Change create->generate. Update sentence linking to development notes. 2020-08-29 15:41:56 -04:00
mmcwilliams 8b48f93364 A lot of newlines added to the readme. Sentences broken down to 1 line each instead of 1 line per paragraph. This will better track changes over time with smaller diffs per sentence. 2020-08-29 15:19:01 -04:00
mmcwilliams 16d5a1f8eb Add an index and move contact to bottom. 2020-08-29 14:47:02 -04:00
mmcwilliams 7be6630919 Copy updates to README 2020-08-28 11:29:27 -04:00
mmcwilliams 5a8e748f3a Update to language in READMEs 2020-08-27 18:50:58 -04:00
mmcwilliams d3e244bebf Replace image placeholders with actual images 2020-08-27 02:31:33 -04:00
mmcwilliams 5d5e1d70f0 Add more images rendered with POV-Ray to use in readme. 2020-08-27 02:28:03 -04:00
mmcwilliams 14b0c690b2 Update readme and docs 2020-08-27 02:27:25 -04:00
mmcwilliams a8ab96ae37 HTML breaking the rendering? 2020-08-27 00:50:54 -04:00
mmcwilliams 4b9f7ec677 Rename development.md to README.md to trick github into displaying it as a rendered html file at the ./docs path. This is easier for me to render in my site builder script. 2020-08-27 00:49:28 -04:00
mmcwilliams 0b2e827981 Re-rendered spiral with latest 50ft v3 model (no triangular voids). 2020-08-27 00:46:54 -04:00
mmcwilliams 33a79181ca Migrade development notes into their own file. 2020-08-27 00:45:38 -04:00
mmcwilliams 396cfe85de Major README updates. Still needs proofing, images and more links to files. 2020-08-26 18:53:01 -04:00
mmcwilliams fae0100b7f First complete POV-Ray render 2020-08-26 18:52:42 -04:00
mmcwilliams 400120826c Re-render v2 with better triangular voids 2020-08-25 10:08:34 -04:00
mmcwilliams 2cf56276af Use local size.sh script with cross-platform support 2020-08-25 10:07:33 -04:00
mmcwilliams 2760cf5fee Remove triangular voids from v3 and move the improved triangular voids into v2 to consolidate the best attempt at this design to that version. 2020-08-24 17:41:05 -04:00
41 changed files with 788 additions and 405 deletions

4
.gitignore vendored
View File

@ -1,3 +1,5 @@
*.DS_Store
benchmark
releases
releases
stl/*/*.txt
csg/*

View File

@ -1,9 +1,9 @@
MIT License
Copyright (c) 2020 Matt McWilliams
Copyright (c) 2021 Matt McWilliams
Permission is hereby granted, free of charge, to any person obtaining a copy of this hardware, software, and associated documentation files (the "Product"), to deal in the Product without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Product, and to permit persons to whom the Product is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Product.
THE PRODUCT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE PRODUCT OR THE USE OR OTHER DEALINGS IN THE PRODUCT.
THE PRODUCT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE PRODUCT OR THE USE OR OTHER DEALINGS IN THE PRODUCT.

300
README.md
View File

@ -1,34 +1,54 @@
# GNAL
Free and open source processing system for 16mm and Super8 film
A free and open-source processing system for 16mm and Super8 film
IMAGE_PLACEHOLDER
![GNAL 50ft V3 all pieces](/img/gnal_50ft_v3.jpg)
Would you like to buy one?
# [Email me](mailto:gnal@sixteenmillimeter.com)
1. [What's GNAL?](#what)
2. [STL Files](#stls)
3. [Printers](#printers)
4. [Material](#material)
5. [Troubleshooting](#troubleshooting)
6. [Contact](#contact)
---
<a name="what"></a>
## What's GNAL? Gnal's Not A Lomo!
GNAL stands for Gnal's Not A Lomo because it isn't. While inspired by a certain motion picture development tank the goal of this project is to create an open source, modification-friendly processing system for small format movie film with the added constraint that it be 3D printable or otherwise able to be fabricated on a small scale. All source code and STL files for printing will be made available in this repository.
GNAL stands for Gnal's Not A Lomo because it isn't.
While inspired by a certain motion picture development tank the goal of this project is to create a free, open-source, modification-friendly processing system for small format movie film with the added constraint that it be 3D printable or otherwise able to be fabricated on a small scale.
All source code and STL files for printing will be made available in this repository.
GNAL is built using [OpenSCAD](https://www.openscad.org/). OpenSCAD is a free, open source CAD program that uses scripts to generate objects. Building this project in OpenSCAD serves two purposes: it uses only free and open source software to create the GNAL processing spirals and it future-proofs the design by preserving its dimensions in human-readable text format. Even if OpenSCAD were to disappear tomorrow (sincerely hope it doesn't) it would still be possible to recreate the GNAL models in another CAD program just by reading the code and reproducing the measurements.
GNAL is built using [OpenSCAD](https://www.openscad.org/): a free, open-source CAD program that uses scripts to generate objects.
Building this project in a scripting language serves two purposes: it uses only free and open-source software to generate the GNAL processing spirals and it future-proofs the design by preserving its dimensions in human-readable text format.
Even if OpenSCAD were to disappear tomorrow (and we sincerely hope it doesn't) it would still be possible to recreate the GNAL models in another CAD program just by reading the code and reproducing the measurements.
While the files are all free, open-source and readily available to download; actually printing them can be a challenge.
Please read through this README for information about materials, printers and troubleshooting your prints. Check out the [development notes](docs/) if you want to modify this project.
Happy processing!
## Other Spirals
There has been a lot of development around 3D printed processing spirals and any projects will be linked here.
If you find any, please share with the email address at the bottom of this README.
* [Movie Film Spiral Developing Tank by mb_maker on Thingiverse](https://www.thingiverse.com/thing:4715086)
* [New 16mm developing tank](https://cinematography.com/index.php?/forums/topic/83456-new-16mm-developing-tank/)
## Where's the tank?
Good question!
----
<a name="stls"></a>
## V3 STL Files
![V3 50ft spiral top and bottom](/img/gnal_50ft_v3_spiral_render.jpg)
**50ft/15m**
IMAGE_PLACEHOLDER
#### [All 50ft v3 STL files in a .zip]()
#### [All 50ft v3 STL files in a .zip](https://links.sixteenmillimeter.com/mE4nkSm4)
* [Spiral](stl/50ft_v3/gnal_50ft_spiral.stl)
* [Top](stl/50ft_v3/gnal_50ft_top.stl)
@ -41,9 +61,7 @@ IMAGE_PLACEHOLDER
**100ft/30m**
IMAGE_PLACEHOLDER
#### [All 100ft v3 STL files in a .zip]()
#### [All 100ft v3 STL files in a .zip](https://links.sixteenmillimeter.com/fbdwf3C8)
* [Spiral](stl/100ft_v3/gnal_100ft_spiral.stl)
* [Top](stl/100ft_v3/gnal_100ft_top.stl)
@ -56,11 +74,11 @@ IMAGE_PLACEHOLDER
## V2 STL Files
![V2 50ft spiral top and bottom](/img/gnal_50ft_v2_spiral_render.jpg)
**50ft/15m**
IMAGE_PLACEHOLDER
#### [All 50ft v2 STL files in a .zip]()
#### [All 50ft v2 STL files in a .zip](https://links.sixteenmillimeter.com/vRPj4yTC)
* [Spiral](stl/50ft_v2/gnal_50ft_spiral.stl)
* [Top](stl/50ft_v2/gnal_50ft_top.stl)
@ -71,25 +89,22 @@ IMAGE_PLACEHOLDER
**100ft/30m**
IMAGE_PLACEHOLDER
#### [All 100ft v2 STL files in a .zip]()
#### [All 100ft v2 STL files in a .zip](https://links.sixteenmillimeter.com/XRlnssjz)
* [Spiral](stl/100ft_v2/gnal_100ft_spiral.stl)
* [Top](stl/100ft_v2/gnal_100ft_top.stl)
* [Top Spacer](stl/100ft_v2/gnal_100ft_spacer.stl)
* [Bottom Spiral Insert S8](stl/100ft_v2/gnal_100ft_spiral.stl)
* [Bottom Spiral Insert 16mm]()
* [Bottom Spacer 16mm]()
* [Bottom Spiral Insert 16mm](stl/100ft_v2/gnal_100ft_insert_16.stl)
* [Bottom Spacer 16mm](stl/100ft_v2/gnal_100ft_insert_s8.stl)
## V1 STL Files
![V1 50ft spiral top and bottom](/img/gnal_50ft_v1_spiral_render.jpg)
**50ft/15m**
IMAGE_PLACEHOLDER
#### [All 50ft v1 STL files in a .zip]()
#### [All 50ft v1 STL files in a .zip](https://links.sixteenmillimeter.com/f67lQo2n)
* [Bottom Spiral](stl/50ft_v1/gnal_50ft_bottom_spiral.stl)
* [Top Spiral](stl/50ft_v1/gnal_50ft_top_spiral.stl)
@ -98,7 +113,7 @@ IMAGE_PLACEHOLDER
**100ft/30m**
#### [All 100ft v1 STL files in a .zip]()
#### [All 100ft v1 STL files in a .zip](https://links.sixteenmillimeter.com/CVihrAr5)
* [Bottom Spiral](stl/100ft_v1/gnal_100ft_bottom_spiral.stl)
* [Top Spiral](stl/100ft_v1/gnal_100ft_top_spiral.stl)
@ -106,13 +121,16 @@ IMAGE_PLACEHOLDER
* [Spacer](stl/100ft_v1/gnal_100ft_spacer.stl)
-----
<a name="printers"></a>
## Printers
The diameter of these spiral reels limit the number of printers that are capable of printing this design. The 50ft/15m model is 225.71mm (8.88in) wide at the base and the 100ft/30m model is 299mm (11.77in) wide.
The diameter of these spiral reels limit the printers that are capable of making this design.
The 50ft/15m model is 225.71mm (8.88in) wide at the base and the 100ft/30m model is 299mm (11.77in) wide.
**50ft/15m Capable Printers**
* [PrintrBot Metal Plus](https://www.adafruit.com/product/2302) **Tested** **[Discontinued]**
* [LulzBot TAZ 6](https://www.lulzbot.com/store/printers/lulzbot-taz-6) Untested
* [aniwaa.com Search: Printers with print bed > 225mm x 225mm](https://www.aniwaa.com/comparison/3d-printers/?sort=price&order=asc&filter_search&filter_price_minimum&filter_price_maximum&filter_build_size_width=225&filter_build_size_height=225&filter_build_size_depth)
**100ft/30m Capable Printers**
@ -120,180 +138,86 @@ The diameter of these spiral reels limit the number of printers that are capable
* [Creality Ender 5 Plus](https://www.creality3d.shop/collections/3d-printer/products/creality3d-ender-5-plus-3d-printer) ***Tested***
* [aniwaa.com Search: Printers with print bed > 300mm x 300mm](https://www.aniwaa.com/comparison/3d-printers/?filter_search&filter_price_minimum&filter_price_maximum&filter_build_size_width=300&filter_build_size_height=300&filter_build_size_depth)
There are people printing spirals in sections on smaller printers, but that is not a *recommended* use of these files as it requires extreme precision to reconstruct the parts into a reel that will load smoothly. Another thing to consider is the longevity of the bond made by the adhesive you choose. Don't let that stop you, though. A multi-part printed reel is just not a priority for *this* particular project. An enterprising spirit might notice the `gnal_50ft_spiral_quarter()` and `gnal_100ft_spiral_quarter()` modules in the v3 OpenSCAD script and begin to wonder what is possible.
There are people printing spirals in sections on smaller printers, but that is not a *recommended* use of these files as it requires extreme precision to reconstruct the parts into a reel that will load without problems.
Another thing to consider is the longevity of the bond made by the adhesive you choose.
Don't let that stop you, though. A multi-part printed reel is just not a priority for *this* particular project.
An enterprising spirit might notice the `gnal_50ft_spiral_quarter()` and `gnal_100ft_spiral_quarter()` modules in the V3 OpenSCAD scripts and begin to wonder what is possible.
-----
<a name="material"></a>
## Material
PETG is the recommended plastic for printing the GNAL. Since this is a piece of darkroom processing equipment its exposure to water and photochemistry is inevitable and should be considered primarily. PETG (Polyethylene terephthalate glycol) is a copolymer of PET, which is a plastic that's typically encountered in plastic bottles and food containers. This is not a scientific evalution and may stand to be corrected.
[PETG](https://en.wikipedia.org/wiki/Polyethylene_terephthalate#Copolymers) is currently the recommended plastic for printing the GNAL.
Since this is a piece of darkroom processing equipment its exposure to water and photochemistry is inevitable and should be considered primarily.
PETG (Polyethylene terephthalate glycol) is PET--which is a plastic that's typically encountered in plastic bottles and food containers--in a copolymer with glycol.
ABS is a viable option but has more tendency to warp on larger prints without proper temperature control around the print bed. Since this model needs to be consistently flat across the bottom of the reel,
Various manufacturers have published [safety data sheets](http://www.ilpi.com/msds/) for PETG filament.
The only warning about reactivity I have discovered states that a condition to avoid is "strong oxidizing agents" which may include reversal bleaches that are comprised of strong acids.
This is not a scientific evaluation and may stand to be corrected.
PLA is not recommended but this doesn't mean you can't get an acceptable results with it. The lack of endorsement comes from mostly anecdotal experience witnessing the wear and tear of water on PLA. Biodegradable and porous, PLA prints will wear down in the weakest parts first and on this model that would be the spiral. If you do not need your processing equipment to last a long time, you may find it acceptable. PLA stands for polylactic acid
[ABS](https://en.wikipedia.org/wiki/Acrylonitrile_butadiene_styrene) is a viable option but has a greater tendency to warp on larger prints without proper temperature control around the print bed.
Since this model needs to be perfectly flat across the bottom of the reel, this is not ideal and will make for a challenging print.
ABS is a plastic commonly used in injection molding and is also generally non-reactive with photochemistry.
[PLA](https://en.wikipedia.org/wiki/Polylactic_acid) is not recommended but this doesn't mean you can't get an acceptable result with it.
The lack of endorsement comes from mostly anecdotal experience witnessing the wear and tear caused by exposure to water on PLA prints.
Biodegradable and porous, PLA will wear down in the weakest parts first and on this model that would be the spiral.
If you do not need your processing equipment to last a long time, you may find it acceptable.
PLA stands for polylactic acid and is likely the most reactive material to use with photochemistry where it is vital to maintain pH for consistent results.
-----
<a name="troubleshooting"></a>
## Troubleshooting
Many, many issues were encountered during the development of this tool.
Prints came out warped, failed midway during multi-day prints and had other mysterious ailments.
I am by no means an expert but have built up months of experience trying to print these models on a variety of machines.
#### Warping
Fused filament fabrication relies on the behavior of plastics at high heat to create a physical object.
If your prints are warping, there are a few things to look at:
1. Material
2. Temperature
3. Slicer settings
The first thing to consider when your prints are coming out warped off the print bed is whether or not your **material** is appropriate for this model.
Check the [material](#material) section of this README for more information, but theres a chance if you are using PLA or ABS that large flat prints of this size are warping due to limitations with the material you are using. PETG has proven to warp far less in my own anecdotal experience and is the recommended material for this project.
The thermal properties of the material you're printing with are what causes warping, so check if your printer is being set to the recommended **temperatures** on both the bed and extruder for the material and printer you are using.
Warping occurs consistently when a section of a part cools too quickly and contracts while the rest of it is still being printed.
Mitigate this by using an enclosure on your open-frame printer or by printing in a space with low air movement but still with appropriate ventilation for the material you use.
The **slicer** you use and the **settings** in its configuration will make a lot of difference in how your print comes out.
During the development of this project [Cura](https://ultimaker.com/software/ultimaker-cura) is the slicer used most for test prints, however you might find that different software works best with your machine.
The settings are important to test before you commit to a complete print of the spiral part.
Here is an example of the important settings used during development while printing with PETG.
|Setting|Value|
|---|---|
|Extruder Temperature|240<sup>o</sup> C|
|Bed Temperature|80<sup>o</sup> C|
|Generate Supports|Yes|
|Infill|20%|
|Print Speed|40 mm/s|
This is a fraction of the overall settings that Cura has, but they note some of the key features that were changed from the default profile for PETG and my printer.
-----
## Development
This project can be edited with only OpenSCAD and the source files in the `*_v1`, `*_v2` or `*_v3` directories which make reference to files from `libraries`. If you wish to run the development scripts you should install the following dependencies.
With just OpenSCAD, you can use scripts such as `50ft_v3/gnal_50ft.scad` and export the different modules in [OFF](https://en.wikipedia.org/wiki/OFF_(file_format)), [AMF](https://en.wikipedia.org/wiki/Additive_manufacturing_file_format), [3MF](https://en.wikipedia.org/wiki/3D_Manufacturing_Format), [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF) or SVG (drawing) format. The CSG models can be [imported](https://wiki.freecadweb.org/OpenSCAD_CSG) into [FreeCAD](https://www.freecadweb.org/) and DXF models should be readable by AutoCAD and [QCAD](https://www.qcad.org/en/).
### Dependencies
* Bash
* [OpenSCAD](https://www.openscad.org/downloads.html) + [cli](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment) ([Mac](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment#MacOS_notes)) ([Windows](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment#Windows_notes))
* [ADMesh](https://github.com/admesh/admesh)
### Build Scripts
Running any of the build scripts scripts--`scripts/v1.sh`, `scripts/v2.sh` or `scripts/v3.sh`--will start an OpenSCAD build process of all components and will log stats about the resulting files and render times to `notes/v1.csv`, `notes/v2.csv` or `notes/v3.csv`.
Keep in mind that V1 and V2 compile times are extremely long and all scripts will use an entire CPU core at 100% utilization while rendering. It's best to run these scripts in the background on a powerful machine or better yet, not at all. See the `stl` folder for pre-compiled STL files for 3D printing or the [releases page](/releases/latest) for .zip archives of all versions.
These scripts will render STL files, PNG images of the files and then
### Benchmarks
The `scripts/benchmark.sh` script will run various tests on the different approaches to generating spirals in the `spiral` directory. See notes on the actual results of this script [below](#benchmarks)
To read more about developing and modifying the GNAL, check out the [development notes](docs/).
-----
## Version notes
<a name="v1"></a>
### V1
<a name="contact"></a>
Intended to be mostly compatible with existing processing spirals with some caveats. A spacer that is typically threaded has been replaced by a friction fit part so they are not interchangeable.
This version is designed to fit in existing tanks and use the same spindle screws.
In the process of building this first version several approaches were evaluated to generate the spiral shape. The first is what's best described as a brute force approach laying out an excessive amount of rectangular facets and unioning them together in such a way that the result would be a single continuous spiral. This took hours to days to render depending on the machine used.
Besides the exhausting render times this approach bugged me for one reason: all facets of the spiral were the same size, meaning that the small diameter inner parts of the spiral were packing in millions of unnecessary polygons to allow for the large diameter parts of the spiral to be smooth. This didn't sit well with me. How many CPU hours are being burned by adding detail to a place that doesn't matter? Answer: a lot.
Finally an external library called [`path_extrude.scad`](https://github.com/gringer/bioinfscripts/blob/master/path_extrude.scad) by [@gringer](https://github.com/gringer) was brought in to handle the complicated spiral extrusion step. A simple function that plots a spiral in Cartesian coordinates is used to draw the path and a 2D triangle is extruded along it by the library. This allowed for the path to be drawn at a consistent "resolution" throughout the entire spiral, so the facets of the outermost and innermost parts were the same or extremely similar.
Here is that function reduced to a single line in order to generate an array of coordinates.
```
spiralPath = [ for(t = [0 : $fn + 1]) [((d / 2) + (t * increment)) * cos(t * angle_i), ((d / 2) + (t * increment)) * sin(t * angle_i), 0] ];
```
The experimentation in this version predate this particular git repo and so will not be found in the git history, but you can find the vestigial functions in the `spiral` directory used for benchmarking different approaches.
#### Beware
This version of the spiral must be printed with supports. The spirals themselves are suspended over voids and this particular feature is addressed in the later versions.
#### Benchmarks
Rendered using OpenSCAD version 2019.05 on a 2.2 GHz Core i7 (I7-4770HQ) chip running macOS 10.14.
| Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|-------|--------------|--------|-------------------------|-------------------|
|gnal_50ft_spacer.stl|991452|5736|2888.155029|68|
|gnal_50ft_top.stl|2132181|12624|57936.746094|233|
| **gnal_50ft_spiral_top.stl** |36509561|214404|120299.773438| **12249** |
| **gnal_50ft_spiral_bottom.stl** |36606204|214970|121519.937500| **13698** |
|gnal_100ft_spacer.stl|991452|5736|2888.149658|74|
|gnal_100ft_top.stl|3302563|19552|102590.546875|477|
|gnal_100ft_spiral_top.stl|92423369|542836|223602.078125|89137|
Had issues or success printing this? Interested in getting in contact?
# [Email me](mailto:gnal@sixteenmillimeter.com)
-----
<a name="v2"></a>
### V2
This version aims to improve printability over the V1 model and reducing render time of the spiral. The biggest change to the physical structure of the design is the removal of overhangs from beneath the spiral film guide.
When printing a model with [FFF printing](https://en.wikipedia.org/wiki/Fused_filament_fabrication), any piece that overhangs empty space (usually) needs to be supported by a temporary removable structure beneath it otherwise you risk the piece drooping. In the case of V1 model, the spiral was completely suspended by the spokes of the reel with large gaps of empty space. This means there were 90 degree overhangs under the most critical part of this model; the grooves for holding the film in position. Printing and removing support structures from beneath the fragile spiral made post-production dangerous for the piece and time consuming.
The solution to this was to extend the spiral to the bottom of the reel and remove triangular sections from them to allow for a lighter print and better chemistry movement. Most printers should be able to print these structures without any support material or any resulting deformations in the model.
One other change in this version is that it reduces the spiral models to a single one to be duplicated, rather than two distinct top and a bottom pieces that differ in only minor ways. This decision was motivated by an interest in making this design better (cheaper) for injection molding.
A secondary benefit of reducing the spiral to a single model was to immediately cut render times for the entire project nearly in half before any other optimizations were made. The first meaningful code optimization toward this goal was provided by a helpful comment made on a long-forgotten design shared on a 3D printing forum.
[@sousvide59](https://www.thingiverse.com/sousvide59/designs) (Les Smith) writes
> It may be more efficient to approximate the spiral as a series of arc segments, like this <[Github gist](https://gist.github.com/sixteenmillimeter/839c16d39d26d04154f52b3f3ee6ee78)>.
Les was right. This reduced the several hours render time to 1-2 hours, which worked for this version. Ideally this will be improved further in future versions. Beyond some explorations into OpenSCAD hacks (rendering each complete rotation of the spiral and stitching all resulting STLs) the next version will incorporate other languages and platforms to find the fastest render time for a GNAL spiral. All previous approaches are being compiled into a suite of tests to benchmark render times.
#### Benchmarks
Rendered using OpenSCAD version 2020.01.17 on a 3.2 GHz Core i5 (I5-4460) chip running Ubuntu 18.04.
| Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|-------|--------------|--------|-------------------------|-------------------|
|gnal_50ft_spacer.stl|991452|5736|2888.150879|22|
|gnal_50ft_top.stl|2132181|12624|57937.210938|73|
| **gnal_50ft_spiral.stl** |34628449|193450|178181.250000| **2341** |
|gnal_50ft_insert_s8.stl|5228272|27230|3493.560303|97|
|gnal_50ft_insert_16.stl|7922994|41426|4664.952637|155|
|gnal_50ft_spacer_16.stl|561267|3272|4015.912109|19|
|gnal_100ft_spacer.stl|991452|5736|2888.152100|23|
|gnal_100ft_top.stl|3302563|19552|102590.812500|118|
| **gnal_100ft_spiral.stl** |59279238|330000|345431.531250| **4542** |
|gnal_100ft_insert_s8.stl|5228272|27230|3493.559326|99|
|gnal_100ft_insert_16.stl|7922994|41426|4664.937500|160|
|gnal_100ft_spacer_16.stl|535264|3112|3964.118164|17|
-----
<a name="v3"></a>
### V3
The goals of V3 are to **greatly** optimize the spiral generation code for speed and to restore the feature of the V1 spiral which maintains a consistent size of individual facets throughout the spiral even as the diameter changes. This will be considered a stable release.
This version will also contain a 4x reel stacking feature so that all models can be stacked with 3 spiral reels and a top piece. That will give 200ft capacity to the 50ft model and 400ft capacity to the 100ft model.
#### Benchmarks
Rendered using OpenSCAD version 2020.08.18 on a 2.2 GHz Core i7 (I7-4770HQ) chip running macOS 10.14.
| Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|-------|--------------|--------|-------------------------|-------------------|
|gnal_50ft_spindle_bottom.stl|3760384|75206|4134.077637|1291|
|gnal_50ft_spindle_top.stl|6915384|138306|22229.814453|1128|
|gnal_50ft_spacer.stl|286884|5736|2888.150635|62|
|gnal_50ft_top.stl|1104884|22096|57933.800781|585|
| **gnal_50ft_spiral.stl** |9500384|190006|171712.140625| **1111** |
|gnal_50ft_insert_s8.stl|1361584|27230|3493.544922|276|
|gnal_50ft_insert_16.stl|2071384|41426|4665.019531|439|
|gnal_50ft_spacer_16.stl|602084|12040|4019.470703|281|
|gnal_100ft_spindle_bottom.stl|3760384|75206|4134.064941|1275|
|gnal_100ft_spindle_top.stl|6979184|139582|22229.773438|1139|
|gnal_100ft_spacer.stl|286884|5736|2888.143555|63|
|gnal_100ft_top.stl|1620084|32400|102557.437500|998|
| **gnal_100ft_spiral.stl** |18364384|367286|326573.812500| **3746** |
|gnal_100ft_insert_s8.stl|1361584|27230|3493.548340|272|
|gnal_100ft_insert_16.stl|2071384|41426|4664.790527|450|
|gnal_100ft_spacer_16.stl|755684|15112|4019.479248|368|
<a name="benchmarks"></a>
## Benchmarks
In the process of publishing this repository I started questioning claims I was making in this readme. Throughout the development of this processing reel I've been plagued by long render times. As a sanity check, I went through my personal development history on this project and produced 7 distinct spiral generation scripts that I ran through a series of tests to benchmark the render performance, total volume generated and number of facets produced. Render time was the primary metric that concerned me, but I considered the other important in comparing these different approaches.
In the `spiral` directory you will find each individual script in a `spiral_#.scad` format. The `scripts/benchmark.sh` script will render spirals at various resolutions and rotation counts and records the results in `notes/benchmark.csv`.
Consider this comparison of just the 50ft spirals (top spiral from V1).
| # | Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|---|-------|--------------|--------|-------------------------|-------------------|
| V1 | gnal_50ft_spiral_top.stl |36509561 | 214404 | 120299.773438 | 12249 |
| V2 | gnal_50ft_spiral.stl |34628449 | 193450 | 178181.250000 | 2341 |
| V3 | gnal_50ft_spiral.stl | 9500384 | 190006 | 171712.140625 | 1111 |
Render times have gone down dramatically.
Halved between V2 and V3.
The volume has stayed consistent with major changes in geometry (between V1 and V2).
The file size of the V3 spiral has reduced to about 30% of the V1 and V2 spirals and the facet count remains roughly the same.
## License

242
docs/README.md Normal file
View File

@ -0,0 +1,242 @@
# Development Notes
1. [Dependencies](#dependencies)
2. [Build Scripts](#scripts)
3. [Version Notes - V1](#v1)
4. [Version Notes - V2](#v2)
5. [Version Notes - V3](#v3)
6. [Benchmarks](#benchmarks)
This project can be edited with only [OpenSCAD](https://www.openscad.org/downloads.html) and the source files in the `scad/*_v1`, `scad/*_v2` or `scad/*_v3` directories which make reference to files from `scad/libraries`.
If you wish to run the development scripts you should install the following dependencies.
With just OpenSCAD, you can use scripts such as `scad/50ft_v3/gnal_50ft.scad` and export the different modules in [OFF](https://en.wikipedia.org/wiki/OFF_(file_format)), [AMF](https://en.wikipedia.org/wiki/Additive_manufacturing_file_format), [3MF](https://en.wikipedia.org/wiki/3D_Manufacturing_Format), [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF) or SVG (drawing) format.
The CSG models can be [imported](https://wiki.freecadweb.org/OpenSCAD_CSG) into [FreeCAD](https://www.freecadweb.org/) and DXF models should be readable by AutoCAD and [QCAD](https://www.qcad.org/en/).
-----
<a name="dependencies"></a>
### Dependencies
* [Bash](https://www.gnu.org/software/bash/) - Available by default on Mac and Linux
* [OpenSCAD](https://www.openscad.org/downloads.html) + [cli](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment) ([Mac](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment#MacOS_notes)) ([Windows](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment#Windows_notes))
* [ADMesh](https://github.com/admesh/admesh)
* (optional) [POV-Ray](http://www.povray.org/download/)
<a name="scripts"></a>
### Build Scripts
Running any of the build scripts scripts--`scripts/v1.sh`, `scripts/v2.sh` or `scripts/v3.sh`--will start an OpenSCAD build process of all components and will log stats about the resulting files and render times to `notes/v1.csv`, `notes/v2.csv` or `notes/v3.csv`.
Keep in mind that V1 and V2 compile times are extremely long and all scripts will use an entire CPU core at 100% utilization while rendering.
It's best to run these scripts in the background on a powerful machine or better yet, not at all. See the `stl` folder for pre-compiled STL files for 3D printing or the [releases page](https://github.com/sixteenmillimeter/GNAL/releases) for .zip and .tar.gz archives of all versions.
These scripts will render STL files, PNG images of the files and capture metadata about the render process while doing so.
-----
## Version Notes
<a name="v1"></a>
### V1
Intended to be mostly compatible with existing processing spirals with some caveats.
A spacer that is typically threaded has been replaced by a friction fit part so they are not interchangeable.
This version is designed to fit in existing tanks and use the same spindle screws.
In the process of building this first version several approaches were evaluated to generate the spiral shape.
The first is what's best described as a brute force approach laying out an excessive amount of rectangular facets and unioning them together in such a way that the result would be a single continuous spiral.
This took hours to days to render depending on the machine used.
Besides the exhausting render times this approach bugged me for one reason: all facets of the spiral were the same size, meaning that the small diameter inner parts of the spiral were packing in millions of unnecessary polygons to allow for the large diameter parts of the spiral to be smooth.
This didn't sit well with me.
How many CPU hours are being burned by adding detail to a place that doesn't matter?
Answer: a lot.
Finally, an external library called [`path_extrude.scad`](https://github.com/gringer/bioinfscripts/blob/master/path_extrude.scad) by [@gringer](https://github.com/gringer) was brought in to handle the complicated spiral extrusion step.
A simple function that plots a spiral in Cartesian coordinates is used to draw the path and a 2D triangle is extruded along it by the library.
This allowed for the path to be drawn at a consistent "resolution" throughout the entire spiral, so the facets of the outermost and innermost parts were the same or extremely similar.
Here is that function reduced to a single line in order to generate an array of coordinates.
```
spiralPath = [ for(t = [0 : $fn + 1]) [((d / 2) + (t * increment)) * cos(t * angle_i), ((d / 2) + (t * increment)) * sin(t * angle_i), 0] ];
```
The experimentation in this version predate this particular git repo and so will not be found in the git history, but you can find the vestigial functions in the `spiral` directory used for benchmarking different approaches.
#### Beware
This version of the spiral must be printed with supports.
The spirals themselves are suspended over voids and this particular feature is addressed in the later versions.
#### Rendering
Rendered using OpenSCAD version 2019.05 on a 2.2 GHz Core i7 (I7-4770HQ) chip running macOS 10.14.
| Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|-------|--------------|--------|-------------------------|-------------------|
|gnal_50ft_spacer.stl|991452|5736|2888.155029|68|
|gnal_50ft_top.stl|2132181|12624|57936.746094|233|
| **gnal_50ft_spiral_top.stl** |36509561|214404|120299.773438| **12249** |
| **gnal_50ft_spiral_bottom.stl** |36606204|214970|121519.937500| **13698** |
|gnal_100ft_spacer.stl|991452|5736|2888.149658|74|
|gnal_100ft_top.stl|3302563|19552|102590.546875|477|
|gnal_100ft_spiral_top.stl|92423369|542836|223602.078125|89137|
|gnal_100ft_spiral_bottom.stl|N/A|N/A|N/A|N/A|
-----
<a name="v2"></a>
### V2
This version aims to improve printability over the V1 model and reducing render time of the spiral.
The biggest change to the physical structure of the design is the removal of overhangs from beneath the spiral film guide.
When printing a model with [FFF printing](https://en.wikipedia.org/wiki/Fused_filament_fabrication), any piece that overhangs empty space (usually) needs to be supported by a temporary removable structure beneath it otherwise you risk the piece drooping.
In the case of V1 model, the spiral was completely suspended by the spokes of the reel with large gaps of empty space.
This means there were 90 degree overhangs under the most critical part of this model; the grooves for holding the film in position.
Printing and removing support structures from beneath the fragile spiral made post-production dangerous for the piece and time consuming.
The solution to this was to extend the spiral to the bottom of the reel and remove triangular sections from them to allow for a lighter print and better chemistry movement.
Most printers should be able to print these structures without any support material or any resulting deformations in the model.
One other change in this version is that it reduces the spiral models to a single one to be duplicated, rather than two distinct top and a bottom pieces that differ in only minor ways.
This decision was motivated by an interest in making this design better (cheaper) for injection molding.
A secondary benefit of reducing the spiral to a single model was to immediately cut render times for the entire project nearly in half before any other optimizations were made.
The first meaningful code optimization toward this goal was provided by a helpful comment made on a long-forgotten design shared on a 3D printing forum.
[@sousvide59](https://www.thingiverse.com/sousvide59/designs) (Les Smith) writes
> It may be more efficient to approximate the spiral as a series of arc segments, like this <[Github gist](https://gist.github.com/sixteenmillimeter/839c16d39d26d04154f52b3f3ee6ee78)>.
Les was right.
This reduced the several hours render time to 1-2 hours, which worked for this version. Ideally this will be improved further in future versions.
Beyond some explorations into OpenSCAD hacks (rendering each complete rotation of the spiral and stitching all resulting STLs) the next version will incorporate other languages and platforms to find the fastest render time for a GNAL spiral.
All previous approaches are being compiled into a suite of tests to benchmark render times.
#### Rendering
Rendered using OpenSCAD version 2020.01.17 on a 3.2 GHz Core i5 (I5-4460) chip running Ubuntu 18.04.
| Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|-------|--------------|--------|-------------------------|-------------------|
|gnal_50ft_spacer.stl|991452|5736|2888.150879|22|
|gnal_50ft_top.stl|2132181|12624|57937.210938|73|
| **gnal_50ft_spiral.stl** |34628449|193450|178181.250000| **2341** |
|gnal_50ft_insert_s8.stl|5228272|27230|3493.560303|97|
|gnal_50ft_insert_16.stl|7922994|41426|4664.952637|155|
|gnal_50ft_spacer_16.stl|561267|3272|4015.912109|19|
|gnal_100ft_spacer.stl|991452|5736|2888.152100|23|
|gnal_100ft_top.stl|3302563|19552|102590.812500|118|
| **gnal_100ft_spiral.stl** |59279238|330000|345431.531250| **4542** |
|gnal_100ft_insert_s8.stl|5228272|27230|3493.559326|99|
|gnal_100ft_insert_16.stl|7922994|41426|4664.937500|160|
|gnal_100ft_spacer_16.stl|535264|3112|3964.118164|17|
-----
<a name="v3"></a>
### V3
The goals of V3 are to **greatly** optimize the spiral generation code for speed and to restore the feature of the V1 spiral which maintains a consistent size of individual facets throughout the spiral even as the diameter changes.
This will be considered a stable release candidate for publishing the project.
Since the benchmarking process ([see below](#benchmarks)) was developed between V2 and V3, render times are optimized in this iteration of the project.
The success of the [`spiral_3.scad`](../scad/spiral/spiral_3.scad) approach stood out from the rest as fastest, so it was reworked into what exists in V3.
The spiral itself is plotted in 2D with a relatively simple formula that is expressed in this OpenSCAD script through a number of in-line helper functions.
It draws the position of various points along the spiral path and then uses the `path_extrude.scad` library to extrude a shape along those coordinates.
This proves to be fast and efficient while not sacrificing any detail in the geometry.
Prior to release a serious flaw was found while printing the V3 design.
The attempt to remove the need for supports in V2, actually printing the spiral was creating curious side effects during fabrication.
Not having material in the voids below the spiral, it seems, allowed air to cool the part and would consistently cause prints to fail when it reached the actual spiral at the top of the reel.
Since this is the most important element of the reel, the triangles have been removed and the design is more similar to V1.
Testing continues on this version.
In a compromise to make the process of removing the support material less dangerous to the detail on the top, the spiral itself extends lower than V1 into the space between the spokes of the reel.
The spiral is also made thicker and is a multiple of my nozzle diameter (0.4mm).
This uses slightly more material but is less fragile than V1 and test prints proved that the supports were less difficult to remove than in the earliest model.
This version will also contain a 4x reel stacking feature so that all models can be stacked with 4 spiral reels and a top piece.
That will give 200ft capacity to the 50ft model and 400ft capacity to the 100ft model.
A stretch goal for this version is to make a 35mm spacer and spindle set so that movie film in the format can be processed in 100ft lengths.
#### Beware
This version *also* requires the use of support material while printing.
#### Rendering
Rendered using OpenSCAD version 2020.08.18 on a 2.2 GHz Core i7 (I7-4770HQ) chip running macOS 10.14.
| Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|-------|--------------|--------|-------------------------|-------------------|
|gnal_50ft_spindle_bottom.stl|3760384|75206|4134.077637|1291|
|gnal_50ft_spindle_top.stl|6915384|138306|22229.814453|1128|
|gnal_50ft_spacer.stl|286884|5736|2888.150635|62|
|gnal_50ft_top.stl|1104884|22096|57933.800781|585|
| **gnal_50ft_spiral.stl** |9500384|190006|171712.140625| **1111** |
|gnal_50ft_insert_s8.stl|1361584|27230|3493.544922|276|
|gnal_50ft_insert_16.stl|2071384|41426|4665.019531|439|
|gnal_50ft_spacer_16.stl|602084|12040|4019.470703|281|
|gnal_100ft_spindle_bottom.stl|3760384|75206|4134.064941|1275|
|gnal_100ft_spindle_top.stl|6979184|139582|22229.773438|1139|
|gnal_100ft_spacer.stl|286884|5736|2888.143555|63|
|gnal_100ft_top.stl|1620084|32400|102557.437500|998|
| **gnal_100ft_spiral.stl** |18364384|367286|326573.812500| **3746** |
|gnal_100ft_insert_s8.stl|1361584|27230|3493.548340|272|
|gnal_100ft_insert_16.stl|2071384|41426|4664.790527|450|
|gnal_100ft_spacer_16.stl|755684|15112|4019.479248|368|
<a name="benchmarks"></a>
## Benchmarks
In the process of publishing this repository I started questioning claims I was making in this README.
Throughout the development of this processing reel I've been plagued by long render times.
As a sanity check, I went through my personal development history on this project and produced 6 distinct spiral generation scripts that I ran through a series of tests to benchmark the render performance, total volume generated and number of facets produced.
Render time was the primary metric that concerned me, but I considered the others important in comparing these different approaches.
This work led to the creation of the approach in `spiral_7.scad` and was ultimately used in V3.
An example of a single test pulled from the `notes/benchmark.csv` results.
These example results are rendered using OpenSCAD 2020.05.23 on a 2.3 GHz Xeon Gold 6140 chip running Ubuntu 18.04.
|Spiral Test|Diameter (mm)|Rotations| [$fn](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#$fa,_$fs_and_$fn) |Size (bytes)|Facets|Volume (mm<sup>3</sup>)|Time (sec)|
|---|---|---|---|---|---|---|---|
|[spiral_1.scad](../scad/spiral/spiral_1.scad)|47|10|100|7409653|41064|5391.819336|209|
|[spiral_2.scad](../scad/spiral/spiral_2.scad)|47|10|100|15349620|86646|3639.441162|855|
|[spiral_3.scad](../scad/spiral/spiral_3.scad)|47|10|100|1336635|8004|3589.485596|0|
|[spiral_4.scad](../scad/spiral/spiral_4.scad)|47|10|100|1607691|9624|3830.134521|23|
|[spiral_5.scad](../scad/spiral/spiral_5.scad)|47|10|100|4711486|28188|3602.101562|8|
|[spiral_6.scad](../scad/spiral/spiral_6.scad)|47|10|100|4265376|25396|14337.455078|120|
|[spiral_7.scad](../scad/spiral/spiral_7.scad)|47|10|100|990006|5924|3581.499756|0|
As you can see, the different approaches lead to wildly different render times for the same test.
If you look at the complete results you will see many tests did not even finish due to exhausting memory on the machine or the process being killed by the cloud host (using too much CPU for too long, most likely).
In the case of `spiral_3.scad` and `spiral_7.scad` measuring "0" seconds, this just means that the process finished rendering in less than 1 second.
In the `scad/spiral` directory you will find each individual script in a `scad/spiral/spiral_#.scad` file.
The `scripts/benchmark.sh` script will render spirals at various resolutions and rotation counts and record the results in `notes/benchmark.csv`.
Insights gleaned from these benchmarks was incorporated into the latest versions of design.
Consider this comparison of just the 50ft spirals (top spiral from V1).
| # | Model | Size (bytes) | Facets | Volume (mm<sup>3</sup>) | Render Time (sec) |
|---|-------|--------------|--------|-------------------------|-------------------|
| V1 | gnal_50ft_spiral_top.stl |36509561 | 214404 | 120299.773438 | 12249 |
| V2 | gnal_50ft_spiral.stl |34628449 | 193450 | 178181.250000 | 2341 |
| V3 | gnal_50ft_spiral.stl | 9500384 | 190006 | 171712.140625 | 1111 |
Render times have gone down dramatically between V1 and V2.
Times halved again between V2 and V3.
The volume has stayed consistent with major changes in geometry (between V1 and V2).
The file size of the V3 spiral has reduced to about 30% of the V1 and V2 spirals and the facet count remains roughly the same throughout (which was a surprise).
Faster render times mean more iteration and less time between tests.
The next part of the process to examine is slicing which has primarily been done with Cura, but other engines will be looked at for their speed, efficiency and print quality.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 59 KiB

BIN
img/gnal_50ft_v3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
img/gnal_50ft_v3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -106,22 +106,22 @@ module gnal_100ft_spiral (spiral_count = 60, od = 298.75) {
rotate([0, 0, -90]) {
difference () {
film_guide(spiral_count, od);
for (i = [0 : SPOKE_COUNT]) {
for (i = [0 : SPOKE_COUNT - 1]) {
rotate([0, 0, (i + 0.5) * (360 / SPOKE_COUNT) ]) {
translate([(83 / 4) + (48 / 2), 0, -3.6]) triangle_void();
}
}
for (i = [0 : SPOKE_COUNT * 2]) {
for (i = [0 : (SPOKE_COUNT * 2) - 1]) {
rotate([0, 0, (i + 0.5) * (360 / (SPOKE_COUNT * 2)) ]) {
translate([(258 / 2) - (spoke_2_len / 2) + 1 , 0, -3.6]) triangle_void_2();
translate([(258 / 2) - (spoke_2_len / 2) + 1 , 0, -3.6 ]) triangle_void_2(i);
}
}
for (i = [0 : SPOKE_COUNT * 4]) {
for (i = [0 : (SPOKE_COUNT * 4) - 1]) {
rotate([0, 0, (i + 0.5) * (360 / (SPOKE_COUNT * 4)) ]) {
if (i % 2 == 0) {
translate([(outer_d / 2) - (spoke_3_len / 2) + 1 , 0.3, -3.6]) triangle_void_3();
translate([(outer_d / 2) - (spoke_3_len / 2) + 1 , 0.3, -3.6]) triangle_void_3(i);
} else {
translate([(outer_d / 2) - (spoke_3_len / 2) + 1, -0.3, -3.6]) triangle_void_3();
translate([(outer_d / 2) - (spoke_3_len / 2) + 1 , -0.3, -3.6]) triangle_void_3(i);
}
}
}

View File

@ -101,38 +101,9 @@ module gnal_100ft_spiral (spiral_count = 60, od = 298.75, quarter = false) {
}
}
//Triangular voids
/*
translate([0, 0, -.1]) {
rotate([0, 0, -90]) {
difference () {
film_guide(spiral_count);
for (i = [0 : SPOKE_COUNT - 1]) {
rotate([0, 0, (i + 0.5) * (360 / SPOKE_COUNT) ]) {
translate([(83 / 4) + (48 / 2), 0, -3.6]) triangle_void();
}
}
for (i = [0 : (SPOKE_COUNT * 2) - 1]) {
rotate([0, 0, (i + 0.5) * (360 / (SPOKE_COUNT * 2)) ]) {
translate([(258 / 2) - (spoke_2_len / 2) + 1 , 0, -3.6 ]) triangle_void_2(i);
}
}
for (i = [0 : (SPOKE_COUNT * 4) - 1]) {
rotate([0, 0, (i + 0.5) * (360 / (SPOKE_COUNT * 4)) ]) {
if (i % 2 == 0) {
translate([(outer_d / 2) - (spoke_3_len / 2) + 1 , 0.3, -3.6]) triangle_void_3(i);
} else {
translate([(outer_d / 2) - (spoke_3_len / 2) + 1 , -0.3, -3.6]) triangle_void_3(i);
}
}
}
}
}
}
*/
translate([0, 0, -.1]) {
rotate([0, 0, -90]) {
film_guide2(spiral_count);
film_guide(spiral_count);
}
}
}
@ -281,11 +252,8 @@ module gnal_100ft_top () {
FN = 200;
$fn = FN;
module film_guide (rotations = 60, id = 45.55, spacing = 2.075, bottom = -7.1) {
spiral(rotations, id, spacing, bottom, $fn);
}
module film_guide2 (rotations = 60, id = 45.55, spacing = 2.075, bottom = -2) {
module film_guide (rotations = 60, id = 45.55, spacing = 2.075, bottom = -2) {
spiral(rotations, id, spacing, bottom, $fn);
}
@ -309,10 +277,14 @@ if (PART == "spiral") {
gnal_spiral_bottom_insert_s8();
} else if (PART == "insert_16") {
gnal_spiral_bottom_insert_16();
} else if (PART == "insert_single") {
gnal_spiral_bottom_insert_single();
} else if (PART == "spacer_16") {
gnal_spacer_16();
} else if (PART == "spindle_top") {
gnal_spindle_top();
} else if (PART == "spindle_bottom") {
gnal_spindle_bottom();
}
} else if (PART == "spindle_single") {
gnal_spindle_single();
}

View File

@ -73,7 +73,7 @@ module gnal_50ft_spiral (spiral_count = 40, od = 215.75) {
}
for (i = [0 : SPOKE_COUNT * 2]) {
rotate([0, 0, (i + 0.5) * (360 / (SPOKE_COUNT * 2)) ]) {
translate([(outer_d / 2) - (spoke_2_len / 2) + 1 , 0, -3.6]) triangle_void_2();
translate([(outer_d / 2) - (spoke_2_len / 2) + 1 , 0, -3.6]) triangle_void_2(i);
}
}
}

View File

@ -62,29 +62,9 @@ module gnal_50ft_spiral (spiral_count = 40, od = 215.75, quarter = false) {
}
}
//Triangular voids
/*
translate([0, 0, -.1]) {
rotate([0, 0, -90]) {
difference () {
film_guide(spiral_count);
for (i = [0 : SPOKE_COUNT]) {
rotate([0, 0, (i + 0.5) * (360 / SPOKE_COUNT) ]) {
translate([(spoke_len / 4) + (48 / 2), 0, -3.6]) triangle_void();
}
}
for (i = [0 : SPOKE_COUNT * 2]) {
rotate([0, 0, (i + 0.5) * (360 / (SPOKE_COUNT * 2)) ]) {
translate([(outer_d / 2) - (spoke_2_len / 2) + 1 , 0, -3.6]) triangle_void_2(i);
}
}
}
}
}
*/
translate([0, 0, -.1]) {
rotate([0, 0, -90]) {
film_guide2(spiral_count);
film_guide(spiral_count);
}
}
}
@ -202,11 +182,8 @@ module gnal_50ft_top () {
FN = 200;
$fn = FN;
module film_guide (rotations = 40, id = 45.55 - .5, spacing = 2.075, bottom = -7.1) {
spiral(rotations, id, spacing, bottom, $fn);
}
module film_guide2 (rotations = 40, id = 45.55 - .5, spacing = 2.075, bottom = -2) {
module film_guide (rotations = 40, id = 45.55 - .5, spacing = 2.075, bottom = -2) {
spiral(rotations, id, spacing, bottom, $fn);
}
@ -230,12 +207,16 @@ if (PART == "spiral") {
gnal_spiral_bottom_insert_s8();
} else if (PART == "insert_16") {
gnal_spiral_bottom_insert_16();
} else if (PART == "insert_single") {
gnal_spiral_bottom_insert_single();
} else if (PART == "spacer_16") {
gnal_spacer_16();
} else if (PART == "spindle_top") {
gnal_spindle_top();
} else if (PART == "spindle_bottom") {
gnal_spindle_bottom();
} else if (PART == "spindle_single") {
gnal_spindle_top();
} else if (PART == "spiral_test") {
difference () {
gnal_50ft_spiral();

View File

@ -306,13 +306,14 @@ module gnal_spacer_16 () {
/**
* Spokes
**/
module triangle_void () {
length = (81 / 2) - 9;
length = (81 / 2) - 9 + 10;
width = 12;
height = 4.5 + 2.7;
ANGLE_A = 34.8;
ANGLE_B = 180 / SPOKE_COUNT;
ANGLE_C = 20;
difference () {
translate([-1, 0, 0]) cube([length, width, height], center = true);
translate([0, 10.3, 0]) rotate([0, 0, ANGLE_B]) cube([length * 2, width, height + 1], center = true);
@ -320,40 +321,57 @@ module triangle_void () {
translate([0, 10.3, -.7]) rotate([ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([0, -10.3, -.7]) rotate([-ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([(length / 2) + 2, 0, 0]) rotate([0, 0, ANGLE_C]) cube([10, width * 2, height + 1], center = true);
}
}
module triangle_void_2 () {
length = 43 - 8;
module triangle_void_2 (i) {
length = 43 - 8 + 12;
width = 12;
height = 4.5 + 2.7;
ANGLE_A = 34.8;
ANGLE_B = 90 / SPOKE_COUNT;
ANGLE_C = 20;
angle_w = 10.2;
difference () {
translate([-1, 0, 0]) cube([length, width, height], center = true);
translate([-3, 0, 0]) cube([length, width, height], center = true);
translate([0, angle_w, 0]) rotate([0, 0, ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, 0]) rotate([0, 0, -ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, angle_w, -.7]) rotate([ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, -.7]) rotate([-ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
if (i % 2 == 0) {
translate([-(length / 2) - 5, 0, 0]) rotate([0, 0, ANGLE_C]) cube([10, width * 2, height + 1], center = true);
} else {
translate([-(length / 2) - 7, 0, 0]) rotate([0, 0, ANGLE_C]) cube([10, width * 2, height + 1], center = true);
}
translate([(length / 2) + 1, 0, 0]) rotate([0, 0, -ANGLE_C]) cube([10, width * 2, height + 1], center = true);;
}
}
module triangle_void_3 () {
length = 32;
module triangle_void_3 (i) {
length = 32 + 10;
width = 10;
height = 4.5 + 2.7;
ANGLE_A = 31;
ANGLE_B = 45 / SPOKE_COUNT;
ANGLE_C = 20;
angle_w = 7.8;
difference () {
translate([-1, 0, 0]) cube([length, width, height], center = true);
translate([-3, 0, 0]) cube([length, width, height], center = true);
translate([0, angle_w, 0]) rotate([0, 0, ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, 0]) rotate([0, 0, -ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, angle_w, -.7]) rotate([ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, -.7]) rotate([-ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
if (i % 2 == 0) {
translate([-(length / 2) - 7, 0, 0]) rotate([0, 0, -ANGLE_C]) cube([10, width * 2, height + 1], center = true);
} else {
translate([-(length / 2) - 5, 0, 0]) rotate([0, 0, -ANGLE_C]) cube([10, width * 2, height + 1], center = true);
}
}
}

View File

@ -13,6 +13,8 @@ include <./Triangles.scad>;
* + clone translated along Z by 0.2mm
* BOTTOM (small screw)
* metric_thread (diameter=10, pitch=1.5, thread_size = 1.6, length=LEN);
* SINGLE LEVEL (middle screw)
*
*/
FINE = 200;
@ -23,6 +25,7 @@ THREAD = 1.6;
LEN = 21;
INSERT_D = 26;
SINGLE_THREAD_D = 12;
function X (start_r, spacing, fn, r, i) = (start_r + (r * spacing) + (i * calcIncrement(spacing, fn))) * cos(i * calcAngle(fn));
function Y (start_r, spacing, fn, r, i) = (start_r + (r * spacing) + (i * calcIncrement(spacing, fn))) * sin(i * calcAngle(fn));
@ -120,7 +123,7 @@ module gnal_spiral_core () {
}
}
cylinder(r = void_d / 2, h = 30, center = true);
translate([0, 0, -7.2]) spiral_bottom_insert_void();
translate([0, 0, -7.2]) spiral_insert_void();
}
//arms
@ -182,11 +185,11 @@ module gnal_spiral_core () {
cylinder(r = core_void_outer_d / 2, h = core_void_h, center = true);
rotate([0, 0, -120]) translate([20, 0, -1.5]) rotate([0, 0, 45]) cube([20, 20, 3.01], center = true);
cylinder(r = void_d / 2, h = 30, center = true);
translate([0, 0, -7.2]) spiral_bottom_insert_void();
translate([0, 0, -7.2]) spiral_insert_void();
}
}
module spiral_bottom_insert_void () {
module spiral_insert_void () {
intersection () {
rotate([0, 45, 0]) cube([3, INSERT_D + 2, 3], center = true);
cylinder(r = (INSERT_D + 1) / 2, h = 6, center = true);
@ -272,6 +275,45 @@ module gnal_spiral_bottom_insert_16 () {
}
}
/**
* Comment to preserve my sanity when developing: This single-spiral
* insert is the same height as the s8 insert but has a different
* diameter void fo the screw to prevent mismatching of spindle screws
* designed for different purposes.
**/
module gnal_spiral_bottom_insert_single () {
$fn = 160;
void_d = 18 - .3;
H = 17;
D2 = INSERT_D;
translate([0, 0, 0]) difference () {
union () {
cylinder(r = void_d / 2, h = H, center = true);
//skirt
translate([0, 0, -(H - 1) / 2]) cylinder(r = D2 / 2, h = 1.5, center = true);
//notches
translate([0, 0, -((H - 2.5) / 2) - .1]) {
intersection () {
cylinder(r = D2 / 2, h = 6, center = true);
difference () {
rotate([0, 45, 0]) cube([3, D2 + 2, 3], center = true);
translate([0, 0, -1.5]) cube([6, D2 + 3, 3], center = true);
}
}
intersection () {
cylinder(r = D2 / 2, h = 6, center = true);
rotate([0, 0, 90]) difference () {
rotate([0, 45, 0]) cube([3, D2 + 2, 3], center = true);
translate([0, 0, -1.5]) cube([6, D2 + 3, 3], center = true);
}
}
}
}
translate([0, 0, -LEN / 2]) metric_thread (diameter=SINGLE_THREAD_D, pitch=PITCH, thread_size = THREAD, length = LEN);
}
}
/**
* Spacers
**/
@ -359,78 +401,6 @@ module gnal_spacer_16 () {
}
}
/**
* Spokes
**/
module triangle_void () {
length = (81 / 2) - 9 + 10;
width = 12;
height = 4.5 + 2.7;
ANGLE_A = 34.8;
ANGLE_B = 180 / SPOKE_COUNT;
ANGLE_C = 20;
difference () {
translate([-1, 0, 0]) cube([length, width, height], center = true);
translate([0, 10.3, 0]) rotate([0, 0, ANGLE_B]) cube([length * 2, width, height + 1], center = true);
translate([0, -10.3, 0]) rotate([0, 0, -ANGLE_B]) cube([length * 2, width, height + 1], center = true);
translate([0, 10.3, -.7]) rotate([ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([0, -10.3, -.7]) rotate([-ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([(length / 2) + 2, 0, 0]) rotate([0, 0, ANGLE_C]) cube([10, width * 2, height + 1], center = true);
}
}
module triangle_void_2 (i) {
length = 43 - 8 + 12;
width = 12;
height = 4.5 + 2.7;
ANGLE_A = 34.8;
ANGLE_B = 90 / SPOKE_COUNT;
ANGLE_C = 20;
angle_w = 10.2;
difference () {
translate([-3, 0, 0]) cube([length, width, height], center = true);
translate([0, angle_w, 0]) rotate([0, 0, ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, 0]) rotate([0, 0, -ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, angle_w, -.7]) rotate([ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, -.7]) rotate([-ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
if (i % 2 == 0) {
translate([-(length / 2) - 5, 0, 0]) rotate([0, 0, ANGLE_C]) cube([10, width * 2, height + 1], center = true);
} else {
translate([-(length / 2) - 7, 0, 0]) rotate([0, 0, ANGLE_C]) cube([10, width * 2, height + 1], center = true);
}
translate([(length / 2) + 1, 0, 0]) rotate([0, 0, -ANGLE_C]) cube([10, width * 2, height + 1], center = true);;
}
}
module triangle_void_3 (i) {
length = 32 + 10;
width = 10;
height = 4.5 + 2.7;
ANGLE_A = 31;
ANGLE_B = 45 / SPOKE_COUNT;
ANGLE_C = 20;
angle_w = 7.8;
difference () {
translate([-3, 0, 0]) cube([length, width, height], center = true);
translate([0, angle_w, 0]) rotate([0, 0, ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, 0]) rotate([0, 0, -ANGLE_B]) cube([length *2, width, height * 10], center = true);
translate([0, angle_w, -.7]) rotate([ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
translate([0, -angle_w, -.7]) rotate([-ANGLE_A, 0, 0]) cube([length *2, width, height * 10], center = true);
if (i % 2 == 0) {
translate([-(length / 2) - 7, 0, 0]) rotate([0, 0, -ANGLE_C]) cube([10, width * 2, height + 1], center = true);
} else {
translate([-(length / 2) - 5, 0, 0]) rotate([0, 0, -ANGLE_C]) cube([10, width * 2, height + 1], center = true);
}
}
}
/**
* Spindles
**/
@ -515,6 +485,12 @@ module gnal_spindle_bottom (ALT = false, HEX = false) {
}
}
module number_one () {
rotate([0, 45, 0]) cube([1, 6, 1], center = true);
translate([0, 6 / 2, 0]) rotate([45, 0, 0]) cube([2, 1, 1], center = true);
translate([0, -6 / 2, 0]) rotate([45, 0, 0]) cube([2, 1, 1], center = true);
}
module gnal_spindle_top () {
D = 50;
THICKNESS = 2.5;
@ -567,6 +543,9 @@ module gnal_spindle_top () {
translate([0, 0, -15]) {
difference() {
cylinder(r1 = HANDLE_BASE / 2, r2 = HANDLE_TOP / 2, h = HANDLE_H, $fn = FINE);
//text
translate([3 / 2, 0, 15 + 39.75]) number_one();
translate([-3 / 2, 0, 15 + 39.75]) number_one();
//ring negative
translate([0, 0, 31 + 14.5]) {
difference () {
@ -604,10 +583,116 @@ module gnal_spindle_top () {
}
//screw
translate([0, 0, -37.5]) {
metric_thread (diameter=13.6, pitch=1.5 ,thread_size = 1.6, length = 21);
metric_thread (diameter=13.6, pitch = PITCH, thread_size = THREAD, length = 21);
}
//cylinder plug
translate([0, 0, -37.5 + (21 / 2) - 1]) {
cylinder(r = 12 / 2, h = 21, center = true, $fn = FINE);
}
}
module gnal_spindle_single () {
D = 50;
THICKNESS = 2.5;
H = 19.5;
ROUND = 8;
HANDLE_D = 13.25;
HANDLE_BASE = 16;
HANDLE_TOP = 13;
HANDLE_H = 54.5;
NOTCHES = 17;
NOTCH = 1.5;
FINE = 200;
SINGLE_INSERT = 11;
difference () {
//cup
translate([0, 0, ROUND - 2]) minkowski () {
cylinder(r = (D / 2) - ROUND, h = (H * 2) - ROUND, center = true, $fn = FINE);
sphere(r = ROUND, $fn = FINE);
}
translate([0, 0, ROUND - 2 + THICKNESS]) minkowski () {
cylinder(r = (D / 2) - THICKNESS - ROUND, h = (H * 2) - ROUND, center = true, $fn = 200);
sphere(r = ROUND, $fn = FINE);
}
//hollow out cup
translate([0, 0, H + ROUND - 4 - 3]) {
cylinder(r = (D / 2) + 1, h = H * 2, center = true);
}
//inner cup bevel
translate([0, 0, (H / 2) - ROUND - 1]) {
cylinder(r1 = (D / 2) - 2.5, r2 = (D / 2) - 2.5 + 1, h = 1, center = true, $fn = FINE);
}
//outer cup bevel
translate([0, 0, (H / 2) - ROUND - 1]) {
difference () {
cylinder(r = (D / 2) + .25, h = 1, center = true, $fn = FINE);
cylinder(r2 = (D / 2) - .8, r1 = (D / 2) - .8 + 1, h = 1, center = true, $fn = FINE);
}
}
//hole in cup
translate([21, 0, -10]) cylinder(r = 3 / 2, h = 40, center = true, $fn = 40);
}
//reference cylinder
//translate([0, 0, -6.6]) color("red") cylinder(r = 50 / 2, h = 19.57, center = true);
//handle
translate([0, 0, -15]) {
difference() {
cylinder(r1 = HANDLE_BASE / 2, r2 = HANDLE_TOP / 2, h = HANDLE_H, $fn = FINE);
//text
translate([0, 0, 15 + 39.75]) number_one();
//ring negative
translate([0, 0, 31 + 14.5]) {
difference () {
cylinder(r = HANDLE_D / 2 + 2, h = 20, center = true);
cylinder(r = HANDLE_D / 2 - .5, h = 20 + 1, center = true);
}
}
//handle notches
for(i = [0 : NOTCHES]) {
rotate([0, 0, i * (360 / NOTCHES)]) {
translate([0, HANDLE_D / 2 - .5, 31 + 14.5]) {
rotate([0.75, 0, 0]) rotate([0, 0, 45]) {
Right_Angled_Triangle(a = NOTCH, b = NOTCH, height = 20, centerXYZ=[true, true, true]);
}
}
}
}
//bevel handle at top
translate([0, 0, 54.01]) {
difference () {
cylinder(r = 13 / 2, h = 1, center = true);
cylinder(r1 = 12.5 / 2, r2 = 11.5 / 2, h = 1.01, center = true);
}
}
}
}
//attach handle with pyramid cylinder
translate ([0, 0, -13.7]) {
cylinder(r1 = 16 / 2 + 2, r2 = 16 / 2 - .1, h = 3, center = true, $fn = FINE);
}
//plate under cup
translate([0, 0, -17.75]) {
cylinder(r = 31.5 / 2, h = 1, center = true, $fn = FINE);
}
//insert for single layer
translate ([0, 0, -24.25]) {
cylinder(r = 22 / 2, h = 14, center = true, $fn = FINE);
}
//screw
translate([0, 0, -37.5 - SINGLE_INSERT]) {
metric_thread (diameter=SINGLE_THREAD_D, pitch = PITCH, thread_size = THREAD, length = 21);
}
//cylinder plug
translate([0, 0, -37.5 - SINGLE_INSERT + (21 / 2) - 1]) {
cylinder(r = 10 / 2, h = 21, center = true, $fn = FINE);
}
}

View File

@ -16,7 +16,7 @@ do
FILES=./stl/${SIZE}_${VERSION}/*.stl
for stl in $FILES
do
fileSize=`wc -c < "$stl"`
fileSize=`bash ./scripts/size.sh "$stl"`
fileSize=`echo $newSize | xargs`
firstline=`head -n 1 "$stl"`
@ -24,7 +24,7 @@ do
echo "Converting $stl to binary..."
#convert from ascii to binary
admesh -c -b "$stl" "$stl"
newSize=`wc -c < "$stl"`
newSize=`bash ./scripts/size.sh "$stl"`
newSize=`echo $newSize | xargs`
percent=`echo "scale=1;($newSize/$fileSize)*100" | bc`
#fileSize="${newSize}"

11
scripts/cores.sh Normal file
View File

@ -0,0 +1,11 @@
#!/bin/bash
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
CORES=`grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}'`
elif [[ "$OSTYPE" == "darwin"* ]]; then
CORES=`sysctl -n hw.ncpu`
else
CORES=?
fi
echo $CORES

View File

@ -8,5 +8,4 @@ else
CPU=-1
fi
echo $CPU

39
scripts/deps.sh Normal file
View File

@ -0,0 +1,39 @@
DEPS=(
echo
git
date
wc
grep
awk
uniq
sha256sum
zip
tar
sqlite3
admesh
openscad
)
for dep in ${DEPS[@]}; do
if ! command -v "${dep}" &> /dev/null
then
echo "Application ${dep} could not be found"
echo "Please install ${dep} before running the build script"
if [[ "${dep}" == "admesh" ]]; then
echo "For more information about how to install admesh https://github.com/admesh/admesh"
echo "OR https://www.howtoinstall.me/ubuntu/18-04/admesh/"
fi
echo "Individual .scad files can be compiled directly without this script"
exit 1
fi
done
echo "All dependencies are installed"
VERSION=`bash ./scripts/version.sh`
CPU=`bash ./scripts/cpu.sh`
CORES=`bash ./scripts/cores.sh`
echo "CPU: (${CORES}x) ${CPU}"
echo "OpenSCAD: ${VERSION}"

12
scripts/license.sh Normal file
View File

@ -0,0 +1,12 @@
#!/bin/bash
YEAR=`cat LICENSE.txt | grep "^Copyright" | awk '{print $3}'`
NOW=`date '+%Y'`
if [ $NOW -gt $YEAR ]; then
echo "Current year $NOW > $YEAR, updating license..."
LICENSE=`cat LICENSE.txt`
UPDATED=`echo "${LICENSE}" | sed "s/${YEAR}/${NOW}/"`
echo "${UPDATED}" > LICENSE.txt
fi

27
scripts/size.sh Normal file
View File

@ -0,0 +1,27 @@
#!/bin/bash
FILE="$1"
if [ "$FILE" = "" ]; then
echo -1
exit 1
fi
#wc -c < "$FILE"
#exit 0
if [ "$(uname)" == "Darwin" ]; then
# Mac OS X platform
stat -f%z "${FILE}"
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
# GNU/Linux platform
stat -c%s "${FILE}"
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then
# 32 bits Windows NT platform
echo -1
exit 2
elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
# 64 bits Windows NT platform
echo -1
exit 3
fi

View File

@ -3,88 +3,159 @@ V="v3"
echo "Rendering GNAL ${V}"
bash ./scripts/deps.sh
bash ./scripts/license.sh
VERSION=`bash ./scripts/version.sh`
CPU=`bash ./scripts/cpu.sh`
DIST=./stl
CSG=./csg
IMG=./img
NOTES=./notes/${V}.csv
STEP=true
LOGGING=true
#"quarter_a" "quarter_b" "quarter_c" "quarter_d"
#quarter pieces not rendering properly
FILES=( "spindle_bottom" "spindle_top" "spacer" "top" "spiral" "insert_s8" "insert_16" "spacer_16" )
FILES=(
"spindle_bottom"
"spindle_top"
"spindle_single"
"insert_s8"
"insert_16"
"spacer_16"
"insert_single"
"top"
"spiral"
)
SIZES=( "50ft" "100ft" )
mkdir -p $DIST
mkdir -p "${DIST}"
if [ $STEP = true ]; then
mkdir -p "${CSG}"
mkdir -p "${CSG}/${SIZE}_${V}/"
fi
render_part () {
scad="${1}"
SIZE="${2}"
FILE="${3}"
stl="${DIST}/${SIZE}_${V}/gnal_${SIZE}_${FILE}.stl"
csg="${CSG}/${SIZE}_${V}/gnal_${SIZE}_${FILE}.csg"
png="${IMG}/gnal_${SIZE}_${V}_${FILE}.png"
echo "${scad} - ${FILE}"
start=`date +%s`
if [[ "${SIZE}" == "100ft" ]]; then
openscad --csglimit=2000000 -o "$stl" -D "PART=\"${FILE}\"" -D "FN=800" "${scad}"
else
openscad --csglimit=1000000 -o "$stl" -D "PART=\"${FILE}\"" -D "FN=600" "${scad}"
fi
end=`date +%s`
runtime=$((end-start))
fileSize=`wc -c < "$stl"`
fileSize=`echo $fileSize | xargs`
if ! [ -x "$(command -v admesh)" ]; then
facets="N/A"
volume="N/A"
else
firstline=`head -n 1 "$stl"`
if [[ $firstline == solid* ]]; then
#convert from ascii to binary
tmpBinary=`mktemp`
admesh -c -b "$tmpBinary" "$stl"
newSize=`wc -c < "$tmpBinary"`
newSize=`echo $newSize | xargs`
if [ $newSize -lt $fileSize ]; then
cp "$tmpBinary" "$stl"
percent=`echo "scale=1;($newSize/$fileSize)*100" | bc`
fileSize="${newSize}"
echo "Binary conversion created STL file ${percent}% of original"
else
echo "Binary STL is larger than ASCII original, skipping conversion..."
fi
rm "$tmpBinary"
fi
ao=`admesh -c "$stl"`
facets=`echo "$ao" | grep "Number of facets" | awk '{print $5}'`
volume=`echo "$ao" | grep "Number of parts" | awk '{print $8}'`
fi
hash=`sha256sum "$stl" | awk '{ print $1 }'`
if [ ${LOGGING} = true ]; then
line="${VERSION},${CPU},$stl,$hash,$fileSize,$srchash,$srcsize,$facets,$volume,$runtime"
echo "$line" >> $NOTES
echo "$line"
fi
start=`date +%s`
if [[ "${SIZE}" == "100ft" ]]; then
openscad --csglimit=20000000 -o "$csg" -D "PART=\"${FILE}\"" -D "FN=800" "${scad}"
else
openscad --csglimit=10000000 -o "$csg" -D "PART=\"${FILE}\"" -D "FN=600" "${scad}"
fi
end=`date +%s`
runtime=$((end-start))
echo "Rendering image of ${stl}..."
if [[ "${FILE}" == "spiral" ]]; then
tmp=`mktemp`
fullPath=`realpath "${stl}"`
data="import(\"${fullPath}\");"
echo data > "${tmp}.scad"
openscad -o "$png" --imgsize=2048,2048 --colorscheme=DeepOcean "${tmp}.scad"
else
openscad -o "$png" --imgsize=2048,2048 --colorscheme=DeepOcean -D "PART=\"${FILE}\"" "${scad}"
fi
}
if [[ "${1}" != "" ]]; then
LOGGING=false
SIZE="${1}"
scad="./scad/${SIZE}_${V}/gnal_${SIZE}.scad"
mkdir -p "${DIST}/${SIZE}_${V}"
if [[ "${2}" != "" ]]; then
FILE="${2}"
render_part "${scad}" "${SIZE}" "${FILE}"
else
for FILE in "${FILES[@]}"; do
render_part "${scad}" "${SIZE}" "${FILE}"
done
fi
exit 0
fi
echo "version,cpu,file,file_hash,file_size,source_hash,source_size,facets,volume,render_time" > $NOTES
for SIZE in "${SIZES[@]}"
do
:
mkdir -p "${DIST}/${SIZE}_${V}"
scad="./scad/${SIZE}_${V}/gnal_${SIZE}.scad"
srchash=`sha256sum "${scad}" | awk '{ print $1 }'`
srcsize=`wc -c < "${scad}"`
srcsize=`echo $srcsize | xargs`
mkdir -p "${DIST}/${SIZE}_${V}"
for FILE in "${FILES[@]}"
do
:
stl="${DIST}/${SIZE}_${V}/gnal_${SIZE}_${FILE}.stl"
png="${IMG}/gnal_${SIZE}_${V}_${FILE}.png"
echo "${scad} - ${FILE}"
start=`date +%s`
if [[ "${SIZE}" == "100ft" ]]; then
openscad -o "$stl" -D "PART=\"${FILE}\"" -D "FN=800" "${scad}"
else
openscad -o "$stl" -D "PART=\"${FILE}\"" -D "FN=600" "${scad}"
fi
end=`date +%s`
runtime=$((end-start))
fileSize=`wc -c < "$stl"`
fileSize=`echo $fileSize | xargs`
if ! [ -x "$(command -v admesh)" ]; then
facets="N/A"
volume="N/A"
else
firstline=`head -n 1 "$stl"`
if [[ $firstline == solid* ]]; then
#convert from ascii to binary
admesh -c -b "$stl" "$stl"
newSize=`wc -c < "$stl"`
newSize=`echo $newSize | xargs`
percent=`echo "scale=1;($newSize/$fileSize)*100" | bc`
fileSize="${newSize}"
echo "Binary conversion created STL file ${percent}% of original"
fi
ao=`admesh -c "$stl"`
facets=`echo "$ao" | grep "Number of facets" | awk '{print $5}'`
volume=`echo "$ao" | grep "Number of parts" | awk '{print $8}'`
fi
hash=`sha256sum "$stl" | awk '{ print $1 }'`
line="${VERSION},${CPU},$stl,$hash,$fileSize,$srchash,$srcsize,$facets,$volume,$runtime"
echo "$line" >> $NOTES
echo "$line"
echo "Rendering image of ${stl}..."
if [[ "${FILE}" == "spiral" ]]; then
tmp=`mktemp`
fullPath=`realpath "${stl}"`
data="import(\"${fullPath}\");"
echo data > "${tmp}.scad"
openscad -o "$png" --imgsize=1920,1080 --colorscheme=DeepOcean "${tmp}.scad"
else
openscad -o "$png" --imgsize=1920,1080 --colorscheme=DeepOcean -D "PART=\"${FILE}\"" "${scad}"
fi
for FILE in "${FILES[@]}"; do
render_part "${scad}" "${SIZE}" "${FILE}"
done
# add license to directories for zip
cp ./LICENSE.txt "./stl/${SIZE}_v3/"
# zip all
zip -x ".*" -r "./releases/gnal_${SIZE}_v3.zip" "./stl/${SIZE}_v3/"
# tar all
tar --exclude=".*" -czvf "./releases/gnal_${SIZE}_v3.tar.gz" "./stl/${SIZE}_v3/"
done
done

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.