Add Chromium-only Blender WebEngine parity work
This commit is contained in:
@@ -0,0 +1,552 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "testing/testing.h"
|
||||
#include "tests/blendfile_loading_base_test.h"
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_appdir.hh"
|
||||
#include "BKE_blender_version.h"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
#include "IO_ply.hh"
|
||||
#include "intern/ply_data.hh"
|
||||
|
||||
#include "ply_export_data.hh"
|
||||
#include "ply_export_header.hh"
|
||||
#include "ply_export_load_plydata.hh"
|
||||
#include "ply_file_buffer_ascii.hh"
|
||||
#include "ply_file_buffer_binary.hh"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace blender::io::ply {
|
||||
|
||||
class PLYExportTest : public BlendfileLoadingBaseTest {
|
||||
public:
|
||||
bool load_file_and_depsgraph(const std::string &filepath,
|
||||
const eEvaluationMode eval_mode = DAG_EVAL_VIEWPORT)
|
||||
{
|
||||
if (!blendfile_load(filepath.c_str())) {
|
||||
return false;
|
||||
}
|
||||
depsgraph_create(eval_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
BlendfileLoadingBaseTest::SetUp();
|
||||
|
||||
BKE_tempdir_init(nullptr);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
BlendfileLoadingBaseTest::TearDown();
|
||||
|
||||
BKE_tempdir_session_purge();
|
||||
}
|
||||
|
||||
std::string get_temp_ply_filename(const std::string &filename)
|
||||
{
|
||||
return std::string(BKE_tempdir_session()) + SEP_STR + filename;
|
||||
}
|
||||
};
|
||||
|
||||
static std::unique_ptr<PlyData> load_cube(PLYExportParams ¶ms)
|
||||
{
|
||||
std::unique_ptr<PlyData> plyData = std::make_unique<PlyData>();
|
||||
plyData->vertices = {
|
||||
{1.122082, 1.122082, 1.122082},
|
||||
{1.122082, 1.122082, -1.122082},
|
||||
{1.122082, -1.122082, 1.122082},
|
||||
{1.122082, -1.122082, -1.122082},
|
||||
{-1.122082, 1.122082, 1.122082},
|
||||
{-1.122082, 1.122082, -1.122082},
|
||||
{-1.122082, -1.122082, 1.122082},
|
||||
{-1.122082, -1.122082, -1.122082},
|
||||
};
|
||||
|
||||
plyData->face_sizes = {4, 4, 4, 4, 4, 4};
|
||||
plyData->face_vertices = {0, 2, 6, 4, 3, 7, 6, 2, 7, 5, 4, 6,
|
||||
5, 7, 3, 1, 1, 3, 2, 0, 5, 1, 0, 4};
|
||||
|
||||
if (params.export_normals) {
|
||||
plyData->vertex_normals = {
|
||||
{-0.5773503, -0.5773503, -0.5773503},
|
||||
{-0.5773503, -0.5773503, 0.5773503},
|
||||
{-0.5773503, 0.5773503, -0.5773503},
|
||||
{-0.5773503, 0.5773503, 0.5773503},
|
||||
{0.5773503, -0.5773503, -0.5773503},
|
||||
{0.5773503, -0.5773503, 0.5773503},
|
||||
{0.5773503, 0.5773503, -0.5773503},
|
||||
{0.5773503, 0.5773503, 0.5773503},
|
||||
};
|
||||
}
|
||||
|
||||
return plyData;
|
||||
}
|
||||
|
||||
/* The following is relative to BKE_tempdir_base.
|
||||
* Use Latin Capital Letter A with Ogonek, Cyrillic Capital Letter Zhe
|
||||
* at the end, to test I/O on non-English file names. */
|
||||
const char *const temp_file_path = "output\xc4\x84\xd0\x96.ply";
|
||||
|
||||
static std::string read_temp_file_in_string(const std::string &file_path)
|
||||
{
|
||||
std::string res;
|
||||
size_t buffer_len;
|
||||
char *buffer = BLI_file_read_text_as_mem(file_path.c_str(), 0, &buffer_len);
|
||||
if (buffer != nullptr) {
|
||||
res.assign(buffer, buffer_len);
|
||||
MEM_delete(buffer);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static char read(std::ifstream &file)
|
||||
{
|
||||
char return_val;
|
||||
file.read(&return_val, sizeof(return_val));
|
||||
return return_val;
|
||||
}
|
||||
|
||||
static std::vector<char> read_temp_file_in_vectorchar(const std::string &file_path)
|
||||
{
|
||||
std::vector<char> res;
|
||||
std::ifstream infile(file_path, std::ios::binary);
|
||||
while (true) {
|
||||
uint64_t c = read(infile);
|
||||
if (!infile.eof()) {
|
||||
res.push_back(c);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteHeaderAscii)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferAscii>(_params.filepath);
|
||||
|
||||
write_header(*buffer, *plyData, _params);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::string result = read_temp_file_in_string(filePath);
|
||||
|
||||
StringRef version = BKE_blender_version_string();
|
||||
|
||||
std::string expected =
|
||||
"ply\n"
|
||||
"format ascii 1.0\n"
|
||||
"comment Created in Blender version " +
|
||||
version +
|
||||
"\n"
|
||||
"element vertex 8\n"
|
||||
"property float x\n"
|
||||
"property float y\n"
|
||||
"property float z\n"
|
||||
"element face 6\n"
|
||||
"property list uchar uint vertex_indices\n"
|
||||
"end_header\n";
|
||||
|
||||
ASSERT_STREQ(result.c_str(), expected.c_str());
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteHeaderBinary)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferBinary>(_params.filepath);
|
||||
|
||||
write_header(*buffer, *plyData, _params);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::string result = read_temp_file_in_string(filePath);
|
||||
|
||||
StringRef version = BKE_blender_version_string();
|
||||
|
||||
std::string expected =
|
||||
"ply\n"
|
||||
"format binary_little_endian 1.0\n"
|
||||
"comment Created in Blender version " +
|
||||
version +
|
||||
"\n"
|
||||
"element vertex 8\n"
|
||||
"property float x\n"
|
||||
"property float y\n"
|
||||
"property float z\n"
|
||||
"element face 6\n"
|
||||
"property list uchar uint vertex_indices\n"
|
||||
"end_header\n";
|
||||
|
||||
ASSERT_STREQ(result.c_str(), expected.c_str());
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteVerticesAscii)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferAscii>(_params.filepath);
|
||||
|
||||
write_vertices(*buffer, *plyData);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::string result = read_temp_file_in_string(filePath);
|
||||
|
||||
std::string expected =
|
||||
"1.122082 1.122082 1.122082\n"
|
||||
"1.122082 1.122082 -1.122082\n"
|
||||
"1.122082 -1.122082 1.122082\n"
|
||||
"1.122082 -1.122082 -1.122082\n"
|
||||
"-1.122082 1.122082 1.122082\n"
|
||||
"-1.122082 1.122082 -1.122082\n"
|
||||
"-1.122082 -1.122082 1.122082\n"
|
||||
"-1.122082 -1.122082 -1.122082\n";
|
||||
|
||||
ASSERT_STREQ(result.c_str(), expected.c_str());
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteVerticesBinary)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferBinary>(_params.filepath);
|
||||
|
||||
write_vertices(*buffer, *plyData);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::vector<char> result = read_temp_file_in_vectorchar(filePath);
|
||||
|
||||
std::vector<char> expected({
|
||||
0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0,
|
||||
0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F,
|
||||
0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0,
|
||||
0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F,
|
||||
0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0,
|
||||
0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F,
|
||||
0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF,
|
||||
});
|
||||
|
||||
ASSERT_EQ(result.size(), expected.size());
|
||||
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
ASSERT_EQ(result[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteFacesAscii)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferAscii>(_params.filepath);
|
||||
|
||||
write_faces(*buffer, *plyData);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::string result = read_temp_file_in_string(filePath);
|
||||
|
||||
std::string expected =
|
||||
"4 0 2 6 4\n"
|
||||
"4 3 7 6 2\n"
|
||||
"4 7 5 4 6\n"
|
||||
"4 5 7 3 1\n"
|
||||
"4 1 3 2 0\n"
|
||||
"4 5 1 0 4\n";
|
||||
|
||||
ASSERT_STREQ(result.c_str(), expected.c_str());
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteFacesBinary)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferBinary>(_params.filepath);
|
||||
|
||||
write_faces(*buffer, *plyData);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::vector<char> result = read_temp_file_in_vectorchar(filePath);
|
||||
|
||||
std::vector<char> expected({
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
});
|
||||
|
||||
ASSERT_EQ(result.size(), expected.size());
|
||||
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
ASSERT_EQ(result[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteVertexNormalsAscii)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = true;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferAscii>(_params.filepath);
|
||||
|
||||
write_vertices(*buffer, *plyData);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::string result = read_temp_file_in_string(filePath);
|
||||
|
||||
std::string expected =
|
||||
"1.122082 1.122082 1.122082 -0.5773503 -0.5773503 -0.5773503\n"
|
||||
"1.122082 1.122082 -1.122082 -0.5773503 -0.5773503 0.5773503\n"
|
||||
"1.122082 -1.122082 1.122082 -0.5773503 0.5773503 -0.5773503\n"
|
||||
"1.122082 -1.122082 -1.122082 -0.5773503 0.5773503 0.5773503\n"
|
||||
"-1.122082 1.122082 1.122082 0.5773503 -0.5773503 -0.5773503\n"
|
||||
"-1.122082 1.122082 -1.122082 0.5773503 -0.5773503 0.5773503\n"
|
||||
"-1.122082 -1.122082 1.122082 0.5773503 0.5773503 -0.5773503\n"
|
||||
"-1.122082 -1.122082 -1.122082 0.5773503 0.5773503 0.5773503\n";
|
||||
|
||||
ASSERT_STREQ(result.c_str(), expected.c_str());
|
||||
}
|
||||
|
||||
TEST_F(PLYExportTest, WriteVertexNormalsBinary)
|
||||
{
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params;
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = true;
|
||||
_params.vertex_colors = ePLYVertexColorMode::None;
|
||||
STRNCPY(_params.filepath, filePath.c_str());
|
||||
|
||||
std::unique_ptr<PlyData> plyData = load_cube(_params);
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer = std::make_unique<FileBufferBinary>(_params.filepath);
|
||||
|
||||
write_vertices(*buffer, *plyData);
|
||||
|
||||
buffer->close_file();
|
||||
|
||||
std::vector<char> result = read_temp_file_in_vectorchar(filePath);
|
||||
|
||||
std::vector<char> expected({
|
||||
0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0x3F, 0x3B, 0xCD, 0x13,
|
||||
0xBF, 0x3B, 0xCD, 0x13, 0xBF, 0x3B, 0xCD, 0x13, 0xBF, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0,
|
||||
0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x3B, 0xCD, 0x13, 0xBF, 0x3B, 0xCD, 0x13, 0xBF, 0x3B,
|
||||
0xCD, 0x13, 0x3F, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F,
|
||||
0x3B, 0xCD, 0x13, 0xBF, 0x3B, 0xCD, 0x13, 0x3F, 0x3B, 0xCD, 0x13, 0xBF, 0x62, 0xA0, 0x8F,
|
||||
0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x3B, 0xCD, 0x13, 0xBF, 0x3B, 0xCD,
|
||||
0x13, 0x3F, 0x3B, 0xCD, 0x13, 0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F, 0x62,
|
||||
0xA0, 0x8F, 0x3F, 0x3B, 0xCD, 0x13, 0x3F, 0x3B, 0xCD, 0x13, 0xBF, 0x3B, 0xCD, 0x13, 0xBF,
|
||||
0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x3B, 0xCD, 0x13,
|
||||
0x3F, 0x3B, 0xCD, 0x13, 0xBF, 0x3B, 0xCD, 0x13, 0x3F, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0,
|
||||
0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0x3F, 0x3B, 0xCD, 0x13, 0x3F, 0x3B, 0xCD, 0x13, 0x3F, 0x3B,
|
||||
0xCD, 0x13, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF, 0x62, 0xA0, 0x8F, 0xBF,
|
||||
0x3B, 0xCD, 0x13, 0x3F, 0x3B, 0xCD, 0x13, 0x3F, 0x3B, 0xCD, 0x13, 0x3F,
|
||||
});
|
||||
|
||||
ASSERT_EQ(result.size(), expected.size());
|
||||
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
ASSERT_EQ(result[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
class PLYExportPLYDataTest : public PLYExportTest {
|
||||
public:
|
||||
PlyData load_ply_data_from_blendfile(const std::string &blendfile, PLYExportParams ¶ms)
|
||||
{
|
||||
PlyData data;
|
||||
if (!load_file_and_depsgraph(blendfile)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
load_plydata(data, depsgraph, params);
|
||||
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(PLYExportPLYDataTest, CubeLoadPLYData)
|
||||
{
|
||||
PLYExportParams params;
|
||||
params.export_uv = false;
|
||||
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/cube_all_data.blend",
|
||||
params);
|
||||
EXPECT_EQ(plyData.vertices.size(), 8);
|
||||
EXPECT_EQ(plyData.uv_coordinates.size(), 0);
|
||||
}
|
||||
TEST_F(PLYExportPLYDataTest, CubeLoadPLYDataUV)
|
||||
{
|
||||
PLYExportParams params;
|
||||
params.export_uv = true;
|
||||
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/cube_all_data.blend",
|
||||
params);
|
||||
EXPECT_EQ(plyData.vertices.size(), 8);
|
||||
EXPECT_EQ(plyData.uv_coordinates.size(), 8);
|
||||
}
|
||||
TEST_F(PLYExportPLYDataTest, CubeLooseEdgesLoadPLYData)
|
||||
{
|
||||
PLYExportParams params;
|
||||
params.export_uv = false;
|
||||
params.forward_axis = IO_AXIS_Y;
|
||||
params.up_axis = IO_AXIS_Z;
|
||||
params.global_scale = 1.0f;
|
||||
PlyData plyData = load_ply_data_from_blendfile(
|
||||
"io_tests/blend_geometry/cube_loose_edges_verts.blend", params);
|
||||
float3 exp_vertices[] = {
|
||||
{1, 1, 1},
|
||||
{1, 1, -1},
|
||||
{1, -1, 1},
|
||||
{1, -1, -1},
|
||||
{-1, 1, 1},
|
||||
{-1, 1, -1},
|
||||
{-1, -1, 1},
|
||||
{-1, -1, -1},
|
||||
};
|
||||
std::pair<int, int> exp_edges[] = {{7, 6}, {6, 4}};
|
||||
uint32_t exp_face_sizes[] = {4, 4};
|
||||
uint32_t exp_faces[] = {5, 1, 3, 7, 5, 4, 0, 1};
|
||||
EXPECT_EQ(plyData.vertices.size(), ARRAY_SIZE(exp_vertices));
|
||||
EXPECT_EQ(plyData.uv_coordinates.size(), 0);
|
||||
EXPECT_EQ(plyData.edges.size(), ARRAY_SIZE(exp_edges));
|
||||
EXPECT_EQ(plyData.face_sizes.size(), ARRAY_SIZE(exp_face_sizes));
|
||||
EXPECT_EQ(plyData.face_vertices.size(), ARRAY_SIZE(exp_faces));
|
||||
EXPECT_EQ_ARRAY(exp_vertices, plyData.vertices.data(), ARRAY_SIZE(exp_vertices));
|
||||
EXPECT_EQ_ARRAY(exp_edges, plyData.edges.data(), ARRAY_SIZE(exp_edges));
|
||||
EXPECT_EQ_ARRAY(exp_face_sizes, plyData.face_sizes.data(), ARRAY_SIZE(exp_face_sizes));
|
||||
EXPECT_EQ_ARRAY(exp_faces, plyData.face_vertices.data(), ARRAY_SIZE(exp_faces));
|
||||
}
|
||||
TEST_F(PLYExportPLYDataTest, CubeLooseEdgesLoadPLYDataUV)
|
||||
{
|
||||
PLYExportParams params;
|
||||
params.forward_axis = IO_AXIS_Y;
|
||||
params.up_axis = IO_AXIS_Z;
|
||||
params.global_scale = 1.0f;
|
||||
params.export_uv = true;
|
||||
PlyData plyData = load_ply_data_from_blendfile(
|
||||
"io_tests/blend_geometry/cube_loose_edges_verts.blend", params);
|
||||
float3 exp_vertices[] = {
|
||||
{-1, 1, -1},
|
||||
{1, 1, -1},
|
||||
{1, -1, -1},
|
||||
{-1, -1, -1},
|
||||
{-1, 1, -1},
|
||||
{-1, 1, 1},
|
||||
{1, 1, 1},
|
||||
{1, -1, 1},
|
||||
{-1, -1, 1},
|
||||
};
|
||||
float2 exp_uv[] = {
|
||||
{0.125f, 0.5f},
|
||||
{0.375f, 0.5f},
|
||||
{0.375f, 0.75f},
|
||||
{0.125f, 0.75f},
|
||||
{0.375f, 0.25f},
|
||||
{0.625f, 0.25f},
|
||||
{0.625f, 0.5f},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
};
|
||||
std::pair<int, int> exp_edges[] = {{3, 8}, {8, 5}};
|
||||
uint32_t exp_face_sizes[] = {4, 4};
|
||||
uint32_t exp_faces[] = {0, 1, 2, 3, 4, 5, 6, 1};
|
||||
EXPECT_EQ(plyData.vertices.size(), 9);
|
||||
EXPECT_EQ(plyData.uv_coordinates.size(), 9);
|
||||
EXPECT_EQ(plyData.edges.size(), ARRAY_SIZE(exp_edges));
|
||||
EXPECT_EQ(plyData.face_sizes.size(), ARRAY_SIZE(exp_face_sizes));
|
||||
EXPECT_EQ(plyData.face_vertices.size(), ARRAY_SIZE(exp_faces));
|
||||
EXPECT_EQ_ARRAY(exp_vertices, plyData.vertices.data(), ARRAY_SIZE(exp_vertices));
|
||||
EXPECT_EQ_ARRAY(exp_uv, plyData.uv_coordinates.data(), ARRAY_SIZE(exp_uv));
|
||||
EXPECT_EQ_ARRAY(exp_edges, plyData.edges.data(), ARRAY_SIZE(exp_edges));
|
||||
EXPECT_EQ_ARRAY(exp_face_sizes, plyData.face_sizes.data(), ARRAY_SIZE(exp_face_sizes));
|
||||
EXPECT_EQ_ARRAY(exp_faces, plyData.face_vertices.data(), ARRAY_SIZE(exp_faces));
|
||||
}
|
||||
|
||||
TEST_F(PLYExportPLYDataTest, CubesVertexAttrs)
|
||||
{
|
||||
PLYExportParams params;
|
||||
params.export_uv = true;
|
||||
params.export_attributes = true;
|
||||
PlyData plyData = load_ply_data_from_blendfile(
|
||||
"io_tests/blend_geometry/cubes_vertex_attrs.blend", params);
|
||||
EXPECT_EQ(plyData.vertices.size(), 28);
|
||||
EXPECT_EQ(plyData.vertex_custom_attr.size(), 11); /* Float 1 + Color 4 + ByteColor 4 + Int2D 2 */
|
||||
EXPECT_EQ(plyData.vertex_custom_attr[0].data.size(), 28);
|
||||
}
|
||||
|
||||
TEST_F(PLYExportPLYDataTest, SuzanneLoadPLYDataUV)
|
||||
{
|
||||
PLYExportParams params;
|
||||
params.export_uv = true;
|
||||
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/suzanne_all_data.blend",
|
||||
params);
|
||||
EXPECT_EQ(plyData.uv_coordinates.size(), 542);
|
||||
}
|
||||
|
||||
} // namespace blender::io::ply
|
||||
@@ -0,0 +1,77 @@
|
||||
/* SPDX-FileCopyrightText: 2023-2025 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "BLI_path_utils.hh"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "ply_import.hh"
|
||||
#include "ply_import_buffer.hh"
|
||||
#include "ply_import_data.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
static CLG_LogRef LOG = {"io.ply"};
|
||||
|
||||
namespace io::ply {
|
||||
|
||||
/* Extensive tests for PLY importing are in `io_ply_import_test.py`.
|
||||
* The tests here are only for testing PLY reader buffer refill behavior,
|
||||
* by using a very small buffer size on purpose. */
|
||||
|
||||
TEST(ply_import, BufferRefillTest)
|
||||
{
|
||||
std::string ply_path_a = tests::flags_test_asset_dir() +
|
||||
SEP_STR "io_tests" SEP_STR "ply" SEP_STR + "ASCII_wireframe_cube.ply";
|
||||
std::string ply_path_b = tests::flags_test_asset_dir() +
|
||||
SEP_STR "io_tests" SEP_STR "ply" SEP_STR + "wireframe_cube.ply";
|
||||
|
||||
/* Use a small read buffer size to test buffer refilling behavior. */
|
||||
constexpr size_t buffer_size = 50;
|
||||
PlyReadBuffer infile_a(ply_path_a.c_str(), buffer_size);
|
||||
PlyReadBuffer infile_b(ply_path_b.c_str(), buffer_size);
|
||||
PlyHeader header_a, header_b;
|
||||
const char *header_err_a = read_header(infile_a, header_a);
|
||||
const char *header_err_b = read_header(infile_b, header_b);
|
||||
if (header_err_a != nullptr || header_err_b != nullptr) {
|
||||
CLOG_ERROR(&LOG, "Failed to read PLY header");
|
||||
ADD_FAILURE();
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<PlyData> data_a = import_ply_data(infile_a, header_a);
|
||||
std::unique_ptr<PlyData> data_b = import_ply_data(infile_b, header_b);
|
||||
if (!data_a->error.empty() || !data_b->error.empty()) {
|
||||
CLOG_ERROR(&LOG, "Failed to read PLY data");
|
||||
ADD_FAILURE();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check whether the edges list matches expectations. */
|
||||
std::pair<int, int> exp_edges[] = {{2, 0},
|
||||
{0, 1},
|
||||
{1, 3},
|
||||
{3, 2},
|
||||
{6, 2},
|
||||
{3, 7},
|
||||
{7, 6},
|
||||
{4, 6},
|
||||
{7, 5},
|
||||
{5, 4},
|
||||
{0, 4},
|
||||
{5, 1}};
|
||||
EXPECT_EQ_SPAN<std::pair<int, int>>(Span(exp_edges, 12), data_a->edges);
|
||||
EXPECT_EQ_SPAN<std::pair<int, int>>(Span(exp_edges, 12), data_b->edges);
|
||||
}
|
||||
|
||||
//@TODO: now we put vertex color attribute first, maybe put position first?
|
||||
//@TODO: test with vertex element having list properties
|
||||
//@TODO: test with edges starting with non-vertex index properties
|
||||
//@TODO: test various malformed headers
|
||||
//@TODO: UVs with: s,t; u,v; texture_u,texture_v; texture_s,texture_t (from miniply)
|
||||
//@TODO: colors with: r,g,b in addition to red,green,blue (from miniply)
|
||||
|
||||
} // namespace io::ply
|
||||
} // namespace blender
|
||||
Reference in New Issue
Block a user