Skip to content

Commit 197d747

Browse files
authored
Merge branch 'master' into pv/degenerate
2 parents d06706f + 83f9abd commit 197d747

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+3181
-2133
lines changed

.github/FUNDING.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# These are supported funding model platforms
2+
3+
github: [SimonDanisch]
4+
patreon: # Replace with a single Patreon username
5+
open_collective: simon-danisch
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
otechie: # Replace with a single Otechie username
12+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

.github/workflows/RegisterAction.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ on:
55
version:
66
description: Version to register or component to bump
77
required: true
8-
98
jobs:
109
register:
1110
runs-on: ubuntu-latest

.github/workflows/TagBot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ on:
44
types:
55
- created
66
workflow_dispatch:
7+
inputs:
8+
lookback:
9+
default: 3
10+
permissions:
11+
actions: read
12+
checks: read
13+
contents: write
14+
deployments: read
15+
issues: read
16+
discussions: read
17+
packages: read
18+
pages: read
19+
pull-requests: read
20+
repository-projects: read
21+
security-events: read
22+
statuses: read
723
jobs:
824
TagBot:
925
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'

.github/workflows/ci.yml

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
name: CI
22
on:
3-
- push
4-
- pull_request
3+
push:
4+
branches:
5+
- master
6+
tags: "*"
7+
pull_request:
8+
branches:
9+
- master
10+
- sd/simple-mesh
511
jobs:
612
test:
713
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
@@ -10,9 +16,8 @@ jobs:
1016
fail-fast: false
1117
matrix:
1218
version:
13-
- '1.3'
14-
- '1'
15-
- 'nightly'
19+
- "1.6"
20+
- "1"
1621
os:
1722
- ubuntu-latest
1823
- macOS-latest
@@ -25,16 +30,7 @@ jobs:
2530
with:
2631
version: ${{ matrix.version }}
2732
arch: ${{ matrix.arch }}
28-
- uses: actions/cache@v1
29-
env:
30-
cache-name: cache-artifacts
31-
with:
32-
path: ~/.julia/artifacts
33-
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
34-
restore-keys: |
35-
${{ runner.os }}-test-${{ env.cache-name }}-
36-
${{ runner.os }}-test-
37-
${{ runner.os }}-
33+
- uses: julia-actions/cache@v2
3834
- uses: julia-actions/julia-buildpkg@v1
3935
- uses: julia-actions/julia-runtest@v1
4036
- uses: julia-actions/julia-processcoverage@v1
@@ -43,26 +39,23 @@ jobs:
4339
file: lcov.info
4440
docs:
4541
name: Documentation
46-
runs-on: ubuntu-latest
42+
runs-on: ubuntu-20.04
4743
env:
4844
JULIA_PKG_SERVER: ""
4945
steps:
5046
- uses: actions/checkout@v2
47+
- run: sudo apt-get update && sudo apt-get install -y xorg-dev mesa-utils xvfb libgl1 freeglut3-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev xsettingsd x11-xserver-utils
5148
- uses: julia-actions/setup-julia@v1
5249
with:
53-
version: '1.6'
50+
version: "1.11"
51+
- uses: julia-actions/cache@v2
5452
- run: |
55-
julia --project=docs -e '
53+
DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs -e '
5654
using Pkg
5755
Pkg.develop(PackageSpec(path=pwd()))
56+
pkg"add MeshIO#ff/GeometryBasics_refactor MakieCore#breaking-0.22 Makie#breaking-0.22 GLMakie#breaking-0.22"
5857
Pkg.instantiate()'
59-
- run: |
60-
julia --project=docs -e '
61-
using Documenter: doctest, DocMeta
62-
using GeometryBasics
63-
DocMeta.setdocmeta!(GeometryBasics, :DocTestSetup, :(using GeometryBasics); recursive=true)
64-
doctest(GeometryBasics)'
65-
- run: julia --project=docs docs/make.jl
58+
- run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs docs/make.jl
6659
env:
6760
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6861
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
*.jl.mem
44
.DS_Store
55
/Manifest.toml
6+
docs/Manifest.toml
67
docs/build/
78
*~

Project.toml

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,39 @@
11
name = "GeometryBasics"
22
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
33
authors = ["SimonDanisch <[email protected]>"]
4-
version = "0.4.1"
4+
version = "0.4.11"
55

66
[deps]
77
EarCut_jll = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
8+
Extents = "411431e0-e8b7-467b-b5e0-f676ba4f2910"
9+
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
810
IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
911
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
12+
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
13+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1014
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
11-
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
12-
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
1315

1416
[compat]
17+
Aqua = "0.8"
18+
EarCut_jll = "2"
19+
Extents = "0.1"
20+
GeoInterface = "1.0.1"
21+
GeoJSON = "0.7, 0.8"
1522
IterTools = "1.3.0"
16-
StaticArrays = "0.12, 1.0"
17-
StructArrays = "0.6"
18-
Tables = "0.2, 1"
19-
julia = "1.3"
23+
LinearAlgebra = "<0.0.1,1"
24+
OffsetArrays = "1"
25+
PrecompileTools = "1.0"
26+
Random = "<0.0.1,1"
27+
StaticArrays = "0.6, 1"
28+
Test = "<0.0.1,1"
29+
julia = "1.6"
2030

2131
[extras]
32+
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
33+
GeoJSON = "61d90e0f-e114-555e-ac52-39dfb47a3ef9"
2234
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
2335
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
2436
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2537

2638
[targets]
27-
test = ["Test", "Random", "OffsetArrays"]
39+
test = ["Aqua", "GeoJSON", "Test", "Random", "OffsetArrays"]

docs/make.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#! /usr/bin/env julia
22

33
using Documenter
4-
54
using GeometryBasics
65

76
DocMeta.setdocmeta!(GeometryBasics, :DocTestSetup, :(using GeometryBasics); recursive=true)
@@ -11,11 +10,10 @@ makedocs(format=Documenter.HTML(prettyurls=get(ENV, "CI", "false") == "true"),
1110
pages=[
1211
"index.md",
1312
"primitives.md",
14-
"rectangles.md",
1513
"polygons.md",
1614
"meshes.md",
1715
"decomposition.md",
18-
"metadata.md",
16+
"static_array_types.md",
1917
"api.md"
2018
],
2119
modules=[GeometryBasics])

docs/src/decomposition.md

Lines changed: 24 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,26 @@
11
# Decomposition
22

3-
4-
## GeometryBasics Mesh interface
5-
6-
GeometryBasics defines an interface to decompose abstract geometries into
7-
points and triangle meshes.
8-
This can be done for any arbitrary primitive, by overloading the following interface:
9-
10-
```julia
11-
12-
function GeometryBasics.coordinates(rect::Rect2, nvertices=(2,2))
13-
mini, maxi = extrema(rect)
14-
xrange, yrange = LinRange.(mini, maxi, nvertices)
15-
return ivec(((x,y) for x in xrange, y in yrange))
16-
end
17-
18-
function GeometryBasics.faces(rect::Rect2, nvertices=(2, 2))
19-
w, h = nvertices
20-
idx = LinearIndices(nvertices)
21-
quad(i, j) = QuadFace{Int}(idx[i, j], idx[i+1, j], idx[i+1, j+1], idx[i, j+1])
22-
return ivec((quad(i, j) for i=1:(w-1), j=1:(h-1)))
23-
end
24-
```
25-
Those methods, for performance reasons, expect you to return an iterator, to make
26-
materializing them with different element types allocation free. But of course,
27-
can also return any `AbstractArray`.
28-
29-
With these methods defined, this constructor will magically work:
30-
31-
```julia
32-
rect = Rect2(0.0, 0.0, 1.0, 1.0)
33-
m = GeometryBasics.mesh(rect)
34-
```
35-
If you want to set the `nvertices` argument, you need to wrap your primitive in a `Tesselation`
36-
object:
37-
```julia
38-
m = GeometryBasics.mesh(Tesselation(rect, (50, 50)))
39-
length(coordinates(m)) == 50^2
40-
```
41-
42-
As you can see, `coordinates` and `faces` are also defined on a mesh
43-
```julia
44-
coordinates(m)
45-
faces(m)
46-
```
47-
But will actually not be an iterator anymore. Instead, the mesh constructor uses
48-
the `decompose` function, that will collect the result of coordinates and will
49-
convert it to a concrete element type:
50-
```julia
51-
decompose(Point2f, rect) == convert(Vector{Point2f}, collect(coordinates(rect)))
52-
```
53-
The element conversion is handled by `simplex_convert`, which also handles convert
54-
between different face types:
55-
```julia
56-
decompose(QuadFace{Int}, rect) == convert(Vector{QuadFace{Int}}, collect(faces(rect)))
57-
length(decompose(QuadFace{Int}, rect)) == 1
58-
fs = decompose(GLTriangleFace, rect)
59-
fs isa Vector{GLTriangleFace}
60-
length(fs) == 2 # 2 triangles make up one quad ;)
61-
```
62-
`mesh` uses the most natural element type by default, which you can get with the unqualified Point type:
63-
```julia
64-
decompose(Point, rect) isa Vector{Point{2, Float64}}
65-
```
66-
You can also pass the element type to `mesh`:
67-
```julia
68-
m = GeometryBasics.mesh(rect, pointtype=Point2f, facetype=QuadFace{Int})
69-
```
70-
You can also set the uv and normal type for the mesh constructor, which will then
71-
calculate them for you, with the requested element type:
72-
```julia
73-
m = GeometryBasics.mesh(rect, uv=Vec2f, normaltype=Vec3f)
74-
```
75-
76-
As you can see, the normals are automatically calculated,
77-
the same is true for texture coordinates. You can overload this behavior by overloading
78-
`normals` or `texturecoordinates` the same way as coordinates.
79-
`decompose` works a bit different for normals/texturecoordinates, since they dont have their own element type.
80-
Instead, you can use `decompose` like this:
81-
```julia
82-
decompose(UV(Vec2f), rect)
83-
decompose(Normal(Vec3f), rect)
84-
# the short form for the above:
85-
decompose_uv(rect)
86-
decompose_normals(rect)
87-
```
88-
You can also use `triangle_mesh`, `normal_mesh` and `uv_normal_mesh` to call the
89-
`mesh` constructor with predefined element types (Point2/3f, Vec2/3f), and the requested attributes.
3+
## decompose functions
4+
5+
The `decompose` functions allow you to grab certain data from an `AbstractGeometry` like a mesh or primitive and convert it to a requested type, if possible.
6+
They can also be used to convert an array of e.g. faces into a different face type directly.
7+
The default decomposition implemented by GeoemtryBasics are:
8+
- `decompose(::Type{<: Point}, source)` which collects data from `source` using `coordinates(source)` and converts it to the given point type.
9+
- `decompose_normals([::Type{<: Vec},] source) = decompose([::Type{Normals{<: Vec}}},] source)` which collects data with `normals(source)` and converts it to the given Vec type.
10+
- `decompose_uv([::Type{<: Vec},] source) = decompose([::Type{UV{<: Vec}}},] source)` which collects data with `texturecoordinates(source)` and converts it to the given Vec type. This function also exists with `UVW` texture coordinates.
11+
- `decompose(::Type{<: AbstractFace}, source)` which collects data with `faces(source)` and converts it to the given face type.
12+
13+
### Extending decompose
14+
15+
For `decompose` to work there needs to be a conversion from some element type to some target type.
16+
GeometryBasics relies on `GeometryBasics.convert_simplex(TargetType, value)` for this.
17+
If you want to add new types to decompose, e.g. a new face type, you will need to add a method to that function.
18+
19+
## Primitive decomposition
20+
21+
GeometryBasics defines an interface to decompose geometry primitives into vertex attributes and faces.
22+
The interface includes four functions:
23+
- `coordinates(primitive[, nvertices])` which produces the positions associated with the primitive
24+
- `faces(primitive[, nvertices])` which produces the faces which connect the vertex positions to a mesh
25+
- `normals(primitive[, nvertices])` which optionally provide normal vectors of the primitive
26+
- `texturecoordinates(primitive[, nvertices])` which optional provide texture coordinates (uv/uvw) of the primitive

docs/src/implementation.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

docs/src/index.md

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,56 +22,20 @@ p2 = Point(1, 3);
2222
p3 = Point(4, 4);
2323
```
2424

25-
Geometries can carry metadata:
26-
27-
```@repl quickstart
28-
poi = meta(p1, city="Abuja", rainfall=1221.2)
29-
```
30-
31-
Metadata is stored in a NamedTuple and can be retrieved as such:
32-
33-
```@repl quickstart
34-
meta(poi)
35-
```
36-
37-
Specific metadata attributes can be directly retrieved:
38-
39-
```@repl quickstart
40-
poi.rainfall
41-
```
42-
43-
To remove the metadata and keep only the geometry, use `metafree`:
44-
45-
```@repl quickstart
46-
metafree(poi)
47-
```
48-
49-
Geometries have predefined metatypes:
50-
51-
```@repl quickstart
52-
multipoi = MultiPointMeta([p1], city="Abuja", rainfall=1221.2)
53-
```
54-
55-
Connect the points with lines:
25+
Connect pairs of points as line segments:
5626

5727
```@repl quickstart
5828
l1 = Line(p1, p2)
5929
l2 = Line(p2, p3);
6030
```
6131

62-
Connect the lines in a linestring:
63-
64-
```@repl quickstart
65-
LineString([l1, l2])
66-
```
67-
68-
Linestrings can also be constructed directly from points:
32+
Or connect multiple points as a linestring:
6933

7034
```@repl quickstart
7135
LineString([p1, p2, p3])
7236
```
7337

74-
The same goes for polygons:
38+
You can also create polygons from points:
7539

7640
```@repl quickstart
7741
Polygon(Point{2, Int}[(3, 1), (4, 4), (2, 4), (1, 2), (3, 1)])
@@ -89,16 +53,16 @@ Decompose the rectangle into two triangular faces:
8953
rect_faces = decompose(TriangleFace{Int}, rect)
9054
```
9155

92-
Decompose the rectangle into four vertices:
56+
Decompose the rectangle into four positions:
9357

9458
```@repl quickstart
95-
rect_vertices = decompose(Point{2, Float64}, rect)
59+
rect_positions = decompose(Point{2, Float64}, rect)
9660
```
9761

9862
Combine the vertices and faces into a triangle mesh:
9963

10064
```@repl quickstart
101-
mesh = Mesh(rect_vertices, rect_faces)
65+
mesh = Mesh(rect_positions, rect_faces)
10266
```
10367

10468
Use `GeometryBasics.mesh` to get a mesh directly from a geometry:

0 commit comments

Comments
 (0)