42#ifndef UFO_CLOUD_IO_PLY_HPP
43#define UFO_CLOUD_IO_PLY_HPP
46#include <ufo/cloud/point_cloud.hpp>
47#include <ufo/core/intensity.hpp>
48#include <ufo/core/normal.hpp>
49#include <ufo/io/cloud_properties.hpp>
50#include <ufo/io/file_handler.hpp>
51#include <ufo/numeric/vec.hpp>
52#include <ufo/vision/color.hpp>
64bool readPLY(std::filesystem::path
const& file, std::vector<Vec3f>& points,
65 std::vector<SmallRGB>* colors, std::vector<SmallRGBA>* colors_with_alpha,
66 std::vector<Normal>* normals, std::vector<Intensity>* intensities);
68bool writePLY(std::filesystem::path
const& file, std::span<Vec3f const> points,
69 std::span<SmallRGB const> colors,
70 std::span<SmallRGBA const> colors_with_alpha,
71 std::span<Normal const> normals, std::span<Intensity const> intensities,
75[[nodiscard]] CloudProperties cloudPropertiesPLY(std::filesystem::path
const& file);
77template <std::size_t Dim,
class T,
class... Ts>
78bool readPLY(std::filesystem::path
const& file, PointCloud<Dim, T, Ts...>& pc)
80 std::vector<Vec3f> points;
81 std::vector<SmallRGB> colors;
82 std::vector<SmallRGBA> colors_with_alpha;
83 std::vector<Normal> normals;
84 std::vector<Intensity> intensities;
86 std::vector<SmallRGB>* p_colors =
nullptr;
87 std::vector<SmallRGBA>* p_colors_with_alpha =
nullptr;
88 std::vector<Normal>* p_normals =
nullptr;
89 std::vector<Intensity>* p_intensities =
nullptr;
91 if constexpr ((is_color_v<Ts> || ...)) {
92 if constexpr (has_alpha_v<first_color_t<Ts...>>) {
93 p_colors_with_alpha = &colors_with_alpha;
98 if constexpr ((is_normal_v<Ts> || ...)) {
101 if constexpr ((is_intensity_v<Ts> || ...)) {
102 p_intensities = &intensities;
105 if (!detail::readPLY(file, points, p_colors, p_colors_with_alpha, p_normals,
111 pc.resize(points.size());
113 for (std::size_t i{}; points.size() > i; ++i) {
114 view<Vec<Dim, T>>(pc)[i] =
convert<Vec<Dim, T>>(points[i]);
115 if constexpr ((is_color_v<Ts> || ...)) {
116 if constexpr (has_alpha_v<first_color_t<Ts...>>) {
117 view<first_color_t<Ts...>>(pc)[i] =
118 convert<first_color_t<Ts...>>(colors_with_alpha[i]);
120 view<first_color_t<Ts...>>(pc)[i] =
convert<first_color_t<Ts...>>(colors[i]);
123 if constexpr ((is_normal_v<Ts> || ...)) {
124 view<Normal>(pc)[i] = normals[i];
126 if constexpr ((is_intensity_v<Ts> || ...)) {
127 view<Intensity>(pc)[i] = intensities[i];
134template <std::size_t Dim,
class T,
class... Ts>
135bool writePLY(std::filesystem::path
const& file, PointCloud<Dim, T, Ts...>
const& pc,
138 std::vector<Vec3f> points;
139 std::vector<SmallRGB> colors;
140 std::vector<SmallRGBA> colors_with_alpha;
142 for (std::size_t i{}; pc.size() > i; ++i) {
143 if constexpr (!std::is_same_v<Vec3f, Vec<Dim, T>>) {
144 points.push_back(convert<Vec3f>(view<Vec<Dim, T>>(pc)[i]));
147 if constexpr ((is_color_v<Ts> || ...)) {
148 if constexpr (has_alpha_v<first_color_t<Ts...>>) {
149 if constexpr (!std::is_same_v<SmallRGBA, first_color_t<Ts...>>) {
150 colors_with_alpha.push_back(
151 convert<SmallRGBA>(view<first_color_t<Ts...>>(pc)[i]));
154 if constexpr (!std::is_same_v<SmallRGB, first_color_t<Ts...>>) {
155 colors.push_back(convert<SmallRGB>(view<first_color_t<Ts...>>(pc)[i]));
161 std::span<Vec3f const> points_span;
162 std::span<SmallRGB const> colors_span;
163 std::span<SmallRGBA const> colors_with_alpha_span;
164 std::span<Normal const> normals_span;
165 std::span<Intensity const> intensities_span;
167 if constexpr (std::is_same_v<Vec3f, Vec<Dim, T>>) {
168 points_span = view<Vec3f>(pc);
170 points_span = std::span<Vec3f>(points);
173 if constexpr ((is_color_v<Ts> || ...)) {
174 if constexpr (std::is_same_v<SmallRGBA, first_color_t<Ts...>>) {
175 colors_with_alpha_span = view<SmallRGBA>(pc);
176 colors_span = std::span<SmallRGB>(colors);
177 }
else if constexpr (std::is_same_v<SmallRGB, first_color_t<Ts...>>) {
178 colors_span = view<SmallRGB>(pc);
179 colors_with_alpha_span = std::span<SmallRGBA>(colors_with_alpha);
181 colors_span = std::span<SmallRGB>(colors);
182 colors_with_alpha_span = std::span<SmallRGBA>(colors_with_alpha);
186 if constexpr ((is_normal_v<Ts> || ...)) {
187 normals_span = view<Normal>(pc);
190 if constexpr ((is_intensity_v<Ts> || ...)) {
191 intensities_span = view<Intensity>(pc);
194 return detail::writePLY(file, points_span, colors_span, colors_with_alpha_span,
195 normals_span, intensities_span, ascii);
All vision-related classes and functions.
constexpr To convert(Vec< Dim, U > const &v) noexcept
Converts a vector to a different Vec type, truncating or zero-padding dimensions.