yapCAD 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. {yapCAD-0.2.0 → yapcad-0.3.0}/.gitignore +5 -0
  2. {yapCAD-0.2.0 → yapcad-0.3.0}/.readthedocs.yml +4 -0
  3. yapcad-0.3.0/CHANGELOG.rst +84 -0
  4. yapcad-0.3.0/PKG-INFO +480 -0
  5. {yapCAD-0.2.0 → yapcad-0.3.0}/README.md +19 -0
  6. {yapCAD-0.2.0 → yapcad-0.3.0}/README.rst +16 -0
  7. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/README.rst +16 -0
  8. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/conf.py +18 -3
  9. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/index.rst +1 -1
  10. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/boxcut/boxcut.py +11 -8
  11. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example1.py +12 -5
  12. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example10.py +18 -5
  13. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example11.py +18 -5
  14. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example12.py +22 -7
  15. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example8-gl.py +10 -2
  16. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example9.py +10 -2
  17. yapcad-0.3.0/pyproject.toml +36 -0
  18. {yapCAD-0.2.0 → yapcad-0.3.0}/requirements.txt +6 -2
  19. {yapCAD-0.2.0 → yapcad-0.3.0}/setup.cfg +8 -16
  20. yapcad-0.3.0/src/yapCAD.egg-info/PKG-INFO +480 -0
  21. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapCAD.egg-info/SOURCES.txt +1 -1
  22. yapcad-0.3.0/src/yapCAD.egg-info/requires.txt +12 -0
  23. yapcad-0.3.0/src/yapcad/__init__.py +11 -0
  24. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/combine.py +14 -8
  25. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/ezdxf_drawable.py +18 -2
  26. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/geom.py +12 -14
  27. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/geometry.py +2 -2
  28. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/xform.py +10 -4
  29. {yapCAD-0.2.0 → yapcad-0.3.0}/tests/test_xform.py +10 -0
  30. yapCAD-0.2.0/CHANGELOG.rst +0 -29
  31. yapCAD-0.2.0/PKG-INFO +0 -453
  32. yapCAD-0.2.0/src/yapCAD.egg-info/PKG-INFO +0 -453
  33. yapCAD-0.2.0/src/yapCAD.egg-info/requires.txt +0 -7
  34. yapCAD-0.2.0/src/yapcad/__init__.py +0 -11
  35. yapCAD-0.2.0/src/yapcad/acdxf.py +0 -120
  36. {yapCAD-0.2.0 → yapcad-0.3.0}/.coveragerc +0 -0
  37. {yapCAD-0.2.0 → yapcad-0.3.0}/AUTHORS.rst +0 -0
  38. {yapCAD-0.2.0 → yapcad-0.3.0}/LICENSE +0 -0
  39. {yapCAD-0.2.0 → yapcad-0.3.0}/LICENSE.txt +0 -0
  40. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/Makefile +0 -0
  41. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/_static/.gitignore +0 -0
  42. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/authors.rst +0 -0
  43. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/changelog.rst +0 -0
  44. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/images/laserbox.jpg +0 -0
  45. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/images/yapCadSplash.png +0 -0
  46. {yapCAD-0.2.0 → yapcad-0.3.0}/docs/license.rst +0 -0
  47. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/README.md +0 -0
  48. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/README.rst +0 -0
  49. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/boxout.dxf +0 -0
  50. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example1-out.dxf +0 -0
  51. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example10-out.dxf +0 -0
  52. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example3-out.dxf +0 -0
  53. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example4-out.dxf +0 -0
  54. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example5-out.dxf +0 -0
  55. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example6-out.dxf +0 -0
  56. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example7-out.dxf +0 -0
  57. {yapCAD-0.2.0 → yapcad-0.3.0}/dxf/example8-out.dxf +0 -0
  58. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/README.md +0 -0
  59. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/README.rst +0 -0
  60. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/boxcut/README.md +0 -0
  61. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/boxcut/README.rst +0 -0
  62. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example2.py +0 -0
  63. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example3.py +0 -0
  64. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example4.py +0 -0
  65. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example5.py +0 -0
  66. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example6.py +0 -0
  67. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example7.py +0 -0
  68. {yapCAD-0.2.0 → yapcad-0.3.0}/examples/example8.py +0 -0
  69. {yapCAD-0.2.0 → yapcad-0.3.0}/images/README.md +0 -0
  70. {yapCAD-0.2.0 → yapcad-0.3.0}/images/README.rst +0 -0
  71. {yapCAD-0.2.0 → yapcad-0.3.0}/images/example6-out.png +0 -0
  72. {yapCAD-0.2.0 → yapcad-0.3.0}/images/example8-out.png +0 -0
  73. {yapCAD-0.2.0 → yapcad-0.3.0}/images/yapCAD01.png +0 -0
  74. {yapCAD-0.2.0 → yapcad-0.3.0}/images/yapCAD02.png +0 -0
  75. {yapCAD-0.2.0 → yapcad-0.3.0}/images/yapCadSplash.png +0 -0
  76. {yapCAD-0.2.0 → yapcad-0.3.0}/setup.py +0 -0
  77. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapCAD.egg-info/dependency_links.txt +0 -0
  78. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapCAD.egg-info/not-zip-safe +0 -0
  79. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapCAD.egg-info/top_level.txt +0 -0
  80. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/drawable.py +0 -0
  81. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/geom3d.py +0 -0
  82. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/poly.py +0 -0
  83. {yapCAD-0.2.0 → yapcad-0.3.0}/src/yapcad/pyglet_drawable.py +0 -0
  84. {yapCAD-0.2.0 → yapcad-0.3.0}/tests/conftest.py +0 -0
  85. {yapCAD-0.2.0 → yapcad-0.3.0}/tests/test_geom.py +0 -0
@@ -48,6 +48,11 @@ MANIFEST
48
48
 
49
49
  # Per-project virtualenvs
50
50
  .venv*/
51
+ venv/
52
+ v_*/
53
+
54
+ #cached python version for pyenv
55
+ .python-version
51
56
 
52
57
  # generated DXF files in examples
53
58
  examples/*.dxf
@@ -12,3 +12,7 @@ sphinx:
12
12
  # Optionally build your docs in additional formats such as PDF
13
13
  formats:
14
14
  - pdf
15
+
16
+ submodules:
17
+ include: all
18
+ recursive: true
@@ -0,0 +1,84 @@
1
+ =========
2
+ Changelog
3
+ =========
4
+
5
+ Version 0.3.0
6
+ =============
7
+
8
+ what's new:
9
+ -----------
10
+
11
+ - Require Python 3.10+ and align dependency metadata with current
12
+ interpreter and library versions.
13
+ - Pin pyglet to 1.x rendering backend and add fallback
14
+ guards to every OpenGL-enabled example so they degrade gracefully on
15
+ systems without a working pyglet/Cocoa stack.
16
+ - Sphinx documentation now builds even when optional themes are
17
+ missing, and `sphinx-apidoc` no longer depends on ``pkg_resources``.
18
+
19
+ Known problems
20
+ --------------
21
+
22
+ - Incomplete documentation, especially outside the ``yapcad.geom`` module.
23
+ - Occasional problems with complex boolean operations.
24
+ - Incomplete functionality around 3D modeling.
25
+
26
+ Version 0.1.5
27
+ =============
28
+
29
+ what's new:
30
+ -----------
31
+
32
+ - Pre-release, heading towards V0.2.x
33
+
34
+ - Restructuring for package release
35
+
36
+ - Lots more documentation (still incomplete)
37
+
38
+ - Fixes to package configuration
39
+
40
+ Known problems
41
+ --------------
42
+
43
+ - Incomplete documentation, especially outside the ``yapcad.geom`` module.
44
+
45
+ - Occasional problems with complex boolean operations
46
+
47
+ - Incomplete functionality around 3D modeling
48
+
49
+ - Inconsistent inclusion of licensing boilerplate
50
+
51
+ Version 0.2.0
52
+ =============
53
+
54
+ what's new:
55
+ -----------
56
+
57
+ - First announced version of **yapCAD**. Yay!
58
+
59
+ - Added new ``boxcut`` example, showing a fully worked (if simple)
60
+ parametric design system.
61
+
62
+ - Additional documentation updates and minor bugfixes.
63
+
64
+ Known problems
65
+ --------------
66
+
67
+ - Our `yapCAD readthedocs`_ documentation is missing the expanded
68
+ documentation from submodules, which is a problem since much of
69
+ **yapCAD**'s documentation is in the form of docstrings in the
70
+ source. I'm working on getting this sorted out. In the mean time,
71
+ you may want to build a local copy of the documentation as described
72
+ in the main ``README`` file. Or, checkout and read the source.
73
+
74
+ - Incomplete documentation, especially outside the ``yapcad.geom`` module.
75
+
76
+ - Occasional problems with complex boolean operations. A bug in the
77
+ ``intersectXY`` method of the ``Boolean`` class.
78
+
79
+ - Incomplete functionality around 3D modeling
80
+
81
+ - Inconsistent inclusion of licensing boilerplate, other minor
82
+ formatting issues.
83
+
84
+ .. _yapCAD readthedocs: https://yapcad.readthedocs.io/en/latest/index.html
yapcad-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,480 @@
1
+ Metadata-Version: 2.4
2
+ Name: yapCAD
3
+ Version: 0.3.0
4
+ Summary: yet another procedural CAD and computational geometry system
5
+ Author-email: Richard DeVaul <richard.devaul@gmail.com>
6
+ Project-URL: Homepage, https://github.com/rdevaul/yapCAD/
7
+ Project-URL: Documentation, https://yapcad.readthedocs.io/en/latest/
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/x-rst
13
+ License-File: LICENSE
14
+ License-File: LICENSE.txt
15
+ License-File: AUTHORS.rst
16
+ Requires-Dist: ezdxf>=1.1
17
+ Requires-Dist: pyglet<2,>=1.5
18
+ Requires-Dist: mpmath>=1.2
19
+ Requires-Dist: pyobjc-core; platform_system == "Darwin"
20
+ Requires-Dist: pyobjc-framework-Cocoa; platform_system == "Darwin"
21
+ Requires-Dist: pyobjc-framework-Quartz; platform_system == "Darwin"
22
+ Provides-Extra: tests
23
+ Requires-Dist: pytest; extra == "tests"
24
+ Requires-Dist: pytest-cov; extra == "tests"
25
+ Dynamic: license-file
26
+
27
+ **yapCAD**
28
+ ==========
29
+
30
+ yet another procedural CAD and computational geometry system written in
31
+ python 3
32
+
33
+ .. figure:: images/yapCadSplash.png
34
+ :alt: **yapCAD** image
35
+
36
+ **yapCAD** image
37
+
38
+ what’s **yapCAD** for?
39
+ ----------------------
40
+
41
+ First and foremost, **yapCAD** is a framework for creating
42
+ `parametric <https://en.wikipedia.org/wiki/Parametric_design>`__,
43
+ procedural, and
44
+ `generative <https://en.wikipedia.org/wiki/Parametric_design>`__ design
45
+ systems. You can also use **yapCAD** for other CAD, CAM, and
46
+ computational geometry purposes.
47
+
48
+ software status
49
+ ---------------
50
+
51
+ **yapCAD** is still very much in **beta**, although it is already being
52
+ used by for professional engineering purposes. If you are using
53
+ **yapCAD** in interesting ways, feel free to let us know in the `yapCAD
54
+ discussions <https://github.com/rdevaul/yapCAD/discussions>`__ forum
55
+
56
+ **yapCAD** installation, documentation, and examples
57
+ ----------------------------------------------------
58
+
59
+ installation
60
+ ~~~~~~~~~~~~
61
+
62
+ **yapCAD** is a pure python library, so no special steps are required
63
+ for installation. You can install it a variety of ways, but the
64
+ recommended method is to use pip to install it into your local
65
+ ``site-packages`` directory, as follows:
66
+
67
+ ::
68
+
69
+ pip install yapCAD --user
70
+
71
+ You can also clone the github repository and install from source:
72
+
73
+ ::
74
+
75
+ git clone https://github.com/rdevaul/yapCAD.git
76
+ cd yapCAD
77
+ python setup.py install --user
78
+
79
+ examples
80
+ ~~~~~~~~
81
+
82
+ The **yapCAD** github repository includes examples. To run the examples,
83
+ clone the github repository as shown above, and make sure that your
84
+ PYTHONPATH includes the cloned top-level ``yapCAD`` directory. You will
85
+ find the examples in the ``yapCAD/examples`` directory.
86
+
87
+ For a fully worked parametric design system, see the ``boxcut`` example.
88
+
89
+ documentation
90
+ ~~~~~~~~~~~~~
91
+
92
+ Online **yapCAD** documentation can be found here:
93
+ https://yapcad.readthedocs.io/en/latest/ — for some reason
94
+ ``readthedocs.io`` isn’t generating the full module documentation, so
95
+ you might want to build a local copy, as described below.
96
+
97
+ To build the HTML **yapCAD** documentation locally, first make sure you
98
+ have the sphinx package installed:
99
+
100
+ ::
101
+
102
+ pip install sphinx --user
103
+
104
+ Then clone the github repository as shown above, ``cd`` to the
105
+ ``yapCAD`` directory, and type
106
+
107
+ ::
108
+
109
+ make -C docs html
110
+
111
+ This will build the HTML documents in the ``build/sphinx/html``
112
+ directory. You can also build documentation in the other formats
113
+ supported by Sphinx. See the `Sphinx
114
+ documentation <https://www.sphinx-doc.org/en/master/>`__ for more
115
+ information.
116
+
117
+ running tests
118
+ ~~~~~~~~~~~~~
119
+
120
+ The repository includes a small pytest suite that exercises the core
121
+ geometry primitives. Install the testing dependencies and run pytest
122
+ from the project root with the source tree on ``PYTHONPATH``::
123
+
124
+ python3 -m pip install pytest pytest-cov
125
+ PYTHONPATH=./src python3 -m pytest
126
+
127
+ The default configuration enables coverage reporting via
128
+ ``pytest-cov``. If you prefer to skip coverage, you can override the
129
+ options::
130
+
131
+ PYTHONPATH=./src python3 -m pytest --override-ini addopts=
132
+
133
+ **yapCAD** goals
134
+ ----------------
135
+
136
+ The purpose of **yapCAD** is to support 2D and 3D computational geometry
137
+ and parametric, procedural, and generative design projects in python3.
138
+ **yapCAD** is designed to support multiple rendering back-ends, such
139
+ that a relatively small amount of code is necessary to add support for a
140
+ 2D or 3D cad or drawing file format. At present, **yapCAD** supports the
141
+ AutoCad DXF file format for creating two-dimensional drawings and OpenGL
142
+ for creating interactive 2D and 3D renderings.
143
+
144
+ The foundations of **yapCAD** are grounded in decades of the author’s
145
+ experience with graphics system programming, 3D CAD and simulation.
146
+ **yapCAD** has an underlying framework and architecture designed to
147
+ support sophisticated computational geometry and procedural CAD
148
+ applications. At the same time, the design of **yapCAD** should make
149
+ easy stuff relatively easy, and the more advanced stuff possible.
150
+
151
+ The initial implementation of **yapCAD** provides DXF file creation
152
+ support through the awesome `ezdxf <https://github.com/mozman/ezdxf>`__
153
+ package, and interactive OpenGL visualization using the amazing
154
+ `pyglet <https://github.com/pyglet/pyglet>`__ package.
155
+
156
+ **yapCAD** examples
157
+ -------------------
158
+
159
+ (for a more complete list, see the `examples folder <./examples/>`__)
160
+
161
+ It’s pretty easy to make a DXF drawing with **yapCAD**. Here is an
162
+ example:
163
+
164
+ ::
165
+
166
+ from yapcad.ezdxf_drawable import *
167
+ from yapcad.geom import *
168
+
169
+ #set up DXF rendering
170
+ dd=ezdxfDraw()
171
+ dd.filename = "example1-out"
172
+
173
+ ## make dxf-renderable geometry
174
+
175
+ # make a point located at 10,10 in the x-y plane, rendered as a small
176
+ # red cross and circle
177
+ dd.pointstyle = 'xo' # also valid are 'x' or 'o'
178
+ dd.linecolor = 1 # set color to red (DXF index color 1)
179
+ dd.draw(point(10,10))
180
+
181
+ # make a line segment between the points -5,10 and 10,-5 in the x-y plane
182
+ # and draw it in white
183
+
184
+ dd.linecolor='white' # set color by name
185
+ dd.draw(line(point(-5,10),
186
+ point(10,-5)))
187
+
188
+ # make an arc with a center at 0,3 with a radius of 3, from 45 degrees
189
+ # to 135 degrees, and draw it in aqua
190
+
191
+ dd.linecolor=[0,255,255] # RGB tripple, corresponds to 'aqua'
192
+ dd.draw(arc(point(0,3),3,45,135))
193
+
194
+ # write out the geometry as example1-out.dxf
195
+ dd.display()
196
+
197
+ The **yapCAD** system isn’t just about rendering, of course, it’s about
198
+ computational geometry. For example, if you want to calculate the
199
+ intersection of lines and arcs in a plane, we have you covered:
200
+
201
+ ::
202
+
203
+ from yapcad.geom import *
204
+
205
+ # define some points
206
+ a = point(5,0)
207
+ b = point(0,5)
208
+ c = point(-3,0)
209
+ d = point(10,10)
210
+
211
+ # make a couple of lines
212
+ l1 = line(a,b)
213
+ l2 = line(c,d)
214
+
215
+ # define a semicircular arc centered at 2.5, 2,5 with a radius of 2.5
216
+ # extending from 90 degrees to 135 degrees
217
+
218
+ arc1=arc(point(2.5,2.5),2.5,90.0,270.0)
219
+
220
+ # calculate the intersection of lines l1 and l2
221
+ int0 = intersectXY(l1,l2)
222
+
223
+ # calculate the intersection of the line l1 and the arc arc1
224
+ int1 = intersectXY(l1,arc1)
225
+
226
+ print("intersection of l1 and l2:",vstr(int0))
227
+ print("intersection of l1 and arc1:",vstr(int1))
228
+
229
+ And of course **yapCAD** supports calculating intersections between any
230
+ simple and compound, or compound and compound geometry object.
231
+
232
+ There are lots more `examples <examples/README.rst>`__ available to
233
+ demonstrate the various computational geometry and rendering
234
+ capabilities of **yapCAD**, including 3D geometry and OpenGL rendering.
235
+
236
+ **yapCAD** geometry
237
+ -------------------
238
+
239
+ **yapCAD** distinguishes between “pure” geometric elements, such as
240
+ lines, arcs, **etc.**, and drawn representations of those things, which
241
+ might have attributes like line color, line weight, drawing layer,
242
+ **etc.** This distinction is important, because the pure geometry exists
243
+ independent of these attributes, which are themselves rendering-system
244
+ dependent.
245
+
246
+ More importantly, for every geometric element you decide to draw, there
247
+ will typically be many more — perhaps dozens — that should not be in the
248
+ final rendering. By separating these two elements — computation and
249
+ rendering — **yapCAD** makes them both more intentional and reduces the
250
+ likelihood of certain type of drawing-quality issues, such as redundant
251
+ or spurious drawing elements, that can cause confusion problems for
252
+ computer-aided manufacturing (CAM).
253
+
254
+ For example, you might construct a finished drawing that includes a
255
+ drill pattern that consists of circles (drill holes with centers) that
256
+ follow a complex, geometrically constrained pattern. This pattern is
257
+ itself the result of numerous computational geometry operations, perhaps
258
+ driven by parameters relating to the size and shape of other parts.
259
+
260
+ In a program like Autodesk’s Fusion360, you would typically use
261
+ construction lines and constraints to create the underlying geometric
262
+ pattern. These additional construction elements would have to be removed
263
+ in order to make a clean DXF export of your drawing. On more than one
264
+ occasion **yapCAD**\ ’s author has created headaches by failing to
265
+ remove some of these elements, confusing CAM technicians, causing
266
+ delays, and sometimes resulting in expensive part fabrication errors.
267
+
268
+ Thus, **yapCAD** allows you to work freely with computational geometry
269
+ without cluttering up your drawing page, since you specifically decide
270
+ what to draw. It also means you can do computational geometry in
271
+ **yapCAD** without ever invoking a rendering system, which can be useful
272
+ when incorporating these geometry operations as part of a larger
273
+ computational system, such as a tool-path generator.
274
+
275
+ As a rule, in **yapCAD** pure geometry representations capture only the
276
+ minimum necessary to perform computational geometry, and the rest gets
277
+ dealt with by the rendering system, which are subclasses of ``Drawable``
278
+ that actually make images, CAD drawings, **etc.**
279
+
280
+ vector representation in **yapCAD**
281
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282
+
283
+ For the sake of uniformity, all **yapCAD** vectors are stored as
284
+ projective geometry 4-vectors. (see discussion in **architecture**,
285
+ below) However, most of the time you will work with them as though they
286
+ are 3-vectors or 2-vectors.
287
+
288
+ It would be annoying to have to specify the redundant coordinates you
289
+ aren’t using every time you specify a vector, so **yapCAD** provides you
290
+ with the ``vect`` function. It fills in defaults for the z and w
291
+ parameters you may not want to specify. **e.g.**
292
+
293
+ ::
294
+
295
+ >>> from yapcad.geom import *
296
+ >>> vect(10,4)
297
+ [10, 4, 0, 1]
298
+ >>> add(vect(10,4),vect(10,9)) ## add operates in 3-space
299
+ [20, 13, 0, 1.0]
300
+
301
+ Of course, you can specify all three (or even four) coordinates using
302
+ ``vect``.
303
+
304
+ Since it gets ugly to look at a bunch of [x, y, z, w] lists that all end
305
+ in ``0, 1]`` when you are doing 2D stuff, **yapCAD** provides a
306
+ convenience function ``vstr`` that intelligently converts **yapCAD**
307
+ vectors (and lists that contain vectors, such as lines, triangles, and
308
+ polygons) to strings, assuming that as long as z = 0 and w = 1, you
309
+ don’t need to see those coordinates.
310
+
311
+ ::
312
+
313
+ >>> from yapcad.geom import *
314
+ >>> a = sub(vect(10,4),vect(10,9)) ## subtract a couple of vectors
315
+ >>> a
316
+ [0, -5, 0, 1.0]
317
+ >>> print(vstr(a)) ## pretty printing, elide the z and w coordinates
318
+ >>> [0, -5]
319
+
320
+ pure geometry
321
+ ~~~~~~~~~~~~~
322
+
323
+ Pure geometric elements in **yapCAD** form the basis for computational
324
+ geometry operations, including intersection and inside-outside testing.
325
+ Pure geometry can also be drawn, of course — see **drawable geometry**
326
+ below.
327
+
328
+ In general, **yapCAD** pure geometry supports the operations of
329
+ parametric sampling, intersection calculation, inside-outside testing
330
+ (for closed figures), “unsampling” (going from a point on the figure to
331
+ the sampling parameter that would produce it), and bounding box
332
+ calculation. **yapCAD** geometry is based on projective or homogeneous
333
+ coordinates, thus supporting generalized affine transformations; See the
334
+ discussion in **architecture**, below.
335
+
336
+ simple (non-compound) pure geometric elements
337
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
338
+
339
+ Simple, which is to say non-compound, geometry includes vectors, points,
340
+ and lines. A vector is a list of exactly four numbers, each of which is
341
+ a float or integer. A point is a vector that lies in a w > 0 hyperplane;
342
+ Points are used to represent transformable coordinates in **yapCAD**
343
+ geometry. A line is a list of two points.
344
+
345
+ Simple geometry also includes arcs. An arc is a list of a point and a
346
+ vector, followed optionally by another point. The first list element is
347
+ the center of the arc, the second is a vector in the w=-1 hyperplane
348
+ (for right-handed arcs) whose first three elements are the scalar
349
+ parameters ``[r, s, e]``: the radius, the start angle in degrees, and
350
+ the end angle in degrees. The third element (if it exists) is the normal
351
+ for the plane of the arc, which is assumed to be ``[0, 0, 1]`` (the x-y
352
+ plane) if it is not specified. Arcs are by default right-handed, but
353
+ left-handed arcs are also supported, with parameter vectors lying in the
354
+ w=-2 hyperplane.
355
+
356
+ compound figures
357
+ ^^^^^^^^^^^^^^^^
358
+
359
+ A list of more than two points represents a multi-vertex polylines. If
360
+ there are at least four points in the list and the last point is the
361
+ same as the first, the polyline figure is closed. (We sometimes refer to
362
+ these point-list polygons or polylines as ``poly()`` entities.) Closed
363
+ coplanar polylines are drawn as polygons and may be subject to
364
+ inside-outside testing. Like other elements of pure geometry, polylines
365
+ are subject to sampling, unsampling, intersection calculation, **etc.**
366
+
367
+ If instead of sharp corners you want closed or open figures with rounded
368
+ corners, you should use ``Polyline`` or ``Polygon`` instances. Instances
369
+ of these classes are used for representing compound geometric elements
370
+ in an XY plane with C0 continuity. They differ from the point-list-based
371
+ ``poly()`` representation in that the elements of a ``Polyline`` or
372
+ ``Polygon`` can include lines and arcs as well as points. These elements
373
+ need not be contiguous, as successive elements will be automatically
374
+ joined by straight lines. ``Polygons`` are special in that they are
375
+ always closed, and that any full circle elements are interpreted as
376
+ “rounded corners,” with the actual span of the arc calculated after
377
+ tangent lines are drawn.
378
+
379
+ The ``Polygon`` class supports boolean operations, as described below,
380
+ and also supports the ``grow()`` operation that makes generating a
381
+ derived figure that is bigger by a fixed amount easy. This grow feature
382
+ is very useful for many engineering operations, such as creating an
383
+ offset path for drill holes, CAM paths, etc.
384
+
385
+ boolean operations on ``Polygon`` instances
386
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
387
+
388
+ **yapCAD** supports boolean set operations on ``Polygon`` instances,
389
+ allowing you to construct more complex two-dimensional figures from
390
+ union, intersection, and difference operations. Note that the difference
391
+ operation can result in the creation of disjoint geometry in the form of
392
+ two or more closed figures with positive area (see below), or closed
393
+ figures with holes.
394
+
395
+ See `Example 11 <./examples/example11.py>`__ for a relatively simple
396
+ example of boolean operations, and `Example
397
+ 12 <./examples/example12.py>`__ for a more complex example.
398
+
399
+ **yapCAD** employs the convention that closed figures with right-handed
400
+ geometry (increasing the sampling parameter corresponds to points that
401
+ trace a counter-clockwise path) represent “positive” area, and that
402
+ closed figures with left-handed geometry represent holes. This
403
+ distinction is currently not operational, but will be important for
404
+ future development such as turning polygons into rendered surfaces and
405
+ extruding these surfaces into 3D.
406
+
407
+ disjoint compound geometry
408
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
409
+
410
+ Boolean difference operations can result in disjoint figures. It is also
411
+ possible to combine **yapCAD** geometric elements in geometry lists,
412
+ which is to say a list of zero or more elements of **yapCAD** pure
413
+ geometry, which enforce no continuity constraints. Geometry lists
414
+ provide the basis for **yapCAD** rendering.
415
+
416
+ drawable geometry
417
+ ~~~~~~~~~~~~~~~~~
418
+
419
+ The idea is that you will do your computational geometry with “pure”
420
+ geometry, and then generate rendered previews or output with one or more
421
+ ``Drawable`` instances.
422
+
423
+ In **yapCAD**, geometry is rendered with instances of subclasses of
424
+ ``Drawable``, which at present include ``ezdxfDrawable``, a class for
425
+ producing DXF renderings using the awesome ``ezdxf`` package, and
426
+ ``pygletDrawable``, a class for interactive 2D and 3D OpenGL rendering.
427
+
428
+ To setup a drawing environment, you create an instance of the
429
+ ``Drawable`` base class corresponding to the rendering system you want
430
+ to use.
431
+
432
+ To draw, create the pure geometry and then pass that to the drawbles’s
433
+ ``draw()`` method. To display or write out the results you will invoke
434
+ the ``display`` method of the drawable instance.
435
+
436
+ supported rendering systems
437
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
438
+
439
+ DXF rendering using ``ezdxf`` and interactive OpenGL rendering using
440
+ ``pyglet`` are currently supported, and the design of **yapCAD** makes
441
+ it easy to support other rendering backends.
442
+
443
+ **yapCAD** architecture
444
+ -----------------------
445
+
446
+ Under the hood, **yapCAD** is using `projective
447
+ coordinates <https://en.wikipedia.org/wiki/Homogeneous_coordinates>`__,
448
+ sometimes called homogeneous coordinates, to represent points as 3D
449
+ coordinates in the w=1 hyperplane. If that sounds complicated, its
450
+ because it is. :P But it does allow for a wide range of geometry
451
+ operations, specifically `affine
452
+ transforms <https://www.cs.utexas.edu/users/fussell/courses/cs384g-fall2011/lectures/lecture07-Affine.pdf>`__
453
+ to be represented as composable transformation matrices. The benefits of
454
+ this conceptual complexity is an architectural elegance and generality.
455
+
456
+ Support for affine transforms is at present rudimentary, but once a
457
+ proper matrix transform stack is implemented it will allow for the
458
+ seamless implementation and relatively easy use of a wide range of
459
+ transformation and projection operations.
460
+
461
+ What does that buy you? It means that under the hood, **yapCAD** uses
462
+ the same type of geometry engine that advanced CAD and GPU-based
463
+ rendering systems use, and should allow for a wide range of
464
+ computational geometry systems, possibly hardware-accelerated, to be
465
+ built on top of it.
466
+
467
+ The good news is that you don’t need to know about homogeneous
468
+ coordinates, affine transforms, etc., to use **yapCAD**. And most of the
469
+ time you can pretend that your vectors are just two-dimensional if
470
+ everything you are doing happens to lie in the x-y plane.
471
+
472
+ So, if you want to do simple 2D drawings, we have you covered. If you
473
+ want to build a GPU-accelerated constructive solid geometry system, you
474
+ can do that, too.
475
+
476
+ Note
477
+ ----
478
+
479
+ This project has been set up using PyScaffold 3.2.3. For details and
480
+ usage information on PyScaffold see https://pyscaffold.org/.
@@ -68,6 +68,25 @@ supported by Sphinx. See the [Sphinx
68
68
  documentation](https://www.sphinx-doc.org/en/master/) for more
69
69
  information.
70
70
 
71
+ ### running tests
72
+
73
+ The repository includes a small pytest suite that exercises the core
74
+ geometry primitives. Install the testing dependencies and run pytest
75
+ from the project root with the source tree on `PYTHONPATH`:
76
+
77
+ ```bash
78
+ python3 -m pip install pytest pytest-cov
79
+ PYTHONPATH=./src python3 -m pytest
80
+ ```
81
+
82
+ The default configuration enables coverage reporting via
83
+ `pytest-cov`. If you prefer to skip coverage, you can override the
84
+ options:
85
+
86
+ ```bash
87
+ PYTHONPATH=./src python3 -m pytest --override-ini addopts=
88
+ ```
89
+
71
90
  ## **yapCAD** goals
72
91
 
73
92
  The purpose of **yapCAD** is to support 2D and 3D computational
@@ -88,6 +88,22 @@ supported by Sphinx. See the `Sphinx
88
88
  documentation <https://www.sphinx-doc.org/en/master/>`__ for more
89
89
  information.
90
90
 
91
+ running tests
92
+ ~~~~~~~~~~~~~
93
+
94
+ The repository includes a small pytest suite that exercises the core
95
+ geometry primitives. Install the testing dependencies and run pytest
96
+ from the project root with the source tree on ``PYTHONPATH``::
97
+
98
+ python3 -m pip install pytest pytest-cov
99
+ PYTHONPATH=./src python3 -m pytest
100
+
101
+ The default configuration enables coverage reporting via
102
+ ``pytest-cov``. If you prefer to skip coverage, you can override the
103
+ options::
104
+
105
+ PYTHONPATH=./src python3 -m pytest --override-ini addopts=
106
+
91
107
  **yapCAD** goals
92
108
  ----------------
93
109
 
@@ -88,6 +88,22 @@ supported by Sphinx. See the `Sphinx
88
88
  documentation <https://www.sphinx-doc.org/en/master/>`__ for more
89
89
  information.
90
90
 
91
+ running tests
92
+ ~~~~~~~~~~~~~
93
+
94
+ The repository includes a small pytest suite that exercises the core
95
+ geometry primitives. Install the testing dependencies and run pytest
96
+ from the project root with the source tree on ``PYTHONPATH``::
97
+
98
+ python3 -m pip install pytest pytest-cov
99
+ PYTHONPATH=./src python3 -m pytest
100
+
101
+ The default configuration enables coverage reporting via
102
+ ``pytest-cov``. If you prefer to skip coverage, you can override the
103
+ options::
104
+
105
+ PYTHONPATH=./src python3 -m pytest --override-ini addopts=
106
+
91
107
  **yapCAD** goals
92
108
  ----------------
93
109