give some love
This commit is contained in:
parent
8fb1ee048d
commit
3f38d34694
5 changed files with 225276 additions and 1 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Max Halford
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software 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 Software.
|
||||||
|
|
||||||
|
THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
43
README.md
43
README.md
|
|
@ -1,6 +1,49 @@
|
||||||
|
# svg2stl
|
||||||
|
|
||||||
|
This repository provides a script which takes as input an SVG such as this one:
|
||||||
|
|
||||||
|
![example.svg]
|
||||||
|
|
||||||
|
It outputs an [STL file](https://www.wikiwand.com/en/STL_(file_format)) like this one:
|
||||||
|
|
||||||
|
![example.png]
|
||||||
|
|
||||||
|
The resulting solid is a cuboid with holes in it. It essentially adds a third dimension to the SVG file. The purpose of the output STL is to be fed into a 3D printer. The end goal is to make a physical [stencil](https://www.wikiwand.com/en/Stencil) for artistic purposes.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/MaxHalford/svg2stl
|
git clone https://github.com/MaxHalford/svg2stl
|
||||||
cd svg2stl
|
cd svg2stl
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
You can generate an STL with the same name as the input file like this:
|
||||||
|
|
||||||
|
```py
|
||||||
python svg2stl.py example.svg --thickness 4
|
python svg2stl.py example.svg --thickness 4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also show what this looks like in a GUI:
|
||||||
|
|
||||||
|
```py
|
||||||
|
python svg2stl.py example.svg --thickness 4 --show
|
||||||
|
```
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
- The SVG file is parsed into a sequence of steps thanks to [`svg.path`](https://github.com/regebro/svg.path).
|
||||||
|
- Each step is turned into 2D geometric coordinates by sampling from each step's parametric equation with [`numpy`](https://numpy.org/).
|
||||||
|
- Each coordinate is duplicated so that there are top and bottom coordinates.
|
||||||
|
- The coordinates are stitched together to define panes: a floor, a ceiling, and many walls.
|
||||||
|
- [`pygmsh`](https://github.com/nschloe/pygmsh) does the heavy lifting. It generates a mesh of triangles from the panes through [constrained Delaunay triangulation](https://www.wikiwand.com/en/Constrained_Delaunay_triangulation).
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
There are some websites out there that already do this. Like [this](https://svg2stl.com/), [this](https://activmap.github.io/svg-to-stl/), and [this](https://github.com/rcalme/svg-to-stl). But they're websites, and sometimes it's nice to be able to do this from the command line. Especially if you want to process many SVGs.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT). Please see the [license file](LICENSE) for more information.
|
||||||
|
|
|
||||||
BIN
example.png
Normal file
BIN
example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 236 KiB |
225206
example.stl
Normal file
225206
example.stl
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,5 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
import pathlib
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
|
|
||||||
import gmsh
|
import gmsh
|
||||||
|
|
@ -17,6 +18,7 @@ if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Convert an SVG into an STL.")
|
parser = argparse.ArgumentParser(description="Convert an SVG into an STL.")
|
||||||
parser.add_argument("svg_path", type=str, help="path towards an SVG file")
|
parser.add_argument("svg_path", type=str, help="path towards an SVG file")
|
||||||
parser.add_argument("--thickness", default=1, type=float)
|
parser.add_argument("--thickness", default=1, type=float)
|
||||||
|
parser.add_argument("--show", dest="show", action="store_true", default=False)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
steps = parse_svg_into_steps(args.svg_path)
|
steps = parse_svg_into_steps(args.svg_path)
|
||||||
|
|
@ -147,4 +149,7 @@ if __name__ == "__main__":
|
||||||
gmsh.model.geo.synchronize()
|
gmsh.model.geo.synchronize()
|
||||||
gmsh.model.mesh.generate()
|
gmsh.model.mesh.generate()
|
||||||
|
|
||||||
|
gmsh.write(str(pathlib.Path(args.svg_path).with_suffix(".stl")))
|
||||||
|
|
||||||
|
if args.show:
|
||||||
gmsh.fltk.run()
|
gmsh.fltk.run()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue