Compare commits
No commits in common. "master" and "v0.13" have entirely different histories.
4 changed files with 20 additions and 20 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
**Homepage:** https://mpxd.net/code/jan/fatamorgana
|
**Homepage:** https://mpxd.net/code/jan/fatamorgana
|
||||||
* [PyPI](https://pypi.org/project/fatamorgana)
|
* [PyPI](https://pypi.org/project/fatamorgana)
|
||||||
|
* [Github mirror](https://github.com/anewusername/fatamorgana)
|
||||||
|
|
||||||
**Capabilities:**
|
**Capabilities:**
|
||||||
* This package is a work-in-progress and is largely untested -- it works for
|
* This package is a work-in-progress and is largely untested -- it works for
|
||||||
|
|
@ -27,7 +28,12 @@
|
||||||
|
|
||||||
Install with pip from PyPi (preferred):
|
Install with pip from PyPi (preferred):
|
||||||
```bash
|
```bash
|
||||||
pip install fatamorgana
|
pip3 install fatamorgana
|
||||||
|
```
|
||||||
|
|
||||||
|
Install directly from git repository:
|
||||||
|
```bash
|
||||||
|
pip3 install git+https://mpxd.net/code/jan/fatamorgana.git@release
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
@ -38,6 +44,7 @@ To read the inline help,
|
||||||
import fatamorgana
|
import fatamorgana
|
||||||
help(fatamorgana.OasisLayout)
|
help(fatamorgana.OasisLayout)
|
||||||
```
|
```
|
||||||
|
The documentation is currently very sparse and I expect to improve it whenever possible!
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
This module contains all datatypes and parsing/writing functions for
|
This module contains all datatypes and parsing/writing functions for
|
||||||
all abstractions below the 'record' or 'block' level.
|
all abstractions below the 'record' or 'block' level.
|
||||||
"""
|
"""
|
||||||
from typing import Any, IO, Union, TYPE_CHECKING
|
from typing import Any, IO, Union
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
@ -250,7 +250,6 @@ def write_uint(stream: IO[bytes], n: int) -> int:
|
||||||
Raises:
|
Raises:
|
||||||
SignedError: if `n` is negative.
|
SignedError: if `n` is negative.
|
||||||
"""
|
"""
|
||||||
n = int(n)
|
|
||||||
if n < 0:
|
if n < 0:
|
||||||
raise SignedError(f'uint must be positive: {n}')
|
raise SignedError(f'uint must be positive: {n}')
|
||||||
|
|
||||||
|
|
@ -296,7 +295,6 @@ def encode_sint(sint: int) -> int:
|
||||||
Returns:
|
Returns:
|
||||||
Unsigned integer encoding for the input.
|
Unsigned integer encoding for the input.
|
||||||
"""
|
"""
|
||||||
sint = int(sint)
|
|
||||||
return (abs(sint) << 1) | (sint < 0)
|
return (abs(sint) << 1) | (sint < 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1213,10 +1211,6 @@ class GridRepetition:
|
||||||
InvalidDataError: if `b_count` and `b_vector` inputs conflict
|
InvalidDataError: if `b_count` and `b_vector` inputs conflict
|
||||||
with each other or if `a_count < 1`.
|
with each other or if `a_count < 1`.
|
||||||
"""
|
"""
|
||||||
a_count = int(a_count)
|
|
||||||
if b_count is not None:
|
|
||||||
b_count = int(b_count)
|
|
||||||
|
|
||||||
if b_vector is None or b_count is None:
|
if b_vector is None or b_count is None:
|
||||||
if b_vector is not None or b_count is not None:
|
if b_vector is not None or b_count is not None:
|
||||||
raise InvalidDataError('Repetition has only one of'
|
raise InvalidDataError('Repetition has only one of'
|
||||||
|
|
@ -1601,7 +1595,7 @@ def read_point_list(
|
||||||
|
|
||||||
def write_point_list(
|
def write_point_list(
|
||||||
stream: IO[bytes],
|
stream: IO[bytes],
|
||||||
points: 'list[Sequence[int]] | NDArray',
|
points: list[Sequence[int]],
|
||||||
fast: bool = False,
|
fast: bool = False,
|
||||||
implicit_closed: bool = True
|
implicit_closed: bool = True
|
||||||
) -> int:
|
) -> int:
|
||||||
|
|
@ -1624,8 +1618,6 @@ def write_point_list(
|
||||||
Number of bytes written.
|
Number of bytes written.
|
||||||
"""
|
"""
|
||||||
# If we're in a hurry, just write the points as arbitrary Deltas
|
# If we're in a hurry, just write the points as arbitrary Deltas
|
||||||
if _USE_NUMPY:
|
|
||||||
points = numpy.asarray(points, dtype=int)
|
|
||||||
if fast:
|
if fast:
|
||||||
size = write_uint(stream, 4)
|
size = write_uint(stream, 4)
|
||||||
size += write_uint(stream, len(points))
|
size += write_uint(stream, len(points))
|
||||||
|
|
|
||||||
|
|
@ -1434,7 +1434,7 @@ class Placement(Record):
|
||||||
size += self.name.write(stream) # type: ignore
|
size += self.name.write(stream) # type: ignore
|
||||||
if mm:
|
if mm:
|
||||||
size += write_real(stream, self.magnification) # type: ignore
|
size += write_real(stream, self.magnification) # type: ignore
|
||||||
if aq:
|
if aa:
|
||||||
size += write_real(stream, self.angle) # type: ignore
|
size += write_real(stream, self.angle) # type: ignore
|
||||||
if xx:
|
if xx:
|
||||||
size += write_sint(stream, self.x) # type: ignore
|
size += write_sint(stream, self.x) # type: ignore
|
||||||
|
|
@ -1717,8 +1717,8 @@ class Polygon(Record, GeometryMixin):
|
||||||
repetition: repetition_t | None
|
repetition: repetition_t | None
|
||||||
point_list: point_list_t | None
|
point_list: point_list_t | None
|
||||||
"""
|
"""
|
||||||
List of offsets between consecutive vertices, starting from the initial
|
List of offsets from the initial vertex (x, y) to the remaining
|
||||||
vertex (x, y): `[[dx0, dy0], [dx1, dy1], ...]`.
|
vertices, `[[dx0, dy0], [dx1, dy1], ...]`.
|
||||||
The list is an implicitly closed path, vertices are [int, int].
|
The list is an implicitly closed path, vertices are [int, int].
|
||||||
The initial vertex is located at (x, y) and is not represented in `point_list`.
|
The initial vertex is located at (x, y) and is not represented in `point_list`.
|
||||||
`None` means reuse modal.
|
`None` means reuse modal.
|
||||||
|
|
@ -1744,7 +1744,7 @@ class Polygon(Record, GeometryMixin):
|
||||||
self.point_list = point_list
|
self.point_list = point_list
|
||||||
self.properties = [] if properties is None else properties
|
self.properties = [] if properties is None else properties
|
||||||
|
|
||||||
if point_list is not None and len(point_list) < 2:
|
if point_list is not None and len(point_list) < 3:
|
||||||
warn('Polygon with < 3 points', stacklevel=2)
|
warn('Polygon with < 3 points', stacklevel=2)
|
||||||
|
|
||||||
def get_point_list(self) -> point_list_t:
|
def get_point_list(self) -> point_list_t:
|
||||||
|
|
@ -1827,8 +1827,8 @@ class Path(Record, GeometryMixin):
|
||||||
repetition: repetition_t | None = None
|
repetition: repetition_t | None = None
|
||||||
point_list: point_list_t | None = None
|
point_list: point_list_t | None = None
|
||||||
"""
|
"""
|
||||||
List of offsets between consecutive vertices, starting from the initial
|
List of offsets from the initial vertex (x, y) to the remaining vertices,
|
||||||
vertex (x, y): `[[dx0, dy0], [dx1, dy1], ...]`.
|
`[[dx0, dy0], [dx1, dy1], ...]`.
|
||||||
The initial vertex is located at (x, y) and is not represented in `point_list`.
|
The initial vertex is located at (x, y) and is not represented in `point_list`.
|
||||||
Offsets are [int, int]; `None` means reuse modal.
|
Offsets are [int, int]; `None` means reuse modal.
|
||||||
"""
|
"""
|
||||||
|
|
@ -1960,7 +1960,7 @@ class Path(Record, GeometryMixin):
|
||||||
dd = self.datatype is not None
|
dd = self.datatype is not None
|
||||||
ll = self.layer is not None
|
ll = self.layer is not None
|
||||||
|
|
||||||
size = write_uint(stream, 22)
|
size = write_uint(stream, 21)
|
||||||
size += write_bool_byte(stream, (ee, ww, pp, xx, yy, rr, dd, ll))
|
size += write_bool_byte(stream, (ee, ww, pp, xx, yy, rr, dd, ll))
|
||||||
if ll:
|
if ll:
|
||||||
size += write_uint(stream, self.layer) # type: ignore
|
size += write_uint(stream, self.layer) # type: ignore
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,15 @@ keywords = [
|
||||||
]
|
]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Development Status :: 4 - Beta",
|
"Development Status :: 3 - Alpha",
|
||||||
|
"Environment :: Other Environment",
|
||||||
"Intended Audience :: Developers",
|
"Intended Audience :: Developers",
|
||||||
"Intended Audience :: Information Technology",
|
"Intended Audience :: Information Technology",
|
||||||
"Intended Audience :: Manufacturing",
|
"Intended Audience :: Manufacturing",
|
||||||
"Intended Audience :: Science/Research",
|
"Intended Audience :: Science/Research",
|
||||||
"License :: OSI Approved :: GNU Affero General Public License v3",
|
"License :: OSI Approved :: GNU Affero General Public License v3",
|
||||||
|
"Topic :: Scientific/Engineering",
|
||||||
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
||||||
"Topic :: File Formats",
|
|
||||||
]
|
]
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue