/
pcloud.jl
84 lines (65 loc) · 2.45 KB
/
pcloud.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
export PointCloud, npoints
"""
PointCloud
Initialize PointCloud representation.
`points` should be Array of size `(D, N, B)` where `N` is the number of points, `D` is
dimensionality of each points (i.e. `D`=2 or `D`=3) and `B` is the batch size of PointCloud.
`normals` is optional field, if given should be Array of size `(D, N, B)` where `N` and `B`
should match with the `N` and `B` of `points` and `D`=2 or `D`=3
(i.e. normals for 2D and 3D PointCloud respectively).
### Fields:
- `points` - Points that makes up whole PointCloud.
- `normals` - Normals of each points in PointCloud.
### Available Contructor:
- `PointCloud(points, normals=nothing)`
- `PointCloud(;points, normals=nothing)`
- `PointCloud(pcloud::PointCloud)`
"""
mutable struct PointCloud{T<:Float32} <: AbstractObject
points::AbstractArray{T,3}
normals::Union{AbstractArray{T,3},Nothing}
end
function PointCloud(
points::AbstractArray{Float32,2},
normals::Union{AbstractArray{Float32,2},Nothing} = nothing,
)
points = reshape(points, size(points)..., 1)
if !(normals isa Nothing)
size(points, 2) == size(normals, 2) ||
error("number of points and normals must match in PointCloud.")
normals = reshape(normals, size(normals)..., 1)
end
return PointCloud(points, normals)
end
function PointCloud(points::AbstractArray, normals::Union{AbstractArray,Nothing} = nothing)
points = Float32.(points)
if normals !== nothing
normals = Float32.(normals)
end
return PointCloud(points, normals)
end
PointCloud(; points, normals = nothing) = PointCloud(points, normals)
PointCloud(pcloud::PointCloud) = PointCloud(pcloud.points, pcloud.normals)
@functor PointCloud
# deepcopy generate error when using on PointCloud with parent field of points not Nothing
Base.deepcopy_internal(x::PointCloud, dict::IdDict) =
PointCloud(copy(x.points), (x.normals === nothing ? nothing : copy(x.normals)))
Base.getindex(p::PointCloud, index::Number) = p.points[:, :, index]
function Base.show(io::IO, m::PointCloud{T}) where {T}
print(
io,
"PointCloud{$(T)} Structure:\n Batch size: ",
size(m.points, 3),
"\n Points: ",
size(m.points, 2),
"\n Normals ",
(m.normals === nothing ? 0 : size(m.normals, 2)),
"\n Storage type: ",
typeof(m.points),
)
end
"""
npoints(p::PointCloud)
Returns the size of PointCloud.
"""
npoints(p::PointCloud) = size(p.points, 2)