Fix: USD import: lazily create cache file
This fixes an issue where a CacheFile was always created for the USD file, causing USD_create_handle() to be called unnecessarily even if the USD does not have animating meshes or transforms. This bug would sometimes result in the stage remaining open in a CacheArchiveHandle after import (because the CacheFile is never freed), preventing the USD from being reloaded from disk. The cache file is now accessible to readers through an ImportSettings::get_cache_file function wrapper which creates a CacheFile as needed, the first time the function is called. The allocated CacheFile pointer is now stored in a new ImportJobData::cache_file member. Pull Request: https://projects.blender.org/blender/blender/pulls/116242
This commit is contained in:
committed by
Michael Kowalski
parent
935ed0791f
commit
3fc97a3ed4
@@ -183,6 +183,8 @@ struct ImportJobData {
|
||||
bool was_canceled;
|
||||
bool import_ok;
|
||||
timeit::TimePoint start_time;
|
||||
|
||||
CacheFile *cache_file;
|
||||
};
|
||||
|
||||
static void report_job_duration(const ImportJobData *data)
|
||||
@@ -203,6 +205,7 @@ static void import_startjob(void *customdata, wmJobWorkerStatus *worker_status)
|
||||
data->was_canceled = false;
|
||||
data->archive = nullptr;
|
||||
data->start_time = timeit::Clock::now();
|
||||
data->cache_file = nullptr;
|
||||
|
||||
data->params.worker_status = worker_status;
|
||||
|
||||
@@ -227,19 +230,26 @@ static void import_startjob(void *customdata, wmJobWorkerStatus *worker_status)
|
||||
|
||||
BLI_path_abs(data->filepath, BKE_main_blendfile_path_from_global());
|
||||
|
||||
CacheFile *cache_file = static_cast<CacheFile *>(
|
||||
BKE_cachefile_add(data->bmain, BLI_path_basename(data->filepath)));
|
||||
/* Callback function to lazily create a cache file when converting
|
||||
* time varying data. */
|
||||
auto get_cache_file = [data]() {
|
||||
if (!data->cache_file) {
|
||||
data->cache_file = static_cast<CacheFile *>(
|
||||
BKE_cachefile_add(data->bmain, BLI_path_basename(data->filepath)));
|
||||
|
||||
/* Decrement the ID ref-count because it is going to be incremented for each
|
||||
* modifier and constraint that it will be attached to, so since currently
|
||||
* it is not used by anyone, its use count will off by one. */
|
||||
id_us_min(&cache_file->id);
|
||||
/* Decrement the ID ref-count because it is going to be incremented for each
|
||||
* modifier and constraint that it will be attached to, so since currently
|
||||
* it is not used by anyone, its use count will off by one. */
|
||||
id_us_min(&data->cache_file->id);
|
||||
|
||||
cache_file->is_sequence = data->params.is_sequence;
|
||||
cache_file->scale = data->params.scale;
|
||||
STRNCPY(cache_file->filepath, data->filepath);
|
||||
data->cache_file->is_sequence = data->params.is_sequence;
|
||||
data->cache_file->scale = data->params.scale;
|
||||
STRNCPY(data->cache_file->filepath, data->filepath);
|
||||
}
|
||||
return data->cache_file;
|
||||
};
|
||||
|
||||
data->settings.cache_file = cache_file;
|
||||
data->settings.get_cache_file = get_cache_file;
|
||||
|
||||
*data->do_update = true;
|
||||
*data->progress = 0.05f;
|
||||
|
||||
@@ -22,12 +22,16 @@ namespace blender::io::usd {
|
||||
|
||||
void USDGeomReader::add_cache_modifier()
|
||||
{
|
||||
if (!settings_->get_cache_file) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModifierData *md = BKE_modifier_new(eModifierType_MeshSequenceCache);
|
||||
BLI_addtail(&object_->modifiers, md);
|
||||
|
||||
MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
|
||||
|
||||
mcmd->cache_file = settings_->cache_file;
|
||||
mcmd->cache_file = settings_->get_cache_file();
|
||||
id_us_plus(&mcmd->cache_file->id);
|
||||
mcmd->read_flag = import_params_.mesh_read_flag;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ struct ImportSettings {
|
||||
|
||||
bool validate_meshes;
|
||||
|
||||
CacheFile *cache_file;
|
||||
std::function<CacheFile *()> get_cache_file;
|
||||
|
||||
/* Map a USD material prim path to a Blender material name.
|
||||
* This map is updated by readers during stage traversal.
|
||||
@@ -74,7 +74,7 @@ struct ImportSettings {
|
||||
sequence_offset(0),
|
||||
read_flag(0),
|
||||
validate_meshes(false),
|
||||
cache_file(NULL),
|
||||
get_cache_file(nullptr),
|
||||
stage_meters_per_unit(1.0),
|
||||
skip_prefix(pxr::SdfPath{})
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ void USDXformReader::read_object_data(Main * /*bmain*/, const double motionSampl
|
||||
|
||||
read_matrix(transform_from_usd, motionSampleTime, import_params_.scale, &is_constant);
|
||||
|
||||
if (!is_constant) {
|
||||
if (!is_constant && settings_->get_cache_file) {
|
||||
bConstraint *con = BKE_constraint_add_for_object(
|
||||
object_, nullptr, CONSTRAINT_TYPE_TRANSFORM_CACHE);
|
||||
bTransformCacheConstraint *data = static_cast<bTransformCacheConstraint *>(con->data);
|
||||
@@ -55,7 +55,7 @@ void USDXformReader::read_object_data(Main * /*bmain*/, const double motionSampl
|
||||
|
||||
STRNCPY(data->object_path, prim_path.c_str());
|
||||
|
||||
data->cache_file = settings_->cache_file;
|
||||
data->cache_file = settings_->get_cache_file();
|
||||
id_us_plus(&data->cache_file->id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user