Code Monkey home page Code Monkey logo

pyclipper's Introduction

CI Build Status Coverage Status PyPI Join the chat at https://gitter.im/fonttools-dev/Lobby

What is this?

fontTools is a library for manipulating fonts, written in Python. The project includes the TTX tool, that can convert TrueType and OpenType fonts to and from an XML text format, which is also called TTX. It supports TrueType, OpenType, AFM and to an extent Type 1 and some Mac-specific formats. The project has an MIT open-source licence.
Among other things this means you can use it free of charge.

User documentation and developer documentation are available at Read the Docs.

Installation

FontTools requires Python 3.8 or later. We try to follow the same schedule of minimum Python version support as NumPy (see NEP 29).

The package is listed in the Python Package Index (PyPI), so you can install it with pip:

pip install fonttools

If you would like to contribute to its development, you can clone the repository from GitHub, install the package in 'editable' mode and modify the source code in place. We recommend creating a virtual environment, using virtualenv or Python 3 venv module.

# download the source code to 'fonttools' folder
git clone https://github.com/fonttools/fonttools.git
cd fonttools

# create new virtual environment called e.g. 'fonttools-venv', or anything you like
python -m virtualenv fonttools-venv

# source the `activate` shell script to enter the environment (Unix-like); to exit, just type `deactivate`
. fonttools-venv/bin/activate

# to activate the virtual environment in Windows `cmd.exe`, do
fonttools-venv\Scripts\activate.bat

# install in 'editable' mode
pip install -e .

Optional Requirements

The fontTools package currently has no (required) external dependencies besides the modules included in the Python Standard Library. However, a few extra dependencies are required by some of its modules, which are needed to unlock optional features. The fonttools PyPI distribution also supports so-called "extras", i.e. a set of keywords that describe a group of additional dependencies, which can be used when installing via pip, or when specifying a requirement. For example:

pip install fonttools[ufo,lxml,woff,unicode]

This command will install fonttools, as well as the optional dependencies that are required to unlock the extra features named "ufo", etc.

  • Lib/fontTools/misc/etree.py

    The module exports a ElementTree-like API for reading/writing XML files, and allows to use as the backend either the built-in xml.etree module or lxml. The latter is preferred whenever present, as it is generally faster and more secure.

    Extra: lxml

  • Lib/fontTools/ufoLib

    Package for reading and writing UFO source files; it requires:

    • fs: (aka pyfilesystem2) filesystem abstraction layer.
    • enum34: backport for the built-in enum module (only required on Python < 3.4).

    Extra: ufo

  • Lib/fontTools/ttLib/woff2.py

    Module to compress/decompress WOFF 2.0 web fonts; it requires:

    • brotli: Python bindings of the Brotli compression library.

    Extra: woff

  • Lib/fontTools/ttLib/sfnt.py

    To better compress WOFF 1.0 web fonts, the following module can be used instead of the built-in zlib library:

    • zopfli: Python bindings of the Zopfli compression library.

    Extra: woff

  • Lib/fontTools/unicode.py

    To display the Unicode character names when dumping the cmap table with ttx we use the unicodedata module in the Standard Library. The version included in there varies between different Python versions. To use the latest available data, you can install:

    • unicodedata2: unicodedata backport for Python 3.x updated to the latest Unicode version 15.0.

    Extra: unicode

  • Lib/fontTools/varLib/interpolatable.py

    Module for finding wrong contour/component order between different masters. It requires one of the following packages in order to solve the so-called "minimum weight perfect matching problem in bipartite graphs", or the Assignment problem:

    • scipy: the Scientific Library for Python, which internally uses NumPy arrays and hence is very fast;
    • munkres: a pure-Python module that implements the Hungarian or Kuhn-Munkres algorithm.

    To plot the results to a PDF or HTML format, you also need to install:

    • pycairo: Python bindings for the Cairo graphics library. Note that wheels are currently only available for Windows, for other platforms see pycairo's installation instructions.

    Extra: interpolatable

  • Lib/fontTools/varLib/plot.py

    Module for visualizing DesignSpaceDocument and resulting VariationModel.

    Extra: plot

  • Lib/fontTools/misc/symfont.py

    Advanced module for symbolic font statistics analysis; it requires:

    • sympy: the Python library for symbolic mathematics.

    Extra: symfont

  • Lib/fontTools/t1Lib.py

    To get the file creator and type of Macintosh PostScript Type 1 fonts on Python 3 you need to install the following module, as the old MacOS module is no longer included in Mac Python:

    • xattr: Python wrapper for extended filesystem attributes (macOS platform only).

    Extra: type1

  • Lib/fontTools/ttLib/removeOverlaps.py

    Simplify TrueType glyphs by merging overlapping contours and components.

    • skia-pathops: Python bindings for the Skia library's PathOps module, performing boolean operations on paths (union, intersection, etc.).

    Extra: pathops

  • Lib/fontTools/pens/cocoaPen.py and Lib/fontTools/pens/quartzPen.py

    Pens for drawing glyphs with Cocoa NSBezierPath or CGPath require:

    • PyObjC: the bridge between Python and the Objective-C runtime (macOS platform only).
  • Lib/fontTools/pens/qtPen.py

    Pen for drawing glyphs with Qt's QPainterPath, requires:

    • PyQt5: Python bindings for the Qt cross platform UI and application toolkit.
  • Lib/fontTools/pens/reportLabPen.py

    Pen to drawing glyphs as PNG images, requires:

    • reportlab: Python toolkit for generating PDFs and graphics.
  • Lib/fontTools/pens/freetypePen.py

    Pen to drawing glyphs with FreeType as raster images, requires:

    • freetype-py: Python binding for the FreeType library.
  • Lib/fontTools/ttLib/tables/otBase.py

    Use the Harfbuzz library to serialize GPOS/GSUB using hb_repack method, requires:

    • uharfbuzz: Streamlined Cython bindings for the harfbuzz shaping engine

    Extra: repacker

How to make a new release

  1. Update NEWS.rst with all the changes since the last release. Write a changelog entry for each PR, with one or two short sentences summarizing it, as well as links to the PR and relevant issues addressed by the PR. Do not put a new title, the next command will do it for you.
  2. Use semantic versioning to decide whether the new release will be a 'major', 'minor' or 'patch' release. It's usually one of the latter two, depending on whether new backward compatible APIs were added, or simply some bugs were fixed.
  3. From inside a venv, first do pip install -r dev-requirements.txt, then run the python setup.py release command from the tip of the main branch. By default this bumps the third or 'patch' digit only, unless you pass --major or --minor to bump respectively the first or second digit. This bumps the package version string, extracts the changes since the latest version from NEWS.rst, and uses that text to create an annotated git tag (or a signed git tag if you pass the --sign option and your git and Github account are configured for signing commits using a GPG key). It also commits an additional version bump which opens the main branch for the subsequent developmental cycle
  4. Push both the tag and commit to the upstream repository, by running the command git push --follow-tags. Note: it may push other local tags as well, be careful.
  5. Let the CI build the wheel and source distribution packages and verify both get uploaded to the Python Package Index (PyPI).
  6. [Optional] Go to fonttools Github Releases page and create a new release, copy-pasting the content of the git tag message. This way, the release notes are nicely formatted as markdown, and users watching the repo will get an email notification. One day we shall automate that too.

Acknowledgements

In alphabetical order:

aschmitz, Olivier Berten, Samyak Bhuta, Erik van Blokland, Petr van Blokland, Jelle Bosma, Sascha Brawer, Tom Byrer, Antonio Cavedoni, Frédéric Coiffier, Vincent Connare, David Corbett, Simon Cozens, Dave Crossland, Simon Daniels, Peter Dekkers, Behdad Esfahbod, Behnam Esfahbod, Hannes Famira, Sam Fishman, Matt Fontaine, Takaaki Fuji, Rob Hagemans, Yannis Haralambous, Greg Hitchcock, Jeremie Hornus, Khaled Hosny, John Hudson, Denis Moyogo Jacquerye, Jack Jansen, Tom Kacvinsky, Jens Kutilek, Antoine Leca, Werner Lemberg, Tal Leming, Peter Lofting, Cosimo Lupo, Olli Meier, Masaya Nakamura, Dave Opstad, Laurence Penney, Roozbeh Pournader, Garret Rieger, Read Roberts, Colin Rofls, Guido van Rossum, Just van Rossum, Andreas Seidel, Georg Seifert, Chris Simpkins, Miguel Sousa, Adam Twardoch, Adrien Tétar, Vitaly Volkov, Paul Wise.

Copyrights

Copyright (c) 1999-2004 Just van Rossum, LettError ([email protected])
See LICENSE for the full license.

Copyright (c) 2000 BeOpen.com. All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved.

Have fun!

pyclipper's People

Contributors

anthrotype avatar arthurzam avatar athos-ribeiro avatar feuermurmel avatar greginvm avatar jamiebull1 avatar jessecrocker avatar pgajdos avatar revarbat avatar rubo3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyclipper's Issues

Add support to release aarch64 wheels

Problem

On aarch64, pip install pyclipper builds the wheels from source code and then install it. It requires user to have development environment installed on his system. also, it take some time to build the wheels than downloading and extracting the wheels from pypi.

Resolution

On aarch64, pip install pyclipper should download the wheels from pypi

@anthrotype, Please let me know your interest on releasing aarch64 wheels. I can help in this.

Offset needs to be scaled?

It seems that when trying to execute an offset, you need to scale the value according to the scale of the coordinates (the original, before calling scale_to_clipper())

I have a set of coordinates that look like this:

(0.02196335606276989, 0.025453664362430573), 
(0.021962668746709824, 0.02545437589287758), 
(0.021961797028779984, 0.025455275550484657)

Passing -7.0 to PyclipperOffset as the docs suggest doesn't affect the path at all. I have to use a rather large number instead:

solution = pco.Execute(1500.0 ** 2)

Not sure whether this is a bug or a detail that may have escaped me, but I couldn't find anything about scaling the offset on the docs. It seems the offset depends on the path size too? For larger paths (300 meters in scale) I had to use 5000 ** 3 before seeing any change.

Large coordinates are not returned exactly, because of conversion to floats

I've noticed that the coordinates of the paths returned by pyclipper.Execute() are represented using floats. This introduces some inaccuracies for very large coordinate values as not all values of an int64_t can be represented by a double. I've added a test case here showing the problem:

https://github.com/Feuermurmel/pyclipper/tree/inexact-coordinates

I see that the library supports automatic scaling of coordinate values by setting the global pyclipper.SCALING_FACTOR. This of course means that, unless this variable is set to 1, a type other than int is necessary to represent coordinates. Thus I'm not sure what the best way is to solve this problem. I currently see the following options:

– Remove pyclipper.SCALING_FACTOR, but there are probably some people using it.
– Only use floats when pyclipper.SCALING_FACTOR is not set to 1. Seems a bit hack-ish.
– Add a second implementation of pyclipper.Pyclipper which ignores the scaling factor and uses ints instead. This seems obscure and bloats the library.

Releasing GIL While Processing

If you could release the Global Interpreter Lock while doing more CPU intensive calls to ClipperLib (union, difference, intersection, minkowski, offset, etc), it would allow Python apps to parallelize much better when using threading. I wrote a 3D printing slicer program in Python called Mandoline-Py ( https://github.com/revarbat/mandoline-py ), and ran headlong into the performance limitations of the GIL.

As best as I can tell, this should be just a matter of surrounding the CPU intensive code with Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. (See https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock )

TypeError: 'filter' object is not subscriptable

I try to install this in Arch Linux, failed.

This is the part log:

Development mode: Compiling Cython modules from .pyx sources.                                                                           
Traceback (most recent call last):                                                                                                      
  File "setup.py", line 96, in <module>                                                                                                 
    cmdclass=cmdclass,                                                                                                                  
  File "/usr/lib/python3.6/site-packages/setuptools/__init__.py", line 129, in setup                                                    
    return distutils.core.setup(**attrs)                                                                                                
  File "/usr/lib/python3.6/distutils/core.py", line 108, in setup                                                                       
    _setup_distribution = dist = klass(attrs)                                                                                           
  File "/usr/lib/python3.6/site-packages/setuptools/dist.py", line 370, in __init__                                                     
    k: v for k, v in attrs.items()                                                                                                      
  File "/usr/lib/python3.6/distutils/dist.py", line 281, in __init__                                                                    
    self.finalize_options()
  File "/usr/lib/python3.6/site-packages/setuptools/dist.py", line 529, in finalize_options                                            
    ep.load()(self, ep.name, value)
  File "/home/acgtyrant/.cache/aurman/python-pyclipper/src/pyclipper-1.1.0/.eggs/setuptools_scm-3.0.2-py3.6.egg/setuptools_scm/integration.py", line 23, in version_keyword
    dist.metadata.version = get_version(**value)
  File "/home/acgtyrant/.cache/aurman/python-pyclipper/src/pyclipper-1.1.0/.eggs/setuptools_scm-3.0.2-py3.6.egg/setuptools_scm/__init__.py", line 135, in get_version
    parsed_version = _do_parse(config)
  File "/home/acgtyrant/.cache/aurman/python-pyclipper/src/pyclipper-1.1.0/.eggs/setuptools_scm-3.0.2-py3.6.egg/setuptools_scm/__init__.py", line 88, in _do_parse
    config, "setuptools_scm.parse_scm"
  File "/home/acgtyrant/.cache/aurman/python-pyclipper/src/pyclipper-1.1.0/.eggs/setuptools_scm-3.0.2-py3.6.egg/setuptools_scm/__init__.py", line 45, in _version_from_entrypoint
    version = _call_entrypoint_fn(config, ep.load())
  File "/home/acgtyrant/.cache/aurman/python-pyclipper/src/pyclipper-1.1.0/.eggs/setuptools_scm-3.0.2-py3.6.egg/setuptools_scm/__init__.py", line 40, in _call_entrypoint_fn
    return fn(config.absolute_root)
  File "/home/acgtyrant/.cache/aurman/python-pyclipper/src/pyclipper-1.1.0/.eggs/setuptools_scm_git_archive-1.0-py3.6.egg/setuptools_scm_git_archive/__init__.py", line 21, in parse
    return archival_to_version(data)
  File "/home/acgtyrant/.cache/aurman/python-pyclipper/src/pyclipper-1.1.0/.eggs/setuptools_scm_git_archive-1.0-py3.6.egg/setuptools_scm_git_archive/__init__.py", line 15, in archival_to_version
    return meta(versions[0])
TypeError: 'filter' object is not subscriptable
==> ERROR: A failure occurred in build().
    Aborting...
2018-07-27 17:35:44,380 - wrappers - makepkg - ERROR - makepkg query ['makepkg', '-cf', '--noconfirm'] failed in directory /home/acgtyrant/.cache/aurman/python-pyclipper

deployment to github releases from appveyor fails

The upload of the generated wheels to Github Releases requires that the admin of this repo, @greginvm, updates the auth_token field in the .appveyor.yml file with his Github API key, as explained in the inline comments in that file.

I am only a collaborator so I can push tags, but can't generate a new API token, nor I can encrypt it using the Appveyor account that is linked to this repo (that also needs @greginvm privileges).

I am thinking that maybe it's not worth keeping this "upload to github" feature. We simply need the wheels to be uploaded to PyPI, where pip can download them from. Having them on Github is a bonus but not really required.

So if we agree, I can set up Appveyor and Travis to upload the wheels directly to PyPI using my own PyPI credentials (i have access to the pyclipper PyPI account so it should work).

1.1.0.post2 fails to build: LookupError: setuptools-scm was unable to detect version for '/var/tmp/portage/dev-python/pyclipper-1.1.0_p2/work/pyclipper-1.1.0.post2'.

I get this error:
python2.7 setup.py build
Development mode: Compiling Cython modules from .pyx sources.
Traceback (most recent call last):
File "setup.py", line 97, in
cmdclass=cmdclass,
File "/usr/lib64/python2.7/site-packages/setuptools/init.py", line 143, in setup
return distutils.core.setup(**attrs)
File "/usr/lib64/python2.7/distutils/core.py", line 111, in setup
_setup_distribution = dist = klass(attrs)
File "/usr/lib64/python2.7/site-packages/setuptools/dist.py", line 442, in init
k: v for k, v in attrs.items()
File "/usr/lib64/python2.7/distutils/dist.py", line 287, in init
self.finalize_options()
File "/usr/lib64/python2.7/site-packages/setuptools/dist.py", line 601, in finalize_options
ep.load()(self, ep.name, value)
File "/usr/lib64/python2.7/site-packages/setuptools_scm/integration.py", line 23, in version_keyword
dist.metadata.version = get_version(**value)
File "/usr/lib64/python2.7/site-packages/setuptools_scm/init.py", line 144, in get_version
parsed_version = _do_parse(config)
File "/usr/lib64/python2.7/site-packages/setuptools_scm/init.py", line 111, in _do_parse
"use git+https://github.com/user/proj.git#egg=proj" % config.absolute_root
LookupError: setuptools-scm was unable to detect version for '/var/tmp/portage/dev-python/pyclipper-1.1.0_p2/work/pyclipper-1.1.0.post2'.

Make sure you're either building from a fully intact git repository or PyPI tarballs. Most other sources (such as GitHub's tarballs, a git checkout without the .git folder) don't contain the necessary metadata and will not work.

Thanks

Docker image isn't working for poweron -ppc64le

I am par of IBM team and working on power support for this package and faced the below issue during build

latest: Pulling from pypa/manylinux1_x86_64
7d0d9526f38a: Pulling fs layer
91fad6b78bdb: Pulling fs layer
23ba7405f2ac: Pulling fs layer
de2b88ef949b: Pulling fs layer
de2b88ef949b: Waiting
91fad6b78bdb: Download complete
23ba7405f2ac: Verifying Checksum
23ba7405f2ac: Download complete
7d0d9526f38a: Verifying Checksum
7d0d9526f38a: Download complete
7d0d9526f38a: Pull complete
91fad6b78bdb: Pull complete
23ba7405f2ac: Pull complete
de2b88ef949b: Verifying Checksum
de2b88ef949b: Download complete
de2b88ef949b: Pull complete
Digest: sha256:4071e3b54d5aef04c415ac7629e8945af4b5bbc1d53ecf03636f5620e3260d5c
Status: Downloaded newer image for quay.io/pypa/manylinux1_x86_64:latest
standard_init_linux.go:211: exec user process caused "exec format error"

It looks the problem is with starting docker can you help with the below method (suggestions) for power on support to enable

1- The images for ppc64le can be built and pushed manually by doing native builds on ppc64le VMs available via OSU, OSL https://osuosl.org/services/powerdev/request_hosting/ (do let me know if you choose to go via that path and I can share more specific details). Once the Power images are published, multiarch manifests can be used https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/ to ensure support across different architectures, this would need to be created and published as well.
2- The process can be automated via travis-ci using multi-stage travis builds as shown here https://www.youtube.com/watch?v=_PbpRETbpow
3- not ideal from a performance perspective, but we can do cross-builds using docker buildx.

Pls tag @seth-priya and me for further clarification.

Windows: Dependency on msvcp140.dll intentional?

I wasted an hour yesterday trying to track down why pyclipper (installed from PyPI) wouldn't import on a freshly installed Windows 10 PC with Python 3. Turns out the above mentioned DLL was not found (which the ImportError didn't tell me...). I was wondering if the dependency is strictly necessary?

Failure to scale - TypeError: 'Zero' object is not iterable

Cross-posted from Stack Overflow.

Thanks for the library - it looks like exactly what we need for working with geometry in eppy.

However I've just come up against a TypeError I've not seen before and can't figure out why it's occurring. Googling for the error TypeError: 'Zero' object is not iterable returns no results. I've tested in python 2.7 and 3.5 and the error is the same in both cases.

The error comes up when I have a list of vertices which used to be part of a SymPy Polygon object, though as far as I can see the lists are identical and the assert statement in the MCVE passes.

Here's the MCVE:

from sympy.geometry.polygon import Polygon
import pyclipper as pc

start_list = [(0, 2), (2, 2), (2, 0), (0, 0)]
scaled = pc.scale_to_clipper(start_list)  # this works fine

as_poly = Polygon(*start_list)
new_list = [(pt.x, pt.y) for pt in as_poly.vertices]
assert new_list == start_list  # check that the lists are the same

fail_to_scale = pc.scale_to_clipper(new_list)  # this fails

And the traceback:

Traceback (most recent call last):
  File "C:\Users\Jamie\<blah>\mcve.py", line 10, in <module>
    fails = pc.scale_to_clipper(new_list)
  File "pyclipper/pyclipper.pyx", line 544, in pyclipper.scale_to_clipper (pyclipper/pyclipper.cpp:3535)
  File "pyclipper/pyclipper.pyx", line 542, in pyclipper.scale_to_clipper.scale_value (pyclipper/pyclipper.cpp:3454)
  File "pyclipper/pyclipper.pyx", line 542, in pyclipper.scale_to_clipper.scale_value (pyclipper/pyclipper.cpp:3454)
  File "pyclipper/pyclipper.pyx", line 542, in pyclipper.scale_to_clipper.scale_value (pyclipper/pyclipper.cpp:3416)
TypeError: 'Zero' object is not iterable

Any idea what the source of and solution to this error could be?

New Clipper version (6.4.2)

Hello,

I am preparing this package to include it in Project Fedora repositories. I would like to know if you are willing to update Clipper to the latest version here (I patched the project to use system libraries and will provide an option for that if you would like it).

Importing pyclipper throws module not found error

I am unable to import pyclipper after installing it using pip (and pip3). This first showed up while trying to install the K40 Whisprer tool on a raspberry pi, but I am also seeing it on my Windows desktop. Thank you in advance for your help.

Here is the output from pip that shows a successful install of pyclipper 1.1.0.
pip3 install pyclipper
Collecting pyclipper
Downloading https://files.pythonhosted.org/packages/8f/70/b1e5d149c3cda6e52f112733b81c90d5827353915028b25a47a73815cc08/pyclipper-1.1.0.post3-cp37-cp37m-win32.whl (92kB)
100% |████████████████████████████████| 102kB 1.4MB/s
Installing collected packages: pyclipper
Successfully installed pyclipper-1.1.0.post3

Here is the output from the interactive python exe showing only an import.
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
import pyclipper
Traceback (most recent call last):
File "", line 1, in
ModuleNotFoundError: No module named 'pyclipper'

"IndexError: list index out of range" when using negative offset

When I use a negative offset of say 2 meter in a polygon square that is 2m2 (a small square), an "IndexError: list index out of range" error comes up. Ofcourse I would expect an error message in this situation. However, this invalid input offset is not properly handled.

The code that I use:

import pyclipper

negative_offset = -2
coordinates = # Small polygon of around 2m2
clipper_offset = pyclipper.PyclipperOffset()
coordinates_scaled = pyclipper.scale_to_clipper(coordinates)

clipper_offset.AddPath(coordinates_scaled, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)

new_coordinates = clipper_offset.Execute(pyclipper.scale_to_clipper(negative_offset))

new_coordinates_scaled = pyclipper.scale_from_clipper(new_coordinates)

XOR branching/non-manifold result?

Hi,
Intersection, Union, and Difference work just fine, but I am having a hard time figuring out how I should read the output of a simple XOR clip as below. When I try to build a set of polycurves from the output results, my graphics library complains that the points form a branching/non-manifold result. Any help on how to correctly transform the data to a set of closed simple polygons would be appreciated.

import pyclipper

subj = (
((180, 200), (260, 200), (260, 150), (180, 150)),
((215, 160), (230, 190), (200, 190))
)
clip = ((190, 210), (240, 210), (240, 130), (190, 130))

pc = pyclipper.Pyclipper()
pc.AddPath(clip, pyclipper.PT_CLIP, True)
pc.AddPaths(subj, pyclipper.PT_SUBJECT, True)

solution = pc.Execute(pyclipper.CT_XOR, pyclipper.PFT_EVENODD, pyclipper.PFT_EVENODD)

Exceptions aren't translated to Python

For example, playing in the REPL I forgot to close a path:

>>> pco = pyclipper.PyclipperOffset()
>>> pc.AddPath([[0,0], [10,0], [10,10], [0, 10]], pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)
terminate called after throwing an instance of 'ClipperLib::clipperException'
  what():  AddPath: Open paths must be subject.
Aborted (core dumped)

pre-compiled wheels on PyPI?

Hi @greginvm,

Thanks for the great package. I was wondering if you would be interested in setting up Travis and Appveyor CI to build wheel packages to be deployed on PyPI, alongside the current source distribution.

Being written in cython, the library is very portable and can be easily compiled on all platforms. However, a lot of users (especially Windows and Mac users) do not have easy access to a C++ compiler. It would be nice if they could just pip install pyclipper or if other higher-level libraries could simply specify pyclipper as a dependency, without worring about the dreaded Unable to find vcvarsall.bat error ;)

I can work on a pull request, but first wanted to check with you.
Thanks,

Cosimo

build and upload wheels for python 3.7

we need to update the CI config files to also run tests and build wheels on python 3.7.
The multibuild tools we use already support 3.7 for all linux, macos and windows (the latter via a powershell install.ps1 script, since Appveyor VMs haven't been updated to ship python 3.7 by default yet).

clockwise path orientation is inverted when doing union

Hello,

I noticed that if a polygon has clockwise orientation and is "black" (not a hole nested inside another polygon), after it is sent through a union operation, it returns with the orientation flipped to counter-clockwise.

import pyclipper

pc = pyclipper.Pyclipper()
# polygon has clockwise orientation
pc.AddPath(((194, 510), (322, 0), (66, 0)), pyclipper.PT_SUBJECT)
solution = pc.Execute(pyclipper.CT_UNION)

print(solution)
# returned polygon has counter-clockwise orientation
# [[[194, 510], [66, 0], [322, 0]]]

# same result here
print(pyclipper.SimplifyPolygon(((194, 510), (322, 0), (66, 0))))

The example above only has one subject path so does nothing, but it's enough to show the problem.
It looks like clipper "normalizes" the orientation to counter-clockwise for such polygons.
Is this the way it's supposed to be?

Most users probably won't care since it doesn't change the appearance of the resulting polygon (it's filled in both cases), but in the context of font editing software where some glyphs (letterforms) can be reused as "components" or references inside other glyphs, then the path orientation matters. Because, when two components overlap with each other, it's the path orientation of the "base" glyphs that determines the way such "composite" glyphs will be rendered (e.g. a single black shape, or with cuts and holes).

Could IDE be supported better?

well, this module can't work well with Pycharm. Excuse my poor English. Methods of Class can't jump out automatically.

Use semantic versioning for release tags

Could pyclipper tag its future releases according to semantic versioning? For example, the last release was tagged as 1.1.0.post3 which isn’t quite according to the spec; see test page. It’s certainly not the end of the world to ignore semver.org, but some Linux distributions actually assume that projects follow semantic versioning. Maybe pyclipper could simply tag its future releases as major.minor.patch?

Is it possible to split a polyhedron by a plane?

I want to split a parent convex polyhedron (3D) using a plane (2D) into 2 child closed convex polyhedrons. Is it possible to do it with pyclipper?

Note: It is not an issue but a question regarding capabilities of the library.

Clipping polygons that are entirely contained in another polygon

When I try to do this clipping, I get just the small rectangle.
The orange is pc.AddPath(geometry, pyclipper.PT_SUBJECT, True)
In red is pc.AddPath(rectangle, pyclipper.PT_CLIP, True)
Then the result is from this. I'm not sure what exactly is causing this issue.
pc.Execute(pyclipper.CT_DIFFERENCE)
toClip
result

Build fails on Python 2.7 due to setuptools 45

When using python 2.7 for instillation both via pip as well as from source the build fails due to a syntax error from /tmp/easy_install-aGfdOC/setuptools_scm-6.3.2/setup.py. When installing with pip3, pyclipper installs and builds without issue.

Screen Shot 2021-10-15 at 9 27 46 AM

.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.