Transforms

Geometric (e.g. coordinates) transforms are implemented according to the TransformsBase.jl interface. Please read their documentation for more details.

Some transforms have an inverse that can be created with the inverse function. The function isinvertible can be used to check if a transform is invertible.

TransformsBase.isinvertibleFunction
isinvertible(transform)

Tells whether or not the transform is invertible, i.e. whether it implements the inverse function. Defaults to false for new transform types.

Transforms can be invertible in the mathematical sense, i.e., there exists a one-to-one mapping between input and output spaces.

See also inverse, isrevertible.

source

Rotate

Meshes.RotateType
Rotate(R)

Rotate geometry or domain with rotation R from Rotations.jl.

Rotate(u, v)

Rotation mapping the axis directed by u to the axis directed by v. More precisely, it maps the plane passing through the origin with normal vector u to the plane passing through the origin with normal vector v.

Rotate(θ)

Rotate the 2D geometry or domain by angle θ, in radians, using the Angle2d rotation.

Examples

Rotate(one(RotXYZ{Float64})) # identity rotation
Rotate(AngleAxis(0.2, 1.0, 0.0, 0.0)) # rotate 0.2 radians around X axis
Rotate(rand(QuatRotation{Float64})) # random rotation
Rotate(Vec(1, 0, 0), Vec(1, 1, 1)) # rotation from (1, 0, 0) to (1, 1, 1)
Rotate(π / 2) # 2D rotation with angle in radians
source
grid = CartesianGrid(10, 10)

mesh = grid |> Rotate(π/4)

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], grid)
viz(fig[1,2], mesh)
fig
Example block output

Translate

Meshes.TranslateType
Translate(o₁, o₂, ...)

Translate coordinates of geometry or mesh by given offsets o₁, o₂, ....

source
grid = CartesianGrid(10, 10)

mesh = grid |> Translate(10., 20.)

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], grid)
viz(fig[1,2], mesh)
fig
Example block output

Scale

Meshes.ScaleType
Scale(s₁, s₂, ...)

Scale geometry or domain with strictly positive scaling factors s₁, s₂, ....

Examples

Scale(1.0, 2.0, 3.0)
source
grid = CartesianGrid(10, 10)

mesh = grid |> Scale(2., 3.)

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], grid)
viz(fig[1,2], mesh)
fig
Example block output

Affine

Meshes.AffineType
Affine(A, b)

Affine transform Ax + b with matrix A and vector b.

Examples

Affine(AngleAxis(0.2, 1.0, 0.0, 0.0), [-2, 2, 2])
Affine(Angle2d(π / 2), SVector(2, -2))
Affine([0 -1; 1 0], [-2, 2])
source
using Rotations: Angle2d

grid = CartesianGrid(10, 10)

mesh = grid |> Affine(Angle2d(π/4), [10., 20.])

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], grid)
viz(fig[1,2], mesh)
fig
Example block output

Stretch

Meshes.StretchType
Stretch(s₁, s₂, ...)

Stretch geometry or domain outwards with strictly positive scaling factors s₁, s₂, ....

Examples

Stretch(1.0, 2.0, 3.0)
source
grid = CartesianGrid(10, 10)

mesh = grid |> Stretch(2., 3.)

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], grid)
viz(fig[1,2], mesh)
fig
Example block output

StdCoords

Meshes.StdCoordsType
StdCoords()

Standardize coordinates of all geometries to the interval [-0.5, 0.5].

Examples

julia> CartesianGrid(10, 10) |> StdCoords()
10×10 CartesianGrid{2,Float64}
  minimum: Point(-0.5, -0.5)
  maximum: Point(0.5, 0.5)
  spacing: (0.1, 0.1)
source
# Cartesian grid with coordinates [0,10] x [0,10]
grid = CartesianGrid(10, 10)

# scale coordinates to [-1,1] x [-1,1]
mesh = grid |> StdCoords()

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], grid)
viz(fig[1,2], mesh)
fig
Example block output

Proj

Meshes.ProjType
Proj(CRS)
Proj(code)

Convert the coordinates of geometry or domain to a given coordinate reference system CRS or EPSG/ESRI code.

Optionally, the transform samples the boundary of polytopes, if this option is true, to handle distortions that occur in manifold conversions.

Examples

Proj(Polar)
Proj(WebMercator)
Proj(Mercator{WGS84Latest})
Proj(EPSG{3395})
Proj(ESRI{54017})

Notes

  • By default, only the vertices of the polytopes are transformed, disregarding distortions that occur in manifold conversions. To handle this case, use TransformedGeometry.
source
# load coordinate reference system
using CoordRefSystems: Polar

# triangle with Cartesian coordinates
triangle = Triangle((0, 0), (1, 0), (1, 1))

# reproject to polar coordinates
triangle |> Proj(Polar)
Triangle
├─ Point(ρ: 0.0 m, ϕ: 0.0 rad)
├─ Point(ρ: 1.0 m, ϕ: 0.0 rad)
└─ Point(ρ: 1.4142135623730951 m, ϕ: 0.7853981633974483 rad)

Morphological

Meshes.MorphologicalType
Morphological(fun)

Morphological transform given by a function fun that maps the coordinates of a geometry or a domain to new coordinates (coords -> newcoords).

Examples

ball = Ball((0, 0), 1)
ball |> Morphological(c -> Cartesian(c.x + c.y, c.y, c.x - c.y))

triangle = Triangle(Point(LatLon(0, 0)), Point(LatLon(0, 45)), Point(LatLon(45, 0)))
triangle |> Morphological(c -> LatLonAlt(c.lat, c.lon, 0.0m))

Notes

  • By default, only the vertices of the polytopes are transformed, disregarding distortions that occur in manifold conversions. To handle this case, use TransformedGeometry.
source
# triangle with Cartesian coordinates
triangle = Triangle((0, 0), (1, 0), (1, 1))

# transform triangle coordinates
triangle |> Morphological(c -> Cartesian(c.x, c.y, zero(c.x)))
Triangle
├─ Point(x: 0.0 m, y: 0.0 m, z: 0.0 m)
├─ Point(x: 1.0 m, y: 0.0 m, z: 0.0 m)
└─ Point(x: 1.0 m, y: 1.0 m, z: 0.0 m)

LengthUnit

Meshes.LengthUnitType
LengthUnit(unit)

Convert the length unit of coordinates of a geometry or domain to unit.

Examples

LengthUnit(u"cm")
LengthUnit(u"km")
source
using Unitful: m, cm

# convert meters to centimeters
Point(1m, 2m, 3m) |> LengthUnit(cm)
Point with Cartesian{NoDatum} coordinates
├─ x: 100.0 cm
├─ y: 200.0 cm
└─ z: 300.0 cm

ValidCoords

Meshes.ValidCoordsType
ValidCoords(CRS)

Retain the geometries within the domain of the projected CRS.

ValidCoords(code)

Alternatively, specify the projected CRS using a EPSG/ESRI code.

source
# load coordinate reference system
using CoordRefSystems: LatLon

# regular grid with LatLon coordinates
grid = RegularGrid(Point(LatLon(-90, -180)), Point(LatLon(90, 180)), dims=(10, 10))

# retain elements in the projection domain
subgrid = grid |> ValidCoords(Mercator)

# plot the projected grid
viz(subgrid |> Proj(Mercator), showsegments=true)
Example block output

Shadow

Meshes.ShadowType
Shadow(dims)

Project the geometry or domain onto the given dims, producing a "shadow" of the original object.

Examples

Shadow(:xy)
Shadow("xz")
Shadow(1, 2)
Shadow((1, 3))
source
ball = Ball((0, 0, 0), 1)
disk = ball |> Shadow("xy")


fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], ball)
viz(fig[1,2], disk)
fig
Example block output

Slice

Meshes.SliceType
Slice(x=(xmin, xmax), y=(ymin, ymax), z=(zmin, zmax))
Slice(lat=(latmin, latmax), lon=(lonmin, lonmax))

Retain the domain elements within x limits [xmax,xmax], y limits [ymax,ymax] and z limits [zmin,zmax] in length units (default to meters), or within lat limits [latmin,latmax] and lon limits [lonmin,lonmax] in degree units.

Examples

Slice(x=(1000km, 3000km))
Slice(x=(1000km, 2000km), y=(2000km, 5000km))
Slice(lon=(0°, 90°))
Slice(lon=(0°, 45°), lat=(0°, 45°))
source
grid = CartesianGrid(10, 10)
subgrid = grid |> Slice(x=(1.5, 6.5), y=(3.5, 8.5))

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], grid)
viz(fig[1,2], subgrid)
fig
Example block output

Repair

Meshes.RepairType
Repair(K)

Perform repairing operation with code K.

Available operations

  • K = 0: duplicated vertices and faces are removed
  • K = 1: unused vertices are removed
  • K = 2: non-manifold faces are removed
  • K = 3: degenerate faces are removed
  • K = 4: non-manifold vertices are removed
  • K = 5: non-manifold vertices are split by threshold
  • K = 6: close vertices are merged (given a radius)
  • K = 7: faces are coherently oriented
  • K = 8: zero-area ears are removed
  • K = 9: rings of polygon are sorted
  • K = 10: outer rings of polygon are expanded
  • K = 11: rings of polygon are coherently oriented
  • K = 12: degenerate rings of polygon are removed

Examples

# remove duplicates and degenerates
mesh |> Repair(0) |> Repair(3)
source
# mesh with unreferenced point
points = [(0, 0, 0), (0, 0, 1), (5, 5, 5), (0, 1, 0), (1, 0, 0)]
connec = connect.([(1, 2, 4), (1, 2, 5), (1, 4, 5), (2, 4, 5)])
mesh   = SimpleMesh(points, connec)

rmesh = mesh |> Repair(1)
4 SimpleMesh
  4 vertices
  ├─ Point(x: 0.0 m, y: 0.0 m, z: 0.0 m)
  ├─ Point(x: 0.0 m, y: 0.0 m, z: 1.0 m)
  ├─ Point(x: 0.0 m, y: 1.0 m, z: 0.0 m)
  └─ Point(x: 1.0 m, y: 0.0 m, z: 0.0 m)
  4 elements
  ├─ Triangle(1, 2, 3)
  ├─ Triangle(1, 2, 4)
  ├─ Triangle(1, 3, 4)
  └─ Triangle(2, 3, 4)

Bridge

# polygon with two holes
outer = [(0, 0), (1, 0), (1, 1), (0, 1)]
hole1 = [(0.2, 0.2), (0.2, 0.4), (0.4, 0.4), (0.4, 0.2)]
hole2 = [(0.6, 0.2), (0.6, 0.4), (0.8, 0.4), (0.8, 0.2)]
poly = PolyArea([outer, hole1, hole2])

# polygon with single outer ring
bpoly = poly |> Bridge(0.01)

fig = Mke.Figure(size = (800, 400))
viz(fig[1,1], poly)
viz(fig[1,2], bpoly)
fig
Example block output

Smoothing

using PlyIO

# helper function to read *.ply files
function readply(fname)
  ply = load_ply(fname)
  x = ply["vertex"]["x"]
  y = ply["vertex"]["y"]
  z = ply["vertex"]["z"]
  points = Point.(x, y, z)
  connec = [connect(Tuple(c.+1)) for c in ply["face"]["vertex_indices"]]
  SimpleMesh(points, connec)
end

# download mesh from the web
file = download(
  "https://raw.githubusercontent.com/juliohm/JuliaCon2021/master/data/beethoven.ply"
)

# read mesh from disk
mesh = readply(file)

# smooth mesh with 30 iterations
smesh = mesh |> TaubinSmoothing(30)

fig = Mke.Figure(size = (800, 1200))
viz(fig[1,1], mesh)
viz(fig[2,1], smesh)
fig
Example block output