chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,10 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <charconv>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
@@ -3453,7 +3457,7 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const char *name_dst)
|
||||
bool BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const char *name_dst)
|
||||
{
|
||||
char old_name[80];
|
||||
int len; /* store the length of the string */
|
||||
@@ -3468,46 +3472,99 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
|
||||
|
||||
/* If both names are the same, there is nothing to do. */
|
||||
if (STREQ(name_src, name_dst)) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* save old name */
|
||||
STRNCPY(old_name, pid->cache->name);
|
||||
struct RestoreName {
|
||||
PointCache *cache;
|
||||
const char *name;
|
||||
~RestoreName() { STRNCPY(cache->name, name); }
|
||||
} restore_name{pid->cache, old_name};
|
||||
|
||||
/* get "from" filename */
|
||||
STRNCPY(pid->cache->name, name_src);
|
||||
|
||||
len = ptcache_filepath(pid, old_filepath, 0, false, false); /* no path */
|
||||
if (len <= 0) { CLOG_ERROR(&LOG, "Cannot rename point cache without a valid source filename"); return false; }
|
||||
|
||||
BKE_ptcache_path(pid, path);
|
||||
dir = opendir(path);
|
||||
if (dir == nullptr) {
|
||||
STRNCPY(pid->cache->name, old_name);
|
||||
return;
|
||||
if (errno == ENOENT && !(pid->cache->flag & PTCACHE_BAKED)) return true;
|
||||
CLOG_ERROR(&LOG, "Cannot open point cache directory '%s': %s", path, std::strerror(errno));
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<DIR, decltype(&closedir)> directory(dir, closedir);
|
||||
std::vector<int> frames;
|
||||
bool found_source = false;
|
||||
|
||||
ptcache_filepath_ext_append(pid, ext, 0, false, 0);
|
||||
|
||||
/* put new name into cache */
|
||||
STRNCPY(pid->cache->name, name_dst);
|
||||
|
||||
while ((de = readdir(dir)) != nullptr) {
|
||||
if (strstr(de->d_name, ext)) { /* Do we have the right extension? */
|
||||
while (true) {
|
||||
errno = 0;
|
||||
de = readdir(dir);
|
||||
if (!de) break;
|
||||
const size_t name_len = strlen(de->d_name), ext_len = strlen(ext);
|
||||
if (name_len > size_t(len) + 1 + ext_len && de->d_name[len] == '_' && STREQ(de->d_name + name_len - ext_len, ext)) {
|
||||
if (STREQLEN(old_filepath, de->d_name, len)) { /* Do we have the right prefix. */
|
||||
/* read the number of the file */
|
||||
const int frame = ptcache_frame_from_filename(de->d_name, ext);
|
||||
int frame;
|
||||
const char *frame_end = de->d_name + name_len - ext_len;
|
||||
const auto parsed = std::from_chars(de->d_name + len + 1, frame_end, frame);
|
||||
|
||||
if (frame != -1) {
|
||||
if (parsed.ec == std::errc() && parsed.ptr == frame_end) {
|
||||
char expected[MAX_PTCACHE_FILE];
|
||||
STRNCPY(pid->cache->name, name_src);
|
||||
const bool matches = ptcache_filepath(pid, expected, frame, false, true) > 0 && STREQ(expected, de->d_name);
|
||||
STRNCPY(pid->cache->name, name_dst);
|
||||
if (!matches) continue;
|
||||
found_source = true;
|
||||
BLI_path_join(old_path_full, sizeof(old_path_full), path, de->d_name);
|
||||
ptcache_filepath(pid, new_path_full, frame, true, true);
|
||||
BLI_rename_overwrite(old_path_full, new_path_full);
|
||||
if (ptcache_filepath(pid, new_path_full, frame, true, true) <= 0) { CLOG_ERROR(&LOG, "Invalid point-cache rename destination"); return false; }
|
||||
if (STREQ(old_path_full, new_path_full)) continue;
|
||||
if (BLI_exists(new_path_full)) { CLOG_ERROR(&LOG, "Point-cache rename destination already exists: '%s'", new_path_full); return false; }
|
||||
try { frames.push_back(frame); }
|
||||
catch (const std::bad_alloc &) { CLOG_ERROR(&LOG, "Not enough memory to plan point-cache rename"); return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
STRNCPY(pid->cache->name, old_name);
|
||||
if (errno != 0) { CLOG_ERROR(&LOG, "Cannot enumerate point cache directory '%s': %s", path, std::strerror(errno)); return false; }
|
||||
if (closedir(directory.release()) != 0) { CLOG_ERROR(&LOG, "Cannot close point cache directory '%s': %s", path, std::strerror(errno)); return false; }
|
||||
if (!found_source && (pid->cache->flag & PTCACHE_BAKED)) { CLOG_ERROR(&LOG, "No matching files found for baked point cache in '%s'", path); return false; }
|
||||
const auto rename_frame = [&](int frame, const char *from, const char *to) {
|
||||
STRNCPY(pid->cache->name, from);
|
||||
if (ptcache_filepath(pid, old_path_full, frame, true, true) <= 0) { errno = EINVAL; return -1; }
|
||||
STRNCPY(pid->cache->name, to);
|
||||
if (ptcache_filepath(pid, new_path_full, frame, true, true) <= 0) { errno = EINVAL; return -1; }
|
||||
errno = 0;
|
||||
const int result = BLI_rename(old_path_full, new_path_full);
|
||||
if (result != 0 && errno == 0) errno = EIO;
|
||||
return result;
|
||||
};
|
||||
size_t moved = 0;
|
||||
for (; moved < frames.size(); moved++) {
|
||||
if (rename_frame(frames[moved], name_src, name_dst) != 0) {
|
||||
CLOG_ERROR(&LOG, "Cannot rename point cache '%s' to '%s': %s", old_path_full, new_path_full, std::strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (moved != frames.size()) {
|
||||
while (moved > 0) {
|
||||
if (rename_frame(frames[--moved], name_dst, name_src) != 0) {
|
||||
CLOG_ERROR(&LOG, "Cannot restore point-cache file '%s' to '%s': %s", old_path_full, new_path_full, std::strerror(errno));
|
||||
pid->cache->flag &= ~PTCACHE_BAKED;
|
||||
pid->cache->flag |= PTCACHE_OUTDATED | PTCACHE_FLAG_INFO_DIRTY;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BKE_ptcache_load_external(PTCacheID *pid)
|
||||
|
||||
Reference in New Issue
Block a user