Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed handling of PLY with vertex colors as uchar #1441

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions libs/yocto/yocto_modelio.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <stdexcept>
#include <string>
#include <vector>
#include <limits>

// -----------------------------------------------------------------------------
// USING DIRECTIVES
Expand Down Expand Up @@ -531,6 +532,24 @@ inline T get_value(const ply_property& prop, size_t index) {
}
return 0;
}
// Assumes T is a floating point type, and any integral type will be divided by
// the max value of its type (matching behavior of Blender PLY import).
template <typename T>
inline T get_normalized_value(const ply_property& prop, size_t index) {
switch (prop.type) {
case ply_type::i8: return (T)prop.data_i8[index]/(T)std::numeric_limits<int8_t>::max();
case ply_type::i16: return (T)prop.data_i16[index]/(T)std::numeric_limits<int16_t>::max();
case ply_type::i32: return (T)prop.data_i32[index]/(T)std::numeric_limits<int32_t>::max();
case ply_type::i64: return (T)prop.data_i64[index]/(T)std::numeric_limits<int64_t>::max();
case ply_type::u8: return (T)prop.data_u8[index]/(T)std::numeric_limits<uint8_t>::max();
case ply_type::u16: return (T)prop.data_u16[index]/(T)std::numeric_limits<uint16_t>::max();
case ply_type::u32: return (T)prop.data_u32[index]/(T)std::numeric_limits<uint32_t>::max();
case ply_type::u64: return (T)prop.data_u64[index]/(T)std::numeric_limits<uint64_t>::max();
case ply_type::f32: return (T)prop.data_f32[index];
case ply_type::f64: return (T)prop.data_f64[index];
}
return 0;
}
template <typename T>
inline bool get_value(const ply_model& ply, const string& element,
const string& property, vector<T>& values) {
Expand All @@ -546,7 +565,7 @@ inline bool get_value(const ply_model& ply, const string& element,
}
template <typename T, size_t N>
inline bool get_values(const ply_model& ply, const string& element,
const array<string, N>& properties, vector<array<T, N>>& values) {
const array<string, N>& properties, bool normalize, vector<array<T, N>>& values) {
values.clear();
for (auto& property : properties) {
if (!has_property(ply, element, property)) return false;
Expand All @@ -558,12 +577,21 @@ inline bool get_values(const ply_model& ply, const string& element,
for (auto& property : properties) {
auto& prop = get_property(ply, element, property);
for (auto index = (size_t)0; index < values.size(); index++) {
values[index][item] = get_value<T>(prop, index);
if(normalize) {
values[index][item] = get_normalized_value<T>(prop, index);
} else {
values[index][item] = get_value<T>(prop, index);
}
}
item++;
}
return true;
}
template <typename T, size_t N>
inline bool get_values(const ply_model& ply, const string& element,
const array<string, N>& properties, vector<array<T, N>>& values) {
return get_values(ply, element, properties, /* normalize */ false, values);
}

template <typename T>
inline bool get_lists(const ply_model& ply, const string& element,
Expand Down Expand Up @@ -766,15 +794,15 @@ inline bool get_texcoords(
}
template <typename T>
inline bool get_colors(const ply_model& ply, vector<array<T, 3>>& colors) {
return get_values(ply, "vertex", {"red", "green", "blue"}, colors);
return get_values(ply, "vertex", {"red", "green", "blue"}, /* normalize */ true, colors);
}
template <typename T>
inline bool get_colors(const ply_model& ply, vector<array<T, 4>>& colors) {
if (has_property(ply, "vertex", "alpha")) {
return get_values(ply, "vertex", {"red", "green", "blue", "alpha"}, colors);
return get_values(ply, "vertex", {"red", "green", "blue", "alpha"}, /* normalize */ true, colors);
} else {
auto colors3 = vector<array<T, 3>>{};
if (!get_values(ply, "vertex", {"red", "green", "blue"}, colors3))
if (!get_values(ply, "vertex", {"red", "green", "blue"}, /* normalize */ true, colors3))
return false;
colors.resize(colors3.size());
for (auto i = 0; i < (int)colors.size(); i++)
Expand Down
195 changes: 195 additions & 0 deletions tests/materials5/materials5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
{
"asset": {
"copyright": "Model by Fabio Pellacini from github.com/~xelatihy/yocto-gl",
"generator": "Yocto/GL - https://github.com/xelatihy/yocto-gl",
"version": "4.2"
},
"cameras": [
{
"name": "default",
"frame": [
0.8151804208755493,
-0.0,
0.579207181930542,
0.16660168766975403,
0.9577393531799316,
-0.23447643220424652,
-0.5547295212745667,
0.28763750195503235,
0.7807304263114929,
-0.75,
0.4000000059604645,
0.8999999761581421
],
"aspect": 2.4000000953674316,
"focus": 1.2168092727661133
}
],
"environments": [
{
"name": "sky",
"emission": [
0.5,
0.5,
0.5
],
"emission_tex": 0
}
],
"textures": [
{
"name": "sky",
"uri": "textures/sky.hdr"
},
{
"name": "floor",
"uri": "textures/floor.png"
}
],
"shapes": [
{
"name": "arealight1",
"uri": "shapes/arealight1.ply"
},
{
"name": "arealight2",
"uri": "shapes/arealight2.ply"
},
{
"name": "floor",
"uri": "shapes/floor.ply"
},
{
"name": "sphere_with_uchar_vertex_colors",
"uri": "shapes/sphere_vertex_colors_uchar.ply"
}
],
"subdivs": [],
"materials": [
{
"name": "arealight1",
"type": "matte",
"emission": [
20,
20,
20
],
"color": [
0,
0,
0
]
},
{
"name": "arealight2",
"type": "matte",
"emission": [
20,
20,
20
],
"color": [
0,
0,
0
]
},
{
"name": "floor",
"type": "matte",
"color": [
1,
1,
1
],
"color_tex": 1
},
{
"name": "vertexcolors",
"type": "matte",
"color": [
1,
1,
1
]
}
],
"instances": [
{
"name": "arealight1",
"frame": [
0.8944271802902222,
-0.0,
0.4472135901451111,
0.27562475204467773,
0.7874992489814758,
-0.5512495040893555,
-0.3521803617477417,
0.6163156628608704,
0.7043607234954834,
-0.4000000059604645,
0.800000011920929,
0.800000011920929
],
"shape": 0,
"material": 0
},
{
"name": "arealight2",
"frame": [
0.8944271802902222,
0.0,
-0.4472135901451111,
-0.27562475204467773,
0.7874992489814758,
-0.5512495040893555,
0.3521803617477417,
0.6163156628608704,
0.7043607234954834,
0.4000000059604645,
0.800000011920929,
0.800000011920929
],
"shape": 1,
"material": 1
},
{
"name": "floor",
"frame": [
1,
0,
0,
0,
1,
0,
0,
0,
1,
0,
0,
0
],
"shape": 2,
"material": 2
},
{
"name": "sphere",
"frame": [
1,
0,
0,
0,
1,
0,
0,
0,
1,
-0.4,
0,
0
],
"shape": 3,
"material": 3
}
]
}
Binary file added tests/materials5/shapes/arealight1.ply
Binary file not shown.
Binary file added tests/materials5/shapes/arealight2.ply
Binary file not shown.
Binary file added tests/materials5/shapes/floor.ply
Binary file not shown.
Binary file not shown.
Binary file added tests/materials5/textures/floor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/materials5/textures/sky.hdr
Binary file not shown.