yapCAD 0.2.5__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.
- {yapCAD-0.2.5 → yapcad-0.3.0}/.gitignore +5 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/CHANGELOG.rst +21 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/PKG-INFO +29 -5
- {yapCAD-0.2.5 → yapcad-0.3.0}/README.md +19 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/README.rst +16 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/README.rst +16 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/conf.py +17 -5
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/index.rst +1 -1
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/boxcut/boxcut.py +11 -8
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example1.py +12 -5
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example10.py +18 -5
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example11.py +18 -5
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example12.py +22 -7
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example8-gl.py +10 -2
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example9.py +10 -2
- {yapCAD-0.2.5 → yapcad-0.3.0}/pyproject.toml +9 -6
- {yapCAD-0.2.5 → yapcad-0.3.0}/requirements.txt +6 -3
- {yapCAD-0.2.5 → yapcad-0.3.0}/setup.cfg +8 -1
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapCAD.egg-info/PKG-INFO +29 -5
- yapcad-0.3.0/src/yapCAD.egg-info/requires.txt +12 -0
- yapcad-0.3.0/src/yapcad/__init__.py +11 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/combine.py +14 -8
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/geom.py +12 -14
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/geometry.py +2 -2
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/xform.py +10 -4
- {yapCAD-0.2.5 → yapcad-0.3.0}/tests/test_xform.py +10 -0
- yapCAD-0.2.5/src/yapCAD.egg-info/requires.txt +0 -11
- yapCAD-0.2.5/src/yapcad/__init__.py +0 -11
- {yapCAD-0.2.5 → yapcad-0.3.0}/.coveragerc +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/.readthedocs.yml +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/AUTHORS.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/LICENSE +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/LICENSE.txt +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/Makefile +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/_static/.gitignore +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/authors.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/changelog.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/images/laserbox.jpg +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/images/yapCadSplash.png +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/docs/license.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/README.md +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/README.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/boxout.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example1-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example10-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example3-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example4-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example5-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example6-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example7-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/dxf/example8-out.dxf +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/README.md +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/README.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/boxcut/README.md +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/boxcut/README.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example2.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example3.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example4.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example5.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example6.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example7.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/examples/example8.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/images/README.md +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/images/README.rst +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/images/example6-out.png +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/images/example8-out.png +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/images/yapCAD01.png +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/images/yapCAD02.png +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/images/yapCadSplash.png +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/setup.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapCAD.egg-info/SOURCES.txt +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapCAD.egg-info/dependency_links.txt +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapCAD.egg-info/not-zip-safe +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapCAD.egg-info/top_level.txt +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/drawable.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/ezdxf_drawable.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/geom3d.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/poly.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/src/yapcad/pyglet_drawable.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/tests/conftest.py +0 -0
- {yapCAD-0.2.5 → yapcad-0.3.0}/tests/test_geom.py +0 -0
@@ -2,6 +2,27 @@
|
|
2
2
|
Changelog
|
3
3
|
=========
|
4
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
|
+
|
5
26
|
Version 0.1.5
|
6
27
|
=============
|
7
28
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: yapCAD
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.3.0
|
4
4
|
Summary: yet another procedural CAD and computational geometry system
|
5
5
|
Author-email: Richard DeVaul <richard.devaul@gmail.com>
|
6
6
|
Project-URL: Homepage, https://github.com/rdevaul/yapCAD/
|
@@ -8,13 +8,21 @@ Project-URL: Documentation, https://yapcad.readthedocs.io/en/latest/
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
|
-
Requires-Python: >=3.
|
11
|
+
Requires-Python: >=3.10
|
12
12
|
Description-Content-Type: text/x-rst
|
13
|
-
Provides-Extra: testing
|
14
|
-
Provides-Extra: tests
|
15
13
|
License-File: LICENSE
|
16
14
|
License-File: LICENSE.txt
|
17
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
|
18
26
|
|
19
27
|
**yapCAD**
|
20
28
|
==========
|
@@ -106,6 +114,22 @@ supported by Sphinx. See the `Sphinx
|
|
106
114
|
documentation <https://www.sphinx-doc.org/en/master/>`__ for more
|
107
115
|
information.
|
108
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
|
+
|
109
133
|
**yapCAD** goals
|
110
134
|
----------------
|
111
135
|
|
@@ -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
|
|
@@ -13,7 +13,12 @@ import sys
|
|
13
13
|
import inspect
|
14
14
|
import shutil
|
15
15
|
|
16
|
-
|
16
|
+
try:
|
17
|
+
import sphinx_rtd_theme # optional theme used on RTD
|
18
|
+
_has_rtd_theme = True
|
19
|
+
except ImportError:
|
20
|
+
sphinx_rtd_theme = None
|
21
|
+
_has_rtd_theme = False
|
17
22
|
|
18
23
|
__location__ = os.path.join(os.getcwd(), os.path.dirname(
|
19
24
|
inspect.getfile(inspect.currentframe())))
|
@@ -45,13 +50,17 @@ except FileNotFoundError:
|
|
45
50
|
|
46
51
|
try:
|
47
52
|
import sphinx
|
48
|
-
from pkg_resources import parse_version
|
49
53
|
|
50
54
|
cmd_line_template = "sphinx-apidoc -f -o {outputdir} {moduledir}"
|
51
55
|
cmd_line = cmd_line_template.format(outputdir=output_dir, moduledir=module_dir)
|
52
56
|
|
53
57
|
args = cmd_line.split(" ")
|
54
|
-
|
58
|
+
# sphinx-apidoc switched to a subcommand style interface in 1.7
|
59
|
+
try:
|
60
|
+
major, minor, *_ = (int(x) for x in sphinx.__version__.split('.')[:2])
|
61
|
+
except ValueError:
|
62
|
+
major, minor = 1, 7
|
63
|
+
if (major, minor) >= (1, 7):
|
55
64
|
args = args[1:]
|
56
65
|
|
57
66
|
apidoc.main(args)
|
@@ -68,7 +77,10 @@ except Exception as e:
|
|
68
77
|
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo',
|
69
78
|
'sphinx.ext.autosummary', 'sphinx.ext.viewcode', 'sphinx.ext.coverage',
|
70
79
|
'sphinx.ext.doctest', 'sphinx.ext.ifconfig', 'sphinx.ext.mathjax',
|
71
|
-
'sphinx.ext.napoleon'
|
80
|
+
'sphinx.ext.napoleon']
|
81
|
+
|
82
|
+
if _has_rtd_theme:
|
83
|
+
extensions.append('sphinx_rtd_theme')
|
72
84
|
|
73
85
|
# Add any paths that contain templates here, relative to this directory.
|
74
86
|
templates_path = ['_templates']
|
@@ -138,7 +150,7 @@ pygments_style = 'sphinx'
|
|
138
150
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
139
151
|
# a list of builtin themes.
|
140
152
|
#html_theme = 'alabaster'
|
141
|
-
html_theme = 'sphinx_rtd_theme'
|
153
|
+
html_theme = 'sphinx_rtd_theme' if _has_rtd_theme else 'alabaster'
|
142
154
|
|
143
155
|
# Theme options are theme-specific and customize the look and feel of a theme
|
144
156
|
# further. For a list of options available for each theme, see the
|
@@ -11,7 +11,7 @@ pretty early state, though we hope you will find it useful.
|
|
11
11
|
**yapCAD** was created to solve some fairly specific problems in
|
12
12
|
procedural CAD and `parametric design`_ , and at present is most
|
13
13
|
developed for generating 2D drawings in the `AutoCad DXF`_ format.
|
14
|
-
If you don't know what procedural CAD or
|
14
|
+
If you don't know what procedural CAD or parameterized design
|
15
15
|
might be useful for, this may not be the tool for you.
|
16
16
|
|
17
17
|
On the other hand, if you are tired of manually editing your CAD
|
@@ -561,8 +561,17 @@ if __name__ == "__main__":
|
|
561
561
|
dd.display()
|
562
562
|
|
563
563
|
if ogl:
|
564
|
-
|
565
|
-
|
564
|
+
try:
|
565
|
+
from yapcad.pyglet_drawable import *
|
566
|
+
dd2 = pygletDraw()
|
567
|
+
except RuntimeError as err:
|
568
|
+
print("\nSkipping 3D visualization: {}".format(err))
|
569
|
+
ogl = False
|
570
|
+
except Exception as err:
|
571
|
+
print("\nSkipping 3D visualization due to unexpected error: {}".format(err))
|
572
|
+
ogl = False
|
573
|
+
|
574
|
+
if ogl:
|
566
575
|
# magnification factor for text
|
567
576
|
dd2.magnify=1.5
|
568
577
|
# compute the camera distance assuming a 60 degree (pi/6) FOV
|
@@ -571,13 +580,9 @@ if __name__ == "__main__":
|
|
571
580
|
dist = ((maxd/2) / math.sin(pi/6))*math.cos(pi/6)
|
572
581
|
dd2.cameradist = dist-box_height*2
|
573
582
|
|
574
|
-
|
575
583
|
twoDDraw(polys,dd2,-box_height*2)
|
576
584
|
|
577
585
|
oglGeom = makeOglGeom()
|
578
|
-
#print("oglGeom: ",oglGeom)
|
579
|
-
|
580
|
-
#oglGeom = translate(oglGeom,point(0,0,box_height))
|
581
586
|
|
582
587
|
dd2.layer='PATHS'
|
583
588
|
for i in range(len(oglGeom)):
|
@@ -587,8 +592,6 @@ if __name__ == "__main__":
|
|
587
592
|
dd2.linecolor = 'aqua'
|
588
593
|
else:
|
589
594
|
dd2.linecolor = 'fuchsia'
|
590
|
-
|
591
595
|
dd2.draw(oglGeom[i])
|
592
596
|
dd2.display()
|
593
597
|
print("done")
|
594
|
-
|
@@ -7,7 +7,11 @@ from yapcad.geom import *
|
|
7
7
|
|
8
8
|
#set up openGL rendering
|
9
9
|
def setupGL():
|
10
|
-
|
10
|
+
try:
|
11
|
+
dGl = pygletDraw()
|
12
|
+
except RuntimeError as err:
|
13
|
+
print("\nSkipping OpenGL rendering: {}".format(err))
|
14
|
+
return None
|
11
15
|
dGl.magnify = 1.0
|
12
16
|
dGl.linecolor = 'white'
|
13
17
|
dGl.cameradist = 25
|
@@ -107,15 +111,18 @@ if __name__ == "__main__":
|
|
107
111
|
## add a drawing legend in the OpenGL rendering, setting the
|
108
112
|
## color eplicitly to yellow
|
109
113
|
|
110
|
-
dGl
|
111
|
-
|
114
|
+
if dGl:
|
115
|
+
dGl.linecolor = 'yellow'
|
116
|
+
legend(dGl)
|
112
117
|
|
113
118
|
## draw the geometry in OpenGL
|
114
|
-
|
119
|
+
if dGl:
|
120
|
+
drawGlist(geomlist,dGl)
|
115
121
|
|
116
122
|
## write out the DXF file as example1-out.dxf
|
117
123
|
d.display()
|
118
124
|
|
119
125
|
## create the interactive OpenGL rendering -- do this last
|
120
|
-
dGl
|
126
|
+
if dGl:
|
127
|
+
dGl.display()
|
121
128
|
|
@@ -203,17 +203,30 @@ if __name__ == "__main__":
|
|
203
203
|
quit()
|
204
204
|
if len(sys.argv) > 2 and renderOgl==False:
|
205
205
|
filename = sys.argv[2]+".dxf"
|
206
|
-
|
206
|
+
requestedOgl = renderOgl
|
207
|
+
dd = None
|
207
208
|
if renderOgl:
|
208
209
|
print("OpenGL rendering selected")
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
210
|
+
try:
|
211
|
+
from yapcad.pyglet_drawable import *
|
212
|
+
dd=pygletDraw()
|
213
|
+
except RuntimeError as err:
|
214
|
+
print("\nSkipping OpenGL rendering: {}".format(err))
|
215
|
+
renderOgl = False
|
216
|
+
except Exception as err:
|
217
|
+
print("\nSkipping OpenGL rendering due to unexpected error: {}".format(err))
|
218
|
+
renderOgl = False
|
219
|
+
|
220
|
+
if not renderOgl or dd is None:
|
221
|
+
if requestedOgl and dd is None:
|
222
|
+
print("Falling back to DXF rendering")
|
223
|
+
else:
|
224
|
+
print("DXF rendering selected")
|
213
225
|
from yapcad.ezdxf_drawable import *
|
214
226
|
#set up DXF rendering
|
215
227
|
dd=ezdxfDraw()
|
216
228
|
dd.filename = filename
|
229
|
+
renderOgl = False
|
217
230
|
print("rendering...")
|
218
231
|
testAndDraw(dd)
|
219
232
|
print("done")
|
@@ -106,17 +106,30 @@ if __name__ == "__main__":
|
|
106
106
|
quit()
|
107
107
|
if len(sys.argv) > 2 and renderOgl==False:
|
108
108
|
filename = sys.argv[2]+".dxf"
|
109
|
-
|
109
|
+
requestedOgl = renderOgl
|
110
|
+
dd = None
|
110
111
|
if renderOgl:
|
111
112
|
print("OpenGL rendering selected")
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
try:
|
114
|
+
from yapcad.pyglet_drawable import *
|
115
|
+
dd=pygletDraw()
|
116
|
+
except RuntimeError as err:
|
117
|
+
print("\nSkipping OpenGL rendering: {}".format(err))
|
118
|
+
renderOgl = False
|
119
|
+
except Exception as err:
|
120
|
+
print("\nSkipping OpenGL rendering due to unexpected error: {}".format(err))
|
121
|
+
renderOgl = False
|
122
|
+
|
123
|
+
if not renderOgl or dd is None:
|
124
|
+
if requestedOgl and dd is None:
|
125
|
+
print("Falling back to DXF rendering")
|
126
|
+
else:
|
127
|
+
print("DXF rendering selected")
|
116
128
|
from yapcad.ezdxf_drawable import *
|
117
129
|
#set up DXF rendering
|
118
130
|
dd=ezdxfDraw()
|
119
131
|
dd.filename = filename
|
132
|
+
renderOgl = False
|
120
133
|
print("rendering...")
|
121
134
|
testAndDraw(dd)
|
122
135
|
print("done")
|
@@ -44,6 +44,7 @@ def geometry():
|
|
44
44
|
jigsaw=makeJigsawPiece(poly=True)
|
45
45
|
bigc= makeCircle(point(0,0,0),20)
|
46
46
|
nb = Boolean('union',[logopoly,bigc])
|
47
|
+
nb = nb.scale(0.8,poly=True)
|
47
48
|
nb = nb.translate(point(0,-50),poly=True)
|
48
49
|
docGeomList.append(nb.geom())
|
49
50
|
|
@@ -74,6 +75,8 @@ def testAndDraw(dd):
|
|
74
75
|
else:
|
75
76
|
dd.linecolor = 'aqua'
|
76
77
|
dd.draw(geom2)
|
78
|
+
dd.linecolor = 'red'
|
79
|
+
dd.draw(translate(geom,point(0,0,5)))
|
77
80
|
|
78
81
|
if not renderOgl:
|
79
82
|
dd.layer = 'DOCUMENTATION'
|
@@ -114,20 +117,32 @@ if __name__ == "__main__":
|
|
114
117
|
quit()
|
115
118
|
if len(sys.argv) > 2 and renderOgl==False:
|
116
119
|
filename = sys.argv[2]+".dxf"
|
117
|
-
|
120
|
+
requestedOgl = renderOgl
|
121
|
+
dd = None
|
118
122
|
if renderOgl:
|
119
123
|
print("OpenGL rendering selected")
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
124
|
+
try:
|
125
|
+
from yapcad.pyglet_drawable import *
|
126
|
+
dd=pygletDraw()
|
127
|
+
dd.cameradist=170.0
|
128
|
+
except RuntimeError as err:
|
129
|
+
print("\nSkipping OpenGL rendering: {}".format(err))
|
130
|
+
renderOgl = False
|
131
|
+
except Exception as err:
|
132
|
+
print("\nSkipping OpenGL rendering due to unexpected error: {}".format(err))
|
133
|
+
renderOgl = False
|
134
|
+
|
135
|
+
if not renderOgl or dd is None:
|
136
|
+
if requestedOgl and dd is None:
|
137
|
+
print("Falling back to DXF rendering")
|
138
|
+
else:
|
139
|
+
print("DXF rendering selected")
|
126
140
|
from yapcad.ezdxf_drawable import *
|
127
141
|
#set up DXF rendering
|
128
142
|
dd=ezdxfDraw()
|
129
143
|
dd.filename = filename
|
130
144
|
drawLegend(dd)
|
145
|
+
renderOgl = False
|
131
146
|
print("rendering...")
|
132
147
|
|
133
148
|
testAndDraw(dd)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
## yapCAD poly() intersecton and drawing examples
|
2
2
|
|
3
|
+
import sys
|
3
4
|
from yapcad.geom import *
|
4
5
|
from yapcad.poly import *
|
5
6
|
import random
|
@@ -14,8 +15,15 @@ if __name__ == "__main__":
|
|
14
15
|
making and then mirroring random "flowers." Renders output interactively with OpenGL.
|
15
16
|
""")
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
try:
|
19
|
+
from yapcad.pyglet_drawable import *
|
20
|
+
dd=pygletDraw()
|
21
|
+
except RuntimeError as err:
|
22
|
+
print("\nSkipping OpenGL rendering: {}".format(err))
|
23
|
+
sys.exit(0)
|
24
|
+
except Exception as err:
|
25
|
+
print("\nSkipping OpenGL rendering due to unexpected error: {}".format(err))
|
26
|
+
sys.exit(1)
|
19
27
|
dd.cameradist=150.0
|
20
28
|
glist = mirrorArray()
|
21
29
|
|
@@ -117,7 +117,16 @@ def sphere(diameter,center=point(0,0,0),depth=2):
|
|
117
117
|
|
118
118
|
|
119
119
|
if __name__ == "__main__":
|
120
|
-
|
120
|
+
import sys
|
121
|
+
try:
|
122
|
+
from yapcad.pyglet_drawable import *
|
123
|
+
dd=pygletDraw()
|
124
|
+
except RuntimeError as err:
|
125
|
+
print("\nSkipping OpenGL rendering: {}".format(err))
|
126
|
+
sys.exit(0)
|
127
|
+
except Exception as err:
|
128
|
+
print("\nSkipping OpenGL rendering due to unexpected error: {}".format(err))
|
129
|
+
sys.exit(1)
|
121
130
|
print("example9.py -- yapCAD 3D geometry demonstration")
|
122
131
|
print("""
|
123
132
|
This is a demonstration of the creation and rendering of
|
@@ -127,7 +136,6 @@ engine.
|
|
127
136
|
In this example we create an icosohedron centered at the orign and
|
128
137
|
tesellate it spherically""")
|
129
138
|
|
130
|
-
dd=pygletDraw()
|
131
139
|
dd.linecolor = 'white'
|
132
140
|
|
133
141
|
verts,normals,faces = sphere(50.0,point(0,0,0),3)
|
@@ -1,22 +1,25 @@
|
|
1
1
|
[project]
|
2
2
|
name = "yapCAD"
|
3
|
-
version = "0.
|
3
|
+
version = "0.3.0"
|
4
4
|
authors = [
|
5
5
|
{ name="Richard DeVaul", email="richard.devaul@gmail.com" },
|
6
6
|
]
|
7
7
|
description = "yet another procedural CAD and computational geometry system"
|
8
8
|
readme = "README.rst"
|
9
|
-
requires-python = ">=3.
|
9
|
+
requires-python = ">=3.10"
|
10
10
|
classifiers = [
|
11
11
|
"Programming Language :: Python :: 3",
|
12
12
|
"License :: OSI Approved :: MIT License",
|
13
13
|
"Operating System :: OS Independent",
|
14
14
|
]
|
15
15
|
dependencies = [
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
"ezdxf>=1.1",
|
17
|
+
"pyglet>=1.5,<2",
|
18
|
+
"mpmath>=1.2",
|
19
|
+
"pyobjc-core; platform_system == 'Darwin'",
|
20
|
+
"pyobjc-framework-Cocoa; platform_system == 'Darwin'",
|
21
|
+
"pyobjc-framework-Quartz; platform_system == 'Darwin'"
|
22
|
+
]
|
20
23
|
|
21
24
|
[project.optional-dependencies]
|
22
25
|
tests = [
|
@@ -15,6 +15,9 @@
|
|
15
15
|
# numpy==1.13.3
|
16
16
|
# scipy==1.0
|
17
17
|
#
|
18
|
-
ezdxf
|
19
|
-
pyglet
|
20
|
-
mpmath
|
18
|
+
ezdxf>=1.1
|
19
|
+
pyglet>=1.5,<2
|
20
|
+
mpmath>=1.2
|
21
|
+
pyobjc-core; platform_system == "Darwin"
|
22
|
+
pyobjc-framework-Cocoa; platform_system == "Darwin"
|
23
|
+
pyobjc-framework-Quartz; platform_system == "Darwin"
|
@@ -7,7 +7,14 @@ include_package_data = True
|
|
7
7
|
package_dir =
|
8
8
|
=src
|
9
9
|
setup_requires = pyscaffold>=3.2a0,<3.3a0
|
10
|
-
install_requires =
|
10
|
+
install_requires =
|
11
|
+
ezdxf>=1.1
|
12
|
+
pyglet>=1.5,<2
|
13
|
+
mpmath>=1.2
|
14
|
+
pyobjc-core; platform_system == "Darwin"
|
15
|
+
pyobjc-framework-Cocoa; platform_system == "Darwin"
|
16
|
+
pyobjc-framework-Quartz; platform_system == "Darwin"
|
17
|
+
python_requires = >=3.10
|
11
18
|
|
12
19
|
[options.packages.find]
|
13
20
|
where = src
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: yapCAD
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.3.0
|
4
4
|
Summary: yet another procedural CAD and computational geometry system
|
5
5
|
Author-email: Richard DeVaul <richard.devaul@gmail.com>
|
6
6
|
Project-URL: Homepage, https://github.com/rdevaul/yapCAD/
|
@@ -8,13 +8,21 @@ Project-URL: Documentation, https://yapcad.readthedocs.io/en/latest/
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
|
-
Requires-Python: >=3.
|
11
|
+
Requires-Python: >=3.10
|
12
12
|
Description-Content-Type: text/x-rst
|
13
|
-
Provides-Extra: testing
|
14
|
-
Provides-Extra: tests
|
15
13
|
License-File: LICENSE
|
16
14
|
License-File: LICENSE.txt
|
17
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
|
18
26
|
|
19
27
|
**yapCAD**
|
20
28
|
==========
|
@@ -106,6 +114,22 @@ supported by Sphinx. See the `Sphinx
|
|
106
114
|
documentation <https://www.sphinx-doc.org/en/master/>`__ for more
|
107
115
|
information.
|
108
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
|
+
|
109
133
|
**yapCAD** goals
|
110
134
|
----------------
|
111
135
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
try: # Python >= 3.8
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
4
|
+
except ModuleNotFoundError: # pragma: no cover - for Python < 3.8
|
5
|
+
from importlib_metadata import PackageNotFoundError, version
|
6
|
+
|
7
|
+
|
8
|
+
try:
|
9
|
+
__version__ = version("yapCAD")
|
10
|
+
except PackageNotFoundError: # pragma: no cover - handled when package not installed
|
11
|
+
__version__ = "unknown"
|
@@ -10,16 +10,22 @@ class Boolean(IntersectGeometry):
|
|
10
10
|
|
11
11
|
types = ('union','intersection','difference')
|
12
12
|
|
13
|
-
def __init__(self,type='union',polys=
|
13
|
+
def __init__(self, type='union', polys=None):
|
14
|
+
super().__init__()
|
15
|
+
if type not in self.types:
|
16
|
+
raise ValueError('invalid type passed to Boolean(): {}'.format(type))
|
17
|
+
|
18
|
+
if polys is None:
|
19
|
+
polys = []
|
20
|
+
|
14
21
|
for p in polys:
|
15
|
-
if not (
|
22
|
+
if not (isinstance(p, Polygon) or isinstance(p, Boolean)):
|
16
23
|
raise ValueError('non-poly or non-boolean passed to Boolean(): {}'.format(p))
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
self._outline=[]
|
24
|
+
|
25
|
+
self._elem = list(polys)
|
26
|
+
self._type = type
|
27
|
+
self._update = True
|
28
|
+
self._outline = []
|
23
29
|
|
24
30
|
|
25
31
|
def combine_geom(self,g1,g2):
|
@@ -1870,7 +1870,6 @@ def isinsidepolyXY(a,p):
|
|
1870
1870
|
|
1871
1871
|
"""
|
1872
1872
|
closed=False
|
1873
|
-
|
1874
1873
|
if len(a) > 2 and dist(a[0],a[-1]) < epsilon:
|
1875
1874
|
closed = True
|
1876
1875
|
|
@@ -1887,12 +1886,11 @@ def isinsidepolyXY(a,p):
|
|
1887
1886
|
if not isinsidebbox(bb,p):
|
1888
1887
|
return False
|
1889
1888
|
## inside the bounding box, do intersection testing
|
1890
|
-
p2 = add([
|
1889
|
+
p2 = add([0.01,0.01,0,1],bb[1])
|
1891
1890
|
if vclose(p2,p): ## did we randomly pick an outside point near the
|
1892
|
-
## test point?
|
1893
|
-
|
1891
|
+
## test point? If so, test point is outside bb
|
1892
|
+
return False
|
1894
1893
|
l = line(p,p2)
|
1895
|
-
|
1896
1894
|
pp = intersectSimplePolyXY(l,a)
|
1897
1895
|
if pp == False:
|
1898
1896
|
return False
|
@@ -2285,10 +2283,10 @@ def isinsidegeomlistXY(a,p):
|
|
2285
2283
|
bb = geomlistbbox(a)
|
2286
2284
|
if not isinsidebbox(bb,p):
|
2287
2285
|
return False
|
2288
|
-
p2 = add([1,1,0,1],bb[1])
|
2286
|
+
p2 = add([0.1,0.1,0,1],bb[1])
|
2289
2287
|
if vclose(p2,p): ## did we randomly pick an outside point near the
|
2290
|
-
## test point?
|
2291
|
-
|
2288
|
+
## test point? If so, test point is outside bb
|
2289
|
+
return False
|
2292
2290
|
l = line(p,p2)
|
2293
2291
|
|
2294
2292
|
pp = intersectGeomListXY(l,a)
|
@@ -2365,7 +2363,7 @@ def intersectGeomListXY(g,gl,inside=True,params=False):
|
|
2365
2363
|
raise ValueError('bad gtype in intersectGeomListXY, this should never happen')
|
2366
2364
|
|
2367
2365
|
dst = 0.0
|
2368
|
-
if len(gl) >
|
2366
|
+
if len(gl) > 1:
|
2369
2367
|
for i in range(len(gl)):
|
2370
2368
|
g2 = gl[i]
|
2371
2369
|
uu = []
|
@@ -2389,12 +2387,12 @@ def intersectGeomListXY(g,gl,inside=True,params=False):
|
|
2389
2387
|
elif gtype == 'poly' and gtype2 == 'poly':
|
2390
2388
|
zz1 = []
|
2391
2389
|
zz2 = []
|
2392
|
-
for
|
2393
|
-
zz = intersectSimplePolyXY(line(g[
|
2390
|
+
for j in range(1,len(g)):
|
2391
|
+
zz = intersectSimplePolyXY(line(g[j-1],g[j]),
|
2394
2392
|
g2, params=True)
|
2395
2393
|
if not isinstance(zz,bool):
|
2396
|
-
zz1
|
2397
|
-
zz2
|
2394
|
+
zz1 = zz1 + zz[0]
|
2395
|
+
zz2 = zz2 + zz[1]
|
2398
2396
|
if len(zz1) > 0:
|
2399
2397
|
uu = [ zz1,zz2 ]
|
2400
2398
|
elif gtype == 'simple' and gtype2 == 'glist':
|
@@ -2543,7 +2541,7 @@ def center(x):
|
|
2543
2541
|
pl = []
|
2544
2542
|
for g in x:
|
2545
2543
|
pl.append(center(g))
|
2546
|
-
return
|
2544
|
+
return center(pl)
|
2547
2545
|
else:
|
2548
2546
|
raise ValueError("inappropriate type for center(): ",format(x))
|
2549
2547
|
|
@@ -18,7 +18,7 @@
|
|
18
18
|
## classically-definalble gap (or the possibility thereof) then
|
19
19
|
## implement Geometry instead
|
20
20
|
|
21
|
-
import
|
21
|
+
from copy import deepcopy
|
22
22
|
from yapcad.geom import *
|
23
23
|
|
24
24
|
|
@@ -43,7 +43,7 @@ class Geometry:
|
|
43
43
|
return
|
44
44
|
|
45
45
|
def geom(self):
|
46
|
-
if self.
|
46
|
+
if self._update:
|
47
47
|
self._updateInternals()
|
48
48
|
return deepcopy(self._elem)
|
49
49
|
|
@@ -165,11 +165,17 @@ class Matrix:
|
|
165
165
|
self.m[j] = x
|
166
166
|
|
167
167
|
|
168
|
-
# matrix multiply. If x is a matrix, compute MX. If
|
168
|
+
# matrix multiply. If x is a matrix, compute MX. If x is a
|
169
169
|
# vector, compute Mx. If x is a scalar, compute xM. If x isn't any
|
170
|
-
# of these,
|
171
|
-
|
170
|
+
# of these, a ValueError is raised. Respects transpose flag.
|
171
|
+
|
172
172
|
def mul(self,x):
|
173
|
+
"""Return the product of this matrix and ``x``.
|
174
|
+
|
175
|
+
``x`` may be another :class:`Matrix`, a 4D vector, or a scalar. In
|
176
|
+
each case the appropriate matrix multiplication is performed. If
|
177
|
+
``x`` is none of these types, a :class:`ValueError` is raised.
|
178
|
+
"""
|
173
179
|
if isinstance(x,Matrix):
|
174
180
|
result = Matrix()
|
175
181
|
for i in range(4):
|
@@ -232,7 +238,7 @@ def Rotation(axis,angle,inverse=False):
|
|
232
238
|
|
233
239
|
def Translation(delta,inverse=False):
|
234
240
|
if inverse:
|
235
|
-
delta =
|
241
|
+
delta = geom.scale3(delta, -1.0)
|
236
242
|
dx = delta[0]
|
237
243
|
dy = delta[1]
|
238
244
|
dz = delta[2]
|
@@ -26,6 +26,16 @@ class TestXform:
|
|
26
26
|
## homogeneous coordinates test
|
27
27
|
assert(geom.homo(foo.mul(baz)) ==
|
28
28
|
[18.0/102.0, 46.0/102.0, 74.0/102.0, 1.0])
|
29
|
+
|
30
|
+
def test_translation(self):
|
31
|
+
p = geom.vect(1,2,3)
|
32
|
+
dx = 4
|
33
|
+
dy = -2
|
34
|
+
dz = 1
|
35
|
+
T = Translation([dx,dy,dz])
|
36
|
+
assert(T.mul(p) == geom.vect(1+dx,2+dy,3+dz))
|
37
|
+
Tinv = Translation([dx,dy,dz],inverse=True)
|
38
|
+
assert(Tinv.mul(p) == geom.vect(1-dx,2-dy,3-dz))
|
29
39
|
|
30
40
|
|
31
41
|
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
from pkg_resources import get_distribution, DistributionNotFound
|
3
|
-
|
4
|
-
try:
|
5
|
-
# Change here if project is renamed and does not equal the package name
|
6
|
-
dist_name = 'yapCAD'
|
7
|
-
__version__ = get_distribution(dist_name).version
|
8
|
-
except DistributionNotFound:
|
9
|
-
__version__ = 'unknown'
|
10
|
-
finally:
|
11
|
-
del get_distribution, DistributionNotFound
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|