Skip to content

Commit 1f8081e

Browse files
authored
Merge branch 'main' into main
2 parents f17adb7 + 5284523 commit 1f8081e

File tree

20 files changed

+502
-236
lines changed

20 files changed

+502
-236
lines changed

.github/workflows/build.yml

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,16 @@ on:
99
- main
1010

1111
jobs:
12-
build-packages:
12+
build:
13+
if: "!contains(github.event.pull_request.labels.*.name, 'docs-only')"
1314
runs-on: ${{ matrix.os }}
1415
strategy:
1516
matrix:
1617
os: [ubuntu-latest, macos-latest, windows-latest]
17-
python-version: ['3.7', '3.8', '3.9', '3.10']
18+
python: ['3.7', '3.8', '3.9', '3.10']
1819

1920
steps:
20-
- uses: actions/checkout@v2
21-
22-
- name: Set up Python ${{ matrix.python-version }}
23-
uses: actions/setup-python@v2
24-
with:
25-
python-version: ${{ matrix.python-version }}
26-
27-
- uses: compas-dev/[email protected]
21+
- uses: compas-dev/compas-actions.build@v3
2822
with:
29-
test_lint: true
30-
test_compas: true
23+
python: ${{ matrix.python }}
24+
invoke_lint: true

.github/workflows/docs.yml

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,53 +11,9 @@ on:
1111
- main
1212

1313
jobs:
14-
build:
15-
name: build and deploy docs
14+
docs:
1615
runs-on: ubuntu-latest
1716
steps:
18-
- uses: actions/checkout@v2
19-
20-
- uses: compas-dev/[email protected]
21-
id: docs
22-
with:
23-
dest: deploy
24-
build_to_subfolder: true
25-
test_docs: true
26-
27-
- name: Deploy docs
28-
if: success() && steps.docs.outputs.commit_type != 'pull'
29-
uses: crazy-max/ghaction-github-pages@v2
30-
with:
31-
target_branch: gh-pages
32-
build_dir: deploy
33-
keep_history: true
34-
env:
35-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36-
37-
outputs:
38-
commit_type: ${{ steps.docs.outputs.commit_type }}
39-
current_version: ${{ steps.docs.outputs.current_version }}
40-
41-
docVersions:
42-
needs: build
43-
if: needs.build.outputs.commit_type == 'tag'
44-
name: update doc versions
45-
runs-on: ubuntu-latest
46-
steps:
47-
- uses: actions/checkout@v2
48-
with:
49-
ref: gh-pages
50-
51-
- uses: compas-dev/[email protected]
52-
with:
53-
current_version: ${{ needs.build.outputs.current_version }}
54-
55-
- name: Deploy docs
56-
if: success()
57-
uses: crazy-max/ghaction-github-pages@v2
17+
- uses: compas-dev/compas-actions.docs@v2
5818
with:
59-
target_branch: gh-pages
60-
build_dir: ./
61-
keep_history: false
62-
env:
63-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
github_token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

Lines changed: 21 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,33 @@
11
on:
22
push:
3-
# Sequence of patterns matched against refs/tags
43
tags:
5-
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
4+
- 'v*'
65

76
name: Create Release
87

98
jobs:
109
build:
11-
name: Create Release
12-
runs-on: windows-latest
13-
steps:
14-
- name: Get version from tag
15-
id: tag_name
16-
run: |
17-
echo ::set-output name=current_version::${GITHUB_REF#refs/tags/v}
18-
shell: bash
19-
20-
- name: Checkout code
21-
uses: actions/checkout@v2
22-
23-
- name: Get Changelog Entry
24-
id: changelog_reader
25-
uses: mindsers/changelog-reader-action@v2
26-
with:
27-
version: ${{ steps.tag_name.outputs.current_version }}
28-
path: ./CHANGELOG.md
29-
30-
- name: Create Release
31-
id: create_release
32-
uses: actions/create-release@v1
33-
env:
34-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35-
with:
36-
# This pulls from the "Get Changelog Entry" step above, referencing it's ID to get its outputs object.
37-
# See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
38-
tag_name: ${{ github.ref }}
39-
release_name: COMPAS ${{ steps.changelog_reader.outputs.version }}
40-
body: ${{ steps.changelog_reader.outputs.changes }}
41-
prerelease: ${{ steps.changelog_reader.outputs.status == 'prereleased' }}
42-
draft: ${{ steps.changelog_reader.outputs.status == 'unreleased' }}
43-
44-
- name: Set up Python 3.9
45-
uses: actions/setup-python@v2
46-
with:
47-
python-version: 3.9
10+
runs-on: ${{ matrix.os }}
11+
strategy:
12+
matrix:
13+
os: [ubuntu-latest, macos-latest, windows-latest]
14+
python: ['3.8', '3.9', '3.10']
4815

49-
- uses: compas-dev/[email protected]
16+
steps:
17+
- uses: compas-dev/compas-actions.build@v3
5018
with:
51-
test_lint: true
52-
test_compas: true
53-
- uses: NuGet/[email protected]
54-
- name: Install dependencies
55-
run: |
56-
choco install ironpython --version=2.7.8.1
19+
python: ${{ matrix.python }}
20+
invoke_lint: true
21+
check_import: true
5722

58-
- name: 🦗 Build grasshopper components
59-
uses: compas-dev/compas-actions.ghpython_components@v2
23+
publish:
24+
needs: build
25+
runs-on: windows-latest
26+
steps:
27+
- uses: compas-dev/compas-actions.publish@v2
6028
with:
61-
source: src/compas_ghpython/components
62-
target: src/compas_ghpython/components/ghuser
63-
- name: 💃 Build release
64-
if: success() && startsWith(github.ref, 'refs/tags')
65-
run: |
66-
python setup.py clean --all sdist bdist_wheel
67-
- name: 📦 Publish release to PyPI
68-
if: success() && startsWith(github.ref, 'refs/tags')
69-
run: |
70-
twine check dist/*
71-
twine upload dist/* --skip-existing
72-
env:
73-
TWINE_USERNAME: __token__
74-
TWINE_PASSWORD: ${{ secrets.PYPI }}
29+
pypi_token: ${{ secrets.PYPI }}
30+
github_token: ${{ secrets.GITHUB_TOKEN }}
31+
build_ghpython_components: true
32+
gh_source: src/compas_ghpython/components
33+
gh_target: src/compas_ghpython/components/ghuser

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* Added conversion function `frame_to_rhino_plane` to `compas_rhino.conversions`.
1313
* Added `RhinoSurface.from_frame` to `compas_rhino.geometry`.
1414
* Added representation for trims with `compas.geometry.BrepTrim`.
15+
* Added `Arc` to `compas.geometry`.
16+
* Added `Arc` conversion functions to `compas_rhino.conversions`.
17+
* Added `from_sphere` alternative constructor to `RhinoBrep`.
18+
* Added support for singular trims to `RhinoBrep`.
1519

1620
### Changed
1721

1822
* Patched [CVE-2007-4559](https://github.com/advisories/GHSA-gw9q-c7gh-j9vm) vulnerability.
23+
* Updated workflows to v2.
24+
* Fixed attribute error in `compas_rhino.conversions.ellipse_to_compas`.
25+
* Changed deepcopy of `RhinoBrep` to use the native `Rhino.Geometry` mechanism.
26+
* The normal of the cutting plane is no longer flipped in `compas_rhino.geometry.RhinoBrep`.
27+
* Planar holes caused by `RhinoBrep.trim` are now automatically capped.
28+
* Fixed `Polygon` constructor to not modify the input list of points.
29+
* Fixed serialization of sphere and cylinder Breps in `RhinoBrep`.
30+
* Fixed serialization of some trimmed shapes in `RhinoBrep`.
1931

2032
### Removed
2133

src/compas/geometry/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
Ellipse
5959
Polygon
6060
NurbsSurface
61+
Arc
6162
6263
3-dimensional
6364
-------------
@@ -811,6 +812,7 @@
811812
Polyline,
812813
Quaternion,
813814
Vector,
815+
Arc,
814816
)
815817
from .shapes import ( # noqa: E402
816818
Shape,
@@ -1170,6 +1172,7 @@
11701172
"Geometry",
11711173
"Primitive",
11721174
"Bezier",
1175+
"Arc",
11731176
"Circle",
11741177
"Ellipse",
11751178
"Frame",

src/compas/geometry/primitives/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from .circle import Circle # noqa: F401
1616
from .ellipse import Ellipse # noqa: F401
1717
from .curve import Bezier # noqa: F401
18+
from .arc import Arc # noqa: F401
1819

1920

2021
__all__ = [name for name in dir() if not name.startswith("_")]
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import math
2+
3+
from compas.geometry import close
4+
from compas.geometry.primitives import Frame
5+
from compas.geometry.primitives import Primitive
6+
7+
8+
class Arc(Primitive):
9+
"""Represents a portion of a circle's arc.
10+
11+
Parameters
12+
----------
13+
frame : :class:`~compas.geometry.Frame`
14+
Coordinate frame at the center of the arc's circle.
15+
radius : float
16+
Radius of the arc's circle.
17+
end_angle : float
18+
The angle in radians of the end of this Arc.
19+
start_angle :
20+
The angle in radians of the start of this Arc.
21+
22+
Attributes
23+
----------
24+
length : float
25+
The length of the arc (radius * angle)
26+
angle : float
27+
The sweep angle in radians (between incrementing end angle and start angle).
28+
domain : tuple(float, float)
29+
A tuple containing the start and end angles of this arc, in radians.
30+
center : :class:`~compas.geometry.Point`
31+
The center point of the circle which coincides with this Arc.
32+
circumference : float
33+
The circumference of the circle which coincides with this Arc.
34+
diameter : float
35+
The diameter of the circle which coincides with this Arc.
36+
37+
"""
38+
39+
def __init__(self, frame=None, radius=None, end_angle=None, start_angle=None, **kwargs):
40+
super(Arc, self).__init__(**kwargs)
41+
42+
self._frame = frame
43+
self._radius = radius
44+
self._start_angle = start_angle if start_angle is not None else 0.0
45+
self._end_angle = end_angle
46+
47+
if self._radius is not None and self._end_angle is not None:
48+
self._verify()
49+
50+
@property
51+
def data(self):
52+
return {
53+
"frame": self._frame.data,
54+
"radius": self._radius,
55+
"start": self._start_angle,
56+
"end": self._end_angle,
57+
}
58+
59+
@data.setter
60+
def data(self, value):
61+
self._frame = Frame.from_data(value["frame"])
62+
self._radius = value["radius"]
63+
self._start_angle = value["start"]
64+
self._end_angle = value["end"]
65+
66+
@property
67+
def frame(self):
68+
return self._frame
69+
70+
@frame.setter
71+
def frame(self, value):
72+
self._frame = value
73+
74+
@property
75+
def radius(self):
76+
return self._radius
77+
78+
@radius.setter
79+
def radius(self, value):
80+
self._radius = value
81+
82+
@property
83+
def start_angle(self):
84+
return self._start_angle
85+
86+
@start_angle.setter
87+
def start_angle(self, value):
88+
self._start_angle = value
89+
self._verify()
90+
91+
@property
92+
def end_angle(self):
93+
return self._end_angle
94+
95+
@end_angle.setter
96+
def end_angle(self, value):
97+
self._end_angle = value
98+
self._verify
99+
100+
@property
101+
def length(self):
102+
return self.radius * self.angle
103+
104+
@property
105+
def angle(self):
106+
return self._end_angle - self._start_angle
107+
108+
@property
109+
def domain(self):
110+
return self._start_angle, self._end_angle
111+
112+
@property
113+
def center(self):
114+
return self.frame.point
115+
116+
@property
117+
def circumference(self):
118+
return 2.0 * math.pi * self.radius
119+
120+
@property
121+
def diameter(self):
122+
return 2.0 * self.radius
123+
124+
@property
125+
def is_circle(self):
126+
return close(abs(abs(self.angle) - 2.0 * math.pi), 0.0)
127+
128+
@classmethod
129+
def from_circle(cls, circle, start_angle, end_angle):
130+
"""Creates an Arc from a circle and start and end angles.
131+
132+
Parameters
133+
----------
134+
circle : :class:`~compas.geometry.Circle`
135+
The center point and radius of this circle will be used to create an Arc.
136+
start_angle : float
137+
The start angle in radians.
138+
end_angle : float
139+
The end angle in radians.
140+
141+
Returns
142+
-------
143+
:class:`~compas.geometry.Arc`
144+
145+
"""
146+
frame = Frame.worldXY()
147+
# TODO: take circle.frame once it has one
148+
frame.point = circle.center.copy()
149+
return cls(frame, circle.radius, end_angle, start_angle)
150+
151+
def _verify(self):
152+
if self.angle < 0.0 or self.angle > 2.0 * math.pi:
153+
raise ValueError("Sweep angle must satisfy 0 < angle < 2 * Pi. Currently:{}".format(self.angle))

0 commit comments

Comments
 (0)