Blender V4.3
io_usd.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#ifdef WITH_USD
10# include "DNA_modifier_types.h"
11# include "DNA_space_types.h"
12
13# include "BKE_context.hh"
14# include "BKE_file_handler.hh"
15# include "BKE_report.hh"
16
17# include "BLI_path_utils.hh"
18# include "BLI_string.h"
19
20# include "BLT_translation.hh"
21
22# include "ED_fileselect.hh"
23# include "ED_object.hh"
24
25# include "MEM_guardedalloc.h"
26
27# include "RNA_access.hh"
28# include "RNA_define.hh"
29# include "RNA_enum_types.hh"
30
31# include "UI_interface.hh"
32# include "UI_resources.hh"
33
34# include "WM_api.hh"
35# include "WM_types.hh"
36
37# include "DEG_depsgraph.hh"
38
39# include "IO_orientation.hh"
40# include "io_usd.hh"
41# include "io_utils.hh"
42# include "usd.hh"
43
44# include <pxr/pxr.h>
45
46# include <string>
47# include <utility>
48
49using namespace blender::io::usd;
50
51const EnumPropertyItem rna_enum_usd_export_evaluation_mode_items[] = {
53 "RENDER",
54 0,
55 "Render",
56 "Use Render settings for object visibility, modifier settings, etc"},
58 "VIEWPORT",
59 0,
60 "Viewport",
61 "Use Viewport settings for object visibility, modifier settings, etc"},
62 {0, nullptr, 0, nullptr, nullptr},
63};
64
65const EnumPropertyItem rna_enum_usd_mtl_name_collision_mode_items[] = {
67 "MAKE_UNIQUE",
68 0,
69 "Make Unique",
70 "Import each USD material as a unique Blender material"},
72 "REFERENCE_EXISTING",
73 0,
74 "Reference Existing",
75 "If a material with the same name already exists, reference that instead of importing"},
76 {0, nullptr, 0, nullptr, nullptr},
77};
78
79const EnumPropertyItem rna_enum_usd_attr_import_mode_items[] = {
80 {USD_ATTR_IMPORT_NONE, "NONE", 0, "None", "Do not import USD custom attributes"},
82 "USER",
83 0,
84 "User",
85 "Import USD attributes in the 'userProperties' namespace as Blender custom "
86 "properties. The namespace will be stripped from the property names"},
88 "ALL",
89 0,
90 "All Custom",
91 "Import all USD custom attributes as Blender custom properties. "
92 "Namespaces will be retained in the property names"},
93 {0, nullptr, 0, nullptr, nullptr},
94};
95
96const EnumPropertyItem rna_enum_usd_tex_import_mode_items[] = {
97 {USD_TEX_IMPORT_NONE, "IMPORT_NONE", 0, "None", "Don't import textures"},
98 {USD_TEX_IMPORT_PACK, "IMPORT_PACK", 0, "Packed", "Import textures as packed data"},
99 {USD_TEX_IMPORT_COPY, "IMPORT_COPY", 0, "Copy", "Copy files to textures directory"},
100 {0, nullptr, 0, nullptr, nullptr},
101};
102
103const EnumPropertyItem rna_enum_usd_tex_name_collision_mode_items[] = {
105 "USE_EXISTING",
106 0,
107 "Use Existing",
108 "If a file with the same name already exists, use that instead of copying"},
109 {USD_TEX_NAME_COLLISION_OVERWRITE, "OVERWRITE", 0, "Overwrite", "Overwrite existing files"},
110 {0, nullptr, 0, nullptr, nullptr},
111};
112
113const EnumPropertyItem rna_enum_usd_export_subdiv_mode_items[] = {
115 "IGNORE",
116 0,
117 "Ignore",
118 "Scheme = None. Export base mesh without subdivision"},
120 "TESSELLATE",
121 0,
122 "Tessellate",
123 "Scheme = None. Export subdivided mesh"},
125 "BEST_MATCH",
126 0,
127 "Best Match",
128 "Scheme = Catmull-Clark, when possible. "
129 "Reverts to exporting the subdivided mesh for the Simple subdivision type"},
130 {0, nullptr, 0, nullptr, nullptr},
131};
132
133const EnumPropertyItem rna_enum_usd_xform_op_mode_items[] = {
135 "TRS",
136 0,
137 "Translate, Rotate, Scale",
138 "Export with translate, rotate, and scale Xform operators"},
140 "TOS",
141 0,
142 "Translate, Orient, Scale",
143 "Export with translate, orient quaternion, and scale Xform operators"},
144 {USD_XFORM_OP_MAT, "MAT", 0, "Matrix", "Export matrix operator"},
145 {0, nullptr, 0, nullptr, nullptr},
146};
147
148const EnumPropertyItem prop_usdz_downscale_size[] = {
149 {USD_TEXTURE_SIZE_KEEP, "KEEP", 0, "Keep", "Keep all current texture sizes"},
150 {USD_TEXTURE_SIZE_256, "256", 0, "256", "Resize to a maximum of 256 pixels"},
151 {USD_TEXTURE_SIZE_512, "512", 0, "512", "Resize to a maximum of 512 pixels"},
152 {USD_TEXTURE_SIZE_1024, "1024", 0, "1024", "Resize to a maximum of 1024 pixels"},
153 {USD_TEXTURE_SIZE_2048, "2048", 0, "2048", "Resize to a maximum of 2048 pixels"},
154 {USD_TEXTURE_SIZE_4096, "4096", 0, "4096", "Resize to a maximum of 4096 pixels"},
155 {USD_TEXTURE_SIZE_CUSTOM, "CUSTOM", 0, "Custom", "Specify a custom size"},
156 {0, nullptr, 0, nullptr, nullptr},
157};
158
159const EnumPropertyItem rna_enum_usd_tex_export_mode_items[] = {
160 {USD_TEX_EXPORT_KEEP, "KEEP", 0, "Keep", "Use original location of textures"},
162 "PRESERVE",
163 0,
164 "Preserve",
165 "Preserve file paths of textures from already imported USD files."
166 "Export remaining textures to a 'textures' folder next to the USD file"},
168 "NEW",
169 0,
170 "New Path",
171 "Export textures to a 'textures' folder next to the USD file"},
172 {0, nullptr, 0, nullptr, nullptr}};
173
174const EnumPropertyItem rna_enum_usd_mtl_purpose_items[] = {
176 "MTL_ALL_PURPOSE",
177 0,
178 "All Purpose",
179 "Attempt to import 'allPurpose' materials."},
181 "MTL_PREVIEW",
182 0,
183 "Preview",
184 "Attempt to import 'preview' materials. "
185 "Load 'allPurpose' materials as a fallback"},
187 "MTL_FULL",
188 0,
189 "Full",
190 "Attempt to import 'full' materials. "
191 "Load 'allPurpose' or 'preview' materials, in that order, as a fallback"},
192 {0, NULL, 0, NULL, NULL},
193};
194
195/* Stored in the wmOperator's customdata field to indicate it should run as a background job.
196 * This is set when the operator is invoked, and not set when it is only executed. */
197struct eUSDOperatorOptions {
198 bool as_background_job;
199};
200
201/* Ensure that the prim_path is not set to
202 * the absolute root path '/'. */
203static void process_prim_path(char *prim_path)
204{
205 if (prim_path == nullptr || prim_path[0] == '\0') {
206 return;
207 }
208
209 /* The absolute root "/" path indicates a no-op,
210 * so clear the string. */
211 if (prim_path[0] == '/' && prim_path[1] == '\0') {
212 prim_path[0] = '\0';
213 }
214
215 /* If a prim path doesn't start with a "/" it
216 * is invalid when creating the prim. */
217 if (prim_path[0] != '/') {
218 const std::string prim_path_copy = std::string(prim_path);
219 BLI_snprintf(prim_path, FILE_MAX, "/%s", prim_path_copy.c_str());
220 }
221}
222
223static int wm_usd_export_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
224{
225 eUSDOperatorOptions *options = MEM_cnew<eUSDOperatorOptions>("eUSDOperatorOptions");
226 options->as_background_job = true;
227 op->customdata = options;
228
230
232
234}
235
236static int wm_usd_export_exec(bContext *C, wmOperator *op)
237{
238 if (!RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
239 BKE_report(op->reports, RPT_ERROR, "No filepath given");
240 return OPERATOR_CANCELLED;
241 }
242
243 char filepath[FILE_MAX];
244 RNA_string_get(op->ptr, "filepath", filepath);
245
246 eUSDOperatorOptions *options = static_cast<eUSDOperatorOptions *>(op->customdata);
247 const bool as_background_job = (options != nullptr && options->as_background_job);
249
250 const bool selected_objects_only = RNA_boolean_get(op->ptr, "selected_objects_only");
251 const bool visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only");
252 const bool export_animation = RNA_boolean_get(op->ptr, "export_animation");
253 const bool export_hair = RNA_boolean_get(op->ptr, "export_hair");
254 const bool export_uvmaps = RNA_boolean_get(op->ptr, "export_uvmaps");
255 const bool rename_uvmaps = RNA_boolean_get(op->ptr, "rename_uvmaps");
256 const bool export_mesh_colors = RNA_boolean_get(op->ptr, "export_mesh_colors");
257 const bool export_normals = RNA_boolean_get(op->ptr, "export_normals");
258 const bool export_materials = RNA_boolean_get(op->ptr, "export_materials");
259 const eSubdivExportMode export_subdiv = eSubdivExportMode(
260 RNA_enum_get(op->ptr, "export_subdivision"));
261
262 const bool export_meshes = RNA_boolean_get(op->ptr, "export_meshes");
263 const bool export_lights = RNA_boolean_get(op->ptr, "export_lights");
264 const bool export_cameras = RNA_boolean_get(op->ptr, "export_cameras");
265 const bool export_curves = RNA_boolean_get(op->ptr, "export_curves");
266 const bool export_points = RNA_boolean_get(op->ptr, "export_points");
267 const bool export_volumes = RNA_boolean_get(op->ptr, "export_volumes");
268
269 const bool use_instancing = RNA_boolean_get(op->ptr, "use_instancing");
270 const bool evaluation_mode = RNA_enum_get(op->ptr, "evaluation_mode");
271
272 const bool generate_preview_surface = RNA_boolean_get(op->ptr, "generate_preview_surface");
273 const bool generate_materialx_network = RNA_boolean_get(op->ptr, "generate_materialx_network");
274 const bool overwrite_textures = RNA_boolean_get(op->ptr, "overwrite_textures");
275 const bool relative_paths = RNA_boolean_get(op->ptr, "relative_paths");
276
277 const bool export_armatures = RNA_boolean_get(op->ptr, "export_armatures");
278 const bool export_shapekeys = RNA_boolean_get(op->ptr, "export_shapekeys");
279 const bool only_deform_bones = RNA_boolean_get(op->ptr, "only_deform_bones");
280
281 const bool export_custom_properties = RNA_boolean_get(op->ptr, "export_custom_properties");
282 const bool author_blender_name = RNA_boolean_get(op->ptr, "author_blender_name");
283
284 const bool triangulate_meshes = RNA_boolean_get(op->ptr, "triangulate_meshes");
285 const int quad_method = RNA_enum_get(op->ptr, "quad_method");
286 const int ngon_method = RNA_enum_get(op->ptr, "ngon_method");
287
288 const bool convert_orientation = RNA_boolean_get(op->ptr, "convert_orientation");
289
290 const int global_forward = RNA_enum_get(op->ptr, "export_global_forward_selection");
291 const int global_up = RNA_enum_get(op->ptr, "export_global_up_selection");
292
293 const bool convert_world_material = RNA_boolean_get(op->ptr, "convert_world_material");
294
295 const eUSDXformOpMode xform_op_mode = eUSDXformOpMode(RNA_enum_get(op->ptr, "xform_op_mode"));
296
297 const eUSDZTextureDownscaleSize usdz_downscale_size = eUSDZTextureDownscaleSize(
298 RNA_enum_get(op->ptr, "usdz_downscale_size"));
299
300 const int usdz_downscale_custom_size = RNA_int_get(op->ptr, "usdz_downscale_custom_size");
301
302# if PXR_VERSION >= 2403
303 const bool allow_unicode = RNA_boolean_get(op->ptr, "allow_unicode");
304# else
305 const bool allow_unicode = false;
306# endif
307
308 /* When the texture export settings were moved into an enum this bit
309 * became more involved, but it needs to stick around for API backwards
310 * compatibility until Blender 5.0. */
311
312 const eUSDTexExportMode textures_mode = eUSDTexExportMode(
313 RNA_enum_get(op->ptr, "export_textures_mode"));
314 bool export_textures = RNA_boolean_get(op->ptr, "export_textures");
315 bool use_original_paths = false;
316
317 if (!export_textures) {
318 switch (textures_mode) {
319 case eUSDTexExportMode::USD_TEX_EXPORT_PRESERVE:
320 export_textures = false;
321 use_original_paths = true;
322 break;
323 case eUSDTexExportMode::USD_TEX_EXPORT_NEW_PATH:
324 export_textures = true;
325 use_original_paths = false;
326 break;
327 default:
328 use_original_paths = false;
329 }
330 }
331
332 char root_prim_path[FILE_MAX];
333 RNA_string_get(op->ptr, "root_prim_path", root_prim_path);
334 process_prim_path(root_prim_path);
335
336 char custom_properties_namespace[MAX_IDPROP_NAME];
337 RNA_string_get(op->ptr, "custom_properties_namespace", custom_properties_namespace);
338
340 params.export_animation = export_animation;
341 params.selected_objects_only = selected_objects_only;
342 params.visible_objects_only = visible_objects_only;
343
344 params.export_meshes = export_meshes;
345 params.export_lights = export_lights;
346 params.export_cameras = export_cameras;
347 params.export_curves = export_curves;
348 params.export_points = export_points;
349 params.export_volumes = export_volumes;
350 params.export_hair = export_hair;
351 params.export_uvmaps = export_uvmaps;
352 params.rename_uvmaps = rename_uvmaps;
353 params.export_normals = export_normals;
354 params.export_mesh_colors = export_mesh_colors;
355 params.export_materials = export_materials;
356
357 params.export_armatures = export_armatures;
358 params.export_shapekeys = export_shapekeys;
359 params.only_deform_bones = only_deform_bones;
360
361 params.convert_world_material = convert_world_material;
362
363 params.use_instancing = use_instancing;
364 params.export_custom_properties = export_custom_properties;
365 params.author_blender_name = author_blender_name;
366 params.allow_unicode = allow_unicode;
367
368 params.export_subdiv = export_subdiv;
369 params.evaluation_mode = eEvaluationMode(evaluation_mode);
370
371 params.generate_preview_surface = generate_preview_surface;
372 params.generate_materialx_network = generate_materialx_network;
373 params.export_textures = export_textures;
374 params.overwrite_textures = overwrite_textures;
375 params.relative_paths = relative_paths;
376 params.use_original_paths = use_original_paths;
377
378 params.triangulate_meshes = triangulate_meshes;
379 params.quad_method = quad_method;
380 params.ngon_method = ngon_method;
381
382 params.convert_orientation = convert_orientation;
383 params.forward_axis = eIOAxis(global_forward);
384 params.up_axis = eIOAxis(global_up);
385 params.xform_op_mode = xform_op_mode;
386
387 params.usdz_downscale_size = usdz_downscale_size;
388 params.usdz_downscale_custom_size = usdz_downscale_custom_size;
389
390 STRNCPY(params.root_prim_path, root_prim_path);
391 STRNCPY(params.custom_properties_namespace, custom_properties_namespace);
392 RNA_string_get(op->ptr, "collection", params.collection);
393
394 bool ok = USD_export(C, filepath, &params, as_background_job, op->reports);
395
396 return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
397}
398
399static void wm_usd_export_draw(bContext *C, wmOperator *op)
400{
401 uiLayout *layout = op->layout;
402 PointerRNA *ptr = op->ptr;
403
404 uiLayoutSetPropSep(layout, true);
405 uiLayoutSetPropDecorate(layout, false);
406
407 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_export_general", false, IFACE_("General"))) {
408 uiLayout *col = uiLayoutColumn(panel, false);
409 uiItemR(col, ptr, "root_prim_path", UI_ITEM_NONE, nullptr, ICON_NONE);
410
411 uiLayout *sub = uiLayoutColumnWithHeading(col, true, IFACE_("Include"));
412 if (CTX_wm_space_file(C)) {
413 uiItemR(sub, ptr, "selected_objects_only", UI_ITEM_NONE, nullptr, ICON_NONE);
414 uiItemR(sub, ptr, "visible_objects_only", UI_ITEM_NONE, nullptr, ICON_NONE);
415 }
416 uiItemR(sub, ptr, "export_animation", UI_ITEM_NONE, nullptr, ICON_NONE);
417
418 sub = uiLayoutColumnWithHeading(col, true, IFACE_("Blender Data"));
419 uiItemR(sub, ptr, "export_custom_properties", UI_ITEM_NONE, nullptr, ICON_NONE);
420 uiLayout *props_col = uiLayoutColumn(sub, true);
421 uiItemR(props_col, ptr, "custom_properties_namespace", UI_ITEM_NONE, nullptr, ICON_NONE);
422 uiItemR(props_col, ptr, "author_blender_name", UI_ITEM_NONE, nullptr, ICON_NONE);
423 uiLayoutSetActive(props_col, RNA_boolean_get(op->ptr, "export_custom_properties"));
424# if PXR_VERSION >= 2403
425 uiItemR(sub, ptr, "allow_unicode", UI_ITEM_NONE, nullptr, ICON_NONE);
426# endif
427
428 sub = uiLayoutColumnWithHeading(col, true, IFACE_("File References"));
429 uiItemR(sub, ptr, "relative_paths", UI_ITEM_NONE, nullptr, ICON_NONE);
430
431 col = uiLayoutColumn(panel, false);
432 uiItemR(col, ptr, "convert_orientation", UI_ITEM_NONE, nullptr, ICON_NONE);
433 if (RNA_boolean_get(ptr, "convert_orientation")) {
434 uiItemR(col, ptr, "export_global_forward_selection", UI_ITEM_NONE, nullptr, ICON_NONE);
435 uiItemR(col, ptr, "export_global_up_selection", UI_ITEM_NONE, nullptr, ICON_NONE);
436 }
437 uiItemR(col, ptr, "xform_op_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
438
439 col = uiLayoutColumn(panel, false);
440 uiItemR(col, ptr, "evaluation_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
441 }
442
443 if (uiLayout *panel = uiLayoutPanel(
444 C, layout, "USD_export_types", false, IFACE_("Object Types")))
445 {
446 uiLayout *col = uiLayoutColumn(panel, false);
447 uiItemR(col, ptr, "export_meshes", UI_ITEM_NONE, nullptr, ICON_NONE);
448 uiItemR(col, ptr, "export_lights", UI_ITEM_NONE, nullptr, ICON_NONE);
449 uiItemR(col, ptr, "export_cameras", UI_ITEM_NONE, nullptr, ICON_NONE);
450 uiItemR(col, ptr, "export_curves", UI_ITEM_NONE, nullptr, ICON_NONE);
451 uiItemR(col, ptr, "export_points", UI_ITEM_NONE, nullptr, ICON_NONE);
452 uiItemR(col, ptr, "export_volumes", UI_ITEM_NONE, nullptr, ICON_NONE);
453 uiItemR(col, ptr, "export_hair", UI_ITEM_NONE, nullptr, ICON_NONE);
454 }
455
456 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_export_geometry", false, IFACE_("Geometry")))
457 {
458 uiLayout *col = uiLayoutColumn(panel, false);
459 uiItemR(col, ptr, "export_uvmaps", UI_ITEM_NONE, nullptr, ICON_NONE);
460 uiItemR(col, ptr, "rename_uvmaps", UI_ITEM_NONE, nullptr, ICON_NONE);
461 uiItemR(col, ptr, "export_normals", UI_ITEM_NONE, nullptr, ICON_NONE);
462
463 uiItemR(col, ptr, "triangulate_meshes", UI_ITEM_NONE, nullptr, ICON_NONE);
464 if (RNA_boolean_get(ptr, "triangulate_meshes")) {
465 uiItemR(col, ptr, "quad_method", UI_ITEM_NONE, IFACE_("Method Quads"), ICON_NONE);
466 uiItemR(col, ptr, "ngon_method", UI_ITEM_NONE, IFACE_("Polygons"), ICON_NONE);
467 }
468
469 uiItemR(col, ptr, "export_subdivision", UI_ITEM_NONE, nullptr, ICON_NONE);
470 }
471
472 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_export_rigging", true, IFACE_("Rigging"))) {
473 uiLayout *col = uiLayoutColumn(panel, false);
474
475 uiItemR(col, ptr, "export_shapekeys", UI_ITEM_NONE, nullptr, ICON_NONE);
476 uiItemR(col, ptr, "export_armatures", UI_ITEM_NONE, nullptr, ICON_NONE);
477
478 uiLayout *row = uiLayoutRow(col, true);
479 uiItemR(row, ptr, "only_deform_bones", UI_ITEM_NONE, nullptr, ICON_NONE);
480 uiLayoutSetActive(row, RNA_boolean_get(ptr, "export_armatures"));
481 }
482
483 {
484 PanelLayout panel = uiLayoutPanel(C, layout, "USD_export_materials", true);
485 uiLayoutSetPropSep(panel.header, false);
486 uiItemR(panel.header, ptr, "export_materials", UI_ITEM_NONE, "", ICON_NONE);
487 uiItemL(panel.header, IFACE_("Materials"), ICON_NONE);
488 if (panel.body) {
489 const bool export_materials = RNA_boolean_get(ptr, "export_materials");
490 uiLayoutSetActive(panel.body, export_materials);
491
492 uiLayout *col = uiLayoutColumn(panel.body, false);
493 uiItemR(col, ptr, "generate_preview_surface", UI_ITEM_NONE, nullptr, ICON_NONE);
494 uiItemR(col, ptr, "generate_materialx_network", UI_ITEM_NONE, nullptr, ICON_NONE);
495 uiItemR(col, ptr, "convert_world_material", UI_ITEM_NONE, nullptr, ICON_NONE);
496
497 col = uiLayoutColumn(panel.body, true);
498 uiLayoutSetPropSep(col, true);
499
500 uiItemR(col, ptr, "export_textures_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
501
502 const eUSDTexExportMode textures_mode = eUSDTexExportMode(
503 RNA_enum_get(op->ptr, "export_textures_mode"));
504
505 uiLayout *col2 = uiLayoutColumn(col, true);
506 uiLayoutSetPropSep(col2, true);
507 uiLayoutSetEnabled(col2, textures_mode == USD_TEX_EXPORT_NEW_PATH);
508 uiItemR(col2, ptr, "overwrite_textures", UI_ITEM_NONE, nullptr, ICON_NONE);
509 uiItemR(col2, ptr, "usdz_downscale_size", UI_ITEM_NONE, nullptr, ICON_NONE);
510 if (RNA_enum_get(ptr, "usdz_downscale_size") == USD_TEXTURE_SIZE_CUSTOM) {
511 uiItemR(col2, ptr, "usdz_downscale_custom_size", UI_ITEM_NONE, nullptr, ICON_NONE);
512 }
513 }
514 }
515
516 if (uiLayout *panel = uiLayoutPanel(
517 C, layout, "USD_export_experimental", true, IFACE_("Experimental")))
518 {
519 uiLayout *col = uiLayoutColumn(panel, false);
520 uiItemR(col, ptr, "use_instancing", UI_ITEM_NONE, nullptr, ICON_NONE);
521 }
522}
523
524static void free_operator_customdata(wmOperator *op)
525{
526 if (op->customdata) {
528 op->customdata = nullptr;
529 }
530}
531
532static void wm_usd_export_cancel(bContext * /*C*/, wmOperator *op)
533{
534 free_operator_customdata(op);
535}
536
537static bool wm_usd_export_check(bContext * /*C*/, wmOperator *op)
538{
539 char filepath[FILE_MAX];
540 RNA_string_get(op->ptr, "filepath", filepath);
541
542 if (!BLI_path_extension_check_n(filepath, ".usd", ".usda", ".usdc", ".usdz", nullptr)) {
543 BLI_path_extension_ensure(filepath, FILE_MAX, ".usdc");
544 RNA_string_set(op->ptr, "filepath", filepath);
545 return true;
546 }
547
548 return false;
549}
550
551static void forward_axis_update(Main * /*main*/, Scene * /*scene*/, PointerRNA *ptr)
552{
553 int forward = RNA_enum_get(ptr, "export_global_forward_selection");
554 int up = RNA_enum_get(ptr, "export_global_up_selection");
555 if ((forward % 3) == (up % 3)) {
556 RNA_enum_set(ptr, "export_global_up_selection", (up + 1) % 6);
557 }
558}
559
560static void up_axis_update(Main * /*main*/, Scene * /*scene*/, PointerRNA *ptr)
561{
562 int forward = RNA_enum_get(ptr, "export_global_forward_selection");
563 int up = RNA_enum_get(ptr, "export_global_up_selection");
564 if ((forward % 3) == (up % 3)) {
565 RNA_enum_set(ptr, "export_global_forward_selection", (forward + 1) % 6);
566 }
567}
568
570{
571 ot->name = "Export USD";
572 ot->description = "Export current scene in a USD archive";
573 ot->idname = "WM_OT_usd_export";
574
575 ot->invoke = wm_usd_export_invoke;
576 ot->exec = wm_usd_export_exec;
578 ot->ui = wm_usd_export_draw;
579 ot->cancel = wm_usd_export_cancel;
580 ot->check = wm_usd_export_check;
581
582 ot->flag = OPTYPE_REGISTER | OPTYPE_PRESET; /* No UNDO possible. */
583
587 FILE_SAVE,
591
592 PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.usd", 0, "", "");
594
596 "selected_objects_only",
597 false,
598 "Selection Only",
599 "Only export selected objects. Unselected parents of selected objects are "
600 "exported as empty transform");
601
603 "visible_objects_only",
604 true,
605 "Visible Only",
606 "Only export visible objects. Invisible parents of exported objects are "
607 "exported as empty transforms");
608
609 prop = RNA_def_string(ot->srna, "collection", nullptr, MAX_IDPROP_NAME, "Collection", nullptr);
611
613 ot->srna,
614 "export_animation",
615 false,
616 "Animation",
617 "Export all frames in the render frame range, rather than only the current frame");
619 ot->srna, "export_hair", false, "Hair", "Export hair particle systems as USD curves");
621 ot->srna, "export_uvmaps", true, "UV Maps", "Include all mesh UV maps in the export");
623 "rename_uvmaps",
624 true,
625 "Rename UV Maps",
626 "Rename active render UV map to \"st\" to match USD conventions");
628 "export_mesh_colors",
629 true,
630 "Color Attributes",
631 "Include mesh color attributes in the export");
633 "export_normals",
634 true,
635 "Normals",
636 "Include normals of exported meshes in the export");
638 "export_materials",
639 true,
640 "Materials",
641 "Export viewport settings of materials as USD preview materials, and export "
642 "material assignments as geometry subsets");
643
645 "export_subdivision",
646 rna_enum_usd_export_subdiv_mode_items,
647 USD_SUBDIV_BEST_MATCH,
648 "Subdivision",
649 "Choose how subdivision modifiers will be mapped to the USD subdivision scheme "
650 "during export");
651
653 "export_armatures",
654 true,
655 "Armatures",
656 "Export armatures and meshes with armature modifiers as USD skeletons and "
657 "skinned meshes");
658
660 "only_deform_bones",
661 false,
662 "Only Deform Bones",
663 "Only export deform bones and their parents");
664
666 ot->srna, "export_shapekeys", true, "Shape Keys", "Export shape keys as USD blend shapes");
667
669 "use_instancing",
670 false,
671 "Instancing",
672 "Export instanced objects as references in USD rather than real objects");
673
675 "evaluation_mode",
676 rna_enum_usd_export_evaluation_mode_items,
678 "Use Settings for",
679 "Determines visibility of objects, modifier settings, and other areas where there "
680 "are different settings for viewport and rendering");
681
683 "generate_preview_surface",
684 true,
685 "USD Preview Surface Network",
686 "Generate an approximate USD Preview Surface shader "
687 "representation of a Principled BSDF node network");
688
690 "generate_materialx_network",
691 false,
692 "MaterialX Network",
693 "Generate a MaterialX network representation of the materials");
694
696 ot->srna,
697 "convert_orientation",
698 false,
699 "Convert Orientation",
700 "Convert orientation axis to a different convention to match other applications");
701
702 prop = RNA_def_enum(ot->srna,
703 "export_global_forward_selection",
706 "Forward Axis",
707 "");
708 RNA_def_property_update_runtime(prop, forward_axis_update);
709
710 prop = RNA_def_enum(
711 ot->srna, "export_global_up_selection", io_transform_axis, IO_AXIS_Y, "Up Axis", "");
712 RNA_def_property_update_runtime(prop, up_axis_update);
713
715 "export_textures",
716 false,
717 "Export Textures",
718 "If exporting materials, export textures referenced by material nodes "
719 "to a 'textures' directory in the same directory as the USD file");
720
722 "export_textures_mode",
723 rna_enum_usd_tex_export_mode_items,
724 USD_TEX_EXPORT_NEW_PATH,
725 "Export Textures",
726 "Texture export method");
727
729 "overwrite_textures",
730 false,
731 "Overwrite Textures",
732 "Overwrite existing files when exporting textures");
733
735 "relative_paths",
736 true,
737 "Relative Paths",
738 "Use relative paths to reference external files (i.e. textures, volumes) in "
739 "USD, otherwise use absolute paths");
740
742 "xform_op_mode",
743 rna_enum_usd_xform_op_mode_items,
744 USD_XFORM_OP_TRS,
745 "Xform Ops",
746 "The type of transform operators to write");
747
749 "root_prim_path",
750 "/root",
751 FILE_MAX,
752 "Root Prim",
753 "If set, add a transform primitive with the given path to the stage "
754 "as the parent of all exported data");
755
757 "export_custom_properties",
758 true,
759 "Custom Properties",
760 "Export custom properties as USD attributes");
761
763 "custom_properties_namespace",
764 "userProperties",
766 "Namespace",
767 "If set, add the given namespace as a prefix to exported custom property names. "
768 "This only applies to property names that do not already have a prefix "
769 "(e.g., it would apply to name 'bar' but not 'foo:bar') and does not apply "
770 "to blender object and data names which are always exported in the "
771 "'userProperties:blender' namespace");
772
774 "author_blender_name",
775 true,
776 "Blender Names",
777 "Author USD custom attributes containing the original Blender object and "
778 "object data names");
779
781 ot->srna,
782 "convert_world_material",
783 true,
784 "Convert World Material",
785 "Convert the world material to a USD dome light. "
786 "Currently works for simple materials, consisting of an environment texture "
787 "connected to a background shader, with an optional vector multiply of the texture color");
788
789# if PXR_VERSION >= 2403
791 ot->srna,
792 "allow_unicode",
793 false,
794 "Allow Unicode",
795 "Preserve UTF-8 encoded characters when writing USD prim and property names "
796 "(requires software utilizing USD 24.03 or greater when opening the resulting files)");
797# endif
798
799 RNA_def_boolean(ot->srna, "export_meshes", true, "Meshes", "Export all meshes");
800
801 RNA_def_boolean(ot->srna, "export_lights", true, "Lights", "Export all lights");
802
803 RNA_def_boolean(ot->srna, "export_cameras", true, "Cameras", "Export all cameras");
804
805 RNA_def_boolean(ot->srna, "export_curves", true, "Curves", "Export all curves");
806
807 RNA_def_boolean(ot->srna, "export_points", true, "Point Clouds", "Export all point clouds");
808
809 RNA_def_boolean(ot->srna, "export_volumes", true, "Volumes", "Export all volumes");
810
812 "triangulate_meshes",
813 false,
814 "Triangulate Meshes",
815 "Triangulate meshes during export");
816
818 "quad_method",
821 "Quad Method",
822 "Method for splitting the quads into triangles");
823
825 "ngon_method",
828 "N-gon Method",
829 "Method for splitting the n-gons into triangles");
830
832 "usdz_downscale_size",
833 prop_usdz_downscale_size,
835 "USDZ Texture Downsampling",
836 "Choose a maximum size for all exported textures");
837
839 "usdz_downscale_custom_size",
840 128,
841 64,
842 16384,
843 "USDZ Custom Downscale Size",
844 "Custom size for downscaling exported textures",
845 128,
846 8192);
847}
848
849/* ====== USD Import ====== */
850
851static int wm_usd_import_invoke(bContext *C, wmOperator *op, const wmEvent *event)
852{
853 eUSDOperatorOptions *options = MEM_cnew<eUSDOperatorOptions>("eUSDOperatorOptions");
854 options->as_background_job = true;
855 op->customdata = options;
856
858}
859
860static int wm_usd_import_exec(bContext *C, wmOperator *op)
861{
862 if (!RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
863 BKE_report(op->reports, RPT_ERROR, "No filepath given");
864 return OPERATOR_CANCELLED;
865 }
866
867 char filepath[FILE_MAX];
868 RNA_string_get(op->ptr, "filepath", filepath);
869
870 eUSDOperatorOptions *options = static_cast<eUSDOperatorOptions *>(op->customdata);
871 const bool as_background_job = (options != nullptr && options->as_background_job);
873
874 const float scale = RNA_float_get(op->ptr, "scale");
875
876 const bool set_frame_range = RNA_boolean_get(op->ptr, "set_frame_range");
877
878 const bool read_mesh_uvs = RNA_boolean_get(op->ptr, "read_mesh_uvs");
879 const bool read_mesh_colors = RNA_boolean_get(op->ptr, "read_mesh_colors");
880 const bool read_mesh_attributes = RNA_boolean_get(op->ptr, "read_mesh_attributes");
881
882 char mesh_read_flag = MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY;
883 if (read_mesh_uvs) {
884 mesh_read_flag |= MOD_MESHSEQ_READ_UV;
885 }
886 if (read_mesh_colors) {
887 mesh_read_flag |= MOD_MESHSEQ_READ_COLOR;
888 }
889 if (read_mesh_attributes) {
890 mesh_read_flag |= MOD_MESHSEQ_READ_ATTRIBUTES;
891 }
892
893 const bool import_cameras = RNA_boolean_get(op->ptr, "import_cameras");
894 const bool import_curves = RNA_boolean_get(op->ptr, "import_curves");
895 const bool import_lights = RNA_boolean_get(op->ptr, "import_lights");
896 const bool import_materials = RNA_boolean_get(op->ptr, "import_materials");
897 const bool import_meshes = RNA_boolean_get(op->ptr, "import_meshes");
898 const bool import_volumes = RNA_boolean_get(op->ptr, "import_volumes");
899 const bool import_shapes = RNA_boolean_get(op->ptr, "import_shapes");
900 const bool import_skeletons = RNA_boolean_get(op->ptr, "import_skeletons");
901 const bool import_blendshapes = RNA_boolean_get(op->ptr, "import_blendshapes");
902 const bool import_points = RNA_boolean_get(op->ptr, "import_points");
903
904 const bool import_subdiv = RNA_boolean_get(op->ptr, "import_subdiv");
905
906 const bool support_scene_instancing = RNA_boolean_get(op->ptr, "support_scene_instancing");
907
908 const bool import_visible_only = RNA_boolean_get(op->ptr, "import_visible_only");
909
910 const bool import_defined_only = RNA_boolean_get(op->ptr, "import_defined_only");
911
912 const bool create_collection = RNA_boolean_get(op->ptr, "create_collection");
913
914 char *prim_path_mask = RNA_string_get_alloc(op->ptr, "prim_path_mask", nullptr, 0, nullptr);
915
916 const bool import_guide = RNA_boolean_get(op->ptr, "import_guide");
917 const bool import_proxy = RNA_boolean_get(op->ptr, "import_proxy");
918 const bool import_render = RNA_boolean_get(op->ptr, "import_render");
919
920 const bool import_all_materials = RNA_boolean_get(op->ptr, "import_all_materials");
921
922 const bool import_usd_preview = RNA_boolean_get(op->ptr, "import_usd_preview");
923 const bool set_material_blend = RNA_boolean_get(op->ptr, "set_material_blend");
924
925 const float light_intensity_scale = RNA_float_get(op->ptr, "light_intensity_scale");
926
927 const eUSDMtlPurpose mtl_purpose = eUSDMtlPurpose(RNA_enum_get(op->ptr, "mtl_purpose"));
928 const eUSDMtlNameCollisionMode mtl_name_collision_mode = eUSDMtlNameCollisionMode(
929 RNA_enum_get(op->ptr, "mtl_name_collision_mode"));
930
931 const eUSDAttrImportMode attr_import_mode = eUSDAttrImportMode(
932 RNA_enum_get(op->ptr, "attr_import_mode"));
933
934 const bool validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes");
935
936 const bool create_world_material = RNA_boolean_get(op->ptr, "create_world_material");
937
938 /* TODO(makowalski): Add support for sequences. */
939 const bool is_sequence = false;
940 int offset = 0;
941 int sequence_len = 1;
942
943 const eUSDTexImportMode import_textures_mode = eUSDTexImportMode(
944 RNA_enum_get(op->ptr, "import_textures_mode"));
945
946 char import_textures_dir[FILE_MAXDIR];
947 RNA_string_get(op->ptr, "import_textures_dir", import_textures_dir);
948
949 const eUSDTexNameCollisionMode tex_name_collision_mode = eUSDTexNameCollisionMode(
950 RNA_enum_get(op->ptr, "tex_name_collision_mode"));
951
953 params.prim_path_mask = prim_path_mask;
954 params.scale = scale;
955 params.light_intensity_scale = light_intensity_scale;
956
957 params.mesh_read_flag = mesh_read_flag;
958 params.set_frame_range = set_frame_range;
959 params.is_sequence = is_sequence;
960 params.sequence_len = sequence_len;
961 params.offset = offset;
962
963 params.import_visible_only = import_visible_only;
964 params.import_defined_only = import_defined_only;
965
966 params.import_cameras = import_cameras;
967 params.import_curves = import_curves;
968 params.import_lights = import_lights;
969 params.import_materials = import_materials;
970 params.import_all_materials = import_all_materials;
971 params.import_meshes = import_meshes;
972 params.import_points = import_points;
973 params.import_subdiv = import_subdiv;
974 params.import_volumes = import_volumes;
975
976 params.create_collection = create_collection;
977 params.create_world_material = create_world_material;
978 params.support_scene_instancing = support_scene_instancing;
979
980 params.import_shapes = import_shapes;
981 params.import_skeletons = import_skeletons;
982 params.import_blendshapes = import_blendshapes;
983
984 params.validate_meshes = validate_meshes;
985
986 params.import_guide = import_guide;
987 params.import_proxy = import_proxy;
988 params.import_render = import_render;
989
990 params.import_usd_preview = import_usd_preview;
991 params.set_material_blend = set_material_blend;
992 params.mtl_purpose = mtl_purpose;
993 params.mtl_name_collision_mode = mtl_name_collision_mode;
994 params.import_textures_mode = import_textures_mode;
995 params.tex_name_collision_mode = tex_name_collision_mode;
996
997 params.attr_import_mode = attr_import_mode;
998
999 STRNCPY(params.import_textures_dir, import_textures_dir);
1000
1001 /* Switch out of edit mode to avoid being stuck in it (#54326). */
1002 Object *obedit = CTX_data_edit_object(C);
1003 if (obedit) {
1005 }
1006
1007 const bool ok = USD_import(C, filepath, &params, as_background_job, op->reports);
1008
1009 return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1010}
1011
1012static void wm_usd_import_cancel(bContext * /*C*/, wmOperator *op)
1013{
1014 free_operator_customdata(op);
1015}
1016
1017static void wm_usd_import_draw(bContext *C, wmOperator *op)
1018{
1019 uiLayout *layout = op->layout;
1020 PointerRNA *ptr = op->ptr;
1021
1022 uiLayoutSetPropSep(layout, true);
1023 uiLayoutSetPropDecorate(layout, false);
1024
1025 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_import_general", false, IFACE_("General"))) {
1026 uiLayout *col = uiLayoutColumn(panel, false);
1027
1028 uiItemR(col, ptr, "prim_path_mask", UI_ITEM_NONE, nullptr, ICON_NONE);
1029
1030 uiLayout *sub = uiLayoutColumnWithHeading(col, true, IFACE_("Include"));
1031 uiItemR(sub, ptr, "import_visible_only", UI_ITEM_NONE, nullptr, ICON_NONE);
1032 uiItemR(sub, ptr, "import_defined_only", UI_ITEM_NONE, nullptr, ICON_NONE);
1033
1034 col = uiLayoutColumn(panel, false);
1035 uiItemR(col, ptr, "set_frame_range", UI_ITEM_NONE, nullptr, ICON_NONE);
1036 uiItemR(col, ptr, "create_collection", UI_ITEM_NONE, nullptr, ICON_NONE);
1037 uiItemR(col, ptr, "relative_path", UI_ITEM_NONE, nullptr, ICON_NONE);
1038
1039 uiItemR(col, ptr, "scale", UI_ITEM_NONE, nullptr, ICON_NONE);
1040 uiItemR(col, ptr, "light_intensity_scale", UI_ITEM_NONE, nullptr, ICON_NONE);
1041 uiItemR(col, ptr, "attr_import_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
1042 }
1043
1044 if (uiLayout *panel = uiLayoutPanel(
1045 C, layout, "USD_import_types", false, IFACE_("Object Types")))
1046 {
1047 uiLayout *col = uiLayoutColumn(panel, false);
1048 uiItemR(col, ptr, "import_cameras", UI_ITEM_NONE, nullptr, ICON_NONE);
1049 uiItemR(col, ptr, "import_curves", UI_ITEM_NONE, nullptr, ICON_NONE);
1050 uiItemR(col, ptr, "import_lights", UI_ITEM_NONE, nullptr, ICON_NONE);
1051 uiItemR(col, ptr, "import_materials", UI_ITEM_NONE, nullptr, ICON_NONE);
1052 uiItemR(col, ptr, "import_meshes", UI_ITEM_NONE, nullptr, ICON_NONE);
1053 uiItemR(col, ptr, "import_volumes", UI_ITEM_NONE, nullptr, ICON_NONE);
1054 uiItemR(col, ptr, "import_points", UI_ITEM_NONE, nullptr, ICON_NONE);
1055 uiItemR(col, ptr, "import_shapes", UI_ITEM_NONE, nullptr, ICON_NONE);
1056
1057 col = uiLayoutColumnWithHeading(panel, true, IFACE_("Display Purpose"));
1058 uiItemR(col, ptr, "import_render", UI_ITEM_NONE, nullptr, ICON_NONE);
1059 uiItemR(col, ptr, "import_proxy", UI_ITEM_NONE, nullptr, ICON_NONE);
1060 uiItemR(col, ptr, "import_guide", UI_ITEM_NONE, nullptr, ICON_NONE);
1061
1062 col = uiLayoutColumnWithHeading(panel, true, IFACE_("Material Purpose"));
1063 uiItemR(col, ptr, "mtl_purpose", UI_ITEM_NONE, nullptr, ICON_NONE);
1064 }
1065
1066 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_import_geometry", true, IFACE_("Geometry")))
1067 {
1068 uiLayout *col = uiLayoutColumn(panel, false);
1069 uiItemR(col, ptr, "read_mesh_uvs", UI_ITEM_NONE, nullptr, ICON_NONE);
1070 uiItemR(col, ptr, "read_mesh_colors", UI_ITEM_NONE, nullptr, ICON_NONE);
1071 uiItemR(col, ptr, "read_mesh_attributes", UI_ITEM_NONE, nullptr, ICON_NONE);
1072 uiItemR(col, ptr, "import_subdiv", UI_ITEM_NONE, IFACE_("Subdivision"), ICON_NONE);
1073
1074 col = uiLayoutColumn(panel, false);
1075 uiItemR(col, ptr, "validate_meshes", UI_ITEM_NONE, nullptr, ICON_NONE);
1076 }
1077
1078 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_import_rigging", true, IFACE_("Rigging"))) {
1079 uiLayout *col = uiLayoutColumn(panel, false);
1080 uiItemR(col, ptr, "import_blendshapes", UI_ITEM_NONE, nullptr, ICON_NONE);
1081 uiItemR(col, ptr, "import_skeletons", UI_ITEM_NONE, nullptr, ICON_NONE);
1082 }
1083
1084 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_import_material", true, IFACE_("Materials")))
1085 {
1086 uiLayout *col = uiLayoutColumn(panel, false);
1087
1088 uiItemR(col, ptr, "import_all_materials", UI_ITEM_NONE, nullptr, ICON_NONE);
1089 uiItemR(col, ptr, "import_usd_preview", UI_ITEM_NONE, nullptr, ICON_NONE);
1090 uiItemR(col, ptr, "create_world_material", UI_ITEM_NONE, nullptr, ICON_NONE);
1091 uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials"));
1092
1093 uiLayout *row = uiLayoutRow(col, true);
1094 uiItemR(row, ptr, "set_material_blend", UI_ITEM_NONE, nullptr, ICON_NONE);
1095 uiLayoutSetEnabled(row, RNA_boolean_get(ptr, "import_usd_preview"));
1096 uiItemR(col, ptr, "mtl_name_collision_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
1097 }
1098
1099 if (uiLayout *panel = uiLayoutPanel(C, layout, "USD_import_texture", true, IFACE_("Textures"))) {
1100 uiLayout *col = uiLayoutColumn(panel, false);
1101
1102 uiItemR(col, ptr, "import_textures_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
1103 bool copy_textures = RNA_enum_get(op->ptr, "import_textures_mode") == USD_TEX_IMPORT_COPY;
1104
1105 uiLayout *row = uiLayoutRow(col, true);
1106 uiItemR(row, ptr, "import_textures_dir", UI_ITEM_NONE, nullptr, ICON_NONE);
1107 uiLayoutSetEnabled(row, copy_textures);
1108 row = uiLayoutRow(col, true);
1109 uiItemR(row, ptr, "tex_name_collision_mode", UI_ITEM_NONE, nullptr, ICON_NONE);
1110 uiLayoutSetEnabled(row, copy_textures);
1111 uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials"));
1112 }
1113
1114 if (uiLayout *panel = uiLayoutPanel(
1115 C, layout, "USD_import_instancing", true, IFACE_("Particles and Instancing")))
1116 {
1117 uiLayout *col = uiLayoutColumn(panel, false);
1118 uiItemR(col, ptr, "support_scene_instancing", UI_ITEM_NONE, nullptr, ICON_NONE);
1119 }
1120}
1121
1123{
1124 ot->name = "Import USD";
1125 ot->description = "Import USD stage into current scene";
1126 ot->idname = "WM_OT_usd_import";
1127
1128 ot->invoke = wm_usd_import_invoke;
1129 ot->exec = wm_usd_import_exec;
1130 ot->cancel = wm_usd_import_cancel;
1132 ot->ui = wm_usd_import_draw;
1133
1135
1143
1144 PropertyRNA *prop = RNA_def_string(ot->srna, "filter_glob", "*.usd", 0, "", "");
1146
1148 ot->srna,
1149 "scale",
1150 1.0f,
1151 0.0001f,
1152 1000.0f,
1153 "Scale",
1154 "Value by which to enlarge or shrink the objects with respect to the world's origin",
1155 0.0001f,
1156 1000.0f);
1157
1159 "set_frame_range",
1160 true,
1161 "Set Frame Range",
1162 "Update the scene's start and end frame to match those of the USD archive");
1163
1164 RNA_def_boolean(ot->srna, "import_cameras", true, "Cameras", "");
1165 RNA_def_boolean(ot->srna, "import_curves", true, "Curves", "");
1166 RNA_def_boolean(ot->srna, "import_lights", true, "Lights", "");
1167 RNA_def_boolean(ot->srna, "import_materials", true, "Materials", "");
1168 RNA_def_boolean(ot->srna, "import_meshes", true, "Meshes", "");
1169 RNA_def_boolean(ot->srna, "import_volumes", true, "Volumes", "");
1170 RNA_def_boolean(ot->srna, "import_shapes", true, "USD Shapes", "");
1171 RNA_def_boolean(ot->srna, "import_skeletons", true, "Armatures", "");
1172 RNA_def_boolean(ot->srna, "import_blendshapes", true, "Shape Keys", "");
1173 RNA_def_boolean(ot->srna, "import_points", true, "Point Clouds", "");
1174
1176 "import_subdiv",
1177 false,
1178 "Import Subdivision Scheme",
1179 "Create subdivision surface modifiers based on the USD "
1180 "SubdivisionScheme attribute");
1181
1183 "support_scene_instancing",
1184 true,
1185 "Scene Instancing",
1186 "Import USD scene graph instances as collection instances");
1187
1189 "import_visible_only",
1190 true,
1191 "Visible Primitives Only",
1192 "Do not import invisible USD primitives. "
1193 "Only applies to primitives with a non-animated visibility attribute. "
1194 "Primitives with animated visibility will always be imported");
1195
1197 "create_collection",
1198 false,
1199 "Create Collection",
1200 "Add all imported objects to a new collection");
1201
1202 RNA_def_boolean(ot->srna, "read_mesh_uvs", true, "UV Coordinates", "Read mesh UV coordinates");
1203
1205 ot->srna, "read_mesh_colors", true, "Color Attributes", "Read mesh color attributes");
1206
1208 "read_mesh_attributes",
1209 true,
1210 "Mesh Attributes",
1211 "Read USD Primvars as mesh attributes");
1212
1214 "prim_path_mask",
1215 nullptr,
1216 0,
1217 "Path Mask",
1218 "Import only the primitive at the given path and its descendants. "
1219 "Multiple paths may be specified in a list delimited by commas or semicolons");
1220
1221 RNA_def_boolean(ot->srna, "import_guide", false, "Guide", "Import guide geometry");
1222
1223 RNA_def_boolean(ot->srna, "import_proxy", false, "Proxy", "Import proxy geometry");
1224
1225 RNA_def_boolean(ot->srna, "import_render", true, "Render", "Import final render geometry");
1226
1228 "import_all_materials",
1229 false,
1230 "Import All Materials",
1231 "Also import materials that are not used by any geometry. "
1232 "Note that when this option is false, materials referenced "
1233 "by geometry will still be imported");
1234
1236 "import_usd_preview",
1237 true,
1238 "Import USD Preview",
1239 "Convert UsdPreviewSurface shaders to Principled BSDF shader networks");
1240
1242 "set_material_blend",
1243 true,
1244 "Set Material Blend",
1245 "If the Import USD Preview option is enabled, "
1246 "the material blend method will automatically be set based on the "
1247 "shader's opacity and opacityThreshold inputs");
1248
1250 "light_intensity_scale",
1251 1.0f,
1252 0.0001f,
1253 10000.0f,
1254 "Light Intensity Scale",
1255 "Scale for the intensity of imported lights",
1256 0.0001f,
1257 1000.0f);
1258
1260 "mtl_purpose",
1261 rna_enum_usd_mtl_purpose_items,
1262 USD_MTL_PURPOSE_FULL,
1263 "Material Purpose",
1264 "Attempt to import materials with the given purpose. "
1265 "If no material with this purpose is bound to the primitive, "
1266 "fall back on loading any other bound material");
1267
1269 ot->srna,
1270 "mtl_name_collision_mode",
1271 rna_enum_usd_mtl_name_collision_mode_items,
1272 USD_MTL_NAME_COLLISION_MAKE_UNIQUE,
1273 "Material Name Collision",
1274 "Behavior when the name of an imported material conflicts with an existing material");
1275
1277 "import_textures_mode",
1278 rna_enum_usd_tex_import_mode_items,
1279 USD_TEX_IMPORT_PACK,
1280 "Import Textures",
1281 "Behavior when importing textures from a USDZ archive");
1282
1284 "import_textures_dir",
1285 "//textures/",
1287 "Textures Directory",
1288 "Path to the directory where imported textures will be copied");
1289
1291 ot->srna,
1292 "tex_name_collision_mode",
1293 rna_enum_usd_tex_name_collision_mode_items,
1294 USD_TEX_NAME_COLLISION_USE_EXISTING,
1295 "File Name Collision",
1296 "Behavior when the name of an imported texture file conflicts with an existing file");
1297
1299 "attr_import_mode",
1300 rna_enum_usd_attr_import_mode_items,
1301 USD_ATTR_IMPORT_ALL,
1302 "Custom Properties",
1303 "Behavior when importing USD attributes as Blender custom properties");
1304
1306 ot->srna,
1307 "validate_meshes",
1308 false,
1309 "Validate Meshes",
1310 "Ensure the data is valid "
1311 "(when disabled, data may be imported which causes crashes displaying or editing)");
1312
1314 "create_world_material",
1315 true,
1316 "Create World Material",
1317 "Convert the first discovered USD dome light to a world background shader");
1318
1320 "import_defined_only",
1321 true,
1322 "Defined Primitives Only",
1323 "Import only defined USD primitives. When disabled this allows importing USD "
1324 "primitives which are not defined, such as those with an override specifier");
1325}
1326
1327namespace blender::ed::io {
1329{
1330 auto fh = std::make_unique<blender::bke::FileHandlerType>();
1331 STRNCPY(fh->idname, "IO_FH_usd");
1332 STRNCPY(fh->import_operator, "WM_OT_usd_import");
1333 STRNCPY(fh->export_operator, "WM_OT_usd_export");
1334 STRNCPY(fh->label, "Universal Scene Description");
1335 STRNCPY(fh->file_extensions_str, ".usd;.usda;.usdc;.usdz");
1336 fh->poll_drop = poll_file_object_drop;
1337 bke::file_handler_add(std::move(fh));
1338}
1339} // namespace blender::ed::io
1340
1341#endif /* WITH_USD */
SpaceFile * CTX_wm_space_file(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define FILE_MAX
bool BLI_path_extension_ensure(char *path, size_t path_maxncpy, const char *ext) ATTR_NONNULL(1
bool BLI_path_extension_check_n(const char *path,...) ATTR_NONNULL(1) ATTR_SENTINEL(0)
#define FILE_MAXDIR
#define STRNCPY(dst, src)
Definition BLI_string.h:593
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define IFACE_(msgid)
eEvaluationMode
@ DAG_EVAL_RENDER
@ DAG_EVAL_VIEWPORT
#define MAX_IDPROP_NAME
Definition DNA_ID.h:185
@ MOD_MESHSEQ_READ_COLOR
@ MOD_MESHSEQ_READ_VERT
@ MOD_MESHSEQ_READ_ATTRIBUTES
@ MOD_MESHSEQ_READ_UV
@ MOD_MESHSEQ_READ_POLY
@ MOD_TRIANGULATE_QUAD_SHORTEDGE
@ MOD_TRIANGULATE_NGON_BEAUTY
@ OB_MODE_EDIT
@ FILE_SORT_DEFAULT
@ FILE_BLENDER
@ FILE_TYPE_FOLDER
@ FILE_TYPE_USD
@ FILE_DEFAULTDISPLAY
@ OPERATOR_RUNNING_MODAL
void ED_fileselect_ensure_default_filepath(bContext *C, wmOperator *op, const char *extension)
Definition filesel.cc:1466
eIOAxis
@ IO_AXIS_Y
@ IO_AXIS_NEGATIVE_Z
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ PROP_HIDDEN
Definition RNA_types.hh:239
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void uiItemL(uiLayout *layout, const char *name, int icon)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
#define UI_ITEM_NONE
PanelLayout uiLayoutPanel(const bContext *C, uiLayout *layout, const char *idname, bool default_closed)
uiLayout * uiLayoutColumnWithHeading(uiLayout *layout, bool align, const char *heading)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ WM_FILESEL_RELPATH
Definition WM_api.hh:933
@ WM_FILESEL_SHOW_PROPS
Definition WM_api.hh:939
@ WM_FILESEL_FILEPATH
Definition WM_api.hh:936
@ FILE_OPENFILE
Definition WM_api.hh:945
@ FILE_SAVE
Definition WM_api.hh:946
@ OPTYPE_PRESET
Definition WM_types.hh:175
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
static void set_frame_range(ImportJobData *data)
CCL_NAMESPACE_BEGIN struct Options options
#define NULL
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void WM_OT_usd_import(wmOperatorType *ot)
void WM_OT_usd_export(wmOperatorType *ot)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void file_handler_add(std::unique_ptr< FileHandlerType > file_handler)
bool poll_file_object_drop(const bContext *C, blender::bke::FileHandlerType *)
Definition io_utils.cc:57
void usd_file_handler_add()
int filesel_drop_import_invoke(bContext *C, wmOperator *op, const wmEvent *)
Definition io_utils.cc:25
bool mode_set(bContext *C, eObjectMode mode)
@ USD_TEX_IMPORT_NONE
Definition usd.hh:65
@ USD_TEX_IMPORT_PACK
Definition usd.hh:66
@ USD_TEX_IMPORT_COPY
Definition usd.hh:67
@ USD_XFORM_OP_TRS
Definition usd.hh:92
@ USD_XFORM_OP_TOS
Definition usd.hh:93
@ USD_XFORM_OP_MAT
Definition usd.hh:94
@ USD_ATTR_IMPORT_USER
Definition usd.hh:56
@ USD_ATTR_IMPORT_ALL
Definition usd.hh:57
@ USD_ATTR_IMPORT_NONE
Definition usd.hh:55
@ USD_MTL_PURPOSE_FULL
Definition usd.hh:46
@ USD_MTL_PURPOSE_ALL
Definition usd.hh:44
@ USD_MTL_PURPOSE_PREVIEW
Definition usd.hh:45
bool USD_import(const bContext *C, const char *filepath, const USDImportParams *params, bool as_background_job, ReportList *reports)
eUSDTexNameCollisionMode
Definition usd.hh:74
@ USD_TEX_NAME_COLLISION_USE_EXISTING
Definition usd.hh:75
@ USD_TEX_NAME_COLLISION_OVERWRITE
Definition usd.hh:76
@ USD_SUBDIV_TESSELLATE
Definition usd.hh:83
@ USD_SUBDIV_BEST_MATCH
Definition usd.hh:88
@ USD_SUBDIV_IGNORE
Definition usd.hh:81
void import_blendshapes(Main *bmain, Object *mesh_obj, const pxr::UsdPrim &prim, ReportList *reports, const bool import_anim)
bool USD_export(const bContext *C, const char *filepath, const USDExportParams *params, bool as_background_job, ReportList *reports)
@ USD_TEX_EXPORT_KEEP
Definition usd.hh:111
@ USD_TEX_EXPORT_PRESERVE
Definition usd.hh:112
@ USD_TEX_EXPORT_NEW_PATH
Definition usd.hh:113
eUSDMtlNameCollisionMode
Definition usd.hh:35
@ USD_MTL_NAME_COLLISION_MAKE_UNIQUE
Definition usd.hh:36
@ USD_MTL_NAME_COLLISION_REFERENCE_EXISTING
Definition usd.hh:37
eUSDZTextureDownscaleSize
Definition usd.hh:97
@ USD_TEXTURE_SIZE_256
Definition usd.hh:100
@ USD_TEXTURE_SIZE_CUSTOM
Definition usd.hh:98
@ USD_TEXTURE_SIZE_2048
Definition usd.hh:103
@ USD_TEXTURE_SIZE_4096
Definition usd.hh:104
@ USD_TEXTURE_SIZE_KEEP
Definition usd.hh:99
@ USD_TEXTURE_SIZE_1024
Definition usd.hh:102
@ USD_TEXTURE_SIZE_512
Definition usd.hh:101
const EnumPropertyItem io_transform_axis[]
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
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)
void RNA_def_property_update_runtime(PropertyRNA *prop, RNAPropertyUpdateFunc func)
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)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
const EnumPropertyItem rna_enum_modifier_triangulate_ngon_method_items[]
const EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[]
uiLayout * header
uiLayout * body
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
bool(* check)(bContext *C, wmOperator *op)
Definition WM_types.hh:1014
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
void(* ui)(bContext *C, wmOperator *op)
Definition WM_types.hh:1053
StructRNA * srna
Definition WM_types.hh:1080
void(* cancel)(bContext *C, wmOperator *op)
Definition WM_types.hh:1028
struct ReportList * reports
struct uiLayout * layout
struct PointerRNA * ptr
void WM_event_add_fileselect(bContext *C, wmOperator *op)
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
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)