yapCAD 0.2.0__py2.py3-none-any.whl → 0.3.0__py2.py3-none-any.whl

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/__init__.py CHANGED
@@ -1,11 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
- from pkg_resources import get_distribution, DistributionNotFound
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
+
3
7
 
4
8
  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
9
+ __version__ = version("yapCAD")
10
+ except PackageNotFoundError: # pragma: no cover - handled when package not installed
11
+ __version__ = "unknown"
yapcad/combine.py CHANGED
@@ -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 ( isinstance(p,Polygon) or isinstance(p,Boolean) ):
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
- if not type in self.types:
18
- raise ValueError('invalid type passed to Boolean(): {}'.format(tpe))
19
- self._elem=list(polys)
20
- self._type=type
21
- self._update=True
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):
yapcad/ezdxf_drawable.py CHANGED
@@ -27,6 +27,7 @@
27
27
  from yapcad.geom import *
28
28
  import yapcad.drawable as drawable
29
29
  import ezdxf
30
+ from ezdxf.enums import TextEntityAlignment
30
31
 
31
32
  ## class to provide dxf drawing functionality
32
33
  class ezdxfDraw(drawable.Drawable):
@@ -137,6 +138,17 @@ class ezdxfDraw(drawable.Drawable):
137
138
  else:
138
139
  color = 256 # by layer
139
140
 
141
+ alignment = [];
142
+ if align == 'LEFT':
143
+ alignment = TextEntityAlignment.LEFT
144
+ elif align == 'CENTER':
145
+ alignment = TextEntityAlignment.CENTER
146
+ elif align == 'RIGHT':
147
+ alignment = TextEntityAlignment.RIGHT
148
+ else:
149
+ ## default alignment is left
150
+ alignment = TextEntityAlignment.LEFT
151
+
140
152
  dxfattr = dict()
141
153
  if 'style' in attr:
142
154
  dxfattr['style'] = attr['style']
@@ -144,8 +156,12 @@ class ezdxfDraw(drawable.Drawable):
144
156
  dxfattr['height'] = attr['height']
145
157
  dxfattr.update({ 'layer': layer,
146
158
  'color': color})
147
- self.__msp.add_text(text,dxfattr).set_pos((location[0],location[1]),
148
- align=align)
159
+ self.__msp.add_text(
160
+ text,
161
+ dxfattribs=dxfattr).set_placement(
162
+ (location[0],location[1]),
163
+ align=alignment
164
+ )
149
165
 
150
166
  def display(self):
151
167
  self.__doc.saveas("{}.dxf".format(self.filename))
yapcad/geom.py CHANGED
@@ -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([1,1,0,1],bb[1])
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
- p2 = sub(bb[0],[1,1,0,1])
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
- p2 = sub(bb[0],[1,1,0,1])
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) > 2:
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 i in range(1,len(g)):
2393
- zz = intersectSimplePolyXY(line(g[i-1],g[i]),
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.append(zz[0])
2397
- zz2.append(zz[1])
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 polycenter(pl)
2544
+ return center(pl)
2547
2545
  else:
2548
2546
  raise ValueError("inappropriate type for center(): ",format(x))
2549
2547
 
yapcad/geometry.py CHANGED
@@ -18,7 +18,7 @@
18
18
  ## classically-definalble gap (or the possibility thereof) then
19
19
  ## implement Geometry instead
20
20
 
21
- import copy
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.update:
46
+ if self._update:
47
47
  self._updateInternals()
48
48
  return deepcopy(self._elem)
49
49
 
yapcad/xform.py CHANGED
@@ -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 X is a
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, return False. Respects transpose flag.
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 = mul(delta,-1.0)
241
+ delta = geom.scale3(delta, -1.0)
236
242
  dx = delta[0]
237
243
  dy = delta[1]
238
244
  dz = delta[2]
@@ -1,22 +1,28 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: yapCAD
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: yet another procedural CAD and computational geometry system
5
- Home-page: https://github.com/rdevaul/yapCAD/
6
- Author: Richard DeVaul
7
- Author-email: richard.devaul@gmail.com
8
- License: mit
5
+ Author-email: Richard DeVaul <richard.devaul@gmail.com>
6
+ Project-URL: Homepage, https://github.com/rdevaul/yapCAD/
9
7
  Project-URL: Documentation, https://yapcad.readthedocs.io/en/latest/
10
- Platform: any
11
- Classifier: Development Status :: 4 - Beta
12
- Classifier: Programming Language :: Python
13
- Description-Content-Type: text/x-rst; charset=UTF-8
14
- Requires-Dist: ezdxf
15
- Requires-Dist: pyglet
16
- Requires-Dist: mpmath
17
- Provides-Extra: testing
18
- Requires-Dist: pytest ; extra == 'testing'
19
- Requires-Dist: pytest-cov ; extra == 'testing'
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
20
26
 
21
27
  **yapCAD**
22
28
  ==========
@@ -108,6 +114,22 @@ supported by Sphinx. See the `Sphinx
108
114
  documentation <https://www.sphinx-doc.org/en/master/>`__ for more
109
115
  information.
110
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
+
111
133
  **yapCAD** goals
112
134
  ----------------
113
135
 
@@ -456,5 +478,3 @@ Note
456
478
 
457
479
  This project has been set up using PyScaffold 3.2.3. For details and
458
480
  usage information on PyScaffold see https://pyscaffold.org/.
459
-
460
-
@@ -0,0 +1,17 @@
1
+ yapcad/__init__.py,sha256=CUEd7EOL-ne31ggDprsi4lwLWMV1SRV5KYqkuDTdxrQ,400
2
+ yapcad/combine.py,sha256=uC8QsFRGa198rIkKhNIOm-GhuDvezlGcX3nhEY2N2YE,13993
3
+ yapcad/drawable.py,sha256=RKG8emMC0E6__-L89zrBVxAB1JiFUPA51cAweCu7zP8,14605
4
+ yapcad/ezdxf_drawable.py,sha256=pZGLS9Dw108GG6ItahszSkkRopYLtgP9CDVWxHCrMrs,5948
5
+ yapcad/geom.py,sha256=YSqG-C7Ti9VCkSyIC3VggJImx_tAlyxtN38SNUdGM5Q,108843
6
+ yapcad/geom3d.py,sha256=W6gmo8UifgFwy3HHQvgvvgp96l2ahMqTVyTmbXqNEd8,2865
7
+ yapcad/geometry.py,sha256=H-ahJG2nsXvV__6TqWf_ReRWVFZdL4bBPPPTYEnPvi0,2564
8
+ yapcad/poly.py,sha256=Fku0ynBzYUSb5UZA6WY0yLPmDTc_Eg6BVE3DUKqiJqo,21447
9
+ yapcad/pyglet_drawable.py,sha256=dV9dcwzZRlPwhx18Dv0CX7wQOCxnxwk4Si_FL9heNs8,18475
10
+ yapcad/xform.py,sha256=It95Ql9JpMFqk95X8MvAmqYpCQu0VKp-JShmRTC0Ztk,9538
11
+ yapcad-0.3.0.dist-info/licenses/AUTHORS.rst,sha256=JzvJA3p1aSIOTaaB3aCtB-ZrUQrVm869gdROUV5bRh8,84
12
+ yapcad-0.3.0.dist-info/licenses/LICENSE,sha256=NkGvciCD5MEHmCtnivAi2PqcEhBYAkSAarP-bWAoknM,1071
13
+ yapcad-0.3.0.dist-info/licenses/LICENSE.txt,sha256=FyT_Hxn5USuJ1Mu3-4Ou4T2x-Dzfiy06ZOnWkfdJ33o,1081
14
+ yapcad-0.3.0.dist-info/METADATA,sha256=zfvxqcMOeJJsH2yp5Mw4TJkGeuyIAbeQ507n4f7PTdY,18999
15
+ yapcad-0.3.0.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
16
+ yapcad-0.3.0.dist-info/top_level.txt,sha256=NAtnfsyeALrvhI63FGS3_TEUh26OKRvnm1_lCOOgjKA,7
17
+ yapcad-0.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.33.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -1,18 +0,0 @@
1
- yapcad/__init__.py,sha256=Wi3rOCWkiWUKzXbHatCZ7t6RHrGZXCoxpvTjyv4o1jc,363
2
- yapcad/acdxf.py,sha256=auHSE-iUnToqhcMhBbvUCXjcL0gklDuWeab8aFciRE0,3563
3
- yapcad/combine.py,sha256=N7NPfvKHm00ejWlUFJITzAJ6D4zcFb1ihwKvh5s-EeU,13925
4
- yapcad/drawable.py,sha256=RKG8emMC0E6__-L89zrBVxAB1JiFUPA51cAweCu7zP8,14605
5
- yapcad/ezdxf_drawable.py,sha256=Dhx2gOpRpOQsq_W8htQifecyMD_h3-KIMqb6sUBt-_A,5478
6
- yapcad/geom.py,sha256=nzCPYIsse6Z66AIYxWVoD7IddtrCNcwGWZDX06Mh-_w,108801
7
- yapcad/geom3d.py,sha256=W6gmo8UifgFwy3HHQvgvvgp96l2ahMqTVyTmbXqNEd8,2865
8
- yapcad/geometry.py,sha256=hCVnJvZXX6R4c8bWTwsWGq0tzTUJtzB974Q7s8vO28U,2549
9
- yapcad/poly.py,sha256=Fku0ynBzYUSb5UZA6WY0yLPmDTc_Eg6BVE3DUKqiJqo,21447
10
- yapcad/pyglet_drawable.py,sha256=dV9dcwzZRlPwhx18Dv0CX7wQOCxnxwk4Si_FL9heNs8,18475
11
- yapcad/xform.py,sha256=kL2xAsTlbhZplPwpWERbNp6Izkr2l90sRUf_fSfL3uw,9235
12
- yapCAD-0.2.0.dist-info/AUTHORS.rst,sha256=JzvJA3p1aSIOTaaB3aCtB-ZrUQrVm869gdROUV5bRh8,84
13
- yapCAD-0.2.0.dist-info/LICENSE,sha256=NkGvciCD5MEHmCtnivAi2PqcEhBYAkSAarP-bWAoknM,1071
14
- yapCAD-0.2.0.dist-info/LICENSE.txt,sha256=FyT_Hxn5USuJ1Mu3-4Ou4T2x-Dzfiy06ZOnWkfdJ33o,1081
15
- yapCAD-0.2.0.dist-info/METADATA,sha256=fJHMA91Wp6AYjsVgjEkxqAL9s81XnF6x-IQmDQZWiF4,18142
16
- yapCAD-0.2.0.dist-info/WHEEL,sha256=HX-v9-noUkyUoxyZ1PMSuS7auUxDAR4VBdoYLqD0xws,110
17
- yapCAD-0.2.0.dist-info/top_level.txt,sha256=NAtnfsyeALrvhI63FGS3_TEUh26OKRvnm1_lCOOgjKA,7
18
- yapCAD-0.2.0.dist-info/RECORD,,
yapcad/acdxf.py DELETED
@@ -1,120 +0,0 @@
1
- ## yapCAD support functions for working with Autodesk's DXF file format
2
- ## Created on Fri Oct 9 16:06:08 PDT 2020
3
- ## Copyright (c) 2020 Richard W. DeVaul
4
- ## Copyright (c) 2020 yapCAD contributors
5
- ## All rights reserved
6
- ## See licensing terms here: https://github.com/rdevaul/yapCAD/blob/master/LICENSE
7
-
8
- from yapcad.geom import *
9
- import math
10
-
11
- ## eqivalent to autoLISP polar function
12
- ## note this function works in radians
13
- def polar(p,ang,r):
14
- x = math.cos(ang)*r
15
- y = math.sin(ang)*r
16
- return add(p,point(x,y))
17
-
18
- ## equivalent to autoLISP angle function
19
- ## note this function returns radians
20
- def angle(p1,p2):
21
- if vclose(p1,p2):
22
- raise ValueError('coincident points')
23
- pp = sub(p2,p1)
24
- return atan2(pp[1],pp[0])
25
-
26
- ## utility functions for radian/degree conversions
27
- def rad2deg(theta):
28
- return theta*360.0/pi2
29
-
30
- def deg2rad(theta):
31
- return theta*pi2/360.0
32
-
33
- ## function to convert from DXF Polyline "bulge" representation to
34
- ## a yapCAD arc.
35
- ## Thanks to Lee Mac for autoLISP code examples
36
- ## http://www.lee-mac.com/bulgeconversion.html
37
- def bulge2arc(p1,p2,b):
38
- a = 2.0 * math.atan(b)
39
- r = dist(p1,p2) / (math.sin(a)*2.0)
40
- c = polar(p1, ((math.pi/2.0 - a) + angle(p1, p2)),r)
41
- a1 = rad2deg(angle(c,p1))
42
- a2 = rad2deg(angle(c,p2))
43
- if b < 0.0:
44
- return arc(c,abs(r),a2,a1)
45
- else:
46
- return arc(c,abs(r),a1,a2)
47
-
48
- ## function to convert from a yapCAD arc to a DXF Polyline "bulge"
49
- ## representaiton.
50
- ## Thanks to Lee Mac for autoLISP code examples
51
- def arc2bulge(ac):
52
- c = ac[0]
53
- r= ac[1][0]
54
- a1=deg2rad(ac[1][1])
55
- a2=deg2rad(ac[1][2])
56
-
57
- b = math.tan(((a2-a1)%pi2)/4.0)
58
-
59
- return [polar(c,a1,r),polar(c,a2,r),b]
60
-
61
-
62
- ## Function to convert a yapCAD poly (point list) to an internal DXF
63
- ## polyline representation
64
- def yappoly2acpoly(plist):
65
- dxfpoly=[]
66
- for i in range(len(plist)-1):
67
- p=plist[i]
68
- dxfpoly.append([p[0],p[1],0,-2])
69
- p = plist[-1]
70
- dxfpoly.append([p[0],p[1],0,-2])
71
- return dxfpoly
72
-
73
- ## funtion to convert a yapCAD geometry list to a list of DXF
74
- ## polylines. Each contiguous sequence of yapCAD lines, arcs, and
75
- ## polys will be converted into a DXF polyline.
76
-
77
- ## If there are elements, such as circles, that aren't convertable to
78
- ## a DXF polyline representation, they will be added to a separate
79
- ## "nonconvertable" yapCAD geometry list.
80
-
81
- ## Return value ( dxfpolys , nonconvertable ), where dxfpolys is a
82
- ## list of contiguous dxf bulge polyline representations, and
83
- ## nonconvertable is a yapCAD geometry list of remainders
84
-
85
- def yapgeom2acpoly(glist):
86
- ## internal function to take a non-zero-length geometry list and
87
- ## return one or more contiguous geometry lists
88
- def gl2contig(gl):
89
- nonconv=[]
90
- ggl=[]
91
- cl=[gl[0]]
92
- ep = sample(cl[0],1.0) # find endpoint of first element
93
- for i in range(1,len(gl)):
94
- g = gl[i]
95
- sp = sample(g,0.0) # find start of current element
96
- if vclose(sp,ep): # are they close?
97
- cl.append(g) # yep, append
98
- else:
99
- ggl.append(cl) #nope, finish out current list, start
100
- #new one
101
- cl=g
102
- ep = sample(g,1.0)
103
- return ggl
104
- if not isgeomlist(glist):
105
- return False
106
-
107
- ypgls = gl2contig(glist)
108
- dxfgls = []
109
- dxfgl = []
110
- for ypgl in ypgls:
111
- dxfpoly=[]
112
- for i in range(1,len(ypgl)):
113
- if ispoint(gl):
114
- ## bogus, unfinished function
115
- return
116
-
117
- return
118
-
119
-
120
-