From 06ee6a6b140a45d8d15eb398e707b243c67251e7 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 30 Sep 2025 20:03:30 +0200 Subject: [PATCH 1/2] basic improvements for docs --- .github/workflows/ci.yml | 13 +++-- docs/Project.toml | 6 +++ docs/make.jl | 13 +++-- docs/src/meshes.md | 109 +++++++++++++++++++++++++++++++++++++-- src/basic_types.jl | 4 +- 5 files changed, 126 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16ade19d..81aec9bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,13 +56,12 @@ jobs: with: version: "1.11" - uses: julia-actions/cache@v2 - - run: | - DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs -e ' - using Pkg - Pkg.develop(PackageSpec(path=pwd())) - pkg"add MakieCore Makie GLMakie" - Pkg.instantiate()' - - run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs docs/make.jl + - name: Configure doc environment + shell: julia --project=docs --color=yes {0} + run: | + using Pkg + Pkg.instantiate() + - run: julia --project=docs docs/make.jl env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} diff --git a/docs/Project.toml b/docs/Project.toml index eed229d9..810f3b9a 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,3 +1,9 @@ [deps] +Bonito = "824d6782-a2ef-11e9-3a09-e5662e0c26f8" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73" +WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008" + +[sources] +GeometryBasics = {path = "../"} diff --git a/docs/make.jl b/docs/make.jl index 7b7f8f97..e94f5c43 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -5,18 +5,17 @@ using GeometryBasics DocMeta.setdocmeta!(GeometryBasics, :DocTestSetup, :(using GeometryBasics); recursive=true) -makedocs(format=Documenter.HTML(prettyurls=get(ENV, "CI", "false") == "true"), - sitename="GeometryBasics.jl", - pages=[ - "index.md", +makedocs(; sitename="GeometryBasics.jl", + format=Documenter.HTML(; prettyurls=false, size_threshold=3000000, + example_size_threshold=3000000), + pages=["index.md", "primitives.md", "polygons.md", "meshes.md", "decomposition.md", "boundingboxes.md", "static_array_types.md", - "api.md", - ], + "api.md"], modules=[GeometryBasics]) -deploydocs(repo="github.com/JuliaGeometry/GeometryBasics.jl.git", push_preview=true) +deploydocs(; repo="github.com/JuliaGeometry/GeometryBasics.jl.git", push_preview=true) diff --git a/docs/src/meshes.md b/docs/src/meshes.md index 9b5bd20e..3ec5b8a0 100644 --- a/docs/src/meshes.md +++ b/docs/src/meshes.md @@ -1,5 +1,10 @@ # Meshes +```@setup 1 +using Bonito +Page() +``` + GeometryBasics defines two mesh types to work with - `Mesh` and `MetaMesh` ## Mesh @@ -17,6 +22,48 @@ You can get data from a mesh using a few interface functions: You can also grab the contents of `mesh.vertex_attributes` as if they were fields of the `Mesh`, e.g. `mesh.position` works. +### Custom Attributes + +Meshes support arbitrary custom attributes beyond the standard position, normal, and UV coordinates. You can attach per-vertex or per-face data like material properties, identifiers, or computed values. These are stored in `mesh.vertex_attributes` and accessed using the same interface. + +```julia +using GeometryBasics + +# Define custom data type +struct Material + emissivity::Float64 + absorptivity::Float64 + reflectivity::Float64 +end + +# Create mesh with custom attributes +points = [Point3f(0,0,0), Point3f(1,0,0), Point3f(0,1,0), Point3f(0,0,1)] +faces = [TriangleFace(1,2,3), TriangleFace(1,2,4), TriangleFace(1,3,4), TriangleFace(2,3,4)] + +materials = [ + Material(0.1, 0.8, 0.1), + Material(0.2, 0.7, 0.1), + Material(0.0, 0.9, 0.1), + Material(0.3, 0.6, 0.1) +] + +face_names = ["bottom", "side1", "side2", "top"] + +# Use per_face to create FaceViews for per-face attributes +mesh = GeometryBasics.mesh( + points, + faces, + material=per_face(materials, faces), + face_name=per_face(face_names, faces) +) + +# Access custom attributes +mesh.material[2] # Get material of second face +mesh.face_name[1] # Get name of first face +``` + +This pattern is useful for physical simulations, rendering with material properties, or tagging mesh regions for analysis. + ### FaceView @@ -47,6 +94,40 @@ per_face MetaMesh ``` +`MetaMesh` wraps a `Mesh` and allows you to attach global metadata that applies to the entire mesh rather than individual vertices or faces. This is useful for storing information like source file paths, transformation matrices, object identifiers, or simulation parameters. + +```julia +using GeometryBasics + +# Create a basic mesh +points = [Point3f(0,0,0), Point3f(1,0,0), Point3f(0,1,0)] +faces = [TriangleFace(1,2,3)] +mesh = GeometryBasics.mesh(points, faces; attribute=rand(3)) + +# Wrap with MetaMesh and add global metadata +meta_mesh = MetaMesh(mesh, source_file="model.obj", object_id=42, scale=1.5) + +# Access metadata +meta_mesh[:source_file] # "model.obj" +meta_mesh[:object_id] # 42 +meta_mesh.attribute # access vertex attributes via getproperty +# The underlying mesh is still accessible +meta_mesh.mesh +``` + +You can combine `MetaMesh` for global properties with per-face/per-vertex attributes for complete geometric and metadata representation: + +```julia +# Create mesh with both per-face attributes and global metadata +mesh = GeometryBasics.mesh( + points, faces, + material=per_face(materials, faces), + normal=face_normals(points, faces) +) + +meta_mesh = MetaMesh(mesh, gltf_file="spacecraft.gltf", mass=150.0) +``` + ## How to create a mesh ### GeometryBasics @@ -66,13 +147,33 @@ Note that this doesn't remove any data (e.g. hidden or duplicate vertices), and ### Meshing.jl +```@example 1 +using Meshing +using GeometryBasics +using WGLMakie +using LinearAlgebra + +gyroid(v) = cos(v[1])*sin(v[2])+cos(v[2])*sin(v[3])+cos(v[3])*sin(v[1]) +gyroid_shell(v) = max(gyroid(v)-0.4,-gyroid(v)-0.4) +xr,yr,zr = ntuple(_->LinRange(0,pi*4,50),3) + +A = [gyroid_shell((x,y,z)) for x in xr, y in yr, z in zr] +# generate directly using GeometryBasics API +# Rect specifies the sampling intervals +vts, fcs = isosurface(A, MarchingCubes()) +# view with Makie +fcs = TriangleFace{Int}.(fcs) +vts = Point3d.(vts) +Makie.mesh(GeometryBasics.Mesh(vts, fcs), color=[norm(v) for v in vts]) +``` + ### MeshIO.jl The [`MeshIO.jl`](https://github.com/JuliaIO/MeshIO.jl) package provides load/save support for several file formats which store meshes. -```@example -using GLMakie, GLMakie.FileIO, GeometryBasics +```@example 1 +using WGLMakie, GeometryBasics -m = load(GLMakie.assetpath("cat.obj")) -GLMakie.mesh(m; color=load(GLMakie.assetpath("diffusemap.png")), axis=(; show_axis=false)) +m = Makie.loadasset("cat.obj") +Makie.mesh(m; color=Makie.loadasset("diffusemap.png"), axis=(; show_axis=false)) ``` diff --git a/src/basic_types.jl b/src/basic_types.jl index 48e776d8..8925f120 100644 --- a/src/basic_types.jl +++ b/src/basic_types.jl @@ -380,6 +380,7 @@ faces(x::FaceView) = x.faces Base.values(x::FaceView) = x.data facetype(x::FaceView) = eltype(x.faces) Base.getindex(x::FaceView, f::AbstractFace) = getindex(values(x), f) +Base.getindex(x::FaceView, i::Integer) = x.data[i] Base.isempty(x::FaceView) = isempty(values(x)) Base.:(==)(a::FaceView, b::FaceView) = (values(a) == values(b)) && (faces(a) == faces(b)) @@ -763,10 +764,10 @@ function MetaMesh(points::AbstractVector{<:Point}, faces::AbstractVector{<:Abstr MetaMesh(Mesh(points, faces), Dict{Symbol, Any}(kwargs)) end - @inline function Base.hasproperty(mesh::MetaMesh, field::Symbol) return hasfield(MetaMesh, field) || hasproperty(getfield(mesh, :mesh), field) end + @inline function Base.getproperty(mesh::MetaMesh, field::Symbol) if hasfield(MetaMesh, field) return getfield(mesh, field) @@ -774,6 +775,7 @@ end return getproperty(getfield(mesh, :mesh), field) end end + @inline function Base.propertynames(mesh::MetaMesh) return (fieldnames(MetaMesh)..., propertynames(getfield(mesh, :mesh))...) end From 0e1a8bb052b19473c7d958e19caccd6e74897d71 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 30 Sep 2025 21:01:34 +0200 Subject: [PATCH 2/2] add MeshIO --- docs/Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Project.toml b/docs/Project.toml index 810f3b9a..0ffb13bf 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -2,6 +2,7 @@ Bonito = "824d6782-a2ef-11e9-3a09-e5662e0c26f8" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +MeshIO = "7269a6da-0436-5bbc-96c2-40638cbb6118" Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73" WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008"