Collection Export: Enable STL and PLY exporters
Enables the STL and PLY formats for Collection export. Changes - Set the export operator on the File handlers - Plumb through the `collection` property and make use of it while building the depsgraph - Skip drawing the "Selection only" and "Batch" mode options when used with collections Pull Request: https://projects.blender.org/blender/blender/pulls/120944
This commit is contained in:
committed by
Jesse Yurkovich
parent
49bd285529
commit
32ed9bb107
@@ -28,8 +28,6 @@
|
||||
|
||||
# include "BLT_translation.hh"
|
||||
|
||||
# include "MEM_guardedalloc.h"
|
||||
|
||||
# include "UI_interface.hh"
|
||||
# include "UI_resources.hh"
|
||||
|
||||
@@ -85,6 +83,8 @@ static int wm_ply_export_exec(bContext *C, wmOperator *op)
|
||||
export_params.export_triangulated_mesh = RNA_boolean_get(op->ptr, "export_triangulated_mesh");
|
||||
export_params.ascii_format = RNA_boolean_get(op->ptr, "ascii_format");
|
||||
|
||||
RNA_string_get(op->ptr, "collection", export_params.collection);
|
||||
|
||||
export_params.reports = op->reports;
|
||||
|
||||
PLY_export(C, &export_params);
|
||||
@@ -92,8 +92,11 @@ static int wm_ply_export_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void ui_ply_export_settings(uiLayout *layout, PointerRNA *imfptr)
|
||||
static void wm_ply_export_draw(bContext *C, wmOperator *op)
|
||||
{
|
||||
uiLayout *layout = op->layout;
|
||||
PointerRNA *ptr = op->ptr;
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
|
||||
@@ -103,40 +106,33 @@ static void ui_ply_export_settings(uiLayout *layout, PointerRNA *imfptr)
|
||||
box = uiLayoutBox(layout);
|
||||
col = uiLayoutColumn(box, false);
|
||||
sub = uiLayoutColumnWithHeading(col, false, IFACE_("Format"));
|
||||
uiItemR(sub, imfptr, "ascii_format", UI_ITEM_NONE, IFACE_("ASCII"), ICON_NONE);
|
||||
sub = uiLayoutColumnWithHeading(col, false, IFACE_("Limit to"));
|
||||
uiItemR(
|
||||
sub, imfptr, "export_selected_objects", UI_ITEM_NONE, IFACE_("Selected Only"), ICON_NONE);
|
||||
uiItemR(sub, imfptr, "global_scale", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
uiItemR(sub, ptr, "ascii_format", UI_ITEM_NONE, IFACE_("ASCII"), ICON_NONE);
|
||||
|
||||
uiItemR(sub, imfptr, "forward_axis", UI_ITEM_NONE, IFACE_("Forward Axis"), ICON_NONE);
|
||||
uiItemR(sub, imfptr, "up_axis", UI_ITEM_NONE, IFACE_("Up Axis"), ICON_NONE);
|
||||
/* The Selection only options only make sense when using regular export. */
|
||||
if (CTX_wm_space_file(C)) {
|
||||
sub = uiLayoutColumnWithHeading(col, false, IFACE_("Limit to"));
|
||||
uiItemR(sub, ptr, "export_selected_objects", UI_ITEM_NONE, IFACE_("Selected Only"), ICON_NONE);
|
||||
}
|
||||
uiItemR(sub, ptr, "global_scale", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
|
||||
uiItemR(sub, ptr, "forward_axis", UI_ITEM_NONE, IFACE_("Forward Axis"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "up_axis", UI_ITEM_NONE, IFACE_("Up Axis"), ICON_NONE);
|
||||
|
||||
col = uiLayoutColumn(box, false);
|
||||
sub = uiLayoutColumn(col, false);
|
||||
sub = uiLayoutColumnWithHeading(col, false, IFACE_("Objects"));
|
||||
uiItemR(sub, imfptr, "apply_modifiers", UI_ITEM_NONE, IFACE_("Apply Modifiers"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "apply_modifiers", UI_ITEM_NONE, IFACE_("Apply Modifiers"), ICON_NONE);
|
||||
|
||||
/* Geometry options. */
|
||||
box = uiLayoutBox(layout);
|
||||
col = uiLayoutColumn(box, false);
|
||||
sub = uiLayoutColumnWithHeading(col, false, IFACE_("Geometry"));
|
||||
uiItemR(sub, imfptr, "export_uv", UI_ITEM_NONE, IFACE_("UV Coordinates"), ICON_NONE);
|
||||
uiItemR(sub, imfptr, "export_normals", UI_ITEM_NONE, IFACE_("Vertex Normals"), ICON_NONE);
|
||||
uiItemR(sub, imfptr, "export_colors", UI_ITEM_NONE, IFACE_("Vertex Colors"), ICON_NONE);
|
||||
uiItemR(sub, imfptr, "export_attributes", UI_ITEM_NONE, IFACE_("Vertex Attributes"), ICON_NONE);
|
||||
uiItemR(sub,
|
||||
imfptr,
|
||||
"export_triangulated_mesh",
|
||||
UI_ITEM_NONE,
|
||||
IFACE_("Triangulated Mesh"),
|
||||
ICON_NONE);
|
||||
}
|
||||
|
||||
static void wm_ply_export_draw(bContext * /*C*/, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr = RNA_pointer_create(nullptr, op->type->srna, op->properties);
|
||||
ui_ply_export_settings(op->layout, &ptr);
|
||||
uiItemR(sub, ptr, "export_uv", UI_ITEM_NONE, IFACE_("UV Coordinates"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "export_normals", UI_ITEM_NONE, IFACE_("Vertex Normals"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "export_colors", UI_ITEM_NONE, IFACE_("Vertex Colors"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "export_attributes", UI_ITEM_NONE, IFACE_("Vertex Attributes"), ICON_NONE);
|
||||
uiItemR(
|
||||
sub, ptr, "export_triangulated_mesh", UI_ITEM_NONE, IFACE_("Triangulated Mesh"), ICON_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,6 +199,14 @@ void WM_OT_ply_export(wmOperatorType *ot)
|
||||
false,
|
||||
"Export Selected Objects",
|
||||
"Export only selected objects instead of all supported objects");
|
||||
prop = RNA_def_string(ot->srna,
|
||||
"collection",
|
||||
nullptr,
|
||||
MAX_IDPROP_NAME,
|
||||
"Source Collection",
|
||||
"Export only objects from this collection (and its children)");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_boolean(ot->srna, "export_uv", true, "Export UVs", "");
|
||||
RNA_def_boolean(
|
||||
ot->srna,
|
||||
@@ -346,6 +350,7 @@ void ply_file_handler_add()
|
||||
auto fh = std::make_unique<blender::bke::FileHandlerType>();
|
||||
STRNCPY(fh->idname, "IO_FH_ply");
|
||||
STRNCPY(fh->import_operator, "WM_OT_ply_import");
|
||||
STRNCPY(fh->export_operator, "WM_OT_ply_export");
|
||||
STRNCPY(fh->label, "Stanford PLY");
|
||||
STRNCPY(fh->file_extensions_str, ".ply");
|
||||
fh->poll_drop = poll_file_object_drop;
|
||||
|
||||
@@ -59,6 +59,8 @@ static int wm_stl_export_execute(bContext *C, wmOperator *op)
|
||||
export_params.ascii_format = RNA_boolean_get(op->ptr, "ascii_format");
|
||||
export_params.use_batch = RNA_boolean_get(op->ptr, "use_batch");
|
||||
|
||||
RNA_string_get(op->ptr, "collection", export_params.collection);
|
||||
|
||||
export_params.reports = op->reports;
|
||||
|
||||
STL_export(C, &export_params);
|
||||
@@ -66,8 +68,11 @@ static int wm_stl_export_execute(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void ui_stl_export_settings(uiLayout *layout, PointerRNA *op_props_ptr)
|
||||
static void wm_stl_export_draw(bContext *C, wmOperator *op)
|
||||
{
|
||||
uiLayout *layout = op->layout;
|
||||
PointerRNA *ptr = op->ptr;
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
|
||||
@@ -75,35 +80,27 @@ static void ui_stl_export_settings(uiLayout *layout, PointerRNA *op_props_ptr)
|
||||
|
||||
box = uiLayoutBox(layout);
|
||||
col = uiLayoutColumn(box, false);
|
||||
uiItemR(col, op_props_ptr, "ascii_format", UI_ITEM_NONE, IFACE_("ASCII"), ICON_NONE);
|
||||
uiItemR(col, op_props_ptr, "use_batch", UI_ITEM_NONE, IFACE_("Batch"), ICON_NONE);
|
||||
sub = uiLayoutColumnWithHeading(col, false, IFACE_("Format"));
|
||||
uiItemR(sub, ptr, "ascii_format", UI_ITEM_NONE, IFACE_("ASCII"), ICON_NONE);
|
||||
|
||||
box = uiLayoutBox(layout);
|
||||
sub = uiLayoutColumnWithHeading(box, false, IFACE_("Include"));
|
||||
uiItemR(sub,
|
||||
op_props_ptr,
|
||||
"export_selected_objects",
|
||||
UI_ITEM_NONE,
|
||||
IFACE_("Selection Only"),
|
||||
ICON_NONE);
|
||||
/* The Batch mode and Selection only options only make sense when using regular export. */
|
||||
if (CTX_wm_space_file(C)) {
|
||||
uiItemR(col, ptr, "use_batch", UI_ITEM_NONE, IFACE_("Batch"), ICON_NONE);
|
||||
|
||||
box = uiLayoutBox(layout);
|
||||
sub = uiLayoutColumnWithHeading(box, false, IFACE_("Transform"));
|
||||
uiItemR(sub, op_props_ptr, "global_scale", UI_ITEM_NONE, IFACE_("Scale"), ICON_NONE);
|
||||
uiItemR(sub, op_props_ptr, "use_scene_unit", UI_ITEM_NONE, IFACE_("Scene Unit"), ICON_NONE);
|
||||
uiItemR(sub, op_props_ptr, "forward_axis", UI_ITEM_NONE, IFACE_("Forward"), ICON_NONE);
|
||||
uiItemR(sub, op_props_ptr, "up_axis", UI_ITEM_NONE, IFACE_("Up"), ICON_NONE);
|
||||
box = uiLayoutBox(layout);
|
||||
sub = uiLayoutColumnWithHeading(box, false, IFACE_("Include"));
|
||||
uiItemR(
|
||||
sub, ptr, "export_selected_objects", UI_ITEM_NONE, IFACE_("Selection Only"), ICON_NONE);
|
||||
}
|
||||
|
||||
uiItemR(sub, ptr, "global_scale", UI_ITEM_NONE, IFACE_("Scale"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "use_scene_unit", UI_ITEM_NONE, IFACE_("Scene Unit"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "forward_axis", UI_ITEM_NONE, IFACE_("Forward"), ICON_NONE);
|
||||
uiItemR(sub, ptr, "up_axis", UI_ITEM_NONE, IFACE_("Up"), ICON_NONE);
|
||||
|
||||
box = uiLayoutBox(layout);
|
||||
sub = uiLayoutColumnWithHeading(box, false, IFACE_("Geometry"));
|
||||
uiItemR(
|
||||
sub, op_props_ptr, "apply_modifiers", UI_ITEM_NONE, IFACE_("Apply Modifiers"), ICON_NONE);
|
||||
}
|
||||
|
||||
static void wm_stl_export_draw(bContext * /*C*/, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr = RNA_pointer_create(nullptr, op->type->srna, op->properties);
|
||||
ui_stl_export_settings(op->layout, &ptr);
|
||||
uiItemR(sub, ptr, "apply_modifiers", UI_ITEM_NONE, IFACE_("Apply Modifiers"), ICON_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,6 +160,14 @@ void WM_OT_stl_export(wmOperatorType *ot)
|
||||
"Export Selected Objects",
|
||||
"Export only selected objects instead of all supported objects");
|
||||
|
||||
prop = RNA_def_string(ot->srna,
|
||||
"collection",
|
||||
nullptr,
|
||||
MAX_IDPROP_NAME,
|
||||
"Source Collection",
|
||||
"Export only objects from this collection (and its children)");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
RNA_def_float(ot->srna, "global_scale", 1.0f, 1e-6f, 1e6f, "Scale", "", 0.001f, 1000.0f);
|
||||
RNA_def_boolean(ot->srna,
|
||||
"use_scene_unit",
|
||||
@@ -303,6 +308,7 @@ void stl_file_handler_add()
|
||||
auto fh = std::make_unique<blender::bke::FileHandlerType>();
|
||||
STRNCPY(fh->idname, "IO_FH_stl");
|
||||
STRNCPY(fh->import_operator, "WM_OT_stl_import");
|
||||
STRNCPY(fh->export_operator, "WM_OT_stl_export");
|
||||
STRNCPY(fh->label, "STL");
|
||||
STRNCPY(fh->file_extensions_str, ".stl");
|
||||
fh->poll_drop = poll_file_object_drop;
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include "IO_orientation.hh"
|
||||
|
||||
struct bContext;
|
||||
@@ -45,6 +48,7 @@ struct PLYExportParams {
|
||||
ePLYVertexColorMode vertex_colors;
|
||||
bool export_attributes;
|
||||
bool export_triangulated_mesh;
|
||||
char collection[MAX_IDPROP_NAME] = "";
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
#include <cstdio>
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_report.hh"
|
||||
#include "BKE_scene.hh"
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "IO_ply.hh"
|
||||
|
||||
@@ -26,7 +30,39 @@ namespace blender::io::ply {
|
||||
void exporter_main(bContext *C, const PLYExportParams &export_params)
|
||||
{
|
||||
std::unique_ptr<blender::io::ply::PlyData> plyData = std::make_unique<PlyData>();
|
||||
load_plydata(*plyData, CTX_data_ensure_evaluated_depsgraph(C), export_params);
|
||||
|
||||
Depsgraph *depsgraph = nullptr;
|
||||
bool needs_free = false;
|
||||
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
if (strlen(export_params.collection) > 0) {
|
||||
Collection *collection = reinterpret_cast<Collection *>(
|
||||
BKE_libblock_find_name(bmain, ID_GR, export_params.collection));
|
||||
if (!collection) {
|
||||
BKE_reportf(export_params.reports,
|
||||
RPT_ERROR,
|
||||
"PLY Export: Unable to find collection '%s'",
|
||||
export_params.collection);
|
||||
return;
|
||||
}
|
||||
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
|
||||
needs_free = true;
|
||||
DEG_graph_build_from_collection(depsgraph, collection);
|
||||
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
|
||||
}
|
||||
else {
|
||||
depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
}
|
||||
|
||||
load_plydata(*plyData, depsgraph, export_params);
|
||||
|
||||
if (needs_free) {
|
||||
DEG_graph_free(depsgraph);
|
||||
}
|
||||
|
||||
std::unique_ptr<FileBuffer> buffer;
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include "IO_orientation.hh"
|
||||
|
||||
struct bContext;
|
||||
@@ -38,6 +41,7 @@ struct STLExportParams {
|
||||
bool apply_modifiers;
|
||||
bool ascii_format;
|
||||
bool use_batch;
|
||||
char collection[MAX_IDPROP_NAME] = "";
|
||||
|
||||
ReportList *reports = nullptr;
|
||||
};
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
* \ingroup stl
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_report.hh"
|
||||
#include "BKE_scene.hh"
|
||||
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.hh"
|
||||
@@ -136,13 +137,43 @@ void export_frame(Depsgraph *depsgraph,
|
||||
|
||||
void exporter_main(bContext *C, const STLExportParams &export_params)
|
||||
{
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
Depsgraph *depsgraph = nullptr;
|
||||
bool needs_free = false;
|
||||
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
if (strlen(export_params.collection) > 0) {
|
||||
Collection *collection = reinterpret_cast<Collection *>(
|
||||
BKE_libblock_find_name(bmain, ID_GR, export_params.collection));
|
||||
if (!collection) {
|
||||
BKE_reportf(export_params.reports,
|
||||
RPT_ERROR,
|
||||
"STL Export: Unable to find collection '%s'",
|
||||
export_params.collection);
|
||||
return;
|
||||
}
|
||||
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
|
||||
needs_free = true;
|
||||
DEG_graph_build_from_collection(depsgraph, collection);
|
||||
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
|
||||
}
|
||||
else {
|
||||
depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
}
|
||||
|
||||
float scene_unit_scale = 1.0f;
|
||||
if ((scene->unit.system != USER_UNIT_NONE) && export_params.use_scene_unit) {
|
||||
scene_unit_scale = scene->unit.scale_length;
|
||||
}
|
||||
|
||||
export_frame(depsgraph, scene_unit_scale, export_params);
|
||||
|
||||
if (needs_free) {
|
||||
DEG_graph_free(depsgraph);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::io::stl
|
||||
|
||||
Reference in New Issue
Block a user