Blender V4.3
usd_capi_import.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
5#include "IO_types.hh"
6#include "usd.hh"
7#include "usd_hook.hh"
9#include "usd_reader_geom.hh"
10#include "usd_reader_prim.hh"
11#include "usd_reader_stage.hh"
12
13#include "BKE_cachefile.hh"
14#include "BKE_collection.hh"
15#include "BKE_context.hh"
16#include "BKE_global.hh"
17#include "BKE_layer.hh"
18#include "BKE_lib_id.hh"
19#include "BKE_main.hh"
20#include "BKE_object.hh"
21#include "BKE_report.hh"
22
23#include "BLI_listbase.h"
24#include "BLI_math_matrix.h"
25#include "BLI_math_rotation.h"
26#include "BLI_path_utils.hh"
27#include "BLI_string.h"
28#include "BLI_timeit.hh"
29
30#include "BLT_translation.hh"
31
32#include "DEG_depsgraph.hh"
34
35#include "DNA_cachefile_types.h"
37#include "DNA_layer_types.h"
38#include "DNA_listBase.h"
39#include "DNA_object_types.h"
40#include "DNA_scene_types.h"
42
43#include "ED_undo.hh"
44
45#include "MEM_guardedalloc.h"
46
47#include "WM_api.hh"
48#include "WM_types.hh"
49
50#include <pxr/usd/usd/stage.h>
51#include <pxr/usd/usdGeom/metrics.h>
52#include <pxr/usd/usdGeom/tokens.h>
53
54#include <iostream>
55
56namespace blender::io::usd {
57
59{
60 return reinterpret_cast<CacheArchiveHandle *>(reader);
61}
62
64{
65 return reinterpret_cast<USDStageReader *>(handle);
66}
67
68static bool gather_objects_paths(const pxr::UsdPrim &object, ListBase *object_paths)
69{
70 if (!object.IsValid()) {
71 return false;
72 }
73
74 for (const pxr::UsdPrim &childPrim : object.GetChildren()) {
75 gather_objects_paths(childPrim, object_paths);
76 }
77
78 void *usd_path_void = MEM_callocN(sizeof(CacheObjectPath), "CacheObjectPath");
79 CacheObjectPath *usd_path = static_cast<CacheObjectPath *>(usd_path_void);
80
81 STRNCPY(usd_path->path, object.GetPrimPath().GetString().c_str());
82 BLI_addtail(object_paths, usd_path);
83
84 return true;
85}
86
87/* Update the given import settings with the global rotation matrix to orient
88 * imported objects with Z-up, if necessary */
89static void convert_to_z_up(pxr::UsdStageRefPtr stage, ImportSettings *r_settings)
90{
91 if (!stage || pxr::UsdGeomGetStageUpAxis(stage) == pxr::UsdGeomTokens->z) {
92 return;
93 }
94
95 if (!r_settings) {
96 return;
97 }
98
99 r_settings->do_convert_mat = true;
100
101 /* Rotate 90 degrees about the X-axis. */
102 float rmat[3][3];
103 float axis[3] = {1.0f, 0.0f, 0.0f};
105
106 unit_m4(r_settings->conversion_mat);
107 copy_m4_m3(r_settings->conversion_mat, rmat);
108}
109
114static void find_prefix_to_skip(pxr::UsdStageRefPtr stage, ImportSettings *r_settings)
115{
116 if (!stage) {
117 return;
118 }
119
120 pxr::TfToken generated_key("Blender:generated");
121 pxr::SdfPath path("/");
122 auto prim = stage->GetPseudoRoot();
123 while (true) {
124
125 uint32_t child_count = 0;
126 for (auto child : prim.GetChildren()) {
127 if (child_count == 0) {
128 prim = child.GetPrim();
129 }
130 ++child_count;
131 }
132
133 if (child_count != 1) {
134 /* Our blender write out only supports a single root chain,
135 * so whenever we encounter more than one child, we should
136 * early exit */
137 break;
138 }
139
140 /* We only care about prims that have the key and the value doesn't matter */
141 if (!prim.HasCustomDataKey(generated_key)) {
142 break;
143 }
144 path = path.AppendChild(prim.GetName());
145 }
146
147 /* Treat the root as empty */
148 if (path == pxr::SdfPath("/")) {
149 path = pxr::SdfPath();
150 }
151
152 r_settings->skip_prefix = path;
153}
154
155enum {
158};
159
185
186static void report_job_duration(const ImportJobData *data)
187{
188 timeit::Nanoseconds duration = timeit::Clock::now() - data->start_time;
189 std::cout << "USD import of '" << data->filepath << "' took ";
190 timeit::print_duration(duration);
191 std::cout << '\n';
192}
193
194static void import_startjob(void *customdata, wmJobWorkerStatus *worker_status)
195{
196 ImportJobData *data = static_cast<ImportJobData *>(customdata);
197
198 data->stop = &worker_status->stop;
199 data->do_update = &worker_status->do_update;
200 data->progress = &worker_status->progress;
201 data->was_canceled = false;
202 data->archive = nullptr;
203 data->start_time = timeit::Clock::now();
204 data->cache_file = nullptr;
205
206 data->params.worker_status = worker_status;
207
208 WM_set_locked_interface(data->wm, true);
209 G.is_break = false;
210
211 if (data->params.create_collection) {
212 char display_name[MAX_ID_NAME - 2];
214 display_name, sizeof(display_name), BLI_path_basename(data->filepath));
215 Collection *import_collection = BKE_collection_add(
216 data->bmain, data->scene->master_collection, display_name);
217
218 DEG_id_tag_update(&import_collection->id, ID_RECALC_SYNC_TO_EVAL);
219 DEG_relations_tag_update(data->bmain);
220
221 BKE_view_layer_synced_ensure(data->scene, data->view_layer);
222 data->view_layer->active_collection = BKE_layer_collection_first_from_scene_collection(
223 data->view_layer, import_collection);
224 }
225
227
228 /* Callback function to lazily create a cache file when converting
229 * time varying data. */
230 auto get_cache_file = [data]() {
231 if (!data->cache_file) {
232 data->cache_file = static_cast<CacheFile *>(
233 BKE_cachefile_add(data->bmain, BLI_path_basename(data->filepath)));
234
235 /* Decrement the ID ref-count because it is going to be incremented for each
236 * modifier and constraint that it will be attached to, so since currently
237 * it is not used by anyone, its use count will off by one. */
238 id_us_min(&data->cache_file->id);
239
240 data->cache_file->is_sequence = data->params.is_sequence;
241 data->cache_file->scale = data->params.scale;
242 STRNCPY(data->cache_file->filepath, data->filepath);
243 }
244 return data->cache_file;
245 };
246
247 data->settings.get_cache_file = get_cache_file;
248
249 *data->do_update = true;
250 *data->progress = 0.05f;
251
252 if (G.is_break) {
253 data->was_canceled = true;
254 return;
255 }
256
257 *data->do_update = true;
258 *data->progress = 0.1f;
259
260 std::string prim_path_mask(data->params.prim_path_mask);
261 pxr::UsdStagePopulationMask pop_mask;
262 if (!prim_path_mask.empty()) {
263 for (const std::string &mask_token : pxr::TfStringTokenize(prim_path_mask, ",;")) {
264 pxr::SdfPath prim_path(mask_token);
265 if (!prim_path.IsEmpty()) {
266 pop_mask.Add(prim_path);
267 }
268 }
269 }
270
271 pxr::UsdStageRefPtr stage = pop_mask.IsEmpty() ?
272 pxr::UsdStage::Open(data->filepath) :
273 pxr::UsdStage::OpenMasked(data->filepath, pop_mask);
274
275 if (!stage) {
276 BKE_reportf(worker_status->reports,
277 RPT_ERROR,
278 "USD Import: unable to open stage to read %s",
279 data->filepath);
280 data->import_ok = false;
281 data->error_code = USD_ARCHIVE_FAIL;
282 return;
283 }
284
285 convert_to_z_up(stage, &data->settings);
286 find_prefix_to_skip(stage, &data->settings);
287 data->settings.stage_meters_per_unit = UsdGeomGetStageMetersPerUnit(stage);
288
289 /* Set up the stage for animated data. */
290 if (data->params.set_frame_range) {
291 data->scene->r.sfra = stage->GetStartTimeCode();
292 data->scene->r.efra = stage->GetEndTimeCode();
293 }
294
295 *data->do_update = true;
296 *data->progress = 0.15f;
297
298 USDStageReader *archive = new USDStageReader(stage, data->params, data->settings);
299
300 data->archive = archive;
301
302 archive->collect_readers();
303
304 if (data->params.import_lights && data->params.create_world_material &&
305 !archive->dome_lights().is_empty())
306 {
308 data->params, data->settings, data->scene, data->bmain, archive->dome_lights().first());
309 }
310
311 if (data->params.import_materials && data->params.import_all_materials) {
312 archive->import_all_materials(data->bmain);
313 }
314
315 *data->do_update = true;
316 *data->progress = 0.2f;
317
318 const float size = float(archive->readers().size());
319 size_t i = 0;
320
321 /* Sort readers by name: when creating a lot of objects in Blender,
322 * it is much faster if the order is sorted by name. */
323 archive->sort_readers();
324 *data->do_update = true;
325 *data->progress = 0.25f;
326
327 /* Create blender objects. */
328 for (USDPrimReader *reader : archive->readers()) {
329 if (!reader) {
330 continue;
331 }
332 reader->create_object(data->bmain, 0.0);
333 if ((++i & 1023) == 0) {
334 *data->do_update = true;
335 *data->progress = 0.25f + 0.25f * (i / size);
336 }
337 }
338
339 /* Setup parenthood and read actual object data. */
340 i = 0;
341 for (USDPrimReader *reader : archive->readers()) {
342
343 if (!reader) {
344 continue;
345 }
346
347 Object *ob = reader->object();
348
349 reader->read_object_data(data->bmain, 0.0);
350
351 USDPrimReader *parent = reader->parent();
352
353 if (parent == nullptr) {
354 ob->parent = nullptr;
355 }
356 else {
357 ob->parent = parent->object();
358 }
359
360 *data->progress = 0.5f + 0.5f * (++i / size);
361 *data->do_update = true;
362
363 if (G.is_break) {
364 data->was_canceled = true;
365 return;
366 }
367 }
368
369 if (data->params.import_skeletons) {
371 }
372
373 data->import_ok = !data->was_canceled;
374
375 worker_status->progress = 1.0f;
376 worker_status->do_update = true;
377}
378
379static void import_endjob(void *customdata)
380{
381 ImportJobData *data = static_cast<ImportJobData *>(customdata);
382
383 /* Delete objects on cancellation. */
384 if (data->was_canceled && data->archive) {
385
386 for (USDPrimReader *reader : data->archive->readers()) {
387
388 if (!reader) {
389 continue;
390 }
391
392 /* It's possible that cancellation occurred between the creation of
393 * the reader and the creation of the Blender object. */
394 if (Object *ob = reader->object()) {
395 BKE_id_free_us(data->bmain, ob);
396 }
397 }
398 }
399 else if (data->archive) {
400 Base *base;
401 LayerCollection *lc;
402 const Scene *scene = data->scene;
403 ViewLayer *view_layer = data->view_layer;
404
405 BKE_view_layer_base_deselect_all(scene, view_layer);
406
407 lc = BKE_layer_collection_get_active(view_layer);
408
409 /* Create prototype collections for instancing. */
410 data->archive->create_proto_collections(data->bmain, lc->collection);
411
412 /* Add all objects to the collection. */
413 for (USDPrimReader *reader : data->archive->readers()) {
414 if (!reader) {
415 continue;
416 }
417 if (reader->is_in_proto()) {
418 /* Skip prototype prims, as these are added to prototype collections. */
419 continue;
420 }
421 Object *ob = reader->object();
422 if (!ob) {
423 continue;
424 }
425 BKE_collection_object_add(data->bmain, lc->collection, ob);
426 }
427
428 /* Sync and do the view layer operations. */
429 BKE_view_layer_synced_ensure(scene, view_layer);
430 for (USDPrimReader *reader : data->archive->readers()) {
431 if (!reader) {
432 continue;
433 }
434
435 Object *ob = reader->object();
436 if (!ob) {
437 continue;
438 }
439 base = BKE_view_layer_base_find(view_layer, ob);
440 /* TODO: is setting active needed? */
442
444 DEG_id_tag_update_ex(data->bmain,
445 &ob->id,
448 }
449
450 DEG_id_tag_update(&data->scene->id, ID_RECALC_BASE_FLAGS);
451 DEG_relations_tag_update(data->bmain);
452
453 if (data->params.import_materials && data->params.import_all_materials) {
454 data->archive->fake_users_for_unused_materials();
455 }
456
457 /* Ensure Python types for invoking hooks are registered. */
459
460 call_import_hooks(data->archive->stage(), data->params.worker_status->reports);
461
462 if (data->is_background_job) {
463 /* Blender already returned from the import operator, so we need to store our own extra undo
464 * step. */
465 ED_undo_push(data->C, "USD Import Finished");
466 }
467 }
468
469 WM_set_locked_interface(data->wm, false);
470
471 switch (data->error_code) {
472 default:
473 case USD_NO_ERROR:
474 data->import_ok = !data->was_canceled;
475 break;
476 case USD_ARCHIVE_FAIL:
477 BKE_report(data->params.worker_status->reports,
478 RPT_ERROR,
479 "Could not open USD archive for reading, see console for detail");
480 break;
481 }
482
483 MEM_SAFE_FREE(data->params.prim_path_mask);
484
487}
488
489static void import_freejob(void *user_data)
490{
491 ImportJobData *data = static_cast<ImportJobData *>(user_data);
492
493 delete data->archive;
494 delete data;
495}
496
497bool USD_import(const bContext *C,
498 const char *filepath,
499 const USDImportParams *params,
500 bool as_background_job,
501 ReportList *reports)
502{
503 /* Using new here since `MEM_*` functions do not call constructor to properly initialize data. */
504 ImportJobData *job = new ImportJobData();
505 job->C = const_cast<bContext *>(C);
506 job->bmain = CTX_data_main(C);
507 job->scene = CTX_data_scene(C);
509 job->wm = CTX_wm_manager(C);
510 job->import_ok = false;
511 job->is_background_job = as_background_job;
512 STRNCPY(job->filepath, filepath);
513
514 job->settings.scale = params->scale;
515 job->settings.sequence_offset = params->offset;
516 job->settings.is_sequence = params->is_sequence;
517 job->settings.sequence_len = params->sequence_len;
518 job->settings.validate_meshes = params->validate_meshes;
519 job->settings.sequence_len = params->sequence_len;
521 job->was_canceled = false;
522 job->archive = nullptr;
523
524 job->params = *params;
525
526 G.is_break = false;
527
528 bool import_ok = false;
529 if (as_background_job) {
530 wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
531 CTX_wm_window(C),
532 job->scene,
533 "USD Import",
536
537 /* setup job */
539 WM_jobs_timer(wm_job, 0.1, NC_SCENE, NC_SCENE);
540 WM_jobs_callbacks(wm_job, import_startjob, nullptr, nullptr, import_endjob);
541
542 WM_jobs_start(CTX_wm_manager(C), wm_job);
543 }
544 else {
545 wmJobWorkerStatus worker_status = {};
546 /* Use the operator's reports in non-background case. */
547 worker_status.reports = reports;
548
549 import_startjob(job, &worker_status);
550 import_endjob(job);
551 import_ok = job->import_ok;
552
553 import_freejob(job);
554 }
555
556 return import_ok;
557}
558
559/* TODO(makowalski): Extend this function with basic validation that the
560 * USD reader is compatible with the type of the given (currently unused) 'ob'
561 * Object parameter, similar to the logic in get_abc_reader() in the
562 * Alembic importer code. */
564 const Object * /*ob*/,
565 const char **r_err_str)
566{
567 USDPrimReader *usd_reader = reinterpret_cast<USDPrimReader *>(reader);
568 pxr::UsdPrim iobject = usd_reader->prim();
569
570 if (!iobject.IsValid()) {
571 *r_err_str = RPT_("Invalid object: verify object path");
572 return nullptr;
573 }
574
575 return usd_reader;
576}
577
578USDMeshReadParams create_mesh_read_params(const double motion_sample_time, const int read_flags)
579{
581 params.motion_sample_time = motion_sample_time;
582 params.read_flags = read_flags;
583 return params;
584}
585
587 const Object *ob,
588 blender::bke::GeometrySet &geometry_set,
590 const char **r_err_str)
591{
592 USDGeomReader *usd_reader = dynamic_cast<USDGeomReader *>(get_usd_reader(reader, ob, r_err_str));
593
594 if (usd_reader == nullptr) {
595 return;
596 }
597
598 return usd_reader->read_geometry(geometry_set, params, r_err_str);
599}
600
602 const Object *ob,
603 const Mesh *existing_mesh,
604 const double time,
605 const char **r_err_str)
606{
607 USDGeomReader *usd_reader = dynamic_cast<USDGeomReader *>(get_usd_reader(reader, ob, r_err_str));
608
609 if (usd_reader == nullptr) {
610 return false;
611 }
612
613 return usd_reader->topology_changed(existing_mesh, time);
614}
615
617 CacheReader *reader,
618 Object *object,
619 const char *object_path)
620{
621 if (object_path[0] == '\0') {
622 return reader;
623 }
624
625 USDStageReader *archive = stage_reader_from_handle(handle);
626
627 if (!archive || !archive->valid()) {
628 return reader;
629 }
630
631 if (reader) {
632 USD_CacheReader_free(reader);
633 }
634
635 pxr::UsdPrim prim = archive->stage()->GetPrimAtPath(pxr::SdfPath(object_path));
636
637 if (!prim) {
638 return nullptr;
639 }
640
641 /* TODO(makowalski): The handle does not have the proper import params or settings. */
642 USDPrimReader *usd_reader = archive->create_reader(prim);
643
644 if (usd_reader == nullptr) {
645 /* This object is not supported. */
646 return nullptr;
647 }
648 usd_reader->object(object);
649 usd_reader->incref();
650
651 return reinterpret_cast<CacheReader *>(usd_reader);
652}
653
655{
656 USDPrimReader *usd_reader = reinterpret_cast<USDPrimReader *>(reader);
657 usd_reader->decref();
658
659 if (usd_reader->refcount() == 0) {
660 delete usd_reader;
661 }
662}
663
665 const char *filepath,
666 ListBase *object_paths)
667{
668 pxr::UsdStageRefPtr stage = pxr::UsdStage::Open(filepath);
669
670 if (!stage) {
671 return nullptr;
672 }
673
675
677 convert_to_z_up(stage, &settings);
678 find_prefix_to_skip(stage, &settings);
679 USDStageReader *stage_reader = new USDStageReader(stage, params, settings);
680
681 if (object_paths) {
682 gather_objects_paths(stage->GetPseudoRoot(), object_paths);
683 }
684
685 return handle_from_stage_reader(stage_reader);
686}
687
689{
690 USDStageReader *stage_reader = stage_reader_from_handle(handle);
691 delete stage_reader;
692}
693
694void USD_get_transform(CacheReader *reader, float r_mat_world[4][4], float time, float scale)
695{
696 if (!reader) {
697 return;
698 }
699 USDXformReader *usd_reader = reinterpret_cast<USDXformReader *>(reader);
700
701 bool is_constant = false;
702
703 /* Convert from the local matrix we obtain from USD to world coordinates
704 * for Blender. This conversion is done here rather than by Blender due to
705 * work around the non-standard interpretation of CONSTRAINT_SPACE_LOCAL in
706 * BKE_constraint_mat_convertspace(). */
707 Object *object = usd_reader->object();
708 if (object->parent == nullptr) {
709 /* No parent, so local space is the same as world space. */
710 usd_reader->read_matrix(r_mat_world, time, scale, &is_constant);
711 return;
712 }
713
714 float mat_parent[4][4];
715 BKE_object_get_parent_matrix(object, object->parent, mat_parent);
716
717 float mat_local[4][4];
718 usd_reader->read_matrix(mat_local, time, scale, &is_constant);
719 mul_m4_m4m4(r_mat_world, mat_parent, object->parentinv);
720 mul_m4_m4m4(r_mat_world, r_mat_world, mat_local);
721}
722
723} // namespace blender::io::usd
void * BKE_cachefile_add(Main *bmain, const char *name)
Definition cachefile.cc:318
Collection * BKE_collection_add(Main *bmain, Collection *collection_parent, const char *name_custom)
bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
LayerCollection * BKE_layer_collection_first_from_scene_collection(const ViewLayer *view_layer, const Collection *collection)
LayerCollection * BKE_layer_collection_get_active(ViewLayer *view_layer)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
void BKE_view_layer_base_select_and_set_active(ViewLayer *view_layer, Base *selbase)
void BKE_id_free_us(Main *bmain, void *idv) ATTR_NONNULL()
void id_us_min(ID *id)
Definition lib_id.cc:359
const char * BKE_main_blendfile_path_from_global()
Definition main.cc:837
General operations, lookup, etc. for blender objects.
void BKE_object_get_parent_matrix(const Object *ob, Object *par, float r_parentmat[4][4])
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
#define M_PI_2
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void unit_m4(float m[4][4])
Definition rct.c:1127
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], float angle)
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
void BLI_path_to_display_name(char *display_name, int display_name_maxncpy, const char *name) ATTR_NONNULL(1
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define RPT_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1044
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1071
#define MAX_ID_NAME
Definition DNA_ID.h:377
Object groups, one object can be in many groups at once.
These structs are the foundation for all linked lists in the library system.
Object is a sort of wrapper for general info.
void ED_undo_push(bContext *C, const char *str)
Definition ed_undo.cc:104
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition RandGen.cpp:29
@ WM_JOB_TYPE_USD_IMPORT
Definition WM_api.hh:1598
@ WM_JOB_PROGRESS
Definition WM_api.hh:1566
#define NC_ID
Definition WM_types.hh:362
#define NC_SCENE
Definition WM_types.hh:345
#define NA_ADDED
Definition WM_types.hh:552
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
bool is_empty() const
const T & first() const
virtual void read_geometry(bke::GeometrySet &geometry_set, USDMeshReadParams params, const char **r_err_str)=0
virtual bool topology_changed(const Mesh *, double)
const pxr::UsdPrim & prim() const
USDPrimReader * parent() const
USDPrimReader * create_reader(const pxr::UsdPrim &prim)
const blender::Vector< USDPrimReader * > & readers() const
const blender::Vector< pxr::UsdLuxDomeLight > & dome_lights() const
void import_all_materials(struct Main *bmain)
void read_matrix(float r_mat[4][4], float time, float scale, bool *r_is_constant) const
EvaluationStage stage
Definition deg_eval.cc:83
draw_view in_light_buf[] float
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
#define G(x, y, z)
static void import_endjob(void *customdata)
static USDPrimReader * get_usd_reader(CacheReader *reader, const Object *, const char **r_err_str)
CacheArchiveHandle * USD_create_handle(Main *, const char *filepath, ListBase *object_paths)
CacheReader * CacheReader_open_usd_object(CacheArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
static void convert_to_z_up(pxr::UsdStageRefPtr stage, ImportSettings *r_settings)
static void import_freejob(void *user_data)
static void find_prefix_to_skip(pxr::UsdStageRefPtr stage, ImportSettings *r_settings)
static bool gather_objects_paths(const pxr::UsdPrim &object, ListBase *object_paths)
static void report_job_duration(const ExportJobData *data)
bool USD_mesh_topology_changed(CacheReader *reader, const Object *ob, const Mesh *existing_mesh, const double time, const char **r_err_str)
USDMeshReadParams create_mesh_read_params(const double motion_sample_time, const int read_flags)
void USD_get_transform(CacheReader *reader, float r_mat_world[4][4], float time, float scale)
void USD_read_geometry(CacheReader *reader, const Object *ob, blender::bke::GeometrySet &geometry_set, const USDMeshReadParams params, const char **r_err_str)
bool USD_import(const bContext *C, const char *filepath, const USDImportParams *params, bool as_background_job, ReportList *reports)
void USD_free_handle(CacheArchiveHandle *handle)
void dome_light_to_world_material(const USDImportParams &params, const ImportSettings &, Scene *scene, Main *bmain, const pxr::UsdLuxDomeLight &dome_light, const double motionSampleTime)
void USD_CacheReader_free(CacheReader *reader)
static void import_startjob(void *customdata, wmJobWorkerStatus *worker_status)
void call_import_hooks(pxr::UsdStageRefPtr stage, ReportList *reports)
Definition usd_hook.cc:356
static USDStageReader * stage_reader_from_handle(CacheArchiveHandle *handle)
static CacheArchiveHandle * handle_from_stage_reader(USDStageReader *reader)
void register_hook_converters()
Definition usd_hook.cc:137
std::chrono::nanoseconds Nanoseconds
Definition BLI_timeit.hh:16
Clock::time_point TimePoint
Definition BLI_timeit.hh:15
void print_duration(Nanoseconds duration)
Definition timeit.cc:42
unsigned int uint32_t
Definition stdint.h:80
char filepath[1024]
struct Collection * collection
struct Object * parent
ReportList * reports
Definition WM_types.hh:985
void WM_main_add_notifier(uint type, void *reference)
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
void WM_jobs_timer(wmJob *wm_job, double time_step, uint note, uint endnote)
Definition wm_jobs.cc:352
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:455
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, const eWM_JobFlag flag, const eWM_JobType job_type)
Definition wm_jobs.cc:189
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition wm_jobs.cc:364
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *customdata))
Definition wm_jobs.cc:336