Skip to content

Commit 83f9abd

Browse files
Slim down GeometryBasics and remove all type complexity (#173)
* get rid of StaticArrays * alias must be fully typed * more fixes * fix order * more fixes * simplify fixed array * remove meta types * try to get mesh working * remove all the things!! * more tests * remove 1.3 * drop 1.3 * add imports and get overload * add getindex for faces for vec too * fixes * bring back connect * add / for e.g. mean(points) * small improvements * introduce TriangleMesh * fix constructor and print Mesh more nicely * add zero for value * fix tests * polys * fix some compile errors * fix Simplex <: AbstractSimplex <: Polytope * fix decompose test * fix Rect2 Tesselation * fix ngeom for LineString * fix compat bounds * change getindex index to Integer * remove triangle_mesh Tesselation deprecation warning * fix Base.intersect extension * update union docs and comment out broken diff or rects * add decompose_x methdos with types * disable diff test * fix MatN constructors * fix type ambiguity * fix vcat of StaticVector, Mat convert * add mat[VecOrInt, VecOrInt] and Vec(mat) * match isapprox implementation with docstring * add isapprox to Mat * fix indexing instead of implementing isapprox * rework broadcasting & add more tests * fix nested broadcast * fix Mat getindex, Boundschecks and add tests * fix broadcast size missmatch * handle map like StaticArrays * add isapprox and converts from Matrix for Mat3f-like types * avoid creating Base arrays on copy * Geometry Basics refactor (#219) * update MetaMesh * add MultiFace type * update Mesh & MultiFace types * update Mesh & MetaMesh utils * add MultiFace remapping code * prototype MultiFace Rect -> Mesh pipeline * generalize MultiFace getindex to Integer * remove add_meta, pop_meta * update merge for MultiFace and views * add AbstractVertexFace and AbstractMultiFace * split up mesh() for better usability * minor fixes * add views to Mesh constructors * add `mesh()` method for converting facetype of mesh * switch back to "normals" * fix missing normals rename * add back point/normal/uv-type kwargs * consider face views in face decompose * add mesh(mesh; attribs...) & improve dispatch safety * fix normals(), cleanup tests * add mesh constructor tests + fixes * deprecate normals for normal as vertex attribute name * make NormalFace and NormalUVFace types again * cleanup tests & normals vs normal * let ci run * remove views aware face decomposition * fix rect index order * fix MultiFace remapping with OffsetIntegers * add moreMultiFace utils * restore decompose(FaceType, faces, views) * allow MultiFace -> LineFace conversion * define Rect3 faces counterclockwise * add more convenience types * filter nothing attributes * drop Base.Pairs for 1.6 compat * Add depwarn in hasproperty too * improve MultiFace show * update Pyramid * update Cylinder * add MultiFace decompose * fix Cylinder tests * make OffsetInteger printing copyable * update tests for Rect3 and normal gen * fix remaining tests * fix incorrect vertex index counter * simplify merge of mixed Face types * test merge(meshes) * prototype swapping from MultiFace to FaceViews * treat views in vertex index remapping + some fixes * fix face type change * clean up AbstractVertexFace * extend FaceView interface * update Cylinder, Pyramids * declutter NgonFace prints * update tests * cleanup some test_broken * switch to Dict * fix tests * remove shorthands * export vertex_attributes and FaceView * add center point to Circle to avoid shallow triangles * make untesselated rect vertices counter-clockwise * fix tests * fix Cylinder face windig direction * add `face_normals()` helepr function * cleanup face_normals and normals a bit more * update tests for Cylinder * rename connectivity -> faces * update docs (meshes, primitives, decompose, Point, Vec, Mat) * add/update docstrings * add quick test for face_normals() * fix TetrahedronFace conversions * restore volume functions * fix tests * add some Polygon tests * test Pyramids * test TetrahedronFace decomposition * test and improve Mesh validation * test Mesh inteface functions * test decompose with views * test and fix matrix det, inv, transpose, mat*vec * fix tests * cleanup normal gen and export face_normals * add util for splitting meshes by views * fix missing dot in range .+ idx * improve performance of merge * fix tests * improve GeoInterface conversion performance * switch back to NamedTuple for performance * cleanup merge(meshes) * test clear_faceviews with mesh.views * fix missing import in docs examples * add convert for arrays of meshes * add function for removing duplicate faces * update normal gen tests + fixes - fix normal gen for varying face types - fix normalization of face_normals * remove time piracy * bring back shorthand types * restrict type in meshes to error earlier * update precompiles * autoconvert point dim in merge(meshes) instead of restricitng type * add compat entry * ignore unused PrecompileTools in 1.6, 1.7 * bring back old precompiles * add convert target to orthogonal_vector * revert triangulation changes of Circle * revert to using StaticArrays * avoid some invalidations (and fix get) * fix stale instances due to AbstractVector Apparently T[] is an AbstractVector here? * use string interpolation in error to avoid invalidation from string * * fix test * export clear_faceviews & update FaceView docstring * update type docstring * add notes about views * update Mesh docs * add FaceView ref to Mesh docstring * add brief section about extending decompose * derive Point eltype when dimension is given * reuse docstring * fix docs? * fix docs?? * add GLMakie to docs * fix pkg command * rename clear_faceviews & update * fix pkg * fix another clear_faceviews * fix docs * use action cache * fix typo --------- Co-authored-by: ffreyer <[email protected]>
1 parent 138fd1c commit 83f9abd

37 files changed

+2569
-2098
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
pull_request:
88
branches:
99
- master
10+
- sd/simple-mesh
1011
jobs:
1112
test:
1213
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
@@ -29,16 +30,7 @@ jobs:
2930
with:
3031
version: ${{ matrix.version }}
3132
arch: ${{ matrix.arch }}
32-
- uses: actions/cache@v1
33-
env:
34-
cache-name: cache-artifacts
35-
with:
36-
path: ~/.julia/artifacts
37-
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
38-
restore-keys: |
39-
${{ runner.os }}-test-${{ env.cache-name }}-
40-
${{ runner.os }}-test-
41-
${{ runner.os }}-
33+
- uses: julia-actions/cache@v2
4234
- uses: julia-actions/julia-buildpkg@v1
4335
- uses: julia-actions/julia-runtest@v1
4436
- uses: julia-actions/julia-processcoverage@v1
@@ -47,20 +39,23 @@ jobs:
4739
file: lcov.info
4840
docs:
4941
name: Documentation
50-
runs-on: ubuntu-latest
42+
runs-on: ubuntu-20.04
5143
env:
5244
JULIA_PKG_SERVER: ""
5345
steps:
5446
- 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
5548
- uses: julia-actions/setup-julia@v1
5649
with:
57-
version: "1.7"
50+
version: "1.11"
51+
- uses: julia-actions/cache@v2
5852
- run: |
59-
julia --project=docs -e '
53+
DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs -e '
6054
using Pkg
6155
Pkg.develop(PackageSpec(path=pwd()))
56+
pkg"add MeshIO#ff/GeometryBasics_refactor MakieCore#breaking-0.22 Makie#breaking-0.22 GLMakie#breaking-0.22"
6257
Pkg.instantiate()'
63-
- run: julia --project=docs docs/make.jl
58+
- run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs docs/make.jl
6459
env:
6560
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6661
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}

Project.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ Extents = "411431e0-e8b7-467b-b5e0-f676ba4f2910"
99
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
1010
IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
1111
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
12+
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
13+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1214
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
13-
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
14-
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
1515

1616
[compat]
1717
Aqua = "0.8"
@@ -22,10 +22,9 @@ GeoJSON = "0.7, 0.8"
2222
IterTools = "1.3.0"
2323
LinearAlgebra = "<0.0.1,1"
2424
OffsetArrays = "1"
25+
PrecompileTools = "1.0"
2526
Random = "<0.0.1,1"
26-
StaticArrays = "0.12, 1.0"
27-
StructArrays = "0.6"
28-
Tables = "0.2, 1"
27+
StaticArrays = "0.6, 1"
2928
Test = "<0.0.1,1"
3029
julia = "1.6"
3130

docs/make.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ makedocs(format=Documenter.HTML(prettyurls=get(ENV, "CI", "false") == "true"),
1010
pages=[
1111
"index.md",
1212
"primitives.md",
13-
"rectangles.md",
1413
"polygons.md",
1514
"meshes.md",
1615
"decomposition.md",
17-
"metadata.md",
16+
"static_array_types.md",
1817
"api.md"
1918
],
2019
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 & 79 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,57 +53,20 @@ 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:
10569

10670
```@repl quickstart
10771
mesh = GeometryBasics.mesh(rect)
10872
```
109-
110-
111-
## Aliases
112-
113-
GeometryBasics exports common aliases for Point, Vec, Mat and Rect:
114-
115-
### Vec
116-
117-
| |`T`(eltype) |`Float64` |`Float32` |`Int` |`UInt` |
118-
|--------|------------|----------|----------|----------|----------|
119-
|`N`(dim)|`Vec{N,T}` |`Vecd{N}` |`Vecf{N}` |`Veci{N}` |`Vecui{N}`|
120-
|`2` |`Vec2{T}` |`Vec2d` |`Vec2f` |`Vec2i` |`Vec2ui` |
121-
|`3` |`Vec3{T}` |`Vec3d` |`Vec3f` |`Vec3i` |`Vec3ui` |
122-
123-
### Point
124-
125-
| |`T`(eltype) |`Float64` |`Float32` |`Int` |`UInt` |
126-
|--------|------------|----------|----------|----------|----------|
127-
|`N`(dim)|`Point{N,T}`|`Pointd{N}`|`Pointf{N}`|`Pointi{N}`|`Pointui{N}`|
128-
|`2` |`Point2{T}` |`Point2d` |`Point2f` |`Point2i` |`Point2ui`|
129-
|`3` |`Point3{T}` |`Point3d` |`Point3f` |`Point3i` |`Point3ui`|
130-
131-
### Mat
132-
133-
| |`T`(eltype) |`Float64` |`Float32` |`Int` |`UInt` |
134-
|--------|------------|----------|----------|----------|----------|
135-
|`N`(dim)|`Mat{N,T}` |`Matd{N}` |`Matf{N}` |`Mati{N}` |`Matui{N}`|
136-
|`2` |`Mat2{T}` |`Mat2d` |`Mat2f` |`Mat2i` |`Mat2ui` |
137-
|`3` |`Mat3{T}` |`Mat3d` |`Mat3f` |`Mat3i` |`Mat3ui` |
138-
139-
### Rect
140-
141-
| |`T`(eltype) |`Float64` |`Float32` |`Int` |`UInt` |
142-
|--------|------------|----------|----------|----------|----------|
143-
|`N`(dim)|`Rect{N,T}` |`Rectd{N}`|`Rectf{N}`|`Recti{N}`|`Rectui{N}`|
144-
|`2` |`Rect2{T}` |`Rect2d` |`Rect2f` |`Rect2i` |`Rect2ui` |
145-
|`3` |`Rect3{T}` |`Rect3d` |`Rect3f` |`Rect3i` |`Rect3ui` |

0 commit comments

Comments
 (0)