Blender V4.5
io_fbx_ops.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#ifdef WITH_IO_FBX
10
11# include "BKE_context.hh"
12# include "BKE_file_handler.hh"
13# include "BKE_report.hh"
14
15# include "BLI_string.h"
16
17# include "WM_api.hh"
18
19# include "DNA_space_types.h"
20
21# include "ED_outliner.hh"
22
23# include "RNA_access.hh"
24# include "RNA_define.hh"
25
26# include "BLT_translation.hh"
27
28# include "UI_interface.hh"
29
30# include "IO_fbx.hh"
31# include "io_fbx_ops.hh"
32# include "io_utils.hh"
33
34static const EnumPropertyItem fbx_vertex_colors_mode[] = {
35 {int(eFBXVertexColorMode::None), "NONE", 0, "None", "Do not import color attributes"},
37 "SRGB",
38 0,
39 "sRGB",
40 "Vertex colors in the file are in sRGB color space"},
42 "LINEAR",
43 0,
44 "Linear",
45 "Vertex colors in the file are in linear color space"},
46 {0, nullptr, 0, nullptr, nullptr}};
47
48static wmOperatorStatus wm_fbx_import_exec(bContext *C, wmOperator *op)
49{
51 params.global_scale = RNA_float_get(op->ptr, "global_scale");
52 params.use_custom_normals = RNA_boolean_get(op->ptr, "use_custom_normals");
53 params.use_custom_props = RNA_boolean_get(op->ptr, "use_custom_props");
54 params.props_enum_as_string = RNA_boolean_get(op->ptr, "use_custom_props_enum_as_string");
55 params.ignore_leaf_bones = RNA_boolean_get(op->ptr, "ignore_leaf_bones");
56 params.import_subdivision = RNA_boolean_get(op->ptr, "import_subdivision");
57 params.validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes");
58 params.use_anim = RNA_boolean_get(op->ptr, "use_anim");
59 params.anim_offset = RNA_float_get(op->ptr, "anim_offset");
60 params.vertex_colors = eFBXVertexColorMode(RNA_enum_get(op->ptr, "import_colors"));
61
62 params.reports = op->reports;
63
65
66 if (paths.is_empty()) {
67 BKE_report(op->reports, RPT_ERROR, "No filepath given");
68 return OPERATOR_CANCELLED;
69 }
70 for (const auto &path : paths) {
71 STRNCPY(params.filepath, path.c_str());
73 }
74
75 Scene *scene = CTX_data_scene(C);
80
81 return OPERATOR_FINISHED;
82}
83
84static bool wm_fbx_import_check(bContext * /*C*/, wmOperator * /*op*/)
85{
86 return false;
87}
88
89static void ui_fbx_import_settings(const bContext *C, uiLayout *layout, PointerRNA *ptr)
90{
91 uiLayoutSetPropSep(layout, true);
92 uiLayoutSetPropDecorate(layout, false);
93
94 if (uiLayout *panel = layout->panel(C, "FBX_import_general", false, IFACE_("General"))) {
95 uiLayout *col = &panel->column(false);
96 col->prop(ptr, "global_scale", UI_ITEM_NONE, std::nullopt, ICON_NONE);
97 col->prop(ptr, "use_custom_props", UI_ITEM_NONE, std::nullopt, ICON_NONE);
98 uiLayout &subcol = col->column(false);
99 uiLayoutSetActive(&subcol, RNA_boolean_get(ptr, "use_custom_props"));
100 subcol.prop(ptr, "use_custom_props_enum_as_string", UI_ITEM_NONE, std::nullopt, ICON_NONE);
101 }
102
103 if (uiLayout *panel = layout->panel(C, "FBX_import_geometry", false, IFACE_("Geometry"))) {
104 uiLayout *col = &panel->column(false);
105 col->prop(ptr, "use_custom_normals", UI_ITEM_NONE, std::nullopt, ICON_NONE);
106 col->prop(ptr, "import_subdivision", UI_ITEM_NONE, std::nullopt, ICON_NONE);
107 col->prop(ptr, "import_colors", UI_ITEM_NONE, std::nullopt, ICON_NONE);
108 col->prop(ptr, "validate_meshes", UI_ITEM_NONE, std::nullopt, ICON_NONE);
109 }
110
111 {
112 PanelLayout panel = layout->panel(C, "FBX_import_anim", true);
113 uiLayoutSetPropSep(panel.header, false);
114 panel.header->prop(ptr, "use_anim", UI_ITEM_NONE, "", ICON_NONE);
115 panel.header->label(IFACE_("Animation"), ICON_NONE);
116 if (panel.body) {
117 uiLayout *col = &panel.body->column(false);
118 col->prop(ptr, "anim_offset", UI_ITEM_NONE, std::nullopt, ICON_NONE);
119 }
120 }
121
122 if (uiLayout *panel = layout->panel(C, "FBX_import_armature", false, IFACE_("Armature"))) {
123 uiLayout *col = &panel->column(false);
124 col->prop(ptr, "ignore_leaf_bones", UI_ITEM_NONE, std::nullopt, ICON_NONE);
125 }
126}
127
128static void wm_fbx_import_draw(bContext *C, wmOperator *op)
129{
130 ui_fbx_import_settings(C, op->layout, op->ptr);
131}
132
134{
135 PropertyRNA *prop;
136
137 ot->name = "Import FBX (experimental)";
138 ot->description = "Import FBX file into current scene";
139 ot->idname = "WM_OT_fbx_import";
140
142 ot->exec = wm_fbx_import_exec;
144 ot->check = wm_fbx_import_check;
145 ot->ui = wm_fbx_import_draw;
146 ot->flag = OPTYPE_UNDO | OPTYPE_PRESET;
147
156
157 RNA_def_float(ot->srna, "global_scale", 1.0f, 1e-6f, 1e6f, "Scale", "", 0.001f, 1000.0f);
158 RNA_def_enum(ot->srna,
159 "import_colors",
160 fbx_vertex_colors_mode,
162 "Vertex Colors",
163 "Import vertex color attributes");
164
165 RNA_def_boolean(ot->srna,
166 "use_custom_normals",
167 true,
168 "Custom Normals",
169 "Import custom normals, if available (otherwise Blender will compute them)");
170 RNA_def_boolean(ot->srna,
171 "use_custom_props",
172 true,
173 "Custom Properties",
174 "Import user properties as custom properties");
175 RNA_def_boolean(ot->srna,
176 "use_custom_props_enum_as_string",
177 true,
178 "Enums As Strings",
179 "Store custom property enumeration values as strings");
180 RNA_def_boolean(ot->srna,
181 "import_subdivision",
182 false,
183 "Subdivision Data",
184 "Import FBX subdivision information as subdivision surface modifiers");
185 RNA_def_boolean(ot->srna,
186 "ignore_leaf_bones",
187 false,
188 "Ignore Leaf Bones",
189 "Ignore the last bone at the end of each chain (used to mark the length of the "
190 "previous bone)");
192 ot->srna,
193 "validate_meshes",
194 true,
195 "Validate Meshes",
196 "Ensure the data is valid "
197 "(when disabled, data may be imported which causes crashes displaying or editing)");
198
199 RNA_def_boolean(ot->srna, "use_anim", true, "Import Animation", "Import FBX animation");
200 prop = RNA_def_float(ot->srna,
201 "anim_offset",
202 1.0f,
203 -1e6f,
204 1e6f,
205 "Offset",
206 "Offset to apply to animation timestamps, in frames",
207 -1e4f,
208 1e4f);
209 RNA_def_property_ui_range(prop, -1e4f, 1e4f, 100, 1);
210
211 /* Only show `.fbx` files by default. */
212 prop = RNA_def_string(ot->srna, "filter_glob", "*.fbx", 0, "Extension Filter", "");
214}
215
216namespace blender::ed::io {
218{
219 auto fh = std::make_unique<blender::bke::FileHandlerType>();
220 STRNCPY(fh->idname, "IO_FH_fbx_experimental");
221 STRNCPY(fh->import_operator, "WM_OT_fbx_import");
222 STRNCPY(fh->label, "FBX");
223 STRNCPY(fh->file_extensions_str, ".fbx");
224 fh->poll_drop = poll_file_object_drop;
225 bke::file_handler_add(std::move(fh));
226}
227
228} // namespace blender::ed::io
229
230#endif /* WITH_IO_FBX */
Scene * CTX_data_scene(const bContext *C)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define IFACE_(msgid)
@ FILE_SORT_DEFAULT
@ FILE_BLENDER
@ FILE_TYPE_FOLDER
@ FILE_DEFAULTDISPLAY
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_outliner_select_sync_from_object_tag(bContext *C)
void FBX_import(bContext *C, const FBXImportParams &params)
Definition IO_fbx.cc:29
eFBXVertexColorMode
Definition IO_fbx.hh:21
@ PROP_HIDDEN
Definition RNA_types.hh:324
#define C
Definition RandGen.cpp:29
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
@ WM_FILESEL_FILES
Definition WM_api.hh:1076
@ WM_FILESEL_DIRECTORY
Definition WM_api.hh:1073
@ WM_FILESEL_SHOW_PROPS
Definition WM_api.hh:1078
@ WM_FILESEL_FILEPATH
Definition WM_api.hh:1075
@ FILE_OPENFILE
Definition WM_api.hh:1084
#define ND_OB_ACTIVE
Definition WM_types.hh:437
#define ND_OB_SELECT
Definition WM_types.hh:439
#define NC_SCENE
Definition WM_types.hh:375
#define ND_LAYER_CONTENT
Definition WM_types.hh:450
@ OPTYPE_PRESET
Definition WM_types.hh:195
@ OPTYPE_UNDO
Definition WM_types.hh:182
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void WM_OT_fbx_import(wmOperatorType *ot)
void file_handler_add(std::unique_ptr< FileHandlerType > file_handler)
void fbx_file_handler_add()
bool poll_file_object_drop(const bContext *C, blender::bke::FileHandlerType *)
Definition io_utils.cc:58
Vector< std::string > paths_from_operator_properties(PointerRNA *ptr)
Definition io_utils.cc:75
wmOperatorStatus filesel_drop_import_invoke(bContext *C, wmOperator *op, const wmEvent *)
Definition io_utils.cc:26
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
PanelLayout panel(const bContext *C, blender::StringRef idname, bool default_closed)
void label(blender::StringRef name, int icon)
uiLayout & column(bool align)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
struct ReportList * reports
struct uiLayout * layout
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4227
wmOperatorType * ot
Definition wm_files.cc:4226
void WM_operator_properties_filesel(wmOperatorType *ot, const int filter, const short type, const eFileSel_Action action, const eFileSel_Flag flag, const short display, const short sort)
bool WM_operator_winactive(bContext *C)