16#include "fast_float.h"
41static const char *
drop_plus(
const char *p,
const char *end)
43 if (p < end && *p ==
'+') {
49static const char *
parse_float(
const char *p,
const char *end,
float fallback,
float &dst)
53 fast_float::from_chars_result res = fast_float::from_chars(p, end, dst);
54 if (
ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
60static const char *
parse_int(
const char *p,
const char *end,
int fallback,
int &dst)
64 std::from_chars_result res = std::from_chars(p, end, dst);
65 if (
ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
76 else if (type_size == 4) {
79 else if (type_size == 8) {
89 else if (type_size == 4) {
92 else if (type_size == 8) {
103 1.0f, 127.0f, 255.0f, 32767.0f, 65535.0f,
float(INT_MAX),
float(
UINT_MAX), 1.0f, 1.0f};
105 "PLY data type normalization factor table mismatch");
121 for (
int i = 0, n =
int(
element.properties.size()); i != n; i++) {
123 if (prop.
name == property) {
134 return "Could not read row of ascii property";
138 const char *p = line.
data();
139 const char *end = p + line.
size();
141 while (p < end && value_idx < r_values.
size()) {
144 r_values[value_idx++] = val;
180 val = *(
float *)r_ptr;
184 val = *(
double *)r_ptr;
200 return "Vertex/Edge element contains list properties, this is not supported";
205 return "Could not read row of binary property";
211 for (
int i = 0, n =
int(
element.properties.size()); i != n; i++) {
219 for (
int i = 0, n =
int(
element.properties.size()); i != n; i++) {
227 return "Unknown binary ply format for vertex element";
241 int3 normal_index = {
246 bool has_vertex = vertex_index.x >= 0 && vertex_index.y >= 0 && vertex_index.z >= 0;
247 bool has_color = color_index.x >= 0 && color_index.y >= 0 && color_index.z >= 0;
248 bool has_normal = normal_index.x >= 0 && normal_index.y >= 0 && normal_index.z >= 0;
249 bool has_uv = uv_index.x >= 0 && uv_index.y >= 0;
250 bool has_alpha = alpha_index >= 0;
253 return "Vertex positions are not present in the file";
259 bool is_standard =
ELEM(
260 prop.
name,
"x",
"y",
"z",
"nx",
"ny",
"nz",
"red",
"green",
"blue",
"alpha",
"s",
"t");
264 custom_attr_indices.
append(prop_idx);
266 data->vertex_custom_attr.append(attr);
280 float4 color_norm = {1, 1, 1, 1};
296 for (
int i = 0; i <
element.count; i++) {
298 const char *
error =
nullptr;
305 if (
error !=
nullptr) {
311 vertex3.x = value_vec[vertex_index.x];
312 vertex3.y = value_vec[vertex_index.y];
313 vertex3.z = value_vec[vertex_index.z];
314 data->vertices.append(vertex3);
319 colors4.x = value_vec[color_index.x] / color_norm.x;
320 colors4.y = value_vec[color_index.y] / color_norm.y;
321 colors4.z = value_vec[color_index.z] / color_norm.z;
323 colors4.w = value_vec[alpha_index] / color_norm.w;
328 data->vertex_colors.append(colors4);
334 normals3.x = value_vec[normal_index.x];
335 normals3.y = value_vec[normal_index.y];
336 normals3.z = value_vec[normal_index.z];
337 data->vertex_normals.append(normals3);
343 uvmap.x = value_vec[uv_index.x];
344 uvmap.y = value_vec[uv_index.y];
345 data->uv_coordinates.append(uvmap);
350 float value = value_vec[custom_attr_indices[ci]];
351 data->vertex_custom_attr[ci].data[i] = value;
394 if (prop_index < 0) {
397 if (prop_index < 0 &&
element.properties.size() == 1) {
400 if (prop_index < 0) {
401 return "Face element does not contain vertex indices property";
405 return "Face element vertex indices property must be a list";
412 for (
int i = 0; i <
element.count; i++) {
416 const char *p = line.
data();
417 const char *end = p + line.
size();
421 for (
int j = 0; j < prop_index; j++) {
428 for (
int k = 0; k <
count; ++k) {
438 return "Invalid face size, must be between 1 and 255";
443 fprintf(stderr,
"PLY Importer: ignoring face %i (%i vertices)\n", i,
count);
447 for (
int j = 0; j <
count; j++) {
450 data->face_vertices.append(index);
458 for (
int i = 0; i <
element.count; i++) {
462 for (
int j = 0; j < prop_index; j++) {
471 return "Invalid face size, must be between 1 and 255";
479 fprintf(stderr,
"PLY Importer: ignoring face %i (%i vertices)\n", i,
int(
count));
486 for (
int j = 0; j <
count; ++j) {
488 data->face_vertices.append(index);
494 for (
int j = prop_index + 1; j <
element.properties.size(); j++) {
509 return "Tristrips element should contain one row";
511 if (
element.properties.size() != 1) {
512 return "Tristrips element should contain one property";
516 return "Tristrips element property must be a list";
524 const char *p = line.
data();
525 const char *end = p + line.
size();
530 for (
int j = 0; j <
count; j++) {
550 for (
int j = 0; j <
count; ++j) {
559 for (
size_t i = 0; i < strip.
size(); i++) {
560 if (strip[i] == -1) {
564 else if (i - start >= 2) {
565 int a = strip[i - 2],
b = strip[i - 1], c = strip[i];
567 if ((i - start) & 1) {
571 if (a !=
b && a != c &&
b != c) {
572 data->face_vertices.append(a);
573 data->face_vertices.append(
b);
574 data->face_vertices.append(c);
575 data->face_sizes.append(3);
589 if (prop_vertex1 < 0 || prop_vertex2 < 0) {
590 return "Edge element does not contain vertex1 and vertex2 properties";
601 for (
int i = 0; i <
element.count; i++) {
602 const char *
error =
nullptr;
609 if (
error !=
nullptr) {
612 int index1 = value_vec[prop_vertex1];
613 int index2 = value_vec[prop_vertex2];
614 data->edges.append(std::make_pair(index1, index2));
624 for (
int i = 0; i <
element.count; i++) {
631 for (
int i = 0; i <
element.count; i++) {
642 std::unique_ptr<PlyData>
data = std::make_unique<PlyData>();
644 bool got_vertex =
false, got_face =
false, got_tristrips =
false, got_edge =
false;
646 const char *
error =
nullptr;
647 if (
element.name ==
"vertex") {
651 else if (
element.name ==
"face") {
655 else if (
element.name ==
"tristrips") {
657 got_tristrips =
true;
659 else if (
element.name ==
"edge") {
666 if (
error !=
nullptr) {
670 if (got_vertex && got_face && got_tristrips && got_edge) {
#define BLI_assert_msg(a, msg)
BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) ATTR_NONNULL(1)
BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val) ATTR_NONNULL(1)
void BLI_endian_switch_uint16_array(unsigned short *val, int size) ATTR_NONNULL(1)
BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val) ATTR_NONNULL(1)
void BLI_endian_switch_uint64_array(uint64_t *val, int size) ATTR_NONNULL(1)
void BLI_endian_switch_uint32_array(unsigned int *val, int size) ATTR_NONNULL(1)
ATTR_WARN_UNUSED_RESULT const void * element
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr const T * data() const
constexpr int64_t size() const
constexpr bool is_empty() const
void append(const T &value)
IndexRange index_range() const
void resize(const int64_t new_size)
bool read_bytes(void *dst, size_t size)
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
static void error(const char *str)
static const char * load_face_element(PlyReadBuffer &file, const PlyHeader &header, const PlyElement &element, PlyData *data)
static const char * load_edge_element(PlyReadBuffer &file, const PlyHeader &header, const PlyElement &element, PlyData *data)
static const char * parse_row_ascii(PlyReadBuffer &file, Vector< float > &r_values)
static const char * parse_row_binary(PlyReadBuffer &file, const PlyHeader &header, const PlyElement &element, Vector< uint8_t > &r_scratch, Vector< float > &r_values)
static const char * load_vertex_element(PlyReadBuffer &file, const PlyHeader &header, const PlyElement &element, PlyData *data)
static uint32_t read_list_count(PlyReadBuffer &file, const PlyProperty &prop, Vector< uint8_t > &scratch, bool big_endian)
static const char * load_tristrips_element(PlyReadBuffer &file, const PlyHeader &header, const PlyElement &element, PlyData *data)
static int get_index(const PlyElement &element, StringRef property)
std::unique_ptr< PlyData > import_ply_data(PlyReadBuffer &file, PlyHeader &header)
static const int data_type_size[]
static const float data_type_normalizer[]
static void skip_property(PlyReadBuffer &file, const PlyProperty &prop, Vector< uint8_t > &scratch, bool big_endian)
static T get_binary_value(PlyDataTypes type, const uint8_t *&r_ptr)
static const char * skip_element(PlyReadBuffer &file, const PlyHeader &header, const PlyElement &element)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
static void endian_switch_array(uint8_t *ptr, int type_size, int size)
static void endian_switch(uint8_t *ptr, int type_size)
static const char * drop_plus(const char *p, const char *end)
static const char * parse_int(const char *p, const char *end, int fallback, int &dst)
static const char * drop_whitespace(const char *p, const char *end)
static bool is_whitespace(char c)
static const char * parse_float(const char *p, const char *end, float fallback, float &dst)
static const char * drop_non_whitespace(const char *p, const char *end)
unsigned __int64 uint64_t
Vector< PlyProperty > properties