Документация Engee

mesh

Страница в процессе перевода.

mesh(x, y, z)
mesh(mesh_object)
mesh(x, y, z, faces)
mesh(xyz, faces)

Строит трехмерную или двухмерную сетку. Поддерживаемые объекты mesh_object включают типы Mesh из GeometryBasics.jl.

Тип графика

Псевдоним типа графика для функции mesh — Mesh.

Примеры

Простые сетчатые графики

Сетку можно построить из набора координат вершин и граней.

using GLMakie
vertices = [
    0.0 0.0;
    1.0 0.0;
    1.0 1.0;
    0.0 1.0;
]

faces = [
    1 2 3;
    3 4 1;
]

colors = [:red, :green, :blue, :orange]

mesh(vertices, faces, color = colors, shading = NoShading)
a076fb3

Обратите внимание, что порядок вершин в грани влияет на генерацию нормалей в трехмерном режиме и, следовательно, на затенение. Нормали следуют правилу правой руки, то есть нормали будут направлены наружу, если вершины грани расположены против часовой стрелки.

using GLMakie
vertices = Point3f[(1,0,0), (1,1,0), (0,1,0)]
faces1 = [1 2 3]
faces2 = [1 3 2]
colors = [:red, :green, :blue]

f = Figure(size = (800, 400))
ax = LScene(f[1,1], show_axis = false)
p = mesh!(ax, vertices, faces1, color = colors)
arrows!(ax, vertices, p.converted[1][].normal, lengthscale = 0.1, arrowsize = Vec3f(0.05, 0.05, 0.1), color = :orange)
text!(ax, vertices[faces1[:]], text = ["1", "2", "3"], align = (:center, :center), fontsize = 20, strokecolor = :white, strokewidth = 2, overdraw = true)

ax = LScene(f[1,2], show_axis = false)
p = mesh!(ax, vertices, faces2, color = colors)
arrows!(ax, vertices, p.converted[1][].normal, lengthscale = 0.1, arrowsize = Vec3f(0.05, 0.05, 0.1), color = :orange)
text!(ax, vertices[faces2[:]], text = ["1", "2", "3"], align = (:center, :center), fontsize = 20, strokecolor = :white, strokewidth = 2, overdraw = true)

f
1ba6d88

Еще один быстрый способ создания сетчатого графика заключается в импорте сетки с помощью FileIO (который основан на MeshIO):

using GLMakie
using FileIO

brain = load(assetpath("brain.stl"))

mesh(
    brain,
    color = [tri[1][2] for tri in brain for i in 1:3],
    colormap = Reverse(:Spectral)
)
b1830ca

Цвета и нормали грани

using GLMakie
using GeometryBasics

# Снизим качество сферы
s = Tessellation(Sphere(Point3f(0), 1f0), 12)
ps = coordinates(s)
fs = faces(s)

# Используем FaceView для создания нового набора граней, с одним цветом для каждой грани.
# Каждая грань должна иметь ту же длину, что и соответствующая грань в fs.
# (Для этого следует использовать тот же тип грани.)
FT = eltype(fs); N = length(fs)
cs = FaceView(rand(RGBf, N), [FT(i) for i in 1:N])

# Создадим нормали для каждой грани (при этом создается FaceView).
ns = face_normals(ps, fs)

# Создадим сетку.
m = GeometryBasics.mesh(ps, fs, normal = ns, color = cs)

mesh(m)
ec709a9

Использование GeometryBasics.Mesh и типа Buffer/Sampler

Также можно создать сетку для указания нормалей, uv-координат:

using GeometryBasics, LinearAlgebra, GLMakie, FileIO


# Создадим вершины для сферы.
r = 0.5f0
n = 30
θ = LinRange(0, pi, n)
φ2 = LinRange(0, 2pi, 2 * n)
x2 = [r * cos(φv) * sin(θv) for θv in θ, φv in φ2]
y2 = [r * sin(φv) * sin(θv) for θv in θ, φv in φ2]
z2 = [r * cos(θv) for θv in θ, φv in 2φ2]
points = vec([Point3f(xv, yv, zv) for (xv, yv, zv) in zip(x2, y2, z2)])

# Координаты образуют матрицу, поэтому для соединения соседних вершин с гранью
# мы можем просто использовать грани прямоугольника той же размерности, что и матрица:
_faces = decompose(QuadFace{GLIndex}, Tessellation(Rect(0, 0, 1, 1), size(z2)))
# Нормали центрированной сферы — это просто нормализованные вершины.
_normals = normalize.(points)

# Теперь сгенерируем UV-координаты, которые связывают изображение (текстуру) с вершинами.
# (0, 0) означает нижний левый край изображения, а (1, 1) — верхний правый угол.
function gen_uv(shift)
    return vec(map(CartesianIndices(size(z2))) do ci
        tup = ((ci[1], ci[2]) .- 1) ./ ((size(z2) .* shift) .- 1)
        return Vec2f(reverse(tup))
    end)
end

# Добавим небольшое смещение, чтобы показать, как работают UV-координаты:
uv = gen_uv(0.0)
# Можно использовать тип Buffer для обновления отдельных элементов в массиве напрямую в GPU
# с помощью GLMakie. Они работают как обычные массивы, но передают все записанные в них обновления непосредственно в GPU.
uv_buff = Buffer(uv)
gb_mesh = GeometryBasics.Mesh(points, _faces; uv = uv_buff, normal = _normals)

f, ax, pl = mesh(gb_mesh,  color = rand(100, 100), colormap=:blues)
wireframe!(ax, gb_mesh, color=(:black, 0.2), linewidth=2, transparency=true)
record(f, "uv_mesh.mp4", LinRange(0, 1, 100)) do shift
    uv_buff[1:end] = gen_uv(shift)
end

uv-координаты, выходящие за границы, будут повторяться по умолчанию. Это поведение можно изменить с помощью объекта Sampler:

#=
Possible values:
:clamp_to_edge (default)
:mirrored_repeat
:repeat
=#
data = load(Makie.assetpath("earth.png"))
color = Sampler(rotl90(data'), x_repeat=:mirrored_repeat,y_repeat=:repeat)
f, ax, pl = mesh(gb_mesh,  color = color)
wireframe!(ax, gb_mesh, color=(:black, 0.2), linewidth=2, transparency=true)

record(f, "uv_mesh_mirror.mp4", LinRange(0, 1, 100)) do shift
    uv_buff[1:end] = gen_uv(shift)
end

Текстура объема

В `mesh(args…​; color=volume) можно передать трехмерный массив и проиндексировать объем по uvw-координатам. Вот пример интерактивного средства просмотра срезов объема:

using GLMakie, GeometryBasics, NIfTI
brain = Float32.(niread(Makie.assetpath("brain.nii.gz")).raw)
# Определим позиции.
positions = Observable([Point3f(0.5, 0, 0), Point3f(0.5, 1, 0), Point3f(0.5, 1, 1), Point3f(0.5, 0, 1)])
triangles = GLTriangleFace[(1, 2, 3), (3, 4, 1)]

# Мы останемся в единичном кубе, поэтому uv-координаты — это просто позиции.
uv_mesh = map((p) -> GeometryBasics.Mesh(p, triangles; uv=Vec3f.(p)), positions)
# Передадим график объема для применения цвета.
f, ax, pl = mesh(uv_mesh, color=brain, shading=NoShading, axis=(; show_axis=false))
# Визуализируем единичный куб, в котором присутствует объем.
wireframe!(ax, Rect3f(Vec3f(0), Vec3f(1)), transparency=true, color=(:gray, 0.5))
cam = cameracontrols(ax.scene)
# Будем поворачивать только при нажатии сочетания клавиш СТРЕЛКА ВЛЕВО + ALT, чтобы лучше взаимодействовать со срезом
cam.controls.rotation_button = Mouse.left & Keyboard.left_alt
# Зададим цвета для каждой точки, чтобы выделять его при наведении указателя мыши
colors = Observable(fill(:black, 4))
ms = meshscatter!(ax, positions, markersize=0.05, color=colors)
# Также построим рядом с ним объем с проекцией максимальной интенсивности.
Makie.volume(f[1, 2], brain)

# Используем события мыши для событий перетаскивания и т. д.
m_events = addmouseevents!(ax.scene)
point_idx = Ref(0)
point_start = Ref(Point3f(0))
clear_color() = if any(x -> x == :red, colors[])
    colors[] .= :black
    notify(colors)
end
# Определим обработчик для обработки событий перетаскивания для перемещения среза и
# выделения точек, на которые наведен указатель мыши.
onany(ax.scene.events.mouseposition, m_events.obs) do mp, event
    if event.type == Makie.MouseEventTypes.leftdragstart
        p, idx = Makie.pick(ax.scene)
        if p == ms
            point_idx[] = idx
            colors[][idx] = :red
            point_start[] = positions[][idx]
            notify(colors)
        else
            point_idx[] = 0
        end
    elseif event.type == Makie.MouseEventTypes.leftdrag
        if point_idx[] != 0
            ray = Makie.ray_at_cursor(ax.scene)
            p = point_start[]
            line_start = Point3f(0, p[2], p[3])
            line_end = Point3f(1, p[2], p[3])
            new_point = Makie.closest_point_on_line(line_start, line_end, ray)
            positions[][point_idx[]] = new_point
            notify(positions)
        end
    elseif event.type == Makie.MouseEventTypes.leftdragstop
        point_idx[] = 0
        clear_color()
    elseif event.type == Makie.MouseEventTypes.over
        p, idx = Makie.pick(ax.scene)
        if p == ms
            if colors[][idx] != :red
                colors[][idx] = :red
                notify(colors)
            end
        else
            clear_color()
            point_idx[] = 0
        end
    end
end
f
qwertyu

Сложные сетки (экспериментальные)

using GLMakie
using FileIO

# Загрузим сетку с информацией о материале. В результате получим GeometryBasics.MetaMesh.
sponza = load(assetpath("sponza/sponza.obj"))

# MetaMesh содержит стандартную структуру GeometryBasics.Mesh в `sponza.mesh`
# с `mesh.views`, определяющими различные подсетки, и метаданные материала
# в словаре `sponza.meta`. К метаданным относятся:
# — meta[:material_names], сопоставляющий каждое представление в `mesh.views` с именем материала
# — meta[:materials], сопоставляющий имя материала с вложенным словарем загруженных свойств
# Когда MetaMesh передается в Makie.mesh(), он будет искать эти записи
# и попытается построить график соответствующим образом.
f, a, p = mesh(sponza)

# Настроим камеру.
update_cam!(a.scene, Vec3f(-15, 7, 1), Vec3f(3, 5, 0), Vec3f(0,1,0))
cameracontrols(a).settings.center[] = false # отключить рецентровку на экране
cameracontrols(a).settings.fixed_axis[] = false # вращать без ограничений
f
f4cfd63

Атрибуты

alpha

Значение по умолчанию: 1.0

Альфа-значение цветовой карты или атрибута color. Несколько букв, таких как в plot(alpha=0.2, color=(:red, 0.5), будут умножены.

backlight

Значение по умолчанию: 0.0

Устанавливает вес для расчета вторичного освещения с использованием перевернутых нормалей.

clip_planes

Значение по умолчанию: automatic

Плоскости обрезки позволяют выполнять обрезку в трехмерном пространстве. Вы можете задать вектор длиной до 8 Plane3f Здесь вы можете задать плоскости, за которыми участки будут обрезаны (т.е. станут невидимыми). По умолчанию плоскости клипа наследуются от родительского графика или сцены. Вы можете удалить родительский элемент clip_planes проходя мимо Plane3f[].

color

Значение по умолчанию: @inherit patchcolor

Задает цвет сетки. Может быть a Vector{<:Colorant} для цветов каждой вершины или один Colorant. A Matrix{<:Colorant} может использоваться для окрашивания сетки текстурой, для чего требуется, чтобы сетка содержала текстурные координаты. A <: AbstractPattern can be used to apply a repeated, pixel sampled pattern to the mesh, e.g. for hatching.

colormap

Значение по умолчанию: @inherit colormap :viridis

Задает цветовую карту, которая используется для выбора числовых значений color. Также можно использовать PlotUtils.cgrad(...), Makie.Reverse(any_colormap) или любой символ из ColorBrewer или PlotUtils. Чтобы увидеть все доступные цветовые градиенты, можно вызвать Makie.available_gradients().

colorrange

Значение по умолчанию: automatic

Значения, представляющие начальную и конечную точки colormap.

colorscale

Значение по умолчанию: identity

Функция преобразования цвета. Может быть любой функцией, но хорошо работает только в сочетании с Colorbar для identity, log, log2, log10, sqrt, logit, Makie.pseudolog10 и Makie.Symlog10.

cycle

Значение по умолчанию: [:color => :patchcolor]

Документация недоступна.

depth_shift

Значение по умолчанию: 0.0

настраивает значение глубины участка после всех других преобразований, т.е. в пространстве клипа, где 0 <= depth <= 1. This only applies to GLMakie and WGLMakie and can be used to adjust render order (like a tunable overdraw).

diffuse

Значение по умолчанию: 1.0

Определяет, насколько сильно красный, зеленый и синий каналы реагируют на рассеянный (рассеянный) свет.

fxaa

Значение по умолчанию: true

настраивает, будет ли отображаться график с помощью fxaa (сглаживание, только для GLMakie).

highclip

Значение по умолчанию: automatic

Цвет для любого значения, превышающего цветовой диапазон.

inspectable

Значение по умолчанию: @inherit inspectable

Определяет, должен ли этот сюжет быть виден посетителям DataInspector. Значение по умолчанию зависит от темы родительской сцены.

inspector_clear

Значение по умолчанию: automatic

Устанавливает функцию обратного вызова (inspector, plot) -> ...</span> для очистки пользовательских индикаторов в DataInspector.

inspector_hover

Значение по умолчанию: automatic

Устанавливает функцию обратного вызова (inspector, plot, index) -> ... которая заменяет функцию по умолчанию show_data методы.

inspector_label

Значение по умолчанию: automatic

Устанавливает функцию обратного вызова (plot, index, position) -> string который заменяет метку по умолчанию, сгенерированную DataInspector.

interpolate

Значение по умолчанию: true

устанавливает, следует ли интерполировать цвета

lowclip

Значение по умолчанию: automatic

Цвет для любого значения ниже цветового диапазона.

matcap

Значение по умолчанию: nothing

Документация недоступна.

material

Значение по умолчанию: nothing

RPRMakie - единственный атрибут для установки сложных материалов RadeonProRender. Предупреждаю, способ установки RPR-материала может измениться, и другие серверные системы будут игнорировать этот атрибут

model

Значение по умолчанию: automatic

Задает матрицу модели для построения графика. Это отменяет корректировки, сделанные с помощью translate!, rotate! и scale!.

nan_color

Значение по умолчанию: :transparent

Цвет для значений NaN.

overdraw

Значение по умолчанию: false

Определяет, будет ли график отображаться поверх других графиков. В частности, это означает игнорирование проверок глубины в GL-интерфейсах

shading

Значение по умолчанию: automatic

Задает используемый алгоритм освещения. Возможны следующие варианты: NoShading (без освещения), FastShading (Окружающий свет + точечный свет) или MultiLightShading (Несколько источников света, только GLMakie). Обратите внимание, что это не влияет на RPRMakie.

shininess

Значение по умолчанию: 32.0

Определяет, насколько четким будет отражение.

space

Значение по умолчанию: :data

задает область преобразования для прямоугольника, охватывающего участок. Видеть Makie.spaces() для получения возможных исходных данных.

specular

Значение по умолчанию: 0.2

Определяет, насколько сильно объект отражает свет в красном, зеленом и синем каналах.

ssao

Значение по умолчанию: false

Определяет, будет ли график отображаться с помощью ssao (screen space ambient occlusion). Обратите внимание, что это имеет смысл только для 3D-графиков и применимо только к fxaa = true.

transformation

Значение по умолчанию: :automatic

Документация недоступна.

transparency

Значение по умолчанию: false

Настраивает прозрачность графика. В GLMakie transparency = true в результате используется прозрачность, независимая от порядка.

uv_transform

Значение по умолчанию: automatic

Устанавливает преобразование для uv-координат, которое управляет отображением текстуры на сетку. Атрибутом может быть I, scale::VecTypes{2}, (translation::VecTypes{2}, scale::VecTypes{2}), любой из :rotr90, :rotl90, :rot180, :swap_xy/:transpose, :flip_x, :flip_y, :flip_xy, или, в большинстве случаев, Makie.Mat{2, 3, Float32} или Makie.Mat3f как было возвращено Makie.uv_transform(). Они также могут быть изменены путем передачи кортежа (op3, op2, op1).

visible

Значение по умолчанию: true

Определяет, будет ли отображаться график или нет.