USD Import: mask multiple prim paths. #106974

Merged
Michael Kowalski merged 8 commits from makowalski/blender:usd_import_open_masked into main 2023-04-25 16:32:58 +02:00
4 changed files with 28 additions and 24 deletions

View File

@ -395,8 +395,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
const bool create_collection = RNA_boolean_get(op->ptr, "create_collection");
char prim_path_mask[1024];
RNA_string_get(op->ptr, "prim_path_mask", prim_path_mask);
char *prim_path_mask = RNA_string_get_alloc(op->ptr, "prim_path_mask", NULL, 0, NULL);
const bool import_guide = RNA_boolean_get(op->ptr, "import_guide");
const bool import_proxy = RNA_boolean_get(op->ptr, "import_proxy");
@ -448,6 +447,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
.import_meshes = import_meshes,
.import_volumes = import_volumes,
.import_shapes = import_shapes,
.prim_path_mask = prim_path_mask,
.import_subdiv = import_subdiv,
.import_instance_proxies = import_instance_proxies,
.create_collection = create_collection,
@ -464,7 +464,6 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
.tex_name_collision_mode = tex_name_collision_mode,
.import_all_materials = import_all_materials};
STRNCPY(params.prim_path_mask, prim_path_mask);
STRNCPY(params.import_textures_dir, import_textures_dir);
const bool ok = USD_import(C, filename, &params, as_background_job);
@ -620,12 +619,14 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
RNA_def_boolean(
ot->srna, "read_mesh_colors", true, "Color Attributes", "Read mesh color attributes");
RNA_def_string(ot->srna,
"prim_path_mask",
NULL,
1024,
"Path Mask",
"Import only the subset of the USD scene rooted at the given primitive");
RNA_def_string(
ot->srna,
makowalski marked this conversation as resolved
Review

Typo here, should be "semicolons"

Typo here, should be "semicolons"
"prim_path_mask",
NULL,
0,
"Path Mask",
"Import only the primitive at the given path and its descendents. "
"Multiple paths may be specified in a list delimited by commas or semicolons");
RNA_def_boolean(ot->srna, "import_guide", false, "Guide", "Import guide geometry");

View File

@ -202,7 +202,21 @@ static void import_startjob(void *customdata, bool *stop, bool *do_update, float
*data->do_update = true;
*data->progress = 0.1f;
pxr::UsdStageRefPtr stage = pxr::UsdStage::Open(data->filepath);
std::string prim_path_mask(data->params.prim_path_mask);
pxr::UsdStagePopulationMask pop_mask;
if (!prim_path_mask.empty()) {
const std::vector<std::string> mask_tokens = pxr::TfStringTokenize(prim_path_mask, ",;");
for (const std::string &tok : mask_tokens) {
pxr::SdfPath prim_path(tok);
if (!prim_path.IsEmpty()) {
pop_mask.Add(prim_path);
}
}
}
pxr::UsdStageRefPtr stage = pop_mask.IsEmpty() ?
pxr::UsdStage::Open(data->filepath) :
pxr::UsdStage::OpenMasked(data->filepath, pop_mask);
if (!stage) {
WM_reportf(RPT_ERROR, "USD Import: unable to open stage to read %s", data->filepath);
@ -376,6 +390,8 @@ static void import_endjob(void *customdata)
break;
}
MEM_SAFE_FREE(data->params.prim_path_mask);

MEM_freeN aborts with an error if we attempt to free a null ptr. I think that can't happen here given current implementation, but given that the freeing of the object is so far separated from the allocation, I think it would be safer to only call MEM_freeN if non-null.

`MEM_freeN` aborts with an error if we attempt to free a null ptr. I think that can't happen here given current implementation, but given that the freeing of the object is so far separated from the allocation, I think it would be safer to only call `MEM_freeN` if non-null.

Just use MEM_SAFE_FREE macro, it checks for NULL pointers, and in addition assigns null to freed pointer, which makes further potential invalid access to it very easy to identify.

Just use `MEM_SAFE_FREE` macro, it checks for NULL pointers, and in addition assigns null to freed pointer, which makes further potential invalid access to it very easy to identify.

Thanks for pointing this out, @Matt-McLin and @mont29. I've updated the code to use MEM_SAFE_FREE.

Thanks for pointing this out, @Matt-McLin and @mont29. I've updated the code to use `MEM_SAFE_FREE`.
WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
report_job_duration(data);
}

View File

@ -312,19 +312,6 @@ void USDStageReader::collect_readers(Main *bmain)
/* Iterate through the stage. */
pxr::UsdPrim root = stage_->GetPseudoRoot();
std::string prim_path_mask(params_.prim_path_mask);
if (!prim_path_mask.empty()) {
pxr::UsdPrim prim = stage_->GetPrimAtPath(pxr::SdfPath(prim_path_mask));
if (prim.IsValid()) {
root = prim;
}
else {
std::cerr << "WARNING: Prim Path Mask " << prim_path_mask
<< " does not specify a valid prim.\n";
}
}
stage_->SetInterpolationType(pxr::UsdInterpolationType::UsdInterpolationTypeHeld);
collect_readers(bmain, root);
}

View File

@ -67,7 +67,7 @@ struct USDImportParams {
bool import_meshes;
bool import_volumes;
bool import_shapes;
char prim_path_mask[1024];
char *prim_path_mask;
bool import_subdiv;
bool import_instance_proxies;
bool create_collection;