I set up the first 3D printing service bureau on campus (in Edmonton??) circa 2002
I continue to be a 3D printing hobbyist, working on a variety of projects
What does my typical 3D printing workflow look like?
I've been a Python programmer since 1999
My team recently started to teach Python workshops, with a focus on Jupyter notebooks
Getting started with Python?
I wanted to use Blender to make a Klein bottle tiled with hexagons (a la Bathsheba Grossman)
Why not use ... math? (and Python)
Easy, to do if you don't want hexagons.
Can't find a tool that does this, so I'll have to write my own software to make them.
Produce a 3D, topologically correct (air-tight) mesh, tiled with hexagons
The code has two classes 'Tile' and 'Tessagon' (generates the tiles)
It works, and I've created something useful -- now what do I do with it?
Initial commit is one python file that has both classes, and a demo blender file.
Or am I ... ?
If I can do this for hexagons, surely I can do this for a triangle tiling?
Parent classes: Tile, Tessagon
Subclasses:
HexTile, HexTessagon | TriTile, TriTessagon |
|
|
25-ish subclasses added ...
|
|
|
|
|
|
|
|
A script that runs in Blender generates screenshots/thumbs/markdown
|
|
This is all just math, so why tie it to Blender?
Shimmed a generic output 'Adaptor' to support Blender, VTK, and Python lists/dict data structures.
def add_vert(self, index_keys, ratio_u, ratio_v, **kwargs):
# Use the mesh adaptor to create a vertex.
# In reality, multiple vertices may get defined if symmetry is declared
vert = self._get_vert(index_keys)
if not vert:
coords = self.f(*self.blend(ratio_u, ratio_v))
vert = self.mesh_adaptor.create_vert(coords)
...
I created a layer so that different tiling types can be easily found.
The immediate goal was to create a nicely-ordered, self-generating menu of tilings in Blender.
find_all = TessagonDiscovery()
find_all.to_list() # a list of all of the tessagons
regular = find_all.with_classification('regular')
regular.to_list() # The three regular tilings (HexTessagon, SquareTessagon, TriTessagon)
regular.inverse().to_list() # All tilings except for the regular ones
I also started making stuff
I wanted this project to be set up to have street cred, and I wanted to ensure that it was successful in the long term
Pull requests of feature branches merged into `development` branch as squashed rebases
`master` branch for releases only, merging in `development` when the time feels right
https://www.python.org/dev/peps/pep-0008/
It's bad enough having to read other people's code, let alone having to read code that looks like it was written by three different guys
pip3 install flake8
Stackoverflow: "Linting is the process of running a program that will analyse code for potential errors."
Flake8 looks for violations of PEP8
Before ...
$ flake8 pythagorean_tessagon.py
pythagorean_tessagon.py:22:1: E302 expected 2 blank lines, found 1
pythagorean_tessagon.py:23:3: E111 indentation is not a multiple of four
pythagorean_tessagon.py:25:13: E201 whitespace after '{'
...
... after
$ flake8 pythagorean_tessagon.py
(no output == flake8 isn't angry)
Can turn off specific tests inline
import os
import sys
this_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(this_dir + '/../..')
from tessagon.core.tile import Tile # noqa: E402
E402 corresponds to: module level import not at top of file
A foolish consistency is the hobgoblin of little minds ...Ralph Waldo Emerson
Ensures the software operates correctly
When done right, become your "license to make changes"
pytest
pip3 install pytest
# Measures test coverage
pip3 install pytest-cov
Only 25 tests (yikes)
class TestAbstractTile(CoreTestsBase):
def test_u_range_v_range_params(self):
tessagon = FakeTessagon()
tile = AbstractTile(tessagon, u_range=[0.5, 1.0],
v_range=[2.5, 4.0])
assert (tile.corners == [[0.5, 2.5],
[1, 2.5],
[0.5, 4.0],
[1.0, 4.0]])
Coverage
$ pytest --cov=tessagon tests/
[SNIP]
Name Stmts Miss Cover
---------------------------------------------------------
tessagon/__init__.py 0 0 100%
tessagon/adaptors/__init__.py 0 0 100%
tessagon/adaptors/blender_adaptor.py 18 18 0%
tessagon/adaptors/list_adaptor.py 23 0 100%
[SNIP]
tessagon/types/zig_zag_tessagon.py 58 46 21%
---------------------------------------------------------
TOTAL 2010 1276 37%
(... more yikes)
Ensure that code coming into the project is able to merge and passes project standards
For tessagon, we run the test suite and the linting
.travis.yml
os: linux
sudo: false
language: python
matrix:
include:
- python: 3.6
- python: 3.5
install:
- pip install flake8
script:
- pytest
- flake8 --verbose
Pull request
Builds
. .
├── adaptors ├── demo
├── core ├── documentation
├── demo │ └── images
├── documentation ==> ├── tessagon
│ └── images │ ├── adaptors
├── misc │ ├── core
└── tests │ ├── misc
└── core │ └── types
└── tests
└── core
setup.py
from setuptools import setup, find_packages
# See next slide for long_description
setup(
name='tessagon',
version='0.4.2',
description='Tessellate your favorite 2D manifolds with triangles, ' +
'hexagons, and other interesting patterns.',
long_description=long_description,
url='https://github.com/cwant/tessagon',
author='Chris Want',
classifiers=['Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Intended Audience :: Manufacturing',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: Apache Software License',
'Natural Language :: English',
'Programming Language :: Python :: 3 :: Only',
'Topic :: Artistic Software',
'Topic :: Multimedia :: Graphics :: 3D Modeling',
'Topic :: Scientific/Engineering :: Mathematics',
'Topic :: Scientific/Engineering :: Visualization'],
keywords='tesselation tiling modeling blender vtk',
packages=find_packages(exclude=['tests', 'demo', 'wire_skin.py']),
python_requires='~=3.5'
)
Note: documentation is in ReStructedText (RST), not Markdown
long_description = '''
===========================================
tessagon: tessellation / tiling with python
===========================================
Tessellate your favorite 3D surfaces (technically, 2D manifolds) with
triangles, hexagons, or a number of other curated tiling types!
Please visit the Github repository for documentation:
``_
Either checkout the code from the Github project, or install via pip::
python3 -m pip install tessagon
or::
pip3 install tessagon
'''[1:-1]
Source distribution
python setup.py sdist
Universal wheel (build package):
python setup.py bdist_wheel --universal
$ ls dist/
tessagon-0.4.2-py3-none-any.whl tessagon-0.4.2.tar.gz
We want to host the package on the "Python Package Index" repository
Get an account on both regular and test site
Twine uploads the project to PYPI
pip3 install twine
~/.pypirc
[distutils]
index-servers=
pypi
testpypi
[pypi]
username = cwant
[testpypi]
repository = https://test.pypi.org/legacy/
username = cwant
Upload to test pypi ...
twine upload --repository testpypi dist/*
(Password required)
... or to real pypi
twine upload dist/*
(Password required)
https://pypi.org/project/tessagon
pip3 install tessagon
Stars from:
Number one hit searching for "tessagon" on Google (beating out somebody named Tessa Gon).
Four of the page one hits are about this project, most of the top image hits are about this project
Terms like "python tiling", "python tessellation" fair pretty poorly
Number three hit for "python 3d tiling"
Only one developer still, so not really dominating on that front
By carefully paying attention only to the statistics I like (and ignoring the ones I don't) I can totally say I achieved world domination
Questions?