IO: minor tweaks to the new C++ PLY importer/exporter

Address some issues discussed in PR #104404:
- Vertex color options changed to None/sRGB/Linear, default is sRGB
  to match the existing Python addon.
- Change name to "Stanford PLY" from "PLY" in the menu item.
- Default "Export UVs" to on.
- After importing vertex colors, they are set as enabled for render.
This commit is contained in:
Aras Pranckevicius 2023-03-05 20:44:20 +02:00
parent 43e9c90061
commit a30abe9c2e
7 changed files with 68 additions and 21 deletions

@ -476,7 +476,7 @@ class TOPBAR_MT_file_import(Menu):
if bpy.app.build_options.io_wavefront_obj:
self.layout.operator("wm.obj_import", text="Wavefront (.obj)")
if bpy.app.build_options.io_ply:
self.layout.operator("wm.ply_import", text="PLY (.ply) (experimental)")
self.layout.operator("wm.ply_import", text="Stanford PLY (.ply) (experimental)")
if bpy.app.build_options.io_stl:
self.layout.operator("wm.stl_import", text="STL (.stl) (experimental)")
@ -506,7 +506,7 @@ class TOPBAR_MT_file_export(Menu):
if bpy.app.build_options.io_wavefront_obj:
self.layout.operator("wm.obj_export", text="Wavefront (.obj)")
if bpy.app.build_options.io_ply:
self.layout.operator("wm.ply_export", text="PLY (.ply) (experimental)")
self.layout.operator("wm.ply_export", text="Stanford PLY (.ply) (experimental)")
class TOPBAR_MT_file_external_data(Menu):

@ -36,6 +36,20 @@
# include "IO_ply.h"
# include "io_ply_ops.h"
static const EnumPropertyItem ply_vertex_colors_mode[] = {
{PLY_VERTEX_COLOR_NONE, "NONE", 0, "None", "Do not import/export color attributes"},
{PLY_VERTEX_COLOR_SRGB,
"SRGB",
0,
"sRGB",
"Vertex colors in the file are in sRGB color space"},
{PLY_VERTEX_COLOR_LINEAR,
"LINEAR",
0,
"Linear",
"Vertex colors in the file are in linear color space"},
{0, NULL, 0, NULL, NULL}};
static int wm_ply_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
ED_fileselect_ensure_default_filepath(C, op, ".ply");
@ -63,7 +77,7 @@ static int wm_ply_export_exec(bContext *C, wmOperator *op)
export_params.export_selected_objects = RNA_boolean_get(op->ptr, "export_selected_objects");
export_params.export_uv = RNA_boolean_get(op->ptr, "export_uv");
export_params.export_normals = RNA_boolean_get(op->ptr, "export_normals");
export_params.export_colors = RNA_boolean_get(op->ptr, "export_colors");
export_params.vertex_colors = RNA_enum_get(op->ptr, "export_colors");
export_params.export_triangulated_mesh = RNA_boolean_get(op->ptr, "export_triangulated_mesh");
export_params.ascii_format = RNA_boolean_get(op->ptr, "ascii_format");
@ -200,15 +214,20 @@ void WM_OT_ply_export(struct wmOperatorType *ot)
false,
"Export Selected Objects",
"Export only selected objects instead of all supported objects");
RNA_def_boolean(ot->srna, "export_uv", false, "Export UVs", "");
RNA_def_boolean(ot->srna, "export_uv", true, "Export UVs", "");
RNA_def_boolean(
ot->srna,
"export_normals",
false,
"Export Vertex Normals",
"Export specific vertex normals if available, export calculated normals otherwise");
RNA_def_boolean(
ot->srna, "export_colors", true, "Export Vertex Colors", "Export per-vertex colors");
RNA_def_enum(ot->srna,
"export_colors",
ply_vertex_colors_mode,
PLY_VERTEX_COLOR_SRGB,
"Export Vertex Colors",
"Export vertex color attributes");
RNA_def_boolean(ot->srna,
"export_triangulated_mesh",
false,
@ -240,6 +259,7 @@ static int wm_ply_import_execute(bContext *C, wmOperator *op)
params.use_scene_unit = RNA_boolean_get(op->ptr, "use_scene_unit");
params.global_scale = RNA_float_get(op->ptr, "global_scale");
params.merge_verts = RNA_boolean_get(op->ptr, "merge_verts");
params.vertex_colors = RNA_enum_get(op->ptr, "import_colors");
int files_len = RNA_collection_length(op->ptr, "files");
@ -319,6 +339,12 @@ void WM_OT_ply_import(struct wmOperatorType *ot)
RNA_def_enum(ot->srna, "forward_axis", io_transform_axis, IO_AXIS_Y, "Forward Axis", "");
RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Z, "Up Axis", "");
RNA_def_boolean(ot->srna, "merge_verts", false, "Merge Vertices", "Merges vertices by distance");
RNA_def_enum(ot->srna,
"import_colors",
ply_vertex_colors_mode,
PLY_VERTEX_COLOR_SRGB,
"Import Vertex Colors",
"Import vertex color attributes");
/* Only show .ply files by default. */
prop = RNA_def_string(ot->srna, "filter_glob", "*.ply", 0, "Extension Filter", "");

@ -16,6 +16,12 @@
extern "C" {
#endif
typedef enum {
PLY_VERTEX_COLOR_NONE = 0,
PLY_VERTEX_COLOR_SRGB = 1,
PLY_VERTEX_COLOR_LINEAR = 2,
} ePLYVertexColorMode;
struct PLYExportParams {
/** Full path to the destination .PLY file. */
char filepath[FILE_MAX];
@ -38,7 +44,7 @@ struct PLYExportParams {
bool apply_modifiers;
bool export_uv;
bool export_normals;
bool export_colors;
ePLYVertexColorMode vertex_colors;
bool export_triangulated_mesh;
};
@ -49,6 +55,7 @@ struct PLYImportParams {
eIOAxis up_axis;
bool use_scene_unit;
float global_scale;
ePLYVertexColorMode vertex_colors;
bool merge_verts;
};

@ -180,7 +180,7 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams
}
/* Colors */
if (export_params.export_colors) {
if (export_params.vertex_colors != PLY_VERTEX_COLOR_NONE) {
const StringRef name = mesh->active_color_attribute;
if (!name.is_empty()) {
const bke::AttributeAccessor attributes = mesh->attributes();
@ -191,6 +191,9 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams
for (int i = 0; i < vertex_map.size(); i++) {
ColorGeometry4f colorGeometry = color_attribute[mesh_vertex_index_LUT[i]];
float4 vertColor(colorGeometry.r, colorGeometry.g, colorGeometry.b, colorGeometry.a);
if (export_params.vertex_colors == PLY_VERTEX_COLOR_SRGB) {
linearrgb_to_srgb_v4(vertColor, vertColor);
}
plyData.vertex_colors.append(vertColor);
}
}
@ -219,8 +222,8 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams
}
Map<UV_vertex_key, int> generate_vertex_map(const Mesh *mesh,
const float2 *uv_map,
const PLYExportParams &export_params)
const float2 *uv_map,
const PLYExportParams &export_params)
{
Map<UV_vertex_key, int> vertex_map;

@ -69,15 +69,24 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams &para
}
/* Vertex colors */
if (!data.vertex_colors.is_empty()) {
if (!data.vertex_colors.is_empty() && params.vertex_colors != PLY_VERTEX_COLOR_NONE) {
/* Create a data layer for vertex colors and set them. */
bke::SpanAttributeWriter<ColorGeometry4f> colors =
attributes.lookup_or_add_for_write_span<ColorGeometry4f>("Col", ATTR_DOMAIN_POINT);
for (int i = 0; i < data.vertex_colors.size(); i++) {
copy_v4_v4(colors.span[i], data.vertex_colors[i]);
if (params.vertex_colors == PLY_VERTEX_COLOR_SRGB) {
for (int i = 0; i < data.vertex_colors.size(); i++) {
srgb_to_linearrgb_v4(colors.span[i], data.vertex_colors[i]);
}
}
else {
for (int i = 0; i < data.vertex_colors.size(); i++) {
copy_v4_v4(colors.span[i], data.vertex_colors[i]);
}
}
colors.finish();
BKE_id_attributes_active_color_set(&mesh->id, "Col");
BKE_id_attributes_default_color_set(&mesh->id, "Col");
}
/* Uvmap */

@ -107,7 +107,7 @@ TEST_F(PlyExportTest, WriteHeaderAscii)
PLYExportParams _params;
_params.ascii_format = true;
_params.export_normals = false;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -145,7 +145,7 @@ TEST_F(PlyExportTest, WriteHeaderBinary)
PLYExportParams _params;
_params.ascii_format = false;
_params.export_normals = false;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -183,7 +183,7 @@ TEST_F(PlyExportTest, WriteVerticesAscii)
PLYExportParams _params;
_params.ascii_format = true;
_params.export_normals = false;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -215,7 +215,7 @@ TEST_F(PlyExportTest, WriteVerticesBinary)
PLYExportParams _params;
_params.ascii_format = false;
_params.export_normals = false;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -257,7 +257,7 @@ TEST_F(PlyExportTest, WriteFacesAscii)
PLYExportParams _params;
_params.ascii_format = true;
_params.export_normals = false;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -287,7 +287,7 @@ TEST_F(PlyExportTest, WriteFacesBinary)
PLYExportParams _params;
_params.ascii_format = false;
_params.export_normals = false;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -330,7 +330,7 @@ TEST_F(PlyExportTest, WriteVertexNormalsAscii)
PLYExportParams _params;
_params.ascii_format = true;
_params.export_normals = true;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -362,7 +362,7 @@ TEST_F(PlyExportTest, WriteVertexNormalsBinary)
PLYExportParams _params;
_params.ascii_format = false;
_params.export_normals = true;
_params.export_colors = false;
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
BLI_strncpy(_params.filepath, filePath.c_str(), 1024);
std::unique_ptr<PlyData> plyData = load_cube(_params);
@ -446,6 +446,7 @@ TEST_F(ply_exporter_ply_data_test, SuzanneLoadPLYDataUV)
{
PLYExportParams params;
params.export_uv = true;
params.vertex_colors = PLY_VERTEX_COLOR_SRGB;
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/suzanne_all_data.blend",
params);
EXPECT_EQ(plyData.UV_coordinates.size(), 542);

@ -41,6 +41,7 @@ class PlyImportTest : public BlendfileLoadingBaseTest {
params.forward_axis = IO_AXIS_NEGATIVE_Z;
params.up_axis = IO_AXIS_Y;
params.merge_verts = false;
params.vertex_colors = PLY_VERTEX_COLOR_NONE;
/* Import the test file. */
std::string ply_path = blender::tests::flags_test_asset_dir() + "/io_tests/ply/" + path;