-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplot_shape.jl
105 lines (90 loc) · 3.15 KB
/
plot_shape.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using LinearAlgebra
import PlotlyJS
"""
plot_shape(shape;
title = "3D shape model",
colorbar_title = nothing,
colorscale = "Viridis",
intensity = [norm(node) for node in shape.nodes],
intensitymode = "vertex",
showscale = true,
)
Plot a 3D shape model using PlotlyJS.
# References
- https://plotly.com/julia/3d-mesh/
- https://plotly.com/julia/reference/mesh3d/
"""
function plot_shape(shape;
title = "3D shape model",
colorbar_title = nothing,
colorscale = "Viridis",
intensity = [norm(node) for node in shape.nodes],
intensitymode = "vertex",
showscale = true,
)
if length(intensity) == length(shape.nodes)
intensitymode = "vertex"
hovertext = ["Node #$(i), $(round.(shape.nodes[i], digits=1)), value = $(round(intensity[i], digits=1))" for i in eachindex(shape.nodes)]
elseif length(intensity) == length(shape.faces)
intensitymode = "cell"
hovertext = ["Face #$(i), $(round.(shape.face_centers[i], digits=1)), value = $(round(intensity[i], digits=1))" for i in eachindex(shape.faces)]
else
error("The length of `intensity` must be equal to the number of nodes or faces.")
end
##= Polyhedral mesh =##
trace_mesh = PlotlyJS.mesh3d(
## Vertices
x = [node[1] for node in shape.nodes],
y = [node[2] for node in shape.nodes],
z = [node[3] for node in shape.nodes],
## Triangles (0-index in PlotlyJS)
i = [face[1] - 1 for face in shape.faces],
j = [face[2] - 1 for face in shape.faces],
k = [face[3] - 1 for face in shape.faces],
colorbar_title = colorbar_title,
colorscale = colorscale,
intensity = intensity,
intensitymode = intensitymode,
showscale = showscale,
hoverinfo = "text",
hovertext = hovertext,
)
##= Wireframe =##
edges = extract_edges(shape)
edge_nodes = Matrix{Float64}(undef, 3*length(edges), 3)
for (i, edge) in enumerate(edges)
edge_nodes[3i-2, :] .= shape.nodes[edge[1]]
edge_nodes[3i-1, :] .= shape.nodes[edge[2]]
edge_nodes[3i , :] .= [NaN, NaN, NaN] # To separate each edge
end
trace_wireframe = PlotlyJS.scatter3d(
x = edge_nodes[:, 1],
y = edge_nodes[:, 2],
z = edge_nodes[:, 3],
mode = "lines",
line = PlotlyJS.attr(
color = "black",
width = 1,
),
)
##= Layout =##
layout = PlotlyJS.Layout(
title = title,
width = 1000,
height = 800,
scene = PlotlyJS.attr(
aspectmode="data",
),
)
PlotlyJS.plot([trace_mesh, trace_wireframe], layout)
end
function extract_edges(shape)
edges = Set{SVector{2, Int64}}()
for face in shape.faces
## Add each side of face in order of decreasing node ID
push!(edges, [min(face[1], face[2]), max(face[1], face[2])])
push!(edges, [min(face[2], face[3]), max(face[2], face[3])])
push!(edges, [min(face[3], face[1]), max(face[3], face[1])])
end
return edges
end