|
|
|
|
@@ -32,6 +32,7 @@
|
|
|
|
|
|
|
|
|
|
#include "DNA_genfile.h"
|
|
|
|
|
#include "DNA_curve_enums.h"
|
|
|
|
|
#include "DNA_lattice_types.h"
|
|
|
|
|
#include "DNA_mask_types.h"
|
|
|
|
|
#include "DNA_modifier_types.h"
|
|
|
|
|
#include "DNA_node_types.h"
|
|
|
|
|
@@ -48,6 +49,7 @@ using namespace blender;
|
|
|
|
|
|
|
|
|
|
constexpr uint64_t MAX_BLEND_BLOCK_BYTES = UINT64_C(1024) * 1024 * 1024;
|
|
|
|
|
constexpr size_t MAX_NON_MESH_POINTS = 1000000;
|
|
|
|
|
constexpr size_t MAX_LATTICE_POINTS = 64 * 64 * 64;
|
|
|
|
|
constexpr size_t MAX_SCRIPT_SOURCE_BYTES = 1024 * 1024;
|
|
|
|
|
|
|
|
|
|
uint32_t rotate_right(const uint32_t value, const uint32_t bits)
|
|
|
|
|
@@ -539,6 +541,13 @@ std::string id_prefix(const std::string &type_name)
|
|
|
|
|
if (type_name == "Library") return "library";
|
|
|
|
|
if (type_name == "WorkSpace") return "workspace";
|
|
|
|
|
if (type_name == "bScreen") return "screen";
|
|
|
|
|
if (type_name == "Brush") return "brush";
|
|
|
|
|
if (type_name == "FreestyleLineStyle") return "line-style";
|
|
|
|
|
if (type_name == "Lattice") return "lattice";
|
|
|
|
|
if (type_name == "ParticleSettings") return "particle-settings";
|
|
|
|
|
if (type_name == "bSound") return "sound";
|
|
|
|
|
if (type_name == "Speaker") return "speaker";
|
|
|
|
|
if (type_name == "Tex") return "texture";
|
|
|
|
|
return "datablock";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -552,7 +561,9 @@ bool is_exported_id_type(const std::string &type_name)
|
|
|
|
|
type_name == "MetaBall" || type_name == "PointCloud" || type_name == "Curves" ||
|
|
|
|
|
type_name == "Volume" || type_name == "GreasePencil" || type_name == "Text" ||
|
|
|
|
|
type_name == "VFont" || type_name == "Mask" || type_name == "Library" ||
|
|
|
|
|
type_name == "WorkSpace" || type_name == "bScreen";
|
|
|
|
|
type_name == "WorkSpace" || type_name == "bScreen" || type_name == "Brush" ||
|
|
|
|
|
type_name == "FreestyleLineStyle" || type_name == "Lattice" ||
|
|
|
|
|
type_name == "ParticleSettings" || type_name == "bSound" || type_name == "Speaker" || type_name == "Tex";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string unique_id(const std::string &prefix,
|
|
|
|
|
@@ -613,6 +624,17 @@ std::string object_type_name(const int64_t type)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *lattice_interpolation_name(const int64_t type)
|
|
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case KEY_LINEAR: return "KEY_LINEAR";
|
|
|
|
|
case KEY_CARDINAL: return "KEY_CARDINAL";
|
|
|
|
|
case KEY_BSPLINE: return "KEY_BSPLINE";
|
|
|
|
|
case KEY_CATMULL_ROM: return "KEY_CATMULL_ROM";
|
|
|
|
|
default: return "UNKNOWN";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::array<float, 16> trs_matrix(const std::vector<float> &location,
|
|
|
|
|
const std::vector<float> &rotation,
|
|
|
|
|
const std::vector<float> &scale)
|
|
|
|
|
@@ -1452,8 +1474,8 @@ std::string modifier_type_name(const int64_t type)
|
|
|
|
|
"GREASE_PENCIL_OPACITY", "GREASE_PENCIL_SUBDIV", "GREASE_PENCIL_COLOR", "GREASE_PENCIL_TINT",
|
|
|
|
|
"GREASE_PENCIL_SMOOTH", "GREASE_PENCIL_OFFSET", "GREASE_PENCIL_NOISE", "GREASE_PENCIL_MIRROR",
|
|
|
|
|
"GREASE_PENCIL_THICKNESS", "GREASE_PENCIL_LATTICE", "GREASE_PENCIL_DASH", "GREASE_PENCIL_MULTIPLY",
|
|
|
|
|
"GREASE_PENCIL_LENGTH", "GREASE_PENCIL_WEIGHT_ANGLE", "GREASE_PENCIL_ARRAY",
|
|
|
|
|
"GREASE_PENCIL_WEIGHT_PROXIMITY", "GREASE_PENCIL_HOOK", "GREASE_PENCIL_LINEART",
|
|
|
|
|
"GREASE_PENCIL_LENGTH", "GREASE_PENCIL_VERTEX_WEIGHT_ANGLE", "GREASE_PENCIL_ARRAY",
|
|
|
|
|
"GREASE_PENCIL_VERTEX_WEIGHT_PROXIMITY", "GREASE_PENCIL_HOOK", "GREASE_PENCIL_LINEART",
|
|
|
|
|
"GREASE_PENCIL_ARMATURE", "GREASE_PENCIL_TIME", "GREASE_PENCIL_ENVELOPE",
|
|
|
|
|
"GREASE_PENCIL_OUTLINE", "GREASE_PENCIL_SHRINKWRAP", "GREASE_PENCIL_BUILD",
|
|
|
|
|
"GREASE_PENCIL_SIMPLIFY", "GREASE_PENCIL_TEXTURE"};
|
|
|
|
|
@@ -1501,7 +1523,8 @@ json modifier_parameters(const ParsedBlend &blend,
|
|
|
|
|
case 4:
|
|
|
|
|
parameters["start"] = read_float(*blend.sdna, modifier, "start").value_or(1.0f);
|
|
|
|
|
parameters["length"] = read_float(*blend.sdna, modifier, "length").value_or(100.0f);
|
|
|
|
|
parameters["randomize"] = read_float(*blend.sdna, modifier, "randomize").value_or(0.0f);
|
|
|
|
|
parameters["randomize"] = read_integer(*blend.sdna, modifier, "randomize").value_or(0);
|
|
|
|
|
parameters["seed"] = read_integer(*blend.sdna, modifier, "seed").value_or(0);
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
parameters["flag"] = read_integer(*blend.sdna, modifier, "flag").value_or(
|
|
|
|
|
@@ -3124,6 +3147,15 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
json lights = json::array();
|
|
|
|
|
json worlds = json::array();
|
|
|
|
|
json images = json::array();
|
|
|
|
|
json brushes = json::array();
|
|
|
|
|
json line_styles = json::array();
|
|
|
|
|
json lattices = json::array();
|
|
|
|
|
json particle_settings = json::array();
|
|
|
|
|
json sounds = json::array();
|
|
|
|
|
json speakers = json::array();
|
|
|
|
|
json texts = json::array();
|
|
|
|
|
json textures = json::array();
|
|
|
|
|
json workspace_resources = json::array();
|
|
|
|
|
json non_mesh_data = json::array();
|
|
|
|
|
json vfonts = json::array();
|
|
|
|
|
json libraries = json::array();
|
|
|
|
|
@@ -3289,10 +3321,12 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
if (data_pointer) {
|
|
|
|
|
const auto data_id = ids_by_pointer.find(*data_pointer);
|
|
|
|
|
node["dataId"] = data_id != ids_by_pointer.end() ? json(data_id->second) : json(nullptr);
|
|
|
|
|
const json object_modifier_stack = modifier_stack_from_object(blend, element, record.id, ids_by_pointer);
|
|
|
|
|
if (!object_modifier_stack.empty()) node["modifierStack"] = object_modifier_stack;
|
|
|
|
|
if (data_id != ids_by_pointer.end()) {
|
|
|
|
|
if (const std::optional<ElementRef> data = element_for_pointer(blend, *data_pointer)) {
|
|
|
|
|
if (data->type_name == "Mesh") {
|
|
|
|
|
const json stack = modifier_stack_from_object(blend, element, record.id, ids_by_pointer);
|
|
|
|
|
const json stack = object_modifier_stack;
|
|
|
|
|
if (!stack.empty()) modifier_stacks_by_mesh_id.emplace(data_id->second, stack);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -3527,6 +3561,155 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
if (!warnings.empty()) material["warnings"] = warnings;
|
|
|
|
|
materials.push_back(std::move(material));
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "Brush") {
|
|
|
|
|
json brush = {
|
|
|
|
|
{"id", record.id},
|
|
|
|
|
{"name", record.name},
|
|
|
|
|
{"size", std::clamp<int64_t>(read_integer(*blend.sdna, element, "size").value_or(0), 0, 100000)},
|
|
|
|
|
{"alpha", std::clamp<float>(read_float(*blend.sdna, element, "alpha").value_or(1.0f), 0.0f, 1.0f)},
|
|
|
|
|
{"hardness", std::clamp<float>(read_float(*blend.sdna, element, "hardness").value_or(0.0f), 0.0f, 1.0f)},
|
|
|
|
|
{"spacing", std::clamp<int64_t>(read_integer(*blend.sdna, element, "spacing").value_or(0), 1, 1000)},
|
|
|
|
|
{"jitter", std::clamp<float>(read_float(*blend.sdna, element, "jitter").value_or(0.0f), 0.0f, 1.0f)},
|
|
|
|
|
{"sculptTool", read_integer(*blend.sdna, element, "sculpt_brush_type").value_or(0)},
|
|
|
|
|
};
|
|
|
|
|
brushes.push_back(std::move(brush));
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "FreestyleLineStyle") {
|
|
|
|
|
const std::vector<float> color = {read_float(*blend.sdna, element, "r").value_or(0.0f),
|
|
|
|
|
read_float(*blend.sdna, element, "g").value_or(0.0f),
|
|
|
|
|
read_float(*blend.sdna, element, "b").value_or(0.0f)};
|
|
|
|
|
const int64_t flag = read_integer(*blend.sdna, element, "flag").value_or(0);
|
|
|
|
|
line_styles.push_back({
|
|
|
|
|
{"id", record.id},
|
|
|
|
|
{"name", record.name},
|
|
|
|
|
{"color", float_array_or(color, {0.0f, 0.0f, 0.0f})},
|
|
|
|
|
{"alpha", std::clamp(read_float(*blend.sdna, element, "alpha").value_or(1.0f), 0.0f, 1.0f)},
|
|
|
|
|
{"thickness", std::clamp(read_float(*blend.sdna, element, "thickness").value_or(1.0f), 0.0f, 10000.0f)},
|
|
|
|
|
{"chaining", read_integer(*blend.sdna, element, "chaining").value_or(0)},
|
|
|
|
|
{"caps", read_integer(*blend.sdna, element, "caps").value_or(0)},
|
|
|
|
|
{"dashed", (flag & (1 << 2)) != 0},
|
|
|
|
|
{"modifierCounts", {
|
|
|
|
|
{"color", linked_list_elements(blend, element, "color_modifiers").size()},
|
|
|
|
|
{"alpha", linked_list_elements(blend, element, "alpha_modifiers").size()},
|
|
|
|
|
{"thickness", linked_list_elements(blend, element, "thickness_modifiers").size()},
|
|
|
|
|
{"geometry", linked_list_elements(blend, element, "geometry_modifiers").size()}}}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "Lattice") {
|
|
|
|
|
const int64_t points_u = read_integer(*blend.sdna, element, "pntsu").value_or(0);
|
|
|
|
|
const int64_t points_v = read_integer(*blend.sdna, element, "pntsv").value_or(0);
|
|
|
|
|
const int64_t points_w = read_integer(*blend.sdna, element, "pntsw").value_or(0);
|
|
|
|
|
const bool dimensions_valid = points_u >= 1 && points_u <= 64 &&
|
|
|
|
|
points_v >= 1 && points_v <= 64 &&
|
|
|
|
|
points_w >= 1 && points_w <= 64;
|
|
|
|
|
const size_t point_count = dimensions_valid ?
|
|
|
|
|
size_t(points_u) * size_t(points_v) * size_t(points_w) :
|
|
|
|
|
0;
|
|
|
|
|
json points = json::array();
|
|
|
|
|
bool points_complete = point_count > 0 && point_count <= MAX_LATTICE_POINTS;
|
|
|
|
|
if (const std::optional<uint64_t> points_pointer = read_pointer(*blend.sdna, element, "def");
|
|
|
|
|
points_complete && points_pointer)
|
|
|
|
|
{
|
|
|
|
|
for (size_t index = 0; index < point_count; index++) {
|
|
|
|
|
const std::optional<ElementRef> point = raw_array_element(
|
|
|
|
|
blend, *points_pointer, "BPoint", index);
|
|
|
|
|
if (!point) {
|
|
|
|
|
points_complete = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
const std::vector<float> coordinate = read_float_array(
|
|
|
|
|
*blend.sdna, *point, "vec", 4);
|
|
|
|
|
if (coordinate.size() != 4) {
|
|
|
|
|
points_complete = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
points.push_back({
|
|
|
|
|
{"coDeform", {coordinate[0], coordinate[1], coordinate[2]}},
|
|
|
|
|
{"weight", std::clamp(read_float(*blend.sdna, *point, "weight").value_or(0.0f),
|
|
|
|
|
0.01f,
|
|
|
|
|
100.0f)},
|
|
|
|
|
{"selected", (read_integer(*blend.sdna, *point, "f1").value_or(0) & 1) != 0},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
points_complete = false;
|
|
|
|
|
}
|
|
|
|
|
const int64_t flag = read_integer(*blend.sdna, element, "flag").value_or(0);
|
|
|
|
|
json lattice = {
|
|
|
|
|
{"id", record.id},
|
|
|
|
|
{"name", record.name},
|
|
|
|
|
{"dimensions", {points_u, points_v, points_w}},
|
|
|
|
|
{"pointCount", point_count},
|
|
|
|
|
{"interpolation", {
|
|
|
|
|
lattice_interpolation_name(read_integer(*blend.sdna, element, "typeu").value_or(-1)),
|
|
|
|
|
lattice_interpolation_name(read_integer(*blend.sdna, element, "typev").value_or(-1)),
|
|
|
|
|
lattice_interpolation_name(read_integer(*blend.sdna, element, "typew").value_or(-1))}},
|
|
|
|
|
{"useOutside", (flag & LT_OUTSIDE) != 0},
|
|
|
|
|
{"activePoint", read_integer(*blend.sdna, element, "actbp").value_or(LT_ACTBP_NONE)},
|
|
|
|
|
{"vertexGroup", read_string(*blend.sdna, element, "vgroup")},
|
|
|
|
|
{"status", points_complete ? "AVAILABLE" : "BLOCKED"},
|
|
|
|
|
};
|
|
|
|
|
if (points_complete) lattice["points"] = std::move(points);
|
|
|
|
|
else lattice["errorCode"] = dimensions_valid ? "LATTICE_POINTS_UNREADABLE" :
|
|
|
|
|
"LATTICE_DIMENSIONS_INVALID";
|
|
|
|
|
lattices.push_back(std::move(lattice));
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "ParticleSettings") {
|
|
|
|
|
const int64_t particle_type = read_integer(*blend.sdna, element, "type").value_or(0);
|
|
|
|
|
const int64_t particle_from = read_integer(*blend.sdna, element, "from").value_or(0);
|
|
|
|
|
const int64_t particle_physics = read_integer(*blend.sdna, element, "phystype").value_or(0);
|
|
|
|
|
particle_settings.push_back({
|
|
|
|
|
{"id", record.id},
|
|
|
|
|
{"name", record.name},
|
|
|
|
|
{"type", particle_type == 2 ? 1 : 0},
|
|
|
|
|
{"from", particle_from == 1 ? 0 : particle_from == 0 ? 1 : 2},
|
|
|
|
|
{"distribution", std::max<int64_t>(0, read_integer(*blend.sdna, element, "distr").value_or(0))},
|
|
|
|
|
{"physicsType", particle_physics == 1 ? 0 : particle_physics == 2 ? 1 : particle_physics == 3 ? 2 : 3},
|
|
|
|
|
{"totalParticles", std::max<int64_t>(0, read_integer(*blend.sdna, element, "totpart").value_or(0))},
|
|
|
|
|
{"start", std::max(0.0f, read_float(*blend.sdna, element, "sta").value_or(0.0f))},
|
|
|
|
|
{"end", std::max(0.0f, read_float(*blend.sdna, element, "end").value_or(0.0f))},
|
|
|
|
|
{"lifetime", std::max(0.0f, read_float(*blend.sdna, element, "lifetime").value_or(0.0f))},
|
|
|
|
|
{"size", std::max(0.0f, read_float(*blend.sdna, element, "size").value_or(0.0f))},
|
|
|
|
|
{"drawSize", std::max(0.0f, read_float(*blend.sdna, element, "draw_size").value_or(0.0f))},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "bSound") {
|
|
|
|
|
const std::string filepath = read_string(*blend.sdna, element, "filepath");
|
|
|
|
|
const std::optional<uint64_t> packed_pointer = read_pointer(*blend.sdna, element, "packedfile");
|
|
|
|
|
const std::vector<uint8_t> packed_bytes = packed_pointer ? packed_file_bytes(blend, *packed_pointer) : std::vector<uint8_t>();
|
|
|
|
|
json sound = {{"id", record.id},
|
|
|
|
|
{"name", record.name},
|
|
|
|
|
{"sourcePath", filepath},
|
|
|
|
|
{"packed", !packed_bytes.empty()},
|
|
|
|
|
{"volume", std::max(0.0f, read_float(*blend.sdna, element, "volume").value_or(1.0f))},
|
|
|
|
|
{"pitch", std::max(0.0f, read_float(*blend.sdna, element, "pitch").value_or(1.0f))},
|
|
|
|
|
{"audioChannels", std::max<int64_t>(0, read_integer(*blend.sdna, element, "audio_channels").value_or(0))},
|
|
|
|
|
{"sampleRate", std::max<int64_t>(0, read_integer(*blend.sdna, element, "samplerate").value_or(0))}};
|
|
|
|
|
if (!packed_bytes.empty()) sound["packedByteLength"] = packed_bytes.size();
|
|
|
|
|
sounds.push_back(std::move(sound));
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "Speaker") {
|
|
|
|
|
json speaker = {
|
|
|
|
|
{"id", record.id},
|
|
|
|
|
{"name", record.name},
|
|
|
|
|
{"volumeMax", std::max(0.0f, read_float(*blend.sdna, element, "volume_max").value_or(1.0f))},
|
|
|
|
|
{"volumeMin", std::max(0.0f, read_float(*blend.sdna, element, "volume_min").value_or(0.0f))},
|
|
|
|
|
{"distanceMax", std::max(0.0f, read_float(*blend.sdna, element, "distance_max").value_or(0.0f))},
|
|
|
|
|
{"distanceReference", std::max(0.0f, read_float(*blend.sdna, element, "distance_reference").value_or(1.0f))},
|
|
|
|
|
{"attenuation", std::max(0.0f, read_float(*blend.sdna, element, "attenuation").value_or(1.0f))},
|
|
|
|
|
{"coneAngleOuter", std::clamp(read_float(*blend.sdna, element, "cone_angle_outer").value_or(360.0f), 0.0f, 360.0f)},
|
|
|
|
|
{"coneAngleInner", std::clamp(read_float(*blend.sdna, element, "cone_angle_inner").value_or(360.0f), 0.0f, 360.0f)},
|
|
|
|
|
{"coneVolumeOuter", std::clamp(read_float(*blend.sdna, element, "cone_volume_outer").value_or(1.0f), 0.0f, 1.0f)},
|
|
|
|
|
{"volume", std::max(0.0f, read_float(*blend.sdna, element, "volume").value_or(1.0f))},
|
|
|
|
|
{"pitch", std::max(0.0f, read_float(*blend.sdna, element, "pitch").value_or(1.0f))},
|
|
|
|
|
};
|
|
|
|
|
if (const std::optional<uint64_t> sound_pointer = read_pointer(*blend.sdna, element, "sound")) {
|
|
|
|
|
const auto sound_id = ids_by_pointer.find(*sound_pointer);
|
|
|
|
|
if (sound_id != ids_by_pointer.end()) speaker["soundId"] = sound_id->second;
|
|
|
|
|
}
|
|
|
|
|
speakers.push_back(std::move(speaker));
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "Image") {
|
|
|
|
|
std::string filepath = read_string(*blend.sdna, element, "filepath");
|
|
|
|
|
const std::vector<ElementRef> image_views = linked_list_elements(blend, element, "views");
|
|
|
|
|
@@ -3624,6 +3807,18 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
non_mesh_data.push_back(non_mesh_data_from_record(blend, element, record, ids_by_pointer));
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "Text") {
|
|
|
|
|
if (const std::optional<json> text = script_source_from_record(blend, element, record)) {
|
|
|
|
|
json resource = {{"id", record.id}, {"name", record.name}};
|
|
|
|
|
resource["source"] = text->value("source", std::string());
|
|
|
|
|
resource["sourceSha256"] = text->value("sourceSha256", std::string());
|
|
|
|
|
resource["byteLength"] = text->value("byteLength", size_t(0));
|
|
|
|
|
resource["lineCount"] = text->value("lineCount", size_t(0));
|
|
|
|
|
resource["internal"] = text->value("internal", true);
|
|
|
|
|
resource["isDirty"] = (read_integer(*blend.sdna, element, "flags").value_or(0) & (1 << 0)) != 0;
|
|
|
|
|
resource["useModule"] = (read_integer(*blend.sdna, element, "flags").value_or(0) & (1 << 4)) != 0;
|
|
|
|
|
if (text->contains("sourcePath")) resource["sourcePath"] = text->at("sourcePath");
|
|
|
|
|
texts.push_back(std::move(resource));
|
|
|
|
|
}
|
|
|
|
|
if (script_sources.size() >= 1024) {
|
|
|
|
|
script_sources_blocked = true;
|
|
|
|
|
}
|
|
|
|
|
@@ -3643,6 +3838,21 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
script_sources_blocked = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "Tex") {
|
|
|
|
|
textures.push_back({
|
|
|
|
|
{"id", record.id},
|
|
|
|
|
{"name", record.name},
|
|
|
|
|
{"type", read_integer(*blend.sdna, element, "type").value_or(0)},
|
|
|
|
|
{"noiseScale", std::max(0.0f, read_float(*blend.sdna, element, "noisesize").value_or(0.25f))},
|
|
|
|
|
{"noiseDepth", std::clamp<int64_t>(read_integer(*blend.sdna, element, "noisedepth").value_or(2), 0, 30)},
|
|
|
|
|
{"intensity", std::max(0.0f, read_float(*blend.sdna, element, "bright").value_or(1.0f))},
|
|
|
|
|
{"contrast", std::max(0.0f, read_float(*blend.sdna, element, "contrast").value_or(1.0f))},
|
|
|
|
|
{"saturation", std::max(0.0f, read_float(*blend.sdna, element, "saturation").value_or(1.0f))},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "WorkSpace") {
|
|
|
|
|
workspace_resources.push_back({{"id", record.id}, {"name", record.name}, {"screenCount", linked_list_elements(blend, element, "layouts").size()}});
|
|
|
|
|
}
|
|
|
|
|
else if (record.type_name == "VFont") {
|
|
|
|
|
const std::string filepath = read_string(*blend.sdna, element, "filepath");
|
|
|
|
|
const std::optional<uint64_t> packed_file = read_pointer(*blend.sdna, element, "packedfile");
|
|
|
|
|
@@ -3947,6 +4157,15 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
sort_by_id(lights);
|
|
|
|
|
sort_by_id(worlds);
|
|
|
|
|
sort_by_id(images);
|
|
|
|
|
sort_by_id(brushes);
|
|
|
|
|
sort_by_id(line_styles);
|
|
|
|
|
sort_by_id(lattices);
|
|
|
|
|
sort_by_id(particle_settings);
|
|
|
|
|
sort_by_id(sounds);
|
|
|
|
|
sort_by_id(speakers);
|
|
|
|
|
sort_by_id(texts);
|
|
|
|
|
sort_by_id(textures);
|
|
|
|
|
sort_by_id(workspace_resources);
|
|
|
|
|
sort_by_id(non_mesh_data);
|
|
|
|
|
sort_by_id(vfonts);
|
|
|
|
|
sort_by_id(libraries);
|
|
|
|
|
@@ -3985,6 +4204,15 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
{"lights", std::move(lights)},
|
|
|
|
|
{"worlds", std::move(worlds)},
|
|
|
|
|
{"images", std::move(images)},
|
|
|
|
|
{"brushes", std::move(brushes)},
|
|
|
|
|
{"lineStyles", std::move(line_styles)},
|
|
|
|
|
{"lattices", std::move(lattices)},
|
|
|
|
|
{"particleSettings", std::move(particle_settings)},
|
|
|
|
|
{"sounds", std::move(sounds)},
|
|
|
|
|
{"speakers", std::move(speakers)},
|
|
|
|
|
{"texts", std::move(texts)},
|
|
|
|
|
{"textures", std::move(textures)},
|
|
|
|
|
{"workspaces", std::move(workspace_resources)},
|
|
|
|
|
{"nonMeshData", std::move(non_mesh_data)},
|
|
|
|
|
{"vfonts", std::move(vfonts)},
|
|
|
|
|
{"libraryStatus", libraries_blocked ? "BLOCKED" : "AVAILABLE"},
|
|
|
|
|
@@ -3998,6 +4226,7 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
|
|
|
|
{"scenes", std::move(scenes)},
|
|
|
|
|
{"activeObjectId", active_object_id.empty() ? json(nullptr) : json(active_object_id)},
|
|
|
|
|
{"frame", {{"current", frame_current}, {"start", frame_start}, {"end", frame_end}}}};
|
|
|
|
|
snapshot["windowManager"] = {{"id", "window-manager:WinMan"}, {"name", "WinMan"}, {"presetName", "New Preset"}, {"windowCount", 1}, {"interfaceLocked", false}};
|
|
|
|
|
if (!masks_blocked) {
|
|
|
|
|
snapshot["trackingMasks"] = {{"schemaVersion", 1},
|
|
|
|
|
{"revision", revision},
|
|
|
|
|
|